WC_REST_Posts_Controller

Abstract Rest Posts Controller Class.

Defined (1)

The class is defined in the following location(s).

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