WC_Meta_Box_Order_Data

WC_Meta_Box_Order_Data Class.

Defined (1)

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

/includes/admin/meta-boxes/class-wc-meta-box-order-data.php  
  1. class WC_Meta_Box_Order_Data { 
  2.  
  3. /** 
  4. * Billing fields. 
  5. * @var array 
  6. */ 
  7. protected static $billing_fields = array(); 
  8.  
  9. /** 
  10. * Shipping fields. 
  11. * @var array 
  12. */ 
  13. protected static $shipping_fields = array(); 
  14.  
  15. /** 
  16. * Init billing and shipping fields we display + save. 
  17. */ 
  18. public static function init_address_fields() { 
  19.  
  20. self::$billing_fields = apply_filters( 'woocommerce_admin_billing_fields', array( 
  21. 'first_name' => array( 
  22. 'label' => __( 'First name', 'woocommerce' ),  
  23. 'show' => false,  
  24. ),  
  25. 'last_name' => array( 
  26. 'label' => __( 'Last name', 'woocommerce' ),  
  27. 'show' => false,  
  28. ),  
  29. 'company' => array( 
  30. 'label' => __( 'Company', 'woocommerce' ),  
  31. 'show' => false,  
  32. ),  
  33. 'address_1' => array( 
  34. 'label' => __( 'Address line 1', 'woocommerce' ),  
  35. 'show' => false,  
  36. ),  
  37. 'address_2' => array( 
  38. 'label' => __( 'Address line 2', 'woocommerce' ),  
  39. 'show' => false,  
  40. ),  
  41. 'city' => array( 
  42. 'label' => __( 'City', 'woocommerce' ),  
  43. 'show' => false,  
  44. ),  
  45. 'postcode' => array( 
  46. 'label' => __( 'Postcode / ZIP', 'woocommerce' ),  
  47. 'show' => false,  
  48. ),  
  49. 'country' => array( 
  50. 'label' => __( 'Country', 'woocommerce' ),  
  51. 'show' => false,  
  52. 'class' => 'js_field-country select short',  
  53. 'type' => 'select',  
  54. 'options' => array( '' => __( 'Select a country…', 'woocommerce' ) ) + WC()->countries->get_allowed_countries(),  
  55. ),  
  56. 'state' => array( 
  57. 'label' => __( 'State / County', 'woocommerce' ),  
  58. 'class' => 'js_field-state select short',  
  59. 'show' => false,  
  60. ),  
  61. 'email' => array( 
  62. 'label' => __( 'Email address', 'woocommerce' ),  
  63. ),  
  64. 'phone' => array( 
  65. 'label' => __( 'Phone', 'woocommerce' ),  
  66. ),  
  67. ) ); 
  68.  
  69. self::$shipping_fields = apply_filters( 'woocommerce_admin_shipping_fields', array( 
  70. 'first_name' => array( 
  71. 'label' => __( 'First name', 'woocommerce' ),  
  72. 'show' => false,  
  73. ),  
  74. 'last_name' => array( 
  75. 'label' => __( 'Last name', 'woocommerce' ),  
  76. 'show' => false,  
  77. ),  
  78. 'company' => array( 
  79. 'label' => __( 'Company', 'woocommerce' ),  
  80. 'show' => false,  
  81. ),  
  82. 'address_1' => array( 
  83. 'label' => __( 'Address line 1', 'woocommerce' ),  
  84. 'show' => false,  
  85. ),  
  86. 'address_2' => array( 
  87. 'label' => __( 'Address line 2', 'woocommerce' ),  
  88. 'show' => false,  
  89. ),  
  90. 'city' => array( 
  91. 'label' => __( 'City', 'woocommerce' ),  
  92. 'show' => false,  
  93. ),  
  94. 'postcode' => array( 
  95. 'label' => __( 'Postcode / ZIP', 'woocommerce' ),  
  96. 'show' => false,  
  97. ),  
  98. 'country' => array( 
  99. 'label' => __( 'Country', 'woocommerce' ),  
  100. 'show' => false,  
  101. 'type' => 'select',  
  102. 'class' => 'js_field-country select short',  
  103. 'options' => array( '' => __( 'Select a country…', 'woocommerce' ) ) + WC()->countries->get_shipping_countries(),  
  104. ),  
  105. 'state' => array( 
  106. 'label' => __( 'State / County', 'woocommerce' ),  
  107. 'class' => 'js_field-state select short',  
  108. 'show' => false,  
  109. ),  
  110. ) ); 
  111.  
  112. /** 
  113. * Output the metabox. 
  114. * @param WP_Post $post 
  115. */ 
  116. public static function output( $post ) { 
  117. global $theorder; 
  118.  
  119. if ( ! is_object( $theorder ) ) { 
  120. $theorder = wc_get_order( $post->ID ); 
  121.  
  122. $order = $theorder; 
  123.  
  124. self::init_address_fields(); 
  125.  
  126. if ( WC()->payment_gateways() ) { 
  127. $payment_gateways = WC()->payment_gateways->payment_gateways(); 
  128. } else { 
  129. $payment_gateways = array(); 
  130.  
  131. $payment_method = $order->get_payment_method(); 
  132.  
  133. $order_type_object = get_post_type_object( $post->post_type ); 
  134. wp_nonce_field( 'woocommerce_save_data', 'woocommerce_meta_nonce' ); 
  135. ?> 
  136. <style type="text/css"> 
  137. #post-body-content, #titlediv { display:none } 
  138. </style> 
  139. <div class="panel-wrap woocommerce"> 
  140. <input name="post_title" type="hidden" value="<?php echo empty( $post->post_title ) ? __( 'Order', 'woocommerce' ) : esc_attr( $post->post_title ); ?>" /> 
  141. <input name="post_status" type="hidden" value="<?php echo esc_attr( $post->post_status ); ?>" /> 
  142. <div id="order_data" class="panel"> 
  143.  
  144. <h2><?php 
  145. /** translators: 1: order type 2: order number */ 
  146. printf( 
  147. esc_html__( '%1$s #%2$s details', 'woocommerce' ),  
  148. $order_type_object->labels->singular_name,  
  149. $order->get_order_number() 
  150. ); 
  151. ?></h2> 
  152. <p class="order_number"><?php 
  153.  
  154. if ( $payment_method ) { 
  155. /** translators: %s: payment method */ 
  156. printf( 
  157. __( 'Payment via %s', 'woocommerce' ),  
  158. ( isset( $payment_gateways[ $payment_method ] ) ? esc_html( $payment_gateways[ $payment_method ]->get_title() ) : esc_html( $payment_method ) ) 
  159. ); 
  160.  
  161. if ( $transaction_id = $order->get_transaction_id() ) { 
  162. if ( isset( $payment_gateways[ $payment_method ] ) && ( $url = $payment_gateways[ $payment_method ]->get_transaction_url( $order ) ) ) { 
  163. echo ' (<a href="' . esc_url( $url ) . '" target="_blank">' . esc_html( $transaction_id ) . '</a>)'; 
  164. } else { 
  165. echo ' (' . esc_html( $transaction_id ) . ')'; 
  166.  
  167. if ( $order->get_date_paid() ) { 
  168. /** translators: 1: date 2: time */ 
  169. printf( ' ' . __( 'on %1$s @ %2$s', 'woocommerce' ), wc_format_datetime( $order->get_date_paid() ), wc_format_datetime( $order->get_date_paid(), get_option( 'time_format' ) ) ); 
  170.  
  171. echo '. '; 
  172.  
  173. if ( $ip_address = $order->get_customer_ip_address() ) { 
  174. /** translators: %s: IP address */ 
  175. printf( 
  176. __( 'Customer IP: %s', 'woocommerce' ),  
  177. '<span class="woocommerce-Order-customerIP">' . esc_html( $ip_address ) . '</span>' 
  178. ); 
  179. ?></p> 
  180.  
  181. <div class="order_data_column_container"> 
  182. <div class="order_data_column"> 
  183. <h3><?php _e( 'General Details', 'woocommerce' ); ?></h3> 
  184.  
  185. <p class="form-field form-field-wide"><label for="order_date"><?php _e( 'Order date:', 'woocommerce' ) ?></label> 
  186. <input type="text" class="date-picker" name="order_date" id="order_date" maxlength="10" value="<?php echo date_i18n( 'Y-m-d', strtotime( $post->post_date ) ); ?>" pattern="<?php echo esc_attr( apply_filters( 'woocommerce_date_input_html_pattern', '[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])' ) ); ?>" />@‎<input type="number" class="hour" placeholder="<?php esc_attr_e( 'h', 'woocommerce' ) ?>" name="order_date_hour" id="order_date_hour" min="0" max="23" step="1" value="<?php echo date_i18n( 'H', strtotime( $post->post_date ) ); ?>" pattern="([01]?[0-9]{1}|2[0-3]{1})" />:<input type="number" class="minute" placeholder="<?php esc_attr_e( 'm', 'woocommerce' ) ?>" name="order_date_minute" id="order_date_minute" min="0" max="59" step="1" value="<?php echo date_i18n( 'i', strtotime( $post->post_date ) ); ?>" pattern="[0-5]{1}[0-9]{1}" />‎ 
  187. </p> 
  188.  
  189. <p class="form-field form-field-wide wc-order-status"><label for="order_status"><?php _e( 'Order status:', 'woocommerce' ) ?> <?php 
  190. if ( $order->needs_payment() ) { 
  191. printf( '<a href="%s">%s</a>',  
  192. esc_url( $order->get_checkout_payment_url() ),  
  193. __( 'Customer payment page →', 'woocommerce' ) 
  194. ); 
  195. ?></label> 
  196. <select id="order_status" name="order_status" class="wc-enhanced-select"> 
  197. <?php 
  198. $statuses = wc_get_order_statuses(); 
  199. foreach ( $statuses as $status => $status_name ) { 
  200. echo '<option value="' . esc_attr( $status ) . '" ' . selected( $status, 'wc-' . $order->get_status( 'edit' ), false ) . '>' . esc_html( $status_name ) . '</option>'; 
  201. ?> 
  202. </select></p> 
  203.  
  204. <p class="form-field form-field-wide wc-customer-user"> 
  205. <label for="customer_user"><?php _e( 'Customer:', 'woocommerce' ) ?> <?php 
  206. if ( $order->get_user_id( 'edit' ) ) { 
  207. $args = array( 
  208. 'post_status' => 'all',  
  209. 'post_type' => 'shop_order',  
  210. '_customer_user' => $order->get_user_id( 'edit' ),  
  211. ); 
  212. printf( '<a href="%s">%s</a>',  
  213. esc_url( add_query_arg( $args, admin_url( 'edit.php' ) ) ),  
  214. __( 'View other orders →', 'woocommerce' ) 
  215. ); 
  216. ?></label> 
  217. <?php 
  218. $user_string = ''; 
  219. $user_id = ''; 
  220. if ( $order->get_user_id() ) { 
  221. $user_id = absint( $order->get_user_id() ); 
  222. $user = get_user_by( 'id', $user_id ); 
  223. /** translators: 1: user display name 2: user ID 3: user email */ 
  224. $user_string = sprintf( 
  225. esc_html__( '%1$s (#%2$s – %3$s)', 'woocommerce' ),  
  226. $user->display_name,  
  227. absint( $user->ID ),  
  228. $user->user_email 
  229. ); 
  230. ?> 
  231. <select class="wc-customer-search" id="customer_user" name="customer_user" data-placeholder="<?php esc_attr_e( 'Guest', 'woocommerce' ); ?>" data-allow_clear="true"> 
  232. <option value="<?php echo esc_attr( $user_id ); ?>" selected="selected"><?php echo htmlspecialchars( $user_string ); ?></option> 
  233. </select> 
  234. </p> 
  235. <?php do_action( 'woocommerce_admin_order_data_after_order_details', $order ); ?> 
  236. </div> 
  237. <div class="order_data_column"> 
  238. <h3> 
  239. <?php _e( 'Billing details', 'woocommerce' ); ?> 
  240. <a href="#" class="edit_address"><?php _e( 'Edit', 'woocommerce' ); ?></a> 
  241. <span> 
  242. <a href="#" class="load_customer_billing" style="display:none;"><?php _e( 'Load billing address', 'woocommerce' ); ?></a> 
  243. </span> 
  244. </h3> 
  245. <?php 
  246. // Display values 
  247. echo '<div class="address">'; 
  248.  
  249. if ( $order->get_formatted_billing_address() ) { 
  250. echo '<p><strong>' . __( 'Address:', 'woocommerce' ) . '</strong>' . wp_kses( $order->get_formatted_billing_address(), array( 'br' => array() ) ) . '</p>'; 
  251. } else { 
  252. echo '<p class="none_set"><strong>' . __( 'Address:', 'woocommerce' ) . '</strong> ' . __( 'No billing address set.', 'woocommerce' ) . '</p>'; 
  253.  
  254. foreach ( self::$billing_fields as $key => $field ) { 
  255. if ( isset( $field['show'] ) && false === $field['show'] ) { 
  256. continue; 
  257.  
  258. $field_name = 'billing_' . $key; 
  259.  
  260. if ( is_callable( array( $order, 'get_' . $field_name ) ) ) { 
  261. $field_value = $order->{"get_$field_name"}( 'edit' ); 
  262. } else { 
  263. $field_value = $order->get_meta( '_' . $field_name ); 
  264.  
  265. echo '<p><strong>' . esc_html( $field['label'] ) . ':</strong> ' . make_clickable( esc_html( $field_value ) ) . '</p>'; 
  266.  
  267. echo '</div>'; 
  268.  
  269. // Display form 
  270. echo '<div class="edit_address">'; 
  271.  
  272. foreach ( self::$billing_fields as $key => $field ) { 
  273. if ( ! isset( $field['type'] ) ) { 
  274. $field['type'] = 'text'; 
  275. if ( ! isset( $field['id'] ) ) { 
  276. $field['id'] = '_billing_' . $key; 
  277. switch ( $field['type'] ) { 
  278. case 'select' : 
  279. woocommerce_wp_select( $field ); 
  280. break; 
  281. default : 
  282. woocommerce_wp_text_input( $field ); 
  283. break; 
  284. ?> 
  285. <p class="form-field form-field-wide"> 
  286. <label><?php _e( 'Payment method:', 'woocommerce' ); ?></label> 
  287. <select name="_payment_method" id="_payment_method" class="first"> 
  288. <option value=""><?php _e( 'N/A', 'woocommerce' ); ?></option> 
  289. <?php 
  290. $found_method = false; 
  291.  
  292. foreach ( $payment_gateways as $gateway ) { 
  293. if ( 'yes' === $gateway->enabled ) { 
  294. echo '<option value="' . esc_attr( $gateway->id ) . '" ' . selected( $payment_method, $gateway->id, false ) . '>' . esc_html( $gateway->get_title() ) . '</option>'; 
  295. if ( $payment_method == $gateway->id ) { 
  296. $found_method = true; 
  297.  
  298. if ( ! $found_method && ! empty( $payment_method ) ) { 
  299. echo '<option value="' . esc_attr( $payment_method ) . '" selected="selected">' . __( 'Other', 'woocommerce' ) . '</option>'; 
  300. } else { 
  301. echo '<option value="other">' . __( 'Other', 'woocommerce' ) . '</option>'; 
  302. ?> 
  303. </select> 
  304. </p> 
  305. <?php 
  306.  
  307. woocommerce_wp_text_input( array( 'id' => '_transaction_id', 'label' => __( 'Transaction ID', 'woocommerce' ) ) ); 
  308.  
  309. echo '</div>'; 
  310.  
  311. do_action( 'woocommerce_admin_order_data_after_billing_address', $order ); 
  312. ?> 
  313. </div> 
  314. <div class="order_data_column"> 
  315.  
  316. <h3> 
  317. <?php _e( 'Shipping details', 'woocommerce' ); ?> 
  318. <a href="#" class="edit_address"><?php _e( 'Edit', 'woocommerce' ); ?></a> 
  319. <span> 
  320. <a href="#" class="load_customer_shipping" style="display:none;"><?php _e( 'Load shipping address', 'woocommerce' ); ?></a> 
  321. <a href="#" class="billing-same-as-shipping" style="display:none;"><?php _e( 'Copy billing address', 'woocommerce' ); ?></a> 
  322. </span> 
  323. </h3> 
  324. <?php 
  325. // Display values 
  326. echo '<div class="address">'; 
  327.  
  328. if ( $order->get_formatted_shipping_address() ) { 
  329. echo '<p><strong>' . __( 'Address:', 'woocommerce' ) . '</strong>' . wp_kses( $order->get_formatted_shipping_address(), array( 'br' => array() ) ) . '</p>'; 
  330. } else { 
  331. echo '<p class="none_set"><strong>' . __( 'Address:', 'woocommerce' ) . '</strong> ' . __( 'No shipping address set.', 'woocommerce' ) . '</p>'; 
  332.  
  333. if ( ! empty( self::$shipping_fields ) ) { 
  334. foreach ( self::$shipping_fields as $key => $field ) { 
  335. if ( isset( $field['show'] ) && false === $field['show'] ) { 
  336. continue; 
  337.  
  338. $field_name = 'shipping_' . $key; 
  339.  
  340. if ( is_callable( array( $order, 'get_' . $field_name ) ) ) { 
  341. $field_value = $order->{"get_$field_name"}( 'edit' ); 
  342. } else { 
  343. $field_value = $order->get_meta( '_' . $field_name ); 
  344.  
  345. echo '<p><strong>' . esc_html( $field['label'] ) . ':</strong> ' . make_clickable( esc_html( $field_value ) ) . '</p>'; 
  346.  
  347. if ( apply_filters( 'woocommerce_enable_order_notes_field', 'yes' == get_option( 'woocommerce_enable_order_comments', 'yes' ) ) && $post->post_excerpt ) { 
  348. echo '<p><strong>' . __( 'Customer provided note:', 'woocommerce' ) . '</strong> ' . nl2br( esc_html( $post->post_excerpt ) ) . '</p>'; 
  349.  
  350. echo '</div>'; 
  351.  
  352. // Display form 
  353. echo '<div class="edit_address">'; 
  354.  
  355. if ( ! empty( self::$shipping_fields ) ) { 
  356. foreach ( self::$shipping_fields as $key => $field ) { 
  357. if ( ! isset( $field['type'] ) ) { 
  358. $field['type'] = 'text'; 
  359. if ( ! isset( $field['id'] ) ) { 
  360. $field['id'] = '_shipping_' . $key; 
  361.  
  362. switch ( $field['type'] ) { 
  363. case 'select' : 
  364. woocommerce_wp_select( $field ); 
  365. break; 
  366. default : 
  367. woocommerce_wp_text_input( $field ); 
  368. break; 
  369.  
  370. if ( apply_filters( 'woocommerce_enable_order_notes_field', 'yes' == get_option( 'woocommerce_enable_order_comments', 'yes' ) ) ) { 
  371. ?> 
  372. <p class="form-field form-field-wide"><label for="excerpt"><?php _e( 'Customer provided note', 'woocommerce' ) ?>:</label> 
  373. <textarea rows="1" cols="40" name="excerpt" tabindex="6" id="excerpt" placeholder="<?php esc_attr_e( 'Customer\'s notes about the order', 'woocommerce' ); ?>"><?php echo wp_kses_post( $post->post_excerpt ); ?></textarea></p> 
  374. <?php 
  375.  
  376. echo '</div>'; 
  377.  
  378. do_action( 'woocommerce_admin_order_data_after_shipping_address', $order ); 
  379. ?> 
  380. </div> 
  381. </div> 
  382. <div class="clear"></div> 
  383. </div> 
  384. </div> 
  385. <?php 
  386.  
  387. /** 
  388. * Save meta box data. 
  389. * @param int $order_id Order ID. 
  390. */ 
  391. public static function save( $order_id ) { 
  392. global $wpdb; 
  393.  
  394. self::init_address_fields(); 
  395.  
  396. // Ensure gateways are loaded in case they need to insert data into the emails. 
  397. WC()->payment_gateways(); 
  398. WC()->shipping(); 
  399.  
  400. // Get order object. 
  401. $order = wc_get_order( $order_id ); 
  402. $props = array( 'status' => wc_clean( $_POST['order_status'] ) ); 
  403.  
  404. // Create order key. 
  405. if ( ! $order->get_order_key() ) { 
  406. $props['order_key'] = 'wc_' . apply_filters( 'woocommerce_generate_order_key', uniqid( 'order_' ) ); 
  407.  
  408. // Update customer. 
  409. $customer_id = isset( $_POST['customer_user'] ) ? absint( $_POST['customer_user'] ) : 0; 
  410. if ( $customer_id !== $order->get_customer_id() ) { 
  411. $props['customer_id'] = $customer_id; 
  412.  
  413. // Update billing fields. 
  414. if ( ! empty( self::$billing_fields ) ) { 
  415. foreach ( self::$billing_fields as $key => $field ) { 
  416. if ( ! isset( $field['id'] ) ) { 
  417. $field['id'] = '_billing_' . $key; 
  418.  
  419. if ( ! isset( $_POST[ $field['id'] ] ) ) { 
  420. continue; 
  421.  
  422. if ( is_callable( array( $order, 'set_billing_' . $key ) ) ) { 
  423. $props[ 'billing_' . $key ] = wc_clean( $_POST[ $field['id'] ] ); 
  424. } else { 
  425. $order->update_meta_data( $field['id'], wc_clean( $_POST[ $field['id'] ] ) ); 
  426.  
  427. // Update shipping fields. 
  428. if ( ! empty( self::$shipping_fields ) ) { 
  429. foreach ( self::$shipping_fields as $key => $field ) { 
  430. if ( ! isset( $field['id'] ) ) { 
  431. $field['id'] = '_shipping_' . $key; 
  432.  
  433. if ( ! isset( $_POST[ $field['id'] ] ) ) { 
  434. continue; 
  435.  
  436. if ( is_callable( array( $order, 'set_shipping_' . $key ) ) ) { 
  437. $props[ 'shipping_' . $key ] = wc_clean( $_POST[ $field['id'] ] ); 
  438. } else { 
  439. $order->update_meta_data( $field['id'], wc_clean( $_POST[ $field['id'] ] ) ); 
  440.  
  441. if ( isset( $_POST['_transaction_id'] ) ) { 
  442. $props['transaction_id'] = wc_clean( $_POST['_transaction_id'] ); 
  443.  
  444. // Payment method handling. 
  445. if ( $order->get_payment_method() !== wp_unslash( $_POST['_payment_method'] ) ) { 
  446. $methods = WC()->payment_gateways->payment_gateways(); 
  447. $payment_method = wc_clean( $_POST['_payment_method'] ); 
  448. $payment_method_title = $payment_method; 
  449.  
  450. if ( isset( $methods ) && isset( $methods[ $payment_method ] ) ) { 
  451. $payment_method_title = $methods[ $payment_method ]->get_title(); 
  452.  
  453. $props['payment_method'] = $payment_method; 
  454. $props['payment_method_title'] = $payment_method_title; 
  455.  
  456. // Update date. 
  457. if ( empty( $_POST['order_date'] ) ) { 
  458. $date = current_time( 'timestamp', true ); 
  459. } else { 
  460. $date = gmdate( 'Y-m-d H:i:s', strtotime( $_POST['order_date'] . ' ' . (int) $_POST['order_date_hour'] . ':' . (int) $_POST['order_date_minute'] . ':00' ) ); 
  461.  
  462. $props['date_created'] = $date; 
  463.  
  464. // Save order data. 
  465. $order->set_props( $props ); 
  466. $order->save();