PluginProbe
Advanced Custom Fields (ACF®) / 5.9.8
Advanced Custom Fields (ACF®) v5.9.8
6.8.9 6.8.8 6.8.7 6.8.6 6.8.5 6.8.4 6.8.3 6.8.2 6.8.1 5.8.5 5.8.6 5.8.7 5.8.8 5.8.9 5.9.0 5.9.1 5.9.2 5.9.3 5.9.4 5.9.5 5.9.6 5.9.7 5.9.8 5.9.9 6.0.0 All 230 releases
advanced-custom-fields / includes / fields / class-acf-field-select.php
class-acf-field-select.php
631 lines 13.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if( ! class_exists('acf_field_select') ) :
4
5 class acf_field_select extends acf_field {
6
7
8 /*
9 * __construct
10 *
11 * This function will setup the field type data
12 *
13 * @type function
14 * @date 5/03/2014
15 * @since 5.0.0
16 *
17 * @param n/a
18 * @return n/a
19 */
20
21 function initialize() {
22
23 // vars
24 $this->name = 'select';
25 $this->label = _x('Select', 'noun', 'acf');
26 $this->category = 'choice';
27 $this->defaults = array(
28 'multiple' => 0,
29 'allow_null' => 0,
30 'choices' => array(),
31 'default_value' => '',
32 'ui' => 0,
33 'ajax' => 0,
34 'placeholder' => '',
35 'return_format' => 'value'
36 );
37
38
39 // ajax
40 add_action('wp_ajax_acf/fields/select/query', array($this, 'ajax_query'));
41 add_action('wp_ajax_nopriv_acf/fields/select/query', array($this, 'ajax_query'));
42
43 }
44
45
46 /*
47 * input_admin_enqueue_scripts
48 *
49 * description
50 *
51 * @type function
52 * @date 16/12/2015
53 * @since 5.3.2
54 *
55 * @param $post_id (int)
56 * @return $post_id (int)
57 */
58
59 function input_admin_enqueue_scripts() {
60
61 // bail ealry if no enqueue
62 if( !acf_get_setting('enqueue_select2') ) return;
63
64
65 // globals
66 global $wp_scripts, $wp_styles;
67
68
69 // vars
70 $min = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min';
71 $major = acf_get_setting('select2_version');
72 $version = '';
73 $script = '';
74 $style = '';
75
76
77 // attempt to find 3rd party Select2 version
78 // - avoid including v3 CSS when v4 JS is already enququed
79 if( isset($wp_scripts->registered['select2']) ) {
80
81 $major = (int) $wp_scripts->registered['select2']->ver;
82
83 }
84
85
86 // v4
87 if( $major == 4 ) {
88
89 $version = '4.0';
90 $script = acf_get_url("assets/inc/select2/4/select2.full{$min}.js");
91 $style = acf_get_url("assets/inc/select2/4/select2{$min}.css");
92
93 // v3
94 } else {
95
96 $version = '3.5.2';
97 $script = acf_get_url("assets/inc/select2/3/select2{$min}.js");
98 $style = acf_get_url("assets/inc/select2/3/select2.css");
99
100 }
101
102
103 // enqueue
104 wp_enqueue_script('select2', $script, array('jquery'), $version );
105 wp_enqueue_style('select2', $style, '', $version );
106
107
108 // localize
109 acf_localize_data(array(
110 'select2L10n' => array(
111 'matches_1' => _x('One result is available, press enter to select it.', 'Select2 JS matches_1', 'acf'),
112 'matches_n' => _x('%d results are available, use up and down arrow keys to navigate.', 'Select2 JS matches_n', 'acf'),
113 'matches_0' => _x('No matches found', 'Select2 JS matches_0', 'acf'),
114 'input_too_short_1' => _x('Please enter 1 or more characters', 'Select2 JS input_too_short_1', 'acf' ),
115 'input_too_short_n' => _x('Please enter %d or more characters', 'Select2 JS input_too_short_n', 'acf' ),
116 'input_too_long_1' => _x('Please delete 1 character', 'Select2 JS input_too_long_1', 'acf' ),
117 'input_too_long_n' => _x('Please delete %d characters', 'Select2 JS input_too_long_n', 'acf' ),
118 'selection_too_long_1' => _x('You can only select 1 item', 'Select2 JS selection_too_long_1', 'acf' ),
119 'selection_too_long_n' => _x('You can only select %d items', 'Select2 JS selection_too_long_n', 'acf' ),
120 'load_more' => _x('Loading more results&hellip;', 'Select2 JS load_more', 'acf' ),
121 'searching' => _x('Searching&hellip;', 'Select2 JS searching', 'acf' ),
122 'load_fail' => _x('Loading failed', 'Select2 JS load_fail', 'acf' ),
123 )
124 ));
125 }
126
127
128 /*
129 * ajax_query
130 *
131 * description
132 *
133 * @type function
134 * @date 24/10/13
135 * @since 5.0.0
136 *
137 * @param $post_id (int)
138 * @return $post_id (int)
139 */
140
141 function ajax_query() {
142
143 // validate
144 if( !acf_verify_ajax() ) die();
145
146
147 // get choices
148 $response = $this->get_ajax_query( $_POST );
149
150
151 // return
152 acf_send_ajax_results($response);
153
154 }
155
156
157 /*
158 * get_ajax_query
159 *
160 * This function will return an array of data formatted for use in a select2 AJAX response
161 *
162 * @type function
163 * @date 15/10/2014
164 * @since 5.0.9
165 *
166 * @param $options (array)
167 * @return (array)
168 */
169
170 function get_ajax_query( $options = array() ) {
171
172 // defaults
173 $options = acf_parse_args($options, array(
174 'post_id' => 0,
175 's' => '',
176 'field_key' => '',
177 'paged' => 1
178 ));
179
180
181 // load field
182 $field = acf_get_field( $options['field_key'] );
183 if( !$field ) return false;
184
185
186 // get choices
187 $choices = acf_get_array($field['choices']);
188 if( empty($field['choices']) ) return false;
189
190
191 // vars
192 $results = array();
193 $s = null;
194
195
196 // search
197 if( $options['s'] !== '' ) {
198
199 // strip slashes (search may be integer)
200 $s = strval( $options['s'] );
201 $s = wp_unslash( $s );
202
203 }
204
205
206 // loop
207 foreach( $field['choices'] as $k => $v ) {
208
209 // ensure $v is a string
210 $v = strval( $v );
211
212
213 // if searching, but doesn't exist
214 if( is_string($s) && stripos($v, $s) === false ) continue;
215
216
217 // append
218 $results[] = array(
219 'id' => $k,
220 'text' => $v
221 );
222
223 }
224
225
226 // vars
227 $response = array(
228 'results' => $results
229 );
230
231
232 // return
233 return $response;
234
235 }
236
237
238 /*
239 * render_field()
240 *
241 * Create the HTML interface for your field
242 *
243 * @param $field - an array holding all the field's data
244 *
245 * @type action
246 * @since 3.6
247 * @date 23/01/13
248 */
249
250 function render_field( $field ) {
251
252 // convert
253 $value = acf_get_array($field['value']);
254 $choices = acf_get_array($field['choices']);
255
256
257 // placeholder
258 if( empty($field['placeholder']) ) {
259 $field['placeholder'] = _x('Select', 'verb', 'acf');
260 }
261
262
263 // add empty value (allows '' to be selected)
264 if( empty($value) ) {
265 $value = array('');
266 }
267
268
269 // prepend empty choice
270 // - only for single selects
271 // - have tried array_merge but this causes keys to re-index if is numeric (post ID's)
272 if( $field['allow_null'] && !$field['multiple'] ) {
273 $choices = array( '' => "- {$field['placeholder']} -" ) + $choices;
274 }
275
276
277 // clean up choices if using ajax
278 if( $field['ui'] && $field['ajax'] ) {
279 $minimal = array();
280 foreach( $value as $key ) {
281 if( isset($choices[ $key ]) ) {
282 $minimal[ $key ] = $choices[ $key ];
283 }
284 }
285 $choices = $minimal;
286 }
287
288
289 // vars
290 $select = array(
291 'id' => $field['id'],
292 'class' => $field['class'],
293 'name' => $field['name'],
294 'data-ui' => $field['ui'],
295 'data-ajax' => $field['ajax'],
296 'data-multiple' => $field['multiple'],
297 'data-placeholder' => $field['placeholder'],
298 'data-allow_null' => $field['allow_null']
299 );
300
301
302 // multiple
303 if( $field['multiple'] ) {
304
305 $select['multiple'] = 'multiple';
306 $select['size'] = 5;
307 $select['name'] .= '[]';
308
309 // Reduce size to single line if UI.
310 if( $field['ui'] ) {
311 $select['size'] = 1;
312 }
313 }
314
315
316 // special atts
317 if( !empty($field['readonly']) ) $select['readonly'] = 'readonly';
318 if( !empty($field['disabled']) ) $select['disabled'] = 'disabled';
319 if( !empty($field['ajax_action']) ) $select['data-ajax_action'] = $field['ajax_action'];
320
321
322 // hidden input is needed to allow validation to see <select> element with no selected value
323 if( $field['multiple'] || $field['ui'] ) {
324 acf_hidden_input(array(
325 'id' => $field['id'] . '-input',
326 'name' => $field['name']
327 ));
328 }
329
330
331 // append
332 $select['value'] = $value;
333 $select['choices'] = $choices;
334
335
336 // render
337 acf_select_input( $select );
338
339 }
340
341
342 /*
343 * render_field_settings()
344 *
345 * Create extra options for your field. This is rendered when editing a field.
346 * The value of $field['name'] can be used (like bellow) to save extra data to the $field
347 *
348 * @type action
349 * @since 3.6
350 * @date 23/01/13
351 *
352 * @param $field - an array holding all the field's data
353 */
354
355 function render_field_settings( $field ) {
356
357 // encode choices (convert from array)
358 $field['choices'] = acf_encode_choices($field['choices']);
359 $field['default_value'] = acf_encode_choices($field['default_value'], false);
360
361
362 // choices
363 acf_render_field_setting( $field, array(
364 'label' => __('Choices','acf'),
365 'instructions' => __('Enter each choice on a new line.','acf') . '<br /><br />' . __('For more control, you may specify both a value and label like this:','acf'). '<br /><br />' . __('red : Red','acf'),
366 'name' => 'choices',
367 'type' => 'textarea',
368 ));
369
370
371 // default_value
372 acf_render_field_setting( $field, array(
373 'label' => __('Default Value','acf'),
374 'instructions' => __('Enter each default value on a new line','acf'),
375 'name' => 'default_value',
376 'type' => 'textarea',
377 ));
378
379
380 // allow_null
381 acf_render_field_setting( $field, array(
382 'label' => __('Allow Null?','acf'),
383 'instructions' => '',
384 'name' => 'allow_null',
385 'type' => 'true_false',
386 'ui' => 1,
387 ));
388
389
390 // multiple
391 acf_render_field_setting( $field, array(
392 'label' => __('Select multiple values?','acf'),
393 'instructions' => '',
394 'name' => 'multiple',
395 'type' => 'true_false',
396 'ui' => 1,
397 ));
398
399
400 // ui
401 acf_render_field_setting( $field, array(
402 'label' => __('Stylised UI','acf'),
403 'instructions' => '',
404 'name' => 'ui',
405 'type' => 'true_false',
406 'ui' => 1,
407 ));
408
409
410 // ajax
411 acf_render_field_setting( $field, array(
412 'label' => __('Use AJAX to lazy load choices?','acf'),
413 'instructions' => '',
414 'name' => 'ajax',
415 'type' => 'true_false',
416 'ui' => 1,
417 'conditions' => array(
418 'field' => 'ui',
419 'operator' => '==',
420 'value' => 1
421 )
422 ));
423
424
425 // return_format
426 acf_render_field_setting( $field, array(
427 'label' => __('Return Format','acf'),
428 'instructions' => __('Specify the value returned','acf'),
429 'type' => 'select',
430 'name' => 'return_format',
431 'choices' => array(
432 'value' => __('Value','acf'),
433 'label' => __('Label','acf'),
434 'array' => __('Both (Array)','acf')
435 )
436 ));
437
438 }
439
440
441 /*
442 * load_value()
443 *
444 * This filter is applied to the $value after it is loaded from the db
445 *
446 * @type filter
447 * @since 3.6
448 * @date 23/01/13
449 *
450 * @param $value (mixed) the value found in the database
451 * @param $post_id (mixed) the $post_id from which the value was loaded
452 * @param $field (array) the field array holding all the field options
453 * @return $value
454 */
455 function load_value( $value, $post_id, $field ) {
456
457 // Return an array when field is set for multiple.
458 if( $field['multiple'] ) {
459 if( acf_is_empty( $value ) ) {
460 return array();
461 }
462 return acf_array( $value );
463 }
464
465 // Otherwise, return a single value.
466 return acf_unarray( $value );
467 }
468
469
470 /*
471 * update_field()
472 *
473 * This filter is appied to the $field before it is saved to the database
474 *
475 * @type filter
476 * @since 3.6
477 * @date 23/01/13
478 *
479 * @param $field - the field array holding all the field options
480 * @param $post_id - the field group ID (post_type = acf)
481 *
482 * @return $field - the modified field
483 */
484
485 function update_field( $field ) {
486
487 // decode choices (convert to array)
488 $field['choices'] = acf_decode_choices($field['choices']);
489 $field['default_value'] = acf_decode_choices($field['default_value'], true);
490
491 // Convert back to string for single selects.
492 if( !$field['multiple'] ) {
493 $field['default_value'] = acf_unarray( $field['default_value'] );
494 }
495
496 // return
497 return $field;
498 }
499
500
501 /*
502 * update_value()
503 *
504 * This filter is appied to the $value before it is updated in the db
505 *
506 * @type filter
507 * @since 3.6
508 * @date 23/01/13
509 *
510 * @param $value - the value which will be saved in the database
511 * @param $post_id - the $post_id of which the value will be saved
512 * @param $field - the field array holding all the field options
513 *
514 * @return $value - the modified value
515 */
516
517 function update_value( $value, $post_id, $field ) {
518
519 // Bail early if no value.
520 if( empty($value) ) {
521 return $value;
522 }
523
524 // Format array of values.
525 // - Parse each value as string for SQL LIKE queries.
526 if( is_array($value) ) {
527 $value = array_map('strval', $value);
528 }
529
530 // return
531 return $value;
532 }
533
534
535 /*
536 * translate_field
537 *
538 * This function will translate field settings
539 *
540 * @type function
541 * @date 8/03/2016
542 * @since 5.3.2
543 *
544 * @param $field (array)
545 * @return $field
546 */
547
548 function translate_field( $field ) {
549
550 // translate
551 $field['choices'] = acf_translate( $field['choices'] );
552
553
554 // return
555 return $field;
556
557 }
558
559
560 /*
561 * format_value()
562 *
563 * This filter is appied to the $value after it is loaded from the db and before it is returned to the template
564 *
565 * @type filter
566 * @since 3.6
567 * @date 23/01/13
568 *
569 * @param $value (mixed) the value which was loaded from the database
570 * @param $post_id (mixed) the $post_id from which the value was loaded
571 * @param $field (array) the field array holding all the field options
572 *
573 * @return $value (mixed) the modified value
574 */
575 function format_value( $value, $post_id, $field ) {
576 if( is_array( $value ) ) {
577 foreach( $value as $i => $val ) {
578 $value[ $i ] = $this->format_value_single( $val, $post_id, $field );
579 }
580 } else {
581 $value = $this->format_value_single( $value, $post_id, $field );
582 }
583 return $value;
584 }
585
586
587 function format_value_single( $value, $post_id, $field ) {
588
589 // bail ealry if is empty
590 if( acf_is_empty($value) ) return $value;
591
592
593 // vars
594 $label = acf_maybe_get($field['choices'], $value, $value);
595
596
597 // value
598 if( $field['return_format'] == 'value' ) {
599
600 // do nothing
601
602 // label
603 } elseif( $field['return_format'] == 'label' ) {
604
605 $value = $label;
606
607 // array
608 } elseif( $field['return_format'] == 'array' ) {
609
610 $value = array(
611 'value' => $value,
612 'label' => $label
613 );
614
615 }
616
617
618 // return
619 return $value;
620
621 }
622
623 }
624
625
626 // initialize
627 acf_register_field_type( 'acf_field_select' );
628
629 endif; // class_exists check
630
631 ?>