Completed
Push — trunk ( 4bf362...177664 )
by
unknown
493:49 queued 491:11
created

CMB2_Field::get_data()   C

Complexity

Conditions 9
Paths 45

Size

Total Lines 63
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 90

Importance

Changes 0
Metric Value
cc 9
eloc 17
nc 45
nop 2
dl 0
loc 63
ccs 0
cts 10
cp 0
crap 90
rs 6.6149
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
	 *
22
	 * @var   string
23
	 * @since 2.2.3
24
	 */
25
	protected $properties_name = 'args';
26
27
	/**
28
	 * Field arguments
29
	 *
30
	 * @var   mixed
31
	 * @since 1.1.0
32
	 */
33
	public $args = array();
34
35
	/**
36
	 * Field group object or false (if no group)
37
	 *
38
	 * @var   mixed
39
	 * @since 1.1.0
40
	 */
41
	public $group = false;
42
43
	/**
44
	 * Field meta value
45
	 *
46
	 * @var   mixed
47
	 * @since 1.1.0
48
	 */
49 46
	public $value = null;
50
51 46
	/**
52
	 * Field meta value
53
	 *
54
	 * @var   mixed
55
	 * @since 1.1.0
56 46
	 */
57 46
	public $escaped_value = null;
58 46
59
	/**
60
	 * Grouped Field's current numeric index during the save process
61 46
	 *
62
	 * @var   mixed
63
	 * @since 2.0.0
64
	 */
65
	public $index = 0;
66
67
	/**
68
	 * Array of field options
69
	 *
70
	 * @var   array
71
	 * @since 2.0.0
72
	 */
73
	protected $field_options = array();
74
75
	/**
76
	 * Array of provided field text strings
77
	 *
78 46
	 * @var   array
79
	 * @since 2.0.0
80
	 */
81
	protected $strings;
82
83
	/**
84
	 * The field's render context. In most cases, 'edit', but can be 'display'.
85
	 *
86
	 * @var   string
87
	 * @since 2.2.2
88
	 */
89
	public $render_context = 'edit';
90
91
	/**
92
	 * All CMB2_Field callable field arguments.
93
	 * Can be used to determine if a field argument is callable.
94
	 *
95
	 * @var array
96
	 */
97 46
	public static $callable_fields = array(
98
		'default_cb',
99
		'classes_cb',
100 46
		'options_cb',
101 46
		'text_cb',
102 46
		'label_cb',
103 46
		'render_row_cb',
104
		'display_cb',
105
		'before_group',
106
		'before_group_row',
107
		'before_row',
108
		'before',
109
		'before_field',
110
		'after_field',
111
		'after',
112 38
		'after_row',
113 38
		'after_group_row',
114 38
		'after_group',
115
	);
116
117
	/**
118
	 * Constructs our field object
119
	 *
120
	 * @since 1.1.0
121
	 * @param array $args Field arguments
122
	 */
123 46
	public function __construct( $args ) {
124 46
125 46
		if ( ! empty( $args['group_field'] ) ) {
126
			$this->group       = $args['group_field'];
127
			$this->object_id   = $this->group->object_id;
128
			$this->object_type = $this->group->object_type;
129
			$this->cmb_id      = $this->group->cmb_id;
130
		} else {
131
			$this->object_id   = isset( $args['object_id'] ) && '_' !== $args['object_id'] ? $args['object_id'] : 0;
132
			$this->object_type = isset( $args['object_type'] ) ? $args['object_type'] : 'post';
133
134
			if ( isset( $args['cmb_id'] ) ) {
135 46
				$this->cmb_id = $args['cmb_id'];
136 46
			}
137 46
		}
138
139
		$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...
140 46
141
		if ( $this->object_id ) {
142
			$this->value = $this->get_data();
143
		}
144
	}
145
146
	/**
147
	 * Non-existent methods fallback to checking for field arguments of the same name
148
	 *
149 37
	 * @since  1.1.0
150 37
	 * @param  string $name     Method name
151
	 * @param  array  $arguments Array of passed-in arguments
152
	 * @return mixed             Value of field argument
153
	 */
154
	public function __call( $name, $arguments ) {
155
		if ( 'string' === $name ) {
156
			return call_user_func_array( array( $this, 'get_string' ), $arguments );
157
		}
158
159
		$key = isset( $arguments[0] ) ? $arguments[0] : false;
160 46
		return $this->args( $name, $key );
161 46
	}
162 46
163 46
	/**
164
	 * Retrieves the field id
165 46
	 *
166
	 * @since  1.1.0
167
	 * @param  boolean $raw Whether to retrieve pre-modidifed id
168
	 * @return string       Field id
169
	 */
170
	public function id( $raw = false ) {
171
		$id = $raw ? '_id' : 'id';
172
		return $this->args( $id );
173
	}
174 46
175 46
	/**
176
	 * Get a field argument
177 46
	 *
178
	 * @since  1.1.0
179
	 * @param  string $key  Argument to check
180
	 * @param  string $_key Sub argument to check
181 46
	 * @return mixed        Argument value or false if non-existent
182
	 */
183 46
	public function args( $key = '', $_key = '' ) {
184 46
		$arg = $this->_data( 'args', $key );
185 46
186
		if ( in_array( $key, array( 'default', 'default_cb' ), true ) ) {
187 46
188
			$arg = $this->get_default();
189
190
		} elseif ( $_key ) {
191
192 46
			$arg = isset( $arg[ $_key ] ) ? $arg[ $_key ] : false;
193
		}
194
195
		return $arg;
196
	}
197
198
	/**
199
	 * Retrieve a portion of a field property
200
	 *
201
	 * @since  1.1.0
202
	 * @param  string $var Field property to check
203
	 * @param  string $key Field property array key to check
204
	 * @return mixed        Queried property value or false
205
	 */
206
	public function _data( $var, $key = '' ) {
207
		$vars = $this->{$var};
208
		if ( $key ) {
209
			return array_key_exists( $key, $vars ) ? $vars[ $key ] : false;
210
		}
211
		return $vars;
212
	}
213
214
	/**
215
	 * Get Field's value
216
	 *
217
	 * @since  1.1.0
218
	 * @param  string $key If value is an array, is used to get array key->value
219
	 * @return mixed       Field value or false if non-existent
220
	 */
221
	public function value( $key = '' ) {
222
		return $this->_data( 'value', $key );
223
	}
224
225
	/**
226
	 * Retrieves metadata/option data
227
	 *
228
	 * @since  1.0.1
229
	 * @param  string $field_id Meta key/Option array key
230
	 * @param  array  $args     Override arguments
231
	 * @return mixed            Meta/Option value
232
	 */
233
	public function get_data( $field_id = '', $args = array() ) {
234
		if ( $field_id ) {
235
			$args['field_id'] = $field_id;
236
		} elseif ( $this->group ) {
237
			$args['field_id'] = $this->group->id();
238
		}
239
240
		$a = $this->data_args( $args );
241
242
		/**
243
		 * Filter whether to override getting of meta value.
244
		 * Returning a non 'cmb2_field_no_override_val' value
245
		 * will effectively short-circuit the value retrieval.
246
		 *
247
		 * @since 2.0.0
248
		 *
249
		 * @param mixed $value     The value get_metadata() should
250
		 *                         return - a single metadata value,
251
		 *                         or an array of values.
252
		 *
253
		 * @param int   $object_id Object ID.
254
		 *
255
		 * @param array $args {
256
		 *     An array of arguments for retrieving data
257
		 *
258
		 *     @type string $type     The current object type
259
		 *     @type int    $id       The current object ID
260
		 *     @type string $field_id The ID of the field being requested
261
		 *     @type bool   $repeat   Whether current field is repeatable
262
		 *     @type bool   $single   Whether current field is a single database row
263
		 * }
264
		 *
265
		 * @param CMB2_Field object $field This field object
266
		 */
267
		$data = apply_filters( 'cmb2_override_meta_value', 'cmb2_field_no_override_val', $this->object_id, $a, $this );
268
269
		/**
270
		 * Filter and parameters are documented for 'cmb2_override_meta_value' filter (above).
271
		 *
272
		 * The dynamic portion of the hook, $field_id, refers to the current
273
		 * field id paramater. Returning a non 'cmb2_field_no_override_val' value
274
		 * will effectively short-circuit the value retrieval.
275
		 *
276
		 * @since 2.0.0
277
		 */
278
		$data = apply_filters( "cmb2_override_{$a['field_id']}_meta_value", $data, $this->object_id, $a, $this );
279
280
		// If no override, get value normally
281
		if ( 'cmb2_field_no_override_val' === $data ) {
282
			$data = 'options-page' === $a['type']
283
				? cmb2_options( $a['id'] )->get( $a['field_id'] )
284
				: get_metadata( $a['type'], $a['id'], $a['field_id'], ( $a['single'] || $a['repeat'] ) );
285
		}
286
287
		if ( $this->group ) {
288
289
			$data = is_array( $data ) && isset( $data[ $this->group->index ][ $this->args( '_id' ) ] )
290
				? $data[ $this->group->index ][ $this->args( '_id' ) ]
291
				: false;
292
		}
293
294
		return $data;
295
	}
296
297
	/**
298
	 * Updates metadata/option data
299
	 *
300
	 * @since  1.0.1
301
	 * @param  mixed $new_value Value to update data with
302
	 * @param  bool  $single    Whether data is an array (add_metadata)
303
	 */
304
	public function update_data( $new_value, $single = true ) {
305
		$a = $this->data_args( array( 'single' => $single ) );
306
307
		$a['value'] = $a['repeat'] ? array_values( $new_value ) : $new_value;
308
309
		/**
310
		 * Filter whether to override saving of meta value.
311
		 * Returning a non-null value will effectively short-circuit the function.
312
		 *
313
		 * @since 2.0.0
314
		 *
315
		 * @param null|bool $check  Whether to allow updating metadata for the given type.
316
		 *
317
		 * @param array $args {
318
		 *     Array of data about current field including:
319
		 *
320
		 *     @type string $value    The value to set
321
		 *     @type string $type     The current object type
322
		 *     @type int    $id       The current object ID
323
		 *     @type string $field_id The ID of the field being updated
324
		 *     @type bool   $repeat   Whether current field is repeatable
325
		 *     @type bool   $single   Whether current field is a single database row
326
		 * }
327
		 *
328
		 * @param array $field_args All field arguments
329
		 *
330
		 * @param CMB2_Field object $field This field object
331
		 */
332
		$override = apply_filters( 'cmb2_override_meta_save', null, $a, $this->args(), $this );
333
334
		/**
335
		 * Filter and parameters are documented for 'cmb2_override_meta_save' filter (above).
336
		 *
337
		 * The dynamic portion of the hook, $a['field_id'], refers to the current
338
		 * field id paramater. Returning a non-null value
339
		 * will effectively short-circuit the function.
340
		 *
341
		 * @since 2.0.0
342
		 */
343
		$override = apply_filters( "cmb2_override_{$a['field_id']}_meta_save", $override, $a, $this->args(), $this );
344
345
		// If override, return that
346
		if ( null !== $override ) {
347
			return $override;
348
		}
349
350 46
		// Options page handling (or temp data store)
351 46
		if ( 'options-page' === $a['type'] || empty( $a['id'] ) ) {
352 46
			return cmb2_options( $a['id'] )->update( $a['field_id'], $a['value'], false, $a['single'] );
353 46
		}
354 46
355 46
		// Add metadata if not single
356 46
		if ( ! $a['single'] ) {
357 46
			return add_metadata( $a['type'], $a['id'], $a['field_id'], $a['value'], false );
358 46
		}
359
360
		// Delete meta if we have an empty array
361
		if ( is_array( $a['value'] ) && empty( $a['value'] ) ) {
362
			return delete_metadata( $a['type'], $a['id'], $a['field_id'], $this->value );
363
		}
364
365
		// Update metadata
366
		return update_metadata( $a['type'], $a['id'], $a['field_id'], $a['value'] );
367
	}
368
369
	/**
370
	 * Removes/updates metadata/option data
371
	 *
372
	 * @since  1.0.1
373
	 * @param  string $old Old value
374
	 */
375
	public function remove_data( $old = '' ) {
376
		$a = $this->data_args( array( 'old' => $old ) );
377
378
		/**
379
		 * Filter whether to override removing of meta value.
380
		 * Returning a non-null value will effectively short-circuit the function.
381
		 *
382
		 * @since 2.0.0
383
		 *
384
		 * @param null|bool $delete Whether to allow metadata deletion of the given type.
385
		 * @param array $args       Array of data about current field including:
386
		 *                              'type'     : Current object type
387
		 *                              'id'       : Current object ID
388
		 *                              'field_id' : Current Field ID
389
		 *                              'repeat'   : Whether current field is repeatable
390
		 *                              'single'   : Whether to save as a
391
		 *                              					single meta value
392
		 * @param array $field_args All field arguments
393
		 * @param CMB2_Field object $field This field object
394
		 */
395
		$override = apply_filters( 'cmb2_override_meta_remove', null, $a, $this->args(), $this );
396
397
		/**
398
		 * Filter whether to override removing of meta value.
399
		 *
400
		 * The dynamic portion of the hook, $a['field_id'], refers to the current
401
		 * field id paramater. Returning a non-null value
402
		 * will effectively short-circuit the function.
403
		 *
404
		 * @since 2.0.0
405
		 *
406
		 * @param null|bool $delete Whether to allow metadata deletion of the given type.
407
		 * @param array $args       Array of data about current field including:
408
		 *                              'type'     : Current object type
409
		 *                              'id'       : Current object ID
410
		 *                              'field_id' : Current Field ID
411
		 *                              'repeat'   : Whether current field is repeatable
412
		 *                              'single'   : Whether to save as a
413
		 *                              					single meta value
414
		 * @param array $field_args All field arguments
415
		 * @param CMB2_Field object $field This field object
416
		 */
417
		$override = apply_filters( "cmb2_override_{$a['field_id']}_meta_remove", $override, $a, $this->args(), $this );
418
419
		// If no override, remove as usual
420
		if ( null !== $override ) {
421
			return $override;
422
		} // Option page handling
423
		elseif ( 'options-page' === $a['type'] || empty( $a['id'] ) ) {
424
			return cmb2_options( $a['id'] )->remove( $a['field_id'] );
425
		}
426
427
		// Remove metadata
428
		return delete_metadata( $a['type'], $a['id'], $a['field_id'], $old );
429 39
	}
430 39
431 39
	/**
432 38
	 * Data variables for get/set data methods
433
	 *
434
	 * @since  1.1.0
435
	 * @param  array $args Override arguments
436 7
	 * @return array       Updated arguments
437
	 */
438
	public function data_args( $args = array() ) {
439 7
		$args = wp_parse_args( $args, array(
440 4
			'type'     => $this->object_type,
441
			'id'       => $this->object_id,
442
			'field_id' => $this->id( true ),
443 3
			'repeat'   => $this->args( 'repeatable' ),
444 2
			'single'   => ! $this->args( 'multiple' ),
445
		) );
446 3
		return $args;
447
	}
448
449
	/**
450
	 * Checks if field has a registered sanitization callback
451
	 *
452
	 * @since  1.0.1
453 37
	 * @param  mixed $meta_value Meta value
454
	 * @return mixed             Possibly sanitized meta value
455 37
	 */
456 37
	public function sanitization_cb( $meta_value ) {
457 37
458 37
		if ( $this->args( 'repeatable' ) && is_array( $meta_value ) ) {
459 37
			// Remove empties
460
			$meta_value = array_filter( $meta_value );
461
		}
462
463
		// Check if the field has a registered validation callback
464
		$cb = $this->maybe_callback( 'sanitization_cb' );
465
		if ( false === $cb ) {
466
			// If requesting NO validation, return meta value
467
			return $meta_value;
468 1
		} elseif ( $cb ) {
469
			// Ok, callback is good, let's run it.
470 1
			return call_user_func( $cb, $meta_value, $this->args(), $this );
471 1
		}
472 1
473 1
		$sanitizer = new CMB2_Sanitize( $this, $meta_value );
474 1
475
		/**
476 1
		 * Filter the value before it is saved.
477 1
		 *
478 1
		 * The dynamic portion of the hook name, $this->type(), refers to the field type.
479 1
		 *
480 1
		 * Passing a non-null value to the filter will short-circuit saving
481 1
		 * the field value, saving the passed value instead.
482 1
		 *
483
		 * @param bool|mixed $override_value Sanitization/Validation override value to return.
484
		 *                                   Default false to skip it.
485
		 * @param mixed      $value      The value to be saved to this field.
486
		 * @param int        $object_id  The ID of the object where the value will be saved
487
		 * @param array      $field_args The current field's arguments
488
		 * @param object     $sanitizer  This `CMB2_Sanitize` object
489
		 */
490
		$override_value = apply_filters( "cmb2_sanitize_{$this->type()}", null, $sanitizer->value, $this->object_id, $this->args(), $sanitizer );
491
492 37
		if ( null !== $override_value ) {
493
			return $override_value;
494 37
		}
495 16
496
		// Sanitization via 'CMB2_Sanitize'
497
		return $sanitizer->{$this->type()}();
498 37
	}
499
500
	/**
501 37
	 * Process $_POST data to save this field's value
502
	 *
503
	 * @since  2.0.3
504
	 * @param  array $data_to_save $_POST data to check
505
	 * @return array|int|bool                Result of save, false on failure
506
	 */
507 37
	public function save_field_from_data( array $data_to_save ) {
508 37
		$this->data_to_save = $data_to_save;
509
510
		$meta_value = isset( $this->data_to_save[ $this->id( true ) ] )
511
			? $this->data_to_save[ $this->id( true ) ]
512 37
			: null;
513
514 4
		return $this->save_field( $meta_value );
515
	}
516
517
	/**
518 33
	 * Sanitize/store a value to this field
519 33
	 *
520
	 * @since  2.0.0
521 33
	 * @param  array $meta_value Desired value to sanitize/store
522
	 * @return array|int|bool              Result of save. false on failure
523
	 */
524
	public function save_field( $meta_value ) {
525
526 33
		$updated   = false;
527
		$action    = '';
528
		$new_value = $this->sanitization_cb( $meta_value );
529 33
530 33
		if ( ! $this->args( 'save_field' ) ) {
531
532
			// Nothing to see here.
533
			$action = 'disabled';
534
535
		} elseif ( $this->args( 'multiple' ) && ! $this->args( 'repeatable' ) && ! $this->group ) {
536
537
			$this->remove_data();
538 1
			$count = 0;
539 1
540
			if ( ! empty( $new_value ) ) {
541
				foreach ( $new_value as $add_new ) {
542
					if ( $this->update_data( $add_new, false ) ) {
543
						$count++;
544
					}
545
				}
546
			}
547 1
548
			$updated = $count ? $count : false;
549
			$action  = 'repeatable';
550 1
551
		} elseif ( ! CMB2_Utils::isempty( $new_value ) && $new_value !== $this->get_data() ) {
552
			$updated = $this->update_data( $new_value );
553
			$action  = 'updated';
554 1
		} elseif ( CMB2_Utils::isempty( $new_value ) ) {
555
			$updated = $this->remove_data();
556
			$action  = 'removed';
557
		}
558 1
559
		if ( $updated ) {
560
			$this->value = $this->get_data();
561
			$this->escaped_value = null;
562
		}
563
564
		$field_id = $this->id( true );
565
566
		/**
567
		 * Hooks after save field action.
568 5
		 *
569 5
		 * @since 2.2.0
570
		 *
571
		 * @param string            $field_id the current field id paramater.
572
		 * @param bool              $updated  Whether the metadata update action occurred.
573
		 * @param string            $action   Action performed. Could be "repeatable", "updated", or "removed".
574
		 * @param CMB2_Field object $field    This field object
575
		 */
576
		do_action( 'cmb2_save_field', $field_id, $updated, $action, $this );
577
578 5
		/**
579 5
		 * Hooks after save field action.
580 5
		 *
581
		 * The dynamic portion of the hook, $field_id, refers to the
582 5
		 * current field id paramater.
583
		 *
584
		 * @since 2.2.0
585
		 *
586 5
		 * @param bool              $updated Whether the metadata update action occurred.
587 5
		 * @param string            $action  Action performed. Could be "repeatable", "updated", or "removed".
588 5
		 * @param CMB2_Field object $field   This field object
589
		 */
590
		do_action( "cmb2_save_field_{$field_id}", $updated, $action, $this );
591
592
		return $updated;
593
	}
594
595 5
	/**
596
	 * Determine if current type is exempt from escaping
597
	 *
598 5
	 * @since  1.1.0
599
	 * @return bool  True if exempt
600
	 */
601
	public function escaping_exception() {
602
		// These types cannot be escaped
603 5
		return in_array( $this->type(), array(
604
			'file_list',
605
			'multicheck',
606
			'text_datetime_timestamp_timezone',
607 5
		) );
608
	}
609 5
610
	/**
611 5
	 * Determine if current type cannot be repeatable
612
	 *
613
	 * @since  1.1.0
614
	 * @param  string $type Field type to check
615
	 * @return bool         True if type cannot be repeatable
616
	 */
617
	public function repeatable_exception( $type ) {
618
		// These types cannot be repeatable.
619
		$internal_fields = array(
620 5
			// Use file_list instead
621 5
			'file'                => 1,
622 5
			'radio'               => 1,
623
			'title'               => 1,
624 5
			'wysiwyg'             => 1,
625
			'checkbox'            => 1,
626
			'radio_inline'        => 1,
627 5
			'taxonomy_radio'      => 1,
628
			'taxonomy_select'     => 1,
629 5
			'taxonomy_multicheck' => 1,
630 5
		);
631
632 5
		/**
633
		 * Filter field types that are non-repeatable.
634 5
		 *
635
		 * Note that this does *not* allow overriding the default non-repeatable types.
636 5
		 *
637 5
		 * @since 2.1.1
638
		 *
639
		 * @param array $fields Array of fields designated as non-repeatable. Note that the field names are *keys*,
640
		 *                      and not values. The value can be anything, because it is meaningless. Example:
641
		 *                      array( 'my_custom_field' => 1 )
642
		 */
643
		$all_fields = array_merge( apply_filters( 'cmb2_non_repeatable_fields', array() ), $internal_fields );
644
		return isset( $all_fields[ $type ] );
645 5
	}
646 5
647 5
	/**
648 5
	 * Escape the value before output. Defaults to 'esc_attr()'
649 5
	 *
650
	 * @since  1.0.1
651 5
	 * @param  callable $func       Escaping function (if not esc_attr())
652
	 * @param  mixed    $meta_value Meta value
653 5
	 * @return mixed                Final value
654 5
	 */
655 5
	public function escaped_value( $func = 'esc_attr', $meta_value = '' ) {
656
657 5
		if ( null !== $this->escaped_value ) {
658 3
			return $this->escaped_value;
659 3
		}
660
661 5
		$meta_value = $meta_value ? $meta_value : $this->value();
662
663
		// Check if the field has a registered escaping callback
664
		if ( $cb = $this->maybe_callback( 'escape_cb' ) ) {
665
			// Ok, callback is good, let's run it.
666
			return call_user_func( $cb, $meta_value, $this->args(), $this );
667
		}
668
669
		// Or custom escaping filter can be used
670
		$esc = apply_filters( "cmb2_types_esc_{$this->type()}", null, $meta_value, $this->args(), $this );
671 38
		if ( null !== $esc ) {
672 38
			return $esc;
673
		}
674 2
675 2
		if ( false === $cb || $this->escaping_exception() ) {
676
			// If requesting NO escaping, return meta value
677
			return $this->val_or_default( $meta_value );
678
		}
679 38
680 38
		// escaping function passed in?
681
		$func       = $func ? $func : 'esc_attr';
682
		$meta_value = $this->val_or_default( $meta_value );
683
684
		if ( is_array( $meta_value ) ) {
685
			foreach ( $meta_value as $key => $value ) {
686
				$meta_value[ $key ] = call_user_func( $func, $value );
687
			}
688
		} else {
689
			$meta_value = call_user_func( $func, $meta_value );
690
		}
691
692
		$this->escaped_value = $meta_value;
693
		return $this->escaped_value;
694
	}
695
696
	/**
697
	 * Return non-empty value or field default if value IS empty
698
	 *
699 14
	 * @since  2.0.0
700 14
	 * @param  mixed $meta_value Field value
701 5
	 * @return mixed             Field value, or default value
702 4
	 */
703
	public function val_or_default( $meta_value ) {
704
		return ! CMB2_Utils::isempty( $meta_value ) ? $meta_value : $this->get_default();
705 1
	}
706
707
	/**
708 14
	 * Offset a time value based on timezone
709
	 *
710 14
	 * @since  1.0.0
711 1
	 * @return string Offset time string
712
	 */
713 1
	public function field_timezone_offset() {
714 1
		return CMB2_Utils::timezone_offset( $this->field_timezone() );
715 1
	}
716 1
717
	/**
718 14
	 * Return timezone string
719 4
	 *
720
	 * @since  1.0.0
721
	 * @return string Timezone string
722 11
	 */
723
	public function field_timezone() {
724
		$value = '';
725
726
		// Is timezone arg set?
727
		if ( $this->args( 'timezone' ) ) {
728
			$value = $this->args( 'timezone' );
729
		} // Is there another meta key with a timezone stored as its value we should use?
730 46
		elseif ( $this->args( 'timezone_meta_key' ) ) {
731
			$value = $this->get_data( $this->args( 'timezone_meta_key' ) );
732
		}
733 46
734 46
		return $value;
735 46
	}
736 46
737 46
	/**
738 46
	 * Format the timestamp field value based on the field date/time format arg
739 46
	 *
740 46
	 * @since  2.0.0
741 46
	 * @param  int    $meta_value Timestamp
742 46
	 * @param  string $format     Either date_format or time_format
743 46
	 * @return string             Formatted date
744 46
	 */
745 46
	public function format_timestamp( $meta_value, $format = 'date_format' ) {
746 46
		return date( stripslashes( $this->args( $format ) ), $meta_value );
747 46
	}
748 46
749 46
	/**
750 46
	 * Return a formatted timestamp for a field
751 46
	 *
752 46
	 * @since  2.0.0
753 46
	 * @param  string $format     Either date_format or time_format
754 46
	 * @param  string $meta_value Optional meta value to check
755
	 * @return string             Formatted date
756
	 */
757
	public function get_timestamp_format( $format = 'date_format', $meta_value = 0 ) {
758 46
		$meta_value = $meta_value ? $meta_value : $this->escaped_value();
759
		$meta_value = CMB2_Utils::make_valid_time_stamp( $meta_value );
760 46
761 46
		if ( empty( $meta_value ) ) {
762
			return '';
763
		}
764 46
765
		return is_array( $meta_value )
766
			? array_map( array( $this, 'format_timestamp' ), $meta_value, $format )
767
			: $this->format_timestamp( $meta_value, $format );
768
	}
769 46
770
	/**
771
	 * Get timestamp from text date
772 46
	 *
773
	 * @since  2.2.0
774 46
	 * @param  string $value Date value
775 46
	 * @return mixed         Unix timestamp representing the date.
776
	 */
777 46
	public function get_timestamp_from_value( $value ) {
778
		return CMB2_Utils::get_timestamp_from_value( $value, $this->args( 'date_format' ) );
779
	}
780
781
	/**
782
	 * Get field render callback and Render the field row
783 46
	 *
784 1
	 * @since 1.0.0
785 1
	 */
786 1
	public function render_field() {
787
		$this->render_context = 'edit';
788 46
789
		$this->peform_param_callback( 'render_row_cb' );
790 46
791
		// For chaining
792 2
		return $this;
793 2
	}
794
795 2
	/**
796
	 * Default field render callback
797 46
	 *
798
	 * @since 2.1.1
799
	 */
800
	public function render_field_callback() {
801
802
		// If field is requesting to not be shown on the front-end
803
		if ( ! is_admin() && ! $this->args( 'on_front' ) ) {
804
			return;
805 36
		}
806 36
807
		// If field is requesting to be conditionally shown
808
		if ( ! $this->should_show() ) {
809
			return;
810 1
		}
811
812
		$this->peform_param_callback( 'before_row' );
813
814
		printf( "<div class=\"cmb-row %s\" data-fieldtype=\"%s\">\n", $this->row_classes(), $this->type() );
815
816
		if ( ! $this->args( 'show_names' ) ) {
817
			echo "\n\t<div class=\"cmb-td\">\n";
818
819
			$this->peform_param_callback( 'label_cb' );
820
821
		} else {
822
823
			if ( $this->get_param_callback_result( 'label_cb' ) ) {
824
				echo '<div class="cmb-th">', $this->peform_param_callback( 'label_cb' ), '</div>';
825
			}
826
827
			echo "\n\t<div class=\"cmb-td\">\n";
828
		}
829
830
		$this->peform_param_callback( 'before' );
831
832
		$types = new CMB2_Types( $this );
833
		$types->render();
834
835
		$this->peform_param_callback( 'after' );
836
837
		echo "\n\t</div>\n</div>";
838
839
		$this->peform_param_callback( 'after_row' );
840
841
		// For chaining
842
		return $this;
843
	}
844
845
	/**
846
	 * The default label_cb callback (if not a title field)
847
	 *
848
	 * @since  2.1.1
849
	 * @return string Label html markup
850
	 */
851
	public function label() {
852
		if ( ! $this->args( 'name' ) ) {
853
			return '';
854
		}
855
856
		$style = ! $this->args( 'show_names' ) ? ' style="display:none;"' : '';
857
858
		return sprintf( "\n" . '<label%1$s for="%2$s">%3$s</label>' . "\n", $style, $this->id(), $this->args( 'name' ) );
859
	}
860
861
	/**
862
	 * Defines the classes for the current CMB2 field row
863
	 *
864
	 * @since  2.0.0
865
	 * @return string Space concatenated list of classes
866
	 */
867
	public function row_classes() {
868
869
		$classes = array();
870
871
		/**
872
		 * By default, 'text_url' and 'text' fields get table-like styling
873
		 *
874
		 * @since 2.0.0
875
		 *
876
		 * @param array $field_types The types of fields which should get the 'table-layout' class
877
		 */
878
		$repeat_table_rows_types = apply_filters( 'cmb2_repeat_table_row_types', array(
879
			'text_url',
880
			'text',
881
		) );
882
883
		$conditional_classes = array(
884
			'cmb-type-' . str_replace( '_', '-', sanitize_html_class( $this->type() ) ) => true,
885
			'cmb2-id-' . str_replace( '_', '-', sanitize_html_class( $this->id() ) )    => true,
886
			'cmb-repeat'             => $this->args( 'repeatable' ),
887
			'cmb-repeat-group-field' => $this->group,
888
			'cmb-inline'             => $this->args( 'inline' ),
889
			'table-layout'           => 'edit' === $this->render_context && in_array( $this->type(), $repeat_table_rows_types ),
890
		);
891
892
		foreach ( $conditional_classes as $class => $condition ) {
893
			if ( $condition ) {
894
				$classes[] = $class;
895
			}
896
		}
897
898
		if ( $added_classes = $this->args( 'classes' ) ) {
899
			$added_classes = is_array( $added_classes ) ? implode( ' ', $added_classes ) : (string) $added_classes;
900
		} elseif ( $added_classes = $this->get_param_callback_result( 'classes_cb' ) ) {
901
			$added_classes = is_array( $added_classes ) ? implode( ' ', $added_classes ) : (string) $added_classes;
902
		}
903
904
		if ( $added_classes ) {
905
			$classes[] = esc_attr( $added_classes );
906
		}
907
908
		/**
909
		 * Globally filter row classes
910
		 *
911
		 * @since 2.0.0
912
		 *
913
		 * @param string            $classes Space-separated list of row classes
914
		 * @param CMB2_Field object $field   This field object
915
		 */
916
		return apply_filters( 'cmb2_row_classes', implode( ' ', $classes ), $this );
917
	}
918
919
920
921
	/**
922
	 * Get field display callback and render the display value in the column.
923
	 *
924
	 * @since 2.2.2
925
	 */
926
	public function render_column() {
927
		$this->render_context = 'display';
928
929
		$this->peform_param_callback( 'display_cb' );
930
931
		// For chaining
932
		return $this;
933
	}
934
935
	/**
936
	 * Default callback to outputs field value in a display format.
937
	 *
938
	 * @since 2.2.2
939
	 */
940
	public function display_value_callback() {
941
		// If field is requesting to be conditionally shown
942
		if ( ! $this->should_show() ) {
943
			return;
944
		}
945
946
		$display = new CMB2_Field_Display( $this );
947
948
		/**
949
		 * A filter to bypass the default display.
950
		 *
951
		 * The dynamic portion of the hook name, $this->type(), refers to the field type.
952
		 *
953
		 * Passing a non-null value to the filter will short-circuit the default display.
954
		 *
955
		 * @param bool|mixed         $pre_output Default null value.
956
		 * @param CMB2_Field         $field      This field object.
957
		 * @param CMB2_Field_Display $display    The `CMB2_Field_Display` object.
958
		 */
959
		$pre_output = apply_filters( "cmb2_pre_field_display_{$this->type()}", null, $this, $display );
960
961
		if ( null !== $pre_output ) {
962
			echo $pre_output;
963
			return;
964
		}
965
966
		$this->peform_param_callback( 'before_display_wrap' );
967
968
		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...
969
970
		$this->peform_param_callback( 'before_display' );
971
972
		CMB2_Field_Display::get( $this )->display();
973
974
		$this->peform_param_callback( 'after_display' );
975
976
		echo "\n</div>";
977
978
		$this->peform_param_callback( 'after_display_wrap' );
979
980
		// For chaining
981
		return $this;
982
	}
983
984
	/**
985
	 * Replaces a hash key - {#} - with the repeatable index
986
	 *
987
	 * @since  1.2.0
988
	 * @param  string $value Value to update
989
	 * @return string        Updated value
990
	 */
991
	public function replace_hash( $value ) {
992
		// Replace hash with 1 based count
993
		return str_replace( '{#}', ( $this->index + 1 ), $value );
994
	}
995
996
	/**
997
	 * Retrieve text parameter from field's text array (if it has one), or use fallback text
998
	 * For back-compatibility, falls back to checking the options array.
999
	 *
1000
	 * @since  2.2.2
1001
	 * @param  string $text_key Key in field's text array
1002
	 * @param  string $fallback Fallback text
1003
	 * @return string            Text
1004
	 */
1005
	public function get_string( $text_key, $fallback ) {
1006
		// If null, populate with our field strings values.
1007
		if ( null === $this->strings ) {
1008
			$this->strings = (array) $this->args['text'];
1009
1010 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...
1011
				$strings = call_user_func( $this->args['text_cb'], $this );
1012
1013
				if ( $strings && is_array( $strings ) ) {
1014
					$this->strings += $strings;
1015
				}
1016
			}
1017
		}
1018
1019
		// If we have that string value, send it back.
1020
		if ( isset( $this->strings[ $text_key ] ) ) {
1021
			return $this->strings[ $text_key ];
1022
		}
1023
1024
		// Check options for back-compat.
1025
		$string = $this->options( $text_key );
1026
1027
		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 1027 which is incompatible with the return type documented by CMB2_Field::get_string of type string.
Loading history...
1028
	}
1029
1030
	/**
1031
	 * Retrieve options args. Calls options_cb if it exists.
1032
	 *
1033
	 * @since  2.0.0
1034
	 * @param  string $key Specific option to retrieve
1035
	 * @return array        Array of options
1036
	 */
1037
	public function options( $key = '' ) {
1038
		if ( ! empty( $this->field_options ) ) {
1039
			if ( $key ) {
1040
				return array_key_exists( $key, $this->field_options ) ? $this->field_options[ $key ] : false;
1041
			}
1042
1043
			return $this->field_options;
1044
		}
1045
1046
		$this->field_options = (array) $this->args['options'];
1047
1048 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...
1049
			$options = call_user_func( $this->args['options_cb'], $this );
1050
1051
			if ( $options && is_array( $options ) ) {
1052
				$this->field_options = $options + $this->field_options;
1053
			}
1054
		}
1055
1056
		if ( $key ) {
1057
			return array_key_exists( $key, $this->field_options ) ? $this->field_options[ $key ] : false;
1058
		}
1059
1060
		return $this->field_options;
1061
	}
1062
1063
	/**
1064
	 * Store JS dependencies as part of the field args.
1065
	 *
1066
	 * @since 2.2.0
1067
	 * @param array $dependencies Dependies to register for this field.
1068
	 */
1069
	public function add_js_dependencies( $dependencies = array() ) {
1070
		foreach ( (array) $dependencies as $dependency ) {
1071
			$this->args['js_dependencies'][ $dependency ] = $dependency;
1072
		}
1073
1074
		CMB2_JS::add_dependencies( $dependencies );
1075
	}
1076
1077
	/**
1078
	 * Get CMB2_Field default value, either from default param or default_cb param.
1079
	 *
1080
	 * @since  0.2.2
1081
	 *
1082
	 * @return mixed  Default field value
1083
	 */
1084
	public function get_default() {
1085
		if ( null !== $this->args['default'] ) {
1086
			return $this->args['default'];
1087
		}
1088
1089
		$param = is_callable( $this->args['default_cb'] ) ? 'default_cb' : 'default';
1090
		$default = $this->get_param_callback_result( $param );
1091
1092
		// Allow a filter override of the default value
1093
		$this->args['default'] = apply_filters( 'cmb2_default_filter', $default, $this );
1094
1095
		return $this->args['default'];
1096
	}
1097
1098
	/**
1099
	 * Fills in empty field parameters with defaults
1100
	 *
1101
	 * @since 1.1.0
1102
	 * @param array                                   $args Metabox field config array
1103
	 * @param array       Modified field config array.
1104
	 */
1105
	public function _set_field_defaults( $args ) {
1106
1107
		// Set up blank or default values for empty ones
1108
		$args = wp_parse_args( $args, array(
1109
			'type'              => '',
1110
			'name'              => '',
1111
			'desc'              => '',
1112
			'before'            => '',
1113
			'after'             => '',
1114
			'options'           => array(),
1115
			'options_cb'        => '',
1116
			'text'              => array(),
1117
			'text_cb'           => '',
1118
			'attributes'        => array(),
1119
			'protocols'         => null,
1120
			'default'           => null,
1121
			'default_cb'        => '',
1122
			'classes'           => null,
1123
			'classes_cb'        => '',
1124
			'select_all_button' => true,
1125
			'multiple'          => false,
1126
			'repeatable'        => isset( $args['type'] ) && 'group' == $args['type'],
1127
			'inline'            => false,
1128
			'on_front'          => true,
1129
			'show_names'        => true,
1130
			'save_field'        => true, // Will not save if false
1131
			'date_format'       => 'm\/d\/Y',
1132
			'time_format'       => 'h:i A',
1133
			'description'       => isset( $args['desc'] ) ? $args['desc'] : '',
1134
			'preview_size'      => 'file' == $args['type'] ? array( 350, 350 ) : array( 50, 50 ),
1135
			'render_row_cb'     => array( $this, 'render_field_callback' ),
1136
			'display_cb'        => array( $this, 'display_value_callback' ),
1137
			'label_cb'          => 'title' != $args['type'] ? array( $this, 'label' ) : '',
1138
			'column'            => false,
1139
			'js_dependencies'   => array(),
1140
			'show_in_rest'      => null,
1141
		) );
1142
1143
		/*
1144
		 * Deprecated usage:
1145
		 *
1146
		 * 'std' -- use 'default' (no longer works)
1147
		 * 'row_classes' -- use 'class', or 'class_cb'
1148
		 * 'default' -- as callback (use default_cb)
1149
		 */
1150
		$args = $this->convert_deprecated_params( $args );
1151
1152
		$args['repeatable'] = $args['repeatable'] && ! $this->repeatable_exception( $args['type'] );
1153
		$args['inline']     = $args['inline'] || false !== stripos( $args['type'], '_inline' );
1154
1155
		$args['options']    = 'group' == $args['type'] ? wp_parse_args( $args['options'], array(
1156
			'add_button'    => esc_html__( 'Add Group', 'cmb2' ),
1157
			'remove_button' => esc_html__( 'Remove Group', 'cmb2' ),
1158
		) ) : $args['options'];
1159
1160
		$args['_id']        = $args['id'];
1161
		$args['_name']      = $args['id'];
1162
1163
		if ( $this->group ) {
1164
1165
			$args['id']    = $this->group->args( 'id' ) . '_' . $this->group->index . '_' . $args['id'];
1166
			$args['_name'] = $this->group->args( 'id' ) . '[' . $this->group->index . '][' . $args['_name'] . ']';
1167
		}
1168
1169
		if ( 'wysiwyg' == $args['type'] ) {
1170
			$args['id'] = strtolower( str_ireplace( '-', '_', $args['id'] ) );
1171
			$args['options']['textarea_name'] = $args['_name'];
1172
		}
1173
1174
		$option_types = apply_filters( 'cmb2_all_or_nothing_types', array( 'select', 'radio', 'radio_inline', 'taxonomy_select', 'taxonomy_radio', 'taxonomy_radio_inline' ), $this );
1175
1176
		if ( in_array( $args['type'], $option_types, true ) ) {
1177
1178
			$args['show_option_none'] = isset( $args['show_option_none'] ) ? $args['show_option_none'] : null;
1179
			$args['show_option_none'] = true === $args['show_option_none'] ? esc_html__( 'None', 'cmb2' ) : $args['show_option_none'];
1180
1181
			if ( null === $args['show_option_none'] ) {
1182
				$off_by_default = in_array( $args['type'], array( 'select', 'radio', 'radio_inline' ), true );
1183
				$args['show_option_none'] = $off_by_default ? false : esc_html__( 'None', 'cmb2' );
1184
			}
1185
		}
1186
1187
		$args['has_supporting_data'] = in_array(
1188
			$args['type'],
1189
			array(
1190
				// 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...
1191
				'file',
1192
				// 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...
1193
				'text_datetime_timestamp_timezone',
1194
			),
1195
			true
1196
		);
1197
1198
		return $args;
1199
	}
1200
1201
	/**
1202
	 * Get default field arguments specific to this CMB2 object.
1203
	 *
1204
	 * @since  2.2.0
1205
	 * @param  array      $field_args  Metabox field config array.
1206
	 * @param  CMB2_Field $field_group (optional) CMB2_Field object (group parent)
1207
	 * @return array                   Array of field arguments.
1208
	 */
1209
	protected function get_default_args( $field_args, $field_group = null ) {
1210
		$args = parent::get_default_args( array(), $this->group );
1211
1212
		if ( isset( $field_args['field_args'] ) ) {
1213
			$args = wp_parse_args( $field_args, $args );
1214
		} else {
1215
			$args['field_args'] = wp_parse_args( $field_args, $this->args );
1216
		}
1217
1218
		return $args;
1219
	}
1220
1221
	/**
1222
	 * Returns a cloned version of this field object with, but with
1223
	 * modified/overridden field arguments.
1224
	 *
1225
	 * @since  2.2.2
1226
	 * @param  array $field_args Array of field arguments, or entire array of
1227
	 *                           arguments for CMB2_Field
1228
	 *
1229
	 * @return CMB2_Field         The new CMB2_Field instance.
1230
	 */
1231
	public function get_field_clone( $field_args ) {
1232
		return $this->get_new_field( $field_args );
1233
	}
1234
1235
	/**
1236
	 * Returns the CMB2 instance this field is registered to.
1237
	 *
1238
	 * @since  2.2.2
1239
	 *
1240
	 * @return CMB2|WP_Error If new CMB2_Field is called without cmb_id arg, returns error.
1241
	 */
1242
	public function get_cmb() {
1243
		if ( ! $this->cmb_id ) {
1244
			return new WP_Error( 'no_cmb_id', esc_html__( 'Sorry, this field does not have a cmb_id specified.', 'cmb2' ) );
1245
		}
1246
1247
		return cmb2_get_metabox( $this->cmb_id, $this->object_id, $this->object_type );
1248
	}
1249
1250
	/**
1251
	 * Converts deprecated field parameters to the current/proper parameter, and throws a deprecation notice.
1252
	 *
1253
	 * @since 2.2.3
1254
	 * @param array                                   $args Metabox field config array.
1255
	 * @param array       Modified field config array.
1256
	 */
1257
	protected function convert_deprecated_params( $args ) {
1258
1259
		if ( isset( $args['row_classes'] ) ) {
1260
1261
			// We'll let this one be.
1262
			// $this->deprecated_param( __CLASS__ . '::__construct()', '2.2.3', self::DEPRECATED_PARAM, 'row_classes', 'classes' );
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% 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...
1263
			// row_classes param could be a callback. This is definitely deprecated.
1264
			if ( is_callable( $args['row_classes'] ) ) {
1265
1266
				$this->deprecated_param( __CLASS__ . '::__construct()', '2.2.3', self::DEPRECATED_CB_PARAM, 'row_classes', 'classes_cb' );
1267
1268
				$args['classes_cb'] = $args['row_classes'];
1269
				$args['classes'] = null;
1270
			} else {
1271
1272
				$args['classes'] = $args['row_classes'];
1273
			}
1274
1275
			unset( $args['row_classes'] );
1276
		}
1277
1278
		// default param can be passed a callback as well
1279 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...
1280
1281
			$this->deprecated_param( __CLASS__ . '::__construct()', '2.2.3', self::DEPRECATED_CB_PARAM, 'default', 'default_cb' );
1282
1283
			$args['default_cb'] = $args['default'];
1284
			$args['default'] = null;
1285
		}
1286
1287
		// options param can be passed a callback as well
1288 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...
1289
1290
			$this->deprecated_param( __CLASS__ . '::__construct()', '2.2.3', self::DEPRECATED_CB_PARAM, 'options', 'options_cb' );
1291
1292
			$args['options_cb'] = $args['options'];
1293
			$args['options'] = array();
1294
		}
1295
1296
		return $args;
1297
	}
1298
1299
}
1300