Update biling and shipping address indexes. (#35121)

* Update biling and shipping address indexes.

* Add changelog.

* Code standard fixes.

* Add unit test for search after update.

* PHPCS fixes.
This commit is contained in:
Vedanshu Jain 2022-10-19 16:21:42 +05:30 committed by GitHub
parent a2076f59a5
commit 5b6ddf0b88
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 89 additions and 35 deletions

View File

@ -0,0 +1,4 @@
Significance: patch
Type: fix
Add billing and shipping address indexes on order update.

View File

@ -1008,8 +1008,8 @@ WHERE
* @return bool Whether the order should be synced. * @return bool Whether the order should be synced.
*/ */
private function should_sync_order( \WC_Abstract_Order $order ) : bool { private function should_sync_order( \WC_Abstract_Order $order ) : bool {
$draft_order = in_array( $order->get_status(), array( 'draft', 'auto-draft' ) ); $draft_order = in_array( $order->get_status(), array( 'draft', 'auto-draft' ), true );
$already_synced = in_array( $order->get_id(), self::$reading_order_ids ); $already_synced = in_array( $order->get_id(), self::$reading_order_ids, true );
return ! $draft_order && ! $already_synced; return ! $draft_order && ! $already_synced;
} }
@ -1017,8 +1017,8 @@ WHERE
* Helper method to initialize order object from DB data. * Helper method to initialize order object from DB data.
* *
* @param \WC_Abstract_Order $order Order object. * @param \WC_Abstract_Order $order Order object.
* @param int $order_id Order ID. * @param int $order_id Order ID.
* @param \stdClass $order_data Order data fetched from DB. * @param \stdClass $order_data Order data fetched from DB.
* *
* @return void * @return void
*/ */
@ -1544,6 +1544,9 @@ FROM $order_meta_table
throw new \Exception( sprintf( __( 'Could not persist order to database table "%s".', 'woocommerce' ), $update['table'] ) ); throw new \Exception( sprintf( __( 'Could not persist order to database table "%s".', 'woocommerce' ), $update['table'] ) );
} }
} }
$changes = $order->get_changes();
$this->update_address_index_meta( $order, $changes );
} }
/** /**
@ -2025,7 +2028,17 @@ FROM $order_meta_table
*/ */
public function update_order_meta( &$order ) { public function update_order_meta( &$order ) {
$changes = $order->get_changes(); $changes = $order->get_changes();
$this->update_address_index_meta( $order, $changes );
}
/**
* Helper function to update billing and shipping address metadata.
* @param \WC_Abstract_Order $order Order Object
* @param array $changes Array of changes.
*
* @return void
*/
private function update_address_index_meta( $order, $changes ) {
// If address changed, store concatenated version to make searches faster. // If address changed, store concatenated version to make searches faster.
foreach ( array( 'billing', 'shipping' ) as $address_type ) { foreach ( array( 'billing', 'shipping' ) as $address_type ) {
if ( isset( $changes[ $address_type ] ) ) { if ( isset( $changes[ $address_type ] ) ) {

View File

@ -187,10 +187,12 @@ class OrdersTableDataStoreTests extends WC_Unit_Test_Case {
'status' => 'on-hold', 'status' => 'on-hold',
'cart_hash' => 'YET-ANOTHER-CART-HASH', 'cart_hash' => 'YET-ANOTHER-CART-HASH',
); );
static $datastore_updates = array( static $datastore_updates = array(
'email_sent' => true, 'email_sent' => true,
'order_stock_reduced' => true, 'order_stock_reduced' => true,
); );
static $meta_to_update = array( static $meta_to_update = array(
'my_meta_key' => array( 'my', 'custom', 'meta' ), 'my_meta_key' => array( 'my', 'custom', 'meta' ),
); );
@ -1003,10 +1005,14 @@ class OrdersTableDataStoreTests extends WC_Unit_Test_Case {
* @testDox Test `get_unpaid_orders()`. * @testDox Test `get_unpaid_orders()`.
*/ */
public function test_get_unpaid_orders(): void { public function test_get_unpaid_orders(): void {
// phpcs:ignore WordPress.DateTime.CurrentTimeTimestamp.Requested -- Intentional usage since timezone is changed for this file.
$now = current_time( 'timestamp' ); $now = current_time( 'timestamp' );
// Create a few orders. // Create a few orders.
$orders_by_status = array( 'wc-completed' => 3, 'wc-pending' => 2 ); $orders_by_status = array(
'wc-completed' => 3,
'wc-pending' => 2,
);
$unpaid_ids = array(); $unpaid_ids = array();
foreach ( $orders_by_status as $order_status => $order_count ) { foreach ( $orders_by_status as $order_status => $order_count ) {
foreach ( range( 1, $order_count ) as $_ ) { foreach ( range( 1, $order_count ) as $_ ) {
@ -1206,7 +1212,7 @@ class OrdersTableDataStoreTests extends WC_Unit_Test_Case {
/** /**
* Helper method to allow switching data stores. * Helper method to allow switching data stores.
* *
* @param WC_Order $order Order object. * @param WC_Order $order Order object.
* @param WC_Data_Store $data_store Data store object to switch order to. * @param WC_Data_Store $data_store Data store object to switch order to.
*/ */
private function switch_data_store( $order, $data_store ) { private function switch_data_store( $order, $data_store ) {
@ -1228,6 +1234,7 @@ class OrdersTableDataStoreTests extends WC_Unit_Test_Case {
$order_1 = new WC_Order(); $order_1 = new WC_Order();
$order_1->set_billing_city( 'Fort Quality' ); $order_1->set_billing_city( 'Fort Quality' );
$this->switch_data_store( $order_1, $this->sut ); $this->switch_data_store( $order_1, $this->sut );
$this->disable_cot_sync();
$order_1->save(); $order_1->save();
$product = new WC_Product_Simple(); $product = new WC_Product_Simple();
@ -1257,14 +1264,43 @@ class OrdersTableDataStoreTests extends WC_Unit_Test_Case {
); );
// Order 1's billing address references "Quality" and so does one of Order 2's order items. // Order 1's billing address references "Quality" and so does one of Order 2's order items.
$query = new OrdersTableQuery( array( 's' => 'Quality' ) ); $query = new OrdersTableQuery( array( 's' => 'Quality' ) );
$orders_array = $query->orders;
sort( $orders_array );
$this->assertEquals( $this->assertEquals(
array( $order_1->get_id(), $order_2->get_id() ), array( $order_1->get_id(), $order_2->get_id() ),
$query->orders, $orders_array,
'Search terms match against address data as well as order item names.' 'Search terms match against address data as well as order item names.'
); );
} }
/**
* @testDox Ensure search works as expected on updated orders.
*/
public function test_cot_query_search_update() {
$order_1 = new WC_Order();
$this->switch_data_store( $order_1, $this->sut );
$this->disable_cot_sync();
$order_1->save();
$order_1->set_billing_city( 'New Cybertron' );
$order_1->save();
$order_2 = new WC_Order();
$this->switch_data_store( $order_2, $this->sut );
$order_2->save();
$order_2->set_billing_city( 'Gigantian City' );
$order_2->save();
$query = new OrdersTableQuery( array( 's' => 'Cybertron' ) );
$this->assertEquals(
array( $order_1->get_id() ),
$query->orders,
'Search terms match against updated address data.'
);
}
/** /**
* Test methods get_total_tax_refunded and get_total_shipping_refunded. * Test methods get_total_tax_refunded and get_total_shipping_refunded.
*/ */
@ -1374,7 +1410,7 @@ class OrdersTableDataStoreTests extends WC_Unit_Test_Case {
array( array(
'field' => 'order_key', 'field' => 'order_key',
'value' => 'planck_1', 'value' => 'planck_1',
) ),
); );
$query = new OrdersTableQuery( array( 'field_query' => $field_query ) ); $query = new OrdersTableQuery( array( 'field_query' => $field_query ) );
$this->assertEqualsCanonicalizing( array( $order_ids[0], $order_ids[1] ), $query->orders ); $this->assertEqualsCanonicalizing( array( $order_ids[0], $order_ids[1] ), $query->orders );
@ -1408,8 +1444,8 @@ class OrdersTableDataStoreTests extends WC_Unit_Test_Case {
array( array(
'field' => 'order_key', 'field' => 'order_key',
'value' => '[0-9]$', 'value' => '[0-9]$',
'compare' => 'RLIKE' 'compare' => 'RLIKE',
) ),
); );
$query = new OrdersTableQuery( array( 'field_query' => $field_query ) ); $query = new OrdersTableQuery( array( 'field_query' => $field_query ) );
$this->assertEqualsCanonicalizing( $order_ids, $query->orders ); $this->assertEqualsCanonicalizing( $order_ids, $query->orders );
@ -1419,8 +1455,8 @@ class OrdersTableDataStoreTests extends WC_Unit_Test_Case {
array( array(
'field' => 'order_key', 'field' => 'order_key',
'value' => '[^0-9]$', 'value' => '[^0-9]$',
'compare' => 'NOT RLIKE' 'compare' => 'NOT RLIKE',
) ),
); );
$query = new OrdersTableQuery( array( 'field_query' => $field_query ) ); $query = new OrdersTableQuery( array( 'field_query' => $field_query ) );
$this->assertCount( 0, $query->posts ); $this->assertCount( 0, $query->posts );
@ -1432,7 +1468,7 @@ class OrdersTableDataStoreTests extends WC_Unit_Test_Case {
'value' => '10.0', 'value' => '10.0',
'compare' => '<=', 'compare' => '<=',
'type' => 'NUMERIC', 'type' => 'NUMERIC',
) ),
); );
$query = new OrdersTableQuery( array( 'field_query' => $field_query ) ); $query = new OrdersTableQuery( array( 'field_query' => $field_query ) );
$this->assertEqualsCanonicalizing( array( $order_ids[2] ), $query->orders ); $this->assertEqualsCanonicalizing( array( $order_ids[2] ), $query->orders );
@ -1442,7 +1478,7 @@ class OrdersTableDataStoreTests extends WC_Unit_Test_Case {
array( array(
'field' => 'non_existing_field', 'field' => 'non_existing_field',
'value' => 'any-value', 'value' => 'any-value',
) ),
); );
$query = new OrdersTableQuery( array( 'field_query' => $field_query ) ); $query = new OrdersTableQuery( array( 'field_query' => $field_query ) );
$this->assertCount( 0, $query->posts ); $this->assertCount( 0, $query->posts );
@ -1453,7 +1489,7 @@ class OrdersTableDataStoreTests extends WC_Unit_Test_Case {
'field' => 'wc_orders.total_amount', 'field' => 'wc_orders.total_amount',
'value' => 5.5, 'value' => 5.5,
'compare' => 'IN', 'compare' => 'IN',
) ),
); );
$query = new OrdersTableQuery( array( 'field_query' => $field_query ) ); $query = new OrdersTableQuery( array( 'field_query' => $field_query ) );
$this->assertCount( 0, $query->posts ); $this->assertCount( 0, $query->posts );
@ -1464,7 +1500,7 @@ class OrdersTableDataStoreTests extends WC_Unit_Test_Case {
'field' => 'wc_orders.total_amount', 'field' => 'wc_orders.total_amount',
'value' => 10.0, 'value' => 10.0,
'compare' => 'EXOSTS', 'compare' => 'EXOSTS',
) ),
); );
$query = new OrdersTableQuery( array( 'field_query' => $field_query ) ); $query = new OrdersTableQuery( array( 'field_query' => $field_query ) );
$this->assertCount( 0, $query->posts ); $this->assertCount( 0, $query->posts );
@ -1475,7 +1511,7 @@ class OrdersTableDataStoreTests extends WC_Unit_Test_Case {
'field' => 'total', 'field' => 'total',
'compare' => 'BETWEEN', 'compare' => 'BETWEEN',
'value' => 10.0, 'value' => 10.0,
) ),
); );
$query = new OrdersTableQuery( array( 'field_query' => $field_query ) ); $query = new OrdersTableQuery( array( 'field_query' => $field_query ) );
$this->assertCount( 0, $query->posts ); $this->assertCount( 0, $query->posts );
@ -1486,12 +1522,12 @@ class OrdersTableDataStoreTests extends WC_Unit_Test_Case {
'field' => 'total', 'field' => 'total',
'compare' => 'NOT BETWEEN', 'compare' => 'NOT BETWEEN',
'value' => array( 1.0 ), 'value' => array( 1.0 ),
) ),
); );
$query = new OrdersTableQuery( array( 'field_query' => $field_query ) ); $query = new OrdersTableQuery( array( 'field_query' => $field_query ) );
$this->assertCount( 0, $query->posts ); $this->assertCount( 0, $query->posts );
// Test combinations of field_query with regular query args: // Test combinations of field_query with regular query args.
$args = array( $args = array(
'id' => array( $order_ids[0], $order_ids[1] ), 'id' => array( $order_ids[0], $order_ids[1] ),
); );
@ -1506,7 +1542,7 @@ class OrdersTableDataStoreTests extends WC_Unit_Test_Case {
array( array(
'field' => 'id', 'field' => 'id',
'value' => $order_ids[1], 'value' => $order_ids[1],
) ),
); );
$query = new OrdersTableQuery( $args ); $query = new OrdersTableQuery( $args );
$this->assertEqualsCanonicalizing( array( $order_ids[1] ), $query->orders ); $this->assertEqualsCanonicalizing( array( $order_ids[1] ), $query->orders );
@ -1520,7 +1556,7 @@ class OrdersTableDataStoreTests extends WC_Unit_Test_Case {
$query = new OrdersTableQuery( $args ); $query = new OrdersTableQuery( $args );
$this->assertCount( 0, $query->orders ); $this->assertCount( 0, $query->orders );
// Now a more complex query with meta_query and date_query: // Now a more complex query with meta_query and date_query.
$args = array( $args = array(
'shipping_address' => 'The Universe', 'shipping_address' => 'The Universe',
'field_query' => array( 'field_query' => array(
@ -1537,12 +1573,13 @@ class OrdersTableDataStoreTests extends WC_Unit_Test_Case {
$this->assertEqualsCanonicalizing( array( $order_ids[0], $order_ids[1] ), $query->orders ); $this->assertEqualsCanonicalizing( array( $order_ids[0], $order_ids[1] ), $query->orders );
// ... but only Planck is more than 80 years old. // ... but only Planck is more than 80 years old.
// phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- Intentional usage for test.
$args['meta_query'] = array( $args['meta_query'] = array(
array( array(
'key' => 'customer_age', 'key' => 'customer_age',
'value' => 80, 'value' => 80,
'compare' => '>=' 'compare' => '>=',
) ),
); );
$query = new OrdersTableQuery( $args ); $query = new OrdersTableQuery( $args );
$this->assertEqualsCanonicalizing( array( $order_ids[1] ), $query->orders ); $this->assertEqualsCanonicalizing( array( $order_ids[1] ), $query->orders );
@ -1604,10 +1641,10 @@ class OrdersTableDataStoreTests extends WC_Unit_Test_Case {
/** /**
* Helper method to assert props are set. * Helper method to assert props are set.
* *
* @param array $props List of props to test. * @param array $props List of props to test.
* @param WC_Order $order Order object. * @param WC_Order $order Order object.
* @param mixed $value Value to assert. * @param mixed $value Value to assert.
* @param array $ds_getter_setter_names List of props with custom getter/setter names. * @param array $ds_getter_setter_names List of props with custom getter/setter names.
*/ */
private function assert_get_prop_via_ds_object_and_metadata( array $props, WC_Order $order, $value, array $ds_getter_setter_names ) { private function assert_get_prop_via_ds_object_and_metadata( array $props, WC_Order $order, $value, array $ds_getter_setter_names ) {
wp_cache_flush(); wp_cache_flush();
@ -1680,8 +1717,8 @@ class OrdersTableDataStoreTests extends WC_Unit_Test_Case {
* Helper function to set prop via data store. * Helper function to set prop via data store.
* *
* @param WC_Order $order Order object. * @param WC_Order $order Order object.
* @param array $props List of props and their setter names. * @param array $props List of props and their setter names.
* @param mixed $value value to set. * @param mixed $value value to set.
*/ */
private function set_props_via_data_store( $order, $props, $value ) { private function set_props_via_data_store( $order, $props, $value ) {
foreach ( $props as $meta_key_name => $prop_name ) { foreach ( $props as $meta_key_name => $prop_name ) {
@ -1693,8 +1730,8 @@ class OrdersTableDataStoreTests extends WC_Unit_Test_Case {
* Helper function to set prop value via object. * Helper function to set prop value via object.
* *
* @param WC_Order $order Order object. * @param WC_Order $order Order object.
* @param array $props List of props and their setter names. * @param array $props List of props and their setter names.
* @param mixed $value value to set. * @param mixed $value value to set.
*/ */
private function set_props_via_order_object( $order, $props, $value ) { private function set_props_via_order_object( $order, $props, $value ) {
foreach ( $props as $meta_key_name => $prop_name ) { foreach ( $props as $meta_key_name => $prop_name ) {
@ -1707,8 +1744,8 @@ class OrdersTableDataStoreTests extends WC_Unit_Test_Case {
* Helper function to assert prop value via data store. * Helper function to assert prop value via data store.
* *
* @param WC_Order $order Order object. * @param WC_Order $order Order object.
* @param array $props List of props and their getter names. * @param array $props List of props and their getter names.
* @param mixed $value value to assert. * @param mixed $value value to assert.
*/ */
private function assert_props_value_via_data_store( $order, $props, $value ) { private function assert_props_value_via_data_store( $order, $props, $value ) {
foreach ( $props as $meta_key_name => $prop_name ) { foreach ( $props as $meta_key_name => $prop_name ) {
@ -1720,8 +1757,8 @@ class OrdersTableDataStoreTests extends WC_Unit_Test_Case {
* Helper function to assert prop value via order object. * Helper function to assert prop value via order object.
* *
* @param WC_Order $order Order object. * @param WC_Order $order Order object.
* @param array $props List of props and their getter names. * @param array $props List of props and their getter names.
* @param mixed $value value to assert. * @param mixed $value value to assert.
*/ */
private function assert_props_value_via_order_object( $order, $props, $value ) { private function assert_props_value_via_order_object( $order, $props, $value ) {
foreach ( $props as $meta_key_name => $prop_name ) { foreach ( $props as $meta_key_name => $prop_name ) {