Merge pull request #26705 from woocommerce/enhancement/protections-reserved-stock

Port enhancement to reserved stock feature from wc-blocks
This commit is contained in:
Vedanshu Jain 2020-06-15 18:41:44 +05:30 committed by GitHub
commit c1a007297e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 71 additions and 7 deletions

View File

@ -339,6 +339,29 @@ class WC_Admin_Status {
} }
} }
/**
* Prints table info if a base table is not present.
*/
private static function output_tables_info() {
$missing_tables = WC_Install::verify_base_tables( false );
if ( 0 === count( $missing_tables ) ) {
return;
}
?>
<br>
<strong style="color:#a00;">
<span class="dashicons dashicons-warning"></span>
<?php
esc_html_e( 'Missing base tables: ', 'woocommerce' );
echo esc_html( implode( ', ', $missing_tables ) );
esc_html_e( '. Some WooCommerce functionality may not work as expected.', 'woocommerce' );
?>
</strong>
<?php
}
/** /**
* Prints the information about plugins for the system status report. * Prints the information about plugins for the system status report.
* Used for both active and inactive plugins sections. * Used for both active and inactive plugins sections.

View File

@ -496,10 +496,17 @@ $untested_plugins = $plugin_updates->get_untested_plugins( WC()->version, 'min
?> ?>
</tbody> </tbody>
</table> </table>
<table class="wc_status_table widefat" cellspacing="0"> <table id="status-database" class="wc_status_table widefat" cellspacing="0">
<thead> <thead>
<tr> <tr>
<th colspan="3" data-export-label="Database"><h2><?php esc_html_e( 'Database', 'woocommerce' ); ?></h2></th> <th colspan="3" data-export-label="Database">
<h2>
<?php
esc_html_e( 'Database', 'woocommerce' );
self::output_tables_info();
?>
</h2>
</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>

View File

@ -994,8 +994,8 @@ CREATE TABLE {$wpdb->prefix}wc_reserved_stock (
`order_id` bigint(20) NOT NULL, `order_id` bigint(20) NOT NULL,
`product_id` bigint(20) NOT NULL, `product_id` bigint(20) NOT NULL,
`stock_quantity` double NOT NULL DEFAULT 0, `stock_quantity` double NOT NULL DEFAULT 0,
`timestamp` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `timestamp` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`expires` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `expires` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`order_id`, `product_id`) PRIMARY KEY (`order_id`, `product_id`)
) $collate; ) $collate;
"; ";

View File

@ -13,6 +13,31 @@ defined( 'ABSPATH' ) || exit;
* Stock Reservation class. * Stock Reservation class.
*/ */
final class ReserveStock { final class ReserveStock {
/**
* Is stock reservation enabled?
*
* @var boolean
*/
private $enabled = true;
/**
* Constructor
*/
public function __construct() {
// Table needed for this feature are added in 4.3.
$this->enabled = get_option( 'woocommerce_schema_version', 0 ) >= 430;
}
/**
* Is stock reservation enabled?
*
* @return boolean
*/
protected function is_enabled() {
return $this->enabled;
}
/** /**
* Query for any existing holds on stock for this item. * Query for any existing holds on stock for this item.
* *
@ -24,6 +49,10 @@ final class ReserveStock {
public function get_reserved_stock( \WC_Product $product, $exclude_order_id = 0 ) { public function get_reserved_stock( \WC_Product $product, $exclude_order_id = 0 ) {
global $wpdb; global $wpdb;
if ( ! $this->is_enabled() ) {
return 0;
}
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQL.NotPrepared // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQL.NotPrepared
return (int) $wpdb->get_var( $this->get_query_for_reserved_stock( $product->get_stock_managed_by_id(), $exclude_order_id ) ); return (int) $wpdb->get_var( $this->get_query_for_reserved_stock( $product->get_stock_managed_by_id(), $exclude_order_id ) );
} }
@ -39,7 +68,7 @@ final class ReserveStock {
public function reserve_stock_for_order( \WC_Order $order, $minutes = 0 ) { public function reserve_stock_for_order( \WC_Order $order, $minutes = 0 ) {
$minutes = $minutes ? $minutes : (int) get_option( 'woocommerce_hold_stock_minutes', 60 ); $minutes = $minutes ? $minutes : (int) get_option( 'woocommerce_hold_stock_minutes', 60 );
if ( ! $minutes ) { if ( ! $minutes || ! $this->is_enabled() ) {
return; return;
} }
@ -95,6 +124,10 @@ final class ReserveStock {
public function release_stock_for_order( \WC_Order $order ) { public function release_stock_for_order( \WC_Order $order ) {
global $wpdb; global $wpdb;
if ( ! $this->is_enabled() ) {
return;
}
$wpdb->delete( $wpdb->delete(
$wpdb->wc_reserved_stock, $wpdb->wc_reserved_stock,
array( array(
@ -124,9 +157,10 @@ final class ReserveStock {
$result = $wpdb->query( $result = $wpdb->query(
$wpdb->prepare( $wpdb->prepare(
" "
REPLACE INTO {$wpdb->wc_reserved_stock} ( order_id, product_id, stock_quantity, expires ) INSERT INTO {$wpdb->wc_reserved_stock} ( `order_id`, `product_id`, `stock_quantity`, `timestamp`, `expires` )
SELECT %d, %d, %d, ( NOW() + INTERVAL %d MINUTE ) from DUAL SELECT %d, %d, %d, NOW(), ( NOW() + INTERVAL %d MINUTE ) FROM DUAL
WHERE ( $query_for_stock FOR UPDATE ) - ( $query_for_reserved_stock FOR UPDATE ) >= %d WHERE ( $query_for_stock FOR UPDATE ) - ( $query_for_reserved_stock FOR UPDATE ) >= %d
ON DUPLICATE KEY UPDATE `expires` = VALUES( `expires` )
", ",
$order->get_id(), $order->get_id(),
$product_id, $product_id,