PluginProbe ʕ •ᴥ•ʔ
Secure Custom Fields / 6.4.1-beta7
Secure Custom Fields v6.4.1-beta7
6.9.5 6.9.4 6.9.3 6.9.2 6.9.1 6.9.0 6.8.9 6.8.7 6.8.8 6.8.6 6.8.4 6.8.5 trunk 6.4.0-beta1 6.4.0-beta2 6.4.1 6.4.1-beta3 6.4.1-beta4 6.4.1-beta5 6.4.1-beta6 6.4.1-beta7 6.4.2 6.5.0 6.5.1 6.5.2 6.5.3 6.5.4 6.5.5 6.5.6 6.5.7 6.6.0 6.7.0 6.7.1 6.8.0 6.8.1 6.8.2 6.8.3
secure-custom-fields / includes / fields / class-acf-field-checkbox.php
secure-custom-fields / includes / fields Last commit date
class-acf-field-accordion.php 1 year ago class-acf-field-button-group.php 1 year ago class-acf-field-checkbox.php 1 year ago class-acf-field-clone.php 1 year ago class-acf-field-color_picker.php 1 year ago class-acf-field-date_picker.php 1 year ago class-acf-field-date_time_picker.php 1 year ago class-acf-field-email.php 1 year ago class-acf-field-file.php 1 year ago class-acf-field-flexible-content.php 1 year ago class-acf-field-gallery.php 1 year ago class-acf-field-google-map.php 1 year ago class-acf-field-group.php 1 year ago class-acf-field-icon_picker.php 1 year ago class-acf-field-image.php 1 year ago class-acf-field-link.php 1 year ago class-acf-field-message.php 1 year ago class-acf-field-number.php 1 year ago class-acf-field-oembed.php 1 year ago class-acf-field-output.php 1 year ago class-acf-field-page_link.php 1 year ago class-acf-field-password.php 1 year ago class-acf-field-post_object.php 1 year ago class-acf-field-radio.php 1 year ago class-acf-field-range.php 1 year ago class-acf-field-relationship.php 1 year ago class-acf-field-repeater.php 1 year ago class-acf-field-select.php 1 year ago class-acf-field-separator.php 1 year ago class-acf-field-tab.php 1 year ago class-acf-field-taxonomy.php 1 year ago class-acf-field-text.php 1 year ago class-acf-field-textarea.php 1 year ago class-acf-field-time_picker.php 1 year ago class-acf-field-true_false.php 1 year ago class-acf-field-url.php 1 year ago class-acf-field-user.php 1 year ago class-acf-field-wysiwyg.php 1 year ago class-acf-field.php 1 year ago class-acf-repeater-table.php 1 year ago index.php 1 year ago
class-acf-field-checkbox.php
594 lines
1 <?php
2
3 if ( ! class_exists( 'acf_field_checkbox' ) ) :
4
5 class acf_field_checkbox extends acf_field {
6
7
8 /**
9 * This function will setup the field type data
10 *
11 * @type function
12 * @date 5/03/2014
13 * @since ACF 5.0.0
14 *
15 * @param n/a
16 * @return n/a
17 */
18 function initialize() {
19
20 // vars
21 $this->name = 'checkbox';
22 $this->label = __( 'Checkbox', 'secure-custom-fields' );
23 $this->category = 'choice';
24 $this->description = __( 'A group of checkbox inputs that allow the user to select one, or multiple values that you specify.', 'secure-custom-fields' );
25 $this->preview_image = acf_get_url() . '/assets/images/field-type-previews/field-preview-checkbox.png';
26 $this->doc_url = 'https://developer.wordpress.org/secure-custom-fields/features/fields/checkbox/';
27 $this->tutorial_url = 'https://developer.wordpress.org/secure-custom-fields/features/fields/checkbox/checkbox-tutorial/';
28 $this->defaults = array(
29 'layout' => 'vertical',
30 'choices' => array(),
31 'default_value' => '',
32 'allow_custom' => 0,
33 'save_custom' => 0,
34 'toggle' => 0,
35 'return_format' => 'value',
36 'custom_choice_button_text' => __( 'Add new choice', 'secure-custom-fields' ),
37 );
38 }
39
40
41 /**
42 * Create the HTML interface for your field
43 *
44 * @param $field (array) the $field being rendered
45 *
46 * @type action
47 * @since ACF 3.6
48 * @date 23/01/13
49 *
50 * @param $field (array) the $field being edited
51 * @return n/a
52 */
53 function render_field( $field ) {
54
55 // reset vars
56 $this->_values = array();
57 $this->_all_checked = true;
58
59 // ensure array
60 $field['value'] = acf_get_array( $field['value'] );
61 $field['choices'] = acf_get_array( $field['choices'] );
62
63 // hiden input
64 acf_hidden_input( array( 'name' => $field['name'] ) );
65
66 // vars
67 $li = '';
68 $ul = array(
69 'class' => 'acf-checkbox-list',
70 );
71
72 // append to class
73 $ul['class'] .= ' ' . ( $field['layout'] == 'horizontal' ? 'acf-hl' : 'acf-bl' );
74 $ul['class'] .= ' ' . $field['class'];
75
76 // checkbox saves an array
77 $field['name'] .= '[]';
78
79 // choices
80 if ( ! empty( $field['choices'] ) ) {
81
82 // choices
83 $li .= $this->render_field_choices( $field );
84
85 // toggle
86 if ( $field['toggle'] ) {
87 $li = $this->render_field_toggle( $field ) . $li;
88 }
89 }
90
91 // custom
92 if ( $field['allow_custom'] ) {
93 $li .= $this->render_field_custom( $field );
94 }
95
96 // return
97 echo '<ul ' . acf_esc_attrs( $ul ) . '>' . "\n" . $li . '</ul>' . "\n"; //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- escaped by specific render methods above.
98 }
99
100
101 /**
102 * description
103 *
104 * @type function
105 * @date 15/7/17
106 * @since ACF 5.6.0
107 *
108 * @param $post_id (int)
109 * @return $post_id (int)
110 */
111 function render_field_choices( $field ) {
112
113 // walk
114 return $this->walk( $field['choices'], $field );
115 }
116
117 /**
118 * Validates values for the checkbox field
119 *
120 * @since ACF 6.0.0
121 *
122 * @param boolean $valid If the field is valid.
123 * @param mixed $value The value to validate.
124 * @param array $field The main field array.
125 * @param string $input The input element's name attribute.
126 * @return boolean
127 */
128 public function validate_value( $valid, $value, $field, $input ) {
129 if ( ! is_array( $value ) || empty( $field['allow_custom'] ) ) {
130 return $valid;
131 }
132
133 foreach ( $value as $value ) {
134 if ( empty( $value ) && $value !== '0' ) {
135 return __( 'Checkbox custom values cannot be empty. Uncheck any empty values.', 'secure-custom-fields' );
136 }
137 }
138
139 return $valid;
140 }
141
142 /**
143 * description
144 *
145 * @type function
146 * @date 15/7/17
147 * @since ACF 5.6.0
148 *
149 * @param $post_id (int)
150 * @return $post_id (int)
151 */
152 function render_field_toggle( $field ) {
153
154 // vars
155 $atts = array(
156 'type' => 'checkbox',
157 'class' => 'acf-checkbox-toggle',
158 'label' => __( 'Toggle All', 'secure-custom-fields' ),
159 );
160
161 // custom label
162 if ( is_string( $field['toggle'] ) ) {
163 $atts['label'] = $field['toggle'];
164 }
165
166 // checked
167 if ( $this->_all_checked ) {
168 $atts['checked'] = 'checked';
169 }
170
171 // return
172 return '<li>' . acf_get_checkbox_input( $atts ) . '</li>' . "\n";
173 }
174
175
176 /**
177 * description
178 *
179 * @type function
180 * @date 15/7/17
181 * @since ACF 5.6.0
182 *
183 * @param $post_id (int)
184 * @return $post_id (int)
185 */
186 function render_field_custom( $field ) {
187
188 // vars
189 $html = '';
190
191 // loop
192 foreach ( $field['value'] as $value ) {
193
194 // ignore if already eixsts
195 if ( isset( $field['choices'][ $value ] ) ) {
196 continue;
197 }
198
199 // vars
200 $esc_value = esc_attr( $value );
201 $text_input = array(
202 'name' => $field['name'],
203 'value' => $value,
204 );
205
206 // bail early if choice already exists
207 if ( in_array( $esc_value, $this->_values ) ) {
208 continue;
209 }
210
211 // append
212 $html .= '<li><input class="acf-checkbox-custom" type="checkbox" checked="checked" />' . acf_get_text_input( $text_input ) . '</li>' . "\n";
213 }
214
215 // append button
216 $html .= '<li><a href="#" class="button acf-add-checkbox">' . esc_attr( $field['custom_choice_button_text'] ) . '</a></li>' . "\n";
217
218 // return
219 return $html;
220 }
221
222
223 function walk( $choices = array(), $args = array(), $depth = 0 ) {
224
225 // bail early if no choices
226 if ( empty( $choices ) ) {
227 return '';
228 }
229
230 // defaults
231 $args = wp_parse_args(
232 $args,
233 array(
234 'id' => '',
235 'type' => 'checkbox',
236 'name' => '',
237 'value' => array(),
238 'disabled' => array(),
239 )
240 );
241
242 // vars
243 $html = '';
244
245 // sanitize values for 'selected' matching
246 if ( $depth == 0 ) {
247 $args['value'] = array_map( 'esc_attr', $args['value'] );
248 $args['disabled'] = array_map( 'esc_attr', $args['disabled'] );
249 }
250
251 // loop
252 foreach ( $choices as $value => $label ) {
253
254 // open
255 $html .= '<li>';
256
257 // optgroup
258 if ( is_array( $label ) ) {
259 $html .= '<ul>' . "\n";
260 $html .= $this->walk( $label, $args, $depth + 1 );
261 $html .= '</ul>';
262
263 // option
264 } else {
265
266 // vars
267 $esc_value = esc_attr( $value );
268 $atts = array(
269 'id' => $args['id'] . '-' . str_replace( ' ', '-', $value ),
270 'type' => $args['type'],
271 'name' => $args['name'],
272 'value' => $value,
273 'label' => $label,
274 );
275
276 // selected
277 if ( in_array( $esc_value, $args['value'] ) ) {
278 $atts['checked'] = 'checked';
279 } else {
280 $this->_all_checked = false;
281 }
282
283 // disabled
284 if ( in_array( $esc_value, $args['disabled'] ) ) {
285 $atts['disabled'] = 'disabled';
286 }
287
288 // store value added
289 $this->_values[] = $esc_value;
290
291 // append
292 $html .= acf_get_checkbox_input( $atts );
293 }
294
295 // close
296 $html .= '</li>' . "\n";
297 }
298
299 // return
300 return $html;
301 }
302
303
304
305 /**
306 * Create extra options for your field. This is rendered when editing a field.
307 * The value of $field['name'] can be used (like bellow) to save extra data to the $field
308 *
309 * @type action
310 * @since ACF 3.6
311 * @date 23/01/13
312 *
313 * @param $field - an array holding all the field's data
314 */
315 function render_field_settings( $field ) {
316 // Encode choices (convert from array).
317 $field['choices'] = acf_encode_choices( $field['choices'] );
318 $field['default_value'] = acf_encode_choices( $field['default_value'], false );
319
320 acf_render_field_setting(
321 $field,
322 array(
323 'label' => __( 'Choices', 'secure-custom-fields' ),
324 'instructions' => __( 'Enter each choice on a new line.', 'secure-custom-fields' ) . '<br />' . __( 'For more control, you may specify both a value and label like this:', 'secure-custom-fields' ) . '<br /><span class="acf-field-setting-example">' . __( 'red : Red', 'secure-custom-fields' ) . '</span>',
325 'type' => 'textarea',
326 'name' => 'choices',
327 )
328 );
329
330 acf_render_field_setting(
331 $field,
332 array(
333 'label' => __( 'Default Value', 'secure-custom-fields' ),
334 'instructions' => __( 'Enter each default value on a new line', 'secure-custom-fields' ),
335 'type' => 'textarea',
336 'name' => 'default_value',
337 )
338 );
339
340 acf_render_field_setting(
341 $field,
342 array(
343 'label' => __( 'Return Value', 'secure-custom-fields' ),
344 'instructions' => __( 'Specify the returned value on front end', 'secure-custom-fields' ),
345 'type' => 'radio',
346 'name' => 'return_format',
347 'layout' => 'horizontal',
348 'choices' => array(
349 'value' => __( 'Value', 'secure-custom-fields' ),
350 'label' => __( 'Label', 'secure-custom-fields' ),
351 'array' => __( 'Both (Array)', 'secure-custom-fields' ),
352 ),
353 )
354 );
355 }
356
357 /**
358 * Renders the field settings used in the "Validation" tab.
359 *
360 * @since ACF 6.0
361 *
362 * @param array $field The field settings array.
363 * @return void
364 */
365 function render_field_validation_settings( $field ) {
366 acf_render_field_setting(
367 $field,
368 array(
369 'label' => __( 'Allow Custom Values', 'secure-custom-fields' ),
370 'name' => 'allow_custom',
371 'type' => 'true_false',
372 'ui' => 1,
373 'instructions' => __( "Allow 'custom' values to be added", 'secure-custom-fields' ),
374 )
375 );
376
377 acf_render_field_setting(
378 $field,
379 array(
380 'label' => __( 'Save Custom Values', 'secure-custom-fields' ),
381 'name' => 'save_custom',
382 'type' => 'true_false',
383 'ui' => 1,
384 'instructions' => __( "Save 'custom' values to the field's choices", 'secure-custom-fields' ),
385 'conditions' => array(
386 'field' => 'allow_custom',
387 'operator' => '==',
388 'value' => 1,
389 ),
390 )
391 );
392 }
393
394 /**
395 * Renders the field settings used in the "Presentation" tab.
396 *
397 * @since ACF 6.0
398 *
399 * @param array $field The field settings array.
400 * @return void
401 */
402 function render_field_presentation_settings( $field ) {
403 acf_render_field_setting(
404 $field,
405 array(
406 'label' => __( 'Layout', 'secure-custom-fields' ),
407 'instructions' => '',
408 'type' => 'radio',
409 'name' => 'layout',
410 'layout' => 'horizontal',
411 'choices' => array(
412 'vertical' => __( 'Vertical', 'secure-custom-fields' ),
413 'horizontal' => __( 'Horizontal', 'secure-custom-fields' ),
414 ),
415 )
416 );
417
418 acf_render_field_setting(
419 $field,
420 array(
421 'label' => __( 'Add Toggle All', 'secure-custom-fields' ),
422 'instructions' => __( 'Prepend an extra checkbox to toggle all choices', 'secure-custom-fields' ),
423 'name' => 'toggle',
424 'type' => 'true_false',
425 'ui' => 1,
426 )
427 );
428 }
429
430 /**
431 * This filter is appied to the $field before it is saved to the database
432 *
433 * @type filter
434 * @since ACF 3.6
435 * @date 23/01/13
436 *
437 * @param $field - the field array holding all the field options
438 * @param $post_id - the field group ID (post_type = acf)
439 *
440 * @return $field - the modified field
441 */
442 function update_field( $field ) {
443
444 // Decode choices (convert to array).
445 $field['choices'] = acf_decode_choices( $field['choices'] );
446 $field['default_value'] = acf_decode_choices( $field['default_value'], true );
447 return $field;
448 }
449
450
451 /**
452 * This filter is appied to the $value before it is updated in the db
453 *
454 * @type filter
455 * @since ACF 3.6
456 * @date 23/01/13
457 *
458 * @param $value - the value which will be saved in the database
459 * @param $post_id - the post_id of which the value will be saved
460 * @param $field - the field array holding all the field options
461 *
462 * @return $value - the modified value
463 */
464 function update_value( $value, $post_id, $field ) {
465
466 // bail early if is empty
467 if ( empty( $value ) ) {
468 return $value;
469 }
470
471 // select -> update_value()
472 $value = acf_get_field_type( 'select' )->update_value( $value, $post_id, $field );
473
474 // save_other_choice
475 if ( $field['save_custom'] ) {
476
477 // get raw $field (may have been changed via repeater field)
478 // if field is local, it won't have an ID
479 $selector = $field['ID'] ? $field['ID'] : $field['key'];
480 $field = acf_get_field( $selector );
481 if ( ! $field ) {
482 return false;
483 }
484
485 // bail early if no ID (JSON only)
486 if ( ! $field['ID'] ) {
487 return $value;
488 }
489
490 // loop
491 foreach ( $value as $v ) {
492
493 // ignore if already eixsts
494 if ( isset( $field['choices'][ $v ] ) ) {
495 continue;
496 }
497
498 // unslash (fixes serialize single quote issue)
499 $v = wp_unslash( $v );
500
501 // sanitize (remove tags)
502 $v = sanitize_text_field( $v );
503
504 // append
505 $field['choices'][ $v ] = $v;
506 }
507
508 // save
509 acf_update_field( $field );
510 }
511
512 // return
513 return $value;
514 }
515
516
517 /**
518 * This function will translate field settings
519 *
520 * @type function
521 * @date 8/03/2016
522 * @since ACF 5.3.2
523 *
524 * @param $field (array)
525 * @return $field
526 */
527 function translate_field( $field ) {
528
529 return acf_get_field_type( 'select' )->translate_field( $field );
530 }
531
532
533 /**
534 * This filter is appied to the $value after it is loaded from the db and before it is returned to the template
535 *
536 * @type filter
537 * @since ACF 3.6
538 * @date 23/01/13
539 *
540 * @param $value (mixed) the value which was loaded from the database
541 * @param $post_id (mixed) the post_id from which the value was loaded
542 * @param $field (array) the field array holding all the field options
543 *
544 * @return $value (mixed) the modified value
545 */
546 function format_value( $value, $post_id, $field ) {
547
548 // Bail early if is empty.
549 if ( acf_is_empty( $value ) ) {
550 return array();
551 }
552
553 // Always convert to array of items.
554 $value = acf_array( $value );
555
556 // Return.
557 return acf_get_field_type( 'select' )->format_value( $value, $post_id, $field );
558 }
559
560 /**
561 * Return the schema array for the REST API.
562 *
563 * @param array $field
564 * @return array
565 */
566 public function get_rest_schema( array $field ) {
567 $schema = array(
568 'type' => array( 'integer', 'string', 'array', 'null' ),
569 'required' => isset( $field['required'] ) && $field['required'],
570 'items' => array(
571 'type' => array( 'string', 'integer' ),
572 ),
573 );
574
575 if ( isset( $field['default_value'] ) && '' !== $field['default_value'] ) {
576 $schema['default'] = $field['default_value'];
577 }
578
579 // If we allow custom values, nothing else to do here.
580 if ( ! empty( $field['allow_custom'] ) ) {
581 return $schema;
582 }
583
584 $schema['items']['enum'] = acf_get_field_type( 'select' )->format_rest_choices( $field['choices'] );
585
586 return $schema;
587 }
588 }
589
590
591 // initialize
592 acf_register_field_type( 'acf_field_checkbox' );
593 endif; // class_exists check
594