WC_REST_Order_Notes_V1_Controller

REST API Order Notes controller class.

Defined (1)

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

/includes/api/v1/class-wc-rest-order-notes-controller.php  
  1. class WC_REST_Order_Notes_V1_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 = 'orders/(?P<order_id>[\d]+)/notes'; 
  14.  
  15. /** 
  16. * Post type. 
  17. * @var string 
  18. */ 
  19. protected $post_type = 'shop_order'; 
  20.  
  21. /** 
  22. * Register the routes for order notes. 
  23. */ 
  24. public function register_routes() { 
  25. register_rest_route( $this->namespace, '/' . $this->rest_base, array( 
  26. 'args' => array( 
  27. 'order_id' => array( 
  28. 'description' => __( 'The order ID.', 'woocommerce' ),  
  29. 'type' => 'integer',  
  30. ),  
  31. ),  
  32. array( 
  33. 'methods' => WP_REST_Server::READABLE,  
  34. 'callback' => array( $this, 'get_items' ),  
  35. 'permission_callback' => array( $this, 'get_items_permissions_check' ),  
  36. 'args' => $this->get_collection_params(),  
  37. ),  
  38. array( 
  39. 'methods' => WP_REST_Server::CREATABLE,  
  40. 'callback' => array( $this, 'create_item' ),  
  41. 'permission_callback' => array( $this, 'create_item_permissions_check' ),  
  42. 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( 
  43. 'note' => array( 
  44. 'type' => 'string',  
  45. 'description' => __( 'Order note content.', 'woocommerce' ),  
  46. 'required' => true,  
  47. ),  
  48. ) ),  
  49. ),  
  50. 'schema' => array( $this, 'get_public_item_schema' ),  
  51. ) ); 
  52.  
  53. register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<id>[\d]+)', array( 
  54. 'args' => array( 
  55. 'id' => array( 
  56. 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ),  
  57. 'type' => 'integer',  
  58. ),  
  59. 'order_id' => array( 
  60. 'description' => __( 'The order ID.', 'woocommerce' ),  
  61. 'type' => 'integer',  
  62. ),  
  63. ),  
  64. array( 
  65. 'methods' => WP_REST_Server::READABLE,  
  66. 'callback' => array( $this, 'get_item' ),  
  67. 'permission_callback' => array( $this, 'get_item_permissions_check' ),  
  68. 'args' => array( 
  69. 'context' => $this->get_context_param( array( 'default' => 'view' ) ),  
  70. ),  
  71. ),  
  72. array( 
  73. 'methods' => WP_REST_Server::DELETABLE,  
  74. 'callback' => array( $this, 'delete_item' ),  
  75. 'permission_callback' => array( $this, 'delete_item_permissions_check' ),  
  76. 'args' => array( 
  77. 'force' => array( 
  78. 'default' => false,  
  79. 'type' => 'boolean',  
  80. 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ),  
  81. ),  
  82. ),  
  83. ),  
  84. 'schema' => array( $this, 'get_public_item_schema' ),  
  85. ) ); 
  86.  
  87. /** 
  88. * Check whether a given request has permission to read order notes. 
  89. * @param WP_REST_Request $request Full details about the request. 
  90. * @return WP_Error|boolean 
  91. */ 
  92. public function get_items_permissions_check( $request ) { 
  93. if ( ! wc_rest_check_post_permissions( $this->post_type, 'read' ) ) { 
  94. return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); 
  95.  
  96. return true; 
  97.  
  98. /** 
  99. * Check if a given request has access create order notes. 
  100. * @param WP_REST_Request $request Full details about the request. 
  101. * @return boolean 
  102. */ 
  103. public function create_item_permissions_check( $request ) { 
  104. if ( ! wc_rest_check_post_permissions( $this->post_type, 'create' ) ) { 
  105. return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); 
  106.  
  107. return true; 
  108.  
  109. /** 
  110. * Check if a given request has access to read a order note. 
  111. * @param WP_REST_Request $request Full details about the request. 
  112. * @return WP_Error|boolean 
  113. */ 
  114. public function get_item_permissions_check( $request ) { 
  115. $order = wc_get_order( (int) $request['order_id'] ); 
  116.  
  117. if ( $order && ! wc_rest_check_post_permissions( $this->post_type, 'read', $order->get_id() ) ) { 
  118. return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); 
  119.  
  120. return true; 
  121.  
  122. /** 
  123. * Check if a given request has access delete a order note. 
  124. * @param WP_REST_Request $request Full details about the request. 
  125. * @return boolean 
  126. */ 
  127. public function delete_item_permissions_check( $request ) { 
  128. $order = wc_get_order( (int) $request['order_id'] ); 
  129.  
  130. if ( $order && ! wc_rest_check_post_permissions( $this->post_type, 'delete', $order->get_id() ) ) { 
  131. return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); 
  132.  
  133. return true; 
  134.  
  135. /** 
  136. * Get order notes from an order. 
  137. * @param WP_REST_Request $request 
  138. * @return array 
  139. */ 
  140. public function get_items( $request ) { 
  141. $order = wc_get_order( (int) $request['order_id'] ); 
  142.  
  143. if ( ! $order || $this->post_type !== $order->get_type() ) { 
  144. return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); 
  145.  
  146. $args = array( 
  147. 'post_id' => $order->get_id(),  
  148. 'approve' => 'approve',  
  149. 'type' => 'order_note',  
  150. ); 
  151.  
  152. remove_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10, 1 ); 
  153.  
  154. $notes = get_comments( $args ); 
  155.  
  156. add_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10, 1 ); 
  157.  
  158. $data = array(); 
  159. foreach ( $notes as $note ) { 
  160. $order_note = $this->prepare_item_for_response( $note, $request ); 
  161. $order_note = $this->prepare_response_for_collection( $order_note ); 
  162. $data[] = $order_note; 
  163.  
  164. return rest_ensure_response( $data ); 
  165.  
  166. /** 
  167. * Create a single order note. 
  168. * @param WP_REST_Request $request Full details about the request. 
  169. * @return WP_Error|WP_REST_Response 
  170. */ 
  171. public function create_item( $request ) { 
  172. if ( ! empty( $request['id'] ) ) { 
  173. /** translators: %s: post type */ 
  174. return new WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) ); 
  175.  
  176. $order = wc_get_order( (int) $request['order_id'] ); 
  177.  
  178. if ( ! $order || $this->post_type !== $order->get_type() ) { 
  179. return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); 
  180.  
  181. // Create the note. 
  182. $note_id = $order->add_order_note( $request['note'], $request['customer_note'] ); 
  183.  
  184. if ( ! $note_id ) { 
  185. return new WP_Error( 'woocommerce_api_cannot_create_order_note', __( 'Cannot create order note, please try again.', 'woocommerce' ), array( 'status' => 500 ) ); 
  186.  
  187. $note = get_comment( $note_id ); 
  188. $this->update_additional_fields_for_object( $note, $request ); 
  189.  
  190. /** 
  191. * Fires after a order note is created or updated via the REST API. 
  192. * @param WP_Comment $note New order note object. 
  193. * @param WP_REST_Request $request Request object. 
  194. * @param boolean $creating True when creating item, false when updating. 
  195. */ 
  196. do_action( 'woocommerce_rest_insert_order_note', $note, $request, true ); 
  197.  
  198. $request->set_param( 'context', 'edit' ); 
  199. $response = $this->prepare_item_for_response( $note, $request ); 
  200. $response = rest_ensure_response( $response ); 
  201. $response->set_status( 201 ); 
  202. $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, str_replace( '(?P<order_id>[\d]+)', $order->get_id(), $this->rest_base ), $note_id ) ) ); 
  203.  
  204. return $response; 
  205.  
  206. /** 
  207. * Get a single order note. 
  208. * @param WP_REST_Request $request Full details about the request. 
  209. * @return WP_Error|WP_REST_Response 
  210. */ 
  211. public function get_item( $request ) { 
  212. $id = (int) $request['id']; 
  213. $order = wc_get_order( (int) $request['order_id'] ); 
  214.  
  215. if ( ! $order || $this->post_type !== $order->get_type() ) { 
  216. return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); 
  217.  
  218. $note = get_comment( $id ); 
  219.  
  220. if ( empty( $id ) || empty( $note ) || intval( $note->comment_post_ID ) !== intval( $order->get_id() ) ) { 
  221. return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); 
  222.  
  223. $order_note = $this->prepare_item_for_response( $note, $request ); 
  224. $response = rest_ensure_response( $order_note ); 
  225.  
  226. return $response; 
  227.  
  228. /** 
  229. * Delete a single order note. 
  230. * @param WP_REST_Request $request Full details about the request. 
  231. * @return WP_REST_Response|WP_Error 
  232. */ 
  233. public function delete_item( $request ) { 
  234. $id = (int) $request['id']; 
  235. $force = isset( $request['force'] ) ? (bool) $request['force'] : false; 
  236.  
  237. // We don't support trashing for this type, error out. 
  238. if ( ! $force ) { 
  239. return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Webhooks do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); 
  240.  
  241. $order = wc_get_order( (int) $request['order_id'] ); 
  242.  
  243. if ( ! $order || $this->post_type !== $order->get_type() ) { 
  244. return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); 
  245.  
  246. $note = get_comment( $id ); 
  247.  
  248. if ( empty( $id ) || empty( $note ) || intval( $note->comment_post_ID ) !== intval( $order->get_id() ) ) { 
  249. return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); 
  250.  
  251. $request->set_param( 'context', 'edit' ); 
  252. $response = $this->prepare_item_for_response( $note, $request ); 
  253.  
  254. $result = wp_delete_comment( $note->comment_ID, true ); 
  255.  
  256. if ( ! $result ) { 
  257. return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), 'order_note' ), array( 'status' => 500 ) ); 
  258.  
  259. /** 
  260. * Fires after a order note is deleted or trashed via the REST API. 
  261. * @param WP_Comment $note The deleted or trashed order note. 
  262. * @param WP_REST_Response $response The response data. 
  263. * @param WP_REST_Request $request The request sent to the API. 
  264. */ 
  265. do_action( 'woocommerce_rest_delete_order_note', $note, $response, $request ); 
  266.  
  267. return $response; 
  268.  
  269. /** 
  270. * Prepare a single order note output for response. 
  271. * @param WP_Comment $note Order note object. 
  272. * @param WP_REST_Request $request Request object. 
  273. * @return WP_REST_Response $response Response data. 
  274. */ 
  275. public function prepare_item_for_response( $note, $request ) { 
  276. $data = array( 
  277. 'id' => (int) $note->comment_ID,  
  278. 'date_created' => wc_rest_prepare_date_response( $note->comment_date_gmt ),  
  279. 'note' => $note->comment_content,  
  280. 'customer_note' => (bool) get_comment_meta( $note->comment_ID, 'is_customer_note', true ),  
  281. ); 
  282.  
  283. $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; 
  284. $data = $this->add_additional_fields_to_object( $data, $request ); 
  285. $data = $this->filter_response_by_context( $data, $context ); 
  286.  
  287. // Wrap the data in a response object. 
  288. $response = rest_ensure_response( $data ); 
  289.  
  290. $response->add_links( $this->prepare_links( $note ) ); 
  291.  
  292. /** 
  293. * Filter order note object returned from the REST API. 
  294. * @param WP_REST_Response $response The response object. 
  295. * @param WP_Comment $note Order note object used to create response. 
  296. * @param WP_REST_Request $request Request object. 
  297. */ 
  298. return apply_filters( 'woocommerce_rest_prepare_order_note', $response, $note, $request ); 
  299.  
  300. /** 
  301. * Prepare links for the request. 
  302. * @param WP_Comment $note Delivery order_note object. 
  303. * @return array Links for the given order note. 
  304. */ 
  305. protected function prepare_links( $note ) { 
  306. $order_id = (int) $note->comment_post_ID; 
  307. $base = str_replace( '(?P<order_id>[\d]+)', $order_id, $this->rest_base ); 
  308. $links = array( 
  309. 'self' => array( 
  310. 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $note->comment_ID ) ),  
  311. ),  
  312. 'collection' => array( 
  313. 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $base ) ),  
  314. ),  
  315. 'up' => array( 
  316. 'href' => rest_url( sprintf( '/%s/orders/%d', $this->namespace, $order_id ) ),  
  317. ),  
  318. ); 
  319.  
  320. return $links; 
  321.  
  322. /** 
  323. * Get the Order Notes schema, conforming to JSON Schema. 
  324. * @return array 
  325. */ 
  326. public function get_item_schema() { 
  327. $schema = array( 
  328. '$schema' => 'http://json-schema.org/draft-04/schema#',  
  329. 'title' => 'order_note',  
  330. 'type' => 'object',  
  331. 'properties' => array( 
  332. 'id' => array( 
  333. 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ),  
  334. 'type' => 'integer',  
  335. 'context' => array( 'view', 'edit' ),  
  336. 'readonly' => true,  
  337. ),  
  338. 'date_created' => array( 
  339. 'description' => __( "The date the order note was created, in the site's timezone.", 'woocommerce' ),  
  340. 'type' => 'date-time',  
  341. 'context' => array( 'view', 'edit' ),  
  342. 'readonly' => true,  
  343. ),  
  344. 'note' => array( 
  345. 'description' => __( 'Order note.', 'woocommerce' ),  
  346. 'type' => 'string',  
  347. 'context' => array( 'view', 'edit' ),  
  348. ),  
  349. 'customer_note' => array( 
  350. 'description' => __( 'Shows/define if the note is only for reference or for the customer (the user will be notified).', 'woocommerce' ),  
  351. 'type' => 'boolean',  
  352. 'default' => false,  
  353. 'context' => array( 'view', 'edit' ),  
  354. ),  
  355. ),  
  356. ); 
  357.  
  358. return $this->add_additional_fields_schema( $schema ); 
  359.  
  360. /** 
  361. * Get the query params for collections. 
  362. * @return array 
  363. */ 
  364. public function get_collection_params() { 
  365. return array( 
  366. 'context' => $this->get_context_param( array( 'default' => 'view' ) ),  
  367. );