From 12656332869d31f1f27dea17458c9fe21ee6de39 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 27 Jun 2017 21:22:46 +0100 Subject: [PATCH] If stock changes between page load and editing, reject stock changes Fixes #15818 --- .../class-wc-meta-box-product-data.php | 26 +++++++++++++++++-- .../views/html-product-data-inventory.php | 4 ++- .../meta-boxes/views/html-variation-admin.php | 4 ++- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/includes/admin/meta-boxes/class-wc-meta-box-product-data.php b/includes/admin/meta-boxes/class-wc-meta-box-product-data.php index d92750d8008..08a47bd9c13 100644 --- a/includes/admin/meta-boxes/class-wc-meta-box-product-data.php +++ b/includes/admin/meta-boxes/class-wc-meta-box-product-data.php @@ -310,6 +310,17 @@ class WC_Meta_Box_Product_Data { $classname = WC_Product_Factory::get_product_classname( $post_id, $product_type ? $product_type : 'simple' ); $product = new $classname( $post_id ); $attributes = self::prepare_attributes(); + $stock = null; + + // Handle stock changes. + if ( isset( $_POST['_stock'] ) ) { + if ( isset( $_POST['_original_stock'] ) && wc_stock_amount( $product->get_stock_quantity( 'edit' ) ) !== wc_stock_amount( $_POST['_original_stock'] ) ) { + WC_Admin_Meta_Boxes::add_error( sprintf( __( 'The stock has not been updated because the value has changed since editing. Product %d has %d units in stock.', 'woocommerce' ), $product->get_id(), $product->get_stock_quantity( 'edit' ) ) ); + } else { + $stock = wc_stock_amount( $_POST['_stock'] ); + } + } + $errors = $product->set_props( array( 'sku' => isset( $_POST['_sku'] ) ? wc_clean( $_POST['_sku'] ) : null, 'purchase_note' => wp_kses_post( stripslashes( $_POST['_purchase_note'] ) ), @@ -334,7 +345,7 @@ class WC_Meta_Box_Product_Data { 'manage_stock' => ! empty( $_POST['_manage_stock'] ), 'backorders' => isset( $_POST['_backorders'] ) ? wc_clean( $_POST['_backorders'] ) : null, 'stock_status' => wc_clean( $_POST['_stock_status'] ), - 'stock_quantity' => isset( $_POST['_stock'] ) ? wc_stock_amount( $_POST['_stock'] ) : null, + 'stock_quantity' => $stock, 'download_limit' => '' === $_POST['_download_limit'] ? '' : absint( $_POST['_download_limit'] ), 'download_expiry' => '' === $_POST['_download_expiry'] ? '' : absint( $_POST['_download_expiry'] ), 'downloads' => self::prepare_downloads( @@ -391,6 +402,17 @@ class WC_Meta_Box_Product_Data { } $variation_id = absint( $_POST['variable_post_id'][ $i ] ); $variation = new WC_Product_Variation( $variation_id ); + $stock = null; + + // Handle stock changes. + if ( isset( $_POST['variable_stock'], $_POST['variable_stock'][ $i ] ) ) { + if ( isset( $_POST['variable_original_stock'], $_POST['variable_original_stock'][ $i ] ) && wc_stock_amount( $variation->get_stock_quantity( 'edit' ) ) !== wc_stock_amount( $_POST['variable_original_stock'][ $i ] ) ) { + WC_Admin_Meta_Boxes::add_error( sprintf( __( 'The stock has not been updated because the value has changed since editing. Product %d has %d units in stock.', 'woocommerce' ), $variation->get_id(), $variation->get_stock_quantity( 'edit' ) ) ); + } else { + $stock = wc_stock_amount( $_POST['variable_stock'][ $i ] ); + } + } + $errors = $variation->set_props( array( 'status' => isset( $_POST['variable_enabled'][ $i ] ) ? 'publish' : 'private', 'menu_order' => wc_clean( $_POST['variation_menu_order'][ $i ] ), @@ -409,7 +431,7 @@ class WC_Meta_Box_Product_Data { isset( $_POST['_wc_variation_file_hashes'][ $variation_id ] ) ? $_POST['_wc_variation_file_hashes'][ $variation_id ] : array() ), 'manage_stock' => isset( $_POST['variable_manage_stock'][ $i ] ), - 'stock_quantity' => isset( $_POST['variable_stock'], $_POST['variable_stock'][ $i ] ) ? wc_clean( $_POST['variable_stock'][ $i ] ) : null, + 'stock_quantity' => $stock, 'backorders' => isset( $_POST['variable_backorders'], $_POST['variable_backorders'][ $i ] ) ? wc_clean( $_POST['variable_backorders'][ $i ] ) : null, 'stock_status' => wc_clean( $_POST['variable_stock_status'][ $i ] ), 'image_id' => wc_clean( $_POST['upload_image_id'][ $i ] ), diff --git a/includes/admin/meta-boxes/views/html-product-data-inventory.php b/includes/admin/meta-boxes/views/html-product-data-inventory.php index 706caa74bb9..00ad5dd1f7e 100644 --- a/includes/admin/meta-boxes/views/html-product-data-inventory.php +++ b/includes/admin/meta-boxes/views/html-product-data-inventory.php @@ -35,7 +35,7 @@ if ( ! defined( 'ABSPATH' ) ) { woocommerce_wp_text_input( array( 'id' => '_stock', - 'value' => $product_object->get_stock_quantity( 'edit' ), + 'value' => wc_stock_amount( $product_object->get_stock_quantity( 'edit' ) ), 'label' => __( 'Stock quantity', 'woocommerce' ), 'desc_tip' => true, 'description' => __( 'Stock quantity. If this is a variable product this value will be used to control stock for all variations, unless you define stock at variation level.', 'woocommerce' ), @@ -46,6 +46,8 @@ if ( ! defined( 'ABSPATH' ) ) { 'data_type' => 'stock', ) ); + echo ''; + woocommerce_wp_select( array( 'id' => '_backorders', 'value' => $product_object->get_backorders( 'edit' ), diff --git a/includes/admin/meta-boxes/views/html-variation-admin.php b/includes/admin/meta-boxes/views/html-variation-admin.php index 64edc9d8644..c636b0c365d 100644 --- a/includes/admin/meta-boxes/views/html-variation-admin.php +++ b/includes/admin/meta-boxes/views/html-variation-admin.php @@ -158,7 +158,7 @@ if ( ! defined( 'ABSPATH' ) ) { woocommerce_wp_text_input( array( 'id' => "variable_stock{$loop}", 'name' => "variable_stock[{$loop}]", - 'value' => $variation_object->get_stock_quantity( 'edit' ), + 'value' => wc_stock_amount( $variation_object->get_stock_quantity( 'edit' ) ), 'label' => __( 'Stock quantity', 'woocommerce' ), 'desc_tip' => true, 'description' => __( "Enter a quantity to enable stock management at variation level, or leave blank to use the parent product's options.", 'woocommerce' ), @@ -170,6 +170,8 @@ if ( ! defined( 'ABSPATH' ) ) { 'wrapper_class' => 'form-row form-row-first', ) ); + echo ''; + woocommerce_wp_select( array( 'id' => "variable_backorders{$loop}", 'name' => "variable_backorders[{$loop}]",