From 3d77547d77626374b18103b7566278e6968e246b Mon Sep 17 00:00:00 2001 From: Nestor Soriano Date: Fri, 6 May 2022 10:14:50 +0200 Subject: [PATCH] Fix: product attributes lookup table not filled on WooCommerce update When WooCommerce was updated from an version older than 6.2, and before the user hit the "Update database" button, the product attributes lookup table usage was activated but it was still empty. This caused the search to not work, and the product filtering widget to not appear. --- .../includes/wc-update-functions.php | 4 +- .../DataRegenerator.php | 49 ++++++++++++++----- 2 files changed, 38 insertions(+), 15 deletions(-) diff --git a/plugins/woocommerce/includes/wc-update-functions.php b/plugins/woocommerce/includes/wc-update-functions.php index 2909d03fe28..3de49cf5b54 100644 --- a/plugins/woocommerce/includes/wc-update-functions.php +++ b/plugins/woocommerce/includes/wc-update-functions.php @@ -2358,9 +2358,9 @@ function wc_update_630_create_product_attributes_lookup_table() { /** * If the table exists and contains data, it was manually created by user before the migration ran. - * If the table exists but is empty, it was likely created right now via dbDelta, so a table regenerations is needed. + * If the table exists but is empty, it was likely created right now via dbDelta, so a table regenerations is needed (unless one is in progress already). */ - if ( ! $data_store->check_lookup_table_exists() || ! $data_store->lookup_table_has_data() ) { + if ( ! $data_store->check_lookup_table_exists() || ( ! $data_store->lookup_table_has_data() && ! $data_store->regeneration_is_in_progress() ) ) { $data_regenerator->initiate_regeneration(); } diff --git a/plugins/woocommerce/src/Internal/ProductAttributesLookup/DataRegenerator.php b/plugins/woocommerce/src/Internal/ProductAttributesLookup/DataRegenerator.php index ccfa173f72a..eb03e7a33ad 100644 --- a/plugins/woocommerce/src/Internal/ProductAttributesLookup/DataRegenerator.php +++ b/plugins/woocommerce/src/Internal/ProductAttributesLookup/DataRegenerator.php @@ -137,7 +137,26 @@ class DataRegenerator { // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared $wpdb->query( $this->get_table_creation_sql() ); - $last_existing_product_id = + $last_existing_product_id = $this->get_last_existing_product_id(); + if ( ! $last_existing_product_id ) { + // No products exist, nothing to (re)generate. + return false; + } + + $this->data_store->set_regeneration_in_progress_flag(); + update_option( 'woocommerce_attribute_lookup_last_product_id_to_process', $last_existing_product_id ); + update_option( 'woocommerce_attribute_lookup_processed_count', 0 ); + + return true; + } + + /** + * Get the highest existing product id. + * + * @return int|null Highest existing product id, or null if no products exist at all. + */ + private function get_last_existing_product_id(): ?int { + $last_existing_product_id_array = WC()->call_function( 'wc_get_products', array( @@ -149,16 +168,7 @@ class DataRegenerator { ) ); - if ( ! $last_existing_product_id ) { - // No products exist, nothing to (re)generate. - return false; - } - - $this->data_store->set_regeneration_in_progress_flag(); - update_option( 'woocommerce_attribute_lookup_last_product_id_to_process', current( $last_existing_product_id ) ); - update_option( 'woocommerce_attribute_lookup_processed_count', 0 ); - - return true; + return empty( $last_existing_product_id_array ) ? null : current( $last_existing_product_id_array ); } /** @@ -493,12 +503,25 @@ class DataRegenerator { } /** - * Run additional setup needed after a clean WooCommerce install finishes. + * Run additional setup needed after a WooCommerce install or update finishes. */ private function run_woocommerce_installed_callback() { // The table must exist at this point (created via dbDelta), but we check just in case. - if ( $this->data_store->check_lookup_table_exists() ) { + if ( ! $this->data_store->check_lookup_table_exists() ) { + return; + } + + // If a table regeneration is in progress, leave it alone. + if ( $this->data_store->regeneration_is_in_progress() ) { + return; + } + + // If the lookup table has data, or if it's empty because there are no products yet, we're good. + // Otherwise (lookup table is empty but products exist) we need to initiate a regeneration if one isn't already in progress. + if ( $this->data_store->lookup_table_has_data() || ! $this->get_last_existing_product_id() ) { $this->finalize_regeneration( true ); + } else { + $this->initiate_regeneration(); } } }