Automattic\WooCommerce\Checkout\Helpers
ReserveStock::reserve_stock_for_order()
Put a temporary hold on stock for an order if enough is available.
Method of the class: ReserveStock{}
Hooks from the method
Return
null
. Nothing (null).
Usage
$ReserveStock = new ReserveStock(); $ReserveStock->reserve_stock_for_order( $order, $minutes );
- $order(\WC_Order) (required)
- Order object.
- $minutes(int)
- How long to reserve stock in minutes.
Default: woocommerce_hold_stock_minutes
ReserveStock::reserve_stock_for_order() ReserveStock::reserve stock for order code WC 9.4.2
public function reserve_stock_for_order( $order, $minutes = 0 ) { $minutes = $minutes ? $minutes : (int) get_option( 'woocommerce_hold_stock_minutes', 60 ); /** * Filters the number of minutes an order should reserve stock for. * * This hook allows the number of minutes that stock in an order should be reserved for to be filtered, useful for third party developers to increase/reduce the number of minutes if the order meets certain criteria, or to exclude an order from stock reservation using a zero value. * * @since 8.8.0 * * @param int $minutes How long to reserve stock for the order in minutes. Defaults to woocommerce_hold_stock_minutes or 10 if block checkout entry. * @param \WC_Order $order Order object. */ $minutes = (int) apply_filters( 'woocommerce_order_hold_stock_minutes', $minutes, $order ); if ( ! $minutes || ! $this->is_enabled() ) { return; } $held_stock_notes = array(); try { $items = array_filter( $order->get_items(), function ( $item ) { return $item->is_type( 'line_item' ) && $item->get_product() instanceof \WC_Product && $item->get_quantity() > 0; } ); $rows = array(); foreach ( $items as $item ) { $product = $item->get_product(); if ( ! $product->is_in_stock() ) { throw new ReserveStockException( 'woocommerce_product_out_of_stock', sprintf( /* translators: %s: product name */ __( '"%s" is out of stock and cannot be purchased.', 'woocommerce' ), $product->get_name() ), 403 ); } // If stock management is off, no need to reserve any stock here. if ( ! $product->managing_stock() || $product->backorders_allowed() ) { continue; } $managed_by_id = $product->get_stock_managed_by_id(); /** * Filter order item quantity. * * @param int|float $quantity Quantity. * @param WC_Order $order Order data. * @param WC_Order_Item_Product $item Order item data. */ $item_quantity = apply_filters( 'woocommerce_order_item_quantity', $item->get_quantity(), $order, $item ); $rows[ $managed_by_id ] = isset( $rows[ $managed_by_id ] ) ? $rows[ $managed_by_id ] + $item_quantity : $item_quantity; if ( count( $held_stock_notes ) < 5 ) { // translators: %1$s is a product's formatted name, %2$d: is the quantity of said product to which the stock hold applied. $held_stock_notes[] = sprintf( _x( '- %1$s × %2$d', 'held stock note', 'woocommerce' ), $product->get_formatted_name(), $rows[ $managed_by_id ] ); } } if ( ! empty( $rows ) ) { foreach ( $rows as $product_id => $quantity ) { $this->reserve_stock_for_product( $product_id, $quantity, $order, $minutes ); } } } catch ( ReserveStockException $e ) { $this->release_stock_for_order( $order ); throw $e; } // Add order note after successfully holding the stock. if ( ! empty( $held_stock_notes ) ) { $remaining_count = count( $rows ) - count( $held_stock_notes ); if ( $remaining_count > 0 ) { $held_stock_notes[] = sprintf( // translators: %d is the remaining order items count. _nx( '- ...and %d more item.', '- ... and %d more items.', $remaining_count, 'held stock note', 'woocommerce' ), $remaining_count ); } $order->add_order_note( sprintf( // translators: %1$s is a time in minutes, %2$s is a list of products and quantities. _x( 'Stock hold of %1$s minutes applied to: %2$s', 'held stock note', 'woocommerce' ), $minutes, '<br>' . implode( '<br>', $held_stock_notes ) ) ); } }