Merge pull request #26039 from soulseekah/master

Fix WC_Product_Data_Store_CPT::update_product_stock race condition
This commit is contained in:
Vedanshu Jain 2020-04-07 00:44:33 +05:30 committed by GitHub
commit dff7d8fd44
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 18 additions and 11 deletions

View File

@ -1356,9 +1356,14 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da
if ( 'set' === $operation ) {
$new_stock = wc_stock_amount( $stock_quantity );
// Generate SQL.
$sql = $wpdb->prepare(
"UPDATE {$wpdb->postmeta} SET meta_value = %f WHERE post_id = %d AND meta_key='_stock'",
$new_stock,
$product_id_with_stock
);
} else {
// @todo: potential race condition.
// Read current stock level and lock the row. If the lock can't be acquired, don't wait.
$current_stock = wc_stock_amount(
$wpdb->get_var(
$wpdb->prepare(
@ -1368,25 +1373,27 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da
)
);
// Calculate new value.
// Calculate new value for filter below. Set multiplier to subtract or add the meta_value.
switch ( $operation ) {
case 'increase':
$new_stock = $current_stock + wc_stock_amount( $stock_quantity );
$multiplier = 1;
break;
default:
$new_stock = $current_stock - wc_stock_amount( $stock_quantity );
$multiplier = -1;
break;
}
// Generate SQL.
$sql = $wpdb->prepare(
"UPDATE {$wpdb->postmeta} SET meta_value = meta_value %+f WHERE post_id = %d AND meta_key='_stock'",
wc_stock_amount( $stock_quantity ) * $multiplier, // This will either subtract or add depending on operation.
$product_id_with_stock
);
}
// Generate SQL.
$sql = $wpdb->prepare(
"UPDATE {$wpdb->postmeta} SET meta_value = %f WHERE post_id = %d AND meta_key='_stock'",
$new_stock,
$product_id_with_stock
);
$sql = apply_filters( 'woocommerce_update_product_stock_query', $sql, $product_id_with_stock, $new_stock, 'set' );
$sql = apply_filters( 'woocommerce_update_product_stock_query', $sql, $product_id_with_stock, $new_stock, $operation );
$wpdb->query( $sql ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.PreparedSQL.NotPrepared