WC_Order

Order Class.

Defined (1)

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

/includes/class-wc-order.php  
  1. class WC_Order extends WC_Abstract_Order { 
  2.  
  3. /** 
  4. * Stores data about status changes so relevant hooks can be fired. 
  5. * @var bool|array 
  6. */ 
  7. protected $status_transition = false; 
  8.  
  9. /** 
  10. * Order Data array. This is the core order data exposed in APIs since 3.0.0. 
  11. * @since 3.0.0 
  12. * @var array 
  13. */ 
  14. protected $data = array( 
  15. // Abstract order props 
  16. 'parent_id' => 0,  
  17. 'status' => '',  
  18. 'currency' => '',  
  19. 'version' => '',  
  20. 'prices_include_tax' => false,  
  21. 'date_created' => null,  
  22. 'date_modified' => null,  
  23. 'discount_total' => 0,  
  24. 'discount_tax' => 0,  
  25. 'shipping_total' => 0,  
  26. 'shipping_tax' => 0,  
  27. 'cart_tax' => 0,  
  28. 'total' => 0,  
  29. 'total_tax' => 0,  
  30.  
  31. // Order props 
  32. 'customer_id' => 0,  
  33. 'order_key' => '',  
  34. 'billing' => array( 
  35. 'first_name' => '',  
  36. 'last_name' => '',  
  37. 'company' => '',  
  38. 'address_1' => '',  
  39. 'address_2' => '',  
  40. 'city' => '',  
  41. 'state' => '',  
  42. 'postcode' => '',  
  43. 'country' => '',  
  44. 'email' => '',  
  45. 'phone' => '',  
  46. ),  
  47. 'shipping' => array( 
  48. 'first_name' => '',  
  49. 'last_name' => '',  
  50. 'company' => '',  
  51. 'address_1' => '',  
  52. 'address_2' => '',  
  53. 'city' => '',  
  54. 'state' => '',  
  55. 'postcode' => '',  
  56. 'country' => '',  
  57. ),  
  58. 'payment_method' => '',  
  59. 'payment_method_title' => '',  
  60. 'transaction_id' => '',  
  61. 'customer_ip_address' => '',  
  62. 'customer_user_agent' => '',  
  63. 'created_via' => '',  
  64. 'customer_note' => '',  
  65. 'date_completed' => null,  
  66. 'date_paid' => null,  
  67. 'cart_hash' => '',  
  68. ); 
  69.  
  70. /** 
  71. * When a payment is complete this function is called. 
  72. * Most of the time this should mark an order as 'processing' so that admin can process/post the items. 
  73. * If the cart contains only downloadable items then the order is 'completed' since the admin needs to take no action. 
  74. * Stock levels are reduced at this point. 
  75. * Sales are also recorded for products. 
  76. * Finally, record the date of payment. 
  77. * Order must exist. 
  78. * @param string $transaction_id Optional transaction id to store in post meta. 
  79. * @return bool success 
  80. */ 
  81. public function payment_complete( $transaction_id = '' ) { 
  82. try { 
  83. if ( ! $this->get_id() ) { 
  84. return false; 
  85. do_action( 'woocommerce_pre_payment_complete', $this->get_id() ); 
  86.  
  87. if ( ! empty( WC()->session ) ) { 
  88. WC()->session->set( 'order_awaiting_payment', false ); 
  89.  
  90. if ( $this->has_status( apply_filters( 'woocommerce_valid_order_statuses_for_payment_complete', array( 'on-hold', 'pending', 'failed', 'cancelled' ), $this ) ) ) { 
  91. if ( ! empty( $transaction_id ) ) { 
  92. $this->set_transaction_id( $transaction_id ); 
  93. if ( ! $this->get_date_paid( 'edit' ) ) { 
  94. $this->set_date_paid( current_time( 'timestamp', true ) ); 
  95. $this->set_status( apply_filters( 'woocommerce_payment_complete_order_status', $this->needs_processing() ? 'processing' : 'completed', $this->get_id(), $this ) ); 
  96. $this->save(); 
  97.  
  98. do_action( 'woocommerce_payment_complete', $this->get_id() ); 
  99. } else { 
  100. do_action( 'woocommerce_payment_complete_order_status_' . $this->get_status(), $this->get_id() ); 
  101. } catch ( Exception $e ) { 
  102. return false; 
  103. return true; 
  104.  
  105. /** 
  106. * Gets order total - formatted for display. 
  107. * @param string $tax_display Type of tax display. 
  108. * @param bool $display_refunded If should include refunded value. 
  109. * @return string 
  110. */ 
  111. public function get_formatted_order_total( $tax_display = '', $display_refunded = true ) { 
  112. $formatted_total = wc_price( $this->get_total(), array( 'currency' => $this->get_currency() ) ); 
  113. $order_total = $this->get_total(); 
  114. $total_refunded = $this->get_total_refunded(); 
  115. $tax_string = ''; 
  116.  
  117. // Tax for inclusive prices. 
  118. if ( wc_tax_enabled() && 'incl' == $tax_display ) { 
  119. $tax_string_array = array(); 
  120.  
  121. if ( 'itemized' == get_option( 'woocommerce_tax_total_display' ) ) { 
  122. foreach ( $this->get_tax_totals() as $code => $tax ) { 
  123. $tax_amount = ( $total_refunded && $display_refunded ) ? wc_price( WC_Tax::round( $tax->amount - $this->get_total_tax_refunded_by_rate_id( $tax->rate_id ) ), array( 'currency' => $this->get_currency() ) ) : $tax->formatted_amount; 
  124. $tax_string_array[] = sprintf( '%s %s', $tax_amount, $tax->label ); 
  125. } else { 
  126. $tax_amount = ( $total_refunded && $display_refunded ) ? $this->get_total_tax() - $this->get_total_tax_refunded() : $this->get_total_tax(); 
  127. $tax_string_array[] = sprintf( '%s %s', wc_price( $tax_amount, array( 'currency' => $this->get_currency() ) ), WC()->countries->tax_or_vat() ); 
  128. if ( ! empty( $tax_string_array ) ) { 
  129. $tax_string = ' <small class="includes_tax">' . sprintf( __( '(includes %s)', 'woocommerce' ), implode( ', ', $tax_string_array ) ) . '</small>'; 
  130.  
  131. if ( $total_refunded && $display_refunded ) { 
  132. $formatted_total = '<del>' . strip_tags( $formatted_total ) . '</del> <ins>' . wc_price( $order_total - $total_refunded, array( 'currency' => $this->get_currency() ) ) . $tax_string . '</ins>'; 
  133. } else { 
  134. $formatted_total .= $tax_string; 
  135.  
  136. /** 
  137. * Filter WooCommerce formatted order total. 
  138. * @param string $formatted_total Total to display. 
  139. * @param WC_Order $order Order data. 
  140. * @param string $tax_display Type of tax display. 
  141. * @param bool $display_refunded If should include refunded value. 
  142. */ 
  143. return apply_filters( 'woocommerce_get_formatted_order_total', $formatted_total, $this, $tax_display, $display_refunded ); 
  144.  
  145. /** 
  146. |-------------------------------------------------------------------------- 
  147. | CRUD methods 
  148. |-------------------------------------------------------------------------- 
  149. | Methods which create, read, update and delete orders from the database. 
  150. | Written in abstract fashion so that the way orders are stored can be 
  151. | changed more easily in the future. 
  152. | A save method is included for convenience (chooses update or create based 
  153. | on if the order exists yet). 
  154. */ 
  155.  
  156. /** 
  157. * Save data to the database. 
  158. * @since 3.0.0 
  159. * @return int order ID 
  160. */ 
  161. public function save() { 
  162. $this->maybe_set_user_billing_email(); 
  163. if ( $this->data_store ) { 
  164. // Trigger action before saving to the DB. Allows you to adjust object props before save. 
  165. do_action( 'woocommerce_before_' . $this->object_type . '_object_save', $this, $this->data_store ); 
  166.  
  167. if ( $this->get_id() ) { 
  168. $this->data_store->update( $this ); 
  169. } else { 
  170. $this->data_store->create( $this ); 
  171. $this->save_items(); 
  172. $this->status_transition(); 
  173. return $this->get_id(); 
  174.  
  175. /** 
  176. * Set order status. 
  177. * @since 3.0.0 
  178. * @param string $new_status Status to change the order to. No internal wc- prefix is required. 
  179. * @param string $note (default: '') Optional note to add. 
  180. * @param bool $manual_update is this a manual order status change? 
  181. * @param array details of change 
  182. */ 
  183. public function set_status( $new_status, $note = '', $manual_update = false ) { 
  184. $result = parent::set_status( $new_status ); 
  185.  
  186. if ( true === $this->object_read && ! empty( $result['from'] ) && $result['from'] !== $result['to'] ) { 
  187. $this->status_transition = array( 
  188. 'from' => ! empty( $this->status_transition['from'] ) ? $this->status_transition['from'] : $result['from'],  
  189. 'to' => $result['to'],  
  190. 'note' => $note,  
  191. 'manual' => (bool) $manual_update,  
  192. ); 
  193.  
  194. $this->maybe_set_date_paid(); 
  195. $this->maybe_set_date_completed(); 
  196.  
  197. return $result; 
  198.  
  199. /** 
  200. * Maybe set date paid. 
  201. * Sets the date paid variable when transitioning to the payment complete 
  202. * order status. This is either processing or completed. This is not filtered 
  203. * to avoid infinite loops e.g. if loading an order via the filter. 
  204. * Date paid is set once in this manner - only when it is not already set. 
  205. * This ensures the data exists even if a gateway does not use the 
  206. * `payment_complete` method. 
  207. * @since 3.0.0 
  208. */ 
  209. public function maybe_set_date_paid() { 
  210. if ( ! $this->get_date_paid( 'edit' ) && $this->has_status( apply_filters( 'woocommerce_payment_complete_order_status', $this->needs_processing() ? 'processing' : 'completed', $this->get_id() ) ) ) { 
  211. $this->set_date_paid( current_time( 'timestamp' ) ); 
  212.  
  213. /** 
  214. * Maybe set date completed. 
  215. * Sets the date completed variable when transitioning to completed status. 
  216. * @since 3.0.0 
  217. */ 
  218. protected function maybe_set_date_completed() { 
  219. if ( $this->has_status( 'completed' ) ) { 
  220. $this->set_date_completed( current_time( 'timestamp', true ) ); 
  221.  
  222. /** 
  223. * Updates status of order immediately. Order must exist. 
  224. * @uses WC_Order::set_status() 
  225. * @return bool success 
  226. */ 
  227. public function update_status( $new_status, $note = '', $manual = false ) { 
  228. try { 
  229. if ( ! $this->get_id() ) { 
  230. return false; 
  231. $this->set_status( $new_status, $note, $manual ); 
  232. $this->save(); 
  233. } catch ( Exception $e ) { 
  234. return false; 
  235. return true; 
  236.  
  237. /** 
  238. * Handle the status transition. 
  239. */ 
  240. protected function status_transition() { 
  241. if ( $this->status_transition ) { 
  242. do_action( 'woocommerce_order_status_' . $this->status_transition['to'], $this->get_id(), $this ); 
  243.  
  244. if ( ! empty( $this->status_transition['from'] ) ) { 
  245. /** translators: 1: old order status 2: new order status */ 
  246. $transition_note = sprintf( __( 'Order status changed from %1$s to %2$s.', 'woocommerce' ), wc_get_order_status_name( $this->status_transition['from'] ), wc_get_order_status_name( $this->status_transition['to'] ) ); 
  247.  
  248. do_action( 'woocommerce_order_status_' . $this->status_transition['from'] . '_to_' . $this->status_transition['to'], $this->get_id(), $this ); 
  249. do_action( 'woocommerce_order_status_changed', $this->get_id(), $this->status_transition['from'], $this->status_transition['to'], $this ); 
  250. } else { 
  251. /** translators: %s: new order status */ 
  252. $transition_note = sprintf( __( 'Order status set to %s.', 'woocommerce' ), wc_get_order_status_name( $this->status_transition['to'] ) ); 
  253.  
  254. // Note the transition occurred 
  255. $this->add_order_note( trim( $this->status_transition['note'] . ' ' . $transition_note ), 0, $this->status_transition['manual'] ); 
  256.  
  257. // This has ran, so reset status transition variable 
  258. $this->status_transition = false; 
  259.  
  260. /** 
  261. |-------------------------------------------------------------------------- 
  262. | Getters 
  263. |-------------------------------------------------------------------------- 
  264. | Methods for getting data from the order object. 
  265. */ 
  266.  
  267. /** 
  268. * Get all class data in array format. 
  269. * @since 3.0.0 
  270. * @return array 
  271. */ 
  272. public function get_data() { 
  273. return array_merge( 
  274. array( 
  275. 'id' => $this->get_id(),  
  276. ),  
  277. $this->data,  
  278. array( 
  279. 'number' => $this->get_order_number(),  
  280. 'meta_data' => $this->get_meta_data(),  
  281. 'line_items' => $this->get_items( 'line_item' ),  
  282. 'tax_lines' => $this->get_items( 'tax' ),  
  283. 'shipping_lines' => $this->get_items( 'shipping' ),  
  284. 'fee_lines' => $this->get_items( 'fee' ),  
  285. 'coupon_lines' => $this->get_items( 'coupon' ),  
  286. ); 
  287.  
  288. /** 
  289. * Expands the shipping and billing information in the changes array. 
  290. */ 
  291. public function get_changes() { 
  292. $changed_props = parent::get_changes(); 
  293. $subs = array( 'shipping', 'billing' ); 
  294. foreach ( $subs as $sub ) { 
  295. if ( ! empty( $changed_props[ $sub ] ) ) { 
  296. foreach ( $changed_props[ $sub ] as $sub_prop => $value ) { 
  297. $changed_props[ $sub . '_' . $sub_prop ] = $value; 
  298. if ( isset( $changed_props['customer_note'] ) ) { 
  299. $changed_props['post_excerpt'] = $changed_props['customer_note']; 
  300. return $changed_props; 
  301.  
  302. /** 
  303. * get_order_number function. 
  304. * Gets the order number for display (by default, order ID). 
  305. * @return string 
  306. */ 
  307. public function get_order_number() { 
  308. return (string) apply_filters( 'woocommerce_order_number', $this->get_id(), $this ); 
  309.  
  310. /** 
  311. * Get order key. 
  312. * @since 3.0.0 
  313. * @param string $context 
  314. * @return string 
  315. */ 
  316. public function get_order_key( $context = 'view' ) { 
  317. return $this->get_prop( 'order_key', $context ); 
  318.  
  319. /** 
  320. * Get customer_id. 
  321. * @param string $context 
  322. * @return int 
  323. */ 
  324. public function get_customer_id( $context = 'view' ) { 
  325. return $this->get_prop( 'customer_id', $context ); 
  326.  
  327. /** 
  328. * Alias for get_customer_id(). 
  329. * @param string $context 
  330. * @return int 
  331. */ 
  332. public function get_user_id( $context = 'view' ) { 
  333. return $this->get_customer_id( $context ); 
  334.  
  335. /** 
  336. * Get the user associated with the order. False for guests. 
  337. * @return WP_User|false 
  338. */ 
  339. public function get_user() { 
  340. return $this->get_user_id() ? get_user_by( 'id', $this->get_user_id() ) : false; 
  341.  
  342. /** 
  343. * Gets a prop for a getter method. 
  344. * @since 3.0.0 
  345. * @param string $prop Name of prop to get. 
  346. * @param string $address billing or shipping. 
  347. * @param string $context What the value is for. Valid values are view and edit. 
  348. * @return mixed 
  349. */ 
  350. protected function get_address_prop( $prop, $address = 'billing', $context = 'view' ) { 
  351. $value = null; 
  352.  
  353. if ( array_key_exists( $prop, $this->data[ $address ] ) ) { 
  354. $value = isset( $this->changes[ $address ][ $prop ] ) ? $this->changes[ $address ][ $prop ] : $this->data[ $address ][ $prop ]; 
  355.  
  356. if ( 'view' === $context ) { 
  357. $value = apply_filters( $this->get_hook_prefix() . $address . '_' . $prop, $value, $this ); 
  358. return $value; 
  359.  
  360. /** 
  361. * Get billing_first_name. 
  362. * @param string $context 
  363. * @return string 
  364. */ 
  365. public function get_billing_first_name( $context = 'view' ) { 
  366. return $this->get_address_prop( 'first_name', 'billing', $context ); 
  367.  
  368. /** 
  369. * Get billing_last_name. 
  370. * @param string $context 
  371. * @return string 
  372. */ 
  373. public function get_billing_last_name( $context = 'view' ) { 
  374. return $this->get_address_prop( 'last_name', 'billing', $context ); 
  375.  
  376. /** 
  377. * Get billing_company. 
  378. * @param string $context 
  379. * @return string 
  380. */ 
  381. public function get_billing_company( $context = 'view' ) { 
  382. return $this->get_address_prop( 'company', 'billing', $context ); 
  383.  
  384. /** 
  385. * Get billing_address_1. 
  386. * @param string $context 
  387. * @return string 
  388. */ 
  389. public function get_billing_address_1( $context = 'view' ) { 
  390. return $this->get_address_prop( 'address_1', 'billing', $context ); 
  391.  
  392. /** 
  393. * Get billing_address_2. 
  394. * @param string $context 
  395. * @return string $value 
  396. */ 
  397. public function get_billing_address_2( $context = 'view' ) { 
  398. return $this->get_address_prop( 'address_2', 'billing', $context ); 
  399.  
  400. /** 
  401. * Get billing_city. 
  402. * @param string $context 
  403. * @return string $value 
  404. */ 
  405. public function get_billing_city( $context = 'view' ) { 
  406. return $this->get_address_prop( 'city', 'billing', $context ); 
  407.  
  408. /** 
  409. * Get billing_state. 
  410. * @param string $context 
  411. * @return string 
  412. */ 
  413. public function get_billing_state( $context = 'view' ) { 
  414. return $this->get_address_prop( 'state', 'billing', $context ); 
  415.  
  416. /** 
  417. * Get billing_postcode. 
  418. * @param string $context 
  419. * @return string 
  420. */ 
  421. public function get_billing_postcode( $context = 'view' ) { 
  422. return $this->get_address_prop( 'postcode', 'billing', $context ); 
  423.  
  424. /** 
  425. * Get billing_country. 
  426. * @param string $context 
  427. * @return string 
  428. */ 
  429. public function get_billing_country( $context = 'view' ) { 
  430. return $this->get_address_prop( 'country', 'billing', $context ); 
  431.  
  432. /** 
  433. * Get billing_email. 
  434. * @param string $context 
  435. * @return string 
  436. */ 
  437. public function get_billing_email( $context = 'view' ) { 
  438. return $this->get_address_prop( 'email', 'billing', $context ); 
  439.  
  440. /** 
  441. * Get billing_phone. 
  442. * @param string $context 
  443. * @return string 
  444. */ 
  445. public function get_billing_phone( $context = 'view' ) { 
  446. return $this->get_address_prop( 'phone', 'billing', $context ); 
  447.  
  448. /** 
  449. * Get shipping_first_name. 
  450. * @param string $context 
  451. * @return string 
  452. */ 
  453. public function get_shipping_first_name( $context = 'view' ) { 
  454. return $this->get_address_prop( 'first_name', 'shipping', $context ); 
  455.  
  456. /** 
  457. * Get shipping_last_name. 
  458. * @param string $context 
  459. * @return string 
  460. */ 
  461. public function get_shipping_last_name( $context = 'view' ) { 
  462. return $this->get_address_prop( 'last_name', 'shipping', $context ); 
  463.  
  464. /** 
  465. * Get shipping_company. 
  466. * @param string $context 
  467. * @return string 
  468. */ 
  469. public function get_shipping_company( $context = 'view' ) { 
  470. return $this->get_address_prop( 'company', 'shipping', $context ); 
  471.  
  472. /** 
  473. * Get shipping_address_1. 
  474. * @param string $context 
  475. * @return string 
  476. */ 
  477. public function get_shipping_address_1( $context = 'view' ) { 
  478. return $this->get_address_prop( 'address_1', 'shipping', $context ); 
  479.  
  480. /** 
  481. * Get shipping_address_2. 
  482. * @param string $context 
  483. * @return string 
  484. */ 
  485. public function get_shipping_address_2( $context = 'view' ) { 
  486. return $this->get_address_prop( 'address_2', 'shipping', $context ); 
  487.  
  488. /** 
  489. * Get shipping_city. 
  490. * @param string $context 
  491. * @return string 
  492. */ 
  493. public function get_shipping_city( $context = 'view' ) { 
  494. return $this->get_address_prop( 'city', 'shipping', $context ); 
  495.  
  496. /** 
  497. * Get shipping_state. 
  498. * @param string $context 
  499. * @return string 
  500. */ 
  501. public function get_shipping_state( $context = 'view' ) { 
  502. return $this->get_address_prop( 'state', 'shipping', $context ); 
  503.  
  504. /** 
  505. * Get shipping_postcode. 
  506. * @param string $context 
  507. * @return string 
  508. */ 
  509. public function get_shipping_postcode( $context = 'view' ) { 
  510. return $this->get_address_prop( 'postcode', 'shipping', $context ); 
  511.  
  512. /** 
  513. * Get shipping_country. 
  514. * @param string $context 
  515. * @return string 
  516. */ 
  517. public function get_shipping_country( $context = 'view' ) { 
  518. return $this->get_address_prop( 'country', 'shipping', $context ); 
  519.  
  520. /** 
  521. * Get the payment method. 
  522. * @param string $context 
  523. * @return string 
  524. */ 
  525. public function get_payment_method( $context = 'view' ) { 
  526. return $this->get_prop( 'payment_method', $context ); 
  527.  
  528. /** 
  529. * Get payment_method_title. 
  530. * @param string $context 
  531. * @return string 
  532. */ 
  533. public function get_payment_method_title( $context = 'view' ) { 
  534. return $this->get_prop( 'payment_method_title', $context ); 
  535.  
  536. /** 
  537. * Get transaction_id. 
  538. * @param string $context 
  539. * @return string 
  540. */ 
  541. public function get_transaction_id( $context = 'view' ) { 
  542. return $this->get_prop( 'transaction_id', $context ); 
  543.  
  544. /** 
  545. * Get customer_ip_address. 
  546. * @param string $context 
  547. * @return string 
  548. */ 
  549. public function get_customer_ip_address( $context = 'view' ) { 
  550. return $this->get_prop( 'customer_ip_address', $context ); 
  551.  
  552. /** 
  553. * Get customer_user_agent. 
  554. * @param string $context 
  555. * @return string 
  556. */ 
  557. public function get_customer_user_agent( $context = 'view' ) { 
  558. return $this->get_prop( 'customer_user_agent', $context ); 
  559.  
  560. /** 
  561. * Get created_via. 
  562. * @param string $context 
  563. * @return string 
  564. */ 
  565. public function get_created_via( $context = 'view' ) { 
  566. return $this->get_prop( 'created_via', $context ); 
  567.  
  568. /** 
  569. * Get customer_note. 
  570. * @param string $context 
  571. * @return string 
  572. */ 
  573. public function get_customer_note( $context = 'view' ) { 
  574. return $this->get_prop( 'customer_note', $context ); 
  575.  
  576. /** 
  577. * Get date_completed. 
  578. * @param string $context 
  579. * @return WC_DateTime|NULL object if the date is set or null if there is no date. 
  580. */ 
  581. public function get_date_completed( $context = 'view' ) { 
  582. return $this->get_prop( 'date_completed', $context ); 
  583.  
  584. /** 
  585. * Get date_paid. 
  586. * @param string $context 
  587. * @return WC_DateTime|NULL object if the date is set or null if there is no date. 
  588. */ 
  589. public function get_date_paid( $context = 'view' ) { 
  590. $date_paid = $this->get_prop( 'date_paid', $context ); 
  591.  
  592. if ( 'view' === $context && ! $date_paid && version_compare( $this->get_version( 'edit' ), '3.0', '<' ) && $this->has_status( apply_filters( 'woocommerce_payment_complete_order_status', $this->needs_processing() ? 'processing' : 'completed', $this->get_id() ) ) ) { 
  593. // In view context, return a date if missing. 
  594. $date_paid = $this->get_date_created( 'edit' ); 
  595. return $date_paid; 
  596.  
  597. /** 
  598. * Get cart hash. 
  599. * @param string $context 
  600. * @return string 
  601. */ 
  602. public function get_cart_hash( $context = 'view' ) { 
  603. return $this->get_prop( 'cart_hash', $context ); 
  604.  
  605. /** 
  606. * Returns the requested address in raw, non-formatted way. 
  607. * Note: Merges raw data with get_prop data so changes are returned too. 
  608. * @since 2.4.0 
  609. * @param string $type Billing or shipping. Anything else besides 'billing' will return shipping address. 
  610. * @return array The stored address after filter. 
  611. */ 
  612. public function get_address( $type = 'billing' ) { 
  613. return apply_filters( 'woocommerce_get_order_address', array_merge( $this->data[ $type ], $this->get_prop( $type, 'view' ) ), $type, $this ); 
  614.  
  615. /** 
  616. * Get a formatted shipping address for the order. 
  617. * @return string 
  618. */ 
  619. public function get_shipping_address_map_url() { 
  620. $address = apply_filters( 'woocommerce_shipping_address_map_url_parts', $this->get_address( 'shipping' ), $this ); 
  621. return apply_filters( 'woocommerce_shipping_address_map_url', 'https://maps.google.com/maps?&q=' . urlencode( implode( ', ', $address ) ) . '&z=16', $this ); 
  622.  
  623. /** 
  624. * Get a formatted billing full name. 
  625. * @return string 
  626. */ 
  627. public function get_formatted_billing_full_name() { 
  628. /** translators: 1: first name 2: last name */ 
  629. return sprintf( _x( '%1$s %2$s', 'full name', 'woocommerce' ), $this->get_billing_first_name(), $this->get_billing_last_name() ); 
  630.  
  631. /** 
  632. * Get a formatted shipping full name. 
  633. * @return string 
  634. */ 
  635. public function get_formatted_shipping_full_name() { 
  636. /** translators: 1: first name 2: last name */ 
  637. return sprintf( _x( '%1$s %2$s', 'full name', 'woocommerce' ), $this->get_shipping_first_name(), $this->get_shipping_last_name() ); 
  638.  
  639. /** 
  640. * Get a formatted billing address for the order. 
  641. * @return string 
  642. */ 
  643. public function get_formatted_billing_address() { 
  644. return WC()->countries->get_formatted_address( apply_filters( 'woocommerce_order_formatted_billing_address', $this->get_address( 'billing' ), $this ) ); 
  645.  
  646. /** 
  647. * Get a formatted shipping address for the order. 
  648. * @return string 
  649. */ 
  650. public function get_formatted_shipping_address() { 
  651. if ( $this->get_shipping_address_1() || $this->get_shipping_address_2() ) { 
  652. return WC()->countries->get_formatted_address( apply_filters( 'woocommerce_order_formatted_shipping_address', $this->get_address( 'shipping' ), $this ) ); 
  653. } else { 
  654. return ''; 
  655.  
  656. /** 
  657. |-------------------------------------------------------------------------- 
  658. | Setters 
  659. |-------------------------------------------------------------------------- 
  660. | Functions for setting order data. These should not update anything in the 
  661. | database itself and should only change what is stored in the class 
  662. | object. However, for backwards compatibility pre 3.0.0 some of these 
  663. | setters may handle both. 
  664. */ 
  665.  
  666. /** 
  667. * Sets a prop for a setter method. 
  668. * @since 3.0.0 
  669. * @param string $prop Name of prop to set. 
  670. * @param string $address Name of address to set. billing or shipping. 
  671. * @param mixed $value Value of the prop. 
  672. */ 
  673. protected function set_address_prop( $prop, $address = 'billing', $value ) { 
  674. if ( array_key_exists( $prop, $this->data[ $address ] ) ) { 
  675. if ( true === $this->object_read ) { 
  676. if ( $value !== $this->data[ $address ][ $prop ] || ( isset( $this->changes[ $address ] ) && array_key_exists( $prop, $this->changes[ $address ] ) ) ) { 
  677. $this->changes[ $address ][ $prop ] = $value; 
  678. } else { 
  679. $this->data[ $address ][ $prop ] = $value; 
  680.  
  681. /** 
  682. * Set order_key. 
  683. * @param string $value Max length 22 chars. 
  684. * @throws WC_Data_Exception 
  685. */ 
  686. public function set_order_key( $value ) { 
  687. $this->set_prop( 'order_key', substr( $value, 0, 22 ) ); 
  688.  
  689. /** 
  690. * Set customer_id. 
  691. * @param int $value 
  692. * @throws WC_Data_Exception 
  693. */ 
  694. public function set_customer_id( $value ) { 
  695. $this->set_prop( 'customer_id', absint( $value ) ); 
  696.  
  697. /** 
  698. * Set billing_first_name. 
  699. * @param string $value 
  700. * @throws WC_Data_Exception 
  701. */ 
  702. public function set_billing_first_name( $value ) { 
  703. $this->set_address_prop( 'first_name', 'billing', $value ); 
  704.  
  705. /** 
  706. * Set billing_last_name. 
  707. * @param string $value 
  708. * @throws WC_Data_Exception 
  709. */ 
  710. public function set_billing_last_name( $value ) { 
  711. $this->set_address_prop( 'last_name', 'billing', $value ); 
  712.  
  713. /** 
  714. * Set billing_company. 
  715. * @param string $value 
  716. * @throws WC_Data_Exception 
  717. */ 
  718. public function set_billing_company( $value ) { 
  719. $this->set_address_prop( 'company', 'billing', $value ); 
  720.  
  721. /** 
  722. * Set billing_address_1. 
  723. * @param string $value 
  724. * @throws WC_Data_Exception 
  725. */ 
  726. public function set_billing_address_1( $value ) { 
  727. $this->set_address_prop( 'address_1', 'billing', $value ); 
  728.  
  729. /** 
  730. * Set billing_address_2. 
  731. * @param string $value 
  732. * @throws WC_Data_Exception 
  733. */ 
  734. public function set_billing_address_2( $value ) { 
  735. $this->set_address_prop( 'address_2', 'billing', $value ); 
  736.  
  737. /** 
  738. * Set billing_city. 
  739. * @param string $value 
  740. * @throws WC_Data_Exception 
  741. */ 
  742. public function set_billing_city( $value ) { 
  743. $this->set_address_prop( 'city', 'billing', $value ); 
  744.  
  745. /** 
  746. * Set billing_state. 
  747. * @param string $value 
  748. * @throws WC_Data_Exception 
  749. */ 
  750. public function set_billing_state( $value ) { 
  751. $this->set_address_prop( 'state', 'billing', $value ); 
  752.  
  753. /** 
  754. * Set billing_postcode. 
  755. * @param string $value 
  756. * @throws WC_Data_Exception 
  757. */ 
  758. public function set_billing_postcode( $value ) { 
  759. $this->set_address_prop( 'postcode', 'billing', $value ); 
  760.  
  761. /** 
  762. * Set billing_country. 
  763. * @param string $value 
  764. * @throws WC_Data_Exception 
  765. */ 
  766. public function set_billing_country( $value ) { 
  767. $this->set_address_prop( 'country', 'billing', $value ); 
  768.  
  769. /** 
  770. * Maybe set empty billing email to that of the user who owns the order. 
  771. */ 
  772. protected function maybe_set_user_billing_email() { 
  773. if ( ! $this->get_billing_email() && ( $user = $this->get_user() ) ) { 
  774. try { 
  775. $this->set_billing_email( $user->user_email ); 
  776. } catch( WC_Data_Exception $e ) { 
  777. unset( $e ); 
  778.  
  779. /** 
  780. * Set billing_email. 
  781. * @param string $value 
  782. * @throws WC_Data_Exception 
  783. */ 
  784. public function set_billing_email( $value ) { 
  785. if ( $value && ! is_email( $value ) ) { 
  786. $this->error( 'order_invalid_billing_email', __( 'Invalid billing email address', 'woocommerce' ) ); 
  787. $this->set_address_prop( 'email', 'billing', sanitize_email( $value ) ); 
  788.  
  789. /** 
  790. * Set billing_phone. 
  791. * @param string $value 
  792. * @throws WC_Data_Exception 
  793. */ 
  794. public function set_billing_phone( $value ) { 
  795. $this->set_address_prop( 'phone', 'billing', $value ); 
  796.  
  797. /** 
  798. * Set shipping_first_name. 
  799. * @param string $value 
  800. * @throws WC_Data_Exception 
  801. */ 
  802. public function set_shipping_first_name( $value ) { 
  803. $this->set_address_prop( 'first_name', 'shipping', $value ); 
  804.  
  805. /** 
  806. * Set shipping_last_name. 
  807. * @param string $value 
  808. * @throws WC_Data_Exception 
  809. */ 
  810. public function set_shipping_last_name( $value ) { 
  811. $this->set_address_prop( 'last_name', 'shipping', $value ); 
  812.  
  813. /** 
  814. * Set shipping_company. 
  815. * @param string $value 
  816. * @throws WC_Data_Exception 
  817. */ 
  818. public function set_shipping_company( $value ) { 
  819. $this->set_address_prop( 'company', 'shipping', $value ); 
  820.  
  821. /** 
  822. * Set shipping_address_1. 
  823. * @param string $value 
  824. * @throws WC_Data_Exception 
  825. */ 
  826. public function set_shipping_address_1( $value ) { 
  827. $this->set_address_prop( 'address_1', 'shipping', $value ); 
  828.  
  829. /** 
  830. * Set shipping_address_2. 
  831. * @param string $value 
  832. * @throws WC_Data_Exception 
  833. */ 
  834. public function set_shipping_address_2( $value ) { 
  835. $this->set_address_prop( 'address_2', 'shipping', $value ); 
  836.  
  837. /** 
  838. * Set shipping_city. 
  839. * @param string $value 
  840. * @throws WC_Data_Exception 
  841. */ 
  842. public function set_shipping_city( $value ) { 
  843. $this->set_address_prop( 'city', 'shipping', $value ); 
  844.  
  845. /** 
  846. * Set shipping_state. 
  847. * @param string $value 
  848. * @throws WC_Data_Exception 
  849. */ 
  850. public function set_shipping_state( $value ) { 
  851. $this->set_address_prop( 'state', 'shipping', $value ); 
  852.  
  853. /** 
  854. * Set shipping_postcode. 
  855. * @param string $value 
  856. * @throws WC_Data_Exception 
  857. */ 
  858. public function set_shipping_postcode( $value ) { 
  859. $this->set_address_prop( 'postcode', 'shipping', $value ); 
  860.  
  861. /** 
  862. * Set shipping_country. 
  863. * @param string $value 
  864. * @throws WC_Data_Exception 
  865. */ 
  866. public function set_shipping_country( $value ) { 
  867. $this->set_address_prop( 'country', 'shipping', $value ); 
  868.  
  869. /** 
  870. * Set the payment method. 
  871. * @param string $payment_method Supports WC_Payment_Gateway for bw compatibility with < 3.0 
  872. * @throws WC_Data_Exception 
  873. */ 
  874. public function set_payment_method( $payment_method = '' ) { 
  875. if ( is_object( $payment_method ) ) { 
  876. $this->set_payment_method( $payment_method->id ); 
  877. $this->set_payment_method_title( $payment_method->get_title() ); 
  878. } elseif ( '' === $payment_method ) { 
  879. $this->set_prop( 'payment_method', '' ); 
  880. $this->set_prop( 'payment_method_title', '' ); 
  881. } else { 
  882. $this->set_prop( 'payment_method', $payment_method ); 
  883.  
  884. /** 
  885. * Set payment_method_title. 
  886. * @param string $value 
  887. * @throws WC_Data_Exception 
  888. */ 
  889. public function set_payment_method_title( $value ) { 
  890. $this->set_prop( 'payment_method_title', $value ); 
  891.  
  892. /** 
  893. * Set transaction_id. 
  894. * @param string $value 
  895. * @throws WC_Data_Exception 
  896. */ 
  897. public function set_transaction_id( $value ) { 
  898. $this->set_prop( 'transaction_id', $value ); 
  899.  
  900. /** 
  901. * Set customer_ip_address. 
  902. * @param string $value 
  903. * @throws WC_Data_Exception 
  904. */ 
  905. public function set_customer_ip_address( $value ) { 
  906. $this->set_prop( 'customer_ip_address', $value ); 
  907.  
  908. /** 
  909. * Set customer_user_agent. 
  910. * @param string $value 
  911. * @throws WC_Data_Exception 
  912. */ 
  913. public function set_customer_user_agent( $value ) { 
  914. $this->set_prop( 'customer_user_agent', $value ); 
  915.  
  916. /** 
  917. * Set created_via. 
  918. * @param string $value 
  919. * @throws WC_Data_Exception 
  920. */ 
  921. public function set_created_via( $value ) { 
  922. $this->set_prop( 'created_via', $value ); 
  923.  
  924. /** 
  925. * Set customer_note. 
  926. * @param string $value 
  927. * @throws WC_Data_Exception 
  928. */ 
  929. public function set_customer_note( $value ) { 
  930. $this->set_prop( 'customer_note', $value ); 
  931.  
  932. /** 
  933. * Set date_completed. 
  934. * @param string|integer|null $date UTC timestamp, or ISO 8601 DateTime. If the DateTime string has no timezone or offset, WordPress site timezone will be assumed. Null if their is no date. 
  935. * @throws WC_Data_Exception 
  936. */ 
  937. public function set_date_completed( $date = null ) { 
  938. $this->set_date_prop( 'date_completed', $date ); 
  939.  
  940. /** 
  941. * Set date_paid. 
  942. * @param string|integer|null $date UTC timestamp, or ISO 8601 DateTime. If the DateTime string has no timezone or offset, WordPress site timezone will be assumed. Null if their is no date. 
  943. * @throws WC_Data_Exception 
  944. */ 
  945. public function set_date_paid( $date = null ) { 
  946. $this->set_date_prop( 'date_paid', $date ); 
  947.  
  948. /** 
  949. * Set cart hash. 
  950. * @param string $value 
  951. * @throws WC_Data_Exception 
  952. */ 
  953. public function set_cart_hash( $value ) { 
  954. $this->set_prop( 'cart_hash', $value ); 
  955.  
  956. /** 
  957. |-------------------------------------------------------------------------- 
  958. | Conditionals 
  959. |-------------------------------------------------------------------------- 
  960. | Checks if a condition is true or false. 
  961. */ 
  962.  
  963. /** 
  964. * Check if an order key is valid. 
  965. * @param mixed $key 
  966. * @return bool 
  967. */ 
  968. public function key_is_valid( $key ) { 
  969. return $key === $this->get_order_key(); 
  970.  
  971. /** 
  972. * See if order matches cart_hash. 
  973. * @return bool 
  974. */ 
  975. public function has_cart_hash( $cart_hash = '' ) { 
  976. return hash_equals( $this->get_cart_hash(), $cart_hash ); 
  977.  
  978. /** 
  979. * Checks if an order can be edited, specifically for use on the Edit Order screen. 
  980. * @return bool 
  981. */ 
  982. public function is_editable() { 
  983. return apply_filters( 'wc_order_is_editable', in_array( $this->get_status(), array( 'pending', 'on-hold', 'auto-draft' ) ), $this ); 
  984.  
  985. /** 
  986. * Returns if an order has been paid for based on the order status. 
  987. * @since 2.5.0 
  988. * @return bool 
  989. */ 
  990. public function is_paid() { 
  991. return apply_filters( 'woocommerce_order_is_paid', $this->has_status( wc_get_is_paid_statuses() ), $this ); 
  992.  
  993. /** 
  994. * Checks if product download is permitted. 
  995. * @return bool 
  996. */ 
  997. public function is_download_permitted() { 
  998. return apply_filters( 'woocommerce_order_is_download_permitted', $this->has_status( 'completed' ) || ( 'yes' === get_option( 'woocommerce_downloads_grant_access_after_payment' ) && $this->has_status( 'processing' ) ), $this ); 
  999.  
  1000. /** 
  1001. * Checks if an order needs display the shipping address, based on shipping method. 
  1002. * @return bool 
  1003. */ 
  1004. public function needs_shipping_address() { 
  1005. if ( 'no' === get_option( 'woocommerce_calc_shipping' ) ) { 
  1006. return false; 
  1007.  
  1008. $hide = apply_filters( 'woocommerce_order_hide_shipping_address', array( 'local_pickup' ), $this ); 
  1009. $needs_address = false; 
  1010.  
  1011. foreach ( $this->get_shipping_methods() as $shipping_method ) { 
  1012. // Remove any instance IDs after : 
  1013. $shipping_method_id = current( explode( ':', $shipping_method['method_id'] ) ); 
  1014.  
  1015. if ( ! in_array( $shipping_method_id, $hide ) ) { 
  1016. $needs_address = true; 
  1017. break; 
  1018.  
  1019. return apply_filters( 'woocommerce_order_needs_shipping_address', $needs_address, $hide, $this ); 
  1020.  
  1021. /** 
  1022. * Returns true if the order contains a downloadable product. 
  1023. * @return bool 
  1024. */ 
  1025. public function has_downloadable_item() { 
  1026. foreach ( $this->get_items() as $item ) { 
  1027. if ( $item->is_type( 'line_item' ) && ( $product = $item->get_product() ) && $product->is_downloadable() && $product->has_file() ) { 
  1028. return true; 
  1029. return false; 
  1030.  
  1031. /** 
  1032. * Checks if an order needs payment, based on status and order total. 
  1033. * @return bool 
  1034. */ 
  1035. public function needs_payment() { 
  1036. $valid_order_statuses = apply_filters( 'woocommerce_valid_order_statuses_for_payment', array( 'pending', 'failed' ), $this ); 
  1037. return apply_filters( 'woocommerce_order_needs_payment', ( $this->has_status( $valid_order_statuses ) && $this->get_total() > 0 ), $this, $valid_order_statuses ); 
  1038.  
  1039. /** 
  1040. * See if the order needs processing before it can be completed. 
  1041. * Orders which only contain virtual, downloadable items do not need admin 
  1042. * intervention. 
  1043. * @since 3.0.0 
  1044. * @return bool 
  1045. */ 
  1046. public function needs_processing() { 
  1047. $needs_processing = false; 
  1048.  
  1049. if ( sizeof( $this->get_items() ) > 0 ) { 
  1050. foreach ( $this->get_items() as $item ) { 
  1051. if ( $item->is_type( 'line_item' ) && ( $product = $item->get_product() ) ) { 
  1052. $virtual_downloadable_item = $product->is_downloadable() && $product->is_virtual(); 
  1053.  
  1054. if ( apply_filters( 'woocommerce_order_item_needs_processing', ! $virtual_downloadable_item, $product, $this->get_id() ) ) { 
  1055. $needs_processing = true; 
  1056. break; 
  1057.  
  1058. return $needs_processing; 
  1059.  
  1060. /** 
  1061. |-------------------------------------------------------------------------- 
  1062. | URLs and Endpoints 
  1063. |-------------------------------------------------------------------------- 
  1064. */ 
  1065.  
  1066. /** 
  1067. * Generates a URL so that a customer can pay for their (unpaid - pending) order. Pass 'true' for the checkout version which doesn't offer gateway choices. 
  1068. * @param bool $on_checkout 
  1069. * @return string 
  1070. */ 
  1071. public function get_checkout_payment_url( $on_checkout = false ) { 
  1072. $pay_url = wc_get_endpoint_url( 'order-pay', $this->get_id(), wc_get_page_permalink( 'checkout' ) ); 
  1073.  
  1074. if ( 'yes' == get_option( 'woocommerce_force_ssl_checkout' ) || is_ssl() ) { 
  1075. $pay_url = str_replace( 'http:', 'https:', $pay_url ); 
  1076.  
  1077. if ( $on_checkout ) { 
  1078. $pay_url = add_query_arg( 'key', $this->get_order_key(), $pay_url ); 
  1079. } else { 
  1080. $pay_url = add_query_arg( array( 'pay_for_order' => 'true', 'key' => $this->get_order_key() ), $pay_url ); 
  1081.  
  1082. return apply_filters( 'woocommerce_get_checkout_payment_url', $pay_url, $this ); 
  1083.  
  1084. /** 
  1085. * Generates a URL for the thanks page (order received). 
  1086. * @return string 
  1087. */ 
  1088. public function get_checkout_order_received_url() { 
  1089. $order_received_url = wc_get_endpoint_url( 'order-received', $this->get_id(), wc_get_page_permalink( 'checkout' ) ); 
  1090.  
  1091. if ( 'yes' === get_option( 'woocommerce_force_ssl_checkout' ) || is_ssl() ) { 
  1092. $order_received_url = str_replace( 'http:', 'https:', $order_received_url ); 
  1093.  
  1094. $order_received_url = add_query_arg( 'key', $this->get_order_key(), $order_received_url ); 
  1095.  
  1096. return apply_filters( 'woocommerce_get_checkout_order_received_url', $order_received_url, $this ); 
  1097.  
  1098. /** 
  1099. * Generates a URL so that a customer can cancel their (unpaid - pending) order. 
  1100. * @param string $redirect 
  1101. * @return string 
  1102. */ 
  1103. public function get_cancel_order_url( $redirect = '' ) { 
  1104. return apply_filters( 'woocommerce_get_cancel_order_url', wp_nonce_url( add_query_arg( array( 
  1105. 'cancel_order' => 'true',  
  1106. 'order' => $this->get_order_key(),  
  1107. 'order_id' => $this->get_id(),  
  1108. 'redirect' => $redirect,  
  1109. ), $this->get_cancel_endpoint() ), 'woocommerce-cancel_order' ) ); 
  1110.  
  1111. /** 
  1112. * Generates a raw (unescaped) cancel-order URL for use by payment gateways. 
  1113. * @param string $redirect 
  1114. * @return string The unescaped cancel-order URL. 
  1115. */ 
  1116. public function get_cancel_order_url_raw( $redirect = '' ) { 
  1117. return apply_filters( 'woocommerce_get_cancel_order_url_raw', add_query_arg( array( 
  1118. 'cancel_order' => 'true',  
  1119. 'order' => $this->get_order_key(),  
  1120. 'order_id' => $this->get_id(),  
  1121. 'redirect' => $redirect,  
  1122. '_wpnonce' => wp_create_nonce( 'woocommerce-cancel_order' ),  
  1123. ), $this->get_cancel_endpoint() ) ); 
  1124.  
  1125. /** 
  1126. * Helper method to return the cancel endpoint. 
  1127. * @return string the cancel endpoint; either the cart page or the home page. 
  1128. */ 
  1129. public function get_cancel_endpoint() { 
  1130. $cancel_endpoint = wc_get_page_permalink( 'cart' ); 
  1131. if ( ! $cancel_endpoint ) { 
  1132. $cancel_endpoint = home_url(); 
  1133.  
  1134. if ( false === strpos( $cancel_endpoint, '?' ) ) { 
  1135. $cancel_endpoint = trailingslashit( $cancel_endpoint ); 
  1136.  
  1137. return $cancel_endpoint; 
  1138.  
  1139. /** 
  1140. * Generates a URL to view an order from the my account page. 
  1141. * @return string 
  1142. */ 
  1143. public function get_view_order_url() { 
  1144. return apply_filters( 'woocommerce_get_view_order_url', wc_get_endpoint_url( 'view-order', $this->get_id(), wc_get_page_permalink( 'myaccount' ) ), $this ); 
  1145.  
  1146. /** 
  1147. |-------------------------------------------------------------------------- 
  1148. | Order notes. 
  1149. |-------------------------------------------------------------------------- 
  1150. */ 
  1151.  
  1152. /** 
  1153. * Adds a note (comment) to the order. Order must exist. 
  1154. * @param string $note Note to add. 
  1155. * @param int $is_customer_note (default: 0) Is this a note for the customer? 
  1156. * @param bool added_by_user Was the note added by a user? 
  1157. * @return int Comment ID. 
  1158. */ 
  1159. public function add_order_note( $note, $is_customer_note = 0, $added_by_user = false ) { 
  1160. if ( ! $this->get_id() ) { 
  1161. return 0; 
  1162.  
  1163. if ( is_user_logged_in() && current_user_can( 'edit_shop_order', $this->get_id() ) && $added_by_user ) { 
  1164. $user = get_user_by( 'id', get_current_user_id() ); 
  1165. $comment_author = $user->display_name; 
  1166. $comment_author_email = $user->user_email; 
  1167. } else { 
  1168. $comment_author = __( 'WooCommerce', 'woocommerce' ); 
  1169. $comment_author_email = strtolower( __( 'WooCommerce', 'woocommerce' ) ) . '@'; 
  1170. $comment_author_email .= isset( $_SERVER['HTTP_HOST'] ) ? str_replace( 'www.', '', $_SERVER['HTTP_HOST'] ) : 'noreply.com'; 
  1171. $comment_author_email = sanitize_email( $comment_author_email ); 
  1172. $commentdata = apply_filters( 'woocommerce_new_order_note_data', array( 
  1173. 'comment_post_ID' => $this->get_id(),  
  1174. 'comment_author' => $comment_author,  
  1175. 'comment_author_email' => $comment_author_email,  
  1176. 'comment_author_url' => '',  
  1177. 'comment_content' => $note,  
  1178. 'comment_agent' => 'WooCommerce',  
  1179. 'comment_type' => 'order_note',  
  1180. 'comment_parent' => 0,  
  1181. 'comment_approved' => 1,  
  1182. ), array( 'order_id' => $this->get_id(), 'is_customer_note' => $is_customer_note ) ); 
  1183.  
  1184. $comment_id = wp_insert_comment( $commentdata ); 
  1185.  
  1186. if ( $is_customer_note ) { 
  1187. add_comment_meta( $comment_id, 'is_customer_note', 1 ); 
  1188.  
  1189. do_action( 'woocommerce_new_customer_note', array( 'order_id' => $this->get_id(), 'customer_note' => $commentdata['comment_content'] ) ); 
  1190.  
  1191. return $comment_id; 
  1192.  
  1193. /** 
  1194. * List order notes (public) for the customer. 
  1195. * @return array 
  1196. */ 
  1197. public function get_customer_order_notes() { 
  1198. $notes = array(); 
  1199. $args = array( 
  1200. 'post_id' => $this->get_id(),  
  1201. 'approve' => 'approve',  
  1202. 'type' => '',  
  1203. ); 
  1204.  
  1205. remove_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ) ); 
  1206.  
  1207. $comments = get_comments( $args ); 
  1208.  
  1209. foreach ( $comments as $comment ) { 
  1210. if ( ! get_comment_meta( $comment->comment_ID, 'is_customer_note', true ) ) { 
  1211. continue; 
  1212. $comment->comment_content = make_clickable( $comment->comment_content ); 
  1213. $notes[] = $comment; 
  1214.  
  1215. add_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ) ); 
  1216.  
  1217. return $notes; 
  1218.  
  1219. /** 
  1220. |-------------------------------------------------------------------------- 
  1221. | Refunds 
  1222. |-------------------------------------------------------------------------- 
  1223. */ 
  1224.  
  1225. /** 
  1226. * Get order refunds. 
  1227. * @since 2.2 
  1228. * @return array of WC_Order_Refund objects 
  1229. */ 
  1230. public function get_refunds() { 
  1231. $cache_key = WC_Cache_Helper::get_cache_prefix( 'orders' ) . 'refunds' . $this->get_id(); 
  1232. $cached_data = wp_cache_get( $cache_key, $this->cache_group ); 
  1233.  
  1234. if ( false !== $cached_data ) { 
  1235. return $cached_data; 
  1236.  
  1237. $this->refunds = wc_get_orders( array( 
  1238. 'type' => 'shop_order_refund',  
  1239. 'parent' => $this->get_id(),  
  1240. 'limit' => -1,  
  1241. ) ); 
  1242.  
  1243. wp_cache_set( $cache_key, $this->refunds, $this->cache_group ); 
  1244.  
  1245. return $this->refunds; 
  1246.  
  1247. /** 
  1248. * Get amount already refunded. 
  1249. * @since 2.2 
  1250. * @return string 
  1251. */ 
  1252. public function get_total_refunded() { 
  1253. $cache_key = WC_Cache_Helper::get_cache_prefix( 'orders' ) . 'total_refunded' . $this->get_id(); 
  1254. $cached_data = wp_cache_get( $cache_key, $this->cache_group ); 
  1255.  
  1256. if ( false !== $cached_data ) { 
  1257. return $cached_data; 
  1258.  
  1259. $total_refunded = $this->data_store->get_total_refunded( $this ); 
  1260.  
  1261. wp_cache_set( $cache_key, $total_refunded, $this->cache_group ); 
  1262.  
  1263. return $total_refunded; 
  1264.  
  1265. /** 
  1266. * Get the total tax refunded. 
  1267. * @since 2.3 
  1268. * @return float 
  1269. */ 
  1270. public function get_total_tax_refunded() { 
  1271. $cache_key = WC_Cache_Helper::get_cache_prefix( 'orders' ) . 'total_tax_refunded' . $this->get_id(); 
  1272. $cached_data = wp_cache_get( $cache_key, $this->cache_group ); 
  1273.  
  1274. if ( false !== $cached_data ) { 
  1275. return $cached_data; 
  1276.  
  1277. $total_refunded = $this->data_store->get_total_tax_refunded( $this ); 
  1278.  
  1279. wp_cache_set( $cache_key, $total_refunded, $this->cache_group ); 
  1280.  
  1281. return $total_refunded; 
  1282.  
  1283. /** 
  1284. * Get the total shipping refunded. 
  1285. * @since 2.4 
  1286. * @return float 
  1287. */ 
  1288. public function get_total_shipping_refunded() { 
  1289. $cache_key = WC_Cache_Helper::get_cache_prefix( 'orders' ) . 'total_shipping_refunded' . $this->get_id(); 
  1290. $cached_data = wp_cache_get( $cache_key, $this->cache_group ); 
  1291.  
  1292. if ( false !== $cached_data ) { 
  1293. return $cached_data; 
  1294.  
  1295. $total_refunded = $this->data_store->get_total_shipping_refunded( $this ); 
  1296.  
  1297. wp_cache_set( $cache_key, $total_refunded, $this->cache_group ); 
  1298.  
  1299. return $total_refunded; 
  1300.  
  1301. /** 
  1302. * Gets the count of order items of a certain type that have been refunded. 
  1303. * @since 2.4.0 
  1304. * @param string $item_type 
  1305. * @return string 
  1306. */ 
  1307. public function get_item_count_refunded( $item_type = '' ) { 
  1308. if ( empty( $item_type ) ) { 
  1309. $item_type = array( 'line_item' ); 
  1310. if ( ! is_array( $item_type ) ) { 
  1311. $item_type = array( $item_type ); 
  1312. $count = 0; 
  1313.  
  1314. foreach ( $this->get_refunds() as $refund ) { 
  1315. foreach ( $refund->get_items( $item_type ) as $refunded_item ) { 
  1316. $count += abs( $refunded_item->get_quantity() ); 
  1317.  
  1318. return apply_filters( 'woocommerce_get_item_count_refunded', $count, $item_type, $this ); 
  1319.  
  1320. /** 
  1321. * Get the total number of items refunded. 
  1322. * @since 2.4.0 
  1323. * @param string $item_type type of the item we're checking, if not a line_item 
  1324. * @return integer 
  1325. */ 
  1326. public function get_total_qty_refunded( $item_type = 'line_item' ) { 
  1327. $qty = 0; 
  1328. foreach ( $this->get_refunds() as $refund ) { 
  1329. foreach ( $refund->get_items( $item_type ) as $refunded_item ) { 
  1330. $qty += $refunded_item->get_quantity(); 
  1331. return $qty; 
  1332.  
  1333. /** 
  1334. * Get the refunded amount for a line item. 
  1335. * @param int $item_id ID of the item we're checking 
  1336. * @param string $item_type type of the item we're checking, if not a line_item 
  1337. * @return integer 
  1338. */ 
  1339. public function get_qty_refunded_for_item( $item_id, $item_type = 'line_item' ) { 
  1340. $qty = 0; 
  1341. foreach ( $this->get_refunds() as $refund ) { 
  1342. foreach ( $refund->get_items( $item_type ) as $refunded_item ) { 
  1343. if ( absint( $refunded_item->get_meta( '_refunded_item_id' ) ) === $item_id ) { 
  1344. $qty += $refunded_item->get_quantity(); 
  1345. return $qty; 
  1346.  
  1347. /** 
  1348. * Get the refunded amount for a line item. 
  1349. * @param int $item_id ID of the item we're checking 
  1350. * @param string $item_type type of the item we're checking, if not a line_item 
  1351. * @return integer 
  1352. */ 
  1353. public function get_total_refunded_for_item( $item_id, $item_type = 'line_item' ) { 
  1354. $total = 0; 
  1355. foreach ( $this->get_refunds() as $refund ) { 
  1356. foreach ( $refund->get_items( $item_type ) as $refunded_item ) { 
  1357. if ( absint( $refunded_item->get_meta( '_refunded_item_id' ) ) === $item_id ) { 
  1358. $total += $refunded_item->get_total(); 
  1359. return $total * -1; 
  1360.  
  1361. /** 
  1362. * Get the refunded tax amount for a line item. 
  1363. * @param int $item_id ID of the item we're checking 
  1364. * @param int $tax_id ID of the tax we're checking 
  1365. * @param string $item_type type of the item we're checking, if not a line_item 
  1366. * @return double 
  1367. */ 
  1368. public function get_tax_refunded_for_item( $item_id, $tax_id, $item_type = 'line_item' ) { 
  1369. $total = 0; 
  1370. foreach ( $this->get_refunds() as $refund ) { 
  1371. foreach ( $refund->get_items( $item_type ) as $refunded_item ) { 
  1372. $refunded_item_id = (int) $refunded_item->get_meta( '_refunded_item_id' ); 
  1373. if ( $refunded_item_id === $item_id ) { 
  1374. $taxes = $refunded_item->get_taxes(); 
  1375. $total += isset( $taxes['total'][ $tax_id ] ) ? $taxes['total'][ $tax_id ] : 0; 
  1376. break; 
  1377. return wc_round_tax_total( $total ) * -1; 
  1378.  
  1379. /** 
  1380. * Get total tax refunded by rate ID. 
  1381. * @param int $rate_id 
  1382. * @return float 
  1383. */ 
  1384. public function get_total_tax_refunded_by_rate_id( $rate_id ) { 
  1385. $total = 0; 
  1386. foreach ( $this->get_refunds() as $refund ) { 
  1387. foreach ( $refund->get_items( 'tax' ) as $refunded_item ) { 
  1388. if ( absint( $refunded_item->get_rate_id() ) === $rate_id ) { 
  1389. $total += abs( $refunded_item->get_tax_total() ) + abs( $refunded_item->get_shipping_tax_total() ); 
  1390.  
  1391. return $total; 
  1392.  
  1393. /** 
  1394. * How much money is left to refund? 
  1395. * @return string 
  1396. */ 
  1397. public function get_remaining_refund_amount() { 
  1398. return wc_format_decimal( $this->get_total() - $this->get_total_refunded(), wc_get_price_decimals() ); 
  1399.  
  1400. /** 
  1401. * How many items are left to refund? 
  1402. * @return int 
  1403. */ 
  1404. public function get_remaining_refund_items() { 
  1405. return absint( $this->get_item_count() - $this->get_item_count_refunded() ); 
  1406.  
  1407. /** 
  1408. * Add total row for the payment method. 
  1409. * @param array $total_rows 
  1410. * @param string $tax_display 
  1411. */ 
  1412. protected function add_order_item_totals_payment_method_row( &$total_rows, $tax_display ) { 
  1413. if ( $this->get_total() > 0 && $this->get_payment_method_title() ) { 
  1414. $total_rows['payment_method'] = array( 
  1415. 'label' => __( 'Payment method:', 'woocommerce' ),  
  1416. 'value' => $this->get_payment_method_title(),  
  1417. ); 
  1418.  
  1419. /** 
  1420. * Add total row for refunds. 
  1421. * @param array $total_rows 
  1422. * @param string $tax_display 
  1423. */ 
  1424. protected function add_order_item_totals_refund_rows( &$total_rows, $tax_display ) { 
  1425. if ( $refunds = $this->get_refunds() ) { 
  1426. foreach ( $refunds as $id => $refund ) { 
  1427. $total_rows[ 'refund_' . $id ] = array( 
  1428. 'label' => $refund->get_reason() ? $refund->get_reason() : __( 'Refund', 'woocommerce' ) . ':',  
  1429. 'value' => wc_price( '-' . $refund->get_amount(), array( 'currency' => $this->get_currency() ) ),  
  1430. ); 
  1431.  
  1432. /** 
  1433. * Get totals for display on pages and in emails. 
  1434. * @param mixed $tax_display 
  1435. * @return array 
  1436. */ 
  1437. public function get_order_item_totals( $tax_display = '' ) { 
  1438. $tax_display = $tax_display ? $tax_display : get_option( 'woocommerce_tax_display_cart' ); 
  1439. $total_rows = array(); 
  1440.  
  1441. $this->add_order_item_totals_subtotal_row( $total_rows, $tax_display ); 
  1442. $this->add_order_item_totals_discount_row( $total_rows, $tax_display ); 
  1443. $this->add_order_item_totals_shipping_row( $total_rows, $tax_display ); 
  1444. $this->add_order_item_totals_fee_rows( $total_rows, $tax_display ); 
  1445. $this->add_order_item_totals_tax_rows( $total_rows, $tax_display ); 
  1446. $this->add_order_item_totals_payment_method_row( $total_rows, $tax_display ); 
  1447. $this->add_order_item_totals_refund_rows( $total_rows, $tax_display ); 
  1448. $this->add_order_item_totals_total_row( $total_rows, $tax_display ); 
  1449.  
  1450. return apply_filters( 'woocommerce_get_order_item_totals', $total_rows, $this, $tax_display );