PageRenderTime 54ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-order-notes-v1-controller.php

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