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'] ) ) {
|
if ( ! empty( $items['create'] ) ) {
|
||||||
foreach ( $items['create'] as $item ) {
|
foreach ( $items['create'] as $item ) {
|
||||||
$_item = new WP_REST_Request( 'POST' );
|
$_item = new WP_REST_Request( 'POST', $request->get_route() );
|
||||||
|
|
||||||
// Default parameters.
|
// Default parameters.
|
||||||
$defaults = array();
|
$defaults = array();
|
||||||
|
@ -264,7 +264,7 @@ abstract class WC_REST_Controller extends WP_REST_Controller {
|
||||||
|
|
||||||
if ( ! empty( $items['update'] ) ) {
|
if ( ! empty( $items['update'] ) ) {
|
||||||
foreach ( $items['update'] as $item ) {
|
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 );
|
$_item->set_body_params( $item );
|
||||||
$_response = $this->update_item( $_item );
|
$_response = $this->update_item( $_item );
|
||||||
|
|
||||||
|
@ -291,7 +291,7 @@ abstract class WC_REST_Controller extends WP_REST_Controller {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$_item = new WP_REST_Request( 'DELETE' );
|
$_item = new WP_REST_Request( 'DELETE', $request->get_route() );
|
||||||
$_item->set_query_params(
|
$_item->set_query_params(
|
||||||
array(
|
array(
|
||||||
'id' => $id,
|
'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 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();
|
$data_regenerator->initiate_regeneration();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -137,7 +137,26 @@ class DataRegenerator {
|
||||||
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
||||||
$wpdb->query( $this->get_table_creation_sql() );
|
$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()->call_function(
|
||||||
'wc_get_products',
|
'wc_get_products',
|
||||||
array(
|
array(
|
||||||
|
@ -149,16 +168,7 @@ class DataRegenerator {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
if ( ! $last_existing_product_id ) {
|
return empty( $last_existing_product_id_array ) ? null : current( $last_existing_product_id_array );
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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() {
|
private function run_woocommerce_installed_callback() {
|
||||||
// The table must exist at this point (created via dbDelta), but we check just in case.
|
// 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 );
|
$this->finalize_regeneration( true );
|
||||||
|
} else {
|
||||||
|
$this->initiate_regeneration();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
namespace Automattic\WooCommerce\Internal\ProductAttributesLookup;
|
namespace Automattic\WooCommerce\Internal\ProductAttributesLookup;
|
||||||
|
|
||||||
use Automattic\WooCommerce\Utilities\ArrayUtil;
|
use Automattic\WooCommerce\Utilities\ArrayUtil;
|
||||||
|
use Automattic\WooCommerce\Utilities\StringUtil;
|
||||||
|
|
||||||
defined( 'ABSPATH' ) || exit;
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
|
@ -66,6 +67,15 @@ class LookupDataStore {
|
||||||
1
|
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(
|
add_filter(
|
||||||
'woocommerce_get_settings_products',
|
'woocommerce_get_settings_products',
|
||||||
function ( $settings, $section_id ) {
|
function ( $settings, $section_id ) {
|
||||||
|
@ -633,6 +643,20 @@ class LookupDataStore {
|
||||||
// phpcs:enable WordPress.DB.PreparedSQL.NotPrepared
|
// 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.
|
* Tells if a lookup table regeneration is currently in progress.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue