Completed
Pull Request — trunk (#722)
by José Carlos
07:13
created

CMB2_Field::display_value_callback()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 43
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 3.0593

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 3
eloc 16
c 1
b 0
f 1
nc 3
nop 0
dl 0
loc 43
rs 8.8571
ccs 13
cts 16
cp 0.8125
crap 3.0593
1
<?php
2
/**
3
 * CMB2 field objects
4
 *
5
 * @since  1.1.0
6
 *
7
 * @category  WordPress_Plugin
8
 * @package   CMB2
9
 * @author    WebDevStudios
10
 * @license   GPL-2.0+
11
 * @link      http://webdevstudios.com
12
 *
13
 * @method string _id()
14
 * @method string type()
15
 * @method mixed fields()
16
 */
17
class CMB2_Field extends CMB2_Base {
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
18
19
	/**
20
	 * The object properties name.
21
	 * @var   string
22
	 * @since 2.2.3
23
	 */
24
	protected $properties_name = 'args';
25
26
	/**
27
	 * Field arguments
28
	 * @var   mixed
29
	 * @since 1.1.0
30
	 */
31
	public $args = array();
32
33
	/**
34
	 * Field group object or false (if no group)
35
	 * @var   mixed
36
	 * @since 1.1.0
37
	 */
38
	public $group = false;
39
40
	/**
41
	 * Field meta value
42
	 * @var   mixed
43
	 * @since 1.1.0
44
	 */
45
	public $value = null;
46
47
	/**
48
	 * Field meta value
49
	 * @var   mixed
50
	 * @since 1.1.0
51
	 */
52
	public $escaped_value = null;
53
54
	/**
55
	 * Grouped Field's current numeric index during the save process
56
	 * @var   mixed
57
	 * @since 2.0.0
58
	 */
59
	public $index = 0;
60
61
	/**
62
	 * Array of field options
63
	 * @var   array
64
	 * @since 2.0.0
65
	 */
66
	protected $field_options = array();
67
68
	/**
69
	 * Array of provided field text strings
70
	 * @var   array
71
	 * @since 2.0.0
72
	 */
73
	protected $strings;
74
75
	/**
76
	 * The field's render context. In most cases, 'edit', but can be 'display'.
77
	 * @var   string
78
	 * @since 2.2.2
79
	 */
80
	public $render_context = 'edit';
81
82
	/**
83
	 * All CMB2_Field callable field arguments.
84
	 * Can be used to determine if a field argument is callable.
85
	 *
86
	 * @var array
87
	 */
88
	public static $callable_fields = array(
89
		'default',
90
		'row_classes',
91
		'options_cb',
92
		'label_cb',
93
		'render_row_cb',
94
		'before_group',
95
		'before_group_row',
96
		'before_row',
97
		'before',
98
		'before_field',
99
		'after_field',
100
		'after',
101
		'after_row',
102
		'after_group_row',
103
		'after_group',
104
	);
105
106
	/**
107
	 * Constructs our field object
108
	 * @since 1.1.0
109
	 * @param array $args Field arguments
110
	 */
111 109
	public function __construct( $args ) {
112
113 109
		if ( ! empty( $args['group_field'] ) ) {
114 3
			$this->group       = $args['group_field'];
115 3
			$this->object_id   = $this->group->object_id;
116 3
			$this->object_type = $this->group->object_type;
117 3
			$this->cmb_id      = $this->group->cmb_id;
118 3
		} else {
119 109
			$this->object_id   = isset( $args['object_id'] ) && '_' !== $args['object_id'] ? $args['object_id'] : 0;
120 109
			$this->object_type = isset( $args['object_type'] ) ? $args['object_type'] : 'post';
121
122 109
			if ( isset( $args['cmb_id'] ) ) {
123 40
				$this->cmb_id = $args['cmb_id'];
124 40
			}
125
		}
126
127 109
		$this->args = $this->_set_field_defaults( $args['field_args'], $args );
0 ignored issues
show
Unused Code introduced by
The call to CMB2_Field::_set_field_defaults() has too many arguments starting with $args.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
128
129 109
		if ( $this->object_id ) {
130 103
			$this->value = $this->get_data();
131 103
		}
132 109
	}
133
134
	/**
135
	 * Non-existent methods fallback to checking for field arguments of the same name
136
	 * @since  1.1.0
137
	 * @param  string $name     Method name
138
	 * @param  array  $arguments Array of passed-in arguments
139
	 * @return mixed             Value of field argument
140
	 */
141 97
	public function __call( $name, $arguments ) {
142 97
		if ( 'string' === $name ) {
143
			return call_user_func_array( array( $this, 'get_string' ), $arguments );
144
		}
145
146 97
		$key = isset( $arguments[0] ) ? $arguments[0] : false;
147 97
		return $this->args( $name, $key );
148
	}
149
150
	/**
151
	 * Retrieves the field id
152
	 * @since  1.1.0
153
	 * @param  boolean $raw Whether to retrieve pre-modidifed id
154
	 * @return string       Field id
155
	 */
156 107
	public function id( $raw = false ) {
157 107
		$id = $raw ? '_id' : 'id';
158 107
		return $this->args( $id );
159
	}
160
161
	/**
162
	 * Get a field argument
163
	 * @since  1.1.0
164
	 * @param  string $key  Argument to check
165
	 * @param  string $_key Sub argument to check
166
	 * @return mixed        Argument value or false if non-existent
167
	 */
168 110
	public function args( $key = '', $_key = '' ) {
169 110
		$arg = $this->_data( 'args', $key );
170
171 110
		if ( in_array( $key, array( 'default', 'default_cb' ), true ) ) {
172
173 1
			$arg = $this->get_default();
174
175 110
		} elseif ( $_key ) {
176
177
			$arg = isset( $arg[ $_key ] ) ? $arg[ $_key ] : false;
178
		}
179
180 110
		return $arg;
181
	}
182
183
	/**
184
	 * Retrieve a portion of a field property
185
	 * @since  1.1.0
186
	 * @param  string  $var Field property to check
187
	 * @param  string  $key Field property array key to check
188
	 * @return mixed        Queried property value or false
189
	 */
190 110
	public function _data( $var, $key = '' ) {
191 110
		$vars = $this->{$var};
192 110
		if ( $key ) {
193 110
			return array_key_exists( $key, $vars ) ? $vars[ $key ] : false;
194
		}
195 59
		return $vars;
196
	}
197
198
	/**
199
	 * Get Field's value
200
	 * @since  1.1.0
201
	 * @param  string $key If value is an array, is used to get array key->value
202
	 * @return mixed       Field value or false if non-existent
203
	 */
204 46
	public function value( $key = '' ) {
205 46
		return $this->_data( 'value', $key );
206
	}
207
208
	/**
209
	 * Retrieves metadata/option data
210
	 * @since  1.0.1
211
	 * @param  string $field_id Meta key/Option array key
212
	 * @param  array  $args     Override arguments
213
	 * @return mixed            Meta/Option value
214
	 */
215 105
	public function get_data( $field_id = '', $args = array() ) {
216 105
		if ( $field_id ) {
217
			$args['field_id'] = $field_id;
218 105
		} else if ( $this->group ) {
219
			$args['field_id'] = $this->group->id();
220
		}
221
222 105
		$a = $this->data_args( $args );
223
224
		/**
225
		 * Filter whether to override getting of meta value.
226
		 * Returning a non 'cmb2_field_no_override_val' value
227
		 * will effectively short-circuit the value retrieval.
228
		 *
229
		 * @since 2.0.0
230
		 *
231
		 * @param mixed $value     The value get_metadata() should
232
		 *                         return - a single metadata value,
233
		 *                         or an array of values.
234
		 *
235
		 * @param int   $object_id Object ID.
236
		 *
237
		 * @param array $args {
238
		 *     An array of arguments for retrieving data
239
		 *
240
		 *     @type string $type     The current object type
241
		 *     @type int    $id       The current object ID
242
		 *     @type string $field_id The ID of the field being requested
243
		 *     @type bool   $repeat   Whether current field is repeatable
244
		 *     @type bool   $single   Whether current field is a single database row
245
		 * }
246
		 *
247
		 * @param CMB2_Field object $field This field object
248
		 */
249 105
		$data = apply_filters( 'cmb2_override_meta_value', 'cmb2_field_no_override_val', $this->object_id, $a, $this );
250
251
		/**
252
		 * Filter and parameters are documented for 'cmb2_override_meta_value' filter (above).
253
		 *
254
		 * The dynamic portion of the hook, $field_id, refers to the current
255
		 * field id paramater. Returning a non 'cmb2_field_no_override_val' value
256
		 * will effectively short-circuit the value retrieval.
257
		 *
258
		 * @since 2.0.0
259
		 */
260 105
		$data = apply_filters( "cmb2_override_{$a['field_id']}_meta_value", $data, $this->object_id, $a, $this );
261
262
		// If no override, get value normally
263 105
		if ( 'cmb2_field_no_override_val' === $data ) {
264 102
			$data = 'options-page' === $a['type']
265 102
				? cmb2_options( $a['id'] )->get( $a['field_id'] )
266 102
				: get_metadata( $a['type'], $a['id'], $a['field_id'], ( $a['single'] || $a['repeat'] ) );
267 102
		}
268
269 105
		if ( $this->group ) {
270
271
			$data = is_array( $data ) && isset( $data[ $this->group->index ][ $this->args( '_id' ) ] )
272
				? $data[ $this->group->index ][ $this->args( '_id' ) ]
273
				: false;
274
		}
275
276 105
		return $data;
277
	}
278
279
	/**
280
	 * Updates metadata/option data
281
	 * @since  1.0.1
282
	 * @param  mixed $new_value Value to update data with
283
	 * @param  bool  $single    Whether data is an array (add_metadata)
284
	 */
285 11
	public function update_data( $new_value, $single = true ) {
286 11
		$a = $this->data_args( array( 'single' => $single ) );
287
288 11
		$a['value'] = $a['repeat'] ? array_values( $new_value ) : $new_value;
289
290
		/**
291
		 * Filter whether to override saving of meta value.
292
		 * Returning a non-null value will effectively short-circuit the function.
293
		 *
294
		 * @since 2.0.0
295
		 *
296
		 * @param null|bool $check  Whether to allow updating metadata for the given type.
297
		 *
298
		 * @param array $args {
299
		 *     Array of data about current field including:
300
		 *
301
		 *     @type string $value    The value to set
302
		 *     @type string $type     The current object type
303
		 *     @type int    $id       The current object ID
304
		 *     @type string $field_id The ID of the field being updated
305
		 *     @type bool   $repeat   Whether current field is repeatable
306
		 *     @type bool   $single   Whether current field is a single database row
307
		 * }
308
		 *
309
		 * @param array $field_args All field arguments
310
		 *
311
		 * @param CMB2_Field object $field This field object
312
		 */
313 11
		$override = apply_filters( 'cmb2_override_meta_save', null, $a, $this->args(), $this );
314
315
		/**
316
		 * Filter and parameters are documented for 'cmb2_override_meta_save' filter (above).
317
		 *
318
		 * The dynamic portion of the hook, $a['field_id'], refers to the current
319
		 * field id paramater. Returning a non-null value
320
		 * will effectively short-circuit the function.
321
		 *
322
		 * @since 2.0.0
323
		 */
324 11
		$override = apply_filters( "cmb2_override_{$a['field_id']}_meta_save", $override, $a, $this->args(), $this );
325
326
		// If override, return that
327 11
		if ( null !== $override ) {
328 2
			return $override;
329
		}
330
331
		// Options page handling (or temp data store)
332 10
		if ( 'options-page' === $a['type'] || empty( $a['id'] ) ) {
333 3
			return cmb2_options( $a['id'] )->update( $a['field_id'], $a['value'], false, $a['single'] );
334
		}
335
336
		// Add metadata if not single
337 7
		if ( ! $a['single'] ) {
338 1
			return add_metadata( $a['type'], $a['id'], $a['field_id'], $a['value'], false );
339
		}
340
341
		// Delete meta if we have an empty array
342 6
		if ( is_array( $a['value'] ) && empty( $a['value'] ) ) {
343
			return delete_metadata( $a['type'], $a['id'], $a['field_id'], $this->value );
344
		}
345
346
		// Update metadata
347 6
		return update_metadata( $a['type'], $a['id'], $a['field_id'], $a['value'] );
348
	}
349
350
	/**
351
	 * Removes/updates metadata/option data
352
	 * @since  1.0.1
353
	 * @param  string $old Old value
354
	 */
355 3
	public function remove_data( $old = '' ) {
356 3
		$a = $this->data_args( array( 'old' => $old ) );
357
358
		/**
359
		 * Filter whether to override removing of meta value.
360
		 * Returning a non-null value will effectively short-circuit the function.
361
		 *
362
		 * @since 2.0.0
363
		 *
364
		 * @param null|bool $delete Whether to allow metadata deletion of the given type.
365
		 * @param array $args       Array of data about current field including:
366
		 *                              'type'     : Current object type
367
		 *                              'id'       : Current object ID
368
		 *                              'field_id' : Current Field ID
369
		 *                              'repeat'   : Whether current field is repeatable
370
		 *                              'single'   : Whether to save as a
371
		 *                              					single meta value
372
		 * @param array $field_args All field arguments
373
		 * @param CMB2_Field object $field This field object
374
		 */
375 3
		$override = apply_filters( 'cmb2_override_meta_remove', null, $a, $this->args(), $this );
376
377
		/**
378
		 * Filter whether to override removing of meta value.
379
		 *
380
		 * The dynamic portion of the hook, $a['field_id'], refers to the current
381
		 * field id paramater. Returning a non-null value
382
		 * will effectively short-circuit the function.
383
		 *
384
		 * @since 2.0.0
385
		 *
386
		 * @param null|bool $delete Whether to allow metadata deletion of the given type.
387
		 * @param array $args       Array of data about current field including:
388
		 *                              'type'     : Current object type
389
		 *                              'id'       : Current object ID
390
		 *                              'field_id' : Current Field ID
391
		 *                              'repeat'   : Whether current field is repeatable
392
		 *                              'single'   : Whether to save as a
393
		 *                              					single meta value
394
		 * @param array $field_args All field arguments
395
		 * @param CMB2_Field object $field This field object
396
		 */
397 3
		$override = apply_filters( "cmb2_override_{$a['field_id']}_meta_remove", $override, $a, $this->args(), $this );
398
399
		// If no override, remove as usual
400 3
		if ( null !== $override ) {
401
			return $override;
402
		}
403
		// Option page handling
404 3
		elseif ( 'options-page' === $a['type'] || empty( $a['id'] ) ) {
405 1
			return cmb2_options( $a['id'] )->remove( $a['field_id'] );
406
		}
407
408
		// Remove metadata
409 2
		return delete_metadata( $a['type'], $a['id'], $a['field_id'], $old );
410
	}
411
412
	/**
413
	 * Data variables for get/set data methods
414
	 * @since  1.1.0
415
	 * @param  array $args Override arguments
416
	 * @return array       Updated arguments
417
	 */
418 105
	public function data_args( $args = array() ) {
419 105
		$args = wp_parse_args( $args, array(
420 105
			'type'     => $this->object_type,
421 105
			'id'       => $this->object_id,
422 105
			'field_id' => $this->id( true ),
423 105
			'repeat'   => $this->args( 'repeatable' ),
424 105
			'single'   => ! $this->args( 'multiple' ),
425 105
		) );
426 105
		return $args;
427
	}
428
429
	/**
430
	 * Checks if field has a registered sanitization callback
431
	 * @since  1.0.1
432
	 * @param  mixed $meta_value Meta value
433
	 * @return mixed             Possibly sanitized meta value
434
	 */
435 13
	public function sanitization_cb( $meta_value ) {
436
437 13
		if ( $this->args( 'repeatable' ) && is_array( $meta_value ) ) {
438
			// Remove empties
439 1
			$meta_value = array_filter( $meta_value );
440 1
		}
441
442
		// Check if the field has a registered validation callback
443 13
		$cb = $this->maybe_callback( 'sanitization_cb' );
444 13
		if ( false === $cb ) {
445
			// If requesting NO validation, return meta value
446 1
			return $meta_value;
447 12
		} elseif ( $cb ) {
448
			// Ok, callback is good, let's run it.
449
			return call_user_func( $cb, $meta_value, $this->args(), $this );
450
		}
451
452 12
		$sanitizer = new CMB2_Sanitize( $this, $meta_value );
453
454
		/**
455
		 * Filter the value before it is saved.
456
		 *
457
		 * The dynamic portion of the hook name, $this->type(), refers to the field type.
458
		 *
459
		 * Passing a non-null value to the filter will short-circuit saving
460
		 * the field value, saving the passed value instead.
461
		 *
462
		 * @param bool|mixed $override_value Sanitization/Validation override value to return.
463
		 *                                   Default false to skip it.
464
		 * @param mixed      $value      The value to be saved to this field.
465
		 * @param int        $object_id  The ID of the object where the value will be saved
466
		 * @param array      $field_args The current field's arguments
467
		 * @param object     $sanitizer  This `CMB2_Sanitize` object
468
		 */
469 12
		$override_value = apply_filters( "cmb2_sanitize_{$this->type()}", null, $sanitizer->value, $this->object_id, $this->args(), $sanitizer );
470
471 12
		if ( null !== $override_value ) {
472 1
			return $override_value;
473
		}
474
475
		// Sanitization via 'CMB2_Sanitize'
476 11
		return $sanitizer->{$this->type()}();
477
	}
478
479
	/**
480
	 * Process $_POST data to save this field's value
481
	 * @since  2.0.3
482
	 * @param  array $data_to_save $_POST data to check
483
	 * @return array|int|bool                Result of save, false on failure
484
	 */
485 2
	public function save_field_from_data( array $data_to_save ) {
486 2
		$this->data_to_save = $data_to_save;
487
488 2
		$meta_value = isset( $this->data_to_save[ $this->id( true ) ] )
489 2
			? $this->data_to_save[ $this->id( true ) ]
490 2
			: null;
491
492 2
		return $this->save_field( $meta_value );
493
	}
494
495
	/**
496
	 * Sanitize/store a value to this field
497
	 * @since  2.0.0
498
	 * @param  array $meta_value Desired value to sanitize/store
499
	 * @return array|int|bool              Result of save. false on failure
500
	 */
501 12
	public function save_field( $meta_value ) {
502
503 12
		$updated   = false;
504 12
		$action    = '';
505 12
		$new_value = $this->sanitization_cb( $meta_value );
506
507 12
		if ( ! $this->args( 'save_field' ) ) {
508
509
			// Nothing to see here.
510 1
			$action = 'disabled';
511
512 12
		} elseif ( $this->args( 'multiple' ) && ! $this->args( 'repeatable' ) && ! $this->group ) {
513
514 1
			$this->remove_data();
515 1
			$count = 0;
516
517 1
			if ( ! empty( $new_value ) ) {
518 1
				foreach ( $new_value as $add_new ) {
519 1
					if ( $this->update_data( $add_new, false ) ) {
520 1
						$count++;
521 1
					}
522 1
				}
523 1
			}
524
525 1
			$updated = $count ? $count : false;
526 1
			$action  = 'repeatable';
527
528 11
		} elseif ( ! CMB2_Utils::isempty( $new_value ) && $new_value !== $this->get_data() ) {
529 9
			$updated = $this->update_data( $new_value );
530 9
			$action  = 'updated';
531 10
		} elseif ( CMB2_Utils::isempty( $new_value ) ) {
532 2
			$updated = $this->remove_data();
533 2
			$action  = 'removed';
534 2
		}
535
536 12
		if ( $updated ) {
537 11
			$this->value = $this->get_data();
538 11
			$this->escaped_value = null;
539 11
		}
540
541 12
		$field_id = $this->id( true );
542
543
		/**
544
		 * Hooks after save field action.
545
		 *
546
		 * @since 2.2.0
547
		 *
548
		 * @param string            $field_id the current field id paramater.
549
		 * @param bool              $updated  Whether the metadata update action occurred.
550
		 * @param string            $action   Action performed. Could be "repeatable", "updated", or "removed".
551
		 * @param CMB2_Field object $field    This field object
552
		 */
553 12
		do_action( 'cmb2_save_field', $field_id, $updated, $action, $this );
554
555
		/**
556
		 * Hooks after save field action.
557
		 *
558
		 * The dynamic portion of the hook, $field_id, refers to the
559
		 * current field id paramater.
560
		 *
561
		 * @since 2.2.0
562
		 *
563
		 * @param bool              $updated Whether the metadata update action occurred.
564
		 * @param string            $action  Action performed. Could be "repeatable", "updated", or "removed".
565
		 * @param CMB2_Field object $field   This field object
566
		 */
567 11
		do_action( "cmb2_save_field_{$field_id}", $updated, $action, $this );
568
569 10
		return $updated;
570
	}
571
572
	/**
573
	 * Determine if current type is exempt from escaping
574
	 * @since  1.1.0
575
	 * @return bool  True if exempt
576
	 */
577 46
	public function escaping_exception() {
578
		// These types cannot be escaped
579 46
		return in_array( $this->type(), array(
580 46
			'file_list',
581 46
			'multicheck',
582 46
			'text_datetime_timestamp_timezone',
583 46
		) );
584
	}
585
586
	/**
587
	 * Determine if current type cannot be repeatable
588
	 * @since  1.1.0
589
	 * @param  string $type Field type to check
590
	 * @return bool         True if type cannot be repeatable
591
	 */
592 4
	public function repeatable_exception( $type ) {
593
		// These types cannot be repeatable.
594
		$internal_fields = array(
595
			// Use file_list instead
596 4
			'file'                => 1,
597 4
			'radio'               => 1,
598 4
			'title'               => 1,
599
			// @todo Ajax load wp_editor: http://wordpress.stackexchange.com/questions/51776/how-to-load-wp-editor-through-ajax-jquery
600 4
			'wysiwyg'             => 1,
601 4
			'checkbox'            => 1,
602 4
			'radio_inline'        => 1,
603 4
			'taxonomy_radio'      => 1,
604 4
			'taxonomy_select'     => 1,
605 4
			'taxonomy_multicheck' => 1,
606 4
		);
607
608
		/**
609
		 * Filter field types that are non-repeatable.
610
		 *
611
		 * Note that this does *not* allow overriding the default non-repeatable types.
612
		 *
613
		 * @since 2.1.1
614
		 *
615
		 * @param array $fields Array of fields designated as non-repeatable. Note that the field names are *keys*,
616
		 *                      and not values. The value can be anything, because it is meaningless. Example:
617
		 *                      array( 'my_custom_field' => 1 )
618
		 */
619 4
		$all_fields = array_merge( apply_filters( 'cmb2_non_repeatable_fields', array() ), $internal_fields );
620 4
		return isset( $all_fields[ $type ] );
621
	}
622
623
	/**
624
	 * Escape the value before output. Defaults to 'esc_attr()'
625
	 * @since  1.0.1
626
	 * @param  callable $func       Escaping function (if not esc_attr())
627
	 * @param  mixed    $meta_value Meta value
628
	 * @return mixed                Final value
629
	 */
630 46
	public function escaped_value( $func = 'esc_attr', $meta_value = '' ) {
631
632 46
		if ( null !== $this->escaped_value ) {
633 27
			return $this->escaped_value;
634
		}
635
636 46
		$meta_value = $meta_value ? $meta_value : $this->value();
637
638
		// Check if the field has a registered escaping callback
639 46
		if ( $cb = $this->maybe_callback( 'escape_cb' ) ) {
640
			// Ok, callback is good, let's run it.
641
			return call_user_func( $cb, $meta_value, $this->args(), $this );
642
		}
643
644
		// Or custom escaping filter can be used
645 46
		$esc = apply_filters( "cmb2_types_esc_{$this->type()}", null, $meta_value, $this->args(), $this );
646 46
		if ( null !== $esc ) {
647
			return $esc;
648
		}
649
650 46
		if ( false === $cb || $this->escaping_exception() ) {
651
			// If requesting NO escaping, return meta value
652 5
			return $this->val_or_default( $meta_value );
653
		}
654
655
		// escaping function passed in?
656 41
		$func       = $func ? $func : 'esc_attr';
657 41
		$meta_value = $this->val_or_default( $meta_value );
658
659 41
		if ( is_array( $meta_value ) ) {
660
			foreach ( $meta_value as $key => $value ) {
661
				$meta_value[ $key ] = call_user_func( $func, $value );
662
			}
663
		} else {
664 41
			$meta_value = call_user_func( $func, $meta_value );
665
		}
666
667 41
		$this->escaped_value = $meta_value;
668 41
		return $this->escaped_value;
669
	}
670
671
	/**
672
	 * Return non-empty value or field default if value IS empty
673
	 * @since  2.0.0
674
	 * @param  mixed $meta_value Field value
675
	 * @return mixed             Field value, or default value
676
	 */
677 46
	public function val_or_default( $meta_value ) {
678 46
		return ! CMB2_Utils::isempty( $meta_value ) ? $meta_value : $this->get_default();
679
	}
680
681
	/**
682
	 * Offset a time value based on timezone
683
	 * @since  1.0.0
684
	 * @return string Offset time string
685
	 */
686
	public function field_timezone_offset() {
687
		return CMB2_Utils::timezone_offset( $this->field_timezone() );
688
	}
689
690
	/**
691
	 * Return timezone string
692
	 * @since  1.0.0
693
	 * @return string Timezone string
694
	 */
695
	public function field_timezone() {
696
		$value = '';
697
698
		// Is timezone arg set?
699
		if ( $this->args( 'timezone' ) ) {
700
			$value = $this->args( 'timezone' );
701
		}
702
		// Is there another meta key with a timezone stored as its value we should use?
703
		else if ( $this->args( 'timezone_meta_key' ) ) {
704
			$value = $this->get_data( $this->args( 'timezone_meta_key' ) );
705
		}
706
707
		return $value;
708
	}
709
710
	/**
711
	 * Format the timestamp field value based on the field date/time format arg
712
	 * @since  2.0.0
713
	 * @param  int    $meta_value Timestamp
714
	 * @param  string $format     Either date_format or time_format
715
	 * @return string             Formatted date
716
	 */
717 10
	public function format_timestamp( $meta_value, $format = 'date_format' ) {
718 10
		return date( stripslashes( $this->args( $format ) ), $meta_value );
719
	}
720
721
	/**
722
	 * Return a formatted timestamp for a field
723
	 * @since  2.0.0
724
	 * @param  string $format     Either date_format or time_format
725
	 * @param  string $meta_value Optional meta value to check
726
	 * @return string             Formatted date
727
	 */
728 10
	public function get_timestamp_format( $format = 'date_format', $meta_value = 0 ) {
729 10
		$meta_value = $meta_value ? $meta_value : $this->escaped_value();
730 10
		$meta_value = CMB2_Utils::make_valid_time_stamp( $meta_value );
731
732 10
		if ( empty( $meta_value ) ) {
733
			return '';
734
		}
735
736 10
		return is_array( $meta_value )
737 10
			? array_map( array( $this, 'format_timestamp' ), $meta_value, $format )
738 10
			: $this->format_timestamp( $meta_value, $format );
739
	}
740
741
	/**
742
	 * Get timestamp from text date
743
	 * @since  2.2.0
744
	 * @param  string $value Date value
745
	 * @return mixed         Unix timestamp representing the date.
746
	 */
747
	public function get_timestamp_from_value( $value ) {
748
		return CMB2_Utils::get_timestamp_from_value( $value, $this->args( 'date_format' ) );
749
	}
750
751
	/**
752
	 * Get field render callback and Render the field row
753
	 * @since 1.0.0
754
	 */
755 10
	public function render_field() {
756 10
		$this->render_context = 'edit';
757
758 10
		$this->peform_param_callback( 'render_row_cb' );
759
760
		// For chaining
761 10
		return $this;
762
	}
763
764
	/**
765
	 * Default field render callback
766
	 * @since 2.1.1
767
	 */
768 9
	public function render_field_callback() {
769
770
		// If field is requesting to not be shown on the front-end
771 9
		if ( ! is_admin() && ! $this->args( 'on_front' ) ) {
772
			return;
773
		}
774
775
		// If field is requesting to be conditionally shown
776 9
		if ( ! $this->should_show() ) {
777
			return;
778
		}
779
780 9
		$this->peform_param_callback( 'before_row' );
781
782 9
		printf( "<div class=\"cmb-row %s\" data-fieldtype=\"%s\">\n", $this->row_classes(), $this->type() );
783
784 9
		if ( ! $this->args( 'show_names' ) ) {
785
			echo "\n\t<div class=\"cmb-td\">\n";
786
787
			$this->peform_param_callback( 'label_cb' );
788
789
		} else {
790
791 9
			if ( $this->get_param_callback_result( 'label_cb' ) ) {
792 9
				echo '<div class="cmb-th">', $this->peform_param_callback( 'label_cb' ), '</div>';
793 9
			}
794
795 9
			echo "\n\t<div class=\"cmb-td\">\n";
796
		}
797
798 9
		$this->peform_param_callback( 'before' );
799
800 9
		$field_type = new CMB2_Types( $this );
801 9
		$field_type->render();
802
803 9
		$this->peform_param_callback( 'after' );
804
805 9
		echo "\n\t</div>\n</div>";
806
807 9
		$this->peform_param_callback( 'after_row' );
808
809
		// For chaining
810 9
		return $this;
811
	}
812
813
	/**
814
	 * The default label_cb callback (if not a title field)
815
	 *
816
	 * @since  2.1.1
817
	 * @return string Label html markup
818
	 */
819 9
	public function label() {
820 9
		if ( ! $this->args( 'name' ) ) {
821
			return '';
822
		}
823
824 9
		$style = ! $this->args( 'show_names' ) ? ' style="display:none;"' : '';
825
826 9
		return sprintf( "\n" . '<label%1$s for="%2$s">%3$s</label>' . "\n", $style, $this->id(), $this->args( 'name' ) );
827
	}
828
829
	/**
830
	 * Defines the classes for the current CMB2 field row
831
	 *
832
	 * @since  2.0.0
833
	 * @return string Space concatenated list of classes
834
	 */
835 45
	public function row_classes() {
836
837 45
		$classes = array();
838
839
		/**
840
		 * By default, 'text_url' and 'text' fields get table-like styling
841
		 *
842
		 * @since 2.0.0
843
		 *
844
		 * @param array $field_types The types of fields which should get the 'table-layout' class
845
		 */
846 45
		$repeat_table_rows_types = apply_filters( 'cmb2_repeat_table_row_types', array(
847 45
			'text_url', 'text',
848 45
		) );
849
850
		$conditional_classes = array(
851 45
			'cmb-type-' . str_replace( '_', '-', sanitize_html_class( $this->type() ) ) => true,
852 45
			'cmb2-id-' . str_replace( '_', '-', sanitize_html_class( $this->id() ) )    => true,
853 45
			'cmb-repeat'             => $this->args( 'repeatable' ),
854 45
			'cmb-repeat-group-field' => $this->group,
855 45
			'cmb-inline'             => $this->args( 'inline' ),
856 45
			'table-layout'           => 'edit' === $this->render_context && in_array( $this->type(), $repeat_table_rows_types ),
857 45
		);
858
859 45
		foreach ( $conditional_classes as $class => $condition ) {
860 45
			if ( $condition ) {
861 45
				$classes[] = $class;
862 45
			}
863 45
		}
864
865 45
		if ( $added_classes = $this->args( 'classes' ) ) {
866 1
			$added_classes = is_array( $added_classes ) ? implode( ' ', $added_classes ) : (string) $added_classes;
867 45
		} elseif ( $added_classes = $this->get_param_callback_result( 'classes_cb' ) ) {
868 2
			$added_classes = is_array( $added_classes ) ? implode( ' ', $added_classes ) : (string) $added_classes;
869 2
		}
870
871 45
		if ( $added_classes ) {
872 3
			$classes[] = esc_attr( $added_classes );
873 3
		}
874
875
		/**
876
		 * Globally filter row classes
877
		 *
878
		 * @since 2.0.0
879
		 *
880
		 * @param string            $classes Space-separated list of row classes
881
		 * @param CMB2_Field object $field   This field object
882
		 */
883 45
		return apply_filters( 'cmb2_row_classes', implode( ' ', $classes ), $this );
884
	}
885
886
887
888
	/**
889
	 * Get field display callback and render the display value in the column.
890
	 * @since 2.2.2
891
	 */
892 33
	public function render_column() {
893 33
		$this->render_context = 'display';
894
895 33
		$this->peform_param_callback( 'display_cb' );
896
897
		// For chaining
898 33
		return $this;
899
	}
900
901
	/**
902
	 * Default callback to outputs field value in a display format.
903
	 * @since 2.2.2
904
	 */
905 33
	public function display_value_callback() {
906
		// If field is requesting to be conditionally shown
907 33
		if ( ! $this->should_show() ) {
908
			return;
909
		}
910
911 33
		$display = new CMB2_Field_Display( $this );
912
913
		/**
914
		 * A filter to bypass the default display.
915
		 *
916
		 * The dynamic portion of the hook name, $this->type(), refers to the field type.
917
		 *
918
		 * Passing a non-null value to the filter will short-circuit the default display.
919
		 *
920
		 * @param bool|mixed         $pre_output Default null value.
921
		 * @param CMB2_Field         $field      This field object.
922
		 * @param CMB2_Field_Display $display    The `CMB2_Field_Display` object.
923
		 */
924 33
		$pre_output = apply_filters( "cmb2_pre_field_display_{$this->type()}", null, $this, $display );
925
926 33
		if ( null !== $pre_output ) {
927
			echo $pre_output;
928
			return;
929
		}
930
931 33
		$this->peform_param_callback( 'before_display_wrap' );
932
933 33
		printf( "<div class=\"cmb-column %s\" data-fieldtype=\"%s\">\n", $this->row_classes( 'display' ), $this->type() );
0 ignored issues
show
Unused Code introduced by
The call to CMB2_Field::row_classes() has too many arguments starting with 'display'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
934
935 33
		$this->peform_param_callback( 'before_display' );
936
937 33
		CMB2_Field_Display::get( $this )->display();
938
939 33
		$this->peform_param_callback( 'after_display' );
940
941 33
		echo "\n</div>";
942
943 33
		$this->peform_param_callback( 'after_display_wrap' );
944
945
		// For chaining
946 33
		return $this;
947
	}
948
949
	/**
950
	 * Replaces a hash key - {#} - with the repeatable index
951
	 * @since  1.2.0
952
	 * @param  string $value Value to update
953
	 * @return string        Updated value
954
	 */
955 2
	public function replace_hash( $value ) {
956
		// Replace hash with 1 based count
957 2
		return str_replace( '{#}', ( $this->index + 1 ), $value );
958
	}
959
960
	/**
961
	 * Retrieve text parameter from field's text array (if it has one), or use fallback text
962
	 * For back-compatibility, falls back to checking the options array.
963
	 *
964
	 * @since  2.2.2
965
	 * @param  string  $text_key Key in field's text array
966
	 * @param  string  $fallback Fallback text
967
	 * @return string            Text
968
	 */
969 8
	public function get_string( $text_key, $fallback ) {
970
		// If null, populate with our field strings values.
971 8
		if ( null === $this->strings ) {
972 8
			$this->strings = (array) $this->args['text'];
973
974 8 View Code Duplication
			if ( is_callable( $this->args['text_cb'] ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
975
				$strings = call_user_func( $this->args['text_cb'], $this );
976
977
				if ( $strings && is_array( $strings ) ) {
978
					$this->strings += $strings;
979
				}
980
			}
981 8
		}
982
983
		// If we have that string value, send it back.
984 8
		if ( isset( $this->strings[ $text_key ] ) ) {
985 1
			return $this->strings[ $text_key ];
986
		}
987
988
		// Check options for back-compat.
989 8
		$string = $this->options( $text_key );
990
991 8
		return $string ? $string : $fallback;
0 ignored issues
show
Bug Compatibility introduced by
The expression $string ? $string : $fallback; of type array|string adds the type array to the return on line 991 which is incompatible with the return type documented by CMB2_Field::get_string of type string.
Loading history...
992
	}
993
994
	/**
995
	 * Retrieve options args. Calls options_cb if it exists.
996
	 * @since  2.0.0
997
	 * @param  string  $key Specific option to retrieve
998
	 * @return array        Array of options
999
	 */
1000 31
	public function options( $key = '' ) {
1001 31
		if ( ! empty( $this->field_options ) ) {
1002 5
			if ( $key ) {
1003 5
				return array_key_exists( $key, $this->field_options ) ? $this->field_options[ $key ] : false;
1004
			}
1005
1006 1
			return $this->field_options;
1007
		}
1008
1009 31
		$this->field_options = (array) $this->args['options'];
1010
1011 31 View Code Duplication
		if ( is_callable( $this->args['options_cb'] ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1012 1
			$options = call_user_func( $this->args['options_cb'], $this );
1013
1014 1
			if ( $options && is_array( $options ) ) {
1015 1
				$this->field_options = $options + $this->field_options;
1016 1
			}
1017 1
		}
1018
1019 31
		if ( $key ) {
1020 10
			return array_key_exists( $key, $this->field_options ) ? $this->field_options[ $key ] : false;
1021
		}
1022
1023 23
		return $this->field_options;
1024
	}
1025
1026
	/**
1027
	 * Store JS dependencies as part of the field args.
1028
	 * @since 2.2.0
1029
	 * @param array $dependencies Dependies to register for this field.
1030
	 */
1031 12
	public function add_js_dependencies( $dependencies = array() ) {
1032 12
		foreach ( (array) $dependencies as $dependency ) {
1033 12
			$this->args['js_dependencies'][ $dependency ] = $dependency;
1034 12
		}
1035
1036 12
		CMB2_JS::add_dependencies( $dependencies );
1037 12
	}
1038
1039
	/**
1040
	 * Get CMB2_Field default value, either from default param or default_cb param.
1041
	 *
1042
	 * @since  0.2.2
1043
	 *
1044
	 * @return mixed  Default field value
1045
	 */
1046 33
	public function get_default() {
1047 33
		if ( null !== $this->args['default'] ) {
1048 6
			return $this->args['default'];
1049
		}
1050
1051 32
		$param = is_callable( $this->args['default_cb'] ) ? 'default_cb' : 'default';
1052 32
		$default = $this->get_param_callback_result( $param );
1053
1054
		// Allow a filter override of the default value
1055 32
		$this->args['default'] = apply_filters( 'cmb2_default_filter', $default, $this );
1056
1057 32
		return $this->args['default'];
1058
	}
1059
1060
	/**
1061
	 * Fills in empty field parameters with defaults
1062
	 * @since 1.1.0
1063
	 * @param array $args Metabox field config array
1064
	 * @param array       Modified field config array.
1065
	 */
1066 109
	public function _set_field_defaults( $args ) {
1067
1068
		// Set up blank or default values for empty ones
1069 109
		$args = wp_parse_args( $args, array(
1070 109
			'type'              => '',
1071 109
			'name'              => '',
1072 109
			'desc'              => '',
1073 109
			'before'            => '',
1074 109
			'after'             => '',
1075 109
			'options'           => array(),
1076 109
			'options_cb'        => '',
1077 109
			'text'              => array(),
1078 109
			'text_cb'           => '',
1079 109
			'attributes'        => array(),
1080 109
			'protocols'         => null,
1081 109
			'default'           => null,
1082 109
			'default_cb'        => '',
1083 109
			'classes'           => null,
1084 109
			'classes_cb'        => '',
1085 109
			'select_all_button' => true,
1086 109
			'multiple'          => false,
1087 109
			'repeatable'        => isset( $args['type'] ) && 'group' == $args['type'],
1088 109
			'inline'            => false,
1089 109
			'on_front'          => true,
1090 109
			'show_names'        => true,
1091 109
			'save_field'        => true, // Will not save if false
1092 109
			'date_format'       => 'm\/d\/Y',
1093 109
			'time_format'       => 'h:i A',
1094 109
			'description'       => isset( $args['desc'] ) ? $args['desc'] : '',
1095 109
			'preview_size'      => 'file' == $args['type'] ? array( 350, 350 ) : array( 50, 50 ),
1096 109
			'render_row_cb'     => array( $this, 'render_field_callback' ),
1097 109
			'display_cb'        => array( $this, 'display_value_callback' ),
1098 109
			'label_cb'          => 'title' != $args['type'] ? array( $this, 'label' ) : '',
1099 109
			'column'            => false,
1100 109
			'js_dependencies'   => array(),
1101 109
		) );
1102
1103
		/*
1104
		 * Deprecated usage:
1105
		 *
1106
		 * 'std' -- use 'default' (no longer works)
1107
		 * 'row_classes' -- use 'class', or 'class_cb'
1108
		 * 'default' -- as callback (use default_cb)
1109
		 */
1110 109
		$args = $this->convert_deprecated_params( $args );
1111
1112 109
		$args['repeatable'] = $args['repeatable'] && ! $this->repeatable_exception( $args['type'] );
1113 109
		$args['inline']     = $args['inline'] || false !== stripos( $args['type'], '_inline' );
1114
1115 109
		$args['options']    = 'group' == $args['type'] ? wp_parse_args( $args['options'], array(
1116 3
			'add_button'    => esc_html__( 'Add Group', 'cmb2' ),
1117 3
			'remove_button' => esc_html__( 'Remove Group', 'cmb2' ),
1118 109
		) ) : $args['options'];
1119
1120 109
		$args['_id']        = $args['id'];
1121 109
		$args['_name']      = $args['id'];
1122
1123 109
		if ( $this->group ) {
1124
1125 3
			$args['id']    = $this->group->args( 'id' ) . '_' . $this->group->index . '_' . $args['id'];
1126 3
			$args['_name'] = $this->group->args( 'id' ) . '[' . $this->group->index . '][' . $args['_name'] . ']';
1127 3
		}
1128
1129 109
		if ( 'wysiwyg' == $args['type'] ) {
1130 1
			$args['id'] = strtolower( str_ireplace( '-', '_', $args['id'] ) );
1131 1
			$args['options']['textarea_name'] = $args['_name'];
1132 1
		}
1133
1134 109
		if( 'text_money' === $args['type'] ) {
1135 3
 			$args['before_field'] = apply_filters( 'cmb2_text_money_before_field_filter', ( isset($args['before_field']) ? $args['before_field'] : '$' ), $this );
1136 3
 		}
1137
1138 109
		$option_types = apply_filters( 'cmb2_all_or_nothing_types', array( 'select', 'radio', 'radio_inline', 'taxonomy_select', 'taxonomy_radio', 'taxonomy_radio_inline' ), $this );
1139
1140 109
		if ( in_array( $args['type'], $option_types, true ) ) {
1141
1142 16
			$args['show_option_none'] = isset( $args['show_option_none'] ) ? $args['show_option_none'] : null;
1143 16
			$args['show_option_none'] = true === $args['show_option_none'] ? esc_html__( 'None', 'cmb2' ) : $args['show_option_none'];
1144
1145 16
			if ( null === $args['show_option_none'] ) {
1146 15
				$off_by_default = in_array( $args['type'], array( 'select', 'radio', 'radio_inline' ), true );
1147 15
				$args['show_option_none'] = $off_by_default ? false : esc_html__( 'None', 'cmb2' );
1148 15
			}
1149
1150 16
		}
1151
1152 109
		$args['has_supporting_data'] = in_array(
1153 109
			$args['type'],
1154
			array(
1155
				// CMB2_Sanitize::_save_file_id_value()/CMB2_Sanitize::_get_group_file_value_array()
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1156 109
				'file',
1157
				// See CMB2_Sanitize::_save_utc_value()
0 ignored issues
show
Unused Code Comprehensibility introduced by
38% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1158 109
				'text_datetime_timestamp_timezone',
1159 109
			),
1160
			true
1161 109
		);
1162
1163 109
		return $args;
1164
	}
1165
1166
	/**
1167
	 * Get default field arguments specific to this CMB2 object.
1168
	 * @since  2.2.0
1169
	 * @param  array      $field_args  Metabox field config array.
1170
	 * @param  CMB2_Field $field_group (optional) CMB2_Field object (group parent)
1171
	 * @return array                   Array of field arguments.
1172
	 */
1173 5
	protected function get_default_args( $field_args, $field_group = null ) {
1174 5
		$args = parent::get_default_args( array(), $this->group );
1175
1176 5
		if ( isset( $field_args['field_args'] ) ) {
1177
			$args = wp_parse_args( $field_args, $args );
1178
		} else {
1179 5
			$args['field_args'] = wp_parse_args( $field_args, $this->args );
1180
		}
1181
1182 5
		return $args;
1183
	}
1184
1185
	/**
1186
	 * Returns a cloned version of this field object with, but with
1187
	 * modified/overridden field arguments.
1188
	 *
1189
	 * @since  2.2.2
1190
	 * @param  array  $field_args Array of field arguments, or entire array of
1191
	 *                            arguments for CMB2_Field
1192
	 *
1193
	 * @return CMB2_Field         The new CMB2_Field instance.
1194
	 */
1195 5
	public function get_field_clone( $field_args ) {
1196 5
		return $this->get_new_field( $field_args );
1197
	}
1198
1199
	/**
1200
	 * Returns the CMB2 instance this field is registered to.
1201
	 *
1202
	 * @since  2.2.2
1203
	 *
1204
	 * @return CMB2|WP_Error If new CMB2_Field is called without cmb_id arg, returns error.
1205
	 */
1206 1
	public function get_cmb() {
1207 1
		if ( ! $this->cmb_id ) {
1208
			return new WP_Error( 'no_cmb_id', esc_html__( 'Sorry, this field does not have a cmb_id specified.', 'cmb2' ) );
1209
		}
1210
1211 1
		return cmb2_get_metabox( $this->cmb_id, $this->object_id, $this->object_type );
1212
	}
1213
1214
	/**
1215
	 * Converts deprecated field parameters to the current/proper parameter, and throws a deprecation notice.
1216
	 * @since 2.2.3
1217
	 * @param array $args Metabox field config array.
1218
	 * @param array       Modified field config array.
1219
	 */
1220 109
	protected function convert_deprecated_params( $args ) {
1221
1222 109
		if ( isset( $args['row_classes'] ) ) {
1223
1224 2
			$this->deprecated_param( __CLASS__ . '::__construct()', '2.2.3', self::DEPRECATED_PARAM, 'row_classes', 'classes' );
1225
1226
			// row_classes param could be a callback
1227 2
			if ( is_callable( $args['row_classes'] ) ) {
1228
1229 1
				$this->deprecated_param( __CLASS__ . '::__construct()', '2.2.3', self::DEPRECATED_CB_PARAM, 'row_classes', 'classes_cb' );
1230
1231 1
				$args['classes_cb'] = $args['row_classes'];
1232 1
				$args['classes'] = null;
1233 1
			} else {
1234
1235
1236 1
				$args['classes'] = $args['row_classes'];
1237
			}
1238
1239 2
			unset( $args['row_classes'] );
1240 2
		}
1241
1242
1243
		// default param can be passed a callback as well
1244 109 View Code Duplication
		if ( is_callable( $args['default'] ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1245
1246
			$this->deprecated_param( __CLASS__ . '::__construct()', '2.2.3', self::DEPRECATED_CB_PARAM, 'default', 'default_cb' );
1247
1248
			$args['default_cb'] = $args['default'];
1249
			$args['default'] = null;
1250
		}
1251
1252
		// options param can be passed a callback as well
1253 109 View Code Duplication
		if ( is_callable( $args['options'] ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1254
1255
			$this->deprecated_param( __CLASS__ . '::__construct()', '2.2.3', self::DEPRECATED_CB_PARAM, 'options', 'options_cb' );
1256
1257
			$args['options_cb'] = $args['options'];
1258
			$args['options'] = array();
1259
		}
1260
1261 109
		return $args;
1262
	}
1263
1264
}
1265