PageRenderTime 49ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-content/plugins/woocommerce/includes/legacy/api/v1/class-wc-api-orders.php

https://gitlab.com/campus-academy/krowkaramel
PHP | 396 lines | 224 code | 67 blank | 105 comment | 10 complexity | 5a154dc9559fa5f44e47219369ad775b MD5 | raw file
  1. <?php
  2. /**
  3. * WooCommerce API Orders Class
  4. *
  5. * Handles requests to the /orders endpoint
  6. *
  7. * @author WooThemes
  8. * @category API
  9. * @package WooCommerce\RestApi
  10. * @since 2.1
  11. * @version 2.1
  12. */
  13. if ( ! defined( 'ABSPATH' ) ) {
  14. exit; // Exit if accessed directly
  15. }
  16. class WC_API_Orders extends WC_API_Resource {
  17. /** @var string $base the route base */
  18. protected $base = '/orders';
  19. /**
  20. * Register the routes for this class
  21. *
  22. * GET /orders
  23. * GET /orders/count
  24. * GET|PUT /orders/<id>
  25. * GET /orders/<id>/notes
  26. *
  27. * @since 2.1
  28. * @param array $routes
  29. * @return array
  30. */
  31. public function register_routes( $routes ) {
  32. # GET /orders
  33. $routes[ $this->base ] = array(
  34. array( array( $this, 'get_orders' ), WC_API_Server::READABLE ),
  35. );
  36. # GET /orders/count
  37. $routes[ $this->base . '/count' ] = array(
  38. array( array( $this, 'get_orders_count' ), WC_API_Server::READABLE ),
  39. );
  40. # GET|PUT /orders/<id>
  41. $routes[ $this->base . '/(?P<id>\d+)' ] = array(
  42. array( array( $this, 'get_order' ), WC_API_Server::READABLE ),
  43. array( array( $this, 'edit_order' ), WC_API_Server::EDITABLE | WC_API_Server::ACCEPT_DATA ),
  44. );
  45. # GET /orders/<id>/notes
  46. $routes[ $this->base . '/(?P<id>\d+)/notes' ] = array(
  47. array( array( $this, 'get_order_notes' ), WC_API_Server::READABLE ),
  48. );
  49. return $routes;
  50. }
  51. /**
  52. * Get all orders
  53. *
  54. * @since 2.1
  55. * @param string $fields
  56. * @param array $filter
  57. * @param string $status
  58. * @param int $page
  59. * @return array
  60. */
  61. public function get_orders( $fields = null, $filter = array(), $status = null, $page = 1 ) {
  62. if ( ! empty( $status ) ) {
  63. $filter['status'] = $status;
  64. }
  65. $filter['page'] = $page;
  66. $query = $this->query_orders( $filter );
  67. $orders = array();
  68. foreach ( $query->posts as $order_id ) {
  69. if ( ! $this->is_readable( $order_id ) ) {
  70. continue;
  71. }
  72. $orders[] = current( $this->get_order( $order_id, $fields ) );
  73. }
  74. $this->server->add_pagination_headers( $query );
  75. return array( 'orders' => $orders );
  76. }
  77. /**
  78. * Get the order for the given ID
  79. *
  80. * @since 2.1
  81. * @param int $id the order ID
  82. * @param array $fields
  83. * @return array|WP_Error
  84. */
  85. public function get_order( $id, $fields = null ) {
  86. // ensure order ID is valid & user has permission to read
  87. $id = $this->validate_request( $id, 'shop_order', 'read' );
  88. if ( is_wp_error( $id ) ) {
  89. return $id;
  90. }
  91. $order = wc_get_order( $id );
  92. $order_data = array(
  93. 'id' => $order->get_id(),
  94. 'order_number' => $order->get_order_number(),
  95. 'created_at' => $this->server->format_datetime( $order->get_date_created() ? $order->get_date_created()->getTimestamp() : 0, false, false ), // API gives UTC times.
  96. 'updated_at' => $this->server->format_datetime( $order->get_date_modified() ? $order->get_date_modified()->getTimestamp() : 0, false, false ), // API gives UTC times.
  97. 'completed_at' => $this->server->format_datetime( $order->get_date_completed() ? $order->get_date_completed()->getTimestamp() : 0, false, false ), // API gives UTC times.
  98. 'status' => $order->get_status(),
  99. 'currency' => $order->get_currency(),
  100. 'total' => wc_format_decimal( $order->get_total(), 2 ),
  101. 'subtotal' => wc_format_decimal( $this->get_order_subtotal( $order ), 2 ),
  102. 'total_line_items_quantity' => $order->get_item_count(),
  103. 'total_tax' => wc_format_decimal( $order->get_total_tax(), 2 ),
  104. 'total_shipping' => wc_format_decimal( $order->get_shipping_total(), 2 ),
  105. 'cart_tax' => wc_format_decimal( $order->get_cart_tax(), 2 ),
  106. 'shipping_tax' => wc_format_decimal( $order->get_shipping_tax(), 2 ),
  107. 'total_discount' => wc_format_decimal( $order->get_total_discount(), 2 ),
  108. 'cart_discount' => wc_format_decimal( 0, 2 ),
  109. 'order_discount' => wc_format_decimal( 0, 2 ),
  110. 'shipping_methods' => $order->get_shipping_method(),
  111. 'payment_details' => array(
  112. 'method_id' => $order->get_payment_method(),
  113. 'method_title' => $order->get_payment_method_title(),
  114. 'paid' => ! is_null( $order->get_date_paid() ),
  115. ),
  116. 'billing_address' => array(
  117. 'first_name' => $order->get_billing_first_name(),
  118. 'last_name' => $order->get_billing_last_name(),
  119. 'company' => $order->get_billing_company(),
  120. 'address_1' => $order->get_billing_address_1(),
  121. 'address_2' => $order->get_billing_address_2(),
  122. 'city' => $order->get_billing_city(),
  123. 'state' => $order->get_billing_state(),
  124. 'postcode' => $order->get_billing_postcode(),
  125. 'country' => $order->get_billing_country(),
  126. 'email' => $order->get_billing_email(),
  127. 'phone' => $order->get_billing_phone(),
  128. ),
  129. 'shipping_address' => array(
  130. 'first_name' => $order->get_shipping_first_name(),
  131. 'last_name' => $order->get_shipping_last_name(),
  132. 'company' => $order->get_shipping_company(),
  133. 'address_1' => $order->get_shipping_address_1(),
  134. 'address_2' => $order->get_shipping_address_2(),
  135. 'city' => $order->get_shipping_city(),
  136. 'state' => $order->get_shipping_state(),
  137. 'postcode' => $order->get_shipping_postcode(),
  138. 'country' => $order->get_shipping_country(),
  139. ),
  140. 'note' => $order->get_customer_note(),
  141. 'customer_ip' => $order->get_customer_ip_address(),
  142. 'customer_user_agent' => $order->get_customer_user_agent(),
  143. 'customer_id' => $order->get_user_id(),
  144. 'view_order_url' => $order->get_view_order_url(),
  145. 'line_items' => array(),
  146. 'shipping_lines' => array(),
  147. 'tax_lines' => array(),
  148. 'fee_lines' => array(),
  149. 'coupon_lines' => array(),
  150. );
  151. // add line items
  152. foreach ( $order->get_items() as $item_id => $item ) {
  153. $product = $item->get_product();
  154. $order_data['line_items'][] = array(
  155. 'id' => $item_id,
  156. 'subtotal' => wc_format_decimal( $order->get_line_subtotal( $item ), 2 ),
  157. 'total' => wc_format_decimal( $order->get_line_total( $item ), 2 ),
  158. 'total_tax' => wc_format_decimal( $order->get_line_tax( $item ), 2 ),
  159. 'price' => wc_format_decimal( $order->get_item_total( $item ), 2 ),
  160. 'quantity' => $item->get_quantity(),
  161. 'tax_class' => $item->get_tax_class(),
  162. 'name' => $item->get_name(),
  163. 'product_id' => $item->get_variation_id() ? $item->get_variation_id() : $item->get_product_id(),
  164. 'sku' => is_object( $product ) ? $product->get_sku() : null,
  165. );
  166. }
  167. // add shipping
  168. foreach ( $order->get_shipping_methods() as $shipping_item_id => $shipping_item ) {
  169. $order_data['shipping_lines'][] = array(
  170. 'id' => $shipping_item_id,
  171. 'method_id' => $shipping_item->get_method_id(),
  172. 'method_title' => $shipping_item->get_name(),
  173. 'total' => wc_format_decimal( $shipping_item->get_total(), 2 ),
  174. );
  175. }
  176. // add taxes
  177. foreach ( $order->get_tax_totals() as $tax_code => $tax ) {
  178. $order_data['tax_lines'][] = array(
  179. 'code' => $tax_code,
  180. 'title' => $tax->label,
  181. 'total' => wc_format_decimal( $tax->amount, 2 ),
  182. 'compound' => (bool) $tax->is_compound,
  183. );
  184. }
  185. // add fees
  186. foreach ( $order->get_fees() as $fee_item_id => $fee_item ) {
  187. $order_data['fee_lines'][] = array(
  188. 'id' => $fee_item_id,
  189. 'title' => $fee_item->get_name(),
  190. 'tax_class' => $fee_item->get_tax_class(),
  191. 'total' => wc_format_decimal( $order->get_line_total( $fee_item ), 2 ),
  192. 'total_tax' => wc_format_decimal( $order->get_line_tax( $fee_item ), 2 ),
  193. );
  194. }
  195. // add coupons
  196. foreach ( $order->get_items( 'coupon' ) as $coupon_item_id => $coupon_item ) {
  197. $order_data['coupon_lines'][] = array(
  198. 'id' => $coupon_item_id,
  199. 'code' => $coupon_item->get_code(),
  200. 'amount' => wc_format_decimal( $coupon_item->get_discount(), 2 ),
  201. );
  202. }
  203. return array( 'order' => apply_filters( 'woocommerce_api_order_response', $order_data, $order, $fields, $this->server ) );
  204. }
  205. /**
  206. * Get the total number of orders
  207. *
  208. * @since 2.1
  209. *
  210. * @param string $status
  211. * @param array $filter
  212. *
  213. * @return array|WP_Error
  214. */
  215. public function get_orders_count( $status = null, $filter = array() ) {
  216. if ( ! empty( $status ) ) {
  217. $filter['status'] = $status;
  218. }
  219. $query = $this->query_orders( $filter );
  220. if ( ! current_user_can( 'read_private_shop_orders' ) ) {
  221. return new WP_Error( 'woocommerce_api_user_cannot_read_orders_count', __( 'You do not have permission to read the orders count', 'woocommerce' ), array( 'status' => 401 ) );
  222. }
  223. return array( 'count' => (int) $query->found_posts );
  224. }
  225. /**
  226. * Edit an order
  227. *
  228. * API v1 only allows updating the status of an order
  229. *
  230. * @since 2.1
  231. * @param int $id the order ID
  232. * @param array $data
  233. * @return array|WP_Error
  234. */
  235. public function edit_order( $id, $data ) {
  236. $id = $this->validate_request( $id, 'shop_order', 'edit' );
  237. if ( is_wp_error( $id ) ) {
  238. return $id;
  239. }
  240. $order = wc_get_order( $id );
  241. if ( ! empty( $data['status'] ) ) {
  242. $order->update_status( $data['status'], isset( $data['note'] ) ? $data['note'] : '' );
  243. }
  244. return $this->get_order( $id );
  245. }
  246. /**
  247. * Delete an order
  248. *
  249. * @param int $id the order ID
  250. * @param bool $force true to permanently delete order, false to move to trash
  251. * @return array
  252. */
  253. public function delete_order( $id, $force = false ) {
  254. $id = $this->validate_request( $id, 'shop_order', 'delete' );
  255. return $this->delete( $id, 'order', ( 'true' === $force ) );
  256. }
  257. /**
  258. * Get the admin order notes for an order
  259. *
  260. * @since 2.1
  261. * @param int $id the order ID
  262. * @param string $fields fields to include in response
  263. * @return array|WP_Error
  264. */
  265. public function get_order_notes( $id, $fields = null ) {
  266. // ensure ID is valid order ID
  267. $id = $this->validate_request( $id, 'shop_order', 'read' );
  268. if ( is_wp_error( $id ) ) {
  269. return $id;
  270. }
  271. $args = array(
  272. 'post_id' => $id,
  273. 'approve' => 'approve',
  274. 'type' => 'order_note',
  275. );
  276. remove_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10, 1 );
  277. $notes = get_comments( $args );
  278. add_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10, 1 );
  279. $order_notes = array();
  280. foreach ( $notes as $note ) {
  281. $order_notes[] = array(
  282. 'id' => $note->comment_ID,
  283. 'created_at' => $this->server->format_datetime( $note->comment_date_gmt ),
  284. 'note' => $note->comment_content,
  285. 'customer_note' => (bool) get_comment_meta( $note->comment_ID, 'is_customer_note', true ),
  286. );
  287. }
  288. return array( 'order_notes' => apply_filters( 'woocommerce_api_order_notes_response', $order_notes, $id, $fields, $notes, $this->server ) );
  289. }
  290. /**
  291. * Helper method to get order post objects
  292. *
  293. * @since 2.1
  294. * @param array $args request arguments for filtering query
  295. * @return WP_Query
  296. */
  297. private function query_orders( $args ) {
  298. // set base query arguments
  299. $query_args = array(
  300. 'fields' => 'ids',
  301. 'post_type' => 'shop_order',
  302. 'post_status' => array_keys( wc_get_order_statuses() ),
  303. );
  304. // add status argument
  305. if ( ! empty( $args['status'] ) ) {
  306. $statuses = 'wc-' . str_replace( ',', ',wc-', $args['status'] );
  307. $statuses = explode( ',', $statuses );
  308. $query_args['post_status'] = $statuses;
  309. unset( $args['status'] );
  310. }
  311. $query_args = $this->merge_query_args( $query_args, $args );
  312. return new WP_Query( $query_args );
  313. }
  314. /**
  315. * Helper method to get the order subtotal
  316. *
  317. * @since 2.1
  318. * @param WC_Order $order
  319. * @return float
  320. */
  321. private function get_order_subtotal( $order ) {
  322. $subtotal = 0;
  323. // subtotal
  324. foreach ( $order->get_items() as $item ) {
  325. $subtotal += $item->get_subtotal();
  326. }
  327. return $subtotal;
  328. }
  329. }