Completed
Pull Request — trunk (#541)
by Justin
28:03 queued 25:22
created

CMB2_REST::field_can()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 4
nc 3
nop 3
dl 0
loc 7
ccs 4
cts 4
cp 1
crap 4
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 38
	public function __construct( CMB2 $cmb ) {
87 38
		$this->cmb = $cmb;
88 38
		self::$boxes[ $cmb->cmb_id ] = $this;
89
90 38
		$show_value = $this->cmb->prop( 'show_in_rest' );
91
92 38
		$this->rest_read = self::is_readable( $show_value );
93 38
		$this->rest_edit = self::is_editable( $show_value );
94 38
	}
95
96
	/**
97
	 * Hooks to register on frontend and backend.
98
	 *
99
	 * @since  2.2.4
100
	 *
101
	 * @return void
102
	 */
103 38
	public function universal_hooks() {
104
		// hook up the CMB rest endpoint classes
105 38
		$this->once( 'rest_api_init', array( __CLASS__, 'init_routes' ), 0 );
106
107 38
		if ( function_exists( 'register_rest_field' ) ) {
108 38
			$this->once( 'rest_api_init', array( __CLASS__, 'register_cmb2_fields' ), 50 );
109 38
		}
110
111 38
		$this->declare_read_edit_fields();
112
113 38
		add_filter( 'is_protected_meta', array( $this, 'is_protected_meta' ), 10, 3 );
114 38
	}
115
116
	/**
117
	 * Initiate the CMB2 Boxes and Fields routes
118
	 *
119
	 * @since  2.2.4
120
	 *
121
	 * @return void
122
	 */
123 1
	public static function init_routes() {
124 1
		$wp_rest_server = rest_get_server();
125
126 1
		$boxes_controller = new CMB2_REST_Controller_Boxes( $wp_rest_server );
127 1
		$boxes_controller->register_routes();
128
129 1
		$fields_controller = new CMB2_REST_Controller_Fields( $wp_rest_server );
130 1
		$fields_controller->register_routes();
131 1
	}
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 38
	public static function register_cmb2_fields() {
141 38
		$alltypes = $taxonomies = array();
142
143 38
		foreach ( self::$boxes as $cmb_id => $rest_box ) {
144 38
			$types = array_flip( $rest_box->cmb->box_types() );
145
146 38 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 10
				unset( $types['user'] );
148 10
				self::$type_boxes['user'][ $cmb_id ] = $cmb_id;
149 10
			}
150
151 38 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 10
				unset( $types['comment'] );
153 10
				self::$type_boxes['comment'][ $cmb_id ] = $cmb_id;
154 10
			}
155
156 38
			if ( isset( $types['term'] ) ) {
157 10
				unset( $types['term'] );
158
159 10
				$taxonomies = array_merge(
160 10
					$taxonomies,
161 10
					CMB2_Utils::ensure_array( $rest_box->cmb->prop( 'taxonomies' ) )
162 10
				);
163
164 10
				self::$type_boxes['term'][ $cmb_id ] = $cmb_id;
165 10
			}
166
167 38
			if ( ! empty( $types ) ) {
168 38
				$alltypes = array_merge( $alltypes, array_flip( $types ) );
169 38
				self::$type_boxes['post'][ $cmb_id ] = $cmb_id;
170 38
			}
171 38
		}
172
173 38
		$alltypes = array_unique( $alltypes );
174
175 38
		if ( ! empty( $alltypes ) ) {
176 38
			self::register_rest_field( $alltypes, 'post' );
177 38
		}
178
179 38
		if ( ! empty( self::$type_boxes['user'] ) ) {
180 10
			self::register_rest_field( 'user', 'user' );
181 10
		}
182
183 38
		if ( ! empty( self::$type_boxes['comment'] ) ) {
184 10
			self::register_rest_field( 'comment', 'comment' );
185 10
		}
186
187 38
		if ( ! empty( self::$type_boxes['term'] ) ) {
188 10
			self::register_rest_field( $taxonomies, 'term' );
189 10
		}
190 38
	}
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 38
	protected static function register_rest_field( $object_types, $object_type ) {
204 38
		register_rest_field( $object_types, 'cmb2', array(
205 38
			'get_callback'    => array( __CLASS__, "get_{$object_type}_rest_values" ),
206 38
			'update_callback' => array( __CLASS__, "update_{$object_type}_rest_values" ),
207 38
			'schema'          => null, // @todo add schema
208 38
		) );
209 38
	}
210
211
	/**
212
	 * Setup readable and editable fields.
213
	 *
214
	 * @since  2.2.4
215
	 *
216
	 * @return void
217
	 */
218 38
	protected function declare_read_edit_fields() {
219 38
		foreach ( $this->cmb->prop( 'fields' ) as $field ) {
220 38
			$show_in_rest = isset( $field['show_in_rest'] ) ? $field['show_in_rest'] : null;
221
222 38
			if ( false === $show_in_rest ) {
223
				continue;
224
			}
225
226 38
			if ( $this->can_read( $show_in_rest ) ) {
227 38
				$this->read_fields[] = $field['id'];
228 38
			}
229
230 38
			if ( $this->can_edit( $show_in_rest ) ) {
231 38
				$this->edit_fields[] = $field['id'];
232 38
			}
233
234 38
		}
235 38
	}
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 38
	protected function can_read( $show_in_rest ) {
248
		// if 'null', then use default box value.
249 38
		if ( null === $show_in_rest ) {
250 38
			return $this->rest_read;
251
		}
252
253
		// Else check if the value represents readable.
254 4
		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 38
	protected function can_edit( $show_in_rest ) {
268
		// if 'null', then use default box value.
269 38
		if ( null === $show_in_rest ) {
270 38
			return $this->rest_edit;
271
		}
272
273
		// Else check if the value represents editable.
274 4
		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 4
	public static function get_post_rest_values( $object, $field_name, $request, $object_type ) {
290 4
		if ( 'cmb2' === $field_name ) {
291 4
			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 2
	public static function get_user_rest_values( $object, $field_name, $request, $object_type ) {
308 2
		if ( 'cmb2' === $field_name ) {
309 2
			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 2
	public static function get_comment_rest_values( $object, $field_name, $request, $object_type ) {
326 2
		if ( 'cmb2' === $field_name ) {
327 2
			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 2
	public static function get_term_rest_values( $object, $field_name, $request, $object_type ) {
344 2
		if ( 'cmb2' === $field_name ) {
345 2
			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 10
	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 10
		if ( ! isset( $object['id'] ) ) {
363
			return;
364
		}
365
366 10
		$values = array();
367
368 10
		if ( ! empty( self::$type_boxes[ $main_object_type ] ) ) {
369 10
			foreach ( self::$type_boxes[ $main_object_type ] as $cmb_id ) {
370 10
				$rest_box = self::$boxes[ $cmb_id ];
371
372 10
				foreach ( $rest_box->read_fields as $field_id ) {
373 10
					$rest_box->cmb->object_id( $object['id'] );
374 10
					$rest_box->cmb->object_type( $main_object_type );
375
376 10
					$field = $rest_box->cmb->get_field( $field_id );
377
378 10
					$field->object_id( $object['id'] );
379 10
					$field->object_type( $main_object_type );
380
381 10
					$values[ $cmb_id ][ $field->id( true ) ] = $field->get_data();
382 10
				}
383 10
			}
384 10
		}
385
386 10
		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 2
	public static function update_post_rest_values( $values, $object, $field_name, $request, $object_type ) {
403 2
		if ( 'cmb2' === $field_name ) {
404 2
			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 1
	public static function update_user_rest_values( $values, $object, $field_name, $request, $object_type ) {
422 1
		if ( 'cmb2' === $field_name ) {
423 1
			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 1
	public static function update_comment_rest_values( $values, $object, $field_name, $request, $object_type ) {
441 1
		if ( 'cmb2' === $field_name ) {
442 1
			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 1
	public static function update_term_rest_values( $values, $object, $field_name, $request, $object_type ) {
460 1
		if ( 'cmb2' === $field_name ) {
461 1
			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 5
	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 5
		if ( empty( $values ) || ! is_array( $values ) ) {
480
			return;
481
		}
482
483 5
		$object_id = self::get_object_id( $object, $main_object_type );
484
485 5
		if ( ! $object_id ) {
486
			return;
487
		}
488
489 5
		$updated = array();
490
491 5
		if ( ! empty( self::$type_boxes[ $main_object_type ] ) ) {
492 5
			foreach ( self::$type_boxes[ $main_object_type ] as $cmb_id ) {
493 5
				$rest_box = self::$boxes[ $cmb_id ];
494
495 5
				if ( ! array_key_exists( $cmb_id, $values ) ) {
496
					continue;
497
				}
498
499 5
				$rest_box->cmb->object_id( $object_id );
500 5
				$rest_box->cmb->object_type( $main_object_type );
501
502 5
				$updated[ $cmb_id ] = $rest_box->sanitize_box_values( $values );
503 5
			}
504 5
		}
505
506 5
		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 5
	public function sanitize_box_values( array $values ) {
518 5
		$updated = array();
519
520 5
		$this->cmb->pre_process();
521
522 5
		foreach ( $this->edit_fields as $field_id ) {
523 5
			$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 5
		}
525
526 5
		$this->cmb->after_save();
527
528 5
		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 5
	protected function sanitize_field_value( array $values, $field_id ) {
542 5
		if ( ! array_key_exists( $field_id, $values[ $this->cmb->cmb_id ] ) ) {
543 4
			return;
544
		}
545
546 5
		$field = $this->cmb->get_field( $field_id );
547
548 5
		if ( 'title' == $field->type() ) {
549
			return;
550
		}
551
552 5
		$field->object_id( $this->cmb->object_id() );
553 5
		$field->object_type( $this->cmb->object_type() );
554
555 5
		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 5
		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 6
	protected static function get_object_id( $object, $object_type = 'post' ) {
601
		switch ( $object_type ) {
602 6
			case 'user':
603 6
			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 4
				if ( isset( $object->ID ) ) {
605 4
					return intval( $object->ID );
606
				}
607 3
			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 2
				if ( isset( $object->comment_ID ) ) {
609 2
					return intval( $object->comment_ID );
610
				}
611 2
			case 'term':
612 2
				if ( is_array( $object ) && isset( $object['term_id'] ) ) {
613 1
					return intval( $object['term_id'] );
614 2
				} elseif ( isset( $object->term_id ) ) {
615 2
					return intval( $object->term_id );
616
				}
617 1
		}
618
619 1
		return 0;
620
	}
621
622 6
	public function field_can_read( $field_id, $return_object = false ) {
623 6
		return $this->field_can( 'read_fields', $field_id, $return_object );
624
	}
625
626 4
	public function field_can_edit( $field_id, $return_object = false ) {
627 4
		return $this->field_can( 'edit_fields', $field_id, $return_object );
628
	}
629
630 8
	protected function field_can( $type = 'read_fields', $field_id, $return_object = false ) {
631 8
		if ( ! in_array( $field_id instanceof CMB2_Field ? $field_id->id() : $field_id, $this->{$type}, true ) ) {
632 1
			return false;
633
		}
634
635 8
		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 13
	public static function get_rest_box( $cmb_id ) {
648 13
		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 38
	public static function get_all() {
671 38
		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 38
	public static function is_readable( $value ) {
686 38
		return ! empty( $value ) && ! in_array( $value, array(
687 38
			WP_REST_Server::CREATABLE,
688 38
			WP_REST_Server::EDITABLE,
689 38
			WP_REST_Server::DELETABLE,
690 38
		), 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 38
	public static function is_editable( $value ) {
705 38
		return in_array( $value, array(
706 38
			WP_REST_Server::EDITABLE,
707 38
			WP_REST_Server::ALLMETHODS,
708 38
		), 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 12
	public function __get( $field ) {
720
		switch ( $field ) {
721 12
			case 'read_fields':
722 12
			case 'edit_fields':
723 12
			case 'rest_read':
724 12
			case 'rest_edit':
725 12
				return $this->{$field};
726
			default:
727
				throw new Exception( 'Invalid ' . __CLASS__ . ' property: ' . $field );
728
		}
729
	}
730
731
}
732