Completed
Push — master ( 15aa29...17da96 )
by Claudio
18:39 queued 11s
created

abstracts/abstract-wc-rest-posts-controller.php (3 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * Abstract Rest Posts Controller Class
4
 *
5
 * @class WC_REST_Posts_Controller
6
 * @package WooCommerce/Abstracts
7
 */
8
9 1
if ( ! defined( 'ABSPATH' ) ) {
10
	exit;
11
}
12
13
/**
14
 * WC_REST_Posts_Controller
15
 *
16
 * @package  WooCommerce/Abstracts
17
 * @version  2.6.0
18
 */
19
abstract class WC_REST_Posts_Controller extends WC_REST_Controller {
20
21
	/**
22
	 * Endpoint namespace.
23
	 *
24
	 * @var string
25
	 */
26
	protected $namespace = 'wc/v1';
27
28
	/**
29
	 * Route base.
30
	 *
31
	 * @var string
32
	 */
33
	protected $rest_base = '';
34
35
	/**
36
	 * Post type.
37
	 *
38
	 * @var string
39
	 */
40
	protected $post_type = '';
41
42
	/**
43
	 * Controls visibility on frontend.
44
	 *
45
	 * @var string
46
	 */
47
	protected $public = false;
48
49
	/**
50
	 * Check if a given request has access to read items.
51
	 *
52
	 * @param  WP_REST_Request $request Full details about the request.
53
	 * @return WP_Error|boolean
54
	 */
55 60
	public function get_items_permissions_check( $request ) {
56 60
		if ( ! wc_rest_check_post_permissions( $this->post_type, 'read' ) ) {
57 14
			return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
58
		}
59
60 46
		return true;
61
	}
62
63
	/**
64
	 * Check if a given request has access to create an item.
65
	 *
66
	 * @param  WP_REST_Request $request Full details about the request.
67
	 * @return WP_Error|boolean
68
	 */
69 60
	public function create_item_permissions_check( $request ) {
70 60
		if ( ! wc_rest_check_post_permissions( $this->post_type, 'create' ) ) {
71 14
			return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
72
		}
73
74 46
		return true;
75
	}
76
77
	/**
78
	 * Check if a given request has access to read an item.
79
	 *
80
	 * @param  WP_REST_Request $request Full details about the request.
81
	 * @return WP_Error|boolean
82
	 */
83 View Code Duplication
	public function get_item_permissions_check( $request ) {
0 ignored issues
show
This method seems to be duplicated in 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...
84
		$post = get_post( (int) $request['id'] );
85
86
		if ( $post && ! wc_rest_check_post_permissions( $this->post_type, 'read', $post->ID ) ) {
87
			return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
88
		}
89
90
		return true;
91
	}
92
93
	/**
94
	 * Check if a given request has access to update an item.
95
	 *
96
	 * @param  WP_REST_Request $request Full details about the request.
97
	 * @return WP_Error|boolean
98
	 */
99 View Code Duplication
	public function update_item_permissions_check( $request ) {
0 ignored issues
show
This method seems to be duplicated in 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...
100
		$post = get_post( (int) $request['id'] );
101
102
		if ( $post && ! wc_rest_check_post_permissions( $this->post_type, 'edit', $post->ID ) ) {
103
			return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
104
		}
105
106
		return true;
107
	}
108
109
	/**
110
	 * Check if a given request has access to delete an item.
111
	 *
112
	 * @param  WP_REST_Request $request Full details about the request.
113
	 * @return bool|WP_Error
114
	 */
115 View Code Duplication
	public function delete_item_permissions_check( $request ) {
0 ignored issues
show
This method seems to be duplicated in 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...
116
		$post = get_post( (int) $request['id'] );
117
118
		if ( $post && ! wc_rest_check_post_permissions( $this->post_type, 'delete', $post->ID ) ) {
119
			return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
120
		}
121
122
		return true;
123
	}
124
125
	/**
126
	 * Check if a given request has access batch create, update and delete items.
127
	 *
128
	 * @param  WP_REST_Request $request Full details about the request.
129
	 *
130
	 * @return boolean|WP_Error
131
	 */
132 8
	public function batch_items_permissions_check( $request ) {
133 8
		if ( ! wc_rest_check_post_permissions( $this->post_type, 'batch' ) ) {
134
			return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
135
		}
136
137 8
		return true;
138
	}
139
140
	/**
141
	 * Get a single item.
142
	 *
143
	 * @param WP_REST_Request $request Full details about the request.
144
	 * @return WP_Error|WP_REST_Response
145
	 */
146
	public function get_item( $request ) {
147
		$id   = (int) $request['id'];
148
		$post = get_post( $id );
149
150 View Code Duplication
		if ( ! empty( $post->post_type ) && 'product_variation' === $post->post_type && 'product' === $this->post_type ) {
151
			return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'To manipulate product variations you should use the /products/&lt;product_id&gt;/variations/&lt;id&gt; endpoint.', 'woocommerce' ), array( 'status' => 404 ) );
152
		} elseif ( empty( $id ) || empty( $post->ID ) || $post->post_type !== $this->post_type ) {
153
			return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) );
154
		}
155
156
		$data = $this->prepare_item_for_response( $post, $request );
157
		$response = rest_ensure_response( $data );
158
159
		if ( $this->public ) {
160
			$response->link_header( 'alternate', get_permalink( $id ), array( 'type' => 'text/html' ) );
161
		}
162
163
		return $response;
164
	}
165
166
	/**
167
	 * Create a single item.
168
	 *
169
	 * @param WP_REST_Request $request Full details about the request.
170
	 * @return WP_Error|WP_REST_Response
171
	 */
172
	public function create_item( $request ) {
173
		if ( ! empty( $request['id'] ) ) {
174
			/* translators: %s: post type */
175
			return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) );
176
		}
177
178
		$post = $this->prepare_item_for_database( $request );
179
		if ( is_wp_error( $post ) ) {
180
			return $post;
181
		}
182
183
		$post->post_type = $this->post_type;
184
		$post_id         = wp_insert_post( $post, true );
185
186 View Code Duplication
		if ( is_wp_error( $post_id ) ) {
187
188
			if ( in_array( $post_id->get_error_code(), array( 'db_insert_error' ) ) ) {
189
				$post_id->add_data( array( 'status' => 500 ) );
190
			} else {
191
				$post_id->add_data( array( 'status' => 400 ) );
192
			}
193
			return $post_id;
194
		}
195
		$post->ID = $post_id;
196
		$post     = get_post( $post_id );
197
198
		$this->update_additional_fields_for_object( $post, $request );
199
200
		// Add meta fields.
201
		$meta_fields = $this->add_post_meta_fields( $post, $request );
202
		if ( is_wp_error( $meta_fields ) ) {
203
			// Remove post.
204
			$this->delete_post( $post );
205
206
			return $meta_fields;
207
		}
208
209
		/**
210
		 * Fires after a single item is created or updated via the REST API.
211
		 *
212
		 * @param WP_Post         $post      Post object.
213
		 * @param WP_REST_Request $request   Request object.
214
		 * @param boolean         $creating  True when creating item, false when updating.
215
		 */
216
		do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, true );
217
218
		$request->set_param( 'context', 'edit' );
219
		$response = $this->prepare_item_for_response( $post, $request );
220
		$response = rest_ensure_response( $response );
221
		$response->set_status( 201 );
222
		$response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $post_id ) ) );
223
224
		return $response;
225
	}
226
227
	/**
228
	 * Add post meta fields.
229
	 *
230
	 * @param WP_Post         $post Post Object.
231
	 * @param WP_REST_Request $request WP_REST_Request Object.
232
	 * @return bool|WP_Error
233
	 */
234
	protected function add_post_meta_fields( $post, $request ) {
235
		return true;
236
	}
237
238
	/**
239
	 * Delete post.
240
	 *
241
	 * @param WP_Post $post Post object.
242
	 */
243
	protected function delete_post( $post ) {
244
		wp_delete_post( $post->ID, true );
245
	}
246
247
	/**
248
	 * Update a single post.
249
	 *
250
	 * @param WP_REST_Request $request Full details about the request.
251
	 * @return WP_Error|WP_REST_Response
252
	 */
253
	public function update_item( $request ) {
254
		$id   = (int) $request['id'];
255
		$post = get_post( $id );
256
257 View Code Duplication
		if ( ! empty( $post->post_type ) && 'product_variation' === $post->post_type && 'product' === $this->post_type ) {
258
			return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'To manipulate product variations you should use the /products/&lt;product_id&gt;/variations/&lt;id&gt; endpoint.', 'woocommerce' ), array( 'status' => 404 ) );
259
		} elseif ( empty( $id ) || empty( $post->ID ) || $post->post_type !== $this->post_type ) {
260
			return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) );
261
		}
262
263
		$post = $this->prepare_item_for_database( $request );
264
		if ( is_wp_error( $post ) ) {
265
			return $post;
266
		}
267
		// Convert the post object to an array, otherwise wp_update_post will expect non-escaped input.
268
		$post_id = wp_update_post( (array) $post, true );
269 View Code Duplication
		if ( is_wp_error( $post_id ) ) {
270
			if ( in_array( $post_id->get_error_code(), array( 'db_update_error' ) ) ) {
271
				$post_id->add_data( array( 'status' => 500 ) );
272
			} else {
273
				$post_id->add_data( array( 'status' => 400 ) );
274
			}
275
			return $post_id;
276
		}
277
278
		$post = get_post( $post_id );
279
		$this->update_additional_fields_for_object( $post, $request );
280
281
		// Update meta fields.
282
		$meta_fields = $this->update_post_meta_fields( $post, $request );
283
		if ( is_wp_error( $meta_fields ) ) {
284
			return $meta_fields;
285
		}
286
287
		/**
288
		 * Fires after a single item is created or updated via the REST API.
289
		 *
290
		 * @param WP_Post         $post      Post object.
291
		 * @param WP_REST_Request $request   Request object.
292
		 * @param boolean         $creating  True when creating item, false when updating.
293
		 */
294
		do_action( "woocommerce_rest_insert_{$this->post_type}", $post, $request, false );
295
296
		$request->set_param( 'context', 'edit' );
297
		$response = $this->prepare_item_for_response( $post, $request );
298
		return rest_ensure_response( $response );
299
	}
300
301
	/**
302
	 * Get a collection of posts.
303
	 *
304
	 * @param WP_REST_Request $request Full details about the request.
305
	 * @return WP_Error|WP_REST_Response
306
	 */
307
	public function get_items( $request ) {
308
		$args                         = array();
309
		$args['offset']               = $request['offset'];
310
		$args['order']                = $request['order'];
311
		$args['orderby']              = $request['orderby'];
312
		$args['paged']                = $request['page'];
313
		$args['post__in']             = $request['include'];
314
		$args['post__not_in']         = $request['exclude'];
315
		$args['posts_per_page']       = $request['per_page'];
316
		$args['name']                 = $request['slug'];
317
		$args['post_parent__in']      = $request['parent'];
318
		$args['post_parent__not_in']  = $request['parent_exclude'];
319
		$args['s']                    = $request['search'];
320
321
		$args['date_query'] = array();
322
		// Set before into date query. Date query must be specified as an array of an array.
323 View Code Duplication
		if ( isset( $request['before'] ) ) {
324
			$args['date_query'][0]['before'] = $request['before'];
325
		}
326
327
		// Set after into date query. Date query must be specified as an array of an array.
328 View Code Duplication
		if ( isset( $request['after'] ) ) {
329
			$args['date_query'][0]['after'] = $request['after'];
330
		}
331
332 View Code Duplication
		if ( 'wc/v1' === $this->namespace ) {
333
			if ( is_array( $request['filter'] ) ) {
334
				$args = array_merge( $args, $request['filter'] );
335
				unset( $args['filter'] );
336
			}
337
		}
338
339
		// Force the post_type argument, since it's not a user input variable.
340
		$args['post_type'] = $this->post_type;
341
342
		/**
343
		 * Filter the query arguments for a request.
344
		 *
345
		 * Enables adding extra arguments or setting defaults for a post
346
		 * collection request.
347
		 *
348
		 * @param array           $args    Key value array of query var to query value.
349
		 * @param WP_REST_Request $request The request used.
350
		 */
351
		$args = apply_filters( "woocommerce_rest_{$this->post_type}_query", $args, $request );
352
		$query_args = $this->prepare_items_query( $args, $request );
353
354
		$posts_query = new WP_Query();
355
		$query_result = $posts_query->query( $query_args );
356
357
		$posts = array();
358
		foreach ( $query_result as $post ) {
359
			if ( ! wc_rest_check_post_permissions( $this->post_type, 'read', $post->ID ) ) {
360
				continue;
361
			}
362
363
			$data = $this->prepare_item_for_response( $post, $request );
364
			$posts[] = $this->prepare_response_for_collection( $data );
365
		}
366
367
		$page = (int) $query_args['paged'];
368
		$total_posts = $posts_query->found_posts;
369
370 View Code Duplication
		if ( $total_posts < 1 ) {
371
			// Out-of-bounds, run the query again without LIMIT for total count.
372
			unset( $query_args['paged'] );
373
			$count_query = new WP_Query();
374
			$count_query->query( $query_args );
375
			$total_posts = $count_query->found_posts;
376
		}
377
378
		$max_pages = ceil( $total_posts / (int) $query_args['posts_per_page'] );
379
380
		$response = rest_ensure_response( $posts );
381
		$response->header( 'X-WP-Total', (int) $total_posts );
382
		$response->header( 'X-WP-TotalPages', (int) $max_pages );
383
384
		$request_params = $request->get_query_params();
385
		if ( ! empty( $request_params['filter'] ) ) {
386
			// Normalize the pagination params.
387
			unset( $request_params['filter']['posts_per_page'] );
388
			unset( $request_params['filter']['paged'] );
389
		}
390
		$base = add_query_arg( $request_params, rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ) );
391
392
		if ( $page > 1 ) {
393
			$prev_page = $page - 1;
394
			if ( $prev_page > $max_pages ) {
395
				$prev_page = $max_pages;
396
			}
397
			$prev_link = add_query_arg( 'page', $prev_page, $base );
398
			$response->link_header( 'prev', $prev_link );
399
		}
400
		if ( $max_pages > $page ) {
401
			$next_page = $page + 1;
402
			$next_link = add_query_arg( 'page', $next_page, $base );
403
			$response->link_header( 'next', $next_link );
404
		}
405
406
		return $response;
407
	}
408
409
	/**
410
	 * Delete a single item.
411
	 *
412
	 * @param WP_REST_Request $request Full details about the request.
413
	 * @return WP_REST_Response|WP_Error
414
	 */
415
	public function delete_item( $request ) {
416
		$id    = (int) $request['id'];
417
		$force = (bool) $request['force'];
418
		$post  = get_post( $id );
419
420
		if ( empty( $id ) || empty( $post->ID ) || $post->post_type !== $this->post_type ) {
421
			return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 404 ) );
422
		}
423
424
		$supports_trash = EMPTY_TRASH_DAYS > 0;
425
426
		/**
427
		 * Filter whether an item is trashable.
428
		 *
429
		 * Return false to disable trash support for the item.
430
		 *
431
		 * @param boolean $supports_trash Whether the item type support trashing.
432
		 * @param WP_Post $post           The Post object being considered for trashing support.
433
		 */
434
		$supports_trash = apply_filters( "woocommerce_rest_{$this->post_type}_trashable", $supports_trash, $post );
435
436 View Code Duplication
		if ( ! wc_rest_check_post_permissions( $this->post_type, 'delete', $post->ID ) ) {
437
			/* translators: %s: post type */
438
			return new WP_Error( "woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf( __( 'Sorry, you are not allowed to delete %s.', 'woocommerce' ), $this->post_type ), array( 'status' => rest_authorization_required_code() ) );
439
		}
440
441
		$request->set_param( 'context', 'edit' );
442
		$response = $this->prepare_item_for_response( $post, $request );
443
444
		// If we're forcing, then delete permanently.
445
		if ( $force ) {
446
			$result = wp_delete_post( $id, true );
447 View Code Duplication
		} else {
448
			// If we don't support trashing for this type, error out.
449
			if ( ! $supports_trash ) {
450
				/* translators: %s: post type */
451
				return new WP_Error( 'woocommerce_rest_trash_not_supported', sprintf( __( 'The %s does not support trashing.', 'woocommerce' ), $this->post_type ), array( 'status' => 501 ) );
452
			}
453
454
			// Otherwise, only trash if we haven't already.
455
			if ( 'trash' === $post->post_status ) {
456
				/* translators: %s: post type */
457
				return new WP_Error( 'woocommerce_rest_already_trashed', sprintf( __( 'The %s has already been deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 410 ) );
458
			}
459
460
			// (Note that internally this falls through to `wp_delete_post` if
461
			// the trash is disabled.)
462
			$result = wp_trash_post( $id );
463
		}
464
465
		if ( ! $result ) {
466
			/* translators: %s: post type */
467
			return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 500 ) );
468
		}
469
470
		/**
471
		 * Fires after a single item is deleted or trashed via the REST API.
472
		 *
473
		 * @param object           $post     The deleted or trashed item.
474
		 * @param WP_REST_Response $response The response data.
475
		 * @param WP_REST_Request  $request  The request sent to the API.
476
		 */
477
		do_action( "woocommerce_rest_delete_{$this->post_type}", $post, $response, $request );
478
479
		return $response;
480
	}
481
482
	/**
483
	 * Prepare links for the request.
484
	 *
485
	 * @param WP_Post         $post Post object.
486
	 * @param WP_REST_Request $request Request object.
487
	 * @return array Links for the given post.
488
	 */
489
	protected function prepare_links( $post, $request ) {
490
		$links = array(
491
			'self' => array(
492
				'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $post->ID ) ),
493
			),
494
			'collection' => array(
495
				'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ),
496
			),
497
		);
498
499
		return $links;
500
	}
501
502
	/**
503
	 * Determine the allowed query_vars for a get_items() response and
504
	 * prepare for WP_Query.
505
	 *
506
	 * @param array           $prepared_args Prepared arguments.
507
	 * @param WP_REST_Request $request Request object.
508
	 * @return array          $query_args
509
	 */
510 39
	protected function prepare_items_query( $prepared_args = array(), $request = null ) {
511
512 39
		$valid_vars = array_flip( $this->get_allowed_query_vars() );
513 39
		$query_args = array();
514 39
		foreach ( $valid_vars as $var => $index ) {
515 39
			if ( isset( $prepared_args[ $var ] ) ) {
516
				/**
517
				 * Filter the query_vars used in `get_items` for the constructed query.
518
				 *
519
				 * The dynamic portion of the hook name, $var, refers to the query_var key.
520
				 *
521
				 * @param mixed $prepared_args[ $var ] The query_var value.
522
				 */
523 39
				$query_args[ $var ] = apply_filters( "woocommerce_rest_query_var-{$var}", $prepared_args[ $var ] );
524
			}
525
		}
526
527 39
		$query_args['ignore_sticky_posts'] = true;
528
529 39
		if ( 'include' === $query_args['orderby'] ) {
530
			$query_args['orderby'] = 'post__in';
531 39
		} elseif ( 'id' === $query_args['orderby'] ) {
532 1
			$query_args['orderby'] = 'ID'; // ID must be capitalized.
533 39
		} elseif ( 'slug' === $query_args['orderby'] ) {
534
			$query_args['orderby'] = 'name';
535
		}
536
537 39
		return $query_args;
538
	}
539
540
	/**
541
	 * Get all the WP Query vars that are allowed for the API request.
542
	 *
543
	 * @return array
544
	 */
545 39
	protected function get_allowed_query_vars() {
546
		global $wp;
547
548
		/**
549
		 * Filter the publicly allowed query vars.
550
		 *
551
		 * Allows adjusting of the default query vars that are made public.
552
		 *
553
		 * @param array  Array of allowed WP_Query query vars.
554
		 */
555 39
		$valid_vars = apply_filters( 'query_vars', $wp->public_query_vars );
556
557 39
		$post_type_obj = get_post_type_object( $this->post_type );
558 39
		if ( current_user_can( $post_type_obj->cap->edit_posts ) ) {
559
			/**
560
			 * Filter the allowed 'private' query vars for authorized users.
561
			 *
562
			 * If the user has the `edit_posts` capability, we also allow use of
563
			 * private query parameters, which are only undesirable on the
564
			 * frontend, but are safe for use in query strings.
565
			 *
566
			 * To disable anyway, use
567
			 * `add_filter( 'woocommerce_rest_private_query_vars', '__return_empty_array' );`
568
			 *
569
			 * @param array $private_query_vars Array of allowed query vars for authorized users.
570
			 * }
571
			 */
572 32
			$private = apply_filters( 'woocommerce_rest_private_query_vars', $wp->private_query_vars );
573 32
			$valid_vars = array_merge( $valid_vars, $private );
574
		}
575
		// Define our own in addition to WP's normal vars.
576
		$rest_valid = array(
577 39
			'date_query',
578
			'ignore_sticky_posts',
579
			'offset',
580
			'post__in',
581
			'post__not_in',
582
			'post_parent',
583
			'post_parent__in',
584
			'post_parent__not_in',
585
			'posts_per_page',
586
			'meta_query',
587
			'tax_query',
588
			'meta_key',
589
			'meta_value',
590
			'meta_compare',
591
			'meta_value_num',
592
		);
593 39
		$valid_vars = array_merge( $valid_vars, $rest_valid );
594
595
		/**
596
		 * Filter allowed query vars for the REST API.
597
		 *
598
		 * This filter allows you to add or remove query vars from the final allowed
599
		 * list for all requests, including unauthenticated ones. To alter the
600
		 * vars for editors only.
601
		 *
602
		 * @param array {
603
		 *    Array of allowed WP_Query query vars.
604
		 *
605
		 *    @param string $allowed_query_var The query var to allow.
606
		 * }
607
		 */
608 39
		$valid_vars = apply_filters( 'woocommerce_rest_query_vars', $valid_vars );
609
610 39
		return $valid_vars;
611
	}
612
613
	/**
614
	 * Get the query params for collections of attachments.
615
	 *
616
	 * @return array
617
	 */
618 426
	public function get_collection_params() {
619 426
		$params = parent::get_collection_params();
620
621 426
		$params['context']['default'] = 'view';
622
623 426
		$params['after'] = array(
624 426
			'description'        => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce' ),
625 426
			'type'               => 'string',
626 426
			'format'             => 'date-time',
627 426
			'validate_callback'  => 'rest_validate_request_arg',
628
		);
629 426
		$params['before'] = array(
630 426
			'description'        => __( 'Limit response to resources published before a given ISO8601 compliant date.', 'woocommerce' ),
631 426
			'type'               => 'string',
632 426
			'format'             => 'date-time',
633 426
			'validate_callback'  => 'rest_validate_request_arg',
634
		);
635 426
		$params['exclude'] = array(
636 426
			'description'       => __( 'Ensure result set excludes specific IDs.', 'woocommerce' ),
637 426
			'type'              => 'array',
638
			'items'             => array(
639
				'type'          => 'integer',
640
			),
641
			'default'           => array(),
642 426
			'sanitize_callback' => 'wp_parse_id_list',
643
		);
644 426
		$params['include'] = array(
645 426
			'description'       => __( 'Limit result set to specific ids.', 'woocommerce' ),
646 426
			'type'              => 'array',
647
			'items'             => array(
648
				'type'          => 'integer',
649
			),
650
			'default'           => array(),
651 426
			'sanitize_callback' => 'wp_parse_id_list',
652
		);
653 426
		$params['offset'] = array(
654 426
			'description'        => __( 'Offset the result set by a specific number of items.', 'woocommerce' ),
655 426
			'type'               => 'integer',
656 426
			'sanitize_callback'  => 'absint',
657 426
			'validate_callback'  => 'rest_validate_request_arg',
658
		);
659 426
		$params['order'] = array(
660 426
			'description'        => __( 'Order sort attribute ascending or descending.', 'woocommerce' ),
661 426
			'type'               => 'string',
662 426
			'default'            => 'desc',
663
			'enum'               => array( 'asc', 'desc' ),
664 426
			'validate_callback'  => 'rest_validate_request_arg',
665
		);
666 426
		$params['orderby'] = array(
667 426
			'description'        => __( 'Sort collection by object attribute.', 'woocommerce' ),
668 426
			'type'               => 'string',
669 426
			'default'            => 'date',
670
			'enum'               => array(
671
				'date',
672
				'id',
673
				'include',
674
				'title',
675
				'slug',
676
			),
677 426
			'validate_callback'  => 'rest_validate_request_arg',
678
		);
679
680 426
		$post_type_obj = get_post_type_object( $this->post_type );
681
682 426 View Code Duplication
		if ( isset( $post_type_obj->hierarchical ) && $post_type_obj->hierarchical ) {
683
			$params['parent'] = array(
684
				'description'       => __( 'Limit result set to those of particular parent IDs.', 'woocommerce' ),
685
				'type'              => 'array',
686
				'items'             => array(
687
					'type'          => 'integer',
688
				),
689
				'sanitize_callback' => 'wp_parse_id_list',
690
				'default'           => array(),
691
			);
692
			$params['parent_exclude'] = array(
693
				'description'       => __( 'Limit result set to all items except those of a particular parent ID.', 'woocommerce' ),
694
				'type'              => 'array',
695
				'items'             => array(
696
					'type'          => 'integer',
697
				),
698
				'sanitize_callback' => 'wp_parse_id_list',
699
				'default'           => array(),
700
			);
701
		}
702
703 426
		if ( 'wc/v1' === $this->namespace ) {
704 426
			$params['filter'] = array(
705 426
				'type'        => 'object',
706 426
				'description' => __( 'Use WP Query arguments to modify the response; private query vars require appropriate authorization.', 'woocommerce' ),
707
			);
708
		}
709
710 426
		return $params;
711
	}
712
713
	/**
714
	 * Update post meta fields.
715
	 *
716
	 * @param WP_Post         $post Post object.
717
	 * @param WP_REST_Request $request Request object.
718
	 * @return bool|WP_Error
719
	 */
720
	protected function update_post_meta_fields( $post, $request ) {
721
		return true;
722
	}
723
}
724