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)
This commit is contained in:
Nestor Soriano 2021-11-19 11:36:19 +01:00
parent 8bbd41d6e2
commit b068ade7c6
No known key found for this signature in database
GPG Key ID: 08110F3518C12CAD
5 changed files with 60 additions and 73 deletions

View File

@ -169,6 +169,10 @@ class WC_Install {
'wc_update_600_migrate_rate_limit_options', 'wc_update_600_migrate_rate_limit_options',
'wc_update_600_db_version', '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( $pages = apply_filters(
'woocommerce_create_pages', 'woocommerce_create_pages',
array( array(
'shop' => array( 'shop' => array(
'name' => _x( 'shop', 'Page slug', 'woocommerce' ), 'name' => _x( 'shop', 'Page slug', 'woocommerce' ),
'title' => _x( 'Shop', 'Page title', 'woocommerce' ), 'title' => _x( 'Shop', 'Page title', 'woocommerce' ),
'content' => '', 'content' => '',
), ),
'cart' => array( 'cart' => array(
'name' => _x( 'cart', 'Page slug', 'woocommerce' ), 'name' => _x( 'cart', 'Page slug', 'woocommerce' ),
'title' => _x( 'Cart', 'Page title', 'woocommerce' ), 'title' => _x( 'Cart', 'Page title', 'woocommerce' ),
'content' => '<!-- wp:shortcode -->[' . apply_filters( 'woocommerce_cart_shortcode_tag', 'woocommerce_cart' ) . ']<!-- /wp:shortcode -->', 'content' => '<!-- wp:shortcode -->[' . apply_filters( 'woocommerce_cart_shortcode_tag', 'woocommerce_cart' ) . ']<!-- /wp:shortcode -->',
), ),
'checkout' => array( 'checkout' => array(
'name' => _x( 'checkout', 'Page slug', 'woocommerce' ), 'name' => _x( 'checkout', 'Page slug', 'woocommerce' ),
'title' => _x( 'Checkout', 'Page title', 'woocommerce' ), 'title' => _x( 'Checkout', 'Page title', 'woocommerce' ),
'content' => '<!-- wp:shortcode -->[' . apply_filters( 'woocommerce_checkout_shortcode_tag', 'woocommerce_checkout' ) . ']<!-- /wp:shortcode -->', 'content' => '<!-- wp:shortcode -->[' . apply_filters( 'woocommerce_checkout_shortcode_tag', 'woocommerce_checkout' ) . ']<!-- /wp:shortcode -->',
), ),
'myaccount' => array( 'myaccount' => array(
'name' => _x( 'my-account', 'Page slug', 'woocommerce' ), 'name' => _x( 'my-account', 'Page slug', 'woocommerce' ),
'title' => _x( 'My account', 'Page title', 'woocommerce' ), 'title' => _x( 'My account', 'Page title', 'woocommerce' ),
'content' => '<!-- wp:shortcode -->[' . apply_filters( 'woocommerce_my_account_shortcode_tag', 'woocommerce_my_account' ) . ']<!-- /wp:shortcode -->', 'content' => '<!-- wp:shortcode -->[' . apply_filters( 'woocommerce_my_account_shortcode_tag', 'woocommerce_my_account' ) . ']<!-- /wp:shortcode -->',

View File

@ -11,6 +11,8 @@
defined( 'ABSPATH' ) || exit; defined( 'ABSPATH' ) || exit;
use Automattic\WooCommerce\Internal\AssignDefaultCategory; use Automattic\WooCommerce\Internal\AssignDefaultCategory;
use Automattic\WooCommerce\Internal\ProductAttributesLookup\DataRegenerator;
use Automattic\WooCommerce\Internal\ProductAttributesLookup\LookupDataStore;
/** /**
* Update file paths for 2.0 * Update file paths for 2.0
@ -2306,7 +2308,7 @@ function wc_update_560_db_version() {
function wc_update_600_migrate_rate_limit_options() { function wc_update_600_migrate_rate_limit_options() {
global $wpdb; global $wpdb;
$rate_limits = $wpdb->get_results( $rate_limits = $wpdb->get_results(
" "
SELECT option_name, option_value SELECT option_name, option_value
FROM $wpdb->options FROM $wpdb->options
@ -2335,3 +2337,28 @@ function wc_update_600_migrate_rate_limit_options() {
function wc_update_600_db_version() { function wc_update_600_db_version() {
WC_Install::update_db_version( '6.0.0' ); 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' );
}

View File

@ -21,7 +21,7 @@ defined( 'ABSPATH' ) || exit;
* the data store classes) whenever a product is created/updated. * the data store classes) whenever a product is created/updated.
* *
* Additionally, after the regeneration is completed a 'woocommerce_attribute_lookup_enabled' option * 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, * 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. * 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, * deletes the lookup table and related options if they exist,
* then it creates the table and runs the first step of the regeneration process. * 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.: * 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.
* 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).
*/ */
public function initiate_regeneration() { public function initiate_regeneration() {
$this->enable_or_disable_lookup_table_usage( false ); $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. * 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; global $wpdb;
delete_option( 'woocommerce_attribute_lookup_enabled' ); delete_option( 'woocommerce_attribute_lookup_enabled' );
@ -244,7 +234,7 @@ CREATE TABLE ' . $this->lookup_table_name . '(
private function finalize_regeneration() { private function finalize_regeneration() {
delete_option( 'woocommerce_attribute_lookup_last_product_id_to_process' ); delete_option( 'woocommerce_attribute_lookup_last_product_id_to_process' );
delete_option( 'woocommerce_attribute_lookup_last_products_page_processed' ); 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(); $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. * @return array The tools array with the entry added.
*/ */
private function add_initiate_regeneration_entry_to_tools_array( array $tools_array ) { private function add_initiate_regeneration_entry_to_tools_array( array $tools_array ) {
$lookup_table_exists = $this->data_store->check_lookup_table_exists(); if ( ! $this->data_store->check_lookup_table_exists() ) {
$generation_is_in_progress = $this->data_store->regeneration_is_in_progress(); return $tools_array;
// 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' );
} }
$entry = array( $generation_is_in_progress = $this->data_store->regeneration_is_in_progress();
'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;
},
);
if ( $lookup_table_exists ) { $entry = array(
$entry['selector'] = 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' ), 'description' => __( 'Select a product to regenerate the data for, or leave empty for a full table regeneration:', 'woocommerce' ),
'class' => 'wc-product-search', 'class' => 'wc-product-search',
'search_action' => 'woocommerce_json_search_products', 'search_action' => 'woocommerce_json_search_products',
'name' => 'regenerate_product_attribute_lookup_data_product_id', 'name' => 'regenerate_product_attribute_lookup_data_product_id',
'placeholder' => esc_attr__( 'Search for a product&hellip;', 'woocommerce' ), 'placeholder' => esc_attr__( 'Search for a product&hellip;', 'woocommerce' ),
); ),
} );
if ( $generation_is_in_progress ) { if ( $generation_is_in_progress ) {
$entry['button'] = sprintf( $entry['button'] = sprintf(
@ -300,31 +277,12 @@ CREATE TABLE ' . $this->lookup_table_name . '(
); );
$entry['disabled'] = true; $entry['disabled'] = true;
} else { } else {
$entry['button'] = $generate_item_button; $entry['button'] = __( 'Regenerate', 'woocommerce' );
} }
$tools_array['regenerate_product_attributes_lookup_table'] = $entry; $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(
'<strong class="red">%1$s</strong> %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; return $tools_array;
} }

View File

@ -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_product_id_to_process' ) );
$this->assertFalse( get_option( 'woocommerce_attribute_lookup_last_products_page_processed' ) ); $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() ); $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->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_product_id_to_process' ) );
$this->assertFalse( get_option( 'woocommerce_attribute_lookup_last_products_page_processed' ) ); $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() ); $this->assertEmpty( $this->queue->get_methods_called() );
} }
} }

View File

@ -9,7 +9,6 @@ use Automattic\WooCommerce\Internal\ProductAttributesLookup\DataRegenerator;
use Automattic\WooCommerce\Internal\ProductAttributesLookup\LookupDataStore; use Automattic\WooCommerce\Internal\ProductAttributesLookup\LookupDataStore;
use Automattic\WooCommerce\Testing\Tools\FakeQueue; use Automattic\WooCommerce\Testing\Tools\FakeQueue;
use Automattic\WooCommerce\Utilities\ArrayUtil; use Automattic\WooCommerce\Utilities\ArrayUtil;
use Automattic\WooCommerce\Testing\Tools\CodeHacking\Hacks\FunctionsMockerHack;
/** /**
* Tests for the LookupDataStore class. * Tests for the LookupDataStore class.
@ -36,7 +35,6 @@ class LookupDataStoreTest extends \WC_Unit_Test_Case {
*/ */
public static function tearDownAfterClass() { public static function tearDownAfterClass() {
parent::tearDownAfterClass(); parent::tearDownAfterClass();
wc_get_container()->get( DataRegenerator::class )->delete_all_attributes_lookup_data();
} }
/** /**