PluginProbe
WPGet API – Connect to any external REST API / 2.2.2
WPGet API – Connect to any external REST API v2.2.2
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 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.1.0 2.1.1 2.1.3 2.1.4 2.1.5 2.2.0 2.2.1 2.2.10 2.2.2 2.2.3 All 97 releases
wpgetapi / lib / cmb2 / includes / rest-api / CMB2_REST_Controller.php

CMB2_REST_Controller.php in WPGet API – Connect to any external REST API 2.2.2, at lib/cmb2/includes/rest-api/CMB2_REST_Controller.php

449 lines 10.9 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