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.3 |
7
|
|
|
* |
8
|
|
|
* @category WordPress_Plugin |
9
|
|
|
* @package CMB2 |
10
|
|
|
* @author CMB2 team |
11
|
|
|
* @license GPL-2.0+ |
12
|
|
|
* @link https://cmb2.io |
13
|
|
|
* |
14
|
|
|
* @property-read read_fields Array of readable field objects. |
15
|
|
|
* @property-read edit_fields Array of editable field objects. |
16
|
|
|
* @property-read rest_read Whether CMB2 object is readable via the rest api. |
17
|
|
|
* @property-read rest_edit Whether CMB2 object is editable via the rest api. |
18
|
|
|
*/ |
19
|
|
|
class CMB2_REST extends CMB2_Hookup_Base { |
20
|
|
|
|
21
|
|
|
/** |
22
|
|
|
* The current CMB2 REST endpoint version |
23
|
|
|
* |
24
|
|
|
* @var string |
25
|
|
|
* @since 2.2.3 |
26
|
|
|
*/ |
27
|
|
|
const VERSION = '1'; |
28
|
|
|
|
29
|
|
|
/** |
30
|
|
|
* The CMB2 REST base namespace (v should always be followed by $version) |
31
|
|
|
* |
32
|
|
|
* @var string |
33
|
|
|
* @since 2.2.3 |
34
|
|
|
*/ |
35
|
|
|
const NAME_SPACE = 'cmb2/v1'; |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* @var CMB2 object |
39
|
|
|
* @since 2.2.3 |
40
|
|
|
*/ |
41
|
|
|
public $cmb; |
42
|
|
|
|
43
|
|
|
/** |
44
|
|
|
* @var CMB2_REST[] objects |
45
|
|
|
* @since 2.2.3 |
46
|
|
|
*/ |
47
|
|
|
protected static $boxes = array(); |
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* @var array Array of cmb ids for each type. |
51
|
|
|
* @since 2.2.3 |
52
|
|
|
*/ |
53
|
|
|
protected static $type_boxes = array( |
54
|
|
|
'post' => array(), |
55
|
|
|
'user' => array(), |
56
|
|
|
'comment' => array(), |
57
|
|
|
'term' => array(), |
58
|
|
|
); |
59
|
|
|
|
60
|
|
|
/** |
61
|
|
|
* Array of readable field objects. |
62
|
|
|
* |
63
|
|
|
* @var CMB2_Field[] |
64
|
|
|
* @since 2.2.3 |
65
|
|
|
*/ |
66
|
|
|
protected $read_fields = array(); |
67
|
|
|
|
68
|
|
|
/** |
69
|
|
|
* Array of editable field objects. |
70
|
|
|
* |
71
|
|
|
* @var CMB2_Field[] |
72
|
|
|
* @since 2.2.3 |
73
|
|
|
*/ |
74
|
|
|
protected $edit_fields = array(); |
75
|
|
|
|
76
|
|
|
/** |
77
|
|
|
* Whether CMB2 object is readable via the rest api. |
78
|
|
|
* |
79
|
|
|
* @var boolean |
80
|
|
|
*/ |
81
|
|
|
protected $rest_read = false; |
82
|
|
|
|
83
|
|
|
/** |
84
|
|
|
* Whether CMB2 object is editable via the rest api. |
85
|
|
|
* |
86
|
|
|
* @var boolean |
87
|
|
|
*/ |
88
|
|
|
protected $rest_edit = false; |
89
|
|
|
|
90
|
|
|
/** |
91
|
|
|
* A functionalized constructor, used for the hookup action callbacks. |
92
|
|
|
* |
93
|
|
|
* @since 2.2.6 |
94
|
|
|
* |
95
|
|
|
* @param CMB2 $cmb The CMB2 object to hookup |
96
|
|
|
* |
97
|
|
|
* @return CMB2_Hookup_Base $hookup The hookup object. |
98
|
|
|
*/ |
99
|
|
|
public static function maybe_init_and_hookup( CMB2 $cmb ) { |
100
|
|
|
if ( $cmb->prop( 'show_in_rest' ) && function_exists( 'rest_get_server' ) ) { |
101
|
|
|
|
102
|
|
|
$hookup = new self( $cmb ); |
103
|
|
|
|
104
|
|
|
return $hookup->universal_hooks(); |
|
|
|
|
105
|
|
|
} |
106
|
|
|
|
107
|
|
|
return false; |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
/** |
111
|
|
|
* Constructor |
112
|
|
|
* |
113
|
|
|
* @since 2.2.3 |
114
|
|
|
* |
115
|
|
|
* @param CMB2 $cmb The CMB2 object to be registered for the API. |
116
|
|
|
*/ |
117
|
38 |
|
public function __construct( CMB2 $cmb ) { |
118
|
38 |
|
$this->cmb = $cmb; |
119
|
38 |
|
self::$boxes[ $cmb->cmb_id ] = $this; |
|
|
|
|
120
|
|
|
|
121
|
38 |
|
$show_value = $this->cmb->prop( 'show_in_rest' ); |
122
|
|
|
|
123
|
38 |
|
$this->rest_read = self::is_readable( $show_value ); |
124
|
38 |
|
$this->rest_edit = self::is_editable( $show_value ); |
125
|
38 |
|
} |
126
|
|
|
|
127
|
|
|
/** |
128
|
|
|
* Hooks to register on frontend and backend. |
129
|
|
|
* |
130
|
|
|
* @since 2.2.3 |
131
|
|
|
* |
132
|
|
|
* @return void |
133
|
|
|
*/ |
134
|
38 |
|
public function universal_hooks() { |
135
|
|
|
// hook up the CMB rest endpoint classes |
136
|
38 |
|
$this->once( 'rest_api_init', array( __CLASS__, 'init_routes' ), 0 ); |
137
|
|
|
|
138
|
38 |
|
if ( function_exists( 'register_rest_field' ) ) { |
139
|
38 |
|
$this->once( 'rest_api_init', array( __CLASS__, 'register_cmb2_fields' ), 50 ); |
140
|
|
|
} |
141
|
|
|
|
142
|
38 |
|
$this->declare_read_edit_fields(); |
143
|
|
|
|
144
|
38 |
|
add_filter( 'is_protected_meta', array( $this, 'is_protected_meta' ), 10, 3 ); |
145
|
|
|
|
146
|
38 |
|
return $this; |
147
|
|
|
} |
148
|
|
|
|
149
|
|
|
/** |
150
|
|
|
* Initiate the CMB2 Boxes and Fields routes |
151
|
|
|
* |
152
|
|
|
* @since 2.2.3 |
153
|
|
|
* |
154
|
|
|
* @return void |
155
|
|
|
*/ |
156
|
1 |
|
public static function init_routes() { |
157
|
1 |
|
$wp_rest_server = rest_get_server(); |
|
|
|
|
158
|
|
|
|
159
|
1 |
|
$boxes_controller = new CMB2_REST_Controller_Boxes( $wp_rest_server ); |
160
|
1 |
|
$boxes_controller->register_routes(); |
161
|
|
|
|
162
|
1 |
|
$fields_controller = new CMB2_REST_Controller_Fields( $wp_rest_server ); |
163
|
1 |
|
$fields_controller->register_routes(); |
164
|
1 |
|
} |
165
|
|
|
|
166
|
|
|
/** |
167
|
|
|
* Loop through REST boxes and call register_rest_field for each object type. |
168
|
|
|
* |
169
|
|
|
* @since 2.2.3 |
170
|
|
|
* |
171
|
|
|
* @return void |
172
|
|
|
*/ |
173
|
38 |
|
public static function register_cmb2_fields() { |
174
|
38 |
|
$alltypes = $taxonomies = array(); |
175
|
|
|
|
176
|
38 |
|
foreach ( self::$boxes as $cmb_id => $rest_box ) { |
177
|
38 |
|
$types = array_flip( $rest_box->cmb->box_types( array( 'post' ) ) ); |
178
|
|
|
|
179
|
38 |
|
if ( isset( $types['user'] ) ) { |
180
|
10 |
|
unset( $types['user'] ); |
181
|
10 |
|
self::$type_boxes['user'][ $cmb_id ] = $cmb_id; |
182
|
|
|
} |
183
|
|
|
|
184
|
38 |
|
if ( isset( $types['comment'] ) ) { |
185
|
10 |
|
unset( $types['comment'] ); |
186
|
10 |
|
self::$type_boxes['comment'][ $cmb_id ] = $cmb_id; |
187
|
|
|
} |
188
|
|
|
|
189
|
38 |
|
if ( isset( $types['term'] ) ) { |
190
|
10 |
|
unset( $types['term'] ); |
191
|
|
|
|
192
|
10 |
|
$taxonomies = array_merge( |
193
|
10 |
|
$taxonomies, |
194
|
10 |
|
CMB2_Utils::ensure_array( $rest_box->cmb->prop( 'taxonomies' ) ) |
195
|
|
|
); |
196
|
|
|
|
197
|
10 |
|
self::$type_boxes['term'][ $cmb_id ] = $cmb_id; |
198
|
|
|
} |
199
|
|
|
|
200
|
38 |
|
if ( ! empty( $types ) ) { |
201
|
38 |
|
$alltypes = array_merge( $alltypes, array_flip( $types ) ); |
202
|
38 |
|
self::$type_boxes['post'][ $cmb_id ] = $cmb_id; |
203
|
|
|
} |
204
|
|
|
} |
205
|
|
|
|
206
|
38 |
|
$alltypes = array_unique( $alltypes ); |
207
|
|
|
|
208
|
38 |
|
if ( ! empty( $alltypes ) ) { |
209
|
38 |
|
self::register_rest_field( $alltypes, 'post' ); |
|
|
|
|
210
|
|
|
} |
211
|
|
|
|
212
|
38 |
|
if ( ! empty( self::$type_boxes['user'] ) ) { |
213
|
10 |
|
self::register_rest_field( 'user', 'user' ); |
214
|
|
|
} |
215
|
|
|
|
216
|
38 |
|
if ( ! empty( self::$type_boxes['comment'] ) ) { |
217
|
10 |
|
self::register_rest_field( 'comment', 'comment' ); |
218
|
|
|
} |
219
|
|
|
|
220
|
38 |
|
if ( ! empty( self::$type_boxes['term'] ) ) { |
221
|
10 |
|
self::register_rest_field( $taxonomies, 'term' ); |
|
|
|
|
222
|
|
|
} |
223
|
38 |
|
} |
224
|
|
|
|
225
|
|
|
/** |
226
|
|
|
* Wrapper for register_rest_field. |
227
|
|
|
* |
228
|
|
|
* @since 2.2.3 |
229
|
|
|
* |
230
|
|
|
* @param string|array $object_types Object(s) the field is being registered |
231
|
|
|
* to, "post"|"term"|"comment" etc. |
232
|
|
|
* @param string $object_types Canonical object type for callbacks. |
233
|
|
|
* |
234
|
|
|
* @return void |
235
|
|
|
*/ |
236
|
38 |
|
protected static function register_rest_field( $object_types, $object_type ) { |
237
|
38 |
|
register_rest_field( $object_types, 'cmb2', array( |
|
|
|
|
238
|
38 |
|
'get_callback' => array( __CLASS__, "get_{$object_type}_rest_values" ), |
239
|
38 |
|
'update_callback' => array( __CLASS__, "update_{$object_type}_rest_values" ), |
240
|
|
|
'schema' => null, // @todo add schema |
241
|
|
|
) ); |
242
|
38 |
|
} |
243
|
|
|
|
244
|
|
|
/** |
245
|
|
|
* Setup readable and editable fields. |
246
|
|
|
* |
247
|
|
|
* @since 2.2.3 |
248
|
|
|
* |
249
|
|
|
* @return void |
250
|
|
|
*/ |
251
|
38 |
|
protected function declare_read_edit_fields() { |
252
|
38 |
|
foreach ( $this->cmb->prop( 'fields' ) as $field ) { |
253
|
38 |
|
$show_in_rest = isset( $field['show_in_rest'] ) ? $field['show_in_rest'] : null; |
254
|
|
|
|
255
|
38 |
|
if ( false === $show_in_rest ) { |
256
|
|
|
continue; |
257
|
|
|
} |
258
|
|
|
|
259
|
38 |
|
if ( $this->can_read( $show_in_rest ) ) { |
260
|
38 |
|
$this->read_fields[] = $field['id']; |
261
|
|
|
} |
262
|
|
|
|
263
|
38 |
|
if ( $this->can_edit( $show_in_rest ) ) { |
264
|
38 |
|
$this->edit_fields[] = $field['id']; |
265
|
|
|
} |
266
|
|
|
} |
267
|
38 |
|
} |
268
|
|
|
|
269
|
|
|
/** |
270
|
|
|
* Determines if a field is readable based on it's show_in_rest value |
271
|
|
|
* and the box's show_in_rest value. |
272
|
|
|
* |
273
|
|
|
* @since 2.2.3 |
274
|
|
|
* |
275
|
|
|
* @param bool $show_in_rest Field's show_in_rest value. Default null. |
276
|
|
|
* |
277
|
|
|
* @return bool Whether field is readable. |
278
|
|
|
*/ |
279
|
38 |
|
protected function can_read( $show_in_rest ) { |
280
|
|
|
// if 'null', then use default box value. |
281
|
38 |
|
if ( null === $show_in_rest ) { |
|
|
|
|
282
|
38 |
|
return $this->rest_read; |
283
|
|
|
} |
284
|
|
|
|
285
|
|
|
// Else check if the value represents readable. |
286
|
4 |
|
return self::is_readable( $show_in_rest ); |
287
|
|
|
} |
288
|
|
|
|
289
|
|
|
/** |
290
|
|
|
* Determines if a field is editable based on it's show_in_rest value |
291
|
|
|
* and the box's show_in_rest value. |
292
|
|
|
* |
293
|
|
|
* @since 2.2.3 |
294
|
|
|
* |
295
|
|
|
* @param bool $show_in_rest Field's show_in_rest value. Default null. |
296
|
|
|
* |
297
|
|
|
* @return bool Whether field is editable. |
298
|
|
|
*/ |
299
|
38 |
|
protected function can_edit( $show_in_rest ) { |
300
|
|
|
// if 'null', then use default box value. |
301
|
38 |
|
if ( null === $show_in_rest ) { |
|
|
|
|
302
|
38 |
|
return $this->rest_edit; |
303
|
|
|
} |
304
|
|
|
|
305
|
|
|
// Else check if the value represents editable. |
306
|
4 |
|
return self::is_editable( $show_in_rest ); |
307
|
|
|
} |
308
|
|
|
|
309
|
|
|
/** |
310
|
|
|
* Handler for getting post custom field data. |
311
|
|
|
* |
312
|
|
|
* @since 2.2.3 |
313
|
|
|
* |
314
|
|
|
* @param array $object The object data from the response |
315
|
|
|
* @param string $field_name Name of field |
316
|
|
|
* @param WP_REST_Request $request Current request |
|
|
|
|
317
|
|
|
* @param string $object_type The request object type |
318
|
|
|
* |
319
|
|
|
* @return mixed |
320
|
|
|
*/ |
321
|
4 |
|
public static function get_post_rest_values( $object, $field_name, $request, $object_type ) { |
322
|
4 |
|
if ( 'cmb2' === $field_name ) { |
323
|
4 |
|
return self::get_rest_values( $object, $request, $object_type, 'post' ); |
324
|
|
|
} |
325
|
|
|
} |
326
|
|
|
|
327
|
|
|
/** |
328
|
|
|
* Handler for getting user custom field data. |
329
|
|
|
* |
330
|
|
|
* @since 2.2.3 |
331
|
|
|
* |
332
|
|
|
* @param array $object The object data from the response |
333
|
|
|
* @param string $field_name Name of field |
334
|
|
|
* @param WP_REST_Request $request Current request |
335
|
|
|
* @param string $object_type The request object type |
336
|
|
|
* |
337
|
|
|
* @return mixed |
338
|
|
|
*/ |
339
|
2 |
|
public static function get_user_rest_values( $object, $field_name, $request, $object_type ) { |
340
|
2 |
|
if ( 'cmb2' === $field_name ) { |
341
|
2 |
|
return self::get_rest_values( $object, $request, $object_type, 'user' ); |
342
|
|
|
} |
343
|
|
|
} |
344
|
|
|
|
345
|
|
|
/** |
346
|
|
|
* Handler for getting comment custom field data. |
347
|
|
|
* |
348
|
|
|
* @since 2.2.3 |
349
|
|
|
* |
350
|
|
|
* @param array $object The object data from the response |
351
|
|
|
* @param string $field_name Name of field |
352
|
|
|
* @param WP_REST_Request $request Current request |
353
|
|
|
* @param string $object_type The request object type |
354
|
|
|
* |
355
|
|
|
* @return mixed |
356
|
|
|
*/ |
357
|
2 |
|
public static function get_comment_rest_values( $object, $field_name, $request, $object_type ) { |
358
|
2 |
|
if ( 'cmb2' === $field_name ) { |
359
|
2 |
|
return self::get_rest_values( $object, $request, $object_type, 'comment' ); |
360
|
|
|
} |
361
|
|
|
} |
362
|
|
|
|
363
|
|
|
/** |
364
|
|
|
* Handler for getting term custom field data. |
365
|
|
|
* |
366
|
|
|
* @since 2.2.3 |
367
|
|
|
* |
368
|
|
|
* @param array $object The object data from the response |
369
|
|
|
* @param string $field_name Name of field |
370
|
|
|
* @param WP_REST_Request $request Current request |
371
|
|
|
* @param string $object_type The request object type |
372
|
|
|
* |
373
|
|
|
* @return mixed |
374
|
|
|
*/ |
375
|
2 |
|
public static function get_term_rest_values( $object, $field_name, $request, $object_type ) { |
376
|
2 |
|
if ( 'cmb2' === $field_name ) { |
377
|
2 |
|
return self::get_rest_values( $object, $request, $object_type, 'term' ); |
378
|
|
|
} |
379
|
|
|
} |
380
|
|
|
|
381
|
|
|
/** |
382
|
|
|
* Handler for getting custom field data. |
383
|
|
|
* |
384
|
|
|
* @since 2.2.3 |
385
|
|
|
* |
386
|
|
|
* @param array $object The object data from the response |
387
|
|
|
* @param WP_REST_Request $request Current request |
388
|
|
|
* @param string $object_type The request object type |
389
|
|
|
* @param string $main_object_type The cmb main object type |
390
|
|
|
* |
391
|
|
|
* @return mixed |
392
|
|
|
*/ |
393
|
10 |
|
protected static function get_rest_values( $object, $request, $object_type, $main_object_type = 'post' ) { |
394
|
10 |
|
if ( ! isset( $object['id'] ) ) { |
395
|
|
|
return; |
396
|
|
|
} |
397
|
|
|
|
398
|
10 |
|
$values = array(); |
399
|
|
|
|
400
|
10 |
|
if ( ! empty( self::$type_boxes[ $main_object_type ] ) ) { |
401
|
10 |
|
foreach ( self::$type_boxes[ $main_object_type ] as $cmb_id ) { |
402
|
10 |
|
$rest_box = self::$boxes[ $cmb_id ]; |
403
|
|
|
|
404
|
10 |
|
foreach ( $rest_box->read_fields as $field_id ) { |
405
|
10 |
|
$rest_box->cmb->object_id( $object['id'] ); |
406
|
10 |
|
$rest_box->cmb->object_type( $main_object_type ); |
407
|
|
|
|
408
|
10 |
|
$field = $rest_box->cmb->get_field( $field_id ); |
409
|
|
|
|
410
|
10 |
|
$field->object_id( $object['id'] ); |
411
|
10 |
|
$field->object_type( $main_object_type ); |
412
|
|
|
|
413
|
10 |
|
$values[ $cmb_id ][ $field->id( true ) ] = $field->get_data(); |
414
|
|
|
} |
415
|
|
|
} |
416
|
|
|
} |
417
|
|
|
|
418
|
10 |
|
return $values; |
419
|
|
|
} |
420
|
|
|
|
421
|
|
|
/** |
422
|
|
|
* Handler for updating post custom field data. |
423
|
|
|
* |
424
|
|
|
* @since 2.2.3 |
425
|
|
|
* |
426
|
|
|
* @param mixed $values The value of the field |
427
|
|
|
* @param object $object The object from the response |
428
|
|
|
* @param string $field_name Name of field |
429
|
|
|
* @param WP_REST_Request $request Current request |
430
|
|
|
* @param string $object_type The request object type |
431
|
|
|
* |
432
|
|
|
* @return bool|int |
433
|
|
|
*/ |
434
|
2 |
|
public static function update_post_rest_values( $values, $object, $field_name, $request, $object_type ) { |
435
|
2 |
|
if ( 'cmb2' === $field_name ) { |
436
|
2 |
|
return self::update_rest_values( $values, $object, $request, $object_type, 'post' ); |
437
|
|
|
} |
438
|
|
|
} |
439
|
|
|
|
440
|
|
|
/** |
441
|
|
|
* Handler for updating user custom field data. |
442
|
|
|
* |
443
|
|
|
* @since 2.2.3 |
444
|
|
|
* |
445
|
|
|
* @param mixed $values The value of the field |
446
|
|
|
* @param object $object The object from the response |
447
|
|
|
* @param string $field_name Name of field |
448
|
|
|
* @param WP_REST_Request $request Current request |
449
|
|
|
* @param string $object_type The request object type |
450
|
|
|
* |
451
|
|
|
* @return bool|int |
452
|
|
|
*/ |
453
|
1 |
|
public static function update_user_rest_values( $values, $object, $field_name, $request, $object_type ) { |
454
|
1 |
|
if ( 'cmb2' === $field_name ) { |
455
|
1 |
|
return self::update_rest_values( $values, $object, $request, $object_type, 'user' ); |
456
|
|
|
} |
457
|
|
|
} |
458
|
|
|
|
459
|
|
|
/** |
460
|
|
|
* Handler for updating comment custom field data. |
461
|
|
|
* |
462
|
|
|
* @since 2.2.3 |
463
|
|
|
* |
464
|
|
|
* @param mixed $values The value of the field |
465
|
|
|
* @param object $object The object from the response |
466
|
|
|
* @param string $field_name Name of field |
467
|
|
|
* @param WP_REST_Request $request Current request |
468
|
|
|
* @param string $object_type The request object type |
469
|
|
|
* |
470
|
|
|
* @return bool|int |
471
|
|
|
*/ |
472
|
1 |
|
public static function update_comment_rest_values( $values, $object, $field_name, $request, $object_type ) { |
473
|
1 |
|
if ( 'cmb2' === $field_name ) { |
474
|
1 |
|
return self::update_rest_values( $values, $object, $request, $object_type, 'comment' ); |
475
|
|
|
} |
476
|
|
|
} |
477
|
|
|
|
478
|
|
|
/** |
479
|
|
|
* Handler for updating term custom field data. |
480
|
|
|
* |
481
|
|
|
* @since 2.2.3 |
482
|
|
|
* |
483
|
|
|
* @param mixed $values The value of the field |
484
|
|
|
* @param object $object The object from the response |
485
|
|
|
* @param string $field_name Name of field |
486
|
|
|
* @param WP_REST_Request $request Current request |
487
|
|
|
* @param string $object_type The request object type |
488
|
|
|
* |
489
|
|
|
* @return bool|int |
490
|
|
|
*/ |
491
|
1 |
|
public static function update_term_rest_values( $values, $object, $field_name, $request, $object_type ) { |
492
|
1 |
|
if ( 'cmb2' === $field_name ) { |
493
|
1 |
|
return self::update_rest_values( $values, $object, $request, $object_type, 'term' ); |
494
|
|
|
} |
495
|
|
|
} |
496
|
|
|
|
497
|
|
|
/** |
498
|
|
|
* Handler for updating custom field data. |
499
|
|
|
* |
500
|
|
|
* @since 2.2.3 |
501
|
|
|
* |
502
|
|
|
* @param mixed $values The value of the field |
503
|
|
|
* @param object $object The object from the response |
504
|
|
|
* @param WP_REST_Request $request Current request |
505
|
|
|
* @param string $object_type The request object type |
506
|
|
|
* @param string $main_object_type The cmb main object type |
507
|
|
|
* |
508
|
|
|
* @return bool|int |
509
|
|
|
*/ |
510
|
5 |
|
protected static function update_rest_values( $values, $object, $request, $object_type, $main_object_type = 'post' ) { |
511
|
5 |
|
if ( empty( $values ) || ! is_array( $values ) ) { |
512
|
|
|
return; |
513
|
|
|
} |
514
|
|
|
|
515
|
5 |
|
$object_id = self::get_object_id( $object, $main_object_type ); |
516
|
|
|
|
517
|
5 |
|
if ( ! $object_id ) { |
518
|
|
|
return; |
519
|
|
|
} |
520
|
|
|
|
521
|
5 |
|
$updated = array(); |
522
|
|
|
|
523
|
5 |
|
if ( ! empty( self::$type_boxes[ $main_object_type ] ) ) { |
524
|
5 |
|
foreach ( self::$type_boxes[ $main_object_type ] as $cmb_id ) { |
525
|
5 |
|
$rest_box = self::$boxes[ $cmb_id ]; |
526
|
|
|
|
527
|
5 |
|
if ( ! array_key_exists( $cmb_id, $values ) ) { |
528
|
|
|
continue; |
529
|
|
|
} |
530
|
|
|
|
531
|
5 |
|
$rest_box->cmb->object_id( $object_id ); |
532
|
5 |
|
$rest_box->cmb->object_type( $main_object_type ); |
533
|
|
|
|
534
|
5 |
|
$updated[ $cmb_id ] = $rest_box->sanitize_box_values( $values ); |
535
|
|
|
} |
536
|
|
|
} |
537
|
|
|
|
538
|
5 |
|
return $updated; |
539
|
|
|
} |
540
|
|
|
|
541
|
|
|
/** |
542
|
|
|
* Loop through box fields and sanitize the values. |
543
|
|
|
* |
544
|
|
|
* @since 2.2.o |
545
|
|
|
* |
546
|
|
|
* @param array $values Array of values being provided. |
547
|
|
|
* @return array Array of updated/sanitized values. |
548
|
|
|
*/ |
549
|
5 |
|
public function sanitize_box_values( array $values ) { |
550
|
5 |
|
$updated = array(); |
551
|
|
|
|
552
|
5 |
|
$this->cmb->pre_process(); |
553
|
|
|
|
554
|
5 |
|
foreach ( $this->edit_fields as $field_id ) { |
555
|
5 |
|
$updated[ $field_id ] = $this->sanitize_field_value( $values, $field_id ); |
|
|
|
|
556
|
|
|
} |
557
|
|
|
|
558
|
5 |
|
$this->cmb->after_save(); |
559
|
|
|
|
560
|
5 |
|
return $updated; |
561
|
|
|
} |
562
|
|
|
|
563
|
|
|
/** |
564
|
|
|
* Handles returning a sanitized field value. |
565
|
|
|
* |
566
|
|
|
* @since 2.2.3 |
567
|
|
|
* |
568
|
|
|
* @param array $values Array of values being provided. |
569
|
|
|
* @param string $field_id The id of the field to update. |
570
|
|
|
* |
571
|
|
|
* @return mixed The results of saving/sanitizing a field value. |
572
|
|
|
*/ |
573
|
5 |
|
protected function sanitize_field_value( array $values, $field_id ) { |
574
|
5 |
|
if ( ! array_key_exists( $field_id, $values[ $this->cmb->cmb_id ] ) ) { |
|
|
|
|
575
|
4 |
|
return; |
576
|
|
|
} |
577
|
|
|
|
578
|
5 |
|
$field = $this->cmb->get_field( $field_id ); |
579
|
|
|
|
580
|
5 |
|
if ( 'title' == $field->type() ) { |
581
|
|
|
return; |
582
|
|
|
} |
583
|
|
|
|
584
|
5 |
|
$field->object_id( $this->cmb->object_id() ); |
|
|
|
|
585
|
5 |
|
$field->object_type( $this->cmb->object_type() ); |
586
|
|
|
|
587
|
5 |
|
if ( 'group' == $field->type() ) { |
588
|
|
|
return $this->sanitize_group_value( $values, $field ); |
|
|
|
|
589
|
|
|
} |
590
|
|
|
|
591
|
5 |
|
return $field->save_field( $values[ $this->cmb->cmb_id ][ $field_id ] ); |
592
|
|
|
} |
593
|
|
|
|
594
|
|
|
/** |
595
|
|
|
* Handles returning a sanitized group field value. |
596
|
|
|
* |
597
|
|
|
* @since 2.2.3 |
598
|
|
|
* |
599
|
|
|
* @param array $values Array of values being provided. |
600
|
|
|
* @param CMB2_Field $field CMB2_Field object. |
601
|
|
|
* |
602
|
|
|
* @return mixed The results of saving/sanitizing the group field value. |
603
|
|
|
*/ |
604
|
|
|
protected function sanitize_group_value( array $values, CMB2_Field $field ) { |
605
|
|
|
$fields = $field->fields(); |
606
|
|
|
if ( empty( $fields ) ) { |
607
|
|
|
return; |
608
|
|
|
} |
609
|
|
|
|
610
|
|
|
$this->cmb->data_to_save[ $field->_id() ] = $values[ $this->cmb->cmb_id ][ $field->_id() ]; |
|
|
|
|
611
|
|
|
|
612
|
|
|
return $this->cmb->save_group_field( $field ); |
613
|
|
|
} |
614
|
|
|
|
615
|
|
|
/** |
616
|
|
|
* Filter whether a meta key is protected. |
617
|
|
|
* |
618
|
|
|
* @since 2.2.3 |
619
|
|
|
* |
620
|
|
|
* @param bool $protected Whether the key is protected. Default false. |
621
|
|
|
* @param string $meta_key Meta key. |
622
|
|
|
* @param string $meta_type Meta type. |
623
|
|
|
*/ |
624
|
|
|
public function is_protected_meta( $protected, $meta_key, $meta_type ) { |
625
|
|
|
if ( $this->field_can_edit( $meta_key ) ) { |
626
|
|
|
return false; |
627
|
|
|
} |
628
|
|
|
|
629
|
|
|
return $protected; |
630
|
|
|
} |
631
|
|
|
|
632
|
6 |
|
protected static function get_object_id( $object, $object_type = 'post' ) { |
633
|
|
|
switch ( $object_type ) { |
634
|
6 |
|
case 'user': |
635
|
5 |
|
case 'post': |
636
|
4 |
|
if ( isset( $object->ID ) ) { |
|
|
|
|
637
|
4 |
|
return intval( $object->ID ); |
638
|
|
|
} |
639
|
3 |
|
case 'comment': |
640
|
2 |
|
if ( isset( $object->comment_ID ) ) { |
|
|
|
|
641
|
2 |
|
return intval( $object->comment_ID ); |
642
|
|
|
} |
643
|
2 |
|
case 'term': |
644
|
2 |
|
if ( is_array( $object ) && isset( $object['term_id'] ) ) { |
645
|
1 |
|
return intval( $object['term_id'] ); |
646
|
2 |
|
} elseif ( isset( $object->term_id ) ) { |
647
|
2 |
|
return intval( $object->term_id ); |
648
|
|
|
} |
649
|
|
|
} |
650
|
|
|
|
651
|
1 |
|
return 0; |
652
|
|
|
} |
653
|
|
|
|
654
|
|
|
/** |
655
|
|
|
* Checks if a given field can be read. |
656
|
|
|
* |
657
|
|
|
* @since 2.2.3 |
658
|
|
|
* |
659
|
|
|
* @param string|CMB2_Field $field_id Field ID or CMB2_Field object. |
660
|
|
|
* @param boolean $return_object Whether to return the Field object. |
661
|
|
|
* |
662
|
|
|
* @return mixed False if field can't be read or true|CMB2_Field object. |
663
|
|
|
*/ |
664
|
8 |
|
public function field_can_read( $field_id, $return_object = false ) { |
665
|
8 |
|
return $this->field_can( 'read_fields', $field_id, $return_object ); |
666
|
|
|
} |
667
|
|
|
|
668
|
|
|
/** |
669
|
|
|
* Checks if a given field can be edited. |
670
|
|
|
* |
671
|
|
|
* @since 2.2.3 |
672
|
|
|
* |
673
|
|
|
* @param string|CMB2_Field $field_id Field ID or CMB2_Field object. |
674
|
|
|
* @param boolean $return_object Whether to return the Field object. |
675
|
|
|
* |
676
|
|
|
* @return mixed False if field can't be edited or true|CMB2_Field object. |
677
|
|
|
*/ |
678
|
8 |
|
public function field_can_edit( $field_id, $return_object = false ) { |
679
|
8 |
|
return $this->field_can( 'edit_fields', $field_id, $return_object ); |
680
|
|
|
} |
681
|
|
|
|
682
|
|
|
/** |
683
|
|
|
* Checks if a given field can be read or edited. |
684
|
|
|
* |
685
|
|
|
* @since 2.2.3 |
686
|
|
|
* |
687
|
|
|
* @param string $type Whether we are checking for read or edit fields. |
688
|
|
|
* @param string|CMB2_Field $field_id Field ID or CMB2_Field object. |
689
|
|
|
* @param boolean $return_object Whether to return the Field object. |
690
|
|
|
* |
691
|
|
|
* @return mixed False if field can't be read or edited or true|CMB2_Field object. |
692
|
|
|
*/ |
693
|
12 |
|
protected function field_can( $type = 'read_fields', $field_id, $return_object = false ) { |
694
|
12 |
|
if ( ! in_array( $field_id instanceof CMB2_Field ? $field_id->id() : $field_id, $this->{$type}, true ) ) { |
695
|
2 |
|
return false; |
696
|
|
|
} |
697
|
|
|
|
698
|
11 |
|
return $return_object ? $this->cmb->get_field( $field_id ) : true; |
699
|
|
|
} |
700
|
|
|
|
701
|
|
|
/** |
702
|
|
|
* Get a CMB2_REST instance object from the registry by a CMB2 id. |
703
|
|
|
* |
704
|
|
|
* @since 2.2.3 |
705
|
|
|
* |
706
|
|
|
* @param string $cmb_id CMB2 config id |
707
|
|
|
* |
708
|
|
|
* @return CMB2_REST|false The CMB2_REST object or false. |
709
|
|
|
*/ |
710
|
13 |
|
public static function get_rest_box( $cmb_id ) { |
711
|
13 |
|
return isset( self::$boxes[ $cmb_id ] ) ? self::$boxes[ $cmb_id ] : false; |
712
|
|
|
} |
713
|
|
|
|
714
|
|
|
/** |
715
|
|
|
* Remove a CMB2_REST instance object from the registry. |
716
|
|
|
* |
717
|
|
|
* @since 2.2.3 |
718
|
|
|
* |
719
|
|
|
* @param string $cmb_id A CMB2 instance id. |
720
|
|
|
*/ |
721
|
|
|
public static function remove( $cmb_id ) { |
722
|
|
|
if ( array_key_exists( $cmb_id, self::$boxes ) ) { |
723
|
|
|
unset( self::$boxes[ $cmb_id ] ); |
724
|
|
|
} |
725
|
|
|
} |
726
|
|
|
|
727
|
|
|
/** |
728
|
|
|
* Retrieve all CMB2_REST instances from the registry. |
729
|
|
|
* |
730
|
|
|
* @since 2.2.3 |
731
|
|
|
* @return CMB2[] Array of all registered CMB2_REST instances. |
732
|
|
|
*/ |
733
|
38 |
|
public static function get_all() { |
734
|
38 |
|
return self::$boxes; |
735
|
|
|
} |
736
|
|
|
|
737
|
|
|
/** |
738
|
|
|
* Checks if given value is readable. |
739
|
|
|
* |
740
|
|
|
* Value is considered readable if it is not empty and if it does not match the editable blacklist. |
741
|
|
|
* |
742
|
|
|
* @since 2.2.3 |
743
|
|
|
* |
744
|
|
|
* @param mixed $value Value to check. |
745
|
|
|
* |
746
|
|
|
* @return boolean Whether value is considered readable. |
747
|
|
|
*/ |
748
|
38 |
|
public static function is_readable( $value ) { |
749
|
38 |
|
return ! empty( $value ) && ! in_array( $value, array( |
750
|
38 |
|
WP_REST_Server::CREATABLE, |
|
|
|
|
751
|
|
|
WP_REST_Server::EDITABLE, |
752
|
|
|
WP_REST_Server::DELETABLE, |
753
|
38 |
|
), true ); |
754
|
|
|
} |
755
|
|
|
|
756
|
|
|
/** |
757
|
|
|
* Checks if given value is editable. |
758
|
|
|
* |
759
|
|
|
* Value is considered editable if matches the editable whitelist. |
760
|
|
|
* |
761
|
|
|
* @since 2.2.3 |
762
|
|
|
* |
763
|
|
|
* @param mixed $value Value to check. |
764
|
|
|
* |
765
|
|
|
* @return boolean Whether value is considered editable. |
766
|
|
|
*/ |
767
|
38 |
|
public static function is_editable( $value ) { |
768
|
38 |
|
return in_array( $value, array( |
769
|
38 |
|
WP_REST_Server::EDITABLE, |
770
|
|
|
WP_REST_Server::ALLMETHODS, |
771
|
38 |
|
), true ); |
772
|
|
|
} |
773
|
|
|
|
774
|
|
|
/** |
775
|
|
|
* Magic getter for our object. |
776
|
|
|
* |
777
|
|
|
* @param string $field |
778
|
|
|
* @throws Exception Throws an exception if the field is invalid. |
779
|
|
|
* |
780
|
|
|
* @return mixed |
781
|
|
|
*/ |
782
|
17 |
|
public function __get( $field ) { |
783
|
|
|
switch ( $field ) { |
784
|
17 |
|
case 'read_fields': |
785
|
17 |
|
case 'edit_fields': |
786
|
16 |
|
case 'rest_read': |
787
|
3 |
|
case 'rest_edit': |
788
|
17 |
|
return $this->{$field}; |
789
|
|
|
default: |
790
|
|
|
throw new Exception( 'Invalid ' . __CLASS__ . ' property: ' . $field ); |
791
|
|
|
} |
792
|
|
|
} |
793
|
|
|
|
794
|
|
|
} |
795
|
|
|
|
This check looks for function or method calls that always return null and whose return value is used.
The method
getObject()
can return nothing but null, so it makes no sense to use the return value.The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.