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

/admin/post-types/shop_order.php

https://github.com/CammoKing/woocommerce
PHP | 529 lines | 311 code | 108 blank | 110 comment | 53 complexity | 0110506fbfcd30cb83b024074249d7e3 MD5 | raw file
Possible License(s): GPL-3.0
  1. <?php
  2. /**
  3. * Admin functions for the shop_order post type.
  4. *
  5. * @author WooThemes
  6. * @category Admin
  7. * @package WooCommerce/Admin/Orders
  8. * @version 1.6.4
  9. */
  10. if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
  11. /**
  12. * Disable the auto-save functionality for Orders.
  13. *
  14. * @access public
  15. * @return void
  16. */
  17. function woocommerce_disable_autosave_for_orders(){
  18. global $post;
  19. if ( $post && get_post_type( $post->ID ) === 'shop_order' ) {
  20. wp_dequeue_script( 'autosave' );
  21. }
  22. }
  23. add_action( 'admin_print_scripts', 'woocommerce_disable_autosave_for_orders' );
  24. /**
  25. * Define columns for the orders page.
  26. *
  27. * @access public
  28. * @param mixed $columns
  29. * @return array
  30. */
  31. function woocommerce_edit_order_columns($columns){
  32. global $woocommerce;
  33. $columns = array();
  34. $columns["cb"] = "<input type=\"checkbox\" />";
  35. $columns["order_status"] = __( 'Status', 'woocommerce' );
  36. $columns["order_title"] = __( 'Order', 'woocommerce' );
  37. $columns["billing_address"] = __( 'Billing', 'woocommerce' );
  38. $columns["shipping_address"] = __( 'Shipping', 'woocommerce' );
  39. $columns["total_cost"] = __( 'Order Total', 'woocommerce' );
  40. $columns["order_comments"] = '<img alt="' . esc_attr__( 'Order Notes', 'woocommerce' ) . '" src="' . $woocommerce->plugin_url() . '/assets/images/order-notes_head.png" class="tips" data-tip="' . __( 'Order Notes', 'woocommerce' ) . '" width="12" height="12" />';
  41. $columns["note"] = '<img src="' . $woocommerce->plugin_url() . '/assets/images/note_head.png" alt="' . __( 'Customer Notes', 'woocommerce' ) . '" class="tips" data-tip="' . __( 'Customer Notes', 'woocommerce' ) . '" width="12" height="12" />';
  42. $columns["order_date"] = __( 'Date', 'woocommerce' );
  43. $columns["order_actions"] = __( 'Actions', 'woocommerce' );
  44. return $columns;
  45. }
  46. add_filter('manage_edit-shop_order_columns', 'woocommerce_edit_order_columns');
  47. /**
  48. * Values for the custom columns on the orders page.
  49. *
  50. * @access public
  51. * @param mixed $column
  52. * @return void
  53. */
  54. function woocommerce_custom_order_columns( $column ) {
  55. global $post, $woocommerce;
  56. $order = new WC_Order( $post->ID );
  57. switch ( $column ) {
  58. case "order_status" :
  59. printf( '<mark class="%s">%s</mark>', sanitize_title( $order->status ), esc_html__( $order->status, 'woocommerce' ) );
  60. break;
  61. case "order_title" :
  62. if ( $order->user_id )
  63. $user_info = get_userdata( $order->user_id );
  64. if ( ! empty( $user_info ) ) {
  65. $user = '<a href="user-edit.php?user_id=' . absint( $user_info->ID ) . '">';
  66. if ( $user_info->first_name || $user_info->last_name )
  67. $user .= esc_html( $user_info->first_name . ' ' . $user_info->last_name );
  68. else
  69. $user .= esc_html( $user_info->display_name );
  70. $user .= '</a>';
  71. } else {
  72. $user = __( 'Guest', 'woocommerce' );
  73. }
  74. echo '<a href="' . admin_url( 'post.php?post=' . absint( $post->ID ) . '&action=edit' ) . '"><strong>' . sprintf( __( 'Order %s', 'woocommerce' ), esc_attr( $order->get_order_number() ) ) . '</strong></a> ' . __( 'made by', 'woocommerce' ) . ' ' . $user;
  75. if ( $order->billing_email )
  76. echo '<small class="meta">' . __( 'Email:', 'woocommerce' ) . ' ' . '<a href="' . esc_url( 'mailto:' . $order->billing_email ) . '">' . esc_html( $order->billing_email ) . '</a></small>';
  77. if ( $order->billing_phone )
  78. echo '<small class="meta">' . __( 'Tel:', 'woocommerce' ) . ' ' . esc_html( $order->billing_phone ) . '</small>';
  79. break;
  80. case "billing_address" :
  81. if ( $order->get_formatted_billing_address() )
  82. echo '<a target="_blank" href="' . esc_url( 'http://maps.google.com/maps?&q=' . urlencode( $order->get_billing_address() ) . '&z=16' ) . '">' . esc_html( preg_replace( '#<br\s*/?>#i', ', ', $order->get_formatted_billing_address() ) ) .'</a>';
  83. else
  84. echo '&ndash;';
  85. if ( $order->payment_method_title )
  86. echo '<small class="meta">' . __( 'Via', 'woocommerce' ) . ' ' . esc_html( $order->payment_method_title ) . '</small>';
  87. break;
  88. case "shipping_address" :
  89. if ( $order->get_formatted_shipping_address() )
  90. echo '<a target="_blank" href="' . esc_url( 'http://maps.google.com/maps?&q=' . urlencode( $order->get_shipping_address() ) . '&z=16' ) . '">'. esc_html( preg_replace('#<br\s*/?>#i', ', ', $order->get_formatted_shipping_address() ) ) .'</a>';
  91. else
  92. echo '&ndash;';
  93. if ( $order->shipping_method_title )
  94. echo '<small class="meta">' . __( 'Via', 'woocommerce' ) . ' ' . esc_html( $order->shipping_method_title ) . '</small>';
  95. break;
  96. case "total_cost" :
  97. echo esc_html( strip_tags( $order->get_formatted_order_total() ) );
  98. break;
  99. case "order_date" :
  100. if ( '0000-00-00 00:00:00' == $post->post_date ) {
  101. $t_time = $h_time = __( 'Unpublished', 'woocommerce' );
  102. } else {
  103. $t_time = get_the_time( __( 'Y/m/d g:i:s A', 'woocommerce' ), $post );
  104. $gmt_time = strtotime( $post->post_date_gmt );
  105. $time_diff = current_time('timestamp', 1) - $gmt_time;
  106. if ( $time_diff > 0 && $time_diff < 24*60*60 )
  107. $h_time = sprintf( __( '%s ago', 'woocommerce' ), human_time_diff( $gmt_time, current_time('timestamp', 1) ) );
  108. else
  109. $h_time = get_the_time( __( 'Y/m/d', 'woocommerce' ), $post );
  110. }
  111. echo '<abbr title="' . esc_attr( $t_time ) . '">' . esc_html( apply_filters( 'post_date_column_time', $h_time, $post ) ) . '</abbr>';
  112. break;
  113. case "order_actions" :
  114. ?><p>
  115. <?php
  116. do_action( 'woocommerce_admin_order_actions_start', $order );
  117. $actions = array();
  118. if ( in_array( $order->status, array( 'pending', 'on-hold' ) ) )
  119. $actions[] = array(
  120. 'url' => wp_nonce_url( admin_url( 'admin-ajax.php?action=woocommerce-mark-order-processing&order_id=' . $post->ID ), 'woocommerce-mark-order-processing' ),
  121. 'name' => __( 'Processing', 'woocommerce' ),
  122. 'action' => "processing"
  123. );
  124. if ( in_array( $order->status, array( 'pending', 'on-hold', 'processing' ) ) )
  125. $actions[] = array(
  126. 'url' => wp_nonce_url( admin_url( 'admin-ajax.php?action=woocommerce-mark-order-complete&order_id=' . $post->ID ), 'woocommerce-mark-order-complete' ),
  127. 'name' => __( 'Complete', 'woocommerce' ),
  128. 'action' => "complete"
  129. );
  130. $actions[] = array(
  131. 'url' => admin_url( 'post.php?post=' . $post->ID . '&action=edit' ),
  132. 'name' => __( 'View', 'woocommerce' ),
  133. 'action' => "view"
  134. );
  135. $actions = apply_filters( 'woocommerce_admin_order_actions', $actions, $order );
  136. foreach ( $actions as $action ) {
  137. $image = ( isset( $action['image_url'] ) ) ? $action['image_url'] : $woocommerce->plugin_url() . '/assets/images/icons/' . $action['action'] . '.png';
  138. printf( '<a class="button tips" href="%s" data-tip="%s"><img src="%s" alt="%s" width="14" /></a>', esc_url( $action['url'] ), esc_attr( $action['name'] ), esc_attr( $image ), esc_attr( $action['name'] ) );
  139. }
  140. do_action( 'woocommerce_admin_order_actions_end', $order );
  141. ?>
  142. </p><?php
  143. break;
  144. case "note" :
  145. if ( $order->customer_note )
  146. echo '<img src="'.$woocommerce->plugin_url().'/assets/images/note.png" alt="yes" class="tips" data-tip="' . __( 'Yes', 'woocommerce' ) . '" width="14" height="14" />';
  147. else
  148. echo '<img src="'.$woocommerce->plugin_url().'/assets/images/note-off.png" alt="no" class="tips" data-tip="' . __( 'No', 'woocommerce' ) . '" width="14" height="14" />';
  149. break;
  150. case "order_comments" :
  151. echo '<div class="post-com-count-wrapper">
  152. <a href="'. esc_url( admin_url('post.php?post=' . $post->ID . '&action=edit') ) .'" class="post-com-count"><span class="comment-count">'. $post->comment_count .'</span></a>
  153. </div>';
  154. break;
  155. }
  156. }
  157. add_action( 'manage_shop_order_posts_custom_column', 'woocommerce_custom_order_columns', 2 );
  158. /**
  159. * Filters for the order page.
  160. *
  161. * @access public
  162. * @param mixed $views
  163. * @return array
  164. */
  165. function woocommerce_custom_order_views( $views ) {
  166. unset( $views['publish'] );
  167. if ( isset( $views['trash'] ) ) {
  168. $trash = $views['trash'];
  169. unset( $views['draft'] );
  170. unset( $views['trash'] );
  171. $views['trash'] = $trash;
  172. }
  173. return $views;
  174. }
  175. add_filter( 'views_edit-shop_order', 'woocommerce_custom_order_views' );
  176. /**
  177. * Actions for the orders page.
  178. *
  179. * @access public
  180. * @param mixed $actions
  181. * @return array
  182. */
  183. function woocommerce_remove_row_actions( $actions ) {
  184. if( get_post_type() === 'shop_order' ) {
  185. unset( $actions['view'] );
  186. unset( $actions['inline hide-if-no-js'] );
  187. }
  188. return $actions;
  189. }
  190. add_filter( 'post_row_actions', 'woocommerce_remove_row_actions', 10, 1 );
  191. /**
  192. * Remove edit from the bulk actions.
  193. *
  194. * @access public
  195. * @param mixed $actions
  196. * @return array
  197. */
  198. function woocommerce_bulk_actions( $actions ) {
  199. if ( isset( $actions['edit'] ) )
  200. unset( $actions['edit'] );
  201. return $actions;
  202. }
  203. add_filter( 'bulk_actions-edit-shop_order', 'woocommerce_bulk_actions' );
  204. /**
  205. * Show custom filters to filter orders by status/customer.
  206. *
  207. * @access public
  208. * @return void
  209. */
  210. function woocommerce_restrict_manage_orders() {
  211. global $woocommerce, $typenow, $wp_query;
  212. if ( $typenow != 'shop_order' )
  213. return;
  214. // Status
  215. ?>
  216. <select name='shop_order_status' id='dropdown_shop_order_status'>
  217. <option value=""><?php _e( 'Show all statuses', 'woocommerce' ); ?></option>
  218. <?php
  219. $terms = get_terms('shop_order_status');
  220. foreach ( $terms as $term ) {
  221. echo '<option value="' . esc_attr( $term->slug ) . '"';
  222. if ( isset( $wp_query->query['shop_order_status'] ) )
  223. selected( $term->slug, $wp_query->query['shop_order_status'] );
  224. echo '>' . esc_html__( $term->name, 'woocommerce' ) . ' (' . absint( $term->count ) . ')</option>';
  225. }
  226. ?>
  227. </select>
  228. <?php
  229. // Customers
  230. ?>
  231. <select id="dropdown_customers" name="_customer_user">
  232. <option value=""><?php _e( 'Show all customers', 'woocommerce' ) ?></option>
  233. <?php
  234. if ( ! empty( $_GET['_customer_user'] ) ) {
  235. $user = get_user_by( 'id', absint( $_GET['_customer_user'] ) );
  236. echo '<option value="' . absint( $user->ID ) . '" ';
  237. selected( 1, 1 );
  238. echo '>' . esc_html( $user->display_name ) . ' (#' . absint( $user->ID ) . ' &ndash; ' . esc_html( $user->user_email ) . ')</option>';
  239. }
  240. ?>
  241. </select>
  242. <?php
  243. $woocommerce->add_inline_js( "
  244. jQuery('select#dropdown_shop_order_status, select[name=m]').css('width', '150px').chosen();
  245. jQuery('select#dropdown_customers').css('width', '250px').ajaxChosen({
  246. method: 'GET',
  247. url: '" . admin_url('admin-ajax.php') . "',
  248. dataType: 'json',
  249. afterTypeDelay: 100,
  250. minTermLength: 1,
  251. data: {
  252. action: 'woocommerce_json_search_customers',
  253. security: '" . wp_create_nonce("search-customers") . "',
  254. default: '" . __( 'Show all customers', 'woocommerce' ) . "'
  255. }
  256. }, function (data) {
  257. var terms = {};
  258. $.each(data, function (i, val) {
  259. terms[i] = val;
  260. });
  261. return terms;
  262. });
  263. " );
  264. }
  265. add_action( 'restrict_manage_posts', 'woocommerce_restrict_manage_orders' );
  266. /**
  267. * Filter the orders by the posted customer.
  268. *
  269. * @access public
  270. * @param mixed $vars
  271. * @return array
  272. */
  273. function woocommerce_orders_by_customer_query( $vars ) {
  274. global $typenow, $wp_query;
  275. if ( $typenow == 'shop_order' && isset( $_GET['_customer_user'] ) && $_GET['_customer_user'] > 0 ) {
  276. $vars['meta_key'] = '_customer_user';
  277. $vars['meta_value'] = (int) $_GET['_customer_user'];
  278. }
  279. return $vars;
  280. }
  281. add_filter( 'request', 'woocommerce_orders_by_customer_query' );
  282. /**
  283. * Make order columns sortable.
  284. *
  285. *
  286. * https://gist.github.com/906872
  287. *
  288. * @access public
  289. * @param mixed $columns
  290. * @return array
  291. */
  292. function woocommerce_custom_shop_order_sort( $columns ) {
  293. $custom = array(
  294. 'order_title' => 'ID',
  295. 'order_total' => 'order_total',
  296. 'order_date' => 'date'
  297. );
  298. unset( $columns['comments'] );
  299. return wp_parse_args( $custom, $columns );
  300. }
  301. add_filter( "manage_edit-shop_order_sortable_columns", 'woocommerce_custom_shop_order_sort' );
  302. /**
  303. * Order column orderby/request.
  304. *
  305. * @access public
  306. * @param mixed $vars
  307. * @return array
  308. */
  309. function woocommerce_custom_shop_order_orderby( $vars ) {
  310. global $typenow, $wp_query;
  311. if ( $typenow != 'shop_order' )
  312. return $vars;
  313. // Sorting
  314. if ( isset( $vars['orderby'] ) ) {
  315. if ( 'order_total' == $vars['orderby'] ) {
  316. $vars = array_merge( $vars, array(
  317. 'meta_key' => '_order_total',
  318. 'orderby' => 'meta_value_num'
  319. ) );
  320. }
  321. }
  322. return $vars;
  323. }
  324. add_filter( 'request', 'woocommerce_custom_shop_order_orderby' );
  325. /**
  326. * Search custom fields as well as content.
  327. *
  328. * @access public
  329. * @param mixed $wp
  330. * @return void
  331. */
  332. function woocommerce_shop_order_search_custom_fields( $wp ) {
  333. global $pagenow, $wpdb;
  334. if ( 'edit.php' != $pagenow ) return $wp;
  335. if ( ! isset( $wp->query_vars['s'] ) || ! $wp->query_vars['s'] ) return $wp;
  336. if ( $wp->query_vars['post_type'] != 'shop_order' ) return $wp;
  337. $search_fields = array_map( 'esc_attr', apply_filters( 'woocommerce_shop_order_search_fields', array(
  338. '_order_key',
  339. '_billing_first_name',
  340. '_billing_last_name',
  341. '_billing_company',
  342. '_billing_address_1',
  343. '_billing_address_2',
  344. '_billing_city',
  345. '_billing_postcode',
  346. '_billing_country',
  347. '_billing_state',
  348. '_billing_email',
  349. '_billing_phone'
  350. ) ) );
  351. // Query matching custom fields - this seems faster than meta_query
  352. $post_ids = $wpdb->get_col(
  353. $wpdb->prepare(
  354. "SELECT post_id FROM " . $wpdb->postmeta . " WHERE meta_key IN ('" . implode( "','", $search_fields ) . "') AND meta_value LIKE '%%%s%%'", esc_attr( $_GET['s'] )
  355. )
  356. );
  357. // Query matching excerpts and titles
  358. $post_ids = array_merge( $post_ids, $wpdb->get_col( $wpdb->prepare('
  359. SELECT ' . $wpdb->posts . '.ID
  360. FROM ' . $wpdb->posts . '
  361. LEFT JOIN ' . $wpdb->postmeta . ' ON ' . $wpdb->posts . '.ID = ' . $wpdb->postmeta . '.post_id
  362. LEFT JOIN ' . $wpdb->users . ' ON ' . $wpdb->postmeta . '.meta_value = ' . $wpdb->users . '.ID
  363. WHERE
  364. post_excerpt LIKE "%%%1$s%%" OR
  365. post_title LIKE "%%%1$s%%" OR
  366. (
  367. meta_key = "_customer_user" AND
  368. (
  369. user_login LIKE "%%%1$s%%" OR
  370. user_nicename LIKE "%%%1$s%%" OR
  371. user_email LIKE "%%%1$s%%" OR
  372. display_name LIKE "%%%1$s%%"
  373. )
  374. )
  375. ',
  376. esc_attr($_GET['s'])
  377. ) ) );
  378. // Add ID
  379. $search_order_id = str_replace( 'Order #', '', $_GET['s'] );
  380. if ( is_numeric( $search_order_id ) )
  381. $post_ids[] = $search_order_id;
  382. // Add blank ID so not all results are returned if the search finds nothing
  383. $post_ids[] = 0;
  384. // Remove s - we don't want to search order name
  385. unset( $wp->query_vars['s'] );
  386. // so we know we're doing this
  387. $wp->query_vars['shop_order_search'] = true;
  388. // Search by found posts
  389. $wp->query_vars['post__in'] = $post_ids;
  390. }
  391. /**
  392. * Change the label when searching orders.
  393. *
  394. * @access public
  395. * @param mixed $query
  396. * @return string
  397. */
  398. function woocommerce_shop_order_search_label($query) {
  399. global $pagenow, $typenow;
  400. if ( 'edit.php' != $pagenow ) return $query;
  401. if ( $typenow != 'shop_order' ) return $query;
  402. if ( ! get_query_var( 'shop_order_search' ) ) return $query;
  403. return $_GET['s'];
  404. }
  405. if ( is_admin() ) {
  406. add_filter( 'parse_query', 'woocommerce_shop_order_search_custom_fields' );
  407. add_filter( 'get_search_query', 'woocommerce_shop_order_search_label' );
  408. }
  409. /**
  410. * Query vars for custom searches.
  411. *
  412. * @access public
  413. * @param mixed $public_query_vars
  414. * @return array
  415. */
  416. function woocommerce_add_custom_query_var($public_query_vars) {
  417. $public_query_vars[] = 'sku';
  418. $public_query_vars[] = 'shop_order_search';
  419. return $public_query_vars;
  420. }
  421. add_filter('query_vars', 'woocommerce_add_custom_query_var');