Validate orders separately since it not always a CPT. (#36832)
This commit is contained in:
commit
9b8a5a7308
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: patch
|
||||||
|
Type: fix
|
||||||
|
|
||||||
|
Add HPOS compat for admin report functions.
|
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: patch
|
||||||
|
Type: fix
|
||||||
|
|
||||||
|
Add support for `after`, `before`, `modified_after` and `modified_before` params in local timezone.
|
|
@ -0,0 +1,5 @@
|
||||||
|
Significance: patch
|
||||||
|
Type: fix
|
||||||
|
Comment: Changes are only in unit tests (for HPOS compat).
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
Significance: patch
|
||||||
|
Type: fix
|
||||||
|
Comment: Skipping unit test for legacy widgets when in HPOS context.
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
Significance: patch
|
||||||
|
Type: fix
|
||||||
|
Comment: Changes are only in unit tests, no functionality is affected.
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: patch
|
||||||
|
Type: fix
|
||||||
|
|
||||||
|
Add HPOS compat for wc-user-functions.php.
|
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: patch
|
||||||
|
Type: fix
|
||||||
|
|
||||||
|
Handle date arguments in OrderTableQuery correctly by adjusting their timezones before running.
|
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: patch
|
||||||
|
Type: fix
|
||||||
|
|
||||||
|
Fetch order first to refresh cache before returning prop.
|
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: patch
|
||||||
|
Type: fix
|
||||||
|
|
||||||
|
Treat order as seperate resource when validating for webhook since it's not necessarily a CPT anymore.
|
|
@ -54,6 +54,7 @@ class WC_Post_Data {
|
||||||
add_action( 'wp_trash_post', array( __CLASS__, 'trash_post' ) );
|
add_action( 'wp_trash_post', array( __CLASS__, 'trash_post' ) );
|
||||||
add_action( 'untrashed_post', array( __CLASS__, 'untrash_post' ) );
|
add_action( 'untrashed_post', array( __CLASS__, 'untrash_post' ) );
|
||||||
add_action( 'before_delete_post', array( __CLASS__, 'before_delete_order' ) );
|
add_action( 'before_delete_post', array( __CLASS__, 'before_delete_order' ) );
|
||||||
|
add_action( 'woocommerce_before_delete_order', array( __CLASS__, 'before_delete_order' ) );
|
||||||
|
|
||||||
// Meta cache flushing.
|
// Meta cache flushing.
|
||||||
add_action( 'updated_post_meta', array( __CLASS__, 'flush_object_meta_cache' ), 10, 4 );
|
add_action( 'updated_post_meta', array( __CLASS__, 'flush_object_meta_cache' ), 10, 4 );
|
||||||
|
|
|
@ -274,21 +274,25 @@ class WC_Webhook extends WC_Legacy_Webhook {
|
||||||
private function is_valid_resource( $arg ) {
|
private function is_valid_resource( $arg ) {
|
||||||
$resource = $this->get_resource();
|
$resource = $this->get_resource();
|
||||||
|
|
||||||
if ( in_array( $resource, array( 'order', 'product', 'coupon' ), true ) ) {
|
if ( in_array( $resource, array( 'product', 'coupon' ), true ) ) {
|
||||||
$status = get_post_status( absint( $arg ) );
|
$status = get_post_status( absint( $arg ) );
|
||||||
|
|
||||||
// Ignore auto drafts for all resources.
|
// Ignore auto drafts for all resources.
|
||||||
if ( in_array( $status, array( 'auto-draft', 'new' ), true ) ) {
|
if ( in_array( $status, array( 'auto-draft', 'new' ), true ) ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Ignore standard drafts for orders.
|
if ( 'order' === $resource ) {
|
||||||
if ( 'order' === $resource && 'draft' === $status ) {
|
// Check registered order types for order types args.
|
||||||
|
if ( ! OrderUtil::is_order( absint( $arg ), wc_get_order_types( 'order-webhooks' ) ) ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check registered order types for order types args.
|
$order = wc_get_order( absint( $arg ) );
|
||||||
if ( 'order' === $resource && ! OrderUtil::is_order( absint( $arg ), wc_get_order_types( 'order-webhooks' ) ) ) {
|
|
||||||
|
// Ignore standard drafts for orders.
|
||||||
|
if ( in_array( $order->get_status(), array( 'draft', 'auto-draft', 'new' ), true ) ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -413,6 +413,89 @@ abstract class Abstract_WC_Order_Data_Store_CPT extends WC_Data_Store_WP impleme
|
||||||
return $items;
|
return $items;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the order type of a given item which belongs to WC_Order.
|
||||||
|
*
|
||||||
|
* @since 3.2.0
|
||||||
|
* @param WC_Order $order Order Object.
|
||||||
|
* @param int $order_item_id Order item id.
|
||||||
|
* @return string Order Item type
|
||||||
|
*/
|
||||||
|
public function get_order_item_type( $order, $order_item_id ) {
|
||||||
|
global $wpdb;
|
||||||
|
return $wpdb->get_var( $wpdb->prepare( "SELECT DISTINCT order_item_type FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = %d and order_item_id = %d;", $order->get_id(), $order_item_id ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prime following caches:
|
||||||
|
* 1. item-$order_item_id For individual items.
|
||||||
|
* 2. order-items-$order-id For fetching items associated with an order.
|
||||||
|
* 3. order-item meta.
|
||||||
|
*
|
||||||
|
* @param array $order_ids Order Ids to prime cache for.
|
||||||
|
* @param array $query_vars Query vars for the query.
|
||||||
|
*/
|
||||||
|
protected function prime_order_item_caches_for_orders( $order_ids, $query_vars ) {
|
||||||
|
global $wpdb;
|
||||||
|
if ( isset( $query_vars['fields'] ) && 'all' !== $query_vars['fields'] ) {
|
||||||
|
$line_items = array(
|
||||||
|
'line_items',
|
||||||
|
'shipping_lines',
|
||||||
|
'fee_lines',
|
||||||
|
'coupon_lines',
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( is_array( $query_vars['fields'] ) && 0 === count( array_intersect( $line_items, $query_vars['fields'] ) ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$cache_keys = array_map(
|
||||||
|
function ( $order_id ) {
|
||||||
|
return 'order-items-' . $order_id;
|
||||||
|
},
|
||||||
|
$order_ids
|
||||||
|
);
|
||||||
|
$cache_values = wc_cache_get_multiple( $cache_keys, 'orders' );
|
||||||
|
$non_cached_ids = array();
|
||||||
|
foreach ( $order_ids as $order_id ) {
|
||||||
|
if ( false === $cache_values[ 'order-items-' . $order_id ] ) {
|
||||||
|
$non_cached_ids[] = $order_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( empty( $non_cached_ids ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$non_cached_ids = esc_sql( $non_cached_ids );
|
||||||
|
$non_cached_ids_string = implode( ',', $non_cached_ids );
|
||||||
|
$order_items = $wpdb->get_results(
|
||||||
|
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||||
|
"SELECT order_item_type, order_item_id, order_id, order_item_name FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id in ( $non_cached_ids_string ) ORDER BY order_item_id;"
|
||||||
|
);
|
||||||
|
if ( empty( $order_items ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$order_items_for_all_orders = array_reduce(
|
||||||
|
$order_items,
|
||||||
|
function ( $order_items_collection, $order_item ) {
|
||||||
|
if ( ! isset( $order_items_collection[ $order_item->order_id ] ) ) {
|
||||||
|
$order_items_collection[ $order_item->order_id ] = array();
|
||||||
|
}
|
||||||
|
$order_items_collection[ $order_item->order_id ][] = $order_item;
|
||||||
|
return $order_items_collection;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
foreach ( $order_items_for_all_orders as $order_id => $items ) {
|
||||||
|
wp_cache_set( 'order-items-' . $order_id, $items, 'orders' );
|
||||||
|
}
|
||||||
|
foreach ( $order_items as $item ) {
|
||||||
|
wp_cache_set( 'item-' . $item->order_item_id, $item, 'order-items' );
|
||||||
|
}
|
||||||
|
$order_item_ids = wp_list_pluck( $order_items, 'order_item_id' );
|
||||||
|
update_meta_cache( 'order_item', $order_item_ids );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove all line items (products, coupons, shipping, taxes) from the order.
|
* Remove all line items (products, coupons, shipping, taxes) from the order.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1118,76 +1118,6 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Prime following caches:
|
|
||||||
* 1. item-$order_item_id For individual items.
|
|
||||||
* 2. order-items-$order-id For fetching items associated with an order.
|
|
||||||
* 3. order-item meta.
|
|
||||||
*
|
|
||||||
* @param array $order_ids Order Ids to prime cache for.
|
|
||||||
* @param array $query_vars Query vars for the query.
|
|
||||||
*/
|
|
||||||
private function prime_order_item_caches_for_orders( $order_ids, $query_vars ) {
|
|
||||||
global $wpdb;
|
|
||||||
if ( isset( $query_vars['fields'] ) && 'all' !== $query_vars['fields'] ) {
|
|
||||||
$line_items = array(
|
|
||||||
'line_items',
|
|
||||||
'shipping_lines',
|
|
||||||
'fee_lines',
|
|
||||||
'coupon_lines',
|
|
||||||
);
|
|
||||||
|
|
||||||
if ( is_array( $query_vars['fields'] ) && 0 === count( array_intersect( $line_items, $query_vars['fields'] ) ) ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$cache_keys = array_map(
|
|
||||||
function ( $order_id ) {
|
|
||||||
return 'order-items-' . $order_id;
|
|
||||||
},
|
|
||||||
$order_ids
|
|
||||||
);
|
|
||||||
$cache_values = wc_cache_get_multiple( $cache_keys, 'orders' );
|
|
||||||
$non_cached_ids = array();
|
|
||||||
foreach ( $order_ids as $order_id ) {
|
|
||||||
if ( false === $cache_values[ 'order-items-' . $order_id ] ) {
|
|
||||||
$non_cached_ids[] = $order_id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( empty( $non_cached_ids ) ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$non_cached_ids = esc_sql( $non_cached_ids );
|
|
||||||
$non_cached_ids_string = implode( ',', $non_cached_ids );
|
|
||||||
$order_items = $wpdb->get_results(
|
|
||||||
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
|
||||||
"SELECT order_item_type, order_item_id, order_id, order_item_name FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id in ( $non_cached_ids_string ) ORDER BY order_item_id;"
|
|
||||||
);
|
|
||||||
if ( empty( $order_items ) ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$order_items_for_all_orders = array_reduce(
|
|
||||||
$order_items,
|
|
||||||
function ( $order_items_collection, $order_item ) {
|
|
||||||
if ( ! isset( $order_items_collection[ $order_item->order_id ] ) ) {
|
|
||||||
$order_items_collection[ $order_item->order_id ] = array();
|
|
||||||
}
|
|
||||||
$order_items_collection[ $order_item->order_id ][] = $order_item;
|
|
||||||
return $order_items_collection;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
foreach ( $order_items_for_all_orders as $order_id => $items ) {
|
|
||||||
wp_cache_set( 'order-items-' . $order_id, $items, 'orders' );
|
|
||||||
}
|
|
||||||
foreach ( $order_items as $item ) {
|
|
||||||
wp_cache_set( 'item-' . $item->order_item_id, $item, 'order-items' );
|
|
||||||
}
|
|
||||||
$order_item_ids = wp_list_pluck( $order_items, 'order_item_id' );
|
|
||||||
update_meta_cache( 'order_item', $order_item_ids );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prime cache for raw meta data for orders in bulk. Difference between this and WP built-in metadata is that this method also fetches `meta_id` field which we use and cache it.
|
* Prime cache for raw meta data for orders in bulk. Difference between this and WP built-in metadata is that this method also fetches `meta_id` field which we use and cache it.
|
||||||
*
|
*
|
||||||
|
@ -1240,17 +1170,4 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
|
||||||
);
|
);
|
||||||
WC_Order::prime_raw_meta_data_cache( $raw_meta_data_collection, 'orders' );
|
WC_Order::prime_raw_meta_data_cache( $raw_meta_data_collection, 'orders' );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the order type of a given item which belongs to WC_Order.
|
|
||||||
*
|
|
||||||
* @since 3.2.0
|
|
||||||
* @param WC_Order $order Order Object.
|
|
||||||
* @param int $order_item_id Order item id.
|
|
||||||
* @return string Order Item type
|
|
||||||
*/
|
|
||||||
public function get_order_item_type( $order, $order_item_id ) {
|
|
||||||
global $wpdb;
|
|
||||||
return $wpdb->get_var( $wpdb->prepare( "SELECT DISTINCT order_item_type FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = %d and order_item_id = %d;", $order->get_id(), $order_item_id ) );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -325,6 +325,29 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller {
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* With HPOS, few internal meta keys such as _billing_address_index, _shipping_address_index are not considered internal anymore (since most internal keys were flattened into dedicated columns).
|
||||||
|
*
|
||||||
|
* This function helps in filtering out any remaining internal meta keys with HPOS is enabled.
|
||||||
|
*
|
||||||
|
* @param array $meta_data Order meta data.
|
||||||
|
*
|
||||||
|
* @return array Filtered order meta data.
|
||||||
|
*/
|
||||||
|
private function filter_internal_meta_keys( $meta_data ) {
|
||||||
|
if ( ! OrderUtil::custom_orders_table_usage_is_enabled() ) {
|
||||||
|
return $meta_data;
|
||||||
|
}
|
||||||
|
$cpt_hidden_keys = ( new \WC_Order_Data_Store_CPT() )->get_internal_meta_keys();
|
||||||
|
$meta_data = array_filter(
|
||||||
|
$meta_data,
|
||||||
|
function ( $meta ) use ( $cpt_hidden_keys ) {
|
||||||
|
return ! in_array( $meta->key, $cpt_hidden_keys, true );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return array_values( $meta_data );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get formatted item data.
|
* Get formatted item data.
|
||||||
*
|
*
|
||||||
|
@ -369,6 +392,7 @@ class WC_REST_Orders_V2_Controller extends WC_REST_CRUD_Controller {
|
||||||
case 'meta_data':
|
case 'meta_data':
|
||||||
$meta_data = $order->get_meta_data();
|
$meta_data = $order->get_meta_data();
|
||||||
$data['meta_data'] = $this->get_meta_data_for_response( $this->request, $meta_data );
|
$data['meta_data'] = $this->get_meta_data_for_response( $this->request, $meta_data );
|
||||||
|
$data['meta_data'] = $this->filter_internal_meta_keys( $data['meta_data'] );
|
||||||
break;
|
break;
|
||||||
case 'line_items':
|
case 'line_items':
|
||||||
$data['line_items'] = $order->get_items( 'line_item' );
|
$data['line_items'] = $order->get_items( 'line_item' );
|
||||||
|
|
|
@ -235,33 +235,6 @@ class WC_REST_Orders_Controller extends WC_REST_Orders_V2_Controller {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get formatted item data.
|
|
||||||
*
|
|
||||||
* @param WC_Order $order WC_Data instance.
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
protected function get_formatted_item_data( $order ) {
|
|
||||||
$item_data = parent::get_formatted_item_data( $order );
|
|
||||||
$cpt_hidden_keys = array();
|
|
||||||
|
|
||||||
if ( OrderUtil::custom_orders_table_usage_is_enabled() ) {
|
|
||||||
$cpt_hidden_keys = ( new \WC_Order_Data_Store_CPT() )->get_internal_meta_keys();
|
|
||||||
}
|
|
||||||
|
|
||||||
// XXX: This might be removed once we finalize the design for internal keys vs meta vs props in COT.
|
|
||||||
if ( ! empty( $item_data['meta_data'] ) ) {
|
|
||||||
$item_data['meta_data'] = array_filter(
|
|
||||||
$item_data['meta_data'],
|
|
||||||
function( $meta ) use ( $cpt_hidden_keys ) {
|
|
||||||
return ! in_array( $meta->key, $cpt_hidden_keys, true );
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $item_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare objects query.
|
* Prepare objects query.
|
||||||
*
|
*
|
||||||
|
|
|
@ -714,16 +714,40 @@ function wc_get_customer_order_count( $user_id ) {
|
||||||
function wc_reset_order_customer_id_on_deleted_user( $user_id ) {
|
function wc_reset_order_customer_id_on_deleted_user( $user_id ) {
|
||||||
global $wpdb;
|
global $wpdb;
|
||||||
|
|
||||||
$wpdb->update(
|
if ( OrderUtil::custom_orders_table_usage_is_enabled() ) {
|
||||||
$wpdb->postmeta,
|
$order_table_ds = wc_get_container()->get( OrdersTableDataStore::class );
|
||||||
array(
|
$order_table = $order_table_ds::get_orders_table_name();
|
||||||
'meta_value' => 0,
|
$wpdb->update(
|
||||||
),
|
$order_table,
|
||||||
array(
|
array(
|
||||||
'meta_key' => '_customer_user',
|
'customer_id' => 0,
|
||||||
'meta_value' => $user_id,
|
'date_updated_gmt' => current_time( 'mysql', true ),
|
||||||
)
|
),
|
||||||
); // WPCS: slow query ok.
|
array(
|
||||||
|
'customer_id' => $user_id,
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'%d',
|
||||||
|
'%s',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'%d',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! OrderUtil::custom_orders_table_usage_is_enabled() || OrderUtil::is_custom_order_tables_in_sync() ) {
|
||||||
|
$wpdb->update(
|
||||||
|
$wpdb->postmeta,
|
||||||
|
array(
|
||||||
|
'meta_value' => 0, //phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'meta_key' => '_customer_user', //phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
|
||||||
|
'meta_value' => $user_id, //phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
add_action( 'deleted_user', 'wc_reset_order_customer_id_on_deleted_user' );
|
add_action( 'deleted_user', 'wc_reset_order_customer_id_on_deleted_user' );
|
||||||
|
|
|
@ -10,6 +10,8 @@ namespace Automattic\WooCommerce\Admin\API;
|
||||||
defined( 'ABSPATH' ) || exit;
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
use Automattic\WooCommerce\Admin\API\Reports\Controller as ReportsController;
|
use Automattic\WooCommerce\Admin\API\Reports\Controller as ReportsController;
|
||||||
|
use Automattic\WooCommerce\Internal\DataStores\Orders\OrdersTableDataStore;
|
||||||
|
use Automattic\WooCommerce\Utilities\OrderUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Orders controller.
|
* Orders controller.
|
||||||
|
@ -54,30 +56,61 @@ class Orders extends \WC_REST_Orders_Controller {
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
protected function prepare_objects_query( $request ) {
|
protected function prepare_objects_query( $request ) {
|
||||||
global $wpdb;
|
|
||||||
$args = parent::prepare_objects_query( $request );
|
$args = parent::prepare_objects_query( $request );
|
||||||
|
|
||||||
// Search by partial order number.
|
|
||||||
if ( ! empty( $request['number'] ) ) {
|
if ( ! empty( $request['number'] ) ) {
|
||||||
$partial_number = trim( $request['number'] );
|
$args = $this->search_partial_order_number( $request['number'], $args );
|
||||||
$limit = intval( $args['posts_per_page'] );
|
}
|
||||||
$order_ids = $wpdb->get_col(
|
|
||||||
|
return $args;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to allow searching by partial order number.
|
||||||
|
*
|
||||||
|
* @param int $number Partial order number match.
|
||||||
|
* @param array $args List of arguments for the request.
|
||||||
|
*
|
||||||
|
* @return array Modified args with partial order search included.
|
||||||
|
*/
|
||||||
|
private function search_partial_order_number( $number, $args ) {
|
||||||
|
global $wpdb;
|
||||||
|
|
||||||
|
$partial_number = trim( $number );
|
||||||
|
$limit = intval( $args['posts_per_page'] );
|
||||||
|
if ( OrderUtil::custom_orders_table_usage_is_enabled() ) {
|
||||||
|
$order_table_name = OrdersTableDataStore::get_orders_table_name();
|
||||||
|
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- $orders_table_name is hardcoded.
|
||||||
|
$order_ids = $wpdb->get_col(
|
||||||
$wpdb->prepare(
|
$wpdb->prepare(
|
||||||
"SELECT ID
|
"SELECT id
|
||||||
FROM {$wpdb->prefix}posts
|
FROM $order_table_name
|
||||||
WHERE post_type = 'shop_order'
|
WHERE type = 'shop_order'
|
||||||
AND ID LIKE %s
|
AND id LIKE %s
|
||||||
LIMIT %d",
|
LIMIT %d",
|
||||||
$wpdb->esc_like( absint( $partial_number ) ) . '%',
|
$wpdb->esc_like( absint( $partial_number ) ) . '%',
|
||||||
$limit
|
$limit
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
// phpcs:enable
|
||||||
// Force WP_Query return empty if don't found any order.
|
} else {
|
||||||
$order_ids = empty( $order_ids ) ? array( 0 ) : $order_ids;
|
$order_ids = $wpdb->get_col(
|
||||||
$args['post__in'] = $order_ids;
|
$wpdb->prepare(
|
||||||
|
"SELECT ID
|
||||||
|
FROM {$wpdb->prefix}posts
|
||||||
|
WHERE post_type = 'shop_order'
|
||||||
|
AND ID LIKE %s
|
||||||
|
LIMIT %d",
|
||||||
|
$wpdb->esc_like( absint( $partial_number ) ) . '%',
|
||||||
|
$limit
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Force WP_Query return empty if don't found any order.
|
||||||
|
$order_ids = empty( $order_ids ) ? array( 0 ) : $order_ids;
|
||||||
|
$args['post__in'] = $order_ids;
|
||||||
|
|
||||||
return $args;
|
return $args;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -105,6 +105,7 @@ class DataStore extends ReportsDataStore implements DataStoreInterface {
|
||||||
* Set up all the hooks for maintaining and populating table data.
|
* Set up all the hooks for maintaining and populating table data.
|
||||||
*/
|
*/
|
||||||
public static function init() {
|
public static function init() {
|
||||||
|
add_action( 'woocommerce_before_delete_order', array( __CLASS__, 'delete_order' ) );
|
||||||
add_action( 'delete_post', array( __CLASS__, 'delete_order' ) );
|
add_action( 'delete_post', array( __CLASS__, 'delete_order' ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -180,6 +180,8 @@ class OrdersTableDataStore extends \Abstract_WC_Order_Data_Store_CPT implements
|
||||||
/**
|
/**
|
||||||
* Get the names of all the tables involved in the custom orders table feature.
|
* Get the names of all the tables involved in the custom orders table feature.
|
||||||
*
|
*
|
||||||
|
* See also : get_all_table_names_with_id.
|
||||||
|
*
|
||||||
* @return string[]
|
* @return string[]
|
||||||
*/
|
*/
|
||||||
public function get_all_table_names() {
|
public function get_all_table_names() {
|
||||||
|
@ -191,6 +193,22 @@ class OrdersTableDataStore extends \Abstract_WC_Order_Data_Store_CPT implements
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Similar to get_all_table_names, but also returns the table name along with the items table.
|
||||||
|
*
|
||||||
|
* @return array Names of the tables.
|
||||||
|
*/
|
||||||
|
public static function get_all_table_names_with_id() {
|
||||||
|
global $wpdb;
|
||||||
|
return array(
|
||||||
|
'orders' => self::get_orders_table_name(),
|
||||||
|
'addresses' => self::get_addresses_table_name(),
|
||||||
|
'operational_data' => self::get_operational_data_table_name(),
|
||||||
|
'meta' => self::get_meta_table_name(),
|
||||||
|
'items' => $wpdb->prefix . 'woocommerce_order_items',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Table column to WC_Order mapping for wc_orders table.
|
* Table column to WC_Order mapping for wc_orders table.
|
||||||
*
|
*
|
||||||
|
@ -554,7 +572,8 @@ class OrdersTableDataStore extends \Abstract_WC_Order_Data_Store_CPT implements
|
||||||
* @return bool Whether permissions are granted.
|
* @return bool Whether permissions are granted.
|
||||||
*/
|
*/
|
||||||
public function get_download_permissions_granted( $order ) {
|
public function get_download_permissions_granted( $order ) {
|
||||||
$order = is_int( $order ) ? wc_get_order( $order ) : $order;
|
$order_id = is_int( $order ) ? $order : $order->get_id();
|
||||||
|
$order = wc_get_order( $order_id );
|
||||||
return $order->get_download_permissions_granted();
|
return $order->get_download_permissions_granted();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -580,7 +599,8 @@ class OrdersTableDataStore extends \Abstract_WC_Order_Data_Store_CPT implements
|
||||||
* @return bool Whether sales are recorded.
|
* @return bool Whether sales are recorded.
|
||||||
*/
|
*/
|
||||||
public function get_recorded_sales( $order ) {
|
public function get_recorded_sales( $order ) {
|
||||||
$order = is_int( $order ) ? wc_get_order( $order ) : $order;
|
$order_id = is_int( $order ) ? $order : $order->get_id();
|
||||||
|
$order = wc_get_order( $order_id );
|
||||||
return $order->get_recorded_sales();
|
return $order->get_recorded_sales();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -606,7 +626,8 @@ class OrdersTableDataStore extends \Abstract_WC_Order_Data_Store_CPT implements
|
||||||
* @return bool Whether coupon counts were updated.
|
* @return bool Whether coupon counts were updated.
|
||||||
*/
|
*/
|
||||||
public function get_recorded_coupon_usage_counts( $order ) {
|
public function get_recorded_coupon_usage_counts( $order ) {
|
||||||
$order = is_int( $order ) ? wc_get_order( $order ) : $order;
|
$order_id = is_int( $order ) ? $order : $order->get_id();
|
||||||
|
$order = wc_get_order( $order_id );
|
||||||
return $order->get_recorded_coupon_usage_counts();
|
return $order->get_recorded_coupon_usage_counts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -632,7 +653,8 @@ class OrdersTableDataStore extends \Abstract_WC_Order_Data_Store_CPT implements
|
||||||
* @return bool Whether email is sent.
|
* @return bool Whether email is sent.
|
||||||
*/
|
*/
|
||||||
public function get_email_sent( $order ) {
|
public function get_email_sent( $order ) {
|
||||||
$order = is_int( $order ) ? wc_get_order( $order ) : $order;
|
$order_id = is_int( $order ) ? $order : $order->get_id();
|
||||||
|
$order = wc_get_order( $order_id );
|
||||||
return $order->get_new_order_email_sent();
|
return $order->get_new_order_email_sent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -658,8 +680,7 @@ class OrdersTableDataStore extends \Abstract_WC_Order_Data_Store_CPT implements
|
||||||
* @return bool Whether email was sent.
|
* @return bool Whether email was sent.
|
||||||
*/
|
*/
|
||||||
public function get_new_order_email_sent( $order ) {
|
public function get_new_order_email_sent( $order ) {
|
||||||
$order = is_int( $order ) ? wc_get_order( $order ) : $order;
|
return $this->get_email_sent( $order );
|
||||||
return $order->get_new_order_email_sent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -684,7 +705,8 @@ class OrdersTableDataStore extends \Abstract_WC_Order_Data_Store_CPT implements
|
||||||
* @return bool Whether stock was reduced.
|
* @return bool Whether stock was reduced.
|
||||||
*/
|
*/
|
||||||
public function get_stock_reduced( $order ) {
|
public function get_stock_reduced( $order ) {
|
||||||
$order = is_int( $order ) ? wc_get_order( $order ) : $order;
|
$order_id = is_int( $order ) ? $order : $order->get_id();
|
||||||
|
$order = wc_get_order( $order_id );
|
||||||
return $order->get_order_stock_reduced();
|
return $order->get_order_stock_reduced();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -164,6 +164,12 @@ class OrdersTableQuery {
|
||||||
*/
|
*/
|
||||||
private $date_query = null;
|
private $date_query = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instance of the OrdersTableDataStore class.
|
||||||
|
*
|
||||||
|
* @var OrdersTableDataStore
|
||||||
|
*/
|
||||||
|
private $order_datastore = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets up and runs the query after processing arguments.
|
* Sets up and runs the query after processing arguments.
|
||||||
|
@ -171,19 +177,11 @@ class OrdersTableQuery {
|
||||||
* @param array $args Array of query vars.
|
* @param array $args Array of query vars.
|
||||||
*/
|
*/
|
||||||
public function __construct( $args = array() ) {
|
public function __construct( $args = array() ) {
|
||||||
global $wpdb;
|
// Note that ideally we would inject this dependency via constructor, but that's not possible since this class needs to be backward compatible with WC_Order_Query class.
|
||||||
|
$this->order_datastore = wc_get_container()->get( OrdersTableDataStore::class );
|
||||||
|
|
||||||
$datastore = wc_get_container()->get( OrdersTableDataStore::class );
|
$this->tables = $this->order_datastore::get_all_table_names_with_id();
|
||||||
|
$this->mappings = $this->order_datastore->get_all_order_column_mappings();
|
||||||
// TODO: maybe OrdersTableDataStore::get_all_table_names() could return these keys/indices instead.
|
|
||||||
$this->tables = array(
|
|
||||||
'orders' => $datastore::get_orders_table_name(),
|
|
||||||
'addresses' => $datastore::get_addresses_table_name(),
|
|
||||||
'operational_data' => $datastore::get_operational_data_table_name(),
|
|
||||||
'meta' => $datastore::get_meta_table_name(),
|
|
||||||
'items' => $wpdb->prefix . 'woocommerce_order_items',
|
|
||||||
);
|
|
||||||
$this->mappings = $datastore->get_all_order_column_mappings();
|
|
||||||
|
|
||||||
$this->args = $args;
|
$this->args = $args;
|
||||||
|
|
||||||
|
@ -202,13 +200,13 @@ class OrdersTableQuery {
|
||||||
private function maybe_remap_args(): void {
|
private function maybe_remap_args(): void {
|
||||||
$mapping = array(
|
$mapping = array(
|
||||||
// WP_Query legacy.
|
// WP_Query legacy.
|
||||||
'post_date' => 'date_created_gmt',
|
'post_date' => 'date_created',
|
||||||
'post_date_gmt' => 'date_created_gmt',
|
'post_date_gmt' => 'date_created_gmt',
|
||||||
'post_modified' => 'date_modified_gmt',
|
'post_modified' => 'date_updated',
|
||||||
'post_modified_gmt' => 'date_updated_gmt',
|
'post_modified_gmt' => 'date_updated_gmt',
|
||||||
'post_status' => 'status',
|
'post_status' => 'status',
|
||||||
'_date_completed' => 'date_completed_gmt',
|
'_date_completed' => 'date_completed',
|
||||||
'_date_paid' => 'date_paid_gmt',
|
'_date_paid' => 'date_paid',
|
||||||
'paged' => 'page',
|
'paged' => 'page',
|
||||||
'post_parent' => 'parent_order_id',
|
'post_parent' => 'parent_order_id',
|
||||||
'post_parent__in' => 'parent_order_id',
|
'post_parent__in' => 'parent_order_id',
|
||||||
|
@ -231,12 +229,8 @@ class OrdersTableQuery {
|
||||||
|
|
||||||
// Translate from WC_Order_Query to table structure.
|
// Translate from WC_Order_Query to table structure.
|
||||||
'version' => 'woocommerce_version',
|
'version' => 'woocommerce_version',
|
||||||
'date_created' => 'date_created_gmt',
|
'date_modified' => 'date_updated',
|
||||||
'date_modified' => 'date_updated_gmt',
|
|
||||||
'date_modified_gmt' => 'date_updated_gmt',
|
'date_modified_gmt' => 'date_updated_gmt',
|
||||||
'date_completed' => 'date_completed_gmt',
|
|
||||||
'date_completed_gmt' => 'date_completed_gmt',
|
|
||||||
'date_paid' => 'date_paid_gmt',
|
|
||||||
'discount_total' => 'discount_total_amount',
|
'discount_total' => 'discount_total_amount',
|
||||||
'discount_tax' => 'discount_tax_amount',
|
'discount_tax' => 'discount_tax_amount',
|
||||||
'shipping_total' => 'shipping_total_amount',
|
'shipping_total' => 'shipping_total_amount',
|
||||||
|
@ -276,16 +270,26 @@ class OrdersTableQuery {
|
||||||
$this->args['meta_query'] = array( $shortcut_meta_query ); // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
|
$this->args['meta_query'] = array( $shortcut_meta_query ); // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Date query.
|
||||||
|
if ( isset( $this->args['date_query'] ) && is_array( $this->args['date_query'] ) ) {
|
||||||
|
foreach ( $this->args['date_query'] as $index => $query ) {
|
||||||
|
if ( isset( $query['column'] ) && isset( $mapping[ $query['column'] ] ) ) {
|
||||||
|
$this->args['date_query'][ $index ]['column'] = $mapping[ $query['column'] ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a `WP_Date_Query` compatible query from a given date.
|
* Generates a `WP_Date_Query` compatible query from a given date.
|
||||||
* YYYY-MM-DD queries have 'day' precision for backwards compatibility.
|
* YYYY-MM-DD queries have 'day' precision for backwards compatibility.
|
||||||
*
|
*
|
||||||
* @param mixed $date The date. Can be a {@see \WC_DateTime}, a timestamp or a string.
|
* @param mixed $date The date. Can be a {@see \WC_DateTime}, a timestamp or a string.
|
||||||
|
* @param string $timezone The timezone to use for the date.
|
||||||
* @return array An array with keys 'year', 'month', 'day' and possibly 'hour', 'minute' and 'second'.
|
* @return array An array with keys 'year', 'month', 'day' and possibly 'hour', 'minute' and 'second'.
|
||||||
*/
|
*/
|
||||||
private function date_to_date_query_arg( $date ): array {
|
private function date_to_date_query_arg( $date, $timezone ): array {
|
||||||
$result = array(
|
$result = array(
|
||||||
'year' => '',
|
'year' => '',
|
||||||
'month' => '',
|
'month' => '',
|
||||||
|
@ -294,7 +298,7 @@ class OrdersTableQuery {
|
||||||
$precision = 'second';
|
$precision = 'second';
|
||||||
|
|
||||||
if ( is_numeric( $date ) ) {
|
if ( is_numeric( $date ) ) {
|
||||||
$date = new \WC_DateTime( "@{$date}", new \DateTimeZone( 'UTC' ) );
|
$date = new \WC_DateTime( "@{$date}", new \DateTimeZone( $timezone ) );
|
||||||
} elseif ( ! is_a( $date, 'WC_DateTime' ) ) {
|
} elseif ( ! is_a( $date, 'WC_DateTime' ) ) {
|
||||||
// YYYY-MM-DD queries have 'day' precision for backwards compat.
|
// YYYY-MM-DD queries have 'day' precision for backwards compat.
|
||||||
$date = wc_string_to_datetime( $date );
|
$date = wc_string_to_datetime( $date );
|
||||||
|
@ -321,30 +325,54 @@ class OrdersTableQuery {
|
||||||
* @throws \Exception When date args are invalid.
|
* @throws \Exception When date args are invalid.
|
||||||
*/
|
*/
|
||||||
private function process_date_args(): void {
|
private function process_date_args(): void {
|
||||||
$valid_operators = array( '>', '>=', '=', '<=', '<', '...' );
|
$valid_operators = array( '>', '>=', '=', '<=', '<', '...' );
|
||||||
$date_queries = array();
|
$date_queries = array();
|
||||||
$gmt_date_keys = array(
|
$local_to_gmt_date_keys = array(
|
||||||
'date_created_gmt',
|
'date_created' => 'date_created_gmt',
|
||||||
'date_updated_gmt',
|
'date_updated' => 'date_updated_gmt',
|
||||||
'date_paid_gmt',
|
'date_paid' => 'date_paid_gmt',
|
||||||
'date_completed_gmt',
|
'date_completed' => 'date_completed_gmt',
|
||||||
);
|
);
|
||||||
|
$gmt_date_keys = array_values( $local_to_gmt_date_keys );
|
||||||
|
$local_date_keys = array_keys( $local_to_gmt_date_keys );
|
||||||
|
|
||||||
foreach ( array_filter( $gmt_date_keys, array( $this, 'arg_isset' ) ) as $date_key ) {
|
$valid_date_keys = array_merge( $gmt_date_keys, $local_date_keys );
|
||||||
|
$date_keys = array_filter( $valid_date_keys, array( $this, 'arg_isset' ) );
|
||||||
|
|
||||||
|
// Process already passed date queries args.
|
||||||
|
if ( $this->arg_isset( 'date_query' ) && is_array( $this->args['date_query'] ) ) {
|
||||||
|
foreach ( $this->args['date_query'] as $index => $query ) {
|
||||||
|
if ( ! isset( $query['column'] ) || ! in_array( $query['column'], $valid_date_keys, true ) ) {
|
||||||
|
unset( $this->args['date_query'][ $index ] );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Convert any local dates to GMT.
|
||||||
|
if ( isset( $local_to_gmt_date_keys[ $query['column'] ] ) ) {
|
||||||
|
$this->args['date_query'][ $index ]['column'] = $local_to_gmt_date_keys[ $query['column'] ];
|
||||||
|
$op = isset( $query['after'] ) ? 'after' : 'before';
|
||||||
|
$date_value_local = $query[ $op ];
|
||||||
|
$date_value_gmt = wc_string_to_timestamp( get_gmt_from_date( wc_string_to_datetime( $date_value_local ) ) );
|
||||||
|
$this->args['date_query'][ $index ][ $op ] = $this->date_to_date_query_arg( $date_value_gmt, 'UTC' );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ( $date_keys as $date_key ) {
|
||||||
$date_value = $this->args[ $date_key ];
|
$date_value = $this->args[ $date_key ];
|
||||||
$operator = '=';
|
$operator = '=';
|
||||||
$dates = array();
|
$dates = array();
|
||||||
|
$timezone = in_array( $date_key, $gmt_date_keys, true ) ? '+0000' : wc_timezone_string();
|
||||||
|
|
||||||
if ( is_string( $date_value ) && preg_match( self::REGEX_SHORTHAND_DATES, $date_value, $matches ) ) {
|
if ( is_string( $date_value ) && preg_match( self::REGEX_SHORTHAND_DATES, $date_value, $matches ) ) {
|
||||||
$operator = in_array( $matches[2], $valid_operators, true ) ? $matches[2] : '';
|
$operator = in_array( $matches[2], $valid_operators, true ) ? $matches[2] : '';
|
||||||
|
|
||||||
if ( ! empty( $matches[1] ) ) {
|
if ( ! empty( $matches[1] ) ) {
|
||||||
$dates[] = $this->date_to_date_query_arg( $matches[1] );
|
$dates[] = $this->date_to_date_query_arg( $matches[1], $timezone );
|
||||||
}
|
}
|
||||||
|
|
||||||
$dates[] = $this->date_to_date_query_arg( $matches[3] );
|
$dates[] = $this->date_to_date_query_arg( $matches[3], $timezone );
|
||||||
} else {
|
} else {
|
||||||
$dates[] = $this->date_to_date_query_arg( $date_value );
|
$dates[] = $this->date_to_date_query_arg( $date_value, $timezone );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( empty( $dates ) || ! $operator || ( '...' === $operator && count( $dates ) < 2 ) ) {
|
if ( empty( $dates ) || ! $operator || ( '...' === $operator && count( $dates ) < 2 ) ) {
|
||||||
|
@ -361,6 +389,7 @@ class OrdersTableQuery {
|
||||||
$operator_to_keys[] = 'before';
|
$operator_to_keys[] = 'before';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$date_key = in_array( $date_key, $local_date_keys, true ) ? $local_to_gmt_date_keys[ $date_key ] : $date_key;
|
||||||
$date_queries[] = array_merge(
|
$date_queries[] = array_merge(
|
||||||
array(
|
array(
|
||||||
'column' => $date_key,
|
'column' => $date_key,
|
||||||
|
@ -874,6 +903,9 @@ class OrdersTableQuery {
|
||||||
$ids[] = absint( $value );
|
$ids[] = absint( $value );
|
||||||
} elseif ( is_string( $value ) && is_email( $value ) ) {
|
} elseif ( is_string( $value ) && is_email( $value ) ) {
|
||||||
$emails[] = sanitize_email( $value );
|
$emails[] = sanitize_email( $value );
|
||||||
|
} else {
|
||||||
|
// Invalid query.
|
||||||
|
$pieces[] = '1=0';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
use Automattic\WooCommerce\Proxies\LegacyProxy;
|
use Automattic\WooCommerce\Proxies\LegacyProxy;
|
||||||
use Automattic\WooCommerce\Testing\Tools\CodeHacking\CodeHacker;
|
use Automattic\WooCommerce\Testing\Tools\CodeHacking\CodeHacker;
|
||||||
|
use Automattic\WooCommerce\Utilities\OrderUtil;
|
||||||
use PHPUnit\Framework\Constraint\IsType;
|
use PHPUnit\Framework\Constraint\IsType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -388,4 +389,15 @@ class WC_Unit_Test_Case extends WP_HTTP_TestCase {
|
||||||
$events = self::get_tracks_events( $event_name );
|
$events = self::get_tracks_events( $event_name );
|
||||||
$this->assertEmpty( $events );
|
$this->assertEmpty( $events );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark test skipped when HPOS is enabled.
|
||||||
|
*
|
||||||
|
* @param string $message Message to display when test is skipped.
|
||||||
|
*/
|
||||||
|
protected function skip_if_hpos_enabled( $message ) {
|
||||||
|
if ( OrderUtil::custom_orders_table_usage_is_enabled() ) {
|
||||||
|
$this->markTestSkipped( $message );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ class WC_Tests_Admin_Dashboard extends WC_Unit_Test_Case {
|
||||||
* Test: get_status_widget
|
* Test: get_status_widget
|
||||||
*/
|
*/
|
||||||
public function test_status_widget() {
|
public function test_status_widget() {
|
||||||
|
$this->skip_if_hpos_enabled( 'We don\'t support legacy reports on HPOS' );
|
||||||
wp_set_current_user( $this->user );
|
wp_set_current_user( $this->user );
|
||||||
$order = WC_Helper_Order::create_order();
|
$order = WC_Helper_Order::create_order();
|
||||||
$order->set_status( 'completed' );
|
$order->set_status( 'completed' );
|
||||||
|
@ -58,6 +59,7 @@ class WC_Tests_Admin_Dashboard extends WC_Unit_Test_Case {
|
||||||
* Test: get_status_widget with woo admin disabled.
|
* Test: get_status_widget with woo admin disabled.
|
||||||
*/
|
*/
|
||||||
public function test_status_widget_with_woo_admin_disabled() {
|
public function test_status_widget_with_woo_admin_disabled() {
|
||||||
|
$this->skip_if_hpos_enabled( 'We don\'t support legacy reports on HPOS' );
|
||||||
wp_set_current_user( $this->user );
|
wp_set_current_user( $this->user );
|
||||||
$order = WC_Helper_Order::create_order();
|
$order = WC_Helper_Order::create_order();
|
||||||
$order->set_status( 'completed' );
|
$order->set_status( 'completed' );
|
||||||
|
|
|
@ -18,6 +18,16 @@ class WC_Tests_Admin_Report extends WC_Unit_Test_Case {
|
||||||
include_once WC_Unit_Tests_Bootstrap::instance()->plugin_dir . '/includes/admin/reports/class-wc-admin-report.php';
|
include_once WC_Unit_Tests_Bootstrap::instance()->plugin_dir . '/includes/admin/reports/class-wc-admin-report.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up the test.
|
||||||
|
*/
|
||||||
|
public function setUp(): void {
|
||||||
|
parent::setUp();
|
||||||
|
if ( \Automattic\WooCommerce\Utilities\OrderUtil::custom_orders_table_usage_is_enabled() ) {
|
||||||
|
$this->markTestSkipped( 'This test is not compatible with the custom orders table.' );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear cached report data.
|
* Clear cached report data.
|
||||||
*
|
*
|
||||||
|
|
|
@ -18,6 +18,16 @@ class WC_Tests_Report_Sales_By_Date extends WC_Unit_Test_Case {
|
||||||
include_once WC_Unit_Tests_Bootstrap::instance()->plugin_dir . '/includes/admin/reports/class-wc-report-sales-by-date.php';
|
include_once WC_Unit_Tests_Bootstrap::instance()->plugin_dir . '/includes/admin/reports/class-wc-report-sales-by-date.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up the test.
|
||||||
|
*/
|
||||||
|
public function setUp(): void {
|
||||||
|
parent::setUp();
|
||||||
|
if ( \Automattic\WooCommerce\Utilities\OrderUtil::custom_orders_table_usage_is_enabled() ) {
|
||||||
|
$this->markTestSkipped( 'This test is not compatible with the custom orders table.' );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear cached report data.
|
* Clear cached report data.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use Automattic\WooCommerce\Utilities\OrderUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test meta for https://github.com/woocommerce/woocommerce/issues/13533.
|
* Test meta for https://github.com/woocommerce/woocommerce/issues/13533.
|
||||||
*
|
*
|
||||||
|
@ -106,11 +109,14 @@ class WC_Tests_CRUD_Meta_Data extends WC_Unit_Test_Case {
|
||||||
$this->assertCount( 1, $order->get_meta_data() );
|
$this->assertCount( 1, $order->get_meta_data() );
|
||||||
$this->assertTrue( in_array( 'random', wp_list_pluck( $order->get_meta_data(), 'key' ) ) );
|
$this->assertTrue( in_array( 'random', wp_list_pluck( $order->get_meta_data(), 'key' ) ) );
|
||||||
|
|
||||||
// The new $order should have 3 items of meta since it's freshly loaded.
|
$expected_count = OrderUtil::custom_orders_table_usage_is_enabled() ? 2 : 3;
|
||||||
$this->assertCount( 3, $new_order->get_meta_data() );
|
// The new $order should have 3 items (or 2 in case of HPOS since direct post updates are not read) of meta since it's freshly loaded.
|
||||||
|
$this->assertCount( $expected_count, $new_order->get_meta_data() );
|
||||||
$this->assertTrue( in_array( 'random', wp_list_pluck( $new_order->get_meta_data(), 'key' ) ) );
|
$this->assertTrue( in_array( 'random', wp_list_pluck( $new_order->get_meta_data(), 'key' ) ) );
|
||||||
$this->assertTrue( in_array( 'random_other', wp_list_pluck( $new_order->get_meta_data(), 'key' ) ) );
|
$this->assertTrue( in_array( 'random_other', wp_list_pluck( $new_order->get_meta_data(), 'key' ) ) );
|
||||||
$this->assertTrue( in_array( 'random_other_pre_crud', wp_list_pluck( $new_order->get_meta_data(), 'key' ) ) );
|
if ( ! OrderUtil::custom_orders_table_usage_is_enabled() ) {
|
||||||
|
$this->assertTrue( in_array( 'random_other_pre_crud', wp_list_pluck( $new_order->get_meta_data(), 'key' ), true ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
* @package WooCommerce\Tests\CRUD
|
* @package WooCommerce\Tests\CRUD
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use Automattic\WooCommerce\Utilities\OrderUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Meta
|
* Meta
|
||||||
*
|
*
|
||||||
|
@ -882,10 +884,10 @@ class WC_Tests_CRUD_Orders extends WC_Unit_Test_Case {
|
||||||
$object = new WC_Order();
|
$object = new WC_Order();
|
||||||
|
|
||||||
// Save + create.
|
// Save + create.
|
||||||
$save_id = $object->save();
|
$save_id = $object->save();
|
||||||
$post = get_post( $save_id );
|
$post = get_post( $save_id );
|
||||||
$this->assertEquals( 'shop_order', $post->post_type );
|
$expected_post_type = OrderUtil::custom_orders_table_usage_is_enabled() ? 'shop_order_placehold' : 'shop_order';
|
||||||
$this->assertEquals( 'shop_order', $post->post_type );
|
$this->assertEquals( $expected_post_type, $post->post_type );
|
||||||
|
|
||||||
// Update.
|
// Update.
|
||||||
$update_id = $object->save();
|
$update_id = $object->save();
|
||||||
|
|
|
@ -109,15 +109,19 @@ class WC_Tests_Order_Functions extends WC_Unit_Test_Case {
|
||||||
->will( $this->returnValueMap( $test_counts[ $order_type ] ) );
|
->will( $this->returnValueMap( $test_counts[ $order_type ] ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
$add_mock_datastores = function( $stores ) use ( $mock_datastores ) {
|
$add_mock_datastores = function ( $stores ) use ( $mock_datastores ) {
|
||||||
return array_merge( $stores, $mock_datastores );
|
return array_merge( $stores, $mock_datastores );
|
||||||
};
|
};
|
||||||
$add_mock_order_type = function( $order_types ) use ( $mock_datastores ) {
|
$add_mock_order_type = function ( $order_types ) use ( $mock_datastores ) {
|
||||||
return array( 'shop_order', 'order-fake-type' );
|
return array( 'shop_order', 'order-fake-type' );
|
||||||
};
|
};
|
||||||
|
$return_mock_order_data_store = function ( $stores ) use ( $mock_datastores ) {
|
||||||
|
return $mock_datastores['order'];
|
||||||
|
};
|
||||||
|
|
||||||
add_filter( 'woocommerce_data_stores', $add_mock_datastores );
|
add_filter( 'woocommerce_data_stores', $add_mock_datastores );
|
||||||
add_filter( 'wc_order_types', $add_mock_order_type );
|
add_filter( 'wc_order_types', $add_mock_order_type );
|
||||||
|
add_filter( 'woocommerce_order_data_store', $return_mock_order_data_store, 1000, 2 );
|
||||||
|
|
||||||
// Check counts for specific order types.
|
// Check counts for specific order types.
|
||||||
$this->assertEquals( 2, wc_orders_count( 'on-hold', 'shop_order' ) );
|
$this->assertEquals( 2, wc_orders_count( 'on-hold', 'shop_order' ) );
|
||||||
|
@ -131,6 +135,7 @@ class WC_Tests_Order_Functions extends WC_Unit_Test_Case {
|
||||||
|
|
||||||
remove_filter( 'woocommerce_data_stores', $add_mock_datastores );
|
remove_filter( 'woocommerce_data_stores', $add_mock_datastores );
|
||||||
remove_filter( 'wc_order_types', $add_mock_order_type );
|
remove_filter( 'wc_order_types', $add_mock_order_type );
|
||||||
|
remove_filter( 'woocommerce_order_data_store', $return_mock_order_data_store, 1000 );
|
||||||
|
|
||||||
// Confirm that everything's back to normal.
|
// Confirm that everything's back to normal.
|
||||||
wp_cache_flush();
|
wp_cache_flush();
|
||||||
|
@ -190,7 +195,8 @@ class WC_Tests_Order_Functions extends WC_Unit_Test_Case {
|
||||||
// Assert the return when $the_order args is false.
|
// Assert the return when $the_order args is false.
|
||||||
$this->assertFalse( wc_get_order( false ) );
|
$this->assertFalse( wc_get_order( false ) );
|
||||||
|
|
||||||
$post = get_post( $order->get_id() );
|
$post = get_post( $order->get_id() );
|
||||||
|
$theorder = $order;
|
||||||
$this->assertInstanceOf(
|
$this->assertInstanceOf(
|
||||||
'WC_Order',
|
'WC_Order',
|
||||||
wc_get_order(),
|
wc_get_order(),
|
||||||
|
|
|
@ -14,6 +14,7 @@ use Automattic\WooCommerce\Internal\DataStores\Orders\CustomOrdersTableControlle
|
||||||
use Automattic\WooCommerce\Internal\DataStores\Orders\DataSynchronizer;
|
use Automattic\WooCommerce\Internal\DataStores\Orders\DataSynchronizer;
|
||||||
use Automattic\WooCommerce\Internal\DataStores\Orders\OrdersTableDataStore;
|
use Automattic\WooCommerce\Internal\DataStores\Orders\OrdersTableDataStore;
|
||||||
use Automattic\WooCommerce\Internal\Features\FeaturesController;
|
use Automattic\WooCommerce\Internal\Features\FeaturesController;
|
||||||
|
use Automattic\WooCommerce\Utilities\OrderUtil;
|
||||||
use WC_Data_Store;
|
use WC_Data_Store;
|
||||||
use WC_Mock_Payment_Gateway;
|
use WC_Mock_Payment_Gateway;
|
||||||
use WC_Order;
|
use WC_Order;
|
||||||
|
@ -187,6 +188,8 @@ class OrderHelper {
|
||||||
* @return int Order ID
|
* @return int Order ID
|
||||||
*/
|
*/
|
||||||
public static function create_complex_wp_post_order() {
|
public static function create_complex_wp_post_order() {
|
||||||
|
$current_cot_state = OrderUtil::custom_orders_table_usage_is_enabled();
|
||||||
|
self::toggle_cot( false );
|
||||||
update_option( 'woocommerce_prices_include_tax', 'yes' );
|
update_option( 'woocommerce_prices_include_tax', 'yes' );
|
||||||
update_option( 'woocommerce_calc_taxes', 'yes' );
|
update_option( 'woocommerce_calc_taxes', 'yes' );
|
||||||
$uniq_cust_id = wp_generate_password( 10, false );
|
$uniq_cust_id = wp_generate_password( 10, false );
|
||||||
|
@ -256,6 +259,8 @@ class OrderHelper {
|
||||||
$order->save();
|
$order->save();
|
||||||
$order->save_meta_data();
|
$order->save_meta_data();
|
||||||
|
|
||||||
|
self::toggle_cot( $current_cot_state );
|
||||||
|
|
||||||
return $order->get_id();
|
return $order->get_id();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,9 @@
|
||||||
* @package WooCommerce\Tests\API
|
* @package WooCommerce\Tests\API
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use Automattic\WooCommerce\Internal\DataStores\Orders\OrdersTableDataStore;
|
||||||
|
use Automattic\WooCommerce\Utilities\OrderUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trait for testing the date filtering on controllers that inherit from WC_REST_CRUD_Controller.
|
* Trait for testing the date filtering on controllers that inherit from WC_REST_CRUD_Controller.
|
||||||
*/
|
*/
|
||||||
|
@ -34,18 +37,34 @@ trait DateFilteringForCrudControllers {
|
||||||
public function test_filter_by_creation_or_modification_date( $param_name, $filter_by_gmt, $expected_to_be_returned ) {
|
public function test_filter_by_creation_or_modification_date( $param_name, $filter_by_gmt, $expected_to_be_returned ) {
|
||||||
global $wpdb;
|
global $wpdb;
|
||||||
|
|
||||||
|
$timezone_string_option = get_option( 'timezone_string' );
|
||||||
|
update_option( 'timezone_string', 'Africa/Blantyre', true ); // +02:00
|
||||||
wp_set_current_user( $this->user );
|
wp_set_current_user( $this->user );
|
||||||
$item_id = $this->get_item_for_date_filtering_tests()->get_id();
|
$item = $this->get_item_for_date_filtering_tests();
|
||||||
|
$item_id = $item->get_id();
|
||||||
|
|
||||||
// phpcs:disable WordPress.DB.PreparedSQL.NotPrepared
|
if ( $item instanceof WC_Abstract_Order && OrderUtil::custom_orders_table_usage_is_enabled() ) {
|
||||||
$wpdb->query(
|
$wpdb->update(
|
||||||
'UPDATE ' . $wpdb->prefix . "posts SET
|
OrdersTableDataStore::get_orders_table_name(),
|
||||||
|
array(
|
||||||
|
'date_created_gmt' => '2000-01-01T10:00:00',
|
||||||
|
'date_updated_gmt' => '2000-02-01T10:00:00',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'id' => $item->get_id(),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// phpcs:disable WordPress.DB.PreparedSQL.NotPrepared
|
||||||
|
$wpdb->query(
|
||||||
|
'UPDATE ' . $wpdb->prefix . "posts SET
|
||||||
post_date = '2000-01-01T12:00:00',
|
post_date = '2000-01-01T12:00:00',
|
||||||
post_date_gmt = '2000-01-01T10:00:00',
|
post_date_gmt = '2000-01-01T10:00:00',
|
||||||
post_modified = '2000-02-01T12:00:00',
|
post_modified = '2000-02-01T12:00:00',
|
||||||
post_modified_gmt = '2000-02-01T10:00:00'
|
post_modified_gmt = '2000-02-01T10:00:00'
|
||||||
WHERE ID = " . $item_id
|
WHERE ID = " . $item_id
|
||||||
);
|
);
|
||||||
|
}
|
||||||
// phpcs:enable WordPress.DB.PreparedSQL.NotPrepared
|
// phpcs:enable WordPress.DB.PreparedSQL.NotPrepared
|
||||||
|
|
||||||
$request = new WP_REST_Request( 'GET', $this->get_endpoint_for_date_filtering_tests() );
|
$request = new WP_REST_Request( 'GET', $this->get_endpoint_for_date_filtering_tests() );
|
||||||
|
@ -60,6 +79,7 @@ trait DateFilteringForCrudControllers {
|
||||||
|
|
||||||
$this->assertEquals( 200, $response->get_status() );
|
$this->assertEquals( 200, $response->get_status() );
|
||||||
$this->assertEquals( $expected_to_be_returned ? 1 : 0, count( $response_items ) );
|
$this->assertEquals( $expected_to_be_returned ? 1 : 0, count( $response_items ) );
|
||||||
|
update_option( 'timezone_string', $timezone_string_option );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -80,19 +100,35 @@ trait DateFilteringForCrudControllers {
|
||||||
public function test_can_filter_by_more_than_one_date( $first_param_name, $first_param_value, $second_param_name, $second_param_value, $filter_by_gmt, $expected_to_be_returned ) {
|
public function test_can_filter_by_more_than_one_date( $first_param_name, $first_param_value, $second_param_name, $second_param_value, $filter_by_gmt, $expected_to_be_returned ) {
|
||||||
global $wpdb;
|
global $wpdb;
|
||||||
|
|
||||||
|
$timezone_string_option = get_option( 'timezone_string' );
|
||||||
|
update_option( 'timezone_string', 'Africa/Blantyre', true ); // +02:00
|
||||||
wp_set_current_user( $this->user );
|
wp_set_current_user( $this->user );
|
||||||
$item_id = $this->get_item_for_date_filtering_tests()->get_id();
|
$item = $this->get_item_for_date_filtering_tests();
|
||||||
|
$item_id = $item->get_id();
|
||||||
|
|
||||||
// phpcs:disable WordPress.DB.PreparedSQL.NotPrepared
|
if ( $item instanceof WC_Abstract_Order && OrderUtil::custom_orders_table_usage_is_enabled() ) {
|
||||||
$wpdb->query(
|
$wpdb->update(
|
||||||
'UPDATE ' . $wpdb->prefix . "posts SET
|
OrdersTableDataStore::get_orders_table_name(),
|
||||||
|
array(
|
||||||
|
'date_created_gmt' => '2000-01-01T10:00:00',
|
||||||
|
'date_updated_gmt' => '2000-02-01T10:00:00',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'id' => $item->get_id(),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// phpcs:disable WordPress.DB.PreparedSQL.NotPrepared
|
||||||
|
$wpdb->query(
|
||||||
|
'UPDATE ' . $wpdb->prefix . "posts SET
|
||||||
post_date = '2000-01-01T12:00:00',
|
post_date = '2000-01-01T12:00:00',
|
||||||
post_date_gmt = '2000-01-01T10:00:00',
|
post_date_gmt = '2000-01-01T10:00:00',
|
||||||
post_modified = '2000-02-01T12:00:00',
|
post_modified = '2000-02-01T12:00:00',
|
||||||
post_modified_gmt = '2000-02-01T10:00:00'
|
post_modified_gmt = '2000-02-01T10:00:00'
|
||||||
WHERE ID = " . $item_id
|
WHERE ID = " . $item_id
|
||||||
);
|
);
|
||||||
// phpcs:enable WordPress.DB.PreparedSQL.NotPrepared
|
// phpcs:enable WordPress.DB.PreparedSQL.NotPrepared
|
||||||
|
}
|
||||||
|
|
||||||
$request = new WP_REST_Request( 'GET', $this->get_endpoint_for_date_filtering_tests() );
|
$request = new WP_REST_Request( 'GET', $this->get_endpoint_for_date_filtering_tests() );
|
||||||
$request->set_query_params(
|
$request->set_query_params(
|
||||||
|
@ -107,5 +143,6 @@ trait DateFilteringForCrudControllers {
|
||||||
|
|
||||||
$this->assertEquals( 200, $response->get_status() );
|
$this->assertEquals( 200, $response->get_status() );
|
||||||
$this->assertEquals( $expected_to_be_returned ? 1 : 0, count( $response_items ) );
|
$this->assertEquals( $expected_to_be_returned ? 1 : 0, count( $response_items ) );
|
||||||
|
update_option( 'timezone_string', $timezone_string_option );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -323,13 +323,8 @@ class WC_Admin_Tests_API_Reports_Import extends WC_REST_Unit_Test_Case {
|
||||||
// Create 1 draft order - to be excluded from totals.
|
// Create 1 draft order - to be excluded from totals.
|
||||||
$order = WC_Helper_Order::create_order( $this->customer, $product );
|
$order = WC_Helper_Order::create_order( $this->customer, $product );
|
||||||
$order->set_date_created( time() - ( 5 * DAY_IN_SECONDS ) );
|
$order->set_date_created( time() - ( 5 * DAY_IN_SECONDS ) );
|
||||||
|
$order->set_status( 'auto-draft' );
|
||||||
$order->save();
|
$order->save();
|
||||||
wp_update_post(
|
|
||||||
array(
|
|
||||||
'ID' => $order->get_id(),
|
|
||||||
'post_status' => 'auto-draft',
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Test totals and total params.
|
// Test totals and total params.
|
||||||
$request = new WP_REST_Request( 'GET', $this->endpoint . '/totals' );
|
$request = new WP_REST_Request( 'GET', $this->endpoint . '/totals' );
|
||||||
|
|
|
@ -1,16 +1,47 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WC_Order_Factory_Test Class.
|
* WC_Order_Factory_Test Class.
|
||||||
*/
|
*/
|
||||||
class WC_Order_Factory_Test extends WC_Unit_Test_Case {
|
class WC_Order_Factory_Test extends WC_Unit_Test_Case {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store COT state at the start of the test so we can restore it later.
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
private $cot_state;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disable COT before the test.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setUp(): void {
|
||||||
|
parent::setUp();
|
||||||
|
$this->cot_state = \Automattic\WooCommerce\Utilities\OrderUtil::custom_orders_table_usage_is_enabled();
|
||||||
|
OrderHelper::toggle_cot( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restore COT state after the test.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function tearDown(): void {
|
||||||
|
parent::tearDown();
|
||||||
|
wp_cache_flush();
|
||||||
|
OrderHelper::toggle_cot( $this->cot_state );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @testDox get_orders should be able to return multiple orders of different types.
|
* @testDox get_orders should be able to return multiple orders of different types.
|
||||||
*/
|
*/
|
||||||
public function test_get_orders_with_multiple_order_type() {
|
public function test_get_orders_with_multiple_order_type() {
|
||||||
$order1 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_complex_wp_post_order();
|
$order1 = OrderHelper::create_complex_wp_post_order();
|
||||||
$order2 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_complex_wp_post_order();
|
$order2 = OrderHelper::create_complex_wp_post_order();
|
||||||
|
|
||||||
assert( $order1 > 0 );
|
assert( $order1 > 0 );
|
||||||
assert( $order2 > 0 );
|
assert( $order2 > 0 );
|
||||||
|
|
|
@ -11,11 +11,12 @@ class WC_Customer_Data_Store_Session_Test extends WC_Unit_Test_Case {
|
||||||
* @see https://github.com/woocommerce/woocommerce/issues/28759
|
* @see https://github.com/woocommerce/woocommerce/issues/28759
|
||||||
* @dataProvider provide_customers_with_different_addresses
|
* @dataProvider provide_customers_with_different_addresses
|
||||||
*
|
*
|
||||||
* @param WC_Customer $customer The customer object being tested.
|
* @param Closure $customer_closure The customer object being tested.
|
||||||
* @param bool $states_should_match If the billing and shipping states should match.
|
* @param bool $states_should_match If the billing and shipping states should match.
|
||||||
* @param bool $countries_should_match If the billing and shipping countries should match.
|
* @param bool $countries_should_match If the billing and shipping countries should match.
|
||||||
*/
|
*/
|
||||||
public function test_setting_default_address_fields( WC_Customer $customer, bool $states_should_match, bool $countries_should_match ) {
|
public function test_setting_default_address_fields( Closure $customer_closure, bool $states_should_match, bool $countries_should_match ) {
|
||||||
|
$customer = $customer_closure();
|
||||||
$session_data = new WC_Customer_Data_Store_Session();
|
$session_data = new WC_Customer_Data_Store_Session();
|
||||||
$session_data->read( $customer );
|
$session_data->read( $customer );
|
||||||
|
|
||||||
|
@ -46,66 +47,78 @@ class WC_Customer_Data_Store_Session_Test extends WC_Unit_Test_Case {
|
||||||
* @return array[]
|
* @return array[]
|
||||||
*/
|
*/
|
||||||
public function provide_customers_with_different_addresses() {
|
public function provide_customers_with_different_addresses() {
|
||||||
$has_billing_address_only = new WC_Customer();
|
$cust1_closure = function () {
|
||||||
$has_billing_address_only->set_email( 'wc-customer-test-01@test.user' );
|
$has_billing_address_only = new WC_Customer();
|
||||||
$has_billing_address_only->set_billing_address( '1234 Quality Lane' );
|
$has_billing_address_only->set_email( 'wc-customer-test-01@test.user' );
|
||||||
$has_billing_address_only->set_billing_city( 'Testville' );
|
$has_billing_address_only->set_billing_address( '1234 Quality Lane' );
|
||||||
$has_billing_address_only->set_billing_country( 'US' );
|
$has_billing_address_only->set_billing_city( 'Testville' );
|
||||||
$has_billing_address_only->set_billing_state( 'CA' );
|
$has_billing_address_only->set_billing_country( 'US' );
|
||||||
$has_billing_address_only->set_billing_postcode( '90123' );
|
$has_billing_address_only->set_billing_state( 'CA' );
|
||||||
$has_billing_address_only->save();
|
$has_billing_address_only->set_billing_postcode( '90123' );
|
||||||
|
$has_billing_address_only->save();
|
||||||
|
return $has_billing_address_only;
|
||||||
|
};
|
||||||
|
|
||||||
$separate_billing_and_shipping_state_and_country = new WC_Customer();
|
$cust2_closure = function () {
|
||||||
$separate_billing_and_shipping_state_and_country->set_email( 'wc-customer-test-02@test.user' );
|
$separate_billing_and_shipping_state_and_country = new WC_Customer();
|
||||||
$separate_billing_and_shipping_state_and_country->set_billing_address( '4567 Scenario Street' );
|
$separate_billing_and_shipping_state_and_country->set_email( 'wc-customer-test-02@test.user' );
|
||||||
$separate_billing_and_shipping_state_and_country->set_billing_city( 'Unitly' );
|
$separate_billing_and_shipping_state_and_country->set_billing_address( '4567 Scenario Street' );
|
||||||
$separate_billing_and_shipping_state_and_country->set_billing_country( 'UK' );
|
$separate_billing_and_shipping_state_and_country->set_billing_city( 'Unitly' );
|
||||||
$separate_billing_and_shipping_state_and_country->set_billing_state( 'Computershire' );
|
$separate_billing_and_shipping_state_and_country->set_billing_country( 'UK' );
|
||||||
$separate_billing_and_shipping_state_and_country->set_billing_postcode( 'ZX1 2PQ' );
|
$separate_billing_and_shipping_state_and_country->set_billing_state( 'Computershire' );
|
||||||
$separate_billing_and_shipping_state_and_country->set_shipping_address( '8901 Situation Court' );
|
$separate_billing_and_shipping_state_and_country->set_billing_postcode( 'ZX1 2PQ' );
|
||||||
$separate_billing_and_shipping_state_and_country->set_shipping_city( 'Endtoendly' );
|
$separate_billing_and_shipping_state_and_country->set_shipping_address( '8901 Situation Court' );
|
||||||
$separate_billing_and_shipping_state_and_country->set_shipping_country( 'CA' );
|
$separate_billing_and_shipping_state_and_country->set_shipping_city( 'Endtoendly' );
|
||||||
$separate_billing_and_shipping_state_and_country->set_shipping_state( 'BC' );
|
$separate_billing_and_shipping_state_and_country->set_shipping_country( 'CA' );
|
||||||
$separate_billing_and_shipping_state_and_country->set_shipping_postcode( 'A1B 2C3' );
|
$separate_billing_and_shipping_state_and_country->set_shipping_state( 'BC' );
|
||||||
$separate_billing_and_shipping_state_and_country->save();
|
$separate_billing_and_shipping_state_and_country->set_shipping_postcode( 'A1B 2C3' );
|
||||||
|
$separate_billing_and_shipping_state_and_country->save();
|
||||||
|
return $separate_billing_and_shipping_state_and_country;
|
||||||
|
};
|
||||||
|
|
||||||
$separate_billing_state_same_country = new WC_Customer();
|
$cust3_closure = function () {
|
||||||
$separate_billing_state_same_country->set_email( 'wc-customer-test-03@test.user' );
|
$separate_billing_state_same_country = new WC_Customer();
|
||||||
$separate_billing_state_same_country->set_billing_address( '4567 Scenario Street' );
|
$separate_billing_state_same_country->set_email( 'wc-customer-test-03@test.user' );
|
||||||
$separate_billing_state_same_country->set_billing_city( 'Unitly' );
|
$separate_billing_state_same_country->set_billing_address( '4567 Scenario Street' );
|
||||||
$separate_billing_state_same_country->set_billing_country( 'UK' );
|
$separate_billing_state_same_country->set_billing_city( 'Unitly' );
|
||||||
$separate_billing_state_same_country->set_billing_state( 'Computershire' );
|
$separate_billing_state_same_country->set_billing_country( 'UK' );
|
||||||
$separate_billing_state_same_country->set_billing_postcode( 'ZX1 2PQ' );
|
$separate_billing_state_same_country->set_billing_state( 'Computershire' );
|
||||||
$separate_billing_state_same_country->set_shipping_address( '8901 Situation Court' );
|
$separate_billing_state_same_country->set_billing_postcode( 'ZX1 2PQ' );
|
||||||
$separate_billing_state_same_country->set_shipping_city( 'Endtoendly' );
|
$separate_billing_state_same_country->set_shipping_address( '8901 Situation Court' );
|
||||||
$separate_billing_state_same_country->set_shipping_country( 'UK' );
|
$separate_billing_state_same_country->set_shipping_city( 'Endtoendly' );
|
||||||
$separate_billing_state_same_country->set_shipping_state( 'Byteshire' );
|
$separate_billing_state_same_country->set_shipping_country( 'UK' );
|
||||||
$separate_billing_state_same_country->set_shipping_postcode( 'RS1 2TU' );
|
$separate_billing_state_same_country->set_shipping_state( 'Byteshire' );
|
||||||
$separate_billing_state_same_country->save();
|
$separate_billing_state_same_country->set_shipping_postcode( 'RS1 2TU' );
|
||||||
|
$separate_billing_state_same_country->save();
|
||||||
|
return $separate_billing_state_same_country;
|
||||||
|
};
|
||||||
|
|
||||||
$shipping_address_is_effectively_empty = new WC_Customer();
|
$cust4_closure = function () {
|
||||||
$shipping_address_is_effectively_empty->set_email( 'wc-customer-test-04@test.user' );
|
$shipping_address_is_effectively_empty = new WC_Customer();
|
||||||
$shipping_address_is_effectively_empty->set_shipping_address( ' ' );
|
$shipping_address_is_effectively_empty->set_email( 'wc-customer-test-04@test.user' );
|
||||||
$shipping_address_is_effectively_empty->save();
|
$shipping_address_is_effectively_empty->set_shipping_address( ' ' );
|
||||||
|
$shipping_address_is_effectively_empty->save();
|
||||||
|
return $shipping_address_is_effectively_empty;
|
||||||
|
};
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
'has_billing_address_only' => array(
|
'has_billing_address_only' => array(
|
||||||
$has_billing_address_only,
|
$cust1_closure,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
),
|
),
|
||||||
'separate_billing_and_shipping_state_and_country' => array(
|
'separate_billing_and_shipping_state_and_country' => array(
|
||||||
$separate_billing_and_shipping_state_and_country,
|
$cust2_closure,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
),
|
),
|
||||||
'separate_billing_state_same_country' => array(
|
'separate_billing_state_same_country' => array(
|
||||||
$separate_billing_state_same_country,
|
$cust3_closure,
|
||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
),
|
),
|
||||||
'shipping_address_is_effectively_empty' => array(
|
'shipping_address_is_effectively_empty' => array(
|
||||||
$shipping_address_is_effectively_empty,
|
$cust4_closure,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,9 +1,40 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper;
|
||||||
|
use Automattic\WooCommerce\Utilities\OrderUtil;
|
||||||
|
|
||||||
|
//phpcs:disable Squiz.Classes.ClassFileName.NoMatch, Squiz.Classes.ValidClassName.NotCamelCaps -- Legacy class name.
|
||||||
/**
|
/**
|
||||||
* Class WC_Order_Data_Store_CPT_Test.
|
* Class WC_Order_Data_Store_CPT_Test.
|
||||||
*/
|
*/
|
||||||
class WC_Order_Data_Store_CPT_Test extends WC_Unit_Test_Case {
|
class WC_Order_Data_Store_CPT_Test extends WC_Unit_Test_Case {
|
||||||
|
/**
|
||||||
|
* Store the COT state before the test.
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
private $prev_cot_state;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store the COT state before the test.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setUp(): void {
|
||||||
|
parent::setUp();
|
||||||
|
$this->prev_cot_state = OrderUtil::custom_orders_table_usage_is_enabled();
|
||||||
|
OrderHelper::toggle_cot( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restore the COT state after the test.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function tearDown(): void {
|
||||||
|
OrderHelper::toggle_cot( $this->prev_cot_state );
|
||||||
|
parent::tearDown();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test that refund cache are invalidated correctly when refund is deleted.
|
* Test that refund cache are invalidated correctly when refund is deleted.
|
||||||
|
@ -131,7 +162,7 @@ class WC_Order_Data_Store_CPT_Test extends WC_Unit_Test_Case {
|
||||||
* Legacy getters and setters for props migrated from data stores should be set/reset properly.
|
* Legacy getters and setters for props migrated from data stores should be set/reset properly.
|
||||||
*/
|
*/
|
||||||
public function test_legacy_getters_setters() {
|
public function test_legacy_getters_setters() {
|
||||||
$order_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_complex_wp_post_order();
|
$order_id = OrderHelper::create_complex_wp_post_order();
|
||||||
$order = wc_get_order( $order_id );
|
$order = wc_get_order( $order_id );
|
||||||
$bool_props = array(
|
$bool_props = array(
|
||||||
'_download_permissions_granted' => 'download_permissions_granted',
|
'_download_permissions_granted' => 'download_permissions_granted',
|
||||||
|
|
|
@ -29,8 +29,8 @@ class WC_Gateway_Paypal_Test extends \WC_Unit_Test_Case {
|
||||||
$order = WC_Helper_Order::create_order();
|
$order = WC_Helper_Order::create_order();
|
||||||
$order->save();
|
$order->save();
|
||||||
|
|
||||||
update_post_meta( $order->get_id(), '_paypal_status', 'pending' );
|
$order->update_meta_data( '_paypal_status', 'pending' );
|
||||||
update_post_meta( $order->get_id(), '_transaction_id', $this->transaction_id_26960 );
|
$order->set_transaction_id( $this->transaction_id_26960 );
|
||||||
$order->set_payment_method( 'paypal' );
|
$order->set_payment_method( 'paypal' );
|
||||||
$order->save();
|
$order->save();
|
||||||
|
|
||||||
|
@ -56,8 +56,8 @@ class WC_Gateway_Paypal_Test extends \WC_Unit_Test_Case {
|
||||||
$order = WC_Helper_Order::create_order();
|
$order = WC_Helper_Order::create_order();
|
||||||
$order->save();
|
$order->save();
|
||||||
|
|
||||||
update_post_meta( $order->get_id(), '_paypal_status', 'pending' );
|
$order->update_meta_data( '_paypal_status', 'pending' );
|
||||||
update_post_meta( $order->get_id(), '_transaction_id', $this->transaction_id_26960 );
|
$order->set_transaction_id( $this->transaction_id_26960 );
|
||||||
$order->set_payment_method( 'paypal' );
|
$order->set_payment_method( 'paypal' );
|
||||||
$order->save();
|
$order->save();
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ use Automattic\WooCommerce\Internal\DataStores\Orders\OrdersTableDataStore;
|
||||||
use Automattic\WooCommerce\Internal\DataStores\Orders\OrdersTableQuery;
|
use Automattic\WooCommerce\Internal\DataStores\Orders\OrdersTableQuery;
|
||||||
use Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper;
|
use Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper;
|
||||||
use Automattic\WooCommerce\RestApi\UnitTests\HPOSToggleTrait;
|
use Automattic\WooCommerce\RestApi\UnitTests\HPOSToggleTrait;
|
||||||
|
use Automattic\WooCommerce\Utilities\OrderUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class OrdersTableDataStoreTests.
|
* Class OrdersTableDataStoreTests.
|
||||||
|
@ -37,6 +38,12 @@ class OrdersTableDataStoreTests extends WC_Unit_Test_Case {
|
||||||
*/
|
*/
|
||||||
private $cpt_data_store;
|
private $cpt_data_store;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether COT was enabled before the test.
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
private $cot_state;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes system under test.
|
* Initializes system under test.
|
||||||
*/
|
*/
|
||||||
|
@ -47,6 +54,7 @@ class OrdersTableDataStoreTests extends WC_Unit_Test_Case {
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
// Remove the Test Suite’s use of temporary tables https://wordpress.stackexchange.com/a/220308.
|
// Remove the Test Suite’s use of temporary tables https://wordpress.stackexchange.com/a/220308.
|
||||||
$this->setup_cot();
|
$this->setup_cot();
|
||||||
|
$this->cot_state = OrderUtil::custom_orders_table_usage_is_enabled();
|
||||||
$this->toggle_cot( false );
|
$this->toggle_cot( false );
|
||||||
$this->sut = wc_get_container()->get( OrdersTableDataStore::class );
|
$this->sut = wc_get_container()->get( OrdersTableDataStore::class );
|
||||||
$this->migrator = wc_get_container()->get( PostsToOrdersMigrationController::class );
|
$this->migrator = wc_get_container()->get( PostsToOrdersMigrationController::class );
|
||||||
|
@ -59,6 +67,7 @@ class OrdersTableDataStoreTests extends WC_Unit_Test_Case {
|
||||||
public function tearDown(): void {
|
public function tearDown(): void {
|
||||||
//phpcs:ignore WordPress.DateTime.RestrictedFunctions.timezone_change_date_default_timezone_set -- We need to change the timezone to test the date sync fields.
|
//phpcs:ignore WordPress.DateTime.RestrictedFunctions.timezone_change_date_default_timezone_set -- We need to change the timezone to test the date sync fields.
|
||||||
update_option( 'timezone_string', $this->original_time_zone );
|
update_option( 'timezone_string', $this->original_time_zone );
|
||||||
|
$this->toggle_cot( $this->cot_state );
|
||||||
$this->clean_up_cot_setup();
|
$this->clean_up_cot_setup();
|
||||||
parent::tearDown();
|
parent::tearDown();
|
||||||
}
|
}
|
||||||
|
@ -205,6 +214,7 @@ class OrdersTableDataStoreTests extends WC_Unit_Test_Case {
|
||||||
wp_cache_flush();
|
wp_cache_flush();
|
||||||
$order = new WC_Order();
|
$order = new WC_Order();
|
||||||
$order->set_id( $post_order->get_id() );
|
$order->set_id( $post_order->get_id() );
|
||||||
|
$this->toggle_cot( true );
|
||||||
$this->switch_data_store( $order, $this->sut );
|
$this->switch_data_store( $order, $this->sut );
|
||||||
$this->sut->read( $order );
|
$this->sut->read( $order );
|
||||||
|
|
||||||
|
@ -239,6 +249,7 @@ class OrdersTableDataStoreTests extends WC_Unit_Test_Case {
|
||||||
foreach ( $datastore_updates as $prop => $value ) {
|
foreach ( $datastore_updates as $prop => $value ) {
|
||||||
$this->assertEquals( $value, $this->sut->{"get_$prop"}( $order ), "Unable to match prop $prop" );
|
$this->assertEquals( $value, $this->sut->{"get_$prop"}( $order ), "Unable to match prop $prop" );
|
||||||
}
|
}
|
||||||
|
$this->toggle_cot( false );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1767,6 +1778,7 @@ class OrdersTableDataStoreTests extends WC_Unit_Test_Case {
|
||||||
* Ideally, this should be possible only from getters and setters for objects, but for backward compatibility, earlier ways are also supported.
|
* Ideally, this should be possible only from getters and setters for objects, but for backward compatibility, earlier ways are also supported.
|
||||||
*/
|
*/
|
||||||
public function test_internal_ds_getters_and_setters() {
|
public function test_internal_ds_getters_and_setters() {
|
||||||
|
$this->toggle_cot( true );
|
||||||
$props_to_test = array(
|
$props_to_test = array(
|
||||||
'_download_permissions_granted',
|
'_download_permissions_granted',
|
||||||
'_recorded_sales',
|
'_recorded_sales',
|
||||||
|
@ -1813,6 +1825,7 @@ class OrdersTableDataStoreTests extends WC_Unit_Test_Case {
|
||||||
$order->save();
|
$order->save();
|
||||||
}
|
}
|
||||||
$this->assert_get_prop_via_ds_object_and_metadata( $props_to_test, $order, false, $ds_getter_setter_names );
|
$this->assert_get_prop_via_ds_object_and_metadata( $props_to_test, $order, false, $ds_getter_setter_names );
|
||||||
|
$this->toggle_cot( false );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1855,7 +1868,8 @@ class OrdersTableDataStoreTests extends WC_Unit_Test_Case {
|
||||||
* @testDox Legacy getters and setters for props migrated from data stores should be set/reset properly.
|
* @testDox Legacy getters and setters for props migrated from data stores should be set/reset properly.
|
||||||
*/
|
*/
|
||||||
public function test_legacy_getters_setters() {
|
public function test_legacy_getters_setters() {
|
||||||
$order_id = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper::create_complex_wp_post_order();
|
$this->toggle_cot( true );
|
||||||
|
$order_id = OrderHelper::create_complex_data_store_order( $this->sut );
|
||||||
$order = wc_get_order( $order_id );
|
$order = wc_get_order( $order_id );
|
||||||
$this->switch_data_store( $order, $this->sut );
|
$this->switch_data_store( $order, $this->sut );
|
||||||
$bool_props = array(
|
$bool_props = array(
|
||||||
|
@ -1887,7 +1901,7 @@ class OrdersTableDataStoreTests extends WC_Unit_Test_Case {
|
||||||
$this->assert_props_value_via_data_store( $order, $bool_props, true );
|
$this->assert_props_value_via_data_store( $order, $bool_props, true );
|
||||||
|
|
||||||
$this->assert_props_value_via_order_object( $order, $bool_props, true );
|
$this->assert_props_value_via_order_object( $order, $bool_props, true );
|
||||||
|
$this->toggle_cot( false );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1984,8 +1998,9 @@ class OrdersTableDataStoreTests extends WC_Unit_Test_Case {
|
||||||
*/
|
*/
|
||||||
public function test_read_multiple_dont_sync_again_for_same_order() {
|
public function test_read_multiple_dont_sync_again_for_same_order() {
|
||||||
$this->toggle_cot( true );
|
$this->toggle_cot( true );
|
||||||
$this->enable_cot_sync();
|
|
||||||
$order = $this->create_complex_cot_order();
|
$order = $this->create_complex_cot_order();
|
||||||
|
$this->sut->backfill_post_record( $order );
|
||||||
|
$this->enable_cot_sync();
|
||||||
|
|
||||||
$order_id = $order->get_id();
|
$order_id = $order->get_id();
|
||||||
|
|
||||||
|
@ -1999,6 +2014,7 @@ class OrdersTableDataStoreTests extends WC_Unit_Test_Case {
|
||||||
$this->assertTrue( $should_sync_callable->call( $this->sut, $order ) );
|
$this->assertTrue( $should_sync_callable->call( $this->sut, $order ) );
|
||||||
$this->sut->read_multiple( $orders );
|
$this->sut->read_multiple( $orders );
|
||||||
$this->assertFalse( $should_sync_callable->call( $this->sut, $order ) );
|
$this->assertFalse( $should_sync_callable->call( $this->sut, $order ) );
|
||||||
|
$this->toggle_cot( false );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue