← All changes
|
src/Addons/AdvancedQuantityOptions/QuantityManager.php
+39
-3
6.5.0
→
8.1.0
View file →
| @@ -3,8 +3,9 @@ | ||
| 3 | 3 | use TierPricingTable\PriceManager; |
| 4 | 4 | use TierPricingTable\PricingRule; |
| 5 | 5 | use TierPricingTable\TierPricingTablePlugin; |
| 6 | 6 | use WC_Product; |
| 7 | +use WP_Error; | |
| 7 | 8 | |
| 8 | 9 | class QuantityManager { |
| 9 | 10 | |
| 10 | 11 | public function __construct() { |
| @@ -76,9 +77,13 @@ | ||
| 76 | 77 | $groupOf = $pricingRule->data['group_of_quantity'] ?? null; |
| 77 | 78 | |
| 78 | 79 | if ( $max ) { |
| 79 | 80 | |
| 80 | - if ( ! is_cart() && ! is_checkout() ) { | |
| 81 | + // Subtract what is already in the cart ONLY for the classic product-page input, where | |
| 82 | + // the field means "how many more can be added". The Store API reads this filter's | |
| 83 | + // max_value as the ABSOLUTE cart maximum (QuantityLimits::get_add_to_cart_limits), so | |
| 84 | + // subtracting there double-counts the cart and caps customers at half the real limit. | |
| 85 | + if ( ! is_cart() && ! is_checkout() && ! WC()->is_rest_api_request() ) { | |
| 81 | 86 | $max = max( 1, $max - $this->getProductCartQuantity( $product->get_id() ) ); |
| 82 | 87 | } |
| 83 | 88 | |
| 84 | 89 | $max = max( $groupOf, $max ); |
| @@ -214,11 +219,42 @@ | ||
| 214 | 219 | } |
| 215 | 220 | } |
| 216 | 221 | |
| 217 | 222 | return $passed; |
| 218 | - | |
| 223 | + | |
| 219 | 224 | }, 10, 4 ); |
| 220 | - | |
| 225 | + | |
| 226 | + // The Store API (Cart and Checkout blocks) counterpart of the filter above, WooCommerce 11.2+. The | |
| 227 | + // maximum and the step already reach the Store API's numeric limits through | |
| 228 | + // woocommerce_quantity_input_args; this keeps them in force when another extension raises those | |
| 229 | + // limits. A WP_Error rejects the change; the shopper sees its message in the block. | |
| 230 | + add_filter( 'woocommerce_store_api_cart_item_quantity_validation', function ( $valid, $quantity, $product ) { | |
| 231 | + | |
| 232 | + if ( is_wp_error( $valid ) || ! ( $product instanceof WC_Product ) ) { | |
| 233 | + return $valid; | |
| 234 | + } | |
| 235 | + | |
| 236 | + $pricingRule = PriceManager::getPricingRule( $product->get_id() ); | |
| 237 | + | |
| 238 | + $max = ! empty( $pricingRule->data['maximum_quantity'] ) ? intval( $pricingRule->data['maximum_quantity'] ) : null; | |
| 239 | + $groupOf = ! empty( $pricingRule->data['group_of_quantity'] ) ? intval( $pricingRule->data['group_of_quantity'] ) : null; | |
| 240 | + | |
| 241 | + if ( $max && $quantity > $max ) { | |
| 242 | + return new WP_Error( 'tiered_pricing_table_maximum_quantity', | |
| 243 | + // translators: %s: maximum quantity | |
| 244 | + sprintf( __( 'Maximum order quantity for the product is %s', 'tier-pricing-table' ), $max ) ); | |
| 245 | + } | |
| 246 | + | |
| 247 | + if ( $groupOf && 0 !== (int) $quantity % $groupOf ) { | |
| 248 | + return new WP_Error( 'tiered_pricing_table_quantity_step', | |
| 249 | + // translators: %s: quantity step | |
| 250 | + sprintf( __( 'Order quantity must be multiple of %s', 'tier-pricing-table' ), $groupOf ) ); | |
| 251 | + } | |
| 252 | + | |
| 253 | + return $valid; | |
| 254 | + | |
| 255 | + }, 10, 3 ); | |
| 256 | + | |
| 221 | 257 | add_filter( 'woocommerce_available_variation', function ( $variation ) { |
| 222 | 258 | |
| 223 | 259 | $pricingRule = PriceManager::getPricingRule( $variation['variation_id'] ); |
| 224 | 260 | |