Merge pull request #32893 from woocommerce/fix/product_attributes_lookup_table_update
Fix: product attributes lookup table not being updated on WooCommerce update and on REST API batch requests
This commit is contained in:
commit
8000a9b0ef
|
@ -0,0 +1,4 @@
|
|||
Significance: patch
|
||||
Type: fix
|
||||
|
||||
Product attributes lookup table is now properly updated on WooCommerce upgrade and when using REST API batch endpoints
|
|
@ -227,7 +227,7 @@ abstract class WC_REST_Controller extends WP_REST_Controller {
|
|||
|
||||
if ( ! empty( $items['create'] ) ) {
|
||||
foreach ( $items['create'] as $item ) {
|
||||
$_item = new WP_REST_Request( 'POST' );
|
||||
$_item = new WP_REST_Request( 'POST', $request->get_route() );
|
||||
|
||||
// Default parameters.
|
||||
$defaults = array();
|
||||
|
@ -264,7 +264,7 @@ abstract class WC_REST_Controller extends WP_REST_Controller {
|
|||
|
||||
if ( ! empty( $items['update'] ) ) {
|
||||
foreach ( $items['update'] as $item ) {
|
||||
$_item = new WP_REST_Request( 'PUT' );
|
||||
$_item = new WP_REST_Request( 'PUT', $request->get_route() );
|
||||
$_item->set_body_params( $item );
|
||||
$_response = $this->update_item( $_item );
|
||||
|
||||
|
@ -291,7 +291,7 @@ abstract class WC_REST_Controller extends WP_REST_Controller {
|
|||
continue;
|
||||
}
|
||||
|
||||
$_item = new WP_REST_Request( 'DELETE' );
|
||||
$_item = new WP_REST_Request( 'DELETE', $request->get_route() );
|
||||
$_item->set_query_params(
|
||||
array(
|
||||
'id' => $id,
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
namespace Automattic\WooCommerce\Internal\ProductAttributesLookup;
|
||||
|
||||
use Automattic\WooCommerce\Utilities\ArrayUtil;
|
||||
use Automattic\WooCommerce\Utilities\StringUtil;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
|
@ -66,6 +67,15 @@ class LookupDataStore {
|
|||
1
|
||||
);
|
||||
|
||||
add_action(
|
||||
'woocommerce_rest_insert_product',
|
||||
function ( $product_post, $request ) {
|
||||
$this->on_product_created_or_updated_via_rest_api( $product_post, $request );
|
||||
},
|
||||
100,
|
||||
2
|
||||
);
|
||||
|
||||
add_filter(
|
||||
'woocommerce_get_settings_products',
|
||||
function ( $settings, $section_id ) {
|
||||
|
@ -633,6 +643,20 @@ class LookupDataStore {
|
|||
// phpcs:enable WordPress.DB.PreparedSQL.NotPrepared
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for the woocommerce_rest_insert_product hook.
|
||||
* Needed to update the lookup table when the REST API batch insert/update endpoints are used.
|
||||
*
|
||||
* @param WP_Post $product The post representing the created or updated product.
|
||||
* @param \WP_REST_Request $request The REST request that caused the hook to be fired.
|
||||
* @return void
|
||||
*/
|
||||
private function on_product_created_or_updated_via_rest_api( WP_Post $product, \WP_REST_Request $request ): void {
|
||||
if ( StringUtil::ends_with( $request->get_route(), '/batch' ) ) {
|
||||
$this->on_product_changed( $product->ID );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells if a lookup table regeneration is currently in progress.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue