From b068ade7c61562e1d1ecba544aa7038e803a0dbc Mon Sep 17 00:00:00 2001 From: Nestor Soriano Date: Fri, 19 Nov 2021 11:36:19 +0100 Subject: [PATCH] Create and activate product attributes lookup table in data migration Until now the product attributes lookup table had to be created and its usage had to be activated manually, via the tools page. This commit does the following: 1. Remove the tools to create and delete the table (but keeps the tool to regenerate the table data for one or for all the products) 2. Creates a data migration that triggers the table creation and filling (unless the table already existed) for Woo 6.1 3. After the migration finishes, activates the table usage for product filtering (site admin can still disable it via Settings - Products - Advanced) --- .../woocommerce/includes/class-wc-install.php | 12 ++- .../includes/wc-update-functions.php | 29 ++++++- .../DataRegenerator.php | 86 +++++-------------- .../DataRegeneratorTest.php | 4 +- .../LookupDataStoreTest.php | 2 - 5 files changed, 60 insertions(+), 73 deletions(-) diff --git a/plugins/woocommerce/includes/class-wc-install.php b/plugins/woocommerce/includes/class-wc-install.php index da64bb85fdd..62811c42081 100644 --- a/plugins/woocommerce/includes/class-wc-install.php +++ b/plugins/woocommerce/includes/class-wc-install.php @@ -169,6 +169,10 @@ class WC_Install { 'wc_update_600_migrate_rate_limit_options', 'wc_update_600_db_version', ), + '6.1.0' => array( + 'wc_create_product_attributes_lookup_table', + 'wc_update_610_db_version', + ), ); /** @@ -571,22 +575,22 @@ class WC_Install { $pages = apply_filters( 'woocommerce_create_pages', array( - 'shop' => array( + 'shop' => array( 'name' => _x( 'shop', 'Page slug', 'woocommerce' ), 'title' => _x( 'Shop', 'Page title', 'woocommerce' ), 'content' => '', ), - 'cart' => array( + 'cart' => array( 'name' => _x( 'cart', 'Page slug', 'woocommerce' ), 'title' => _x( 'Cart', 'Page title', 'woocommerce' ), 'content' => '[' . apply_filters( 'woocommerce_cart_shortcode_tag', 'woocommerce_cart' ) . ']', ), - 'checkout' => array( + 'checkout' => array( 'name' => _x( 'checkout', 'Page slug', 'woocommerce' ), 'title' => _x( 'Checkout', 'Page title', 'woocommerce' ), 'content' => '[' . apply_filters( 'woocommerce_checkout_shortcode_tag', 'woocommerce_checkout' ) . ']', ), - 'myaccount' => array( + 'myaccount' => array( 'name' => _x( 'my-account', 'Page slug', 'woocommerce' ), 'title' => _x( 'My account', 'Page title', 'woocommerce' ), 'content' => '[' . apply_filters( 'woocommerce_my_account_shortcode_tag', 'woocommerce_my_account' ) . ']', diff --git a/plugins/woocommerce/includes/wc-update-functions.php b/plugins/woocommerce/includes/wc-update-functions.php index a845efd3a23..1a27c786f37 100644 --- a/plugins/woocommerce/includes/wc-update-functions.php +++ b/plugins/woocommerce/includes/wc-update-functions.php @@ -11,6 +11,8 @@ defined( 'ABSPATH' ) || exit; use Automattic\WooCommerce\Internal\AssignDefaultCategory; +use Automattic\WooCommerce\Internal\ProductAttributesLookup\DataRegenerator; +use Automattic\WooCommerce\Internal\ProductAttributesLookup\LookupDataStore; /** * Update file paths for 2.0 @@ -2306,7 +2308,7 @@ function wc_update_560_db_version() { function wc_update_600_migrate_rate_limit_options() { global $wpdb; - $rate_limits = $wpdb->get_results( + $rate_limits = $wpdb->get_results( " SELECT option_name, option_value FROM $wpdb->options @@ -2335,3 +2337,28 @@ function wc_update_600_migrate_rate_limit_options() { function wc_update_600_db_version() { WC_Install::update_db_version( '6.0.0' ); } + +/** + * Create the product attributes lookup table and initiate its filling, + * unless the table had been already created manually (via the tools page). + * + * @return false Always false, since the LookupDataStore class handles all the data filling process. + */ +function wc_create_product_attributes_lookup_table() { + $data_store = wc_get_container()->get( LookupDataStore::class ); + if ( $data_store->check_lookup_table_exists() ) { + return false; + } + + $data_regenerator = wc_get_container()->get( DataRegenerator::class ); + $data_regenerator->initiate_regeneration(); + return false; +} + +/** + * + * Update DB version to 6.1.0. + */ +function wc_update_610_db_version() { + WC_Install::update_db_version( '6.1.0' ); +} diff --git a/plugins/woocommerce/src/Internal/ProductAttributesLookup/DataRegenerator.php b/plugins/woocommerce/src/Internal/ProductAttributesLookup/DataRegenerator.php index 5f06e5298fb..fca68226c66 100644 --- a/plugins/woocommerce/src/Internal/ProductAttributesLookup/DataRegenerator.php +++ b/plugins/woocommerce/src/Internal/ProductAttributesLookup/DataRegenerator.php @@ -21,7 +21,7 @@ defined( 'ABSPATH' ) || exit; * the data store classes) whenever a product is created/updated. * * Additionally, after the regeneration is completed a 'woocommerce_attribute_lookup_enabled' option - * with a value of 'no' will have been created. + * with a value of 'yes' will have been created, thus effectively enabling the table usage. * * This class also adds two entries to the Status - Tools menu: one for manually regenerating the table contents, * and another one for enabling or disabling the actual lookup table usage. @@ -84,14 +84,8 @@ class DataRegenerator { * deletes the lookup table and related options if they exist, * then it creates the table and runs the first step of the regeneration process. * - * This is the method that should be used as a callback for a data regeneration in wc-update-functions, e.g.: - * - * function wc_update_XX_regenerate_product_attributes_lookup_table() { - * wc_get_container()->get(DataRegenerator::class)->initiate_regeneration(); - * return false; - * } - * - * (Note how we are returning "false" since the class handles the step scheduling by itself). + * This method is intended ONLY to be used as a callback for a db update in wc-update-functions, + * regeneration triggered from the tools page will use initiate_regeneration_from_tools_page instead. */ public function initiate_regeneration() { $this->enable_or_disable_lookup_table_usage( false ); @@ -107,12 +101,8 @@ class DataRegenerator { /** * Delete all the existing data related to the lookup table, including the table itself. - * - * Shortcut to run this method in case the debug tools UI isn't available or for quick debugging: - * - * wp eval "wc_get_container()->get(Automattic\WooCommerce\Internal\ProductAttributesLookup\DataRegenerator::class)->delete_all_attributes_lookup_data();" */ - public function delete_all_attributes_lookup_data() { + private function delete_all_attributes_lookup_data() { global $wpdb; delete_option( 'woocommerce_attribute_lookup_enabled' ); @@ -244,7 +234,7 @@ CREATE TABLE ' . $this->lookup_table_name . '( private function finalize_regeneration() { delete_option( 'woocommerce_attribute_lookup_last_product_id_to_process' ); delete_option( 'woocommerce_attribute_lookup_last_products_page_processed' ); - update_option( 'woocommerce_attribute_lookup_enabled', 'no' ); + update_option( 'woocommerce_attribute_lookup_enabled', 'yes' ); $this->data_store->unset_regeneration_in_progress_flag(); } @@ -255,42 +245,29 @@ CREATE TABLE ' . $this->lookup_table_name . '( * @return array The tools array with the entry added. */ private function add_initiate_regeneration_entry_to_tools_array( array $tools_array ) { - $lookup_table_exists = $this->data_store->check_lookup_table_exists(); - $generation_is_in_progress = $this->data_store->regeneration_is_in_progress(); - - // Regenerate table. - - if ( $lookup_table_exists ) { - $generate_item_name = __( 'Regenerate the product attributes lookup table', 'woocommerce' ); - $generate_item_desc = __( 'This tool will regenerate the product attributes lookup table data from existing product(s) data. This process may take a while.', 'woocommerce' ); - $generate_item_return = __( 'Product attributes lookup table data is regenerating', 'woocommerce' ); - $generate_item_button = __( 'Regenerate', 'woocommerce' ); - } else { - $generate_item_name = __( 'Create and fill product attributes lookup table', 'woocommerce' ); - $generate_item_desc = __( 'This tool will create the product attributes lookup table data and fill it with existing products data. This process may take a while.', 'woocommerce' ); - $generate_item_return = __( 'Product attributes lookup table is being filled', 'woocommerce' ); - $generate_item_button = __( 'Create', 'woocommerce' ); + if ( ! $this->data_store->check_lookup_table_exists() ) { + return $tools_array; } - $entry = array( - 'name' => $generate_item_name, - 'desc' => $generate_item_desc, - 'requires_refresh' => true, - 'callback' => function() use ( $generate_item_return ) { - $this->initiate_regeneration_from_tools_page(); - return $generate_item_return; - }, - ); + $generation_is_in_progress = $this->data_store->regeneration_is_in_progress(); - if ( $lookup_table_exists ) { - $entry['selector'] = array( + $entry = array( + 'name' => __( 'Regenerate the product attributes lookup table', 'woocommerce' ), + 'desc' => __( 'This tool will regenerate the product attributes lookup table data from existing product(s) data. This process may take a while.', 'woocommerce' ), + 'requires_refresh' => true, + 'callback' => function() { + $this->initiate_regeneration_from_tools_page(); + return __( 'Product attributes lookup table data is regenerating', 'woocommerce' ); + + }, + 'selector' => array( 'description' => __( 'Select a product to regenerate the data for, or leave empty for a full table regeneration:', 'woocommerce' ), 'class' => 'wc-product-search', 'search_action' => 'woocommerce_json_search_products', 'name' => 'regenerate_product_attribute_lookup_data_product_id', 'placeholder' => esc_attr__( 'Search for a product…', 'woocommerce' ), - ); - } + ), + ); if ( $generation_is_in_progress ) { $entry['button'] = sprintf( @@ -300,31 +277,12 @@ CREATE TABLE ' . $this->lookup_table_name . '( ); $entry['disabled'] = true; } else { - $entry['button'] = $generate_item_button; + $entry['button'] = __( 'Regenerate', 'woocommerce' ); + } $tools_array['regenerate_product_attributes_lookup_table'] = $entry; - if ( $lookup_table_exists ) { - - // Delete the table. - - $tools_array['delete_product_attributes_lookup_table'] = array( - 'name' => __( 'Delete the product attributes lookup table', 'woocommerce' ), - 'desc' => sprintf( - '%1$s %2$s', - __( 'Note:', 'woocommerce' ), - __( 'This will delete the product attributes lookup table. You can create it again with the "Create and fill product attributes lookup table" tool.', 'woocommerce' ) - ), - 'button' => __( 'Delete', 'woocommerce' ), - 'requires_refresh' => true, - 'callback' => function () { - $this->delete_all_attributes_lookup_data(); - return __( 'Product attributes lookup table has been deleted.', 'woocommerce' ); - }, - ); - } - return $tools_array; } diff --git a/plugins/woocommerce/tests/php/src/Internal/ProductAttributesLookup/DataRegeneratorTest.php b/plugins/woocommerce/tests/php/src/Internal/ProductAttributesLookup/DataRegeneratorTest.php index 2a4ccfce1f3..ee9ff63ce8d 100644 --- a/plugins/woocommerce/tests/php/src/Internal/ProductAttributesLookup/DataRegeneratorTest.php +++ b/plugins/woocommerce/tests/php/src/Internal/ProductAttributesLookup/DataRegeneratorTest.php @@ -157,7 +157,7 @@ class DataRegeneratorTest extends \WC_Unit_Test_Case { $this->assertFalse( get_option( 'woocommerce_attribute_lookup_last_product_id_to_process' ) ); $this->assertFalse( get_option( 'woocommerce_attribute_lookup_last_products_page_processed' ) ); - $this->assertEquals( 'no', get_option( 'woocommerce_attribute_lookup_enabled' ) ); + $this->assertEquals( 'yes', get_option( 'woocommerce_attribute_lookup_enabled' ) ); $this->assertEmpty( $this->queue->get_methods_called() ); } @@ -238,7 +238,7 @@ class DataRegeneratorTest extends \WC_Unit_Test_Case { $this->assertEquals( $product_ids, $this->lookup_data_store->passed_products ); $this->assertFalse( get_option( 'woocommerce_attribute_lookup_last_product_id_to_process' ) ); $this->assertFalse( get_option( 'woocommerce_attribute_lookup_last_products_page_processed' ) ); - $this->assertEquals( 'no', get_option( 'woocommerce_attribute_lookup_enabled' ) ); + $this->assertEquals( 'yes', get_option( 'woocommerce_attribute_lookup_enabled' ) ); $this->assertEmpty( $this->queue->get_methods_called() ); } } diff --git a/plugins/woocommerce/tests/php/src/Internal/ProductAttributesLookup/LookupDataStoreTest.php b/plugins/woocommerce/tests/php/src/Internal/ProductAttributesLookup/LookupDataStoreTest.php index daf91d68c61..3b124f31645 100644 --- a/plugins/woocommerce/tests/php/src/Internal/ProductAttributesLookup/LookupDataStoreTest.php +++ b/plugins/woocommerce/tests/php/src/Internal/ProductAttributesLookup/LookupDataStoreTest.php @@ -9,7 +9,6 @@ use Automattic\WooCommerce\Internal\ProductAttributesLookup\DataRegenerator; use Automattic\WooCommerce\Internal\ProductAttributesLookup\LookupDataStore; use Automattic\WooCommerce\Testing\Tools\FakeQueue; use Automattic\WooCommerce\Utilities\ArrayUtil; -use Automattic\WooCommerce\Testing\Tools\CodeHacking\Hacks\FunctionsMockerHack; /** * Tests for the LookupDataStore class. @@ -36,7 +35,6 @@ class LookupDataStoreTest extends \WC_Unit_Test_Case { */ public static function tearDownAfterClass() { parent::tearDownAfterClass(); - wc_get_container()->get( DataRegenerator::class )->delete_all_attributes_lookup_data(); } /**