PluginProbe
Cool Flipbox – Shortcode & Gutenberg Block / 1.4
Cool Flipbox – Shortcode & Gutenberg Block v1.4
trunk 1.4 1.5 1.6 1.6.2 1.7.1 1.8.3 1.9.0 1.9.1 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.1
flip-boxes / CMB2 / includes / rest-api / CMB2_REST_Controller.php

CMB2_REST_Controller.php in Cool Flipbox – Shortcode & Gutenberg Block 1.4, at CMB2/includes/rest-api/CMB2_REST_Controller.php

449 lines 11.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! class_exists( 'WP_REST_Controller' ) ) {
3 // Shim the WP_REST_Controller class if wp-api plugin not installed, & not in core.
4 require_once cmb2_dir( 'includes/shim/WP_REST_Controller.php' );
5 }
6
7 /**
8 * Creates CMB2 objects/fields endpoint for WordPres REST API.
9 * Allows access to fields registered to a specific post type and more.
10 *
11 * @todo Add better documentation.
12 * @todo Research proper schema.
13 *
14 * @since 2.2.3
15 *
16 * @category WordPress_Plugin
17 * @package CMB2
18 * @author CMB2 team
19 * @license GPL-2.0+
20 * @link https://cmb2.io
21 */
22 abstract class CMB2_REST_Controller extends WP_REST_Controller {
23
24 /**
25 * The namespace of this controller's route.
26 *
27 * @var string
28 */
29 protected $namespace = CMB2_REST::NAME_SPACE;
30
31 /**
32 * The base of this controller's route.
33 *
34 * @var string
35 */
36 protected $rest_base;
37
38 /**
39 * The current request object
40 *
41 * @var WP_REST_Request $request
42 * @since 2.2.3
43 */
44 public $request;
45
46 /**
47 * The current server object
48 *
49 * @var WP_REST_Server $server
50 * @since 2.2.3
51 */
52 public $server;
53
54 /**
55 * Box object id
56 *
57 * @var mixed
58 * @since 2.2.3
59 */
60 public $object_id = null;
61
62 /**
63 * Box object type
64 *
65 * @var string
66 * @since 2.2.3
67 */
68 public $object_type = '';
69
70 /**
71 * CMB2 Instance
72 *
73 * @var CMB2_REST
74 */
75 protected $rest_box;
76
77 /**
78 * CMB2_Field Instance
79 *
80 * @var CMB2_Field
81 */
82 protected $field;
83
84 /**
85 * The initial route
86 *
87 * @var string
88 * @since 2.2.3
89 */
90 protected static $route = '';
91
92 /**
93 * Defines which endpoint the initial request is.
94 *
95 * @var string $request_type
96 * @since 2.2.3
97 */
98 protected static $request_type = '';
99
100 /**
101 * Constructor
102 *
103 * @since 2.2.3
104 */
105 public function __construct( WP_REST_Server $wp_rest_server ) {
106 $this->server = $wp_rest_server;
107 }
108
109 /**
110 * A wrapper for `apply_filters` which checks for box/field properties to hook to the filter.
111 *
112 * Checks if a CMB object callback property exists, and if it does,
113 * hook it to the permissions filter.
114 *
115 * @since 2.2.3
116 *
117 * @param string $filter The name of the filter to apply.
118 * @param bool $default_access The default access for this request.
119 *
120 * @return void
121 */
122 public function maybe_hook_callback_and_apply_filters( $filter, $default_access ) {
123 if ( ! $this->rest_box && $this->request->get_param( 'cmb_id' ) ) {
124 $this->rest_box = CMB2_REST::get_rest_box( $this->request->get_param( 'cmb_id' ) );
125 }
126
127 $default_access = $this->maybe_hook_registered_callback( $filter, $default_access );
128
129 /**
130 * Apply the permissions check filter.
131 *
132 * @since 2.2.3
133 *
134 * @param bool $default_access Whether this CMB2 endpoint can be accessed.
135 * @param object $controller This CMB2_REST_Controller object.
136 */
137 $default_access = apply_filters( $filter, $default_access, $this );
138
139 $this->maybe_unhook_registered_callback( $filter );
140
141 return $default_access;
142 }
143
144 /**
145 * Checks if the CMB2 box has any registered callback parameters for the given filter.
146 *
147 * The registered handlers will have a property name which matches the filter, except:
148 * - The 'cmb2_api' prefix will be removed
149 * - A '_cb' suffix will be added (to stay inline with other '*_cb' parameters).
150 *
151 * @since 2.2.3
152 *
153 * @param string $filter The filter name.
154 * @param bool $default_val The default filter value.
155 *
156 * @return bool The possibly-modified filter value (if the '*_cb' param is non-callable).
157 */
158 public function maybe_hook_registered_callback( $filter, $default_val ) {
159 if ( ! $this->rest_box || is_wp_error( $this->rest_box ) ) {
160 return $default_val;
161 }
162
163 // Hook box specific filter callbacks.
164 $val = $this->rest_box->cmb->maybe_hook_parameter( $filter, $default_val );
165 if ( null !== $val ) {
166 $default_val = $val;
167 }
168
169 return $default_val;
170 }
171
172 /**
173 * Unhooks any CMB2 box registered callback parameters for the given filter.
174 *
175 * @since 2.2.3
176 *
177 * @param string $filter The filter name.
178 *
179 * @return void
180 */
181 public function maybe_unhook_registered_callback( $filter ) {
182 if ( ! $this->rest_box || is_wp_error( $this->rest_box ) ) {
183 return;
184 }
185
186 // Unhook box specific filter callbacks.
187 $this->rest_box->cmb->maybe_hook_parameter( $filter, null, 'remove_filter' );
188 }
189
190 /**
191 * Prepare a CMB2 object for serialization
192 *
193 * @since 2.2.3
194 *
195 * @param mixed $data
196 * @return array $data
197 */
198 public function prepare_item( $data ) {
199 return $this->prepare_item_for_response( $data, $this->request );
200 }
201
202 /**
203 * Output buffers a callback and returns the results.
204 *
205 * @since 2.2.3
206 *
207 * @param mixed $cb Callable function/method.
208 * @return mixed Results of output buffer after calling function/method.
209 */
210 public function get_cb_results( $cb ) {
211 $args = func_get_args();
212 array_shift( $args ); // ignore $cb
213 ob_start();
214 call_user_func_array( $cb, $args );
215
216 return ob_get_clean();
217 }
218
219 /**
220 * Prepare the CMB2 item for the REST response.
221 *
222 * @since 2.2.3
223 *
224 * @param mixed $item WordPress representation of the item.
225 * @param WP_REST_Request $request Request object.
226 * @return WP_REST_Response $response
227 */
228 public function prepare_item_for_response( $data, $request = null ) {
229 $data = $this->filter_response_by_context( $data, $this->request['context'] );
230
231 /**
232 * Filter the prepared CMB2 item response.
233 *
234 * @since 2.2.3
235 *
236 * @param mixed $data Prepared data
237 * @param object $request The WP_REST_Request object
238 * @param object $cmb2_endpoints This endpoints object
239 */
240 return apply_filters( 'cmb2_rest_prepare', rest_ensure_response( $data ), $this->request, $this );
241 }
242
243 /**
244 * Initiates the request property and the rest_box property if box is readable.
245 *
246 * @since 2.2.3
247 *
248 * @param WP_REST_Request $request Request object.
249 * @param string $request_type A description of the type of request being made.
250 *
251 * @return void
252 */
253 protected function initiate_rest_read_box( $request, $request_type ) {
254 $this->initiate_rest_box( $request, $request_type );
255
256 if ( ! is_wp_error( $this->rest_box ) && ! $this->rest_box->rest_read ) {
257 $this->rest_box = new WP_Error( 'cmb2_rest_no_read_error', __( 'This box does not have read permissions.', 'cmb2' ), array(
258 'status' => 403,
259 ) );
260 }
261 }
262
263 /**
264 * Initiates the request property and the rest_box property if box is writeable.
265 *
266 * @since 2.2.3
267 *
268 * @param WP_REST_Request $request Request object.
269 * @param string $request_type A description of the type of request being made.
270 *
271 * @return void
272 */
273 protected function initiate_rest_edit_box( $request, $request_type ) {
274 $this->initiate_rest_box( $request, $request_type );
275
276 if ( ! is_wp_error( $this->rest_box ) && ! $this->rest_box->rest_edit ) {
277 $this->rest_box = new WP_Error( 'cmb2_rest_no_write_error', __( 'This box does not have write permissions.', 'cmb2' ), array(
278 'status' => 403,
279 ) );
280 }
281 }
282
283 /**
284 * Initiates the request property and the rest_box property.
285 *
286 * @since 2.2.3
287 *
288 * @param WP_REST_Request $request Request object.
289 * @param string $request_type A description of the type of request being made.
290 *
291 * @return void
292 */
293 protected function initiate_rest_box( $request, $request_type ) {
294 $this->initiate_request( $request, $request_type );
295
296 $this->rest_box = CMB2_REST::get_rest_box( $this->request->get_param( 'cmb_id' ) );
297
298 if ( ! $this->rest_box ) {
299
300 $this->rest_box = new WP_Error( 'cmb2_rest_box_not_found_error', __( 'No box found by that id. A box needs to be registered with the "show_in_rest" parameter configured.', 'cmb2' ), array(
301 'status' => 403,
302 ) );
303
304 } else {
305
306 if ( isset( $this->request['object_id'] ) ) {
307 $this->rest_box->cmb->object_id( sanitize_text_field( $this->request['object_id'] ) );
308 }
309
310 if ( isset( $this->request['object_type'] ) ) {
311 $this->rest_box->cmb->object_type( sanitize_text_field( $this->request['object_type'] ) );
312 }
313 }
314 }
315
316 /**
317 * Initiates the request property and sets up the initial static properties.
318 *
319 * @since 2.2.3
320 *
321 * @param WP_REST_Request $request Request object.
322 * @param string $request_type A description of the type of request being made.
323 *
324 * @return void
325 */
326 public function initiate_request( $request, $request_type ) {
327 $this->request = $request;
328
329 if ( ! isset( $this->request['context'] ) || empty( $this->request['context'] ) ) {
330 $this->request['context'] = 'view';
331 }
332
333 if ( ! self::$request_type ) {
334 self::$request_type = $request_type;
335 }
336
337 if ( ! self::$route ) {
338 self::$route = $this->request->get_route();
339 }
340 }
341
342 /**
343 * Useful when getting `_embed`-ed items
344 *
345 * @since 2.2.3
346 *
347 * @return string Initial requested type.
348 */
349 public static function get_intial_request_type() {
350 return self::$request_type;
351 }
352
353 /**
354 * Useful when getting `_embed`-ed items
355 *
356 * @since 2.2.3
357 *
358 * @return string Initial requested route.
359 */
360 public static function get_intial_route() {
361 return self::$route;
362 }
363
364 /**
365 * Get CMB2 fields schema, conforming to JSON Schema
366 *
367 * @since 2.2.3
368 *
369 * @return array
370 */
371 public function get_item_schema() {
372 $schema = array(
373 '$schema' => 'http://json-schema.org/draft-04/schema#',
374 'title' => 'CMB2',
375 'type' => 'object',
376 'properties' => array(
377 'description' => array(
378 'description' => __( 'A human-readable description of the object.', 'cmb2' ),
379 'type' => 'string',
380 'context' => array(
381 'view',
382 ),
383 ),
384 'name' => array(
385 'description' => __( 'The id for the object.', 'cmb2' ),
386 'type' => 'integer',
387 'context' => array(
388 'view',
389 ),
390 ),
391 'name' => array(
392 'description' => __( 'The title for the object.', 'cmb2' ),
393 'type' => 'string',
394 'context' => array(
395 'view',
396 ),
397 ),
398 ),
399 );
400
401 return $this->add_additional_fields_schema( $schema );
402 }
403
404 /**
405 * Return an array of contextual links for endpoint/object
406 *
407 * @link http://v2.wp-api.org/extending/linking/
408 * @link http://www.iana.org/assignments/link-relations/link-relations.xhtml
409 *
410 * @since 2.2.3
411 *
412 * @param mixed $object Object to build links from.
413 *
414 * @return array Array of links
415 */
416 abstract protected function prepare_links( $object );
417
418 /**
419 * Get whitelisted query strings from URL for appending to link URLS.
420 *
421 * @since 2.2.3
422 *
423 * @return string URL query stringl
424 */
425 public function get_query_string() {
426 $defaults = array(
427 'object_id' => 0,
428 'object_type' => '',
429 '_rendered' => '',
430 // '_embed' => '',
431 );
432
433 $query_string = '';
434
435 foreach ( $defaults as $key => $value ) {
436 if ( isset( $this->request[ $key ] ) ) {
437 $query_string .= $query_string ? '&' : '?';
438 $query_string .= $key;
439 if ( $value = sanitize_text_field( $this->request[ $key ] ) ) {
440 $query_string .= '=' . $value;
441 }
442 }
443 }
444
445 return $query_string;
446 }
447
448 }
449