'price',
'featured' => array( 'featured', 1 ),
'sku' => 'sku',
'name' => 'title',
);
return wp_parse_args( $custom, $columns );
}
/**
* Make columns sortable - https://gist.github.com/906872.
*
* @param array $columns
* @return array
*/
public function shop_coupon_sortable_columns( $columns ) {
return $columns;
}
/**
* Make columns sortable - https://gist.github.com/906872.
*
* @param array $columns
* @return array
*/
public function shop_order_sortable_columns( $columns ) {
$custom = array(
'order_title' => 'ID',
'order_total' => 'order_total',
'order_date' => 'date',
);
unset( $columns['comments'] );
return wp_parse_args( $custom, $columns );
}
/**
* Remove edit from the bulk actions.
*
* @param array $actions
* @return array
*/
public function shop_order_bulk_actions( $actions ) {
if ( isset( $actions['edit'] ) ) {
unset( $actions['edit'] );
}
return $actions;
}
/**
* Set list table primary column for products and orders.
* Support for WordPress 4.3.
*
* @param string $default
* @param string $screen_id
*
* @return string
*/
public function list_table_primary_column( $default, $screen_id ) {
if ( 'edit-product' === $screen_id ) {
return 'name';
}
if ( 'edit-shop_order' === $screen_id ) {
return 'order_title';
}
if ( 'edit-shop_coupon' === $screen_id ) {
return 'coupon_code';
}
return $default;
}
/**
* Set row actions for products and orders.
*
* @param array $actions
* @param WP_Post $post
*
* @return array
*/
public function row_actions( $actions, $post ) {
if ( 'product' === $post->post_type ) {
return array_merge( array( 'id' => 'ID: ' . $post->ID ), $actions );
}
if ( in_array( $post->post_type, array( 'shop_order', 'shop_coupon' ) ) ) {
if ( isset( $actions['inline hide-if-no-js'] ) ) {
unset( $actions['inline hide-if-no-js'] );
}
}
return $actions;
}
/**
* Product sorting link.
*
* Based on Simple Page Ordering by 10up (https://wordpress.org/plugins/simple-page-ordering/).
*
* @param array $views
* @return array
*/
public function product_sorting_link( $views ) {
global $post_type, $wp_query;
if ( ! current_user_can( 'edit_others_pages' ) ) {
return $views;
}
$class = ( isset( $wp_query->query['orderby'] ) && 'menu_order title' === $wp_query->query['orderby'] ) ? 'current' : '';
$query_string = remove_query_arg( array( 'orderby', 'order' ) );
$query_string = add_query_arg( 'orderby', urlencode( 'menu_order title' ), $query_string );
$query_string = add_query_arg( 'order', urlencode( 'ASC' ), $query_string );
$views['byorder'] = '' . __( 'Sort products', 'woocommerce' ) . '';
return $views;
}
/**
* Custom bulk edit - form.
*
* @param mixed $column_name
* @param mixed $post_type
*/
public function bulk_edit( $column_name, $post_type ) {
if ( 'price' != $column_name || 'product' != $post_type ) {
return;
}
$shipping_class = get_terms( 'product_shipping_class', array(
'hide_empty' => false,
) );
include( WC()->plugin_path() . '/includes/admin/views/html-bulk-edit-product.php' );
}
/**
* Custom quick edit - form.
*
* @param mixed $column_name
* @param mixed $post_type
*/
public function quick_edit( $column_name, $post_type ) {
if ( 'price' != $column_name || 'product' != $post_type ) {
return;
}
$shipping_class = get_terms( 'product_shipping_class', array(
'hide_empty' => false,
) );
include( WC()->plugin_path() . '/includes/admin/views/html-quick-edit-product.php' );
}
/**
* Offers a way to hook into save post without causing an infinite loop
* when quick/bulk saving product info.
*
* @since 2.7.0
* @param int $post_id
* @param object $post
*/
public function bulk_and_quick_edit_hook( $post_id, $post ) {
remove_action( 'save_post', array( $this, 'bulk_and_quick_edit_hook' ) );
do_action( 'woocommerce_product_bulk_and_quick_edit', $post_id, $post );
add_action( 'save_post', array( $this, 'bulk_and_quick_edit_hook' ), 10, 2 );
}
/**
* Quick and bulk edit saving.
*
* @param int $post_id
* @param WP_Post $post
* @return int
*/
public function bulk_and_quick_edit_save_post( $post_id, $post ) {
// If this is an autosave, our form has not been submitted, so we don't want to do anything.
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return $post_id;
}
// Don't save revisions and autosaves
if ( wp_is_post_revision( $post_id ) || wp_is_post_autosave( $post_id ) ) {
return $post_id;
}
// Check post type is product
if ( 'product' != $post->post_type ) {
return $post_id;
}
// Check user permission
if ( ! current_user_can( 'edit_post', $post_id ) ) {
return $post_id;
}
// Check nonces
if ( ! isset( $_REQUEST['woocommerce_quick_edit_nonce'] ) && ! isset( $_REQUEST['woocommerce_bulk_edit_nonce'] ) ) {
return $post_id;
}
if ( isset( $_REQUEST['woocommerce_quick_edit_nonce'] ) && ! wp_verify_nonce( $_REQUEST['woocommerce_quick_edit_nonce'], 'woocommerce_quick_edit_nonce' ) ) {
return $post_id;
}
if ( isset( $_REQUEST['woocommerce_bulk_edit_nonce'] ) && ! wp_verify_nonce( $_REQUEST['woocommerce_bulk_edit_nonce'], 'woocommerce_bulk_edit_nonce' ) ) {
return $post_id;
}
// Get the product and save
$product = wc_get_product( $post );
if ( ! empty( $_REQUEST['woocommerce_quick_edit'] ) ) {
$this->quick_edit_save( $post_id, $product );
} else {
$this->bulk_edit_save( $post_id, $product );
}
return $post_id;
}
/**
* Quick edit.
*
* @param integer $post_id
* @param WC_Product $product
*/
private function quick_edit_save( $post_id, $product ) {
$data_store = $product->get_data_store();
$old_regular_price = $product->get_regular_price();
$old_sale_price = $product->get_sale_price();
// Save fields
if ( isset( $_REQUEST['_sku'] ) ) {
$sku = $product->get_sku();
$new_sku = (string) wc_clean( $_REQUEST['_sku'] );
if ( $new_sku !== $sku ) {
if ( ! empty( $new_sku ) ) {
$unique_sku = wc_product_has_unique_sku( $post_id, $new_sku );
if ( $unique_sku ) {
$product->set_sku( $new_sku );
}
} else {
$product->set_sku( '' );
}
}
}
if ( isset( $_REQUEST['_weight'] ) ) {
$product->set_weight( wc_clean( $_REQUEST['_weight'] ) );
}
if ( isset( $_REQUEST['_length'] ) ) {
$product->set_length( wc_clean( $_REQUEST['_length'] ) );
}
if ( isset( $_REQUEST['_width'] ) ) {
$product->set_width( wc_clean( $_REQUEST['_width'] ) );
}
if ( isset( $_REQUEST['_height'] ) ) {
$product->set_height( wc_clean( $_REQUEST['_height'] ) );
}
if ( ! empty( $_REQUEST['_shipping_class'] ) ) {
$shipping_class = '_no_shipping_class' == $_REQUEST['_shipping_class'] ? '' : wc_clean( $_REQUEST['_shipping_class'] );
$shipping_class_id = $data_store->get_shipping_class_id_by_slug( $shipping_class );
if ( $shipping_class_id ) {
$product->set_shipping_class_id( $shipping_class_id );
}
}
if ( isset( $_REQUEST['_visibility'] ) ) {
$product->set_catalog_visibility( wc_clean( $_REQUEST['_visibility'] ) );
}
if ( isset( $_REQUEST['_featured'] ) ) {
$product->set_featured( true );
} else {
$product->set_featured( false );
}
if ( isset( $_REQUEST['_tax_status'] ) ) {
$product->set_tax_status( wc_clean( $_REQUEST['_tax_status'] ) );
}
if ( isset( $_REQUEST['_tax_class'] ) ) {
$product->set_tax_class( wc_clean( $_REQUEST['_tax_class'] ) );
}
if ( $product->is_type( 'simple' ) || $product->is_type( 'external' ) ) {
if ( isset( $_REQUEST['_regular_price'] ) ) {
$new_regular_price = ( '' === $_REQUEST['_regular_price'] ) ? '' : wc_format_decimal( $_REQUEST['_regular_price'] );
$product->set_regular_price( $new_regular_price );
} else {
$new_regular_price = null;
}
if ( isset( $_REQUEST['_sale_price'] ) ) {
$new_sale_price = ( '' === $_REQUEST['_sale_price'] ) ? '' : wc_format_decimal( $_REQUEST['_sale_price'] );
$product->set_sale_price( $new_sale_price );
} else {
$new_sale_price = null;
}
// Handle price - remove dates and set to lowest
$price_changed = false;
if ( ! is_null( $new_regular_price ) && $new_regular_price != $old_regular_price ) {
$price_changed = true;
} elseif ( ! is_null( $new_sale_price ) && $new_sale_price != $old_sale_price ) {
$price_changed = true;
}
if ( $price_changed ) {
$product->set_date_on_sale_to( '' );
$product->set_date_on_sale_from( '' );
}
}
// Handle Stock Data
$manage_stock = ! empty( $_REQUEST['_manage_stock'] ) && 'grouped' !== $product->get_type() ? 'yes' : 'no';
$backorders = ! empty( $_REQUEST['_backorders'] ) ? wc_clean( $_REQUEST['_backorders'] ) : 'no';
$stock_status = ! empty( $_REQUEST['_stock_status'] ) ? wc_clean( $_REQUEST['_stock_status'] ) : 'instock';
$stock_amount = 'yes' === $manage_stock ? wc_stock_amount( $_REQUEST['_stock'] ) : '';
if ( 'yes' === get_option( 'woocommerce_manage_stock' ) ) {
// Apply product type constraints to stock status
if ( $product->is_type( 'external' ) ) {
// External always in stock
$stock_status = 'instock';
} elseif ( $product->is_type( 'variable' ) ) {
// Stock status is always determined by children
foreach ( $product->get_children() as $child_id ) {
$child = wc_get_product( $child_id );
if ( ! $product->get_manage_stock() ) {
$child->set_stock_status( $stock_status );
$child->save();
}
}
$product = WC_Product_Variable::sync( $product, false );
}
$product->set_manage_stock( $manage_stock );
$product->set_backorders( $backorders );
$product->save();
if ( ! $product->is_type( 'variable') ) {
wc_update_product_stock_status( $post_id, $stock_status );
}
wc_update_product_stock( $post_id, $stock_amount );
} else {
$product->save();
wc_update_product_stock_status( $post_id, $stock_status );
}
do_action( 'woocommerce_product_quick_edit_save', $product );
}
/**
* Bulk edit.
*
* @param integer $post_id
* @param WC_Product $product
*/
public function bulk_edit_save( $post_id, $product ) {
$old_regular_price = $product->get_regular_price();
$old_sale_price = $product->get_sale_price();
// Save fields
if ( ! empty( $_REQUEST['change_weight'] ) && isset( $_REQUEST['_weight'] ) ) {
$product->set_weight( wc_clean( stripslashes( $_REQUEST['_weight'] ) ) );
}
if ( ! empty( $_REQUEST['change_dimensions'] ) ) {
if ( isset( $_REQUEST['_length'] ) ) {
$product->set_length( wc_clean( stripslashes( $_REQUEST['_length'] ) ) );
}
if ( isset( $_REQUEST['_width'] ) ) {
$product->set_width( wc_clean( stripslashes( $_REQUEST['_width'] ) ) );
}
if ( isset( $_REQUEST['_height'] ) ) {
$product->set_height( wc_clean( stripslashes( $_REQUEST['_height'] ) ) );
}
}
if ( ! empty( $_REQUEST['_tax_status'] ) ) {
$product->set_tax_status( wc_clean( $_REQUEST['_tax_status'] ) );
}
if ( ! empty( $_REQUEST['_tax_class'] ) ) {
$tax_class = wc_clean( $_REQUEST['_tax_class'] );
if ( 'standard' == $tax_class ) {
$tax_class = '';
}
$product->set_tax_class( $tax_class );
}
if ( ! empty( $_REQUEST['_shipping_class'] ) ) {
$shipping_class = '_no_shipping_class' == $_REQUEST['_shipping_class'] ? '' : wc_clean( $_REQUEST['_shipping_class'] );
$shipping_class_id = $data_store->get_shipping_class_id_by_slug( $shipping_class );
if ( $shipping_class_id ) {
$product->set_shipping_class_id( $shipping_class_id );
}
}
if ( ! empty( $_REQUEST['_visibility'] ) ) {
$product->set_catalog_visibility( wc_clean( $_REQUEST['_visibility'] ) );
}
if ( ! empty( $_REQUEST['_featured'] ) ) {
$product->set_featured( stripslashes( $_REQUEST['_featured'] ) );
}
// Sold Individually
if ( ! empty( $_REQUEST['_sold_individually'] ) ) {
if ( 'yes' === $_REQUEST['_sold_individually'] ) {
$product->set_sold_individually( 'yes' );
} else {
$product->set_sold_individually( '' );
}
}
// Handle price - remove dates and set to lowest
$change_price_product_types = apply_filters( 'woocommerce_bulk_edit_save_price_product_types', array( 'simple', 'external' ) );
$can_product_type_change_price = false;
foreach ( $change_price_product_types as $product_type ) {
if ( $product->is_type( $product_type ) ) {
$can_product_type_change_price = true;
break;
}
}
if ( $can_product_type_change_price ) {
$price_changed = false;
if ( ! empty( $_REQUEST['change_regular_price'] ) ) {
$change_regular_price = absint( $_REQUEST['change_regular_price'] );
$regular_price = esc_attr( stripslashes( $_REQUEST['_regular_price'] ) );
switch ( $change_regular_price ) {
case 1 :
$new_price = $regular_price;
break;
case 2 :
if ( strstr( $regular_price, '%' ) ) {
$percent = str_replace( '%', '', $regular_price ) / 100;
$new_price = $old_regular_price + ( round( $old_regular_price * $percent, wc_get_price_decimals() ) );
} else {
$new_price = $old_regular_price + $regular_price;
}
break;
case 3 :
if ( strstr( $regular_price, '%' ) ) {
$percent = str_replace( '%', '', $regular_price ) / 100;
$new_price = max( 0, $old_regular_price - ( round( $old_regular_price * $percent, wc_get_price_decimals() ) ) );
} else {
$new_price = max( 0, $old_regular_price - $regular_price );
}
break;
default :
break;
}
if ( isset( $new_price ) && $new_price != $old_regular_price ) {
$price_changed = true;
$new_price = round( $new_price, wc_get_price_decimals() );
$product->set_regular_price( $new_price );
}
}
if ( ! empty( $_REQUEST['change_sale_price'] ) ) {
$change_sale_price = absint( $_REQUEST['change_sale_price'] );
$sale_price = esc_attr( stripslashes( $_REQUEST['_sale_price'] ) );
switch ( $change_sale_price ) {
case 1 :
$new_price = $sale_price;
break;
case 2 :
if ( strstr( $sale_price, '%' ) ) {
$percent = str_replace( '%', '', $sale_price ) / 100;
$new_price = $old_sale_price + ( $old_sale_price * $percent );
} else {
$new_price = $old_sale_price + $sale_price;
}
break;
case 3 :
if ( strstr( $sale_price, '%' ) ) {
$percent = str_replace( '%', '', $sale_price ) / 100;
$new_price = max( 0, $old_sale_price - ( $old_sale_price * $percent ) );
} else {
$new_price = max( 0, $old_sale_price - $sale_price );
}
break;
case 4 :
if ( strstr( $sale_price, '%' ) ) {
$percent = str_replace( '%', '', $sale_price ) / 100;
$new_price = max( 0, $product->regular_price - ( $product->regular_price * $percent ) );
} else {
$new_price = max( 0, $product->regular_price - $sale_price );
}
break;
default :
break;
}
if ( isset( $new_price ) && $new_price != $old_sale_price ) {
$price_changed = true;
$new_price = ! empty( $new_price ) || '0' === $new_price ? round( $new_price, wc_get_price_decimals() ) : '';
$product->set_sale_price( $new_price );
}
}
if ( $price_changed ) {
$product->set_date_on_sale_to( '' );
$product->set_date_on_sale_from( '' );
if ( $product->get_regular_price() < $product->get_sale_price() ) {
$product->set_sale_price( '' );
}
}
}
// Handle Stock Data
$was_managing_stock = $product->get_manage_stock() ? 'yes' : 'no';
$stock_status = $product->get_stock_status();
$backorders = $product->get_backorders();
$backorders = ! empty( $_REQUEST['_backorders'] ) ? wc_clean( $_REQUEST['_backorders'] ) : $backorders;
$stock_status = ! empty( $_REQUEST['_stock_status'] ) ? wc_clean( $_REQUEST['_stock_status'] ) : $stock_status;
if ( ! empty( $_REQUEST['_manage_stock'] ) ) {
$manage_stock = 'yes' === wc_clean( $_REQUEST['_manage_stock'] ) && 'grouped' !== $product->product_type ? 'yes' : 'no';
} else {
$manage_stock = $was_managing_stock;
}
$stock_amount = 'yes' === $manage_stock && isset( $_REQUEST['_change_stock'] ) ? wc_stock_amount( $_REQUEST['_change_stock'] ) : '';
if ( 'yes' === get_option( 'woocommerce_manage_stock' ) ) {
// Apply product type constraints to stock status
if ( $product->is_type( 'external' ) ) {
// External always in stock
$stock_status = 'instock';
} elseif ( $product->is_type( 'variable' ) ) {
// Stock status is always determined by children
foreach ( $product->get_children() as $child_id ) {
$child = wc_get_product( $child_id );
if ( ! $product->get_manage_stock() ) {
$child->set_stock_status( $stock_status );
$child->save();
}
}
$product = WC_Product_Variable::sync( $product, false );
}
$product->set_manage_stock( $manage_stock );
$product->set_backorders( $backorders );
$product->save();
if ( ! $product->is_type( 'variable') ) {
wc_update_product_stock_status( $post_id, $stock_status );
}
wc_update_product_stock( $post_id, $stock_amount );
} else {
$product->save();
wc_update_product_stock_status( $post_id, $stock_status );
}
do_action( 'woocommerce_product_bulk_edit_save', $product );
}
/**
* Add extra bulk action options to mark orders as complete or processing.
*
* Using Javascript until WordPress core fixes: https://core.trac.wordpress.org/ticket/16031.
*/
public function bulk_admin_footer() {
global $post_type;
if ( 'shop_order' == $post_type ) {
?>
current_action();
// Bail out if this is not a status-changing action
if ( strpos( $action, 'mark_' ) === false ) {
return;
}
$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 ] ) ) {
return;
}
$changed = 0;
$post_ids = array_map( 'absint', (array) $_REQUEST['post'] );
foreach ( $post_ids as $post_id ) {
$order = wc_get_order( $post_id );
$order->update_status( $new_status, __( 'Order status changed by bulk edit:', 'woocommerce' ), true );
do_action( 'woocommerce_order_edit_status', $post_id, $new_status );
$changed++;
}
$sendback = add_query_arg( array( 'post_type' => 'shop_order', $report_action => true, 'changed' => $changed, 'ids' => join( ',', $post_ids ) ), '' );
if ( isset( $_GET['post_status'] ) ) {
$sendback = add_query_arg( 'post_status', sanitize_text_field( $_GET['post_status'] ), $sendback );
}
wp_redirect( esc_url_raw( $sendback ) );
exit();
}
/**
* 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
if ( 'edit.php' !== $pagenow || 'shop_order' !== $post_type ) {
return;
}
$order_statuses = wc_get_order_statuses();
// Check if any status changes happened
foreach ( $order_statuses as $slug => $name ) {
if ( isset( $_REQUEST[ 'marked_' . str_replace( 'wc-', '', $slug ) ] ) ) {
$number = isset( $_REQUEST['changed'] ) ? absint( $_REQUEST['changed'] ) : 0;
/* translators: %s: orders count */
$message = sprintf( _n( 'Order status changed.', '%s order statuses changed.', $number, 'woocommerce' ), number_format_i18n( $number ) );
echo '
' . $message . '
';
break;
}
}
}
/**
* Search custom fields as well as content.
* @param WP_Query $wp
*/
public function shop_order_search_custom_fields( $wp ) {
global $pagenow;
if ( 'edit.php' != $pagenow || empty( $wp->query_vars['s'] ) || 'shop_order' !== $wp->query_vars['post_type'] ) {
return;
}
$post_ids = wc_order_search( $_GET['s'] );
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 ) );
}
}
/**
* Change the label when searching orders.
*
* @param mixed $query
* @return string
*/
public function shop_order_search_label( $query ) {
global $pagenow, $typenow;
if ( 'edit.php' != $pagenow ) {
return $query;
}
if ( 'shop_order' !== $typenow ) {
return $query;
}
if ( ! get_query_var( 'shop_order_search' ) ) {
return $query;
}
return wp_unslash( $_GET['s'] );
}
/**
* Query vars for custom searches.
*
* @param mixed $public_query_vars
* @return array
*/
public function add_custom_query_var( $public_query_vars ) {
$public_query_vars[] = 'sku';
$public_query_vars[] = 'shop_order_search';
return $public_query_vars;
}
/**
* Filters for post types.
*/
public function restrict_manage_posts() {
global $typenow;
if ( in_array( $typenow, wc_get_order_types( 'order-meta-boxes' ) ) ) {
$this->shop_order_filters();
} elseif ( 'product' == $typenow ) {
$this->product_filters();
} elseif ( 'shop_coupon' == $typenow ) {
$this->shop_coupon_filters();
}
}
/**
* Show a category filter box.
*/
public function product_filters() {
global $wp_query;
// Category Filtering
wc_product_dropdown_categories();
// Type filtering
$terms = get_terms( 'product_type' );
$output = '';
echo apply_filters( 'woocommerce_product_filters', $output );
}
/**
* Show custom filters to filter coupons by type.
*/
public function shop_coupon_filters() {
?>
display_name,
absint( $user->ID ),
$user->user_email
);
}
?>
'_price',
'orderby' => 'meta_value_num',
) );
}
if ( 'featured' == $vars['orderby'] ) {
$vars = array_merge( $vars, array(
'meta_key' => '_featured',
'orderby' => 'meta_value',
) );
}
if ( 'sku' == $vars['orderby'] ) {
$vars = array_merge( $vars, array(
'meta_key' => '_sku',
'orderby' => 'meta_value',
) );
}
}
} elseif ( 'shop_coupon' === $typenow ) {
if ( ! empty( $_GET['coupon_type'] ) ) {
$vars['meta_key'] = 'discount_type';
$vars['meta_value'] = wc_clean( $_GET['coupon_type'] );
}
} elseif ( in_array( $typenow, wc_get_order_types( 'order-meta-boxes' ) ) ) {
// Filter the orders by the posted customer.
if ( isset( $_GET['_customer_user'] ) && $_GET['_customer_user'] > 0 ) {
$vars['meta_query'] = array(
array(
'key' => '_customer_user',
'value' => (int) $_GET['_customer_user'],
'compare' => '=',
),
);
}
// Sorting
if ( isset( $vars['orderby'] ) ) {
if ( 'order_total' == $vars['orderby'] ) {
$vars = array_merge( $vars, array(
'meta_key' => '_order_total',
'orderby' => 'meta_value_num',
) );
}
}
// Status
if ( ! isset( $vars['post_status'] ) ) {
$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 ] );
}
}
$vars['post_status'] = array_keys( $post_statuses );
}
}
return $vars;
}
/**
* Filter the products in admin based on options.
*
* @param mixed $query
*/
public function product_filters_query( $query ) {
global $typenow, $wp_query;
if ( 'product' == $typenow ) {
if ( isset( $query->query_vars['product_type'] ) ) {
// Subtypes
if ( 'downloadable' == $query->query_vars['product_type'] ) {
$query->query_vars['product_type'] = '';
$query->is_tax = false;
$query->query_vars['meta_value'] = 'yes';
$query->query_vars['meta_key'] = '_downloadable';
} elseif ( 'virtual' == $query->query_vars['product_type'] ) {
$query->query_vars['product_type'] = '';
$query->is_tax = false;
$query->query_vars['meta_value'] = 'yes';
$query->query_vars['meta_key'] = '_virtual';
}
}
// Categories
if ( isset( $_GET['product_cat'] ) && '0' === $_GET['product_cat'] ) {
$query->query_vars['tax_query'][] = array(
'taxonomy' => 'product_cat',
'field' => 'id',
'terms' => get_terms( 'product_cat', array( 'fields' => 'ids' ) ),
'operator' => 'NOT IN',
);
}
// Shipping classes
if ( isset( $_GET['product_shipping_class'] ) && '0' === $_GET['product_shipping_class'] ) {
$query->query_vars['tax_query'][] = array(
'taxonomy' => 'product_shipping_class',
'field' => 'id',
'terms' => get_terms( 'product_shipping_class', array( 'fields' => 'ids' ) ),
'operator' => 'NOT IN',
);
}
}
}
/**
* Search by SKU or ID for products.
*
* @param string $where
* @return string
*/
public function product_search( $where ) {
global $pagenow, $wpdb, $wp;
if ( 'edit.php' != $pagenow || ! is_search() || ! isset( $wp->query_vars['s'] ) || 'product' != $wp->query_vars['post_type'] ) {
return $where;
}
$search_ids = array();
$terms = explode( ',', $wp->query_vars['s'] );
foreach ( $terms as $term ) {
if ( is_numeric( $term ) ) {
$search_ids[] = $term;
}
// Attempt to get a SKU
$sku_to_id = $wpdb->get_results( $wpdb->prepare( "SELECT ID, post_parent FROM {$wpdb->posts} LEFT JOIN {$wpdb->postmeta} ON {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id WHERE meta_key='_sku' AND meta_value LIKE %s;", '%' . $wpdb->esc_like( wc_clean( $term ) ) . '%' ) );
$sku_to_id = array_merge( wp_list_pluck( $sku_to_id, 'ID' ), wp_list_pluck( $sku_to_id, 'post_parent' ) );
if ( sizeof( $sku_to_id ) > 0 ) {
$search_ids = array_merge( $search_ids, $sku_to_id );
}
}
$search_ids = array_filter( array_unique( array_map( 'absint', $search_ids ) ) );
if ( sizeof( $search_ids ) > 0 ) {
$where = str_replace( 'AND (((', "AND ( ({$wpdb->posts}.ID IN (" . implode( ',', $search_ids ) . ")) OR ((", $where );
}
return $where;
}
/**
* Disable the auto-save functionality for Orders.
*/
public function disable_autosave() {
global $post;
if ( $post && in_array( get_post_type( $post->ID ), wc_get_order_types( 'order-meta-boxes' ) ) ) {
wp_dequeue_script( 'autosave' );
}
}
/**
* Change title boxes in admin.
* @param string $text
* @param object $post
* @return string
*/
public function enter_title_here( $text, $post ) {
switch ( $post->post_type ) {
case 'product' :
$text = __( 'Product name', 'woocommerce' );
break;
case 'shop_coupon' :
$text = __( 'Coupon code', 'woocommerce' );
break;
}
return $text;
}
/**
* Print coupon description textarea field.
* @param WP_Post $post
*/
public function edit_form_after_title( $post ) {
if ( 'shop_coupon' === $post->post_type ) {
?>
post_type && 'post' === $screen->base ) {
$hidden = array_merge( $hidden, array( 'postcustom' ) );
}
return $hidden;
}
/**
* Output product visibility options.
*/
public function product_data_visibility() {
global $post;
if ( 'product' != $post->post_type ) {
return;
}
$current_visibility = ( $current_visibility = get_post_meta( $post->ID, '_visibility', true ) ) ? $current_visibility : apply_filters( 'woocommerce_product_visibility_default' , 'visible' );
$current_featured = ( $current_featured = get_post_meta( $post->ID, '_featured', true ) ) ? $current_featured : 'no';
$visibility_options = apply_filters( 'woocommerce_product_visibility_options', array(
'visible' => __( 'Catalog/search', 'woocommerce' ),
'catalog' => __( 'Catalog', 'woocommerce' ),
'search' => __( 'Search', 'woocommerce' ),
'hidden' => __( 'Hidden', 'woocommerce' ),
) );
?>
' . __( 'Choose where this product should be displayed in your catalog. The product will always be accessible directly.', 'woocommerce' ) . '';
foreach ( $visibility_options as $name => $label ) {
echo ' ';
}
echo '
' . __( 'Enable this option to feature this product.', 'woocommerce' ) . '
';
echo ' ';
?>
get_downloads() );
$updated_download_ids = array_keys( (array) $downloadable_files );
$new_download_ids = array_filter( array_diff( $updated_download_ids, $existing_download_ids ) );
$removed_download_ids = array_filter( array_diff( $existing_download_ids, $updated_download_ids ) );
if ( ! empty( $new_download_ids ) || ! empty( $removed_download_ids ) ) {
// determine whether downloadable file access has been granted via the typical order completion, or via the admin ajax method
$existing_permissions = $wpdb->get_results( $wpdb->prepare( "SELECT * from {$wpdb->prefix}woocommerce_downloadable_product_permissions WHERE product_id = %d GROUP BY order_id", $product_id ) );
foreach ( $existing_permissions as $existing_permission ) {
$order = wc_get_order( $existing_permission->order_id );
if ( $order->get_id() ) {
// Remove permissions
if ( ! empty( $removed_download_ids ) ) {
foreach ( $removed_download_ids as $download_id ) {
if ( apply_filters( 'woocommerce_process_product_file_download_paths_remove_access_to_old_file', true, $download_id, $product_id, $order ) ) {
$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions WHERE order_id = %d AND product_id = %d AND download_id = %s", $order->get_id(), $product_id, $download_id ) );
}
}
}
// Add permissions
if ( ! empty( $new_download_ids ) ) {
foreach ( $new_download_ids as $download_id ) {
if ( apply_filters( 'woocommerce_process_product_file_download_paths_grant_access_to_new_file', true, $download_id, $product_id, $order ) ) {
// grant permission if it doesn't already exist
if ( ! $wpdb->get_var( $wpdb->prepare( "SELECT 1=1 FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions WHERE order_id = %d AND product_id = %d AND download_id = %s", $order->get_id(), $product_id, $download_id ) ) ) {
wc_downloadable_file_permission( $download_id, $product_id, $order );
}
}
}
}
}
}
}
}
/**
* Disable DFW feature pointer.
*/
public function disable_dfw_feature_pointer() {
$screen = get_current_screen();
if ( $screen && 'product' === $screen->id && 'post' === $screen->base ) {
remove_action( 'admin_print_footer_scripts', array( 'WP_Internal_Pointers', 'pointer_wp410_dfw' ) );
}
}
/**
* Removes products, orders, and coupons from the list of post types that support "View Mode" switching.
* View mode is seen on posts where you can switch between list or excerpt. Our post types don't support
* it, so we want to hide the useless UI from the screen options tab.
*
* @since 2.6
* @param array $post_types Array of post types supporting view mode
* @return array Array of post types supporting view mode, without products, orders, and coupons
*/
public function disable_view_mode_options( $post_types ) {
unset( $post_types['product'], $post_types['shop_order'], $post_types['shop_coupon'] );
return $post_types;
}
/**
* Show blank slate.
*/
public function maybe_render_blank_state( $which ) {
global $post_type;
if ( in_array( $post_type, array( 'shop_order', 'product', 'shop_coupon' ) ) && 'bottom' === $which ) {
$counts = (array) wp_count_posts( $post_type );
unset( $counts['auto-draft'] );
$count = array_sum( $counts );
if ( 0 < $count ) {
return;
}
echo '