Completed
Pull Request — trunk (#541)
by Justin
06:33
created

CMB2_REST::sanitize_field_value()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
cc 4
eloc 11
nc 4
nop 2
dl 0
loc 20
ccs 0
cts 11
cp 0
crap 20
rs 9.2
c 0
b 0
f 0
1
<?php
2
/**
3
 * Handles hooking CMB2 objects/fields into the WordPres REST API
4
 * which can allow fields to be read and/or updated.
5
 *
6
 * @since  2.2.4
7
 *
8
 * @category  WordPress_Plugin
9
 * @package   CMB2
10
 * @author    WebDevStudios
11
 * @license   GPL-2.0+
12
 * @link      http://webdevstudios.com
13
 */
14
class CMB2_REST extends CMB2_Hookup_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...
15
16
	/**
17
	 * The current CMB2 REST endpoint version
18
	 * @var string
19
	 * @since 2.2.4
20
	 */
21
	const VERSION = '1';
22
23
	/**
24
	 * The CMB2 REST base namespace (v should always be followed by $version)
25
	 * @var string
26
	 * @since 2.2.4
27
	 */
28
	const NAME_SPACE = 'cmb2/v1';
29
30
	/**
31
	 * @var   CMB2 object
32
	 * @since 2.2.4
33
	 */
34
	public $cmb;
35
36
	/**
37
	 * @var   CMB2_REST[] objects
38
	 * @since 2.2.4
39
	 */
40
	protected static $boxes = array();
41
42
	/**
43
	 * @var   array Array of cmb ids for each type.
44
	 * @since 2.2.4
45
	 */
46
	protected static $type_boxes = array(
47
		'post' => array(),
48
		'user' => array(),
49
		'comment' => array(),
50
		'term' => array(),
51
	);
52
53
	/**
54
	 * Array of readable field objects.
55
	 * @var   CMB2_Field[]
56
	 * @since 2.2.4
57
	 */
58
	protected $read_fields = array();
59
60
	/**
61
	 * Array of editable field objects.
62
	 * @var   CMB2_Field[]
63
	 * @since 2.2.4
64
	 */
65
	protected $edit_fields = array();
66
67
	/**
68
	 * whether CMB2 object is readable via the rest api.
69
	 * @var boolean
70
	 */
71
	protected $rest_read = false;
72
73
	/**
74
	 * whether CMB2 object is editable via the rest api.
75
	 * @var boolean
76
	 */
77
	protected $rest_edit = false;
78
79
	/**
80
	 * Constructor
81
	 *
82
	 * @since 2.2.4
83
	 *
84
	 * @param CMB2 $cmb The CMB2 object to be registered for the API.
85
	 */
86
	public function __construct( CMB2 $cmb ) {
87
		$this->cmb = $cmb;
88
		self::$boxes[ $cmb->cmb_id ] = $this;
89
90
		$show_value = $this->cmb->prop( 'show_in_rest' );
91
92
		$this->rest_read = self::is_readable( $show_value );
93
		$this->rest_edit = self::is_editable( $show_value );
94
	}
95
96
	/**
97
	 * Hooks to register on frontend and backend.
98
	 *
99
	 * @since  2.2.4
100
	 *
101
	 * @return void
102
	 */
103
	public function universal_hooks() {
104
		// hook up the CMB rest endpoint classes
105
		$this->once( 'rest_api_init', array( __CLASS__, 'init_routes' ), 0 );
106
107
		if ( function_exists( 'register_rest_field' ) ) {
108
			$this->once( 'rest_api_init', array( __CLASS__, 'register_cmb2_fields' ), 50 );
109
		}
110
111
		$this->declare_read_edit_fields();
112
113
		add_filter( 'is_protected_meta', array( $this, 'is_protected_meta' ), 10, 3 );
114
	}
115
116
	/**
117
	 * Initiate the CMB2 Boxes and Fields routes
118
	 *
119
	 * @since  2.2.4
120
	 *
121
	 * @return void
122
	 */
123
	public static function init_routes() {
124
		$wp_rest_server = rest_get_server();
125
126
		$boxes_controller = new CMB2_REST_Controller_Boxes( $wp_rest_server );
127
		$boxes_controller->register_routes();
128
129
		$fields_controller = new CMB2_REST_Controller_Fields( $wp_rest_server );
130
		$fields_controller->register_routes();
131
	}
132
133
	/**
134
	 * Loop through REST boxes and call register_rest_field for each object type.
135
	 *
136
	 * @since  2.2.4
137
	 *
138
	 * @return void
139
	 */
140
	public static function register_cmb2_fields() {
141
		$alltypes = $taxonomies = array();
142
143
		foreach ( self::$boxes as $cmb_id => $rest_box ) {
144
			$types = array_flip( $rest_box->cmb->box_types() );
145
146 View Code Duplication
			if ( isset( $types['user'] ) ) {
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...
147
				unset( $types['user'] );
148
				self::$type_boxes['user'][ $cmb_id ] = $cmb_id;
149
			}
150
151 View Code Duplication
			if ( isset( $types['comment'] ) ) {
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...
152
				unset( $types['comment'] );
153
				self::$type_boxes['comment'][ $cmb_id ] = $cmb_id;
154
			}
155
156
			if ( isset( $types['term'] ) ) {
157
				unset( $types['term'] );
158
159
				$taxonomies = array_merge(
160
					$taxonomies,
161
					CMB2_Utils::ensure_array( $rest_box->cmb->prop( 'taxonomies' ) )
162
				);
163
164
				self::$type_boxes['term'][ $cmb_id ] = $cmb_id;
165
			}
166
167
			if ( ! empty( $types ) ) {
168
				$alltypes = array_merge( $alltypes, array_flip( $types ) );
169
				self::$type_boxes['post'][ $cmb_id ] = $cmb_id;
170
			}
171
		}
172
173
		$alltypes = array_unique( $alltypes );
174
175
		if ( ! empty( $alltypes ) ) {
176
			self::register_rest_field( $alltypes, 'post' );
177
		}
178
179
		if ( ! empty( self::$type_boxes['user'] ) ) {
180
			self::register_rest_field( 'user', 'user' );
181
		}
182
183
		if ( ! empty( self::$type_boxes['comment'] ) ) {
184
			self::register_rest_field( 'comment', 'comment' );
185
		}
186
187
		if ( ! empty( self::$type_boxes['term'] ) ) {
188
			self::register_rest_field( $taxonomies, 'term' );
189
		}
190
	}
191
192
	/**
193
	 * Wrapper for register_rest_field.
194
	 *
195
	 * @since  2.2.4
196
	 *
197
	 * @param string|array $object_types Object(s) the field is being registered
198
	 *                                   to, "post"|"term"|"comment" etc.
199
	 * @param string $object_types       Canonical object type for callbacks.
200
	 *
201
	 * @return void
202
	 */
203
	protected static function register_rest_field( $object_types, $object_type ) {
204
		register_rest_field( $object_types, 'cmb2', array(
205
			'get_callback'    => array( __CLASS__, "get_{$object_type}_rest_values" ),
206
			'update_callback' => array( __CLASS__, "update_{$object_type}_rest_values" ),
207
			'schema'          => null, // @todo add schema
208
		) );
209
	}
210
211
	/**
212
	 * Setup readable and editable fields.
213
	 *
214
	 * @since  2.2.4
215
	 *
216
	 * @return void
217
	 */
218
	protected function declare_read_edit_fields() {
219
		foreach ( $this->cmb->prop( 'fields' ) as $field ) {
220
			$show_in_rest = isset( $field['show_in_rest'] ) ? $field['show_in_rest'] : null;
221
222
			if ( false === $show_in_rest ) {
223
				continue;
224
			}
225
226
			if ( $this->can_read( $show_in_rest ) ) {
227
				$this->read_fields[] = $field['id'];
228
			}
229
230
			if ( $this->can_edit( $show_in_rest ) ) {
231
				$this->edit_fields[] = $field['id'];
232
			}
233
234
		}
235
	}
236
237
	/**
238
	 * Determines if a field is readable based on it's show_in_rest value
239
	 * and the box's show_in_rest value.
240
	 *
241
	 * @since  2.2.4
242
	 *
243
	 * @param  bool $show_in_rest Field's show_in_rest value. Default null.
244
	 *
245
	 * @return bool               Whether field is readable.
246
	 */
247
	protected function can_read( $show_in_rest ) {
248
		// if 'null', then use default box value.
249
		if ( null === $show_in_rest ) {
250
			return $this->rest_read;
251
		}
252
253
		// Else check if the value represents readable.
254
		return self::is_readable( $show_in_rest );
255
	}
256
257
	/**
258
	 * Determines if a field is editable based on it's show_in_rest value
259
	 * and the box's show_in_rest value.
260
	 *
261
	 * @since  2.2.4
262
	 *
263
	 * @param  bool $show_in_rest Field's show_in_rest value. Default null.
264
	 *
265
	 * @return bool               Whether field is editable.
266
	 */
267
	protected function can_edit( $show_in_rest ) {
268
		// if 'null', then use default box value.
269
		if ( null === $show_in_rest ) {
270
			return $this->rest_edit;
271
		}
272
273
		// Else check if the value represents editable.
274
		return self::is_editable( $show_in_rest );
275
	}
276
277
	/**
278
	 * Handler for getting post custom field data.
279
	 *
280
	 * @since  2.2.4
281
	 *
282
	 * @param  array           $object      The object data from the response
283
	 * @param  string          $field_name  Name of field
284
	 * @param  WP_REST_Request $request     Current request
285
	 * @param  string          $object_type The request object type
286
	 *
287
	 * @return mixed
288
	 */
289
	public static function get_post_rest_values( $object, $field_name, $request, $object_type ) {
290
		if ( 'cmb2' === $field_name ) {
291
			return self::get_rest_values( $object, $request, $object_type, 'post' );
292
		}
293
	}
294
295
	/**
296
	 * Handler for getting user custom field data.
297
	 *
298
	 * @since  2.2.4
299
	 *
300
	 * @param  array           $object      The object data from the response
301
	 * @param  string          $field_name  Name of field
302
	 * @param  WP_REST_Request $request     Current request
303
	 * @param  string          $object_type The request object type
304
	 *
305
	 * @return mixed
306
	 */
307
	public static function get_user_rest_values( $object, $field_name, $request, $object_type ) {
308
		if ( 'cmb2' === $field_name ) {
309
			return self::get_rest_values( $object, $request, $object_type, 'user' );
310
		}
311
	}
312
313
	/**
314
	 * Handler for getting comment custom field data.
315
	 *
316
	 * @since  2.2.4
317
	 *
318
	 * @param  array           $object      The object data from the response
319
	 * @param  string          $field_name  Name of field
320
	 * @param  WP_REST_Request $request     Current request
321
	 * @param  string          $object_type The request object type
322
	 *
323
	 * @return mixed
324
	 */
325
	public static function get_comment_rest_values( $object, $field_name, $request, $object_type ) {
326
		if ( 'cmb2' === $field_name ) {
327
			return self::get_rest_values( $object, $request, $object_type, 'comment' );
328
		}
329
	}
330
331
	/**
332
	 * Handler for getting term custom field data.
333
	 *
334
	 * @since  2.2.4
335
	 *
336
	 * @param  array           $object      The object data from the response
337
	 * @param  string          $field_name  Name of field
338
	 * @param  WP_REST_Request $request     Current request
339
	 * @param  string          $object_type The request object type
340
	 *
341
	 * @return mixed
342
	 */
343
	public static function get_term_rest_values( $object, $field_name, $request, $object_type ) {
344
		if ( 'cmb2' === $field_name ) {
345
			return self::get_rest_values( $object, $request, $object_type, 'term' );
346
		}
347
	}
348
349
	/**
350
	 * Handler for getting custom field data.
351
	 *
352
	 * @since  2.2.4
353
	 *
354
	 * @param  array           $object           The object data from the response
355
	 * @param  WP_REST_Request $request          Current request
356
	 * @param  string          $object_type      The request object type
357
	 * @param  string          $main_object_type The cmb main object type
358
	 *
359
	 * @return mixed
360
	 */
361
	protected static function get_rest_values( $object, $request, $object_type, $main_object_type = 'post' ) {
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $object_type is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
362
		if ( ! isset( $object['id'] ) ) {
363
			return;
364
		}
365
366
		$values = array();
367
368
		if ( ! empty( self::$type_boxes[ $main_object_type ] ) ) {
369
			foreach ( self::$type_boxes[ $main_object_type ] as $cmb_id ) {
370
				$rest_box = self::$boxes[ $cmb_id ];
371
372
				foreach ( $rest_box->read_fields as $field_id ) {
373
					$rest_box->cmb->object_id( $object['id'] );
374
					$rest_box->cmb->object_type( $main_object_type );
375
376
					$field = $rest_box->cmb->get_field( $field_id );
377
378
					$field->object_id( $object['id'] );
379
					$field->object_type( $main_object_type );
380
381
					$values[ $cmb_id ][ $field->id( true ) ] = $field->get_data();
382
				}
383
			}
384
		}
385
386
		return $values;
387
	}
388
389
	/**
390
	 * Handler for updating post custom field data.
391
	 *
392
	 * @since  2.2.4
393
	 *
394
	 * @param  mixed           $value       The value of the field
0 ignored issues
show
Documentation introduced by
There is no parameter named $value. Did you maybe mean $values?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
395
	 * @param  object          $object      The object from the response
396
	 * @param  string          $field_name  Name of field
397
	 * @param  WP_REST_Request $request     Current request
398
	 * @param  string          $object_type The request object type
399
	 *
400
	 * @return bool|int
401
	 */
402
	public static function update_post_rest_values( $values, $object, $field_name, $request, $object_type ) {
403
		if ( 'cmb2' === $field_name ) {
404
			return self::update_rest_values( $values, $object, $request, $object_type, 'post' );
405
		}
406
	}
407
408
	/**
409
	 * Handler for updating user custom field data.
410
	 *
411
	 * @since  2.2.4
412
	 *
413
	 * @param  mixed           $value       The value of the field
0 ignored issues
show
Documentation introduced by
There is no parameter named $value. Did you maybe mean $values?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
414
	 * @param  object          $object      The object from the response
415
	 * @param  string          $field_name  Name of field
416
	 * @param  WP_REST_Request $request     Current request
417
	 * @param  string          $object_type The request object type
418
	 *
419
	 * @return bool|int
420
	 */
421
	public static function update_user_rest_values( $values, $object, $field_name, $request, $object_type ) {
422
		if ( 'cmb2' === $field_name ) {
423
			return self::update_rest_values( $values, $object, $request, $object_type, 'user' );
424
		}
425
	}
426
427
	/**
428
	 * Handler for updating comment custom field data.
429
	 *
430
	 * @since  2.2.4
431
	 *
432
	 * @param  mixed           $value       The value of the field
0 ignored issues
show
Documentation introduced by
There is no parameter named $value. Did you maybe mean $values?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
433
	 * @param  object          $object      The object from the response
434
	 * @param  string          $field_name  Name of field
435
	 * @param  WP_REST_Request $request     Current request
436
	 * @param  string          $object_type The request object type
437
	 *
438
	 * @return bool|int
439
	 */
440
	public static function update_comment_rest_values( $values, $object, $field_name, $request, $object_type ) {
441
		if ( 'cmb2' === $field_name ) {
442
			return self::update_rest_values( $values, $object, $request, $object_type, 'comment' );
443
		}
444
	}
445
446
	/**
447
	 * Handler for updating term custom field data.
448
	 *
449
	 * @since  2.2.4
450
	 *
451
	 * @param  mixed           $value       The value of the field
0 ignored issues
show
Documentation introduced by
There is no parameter named $value. Did you maybe mean $values?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
452
	 * @param  object          $object      The object from the response
453
	 * @param  string          $field_name  Name of field
454
	 * @param  WP_REST_Request $request     Current request
455
	 * @param  string          $object_type The request object type
456
	 *
457
	 * @return bool|int
458
	 */
459
	public static function update_term_rest_values( $values, $object, $field_name, $request, $object_type ) {
460
		if ( 'cmb2' === $field_name ) {
461
			return self::update_rest_values( $values, $object, $request, $object_type, 'term' );
462
		}
463
	}
464
465
	/**
466
	 * Handler for updating custom field data.
467
	 *
468
	 * @since  2.2.4
469
	 *
470
	 * @param  mixed           $value            The value of the field
0 ignored issues
show
Documentation introduced by
There is no parameter named $value. Did you maybe mean $values?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
471
	 * @param  object          $object           The object from the response
472
	 * @param  WP_REST_Request $request          Current request
473
	 * @param  string          $object_type      The request object type
474
	 * @param  string          $main_object_type The cmb main object type
475
	 *
476
	 * @return bool|int
477
	 */
478
	protected static function update_rest_values( $values, $object, $request, $object_type, $main_object_type = 'post' ) {
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $object_type is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
479
		if ( empty( $values ) || ! is_array( $values ) ) {
480
			return;
481
		}
482
483
		$object_id = self::get_object_id( $object, $main_object_type );
484
485
		if ( ! $object_id ) {
486
			return;
487
		}
488
489
		$updated = array();
490
491
		if ( ! empty( self::$type_boxes[ $main_object_type ] ) ) {
492
			foreach ( self::$type_boxes[ $main_object_type ] as $cmb_id ) {
493
				$rest_box = self::$boxes[ $cmb_id ];
494
495
				if ( ! array_key_exists( $cmb_id, $values ) ) {
496
					continue;
497
				}
498
499
				$rest_box->cmb->object_id( $object_id );
500
				$rest_box->cmb->object_type( $main_object_type );
501
502
				$updated[ $cmb_id ] = $rest_box->sanitize_box_values( $values );
503
			}
504
		}
505
506
		return $updated;
507
	}
508
509
	/**
510
	 * Loop through box fields and sanitize the values.
511
	 *
512
	 * @since  2.2.o
513
	 *
514
	 * @param  array   $values Array of values being provided.
515
	 * @return array           Array of updated/sanitized values.
516
	 */
517
	public function sanitize_box_values( array $values ) {
518
		$updated = array();
519
520
		$this->cmb->pre_process();
521
522
		foreach ( $this->edit_fields as $field_id ) {
523
			$updated[ $field_id ] = $this->sanitize_field_value( $values, $field_id );
0 ignored issues
show
Documentation introduced by
$field_id is of type object<CMB2_Field>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
524
		}
525
526
		$this->cmb->after_save();
527
528
		return $updated;
529
	}
530
531
	/**
532
	 * Handles returning a sanitized field value.
533
	 *
534
	 * @since  2.2.4
535
	 *
536
	 * @param  array   $values   Array of values being provided.
537
	 * @param  string  $field_id The id of the field to update.
538
	 *
539
	 * @return mixed             The results of saving/sanitizing a field value.
540
	 */
541
	protected function sanitize_field_value( array $values, $field_id ) {
542
		if ( ! array_key_exists( $field_id, $values[ $this->cmb->cmb_id ] ) ) {
543
			return;
544
		}
545
546
		$field = $this->cmb->get_field( $field_id );
547
548
		if ( 'title' == $field->type() ) {
549
			return;
550
		}
551
552
		$field->object_id( $this->cmb->object_id() );
553
		$field->object_type( $this->cmb->object_type() );
554
555
		if ( 'group' == $field->type() ) {
556
			return $this->sanitize_group_value( $values, $field );
0 ignored issues
show
Security Bug introduced by
It seems like $field defined by $this->cmb->get_field($field_id) on line 546 can also be of type false; however, CMB2_REST::sanitize_group_value() does only seem to accept object<CMB2_Field>, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
557
		}
558
559
		return $field->save_field( $values[ $this->cmb->cmb_id ][ $field_id ] );
560
	}
561
562
	/**
563
	 * Handles returning a sanitized group field value.
564
	 *
565
	 * @since  2.2.4
566
	 *
567
	 * @param  array       $values Array of values being provided.
568
	 * @param  CMB2_Field  $field  CMB2_Field object.
569
	 *
570
	 * @return mixed               The results of saving/sanitizing the group field value.
571
	 */
572
	protected function sanitize_group_value( array $values, CMB2_Field $field ) {
573
		$fields = $field->fields();
574
		if ( empty( $fields ) ) {
575
			return;
576
		}
577
578
		$this->cmb->data_to_save[ $field->_id() ] = $values[ $this->cmb->cmb_id ][ $field->_id() ];
579
580
		return $this->cmb->save_group_field( $field );
0 ignored issues
show
Documentation introduced by
$field is of type object<CMB2_Field>, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
581
	}
582
583
	/**
584
	 * Filter whether a meta key is protected.
585
	 *
586
	 * @since 2.2.4
587
	 *
588
	 * @param bool   $protected Whether the key is protected. Default false.
589
	 * @param string $meta_key  Meta key.
590
	 * @param string $meta_type Meta type.
591
	 */
592
	public function is_protected_meta( $protected, $meta_key, $meta_type ) {
0 ignored issues
show
Unused Code introduced by
The parameter $meta_type is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
593
		if ( $this->field_can_edit( $meta_key ) ) {
594
			return false;
595
		}
596
597
		return $protected;
598
	}
599
600
	protected static function get_object_id( $object, $object_type = 'post' ) {
601
		switch ( $object_type ) {
602
			case 'user':
603
			case 'post':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
604
				if ( isset( $object->ID ) ) {
605
					return intval( $object->ID );
606
				}
607
			case 'comment':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
608
				if ( isset( $object->comment_ID ) ) {
609
					return intval( $object->comment_ID );
610
				}
611
			case 'term':
612
				if ( is_array( $object ) && isset( $object['term_id'] ) ) {
613
					return intval( $object['term_id'] );
614
				} elseif ( isset( $object->term_id ) ) {
615
					return intval( $object->term_id );
616
				}
617
		}
618
619
		return 0;
620
	}
621
622
	public function field_can_read( $field_id, $return_object = false ) {
623
		return $this->field_can( 'read_fields', $field_id, $return_object );
624
	}
625
626
	public function field_can_edit( $field_id, $return_object = false ) {
627
		return $this->field_can( 'edit_fields', $field_id, $return_object );
628
	}
629
630
	protected function field_can( $type = 'read_fields', $field_id, $return_object = false ) {
631
		if ( ! in_array( $field_id instanceof CMB2_Field ? $field_id->id() : $field_id, $this->{$type}, true ) ) {
632
			return false;
633
		}
634
635
		return $return_object ? $this->cmb->get_field( $field_id ) : true;
636
	}
637
638
	/**
639
	 * Get a CMB2_REST instance object from the registry by a CMB2 id.
640
	 *
641
	 * @since  2.2.4
642
	 *
643
	 * @param  string  $cmb_id CMB2 config id
644
	 *
645
	 * @return CMB2_REST|false The CMB2_REST object or false.
646
	 */
647
	public static function get_rest_box( $cmb_id ) {
648
		return isset( self::$boxes[ $cmb_id ] ) ? self::$boxes[ $cmb_id ] : false;
649
	}
650
651
	/**
652
	 * Remove a CMB2_REST instance object from the registry.
653
	 *
654
	 * @since  2.2.4
655
	 *
656
	 * @param string $cmb_id A CMB2 instance id.
657
	 */
658
	public static function remove( $cmb_id ) {
659
		if ( array_key_exists( $cmb_id, self::$boxes ) ) {
660
			unset( self::$boxes[ $cmb_id ] );
661
		}
662
	}
663
664
	/**
665
	 * Retrieve all CMB2_REST instances from the registry.
666
	 *
667
	 * @since  2.2.4
668
	 * @return CMB2[] Array of all registered CMB2_REST instances.
669
	 */
670
	public static function get_all() {
671
		return self::$boxes;
672
	}
673
674
	/**
675
	 * Checks if given value is readable.
676
	 *
677
	 * Value is considered readable if it is not empty and if it does not match the editable blacklist.
678
	 *
679
	 * @since  2.2.4
680
	 *
681
	 * @param  mixed  $value Value to check.
682
	 *
683
	 * @return boolean       Whether value is considered readable.
684
	 */
685
	public static function is_readable( $value ) {
686
		return ! empty( $value ) && ! in_array( $value, array(
687
			WP_REST_Server::CREATABLE,
688
			WP_REST_Server::EDITABLE,
689
			WP_REST_Server::DELETABLE,
690
		), true );
691
	}
692
693
	/**
694
	 * Checks if given value is editable.
695
	 *
696
	 * Value is considered editable if matches the editable whitelist.
697
	 *
698
	 * @since  2.2.4
699
	 *
700
	 * @param  mixed  $value Value to check.
701
	 *
702
	 * @return boolean       Whether value is considered editable.
703
	 */
704
	public static function is_editable( $value ) {
705
		return in_array( $value, array(
706
			WP_REST_Server::EDITABLE,
707
			WP_REST_Server::ALLMETHODS,
708
		), true );
709
	}
710
711
	/**
712
	 * Magic getter for our object.
713
	 *
714
	 * @param string $field
715
	 * @throws Exception Throws an exception if the field is invalid.
716
	 *
717
	 * @return mixed
718
	 */
719
	public function __get( $field ) {
720
		switch ( $field ) {
721
			case 'read_fields':
722
			case 'edit_fields':
723
			case 'rest_read':
724
			case 'rest_edit':
725
				return $this->{$field};
726
			default:
727
				throw new Exception( 'Invalid ' . __CLASS__ . ' property: ' . $field );
728
		}
729
	}
730
731
}
732