2017-11-03 16:10:32 +00:00
< ? php
/**
* List tables : orders .
*
2020-08-05 20:49:10 +00:00
* @ package WooCommerce\Admin
2018-03-06 18:08:30 +00:00
* @ version 3.3 . 0
2017-11-03 16:10:32 +00:00
*/
if ( ! defined ( 'ABSPATH' ) ) {
exit ;
}
if ( class_exists ( 'WC_Admin_List_Table_Orders' , false ) ) {
return ;
}
if ( ! class_exists ( 'WC_Admin_List_Table' , false ) ) {
2017-12-11 12:41:29 +00:00
include_once 'abstract-class-wc-admin-list-table.php' ;
2017-11-03 16:10:32 +00:00
}
/**
* WC_Admin_List_Table_Orders Class .
*/
class WC_Admin_List_Table_Orders extends WC_Admin_List_Table {
/**
* Post type .
*
* @ var string
*/
protected $list_table_type = 'shop_order' ;
/**
* Constructor .
*/
public function __construct () {
parent :: __construct ();
add_action ( 'admin_notices' , array ( $this , 'bulk_admin_notices' ) );
add_action ( 'admin_footer' , array ( $this , 'order_preview_template' ) );
add_filter ( 'get_search_query' , array ( $this , 'search_label' ) );
add_filter ( 'query_vars' , array ( $this , 'add_custom_query_var' ) );
add_action ( 'parse_query' , array ( $this , 'search_custom_fields' ) );
}
/**
* Render blank state .
*/
protected function render_blank_state () {
echo '<div class="woocommerce-BlankState">' ;
2019-02-22 03:13:37 +00:00
2017-11-03 16:10:32 +00:00
echo '<h2 class="woocommerce-BlankState-message">' . esc_html__ ( 'When you receive a new order, it will appear here.' , 'woocommerce' ) . '</h2>' ;
2019-02-22 07:55:03 +00:00
echo '<div class="woocommerce-BlankState-buttons">' ;
2017-11-03 16:10:32 +00:00
echo '<a class="woocommerce-BlankState-cta button-primary button" target="_blank" href="https://docs.woocommerce.com/document/managing-orders/?utm_source=blankslate&utm_medium=product&utm_content=ordersdoc&utm_campaign=woocommerceplugin">' . esc_html__ ( 'Learn more about orders' , 'woocommerce' ) . '</a>' ;
2019-02-22 07:55:03 +00:00
echo '</div>' ;
2019-02-22 03:13:37 +00:00
do_action ( 'wc_marketplace_suggestions_orders_empty_state' );
2017-11-03 16:10:32 +00:00
echo '</div>' ;
}
/**
2017-11-05 15:52:42 +00:00
* Define primary column .
2017-11-03 16:10:32 +00:00
*
2017-12-11 16:41:23 +00:00
* @ return string
2017-11-03 16:10:32 +00:00
*/
protected function get_primary_column () {
return 'order_number' ;
}
/**
* Get row actions to show in the list table .
*
* @ param array $actions Array of actions .
* @ param WP_Post $post Current post object .
* @ return array
*/
protected function get_row_actions ( $actions , $post ) {
return array ();
}
/**
* Define hidden columns .
*
* @ return array
*/
protected function define_hidden_columns () {
return array (
'shipping_address' ,
'billing_address' ,
2017-11-22 16:28:11 +00:00
'wc_actions' ,
2017-11-03 16:10:32 +00:00
);
}
/**
* Define which columns are sortable .
*
* @ param array $columns Existing columns .
* @ return array
*/
public function define_sortable_columns ( $columns ) {
$custom = array (
2017-11-05 15:52:42 +00:00
'order_number' => 'ID' ,
'order_total' => 'order_total' ,
'order_date' => 'date' ,
2017-11-03 16:10:32 +00:00
);
unset ( $columns [ 'comments' ] );
return wp_parse_args ( $custom , $columns );
}
/**
* Define which columns to show on this screen .
*
* @ param array $columns Existing columns .
* @ return array
*/
public function define_columns ( $columns ) {
$show_columns = array ();
$show_columns [ 'cb' ] = $columns [ 'cb' ];
$show_columns [ 'order_number' ] = __ ( 'Order' , 'woocommerce' );
$show_columns [ 'order_date' ] = __ ( 'Date' , 'woocommerce' );
$show_columns [ 'order_status' ] = __ ( 'Status' , 'woocommerce' );
2017-11-20 15:51:25 +00:00
$show_columns [ 'billing_address' ] = __ ( 'Billing' , 'woocommerce' );
$show_columns [ 'shipping_address' ] = __ ( 'Ship to' , 'woocommerce' );
2017-11-03 16:10:32 +00:00
$show_columns [ 'order_total' ] = __ ( 'Total' , 'woocommerce' );
2017-11-22 16:14:30 +00:00
$show_columns [ 'wc_actions' ] = __ ( 'Actions' , 'woocommerce' );
2017-11-03 16:10:32 +00:00
wp_enqueue_script ( 'wc-orders' );
return $show_columns ;
}
/**
* Define bulk actions .
*
* @ param array $actions Existing actions .
* @ return array
*/
public function define_bulk_actions ( $actions ) {
if ( isset ( $actions [ 'edit' ] ) ) {
unset ( $actions [ 'edit' ] );
}
2018-11-29 20:20:56 +00:00
$actions [ 'mark_processing' ] = __ ( 'Change status to processing' , 'woocommerce' );
$actions [ 'mark_on-hold' ] = __ ( 'Change status to on-hold' , 'woocommerce' );
$actions [ 'mark_completed' ] = __ ( 'Change status to completed' , 'woocommerce' );
2019-01-07 11:22:29 +00:00
if ( wc_string_to_bool ( get_option ( 'woocommerce_allow_bulk_remove_personal_data' , 'no' ) ) ) {
2018-11-29 20:20:56 +00:00
$actions [ 'remove_personal_data' ] = __ ( 'Remove personal data' , 'woocommerce' );
}
2017-11-03 16:10:32 +00:00
return $actions ;
}
/**
* Pre - fetch any data for the row each column has access to it . the_order global is there for bw compat .
*
* @ param int $post_id Post ID being shown .
*/
protected function prepare_row_data ( $post_id ) {
global $the_order ;
if ( empty ( $this -> object ) || $this -> object -> get_id () !== $post_id ) {
2017-12-11 16:41:23 +00:00
$this -> object = wc_get_order ( $post_id );
$the_order = $this -> object ;
2017-11-03 16:10:32 +00:00
}
}
/**
* Render columm : order_number .
*/
protected function render_order_number_column () {
$buyer = '' ;
if ( $this -> object -> get_billing_first_name () || $this -> object -> get_billing_last_name () ) {
/* translators: 1: first name 2: last name */
$buyer = trim ( sprintf ( _x ( '%1$s %2$s' , 'full name' , 'woocommerce' ), $this -> object -> get_billing_first_name (), $this -> object -> get_billing_last_name () ) );
} elseif ( $this -> object -> get_billing_company () ) {
$buyer = trim ( $this -> object -> get_billing_company () );
} elseif ( $this -> object -> get_customer_id () ) {
$user = get_user_by ( 'id' , $this -> object -> get_customer_id () );
$buyer = ucwords ( $user -> display_name );
}
2019-05-16 22:02:57 +00:00
/**
* Filter buyer name in list table orders .
*
* @ since 3.7 . 0
* @ param string $buyer Buyer name .
* @ param WC_Order $order Order data .
*/
$buyer = apply_filters ( 'woocommerce_admin_order_buyer_name' , $buyer , $this -> object );
2017-11-15 13:41:20 +00:00
if ( $this -> object -> get_status () === 'trash' ) {
echo '<strong>#' . esc_attr ( $this -> object -> get_order_number () ) . ' ' . esc_html ( $buyer ) . '</strong>' ;
} else {
echo '<a href="#" class="order-preview" data-order-id="' . absint ( $this -> object -> get_id () ) . '" title="' . esc_attr ( __ ( 'Preview' , 'woocommerce' ) ) . '">' . esc_html ( __ ( 'Preview' , 'woocommerce' ) ) . '</a>' ;
echo '<a href="' . esc_url ( admin_url ( 'post.php?post=' . absint ( $this -> object -> get_id () ) ) . '&action=edit' ) . '" class="order-view"><strong>#' . esc_attr ( $this -> object -> get_order_number () ) . ' ' . esc_html ( $buyer ) . '</strong></a>' ;
}
2017-11-03 16:10:32 +00:00
}
/**
* Render columm : order_status .
*/
protected function render_order_status_column () {
2017-12-11 13:20:42 +00:00
$tooltip = '' ;
$comment_count = get_comment_count ( $this -> object -> get_id () );
$approved_comments_count = absint ( $comment_count [ 'approved' ] );
2017-11-03 16:10:32 +00:00
2017-12-11 13:20:42 +00:00
if ( $approved_comments_count ) {
2017-12-11 12:41:29 +00:00
$latest_notes = wc_get_order_notes (
array (
'order_id' => $this -> object -> get_id (),
'limit' => 1 ,
'orderby' => 'date_created_gmt' ,
)
);
2017-11-03 16:10:32 +00:00
$latest_note = current ( $latest_notes );
2017-12-11 13:20:42 +00:00
if ( isset ( $latest_note -> content ) && 1 === $approved_comments_count ) {
2017-11-03 16:10:32 +00:00
$tooltip = wc_sanitize_tooltip ( $latest_note -> content );
} elseif ( isset ( $latest_note -> content ) ) {
/* translators: %d: notes count */
2017-12-11 13:20:42 +00:00
$tooltip = wc_sanitize_tooltip ( $latest_note -> content . '<br/><small style="display:block">' . sprintf ( _n ( 'Plus %d other note' , 'Plus %d other notes' , ( $approved_comments_count - 1 ), 'woocommerce' ), $approved_comments_count - 1 ) . '</small>' );
2017-11-03 16:10:32 +00:00
} else {
/* translators: %d: notes count */
2017-12-11 13:20:42 +00:00
$tooltip = wc_sanitize_tooltip ( sprintf ( _n ( '%d note' , '%d notes' , $approved_comments_count , 'woocommerce' ), $approved_comments_count ) );
2017-11-03 16:10:32 +00:00
}
}
if ( $tooltip ) {
printf ( '<mark class="order-status %s tips" data-tip="%s"><span>%s</span></mark>' , esc_attr ( sanitize_html_class ( 'status-' . $this -> object -> get_status () ) ), wp_kses_post ( $tooltip ), esc_html ( wc_get_order_status_name ( $this -> object -> get_status () ) ) );
} else {
printf ( '<mark class="order-status %s"><span>%s</span></mark>' , esc_attr ( sanitize_html_class ( 'status-' . $this -> object -> get_status () ) ), esc_html ( wc_get_order_status_name ( $this -> object -> get_status () ) ) );
}
}
/**
* Render columm : order_date .
*/
protected function render_order_date_column () {
2018-06-08 15:18:32 +00:00
$order_timestamp = $this -> object -> get_date_created () ? $this -> object -> get_date_created () -> getTimestamp () : '' ;
if ( ! $order_timestamp ) {
echo '–' ;
return ;
}
2017-11-03 16:10:32 +00:00
2018-02-20 02:25:03 +00:00
// Check if the order was created within the last 24 hours, and not in the future.
2019-12-13 20:51:14 +00:00
if ( $order_timestamp > strtotime ( '-1 day' , time () ) && $order_timestamp <= time () ) {
2017-12-11 16:41:23 +00:00
$show_date = sprintf (
/* translators: %s: human-readable time difference */
_x ( '%s ago' , '%s = human-readable time difference' , 'woocommerce' ),
2019-12-13 20:51:14 +00:00
human_time_diff ( $this -> object -> get_date_created () -> getTimestamp (), time () )
2017-12-11 16:41:23 +00:00
);
2017-11-03 16:10:32 +00:00
} else {
2017-11-20 15:51:25 +00:00
$show_date = $this -> object -> get_date_created () -> date_i18n ( apply_filters ( 'woocommerce_admin_order_date_format' , __ ( 'M j, Y' , 'woocommerce' ) ) );
2017-11-03 16:10:32 +00:00
}
printf (
'<time datetime="%1$s" title="%2$s">%3$s</time>' ,
esc_attr ( $this -> object -> get_date_created () -> date ( 'c' ) ),
esc_html ( $this -> object -> get_date_created () -> date_i18n ( get_option ( 'date_format' ) . ' ' . get_option ( 'time_format' ) ) ),
esc_html ( $show_date )
);
}
/**
* Render columm : order_total .
*/
protected function render_order_total_column () {
if ( $this -> object -> get_payment_method_title () ) {
/* translators: %s: method */
echo '<span class="tips" data-tip="' . esc_attr ( sprintf ( __ ( 'via %s' , 'woocommerce' ), $this -> object -> get_payment_method_title () ) ) . '">' . wp_kses_post ( $this -> object -> get_formatted_order_total () ) . '</span>' ;
} else {
echo wp_kses_post ( $this -> object -> get_formatted_order_total () );
}
}
/**
2017-11-22 16:14:30 +00:00
* Render columm : wc_actions .
2017-11-03 16:10:32 +00:00
*/
2017-11-22 16:14:30 +00:00
protected function render_wc_actions_column () {
2017-11-03 16:10:32 +00:00
echo '<p>' ;
do_action ( 'woocommerce_admin_order_actions_start' , $this -> object );
$actions = array ();
if ( $this -> object -> has_status ( array ( 'pending' , 'on-hold' ) ) ) {
$actions [ 'processing' ] = array (
2017-12-11 12:41:29 +00:00
'url' => wp_nonce_url ( admin_url ( 'admin-ajax.php?action=woocommerce_mark_order_status&status=processing&order_id=' . $this -> object -> get_id () ), 'woocommerce-mark-order-status' ),
'name' => __ ( 'Processing' , 'woocommerce' ),
'action' => 'processing' ,
2017-11-03 16:10:32 +00:00
);
}
if ( $this -> object -> has_status ( array ( 'pending' , 'on-hold' , 'processing' ) ) ) {
$actions [ 'complete' ] = array (
2017-12-11 12:41:29 +00:00
'url' => wp_nonce_url ( admin_url ( 'admin-ajax.php?action=woocommerce_mark_order_status&status=completed&order_id=' . $this -> object -> get_id () ), 'woocommerce-mark-order-status' ),
'name' => __ ( 'Complete' , 'woocommerce' ),
'action' => 'complete' ,
2017-11-03 16:10:32 +00:00
);
}
$actions = apply_filters ( 'woocommerce_admin_order_actions' , $actions , $this -> object );
2017-11-20 22:43:37 +00:00
echo wc_render_action_buttons ( $actions ); // WPCS: XSS ok.
2017-11-03 16:10:32 +00:00
do_action ( 'woocommerce_admin_order_actions_end' , $this -> object );
echo '</p>' ;
}
/**
* Render columm : billing_address .
*/
protected function render_billing_address_column () {
2017-12-11 16:41:23 +00:00
$address = $this -> object -> get_formatted_billing_address ();
if ( $address ) {
2017-11-03 16:10:32 +00:00
echo esc_html ( preg_replace ( '#<br\s*/?>#i' , ', ' , $address ) );
2017-11-20 17:06:08 +00:00
if ( $this -> object -> get_payment_method () ) {
/* translators: %s: payment method */
2017-12-11 16:41:23 +00:00
echo '<span class="description">' . sprintf ( __ ( 'via %s' , 'woocommerce' ), esc_html ( $this -> object -> get_payment_method_title () ) ) . '</span>' ; // WPCS: XSS ok.
2017-11-20 17:06:08 +00:00
}
2017-11-03 16:10:32 +00:00
} else {
echo '–' ;
}
}
/**
* Render columm : shipping_address .
*/
protected function render_shipping_address_column () {
2017-12-11 16:41:23 +00:00
$address = $this -> object -> get_formatted_shipping_address ();
if ( $address ) {
2017-11-03 16:10:32 +00:00
echo '<a target="_blank" href="' . esc_url ( $this -> object -> get_shipping_address_map_url () ) . '">' . esc_html ( preg_replace ( '#<br\s*/?>#i' , ', ' , $address ) ) . '</a>' ;
2017-11-20 17:06:08 +00:00
if ( $this -> object -> get_shipping_method () ) {
/* translators: %s: shipping method */
2017-12-11 16:41:23 +00:00
echo '<span class="description">' . sprintf ( __ ( 'via %s' , 'woocommerce' ), esc_html ( $this -> object -> get_shipping_method () ) ) . '</span>' ; // WPCS: XSS ok.
2017-11-20 17:06:08 +00:00
}
2017-11-03 16:10:32 +00:00
} else {
echo '–' ;
}
}
/**
* Template for order preview .
*
* @ since 3.3 . 0
*/
public function order_preview_template () {
?>
< script type = " text/template " id = " tmpl-wc-modal-view-order " >
< div class = " wc-backbone-modal wc-order-preview " >
< div class = " wc-backbone-modal-content " >
< section class = " wc-backbone-modal-main " role = " main " >
< header class = " wc-backbone-modal-header " >
2017-12-04 13:45:52 +00:00
< mark class = " order-status status- { { data.status }} " >< span > {{ data . status_name }} </ span ></ mark >
2017-12-11 16:41:23 +00:00
< ? php /* translators: %s: order ID */ ?>
2017-11-03 16:10:32 +00:00
< h1 >< ? php echo esc_html ( sprintf ( __ ( 'Order #%s' , 'woocommerce' ), '{{ data.order_number }}' ) ); ?> </h1>
< button class = " modal-close modal-close-link dashicons dashicons-no-alt " >
< span class = " screen-reader-text " >< ? php esc_html_e ( 'Close modal panel' , 'woocommerce' ); ?> </span>
</ button >
</ header >
< article >
2017-11-17 20:30:01 +00:00
< ? php do_action ( 'woocommerce_admin_order_preview_start' ); ?>
2017-11-03 16:10:32 +00:00
< div class = " wc-order-preview-addresses " >
< div class = " wc-order-preview-address " >
< h2 >< ? php esc_html_e ( 'Billing details' , 'woocommerce' ); ?> </h2>
{{{ data . formatted_billing_address }}}
< # if ( data.data.billing.email ) { #>
< strong >< ? php esc_html_e ( 'Email' , 'woocommerce' ); ?> </strong>
2017-11-15 12:51:14 +00:00
< a href = " mailto: { { data.data.billing.email }} " > {{ data . data . billing . email }} </ a >
2017-11-03 16:10:32 +00:00
< # } #>
< # if ( data.data.billing.phone ) { #>
< strong >< ? php esc_html_e ( 'Phone' , 'woocommerce' ); ?> </strong>
2017-11-15 12:51:14 +00:00
< a href = " tel: { { data.data.billing.phone }} " > {{ data . data . billing . phone }} </ a >
2017-11-03 16:10:32 +00:00
< # } #>
< # if ( data.payment_via ) { #>
< strong >< ? php esc_html_e ( 'Payment via' , 'woocommerce' ); ?> </strong>
2017-11-23 10:18:23 +00:00
{{{ data . payment_via }}}
2017-11-03 16:10:32 +00:00
< # } #>
</ div >
< # if ( data.needs_shipping ) { #>
< div class = " wc-order-preview-address " >
< h2 >< ? php esc_html_e ( 'Shipping details' , 'woocommerce' ); ?> </h2>
< # if ( data.ship_to_billing ) { #>
{{{ data . formatted_billing_address }}}
< # } else { #>
2017-11-15 12:51:14 +00:00
< a href = " { { data.shipping_address_map_url }} " target = " _blank " > {{{ data . formatted_shipping_address }}} </ a >
2017-11-03 16:10:32 +00:00
< # } #>
< # if ( data.shipping_via ) { #>
< strong >< ? php esc_html_e ( 'Shipping method' , 'woocommerce' ); ?> </strong>
{{ data . shipping_via }}
< # } #>
</ div >
< # } #>
2017-11-20 17:24:00 +00:00
2018-02-16 11:12:15 +00:00
< # if ( data.data.customer_note ) { #>
2018-02-16 14:24:31 +00:00
< div class = " wc-order-preview-note " >
< strong >< ? php esc_html_e ( 'Note' , 'woocommerce' ); ?> </strong>
{{ data . data . customer_note }}
2018-02-19 12:41:55 +00:00
</ div >
2018-02-16 11:12:15 +00:00
< # } #>
2017-11-03 16:10:32 +00:00
</ div >
2017-11-20 17:24:00 +00:00
{{{ data . item_html }}}
2017-11-17 20:30:01 +00:00
< ? php do_action ( 'woocommerce_admin_order_preview_end' ); ?>
2017-11-03 16:10:32 +00:00
</ article >
< footer >
< div class = " inner " >
2017-11-20 22:43:37 +00:00
{{{ data . actions_html }}}
2018-02-15 12:46:47 +00:00
< a class = " button button-primary button-large " aria - label = " <?php esc_attr_e( 'Edit this order', 'woocommerce' ); ?> " href = " <?php echo esc_url( admin_url( 'post.php?action=edit' ) ); ?>&post= { { data.data.id }} " >< ? php esc_html_e ( 'Edit' , 'woocommerce' ); ?> </a>
2017-11-03 16:10:32 +00:00
</ div >
</ footer >
</ section >
</ div >
</ div >
< div class = " wc-backbone-modal-backdrop modal-close " ></ div >
</ script >
< ? php
}
2017-11-21 16:22:43 +00:00
/**
* Get items to display in the preview as HTML .
*
* @ param WC_Order $order Order object .
* @ return string
*/
public static function get_order_preview_item_html ( $order ) {
2017-12-11 12:41:29 +00:00
$hidden_order_itemmeta = apply_filters (
2018-11-29 20:16:51 +00:00
'woocommerce_hidden_order_itemmeta' ,
array (
2017-12-11 12:41:29 +00:00
'_qty' ,
'_tax_class' ,
'_product_id' ,
'_variation_id' ,
'_line_subtotal' ,
'_line_subtotal_tax' ,
'_line_total' ,
'_line_tax' ,
'method_id' ,
'cost' ,
2018-06-08 11:18:15 +00:00
'_reduced_stock' ,
2017-12-11 12:41:29 +00:00
)
);
2017-11-21 16:22:43 +00:00
$line_items = apply_filters ( 'woocommerce_admin_order_preview_line_items' , $order -> get_items (), $order );
2017-12-11 12:41:29 +00:00
$columns = apply_filters (
2018-11-29 20:16:51 +00:00
'woocommerce_admin_order_preview_line_item_columns' ,
array (
2017-12-11 12:41:29 +00:00
'product' => __ ( 'Product' , 'woocommerce' ),
'quantity' => __ ( 'Quantity' , 'woocommerce' ),
'tax' => __ ( 'Tax' , 'woocommerce' ),
'total' => __ ( 'Total' , 'woocommerce' ),
2018-11-29 20:16:51 +00:00
),
$order
2017-12-11 12:41:29 +00:00
);
2017-11-21 16:22:43 +00:00
if ( ! wc_tax_enabled () ) {
unset ( $columns [ 'tax' ] );
}
$html = '
< div class = " wc-order-preview-table-wrapper " >
< table cellspacing = " 0 " class = " wc-order-preview-table " >
< thead >
< tr > ' ;
foreach ( $columns as $column => $label ) {
$html .= '<th class="wc-order-preview-table__column--' . esc_attr ( $column ) . '">' . esc_html ( $label ) . '</th>' ;
}
$html .= '
</ tr >
</ thead >
< tbody > ' ;
foreach ( $line_items as $item_id => $item ) {
2018-01-18 14:57:51 +00:00
2017-11-21 16:22:43 +00:00
$product_object = is_callable ( array ( $item , 'get_product' ) ) ? $item -> get_product () : null ;
2018-01-18 14:57:51 +00:00
$row_class = apply_filters ( 'woocommerce_admin_html_order_preview_item_class' , '' , $item , $order );
2017-11-21 16:22:43 +00:00
2018-01-18 14:57:51 +00:00
$html .= '<tr class="wc-order-preview-table__item wc-order-preview-table__item--' . esc_attr ( $item_id ) . ( $row_class ? ' ' . esc_attr ( $row_class ) : '' ) . '">' ;
2017-11-21 16:22:43 +00:00
foreach ( $columns as $column => $label ) {
$html .= '<td class="wc-order-preview-table__column--' . esc_attr ( $column ) . '">' ;
switch ( $column ) {
case 'product' :
$html .= wp_kses_post ( $item -> get_name () );
if ( $product_object ) {
$html .= '<div class="wc-order-item-sku">' . esc_html ( $product_object -> get_sku () ) . '</div>' ;
}
2017-12-11 16:41:23 +00:00
$meta_data = $item -> get_formatted_meta_data ( '' );
if ( $meta_data ) {
2017-11-21 16:22:43 +00:00
$html .= '<table cellspacing="0" class="wc-order-item-meta">' ;
foreach ( $meta_data as $meta_id => $meta ) {
2018-03-06 18:08:30 +00:00
if ( in_array ( $meta -> key , $hidden_order_itemmeta , true ) ) {
2017-11-21 16:22:43 +00:00
continue ;
}
$html .= '<tr><th>' . wp_kses_post ( $meta -> display_key ) . ':</th><td>' . wp_kses_post ( force_balance_tags ( $meta -> display_value ) ) . '</td></tr>' ;
}
$html .= '</table>' ;
}
break ;
case 'quantity' :
$html .= esc_html ( $item -> get_quantity () );
break ;
case 'tax' :
$html .= wc_price ( $item -> get_total_tax (), array ( 'currency' => $order -> get_currency () ) );
break ;
case 'total' :
$html .= wc_price ( $item -> get_total (), array ( 'currency' => $order -> get_currency () ) );
break ;
2017-12-11 12:41:29 +00:00
default :
2017-11-21 16:22:43 +00:00
$html .= apply_filters ( 'woocommerce_admin_order_preview_line_item_column_' . sanitize_key ( $column ), '' , $item , $item_id , $order );
break ;
}
$html .= '</td>' ;
}
$html .= '</tr>' ;
}
$html .= '
</ tbody >
</ table >
</ div > ' ;
return $html ;
}
/**
* Get actions to display in the preview as HTML .
*
* @ param WC_Order $order Order object .
* @ return string
*/
public static function get_order_preview_actions_html ( $order ) {
$actions = array ();
$status_actions = array ();
if ( $order -> has_status ( array ( 'pending' ) ) ) {
$status_actions [ 'on-hold' ] = array (
2017-12-11 12:41:29 +00:00
'url' => wp_nonce_url ( admin_url ( 'admin-ajax.php?action=woocommerce_mark_order_status&status=on-hold&order_id=' . $order -> get_id () ), 'woocommerce-mark-order-status' ),
'name' => __ ( 'On-hold' , 'woocommerce' ),
2018-02-15 12:46:47 +00:00
'title' => __ ( 'Change order status to on-hold' , 'woocommerce' ),
2017-12-11 12:41:29 +00:00
'action' => 'on-hold' ,
2017-11-21 16:22:43 +00:00
);
}
if ( $order -> has_status ( array ( 'pending' , 'on-hold' ) ) ) {
$status_actions [ 'processing' ] = array (
2017-12-11 12:41:29 +00:00
'url' => wp_nonce_url ( admin_url ( 'admin-ajax.php?action=woocommerce_mark_order_status&status=processing&order_id=' . $order -> get_id () ), 'woocommerce-mark-order-status' ),
'name' => __ ( 'Processing' , 'woocommerce' ),
2018-02-15 12:46:47 +00:00
'title' => __ ( 'Change order status to processing' , 'woocommerce' ),
2017-12-11 12:41:29 +00:00
'action' => 'processing' ,
2017-11-21 16:22:43 +00:00
);
}
if ( $order -> has_status ( array ( 'pending' , 'on-hold' , 'processing' ) ) ) {
$status_actions [ 'complete' ] = array (
2017-12-11 12:41:29 +00:00
'url' => wp_nonce_url ( admin_url ( 'admin-ajax.php?action=woocommerce_mark_order_status&status=completed&order_id=' . $order -> get_id () ), 'woocommerce-mark-order-status' ),
'name' => __ ( 'Completed' , 'woocommerce' ),
2018-02-15 12:46:47 +00:00
'title' => __ ( 'Change order status to completed' , 'woocommerce' ),
2017-12-11 12:41:29 +00:00
'action' => 'complete' ,
2017-11-21 16:22:43 +00:00
);
}
if ( $status_actions ) {
$actions [ 'status' ] = array (
'group' => __ ( 'Change status: ' , 'woocommerce' ),
'actions' => $status_actions ,
);
}
return wc_render_action_buttons ( apply_filters ( 'woocommerce_admin_order_preview_actions' , $actions , $order ) );
}
/**
* Get order details to send to the ajax endpoint for previews .
*
* @ param WC_Order $order Order object .
* @ return array
*/
public static function order_preview_get_order_details ( $order ) {
if ( ! $order ) {
return array ();
}
2017-11-22 16:31:27 +00:00
$payment_via = $order -> get_payment_method_title ();
2017-11-23 10:18:23 +00:00
$payment_method = $order -> get_payment_method ();
2017-11-22 16:31:27 +00:00
$payment_gateways = WC () -> payment_gateways () ? WC () -> payment_gateways -> payment_gateways () : array ();
2017-12-11 16:41:23 +00:00
$transaction_id = $order -> get_transaction_id ();
if ( $transaction_id ) {
2017-11-22 16:31:27 +00:00
2017-12-13 18:59:07 +00:00
$url = isset ( $payment_gateways [ $payment_method ] ) ? $payment_gateways [ $payment_method ] -> get_transaction_url ( $order ) : false ;
if ( $url ) {
2017-11-22 16:31:27 +00:00
$payment_via .= ' (<a href="' . esc_url ( $url ) . '" target="_blank">' . esc_html ( $transaction_id ) . '</a>)' ;
} else {
$payment_via .= ' (' . esc_html ( $transaction_id ) . ')' ;
}
}
2017-12-11 16:41:23 +00:00
$billing_address = $order -> get_formatted_billing_address ();
$shipping_address = $order -> get_formatted_shipping_address ();
2017-12-11 12:41:29 +00:00
return apply_filters (
2018-11-29 20:16:51 +00:00
'woocommerce_admin_order_preview_get_order_details' ,
array (
2017-12-11 12:41:29 +00:00
'data' => $order -> get_data (),
'order_number' => $order -> get_order_number (),
2018-11-29 20:16:51 +00:00
'item_html' => self :: get_order_preview_item_html ( $order ),
'actions_html' => self :: get_order_preview_actions_html ( $order ),
2017-12-11 12:41:29 +00:00
'ship_to_billing' => wc_ship_to_billing_address_only (),
'needs_shipping' => $order -> needs_shipping_address (),
2017-12-11 16:41:23 +00:00
'formatted_billing_address' => $billing_address ? $billing_address : __ ( 'N/A' , 'woocommerce' ),
'formatted_shipping_address' => $shipping_address ? $shipping_address : __ ( 'N/A' , 'woocommerce' ),
2017-12-11 12:41:29 +00:00
'shipping_address_map_url' => $order -> get_shipping_address_map_url (),
'payment_via' => $payment_via ,
'shipping_via' => $order -> get_shipping_method (),
'status' => $order -> get_status (),
'status_name' => wc_get_order_status_name ( $order -> get_status () ),
2018-11-29 20:16:51 +00:00
),
$order
2017-12-11 12:41:29 +00:00
);
2017-11-21 16:22:43 +00:00
}
2017-11-03 16:10:32 +00:00
/**
* Handle bulk actions .
*
* @ param string $redirect_to URL to redirect to .
* @ param string $action Action name .
* @ param array $ids List of ids .
* @ return string
*/
public function handle_bulk_actions ( $redirect_to , $action , $ids ) {
2018-06-05 10:07:35 +00:00
$ids = apply_filters ( 'woocommerce_bulk_action_ids' , array_reverse ( array_map ( 'absint' , $ids ) ), $action , 'order' );
2018-03-16 13:53:18 +00:00
$changed = 0 ;
2017-11-03 16:10:32 +00:00
2018-03-16 13:53:18 +00:00
if ( 'remove_personal_data' === $action ) {
$report_action = 'removed_personal_data' ;
2017-11-03 16:10:32 +00:00
2018-03-16 13:53:18 +00:00
foreach ( $ids as $id ) {
$order = wc_get_order ( $id );
2017-11-03 16:10:32 +00:00
2018-03-16 13:53:18 +00:00
if ( $order ) {
do_action ( 'woocommerce_remove_order_personal_data' , $order );
$changed ++ ;
}
}
} elseif ( false !== strpos ( $action , 'mark_' ) ) {
$order_statuses = wc_get_order_statuses ();
$new_status = substr ( $action , 5 ); // Get the status name from action.
$report_action = 'marked_' . $new_status ;
// Sanity check: bail out if this is actually not a status, or is not a registered status.
if ( isset ( $order_statuses [ 'wc-' . $new_status ] ) ) {
2018-06-12 12:14:09 +00:00
// Initialize payment gateways in case order has hooked status transition actions.
2018-11-08 10:59:07 +00:00
WC () -> payment_gateways ();
2018-06-12 12:14:09 +00:00
2018-03-16 13:53:18 +00:00
foreach ( $ids as $id ) {
$order = wc_get_order ( $id );
$order -> update_status ( $new_status , __ ( 'Order status changed by bulk edit:' , 'woocommerce' ), true );
do_action ( 'woocommerce_order_edit_status' , $id , $new_status );
$changed ++ ;
}
}
2017-11-03 16:10:32 +00:00
}
2018-03-16 13:53:18 +00:00
if ( $changed ) {
$redirect_to = add_query_arg (
array (
'post_type' => $this -> list_table_type ,
'bulk_action' => $report_action ,
'changed' => $changed ,
'ids' => join ( ',' , $ids ),
2018-11-29 20:16:51 +00:00
),
$redirect_to
2018-03-16 13:53:18 +00:00
);
}
2017-11-03 16:10:32 +00:00
return esc_url_raw ( $redirect_to );
}
/**
* Show confirmation message that order status changed for number of orders .
*/
public function bulk_admin_notices () {
global $post_type , $pagenow ;
// Bail out if not on shop order list page.
2018-03-16 13:53:18 +00:00
if ( 'edit.php' !== $pagenow || 'shop_order' !== $post_type || ! isset ( $_REQUEST [ 'bulk_action' ] ) ) { // WPCS: input var ok, CSRF ok.
2017-11-03 16:10:32 +00:00
return ;
}
$order_statuses = wc_get_order_statuses ();
2018-03-16 13:53:18 +00:00
$number = isset ( $_REQUEST [ 'changed' ] ) ? absint ( $_REQUEST [ 'changed' ] ) : 0 ; // WPCS: input var ok, CSRF ok.
$bulk_action = wc_clean ( wp_unslash ( $_REQUEST [ 'bulk_action' ] ) ); // WPCS: input var ok, CSRF ok.
2017-11-03 16:10:32 +00:00
// Check if any status changes happened.
foreach ( $order_statuses as $slug => $name ) {
2018-03-16 13:53:18 +00:00
if ( 'marked_' . str_replace ( 'wc-' , '' , $slug ) === $bulk_action ) { // WPCS: input var ok, CSRF ok.
/* translators: %d: orders count */
2017-11-03 16:10:32 +00:00
$message = sprintf ( _n ( '%d order status changed.' , '%d order statuses changed.' , $number , 'woocommerce' ), number_format_i18n ( $number ) );
echo '<div class="updated"><p>' . esc_html ( $message ) . '</p></div>' ;
break ;
}
}
2018-03-16 13:53:18 +00:00
if ( 'removed_personal_data' === $bulk_action ) { // WPCS: input var ok, CSRF ok.
/* translators: %d: orders count */
$message = sprintf ( _n ( 'Removed personal data from %d order.' , 'Removed personal data from %d orders.' , $number , 'woocommerce' ), number_format_i18n ( $number ) );
echo '<div class="updated"><p>' . esc_html ( $message ) . '</p></div>' ;
}
2017-11-03 16:10:32 +00:00
}
/**
* See if we should render search filters or not .
*/
public function restrict_manage_posts () {
global $typenow ;
if ( in_array ( $typenow , wc_get_order_types ( 'order-meta-boxes' ), true ) ) {
$this -> render_filters ();
}
}
/**
* Render any custom filters and search inputs for the list table .
*/
protected function render_filters () {
$user_string = '' ;
$user_id = '' ;
2019-12-13 19:58:14 +00:00
if ( ! empty ( $_GET [ '_customer_user' ] ) ) { // phpcs:disable WordPress.Security.NonceVerification.Recommended
2017-12-11 12:41:29 +00:00
$user_id = absint ( $_GET [ '_customer_user' ] ); // WPCS: input var ok, sanitization ok.
$user = get_user_by ( 'id' , $user_id );
2017-12-11 16:41:23 +00:00
2017-11-03 16:10:32 +00:00
$user_string = sprintf (
2017-12-11 16:41:23 +00:00
/* translators: 1: user display name 2: user ID 3: user email */
2017-11-03 16:10:32 +00:00
esc_html__ ( '%1$s (#%2$s – %3$s)' , 'woocommerce' ),
$user -> display_name ,
absint ( $user -> ID ),
$user -> user_email
);
}
?>
2018-02-05 14:47:12 +00:00
< select class = " wc-customer-search " name = " _customer_user " data - placeholder = " <?php esc_attr_e( 'Filter by registered customer', 'woocommerce' ); ?> " data - allow_clear = " true " >
2019-04-17 11:02:20 +00:00
< option value = " <?php echo esc_attr( $user_id ); ?> " selected = " selected " >< ? php echo htmlspecialchars ( wp_kses_post ( $user_string ) ); // htmlspecialchars to prevent XSS when rendered by selectWoo. ?><option>
2017-11-03 16:10:32 +00:00
</ select >
< ? php
}
/**
* Handle any filters .
*
* @ param array $query_vars Query vars .
* @ return array
*/
public function request_query ( $query_vars ) {
global $typenow ;
if ( in_array ( $typenow , wc_get_order_types ( 'order-meta-boxes' ), true ) ) {
return $this -> query_filters ( $query_vars );
}
return $query_vars ;
}
/**
* Handle any custom filters .
*
* @ param array $query_vars Query vars .
* @ return array
*/
protected function query_filters ( $query_vars ) {
global $wp_post_statuses ;
// Filter the orders by the posted customer.
if ( ! empty ( $_GET [ '_customer_user' ] ) ) { // WPCS: input var ok.
2018-11-29 20:16:51 +00:00
// @codingStandardsIgnoreStart.
2018-10-29 14:46:02 +00:00
$query_vars [ 'meta_query' ] = array (
array (
2018-11-29 20:16:51 +00:00
'key' => '_customer_user' ,
'value' => ( int ) $_GET [ '_customer_user' ], // WPCS: input var ok, sanitization ok.
2018-10-29 14:46:02 +00:00
'compare' => '=' ,
),
);
// @codingStandardsIgnoreEnd
2017-11-03 16:10:32 +00:00
}
// Sorting.
if ( isset ( $query_vars [ 'orderby' ] ) ) {
if ( 'order_total' === $query_vars [ 'orderby' ] ) {
// @codingStandardsIgnoreStart
$query_vars = array_merge ( $query_vars , array (
'meta_key' => '_order_total' ,
'orderby' => 'meta_value_num' ,
) );
// @codingStandardsIgnoreEnd
}
}
// Status.
2018-12-20 11:48:42 +00:00
if ( empty ( $query_vars [ 'post_status' ] ) ) {
2017-11-03 16:10:32 +00:00
$post_statuses = wc_get_order_statuses ();
foreach ( $post_statuses as $status => $value ) {
if ( isset ( $wp_post_statuses [ $status ] ) && false === $wp_post_statuses [ $status ] -> show_in_admin_all_list ) {
unset ( $post_statuses [ $status ] );
}
}
$query_vars [ 'post_status' ] = array_keys ( $post_statuses );
}
return $query_vars ;
}
/**
* Change the label when searching orders .
*
* @ param mixed $query Current search query .
* @ return string
*/
public function search_label ( $query ) {
global $pagenow , $typenow ;
2019-12-13 19:58:14 +00:00
if ( 'edit.php' !== $pagenow || 'shop_order' !== $typenow || ! get_query_var ( 'shop_order_search' ) || ! isset ( $_GET [ 's' ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
2017-11-03 16:10:32 +00:00
return $query ;
}
return wc_clean ( wp_unslash ( $_GET [ 's' ] ) ); // WPCS: input var ok, sanitization ok.
}
/**
* Query vars for custom searches .
*
* @ param mixed $public_query_vars Array of query vars .
* @ return array
*/
public function add_custom_query_var ( $public_query_vars ) {
$public_query_vars [] = 'shop_order_search' ;
return $public_query_vars ;
}
/**
* Search custom fields as well as content .
*
* @ param WP_Query $wp Query object .
*/
public function search_custom_fields ( $wp ) {
global $pagenow ;
2019-12-13 19:58:14 +00:00
if ( 'edit.php' !== $pagenow || empty ( $wp -> query_vars [ 's' ] ) || 'shop_order' !== $wp -> query_vars [ 'post_type' ] || ! isset ( $_GET [ 's' ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
2017-11-03 16:10:32 +00:00
return ;
}
$post_ids = wc_order_search ( wc_clean ( wp_unslash ( $_GET [ 's' ] ) ) ); // WPCS: input var ok, sanitization ok.
if ( ! empty ( $post_ids ) ) {
// Remove "s" - we don't want to search order name.
unset ( $wp -> query_vars [ 's' ] );
// so we know we're doing this.
$wp -> query_vars [ 'shop_order_search' ] = true ;
// Search by found posts.
$wp -> query_vars [ 'post__in' ] = array_merge ( $post_ids , array ( 0 ) );
}
}
}