Volume_Bundle extends Type implements Actionable, Applicable, Cart_Processor Uses Discount_With_Reductions
Volume Bundle discount type.
Create a discount rule based on the quantity of the products in the order
Tags
Interfaces, Classes and Traits
- Actionable
- Interface for discount types that have cart actions.
- Applicable
- Indicates that a discount type needs to be verified as applicable to the cart as a whole.
- Cart_Processor
- Interface for classes that handle the processing of bundle products during a standard WooCommerce add-to-cart form submission.
Table of Contents
- ORDER = 7
- $discount : Discount
- The discount object.
- $processing_order : bool
- Whether the discount type is processing a WooCommerce order.
- $total_discounted_products : int
- The total number of discounted products in the cart|order.
- $total_order_discount : float
- The total discount that needs to be applied to the order.
- $current_bundle_add_to_cart_context : array<string|int, mixed>
- Temporary storage for bundle item details during an add-to-cart operation.
- apply_discount_to_cart() : void
- Apply quantity-based discounts to the cart when calculation_type is 'cart'.
- apply_discount_to_line_item() : void
- Apply discount to an individual line item (cart or order).
- decrease_total_discounted_products() : self
- Decrease the total number of discounted products in the cart|order.
- decrease_total_order_discount() : self
- Decrease the total discount that needs to be applied to the order.
- filter_item_cart_data() : array<string|int, mixed>
- Adds custom data to a cart item when it's being added as part of a volume bundle.
- generate_virtual_coupon_for_order() : void
- Generate a virtual coupon for the order.
- get_bundle_table_display_location() : string
- Get the bundle table display location.
- get_bundles_for_product() : array<string|int, mixed>
- Get the bundles for a product.
- get_cart_quantity_of_relevant_products() : int
- Return the total quantity of relevant products in the cart.
- get_checked_bundle_index() : int|null
- Get the index of the bundle that should be pre-checked by default.
- get_configured_bundles() : array<string|int, mixed>
- Get the bundle configurations from settings.
- get_default_settings_values() : array<string|int, mixed>
- Get the default settings values for this discount type.
- get_discount() : Discount
- Get the discount object.
- get_discount_amount_type() : string
- Get the type of discount amount.
- get_name() : string
- Get the name for this discount type.
- get_order_quantity_of_relevant_products() : int
- Return the total quantity of relevant products in the order.
- get_reduction() : Reduction
- Get the reduction to apply to products.
- get_settings() : array<string|int, mixed>
- Get the settings for this discount type.
- get_slug() : string
- Get the slug for this discount type.
- get_tooltip() : string
- Get the tooltip for this discount type.
- get_total_discounted_products() : int
- Return the total number of discounted products in the cart|order.
- get_total_order_discount() : float
- Return the total discount that needs to be applied to the order.
- has_sale_badge() : bool
- Determines if the discount has a sale badge enabled.
- increase_total_discounted_products() : self
- Increase the total number of discounted products in the cart|order.
- increase_total_order_discount() : self
- Increase the total discount that needs to be applied to the order.
- is_applicable_to_cart() : bool
- Determine if the discount is applicable to the cart as a whole.
- is_applicable_to_order() : bool
- Determine if the discount is applicable to the order as a whole.
- is_processing_order() : bool
- Return whether the discount type is being applied to a WooCommerce order.
- make() : static
- Make a new discount type.
- maybe_process_bundle_add_to_cart_form_validation() : bool
- Hook into woocommerce_add_to_cart_validation to handle bundle submissions.
- process_add_to_cart_form() : array<string|int, mixed>|bool
- Handles the form submission for adding a bundle to the cart.
- reset_total_discounted_products() : self
- Reset the total number of discounted products in the cart|order.
- reset_total_order_discount() : self
- Reset the total discount that needs to be applied to the order.
- run_cart_actions() : void
- Apply quantity-based discounts to the cart.
- run_order_actions() : void
- Apply quantity-based discounts to the order.
- set_discount() : self
- Set the discount object.
- set_proccesing_order() : self
- Flag whether the discount type is being applied to a WooCommerce order.
- set_total_discounted_products() : self
- Set the total number of discounted products in the cart|order.
- set_total_order_discount() : self
- Set the total discount that needs to be applied to the order.
- apply_virtual_coupon_to_order() : void
- Create and apply a virtual coupon to an order
- calculate_discount_amount() : float
- Calculate discount amount based on discount type and values
- calculate_relevant_products_quantity() : int
- Calculate the total quantity of relevant products.
- collect_bundle_instance_data() : array<string|int, mixed>
- Collect all items belonging to a specific bundle instance
- find_bundle_for_quantity() : array<string|int, mixed>|null
- Find the bundle that matches the given quantity.
- generate_bundle_success_message() : string
- Generate a success message for bundle items added to cart.
- generate_discount_for_entire_order() : void
- Generate a virtual coupon for the discount and apply it to the order when calculation_type is 'cart'.
- generate_discount_for_products_in_order() : void
- Generate a virtual coupon for the discount and apply it to the order when calculation_type is 'individual'.
- handle_bundle_quantity_changes() : void
- Handles changes in bundle item quantities within the cart.
- is_bundle_instance_applicable() : bool
- Checks if a specific bundle instance within a collection of items is applicable for discount.
- is_rest_api_context() : bool
- Check if the current request is a REST API context.
Constants
ORDER
public
mixed
ORDER
= 7
Properties
$discount
The discount object.
protected
Discount
$discount
$processing_order
Whether the discount type is processing a WooCommerce order.
protected
bool
$processing_order
= false
This is used so that we prevent applying discounts at a order line level due to the multitude of issues in how taxes are calculated in WooCommerce.
$total_discounted_products
The total number of discounted products in the cart|order.
protected
int
$total_discounted_products
= 0
This is used to track the number of discounted products in the cart|order but not all types will use this.
Not all discount types need to track the number of discounted products.
$total_order_discount
The total discount that needs to be applied to the order.
protected
float
$total_order_discount
= 0
$current_bundle_add_to_cart_context
Temporary storage for bundle item details during an add-to-cart operation.
private
array<string|int, mixed>
$current_bundle_add_to_cart_context
= []
Used to pass data to the woocommerce_add_cart_item_data filter.
Methods
apply_discount_to_cart()
Apply quantity-based discounts to the cart when calculation_type is 'cart'.
public
apply_discount_to_cart(WC_Cart|WC_Order &$cart_or_order, array<string|int, mixed> $products_to_discount, array<string|int, mixed> $bundle[, bool $is_order = false ]) : void
The discount here is spread across relevant products in the cart.
Parameters
- $cart_or_order : WC_Cart|WC_Order
-
The cart or order instance.
- $products_to_discount : array<string|int, mixed>
-
The products to discount (cart items or order items).
- $bundle : array<string|int, mixed>
-
The matched bundle configuration (contains 'discount' and 'type').
- $is_order : bool = false
-
Whether the discount is being applied to an order.
Return values
void —apply_discount_to_line_item()
Apply discount to an individual line item (cart or order).
public
apply_discount_to_line_item(array<string|int, mixed>|WC_Order_Item_Product &$item, array<string|int, mixed> $bundle_config_on_item[, bool $is_order = false ]) : void
Parameters
- $item : array<string|int, mixed>|WC_Order_Item_Product
-
The cart item array or WC_Order_Item_Product object.
- $bundle_config_on_item : array<string|int, mixed>
-
The bundle configuration stored on the item.
- $is_order : bool = false
-
Whether the discount is being applied to an order item.
Return values
void —decrease_total_discounted_products()
Decrease the total number of discounted products in the cart|order.
public
decrease_total_discounted_products(int $amount) : self
Parameters
- $amount : int
-
The amount to decrease the total number of discounted products by.
Return values
self —The discount type.
decrease_total_order_discount()
Decrease the total discount that needs to be applied to the order.
public
decrease_total_order_discount(float $amount) : self
Parameters
- $amount : float
-
The amount to decrease the total discount by.
Return values
self —The discount type.
filter_item_cart_data()
Adds custom data to a cart item when it's being added as part of a volume bundle.
public
filter_item_cart_data(array<string|int, mixed> $cart_item_data, int $product_id_being_added, int $variation_id_being_added, int $quantity_being_added) : array<string|int, mixed>
Parameters
- $cart_item_data : array<string|int, mixed>
-
Existing cart item data.
- $product_id_being_added : int
-
The product ID currently being added to the cart.
- $variation_id_being_added : int
-
The variation ID, if applicable.
- $quantity_being_added : int
-
The quantity of this specific item being added.
Tags
Return values
array<string|int, mixed> —Modified cart item data with bundle-specific information.
generate_virtual_coupon_for_order()
Generate a virtual coupon for the order.
public
generate_virtual_coupon_for_order(WC_Order $order) : void
This is used to apply the discount to the order and is not a real coupon.
This is mainly used during the creating of manual orders.
Parameters
- $order : WC_Order
-
The order object.
Return values
void —get_bundle_table_display_location()
Get the bundle table display location.
public
get_bundle_table_display_location() : string
Return values
string —get_bundles_for_product()
Get the bundles for a product.
public
get_bundles_for_product(int $product_id) : array<string|int, mixed>
Parameters
- $product_id : int
-
The product ID.
Return values
array<string|int, mixed> —get_cart_quantity_of_relevant_products()
Return the total quantity of relevant products in the cart.
public
get_cart_quantity_of_relevant_products(WC_Cart $cart) : int
Parameters
- $cart : WC_Cart
-
The cart object.
Return values
int —get_checked_bundle_index()
Get the index of the bundle that should be pre-checked by default.
public
get_checked_bundle_index() : int|null
Returns the index of a bundle marked as 'popular' if one exists, otherwise returns the first bundle index (0) or null if no bundles exist.
Return values
int|null —The index of the bundle to pre-check, or null if no bundles available.
get_configured_bundles()
Get the bundle configurations from settings.
public
get_configured_bundles() : array<string|int, mixed>
This is a helper to consistently get and prepare bundle data.
Return values
array<string|int, mixed> —get_default_settings_values()
Get the default settings values for this discount type.
public
static get_default_settings_values() : array<string|int, mixed>
Tags
Return values
array<string|int, mixed> —get_discount()
Get the discount object.
public
get_discount() : Discount
Return values
Discount —get_discount_amount_type()
Get the type of discount amount.
public
get_discount_amount_type() : string
Possible values: 'percentage', 'fixed'.
Return values
string —The type of discount amount.
get_name()
Get the name for this discount type.
public
static get_name() : string
Tags
Return values
string —get_order_quantity_of_relevant_products()
Return the total quantity of relevant products in the order.
public
get_order_quantity_of_relevant_products(WC_Order $order) : int
Parameters
- $order : WC_Order
-
The order object.
Return values
int —get_reduction()
Get the reduction to apply to products.
public
get_reduction() : Reduction
Return values
Reduction —The reduction to apply to products.
get_settings()
Get the settings for this discount type.
public
static get_settings() : array<string|int, mixed>
Tags
Return values
array<string|int, mixed> —get_slug()
Get the slug for this discount type.
public
static get_slug() : string
Tags
Return values
string —get_tooltip()
Get the tooltip for this discount type.
public
static get_tooltip() : string
Tags
Return values
string —get_total_discounted_products()
Return the total number of discounted products in the cart|order.
public
get_total_discounted_products() : int
Return values
int —get_total_order_discount()
Return the total discount that needs to be applied to the order.
public
get_total_order_discount() : float
Return values
float —has_sale_badge()
Determines if the discount has a sale badge enabled.
public
has_sale_badge() : bool
Return values
bool —increase_total_discounted_products()
Increase the total number of discounted products in the cart|order.
public
increase_total_discounted_products(int $amount) : self
Parameters
- $amount : int
-
The amount to increase the total number of discounted products by.
Return values
self —The discount type.
increase_total_order_discount()
Increase the total discount that needs to be applied to the order.
public
increase_total_order_discount(float $amount) : self
Parameters
- $amount : float
-
The amount to increase the total discount by.
Return values
self —The discount type.
is_applicable_to_cart()
Determine if the discount is applicable to the cart as a whole.
public
is_applicable_to_cart(WC_Cart $cart) : bool
Parameters
- $cart : WC_Cart
-
The cart object.
Return values
bool —True if the discount is applicable to the cart as a whole.
is_applicable_to_order()
Determine if the discount is applicable to the order as a whole.
public
is_applicable_to_order(WC_Order $order) : bool
Parameters
- $order : WC_Order
-
The order object.
Return values
bool —True if the discount is applicable to the order as a whole.
is_processing_order()
Return whether the discount type is being applied to a WooCommerce order.
public
is_processing_order() : bool
Return values
bool —make()
Make a new discount type.
public
static make(Discount $discount) : static
Parameters
- $discount : Discount
-
The discount object.
Return values
static —The new discount type.
maybe_process_bundle_add_to_cart_form_validation()
Hook into woocommerce_add_to_cart_validation to handle bundle submissions.
public
maybe_process_bundle_add_to_cart_form_validation(bool $passed, int $product_id, int $quantity) : bool
Parameters
- $passed : bool
- $product_id : int
- $quantity : int
Return values
bool —process_add_to_cart_form()
Handles the form submission for adding a bundle to the cart.
public
process_add_to_cart_form(int $product_id) : array<string|int, mixed>|bool
Parameters
- $product_id : int
-
The ID of the main product being added.
Tags
Return values
array<string|int, mixed>|bool —Array of successfully added item names on success, false on failure.
reset_total_discounted_products()
Reset the total number of discounted products in the cart|order.
public
reset_total_discounted_products() : self
Return values
self —The discount type.
reset_total_order_discount()
Reset the total discount that needs to be applied to the order.
public
reset_total_order_discount() : self
Return values
self —The discount type.
run_cart_actions()
Apply quantity-based discounts to the cart.
public
run_cart_actions(WC_Cart &$cart) : void
Parameters
- $cart : WC_Cart
-
The cart object.
Return values
void —run_order_actions()
Apply quantity-based discounts to the order.
public
run_order_actions(WC_Order &$order) : void
The discount here is processed differently to the cart discount. We do not discount the products directly but instead we generate a virtual coupon for the discount and apply it to the order.
In order to apply the virtual coupon to the order, we need to calculate the total discount amount for the order and then apply the discount to the order using the virtual coupon.
Parameters
- $order : WC_Order
Return values
void —set_discount()
Set the discount object.
public
set_discount(Discount $discount) : self
Parameters
- $discount : Discount
-
The discount object.
Return values
self —set_proccesing_order()
Flag whether the discount type is being applied to a WooCommerce order.
public
set_proccesing_order(bool $processing_order) : self
Parameters
- $processing_order : bool
-
Whether the discount type is processing a WooCommerce order.
Return values
self —The discount type.
set_total_discounted_products()
Set the total number of discounted products in the cart|order.
public
set_total_discounted_products(int $total_discounted_products) : self
Parameters
- $total_discounted_products : int
-
The total number of discounted products in the cart|order.
Return values
self —The discount type.
set_total_order_discount()
Set the total discount that needs to be applied to the order.
public
set_total_order_discount(float $total_order_discount) : self
Parameters
- $total_order_discount : float
-
The total discount that needs to be applied to the order.
Return values
self —The discount type.
apply_virtual_coupon_to_order()
Create and apply a virtual coupon to an order
private
apply_virtual_coupon_to_order(WC_Order $order, float $discount_amount) : void
Parameters
- $order : WC_Order
-
The order to apply the coupon to
- $discount_amount : float
-
The amount to discount
Return values
void —calculate_discount_amount()
Calculate discount amount based on discount type and values
private
calculate_discount_amount(float $subtotal, float $discount_value, string $discount_type[, int $quantity = 1 ]) : float
Parameters
- $subtotal : float
-
The subtotal to calculate discount on
- $discount_value : float
-
The discount value (percentage or fixed amount)
- $discount_type : string
-
The type of discount ('percentage' or 'value')
- $quantity : int = 1
-
Optional quantity for per-item fixed discounts
Return values
float —The calculated discount amount
calculate_relevant_products_quantity()
Calculate the total quantity of relevant products.
private
calculate_relevant_products_quantity(array<string|int, mixed> $products_to_discount[, bool $is_order = false ]) : int
Parameters
- $products_to_discount : array<string|int, mixed>
-
Array of products to calculate quantity for
- $is_order : bool = false
-
Whether we're calculating for an order or cart
Return values
int —Total quantity
collect_bundle_instance_data()
Collect all items belonging to a specific bundle instance
private
collect_bundle_instance_data(string $instance_id, array<string|int, mixed> $all_items[, bool $is_order = false ]) : array<string|int, mixed>
Parameters
- $instance_id : string
-
The bundle instance ID
- $all_items : array<string|int, mixed>
-
All cart items or order items
- $is_order : bool = false
-
Whether we're working with order items
Return values
array<string|int, mixed> —Collected data including items, total quantity and subtotal
find_bundle_for_quantity()
Find the bundle that matches the given quantity.
private
find_bundle_for_quantity(array<string|int, mixed> $bundles_config, int $current_quantity[, array<string|int, mixed> $products_to_discount = [] ][, bool $is_cart_discount = false ]) : array<string|int, mixed>|null
Parameters
- $bundles_config : array<string|int, mixed>
-
Array of bundle configurations from the discount settings. Each item should have at least 'quantity'.
- $current_quantity : int
-
The quantity to match against.
- $products_to_discount : array<string|int, mixed> = []
-
The products to discount (used if calculation is based on selected products).
- $is_cart_discount : bool = false
-
Whether the discount is being applied to the cart as a whole.
Return values
array<string|int, mixed>|null —The matching bundle configuration or null if not found.
generate_bundle_success_message()
Generate a success message for bundle items added to cart.
private
generate_bundle_success_message(array<string|int, mixed> $added_items_details) : string
Parameters
- $added_items_details : array<string|int, mixed>
-
Array of successfully added bundle items.
Return values
string —The formatted success message.
generate_discount_for_entire_order()
Generate a virtual coupon for the discount and apply it to the order when calculation_type is 'cart'.
private
generate_discount_for_entire_order(WC_Order $order, array<string|int, mixed> $relevant_order_items, array<string|int, mixed> $bundle) : void
The discount is based off the total quantity of relevant products in the order.
Parameters
- $order : WC_Order
-
The order.
- $relevant_order_items : array<string|int, mixed>
-
Array of WC_Order_Item_Product objects to consider for subtotal.
- $bundle : array<string|int, mixed>
-
The matched bundle configuration (contains 'discount' and 'type').
Return values
void —generate_discount_for_products_in_order()
Generate a virtual coupon for the discount and apply it to the order when calculation_type is 'individual'.
private
generate_discount_for_products_in_order(WC_Order $order, array<string|int, mixed> $order_items, array<string|int, mixed> $bundles_config) : void
The discount is calculated based on individual product quantities matching a bundle.
Parameters
- $order : WC_Order
-
The order.
- $order_items : array<string|int, mixed>
-
Array of WC_Order_Item_Product objects.
- $bundles_config : array<string|int, mixed>
-
Array of bundle configurations.
Return values
void —handle_bundle_quantity_changes()
Handles changes in bundle item quantities within the cart.
private
handle_bundle_quantity_changes(WC_Cart $cart, array<string|int, mixed> $bundles_config) : void
Re-evaluates bundle instances if item quantities change (e.g., user updates quantity in cart). If the new total quantity of a bundle instance matches a different valid tier, it updates the bundle configuration for all items in that instance. If no tier matches, it marks the bundle items as not eligible for discount.
Parameters
- $cart : WC_Cart
-
The WooCommerce cart object.
- $bundles_config : array<string|int, mixed>
-
The configured bundle tiers from discount settings.
Return values
void —is_bundle_instance_applicable()
Checks if a specific bundle instance within a collection of items is applicable for discount.
private
is_bundle_instance_applicable(string $instance_id, array<string|int, mixed> $bundle_config_on_item, array<string|int, mixed> $all_items_collection, array<string|int, mixed> $bundles_config_from_settings, bool $is_order_context) : bool
Parameters
- $instance_id : string
-
The ID of the bundle instance to check.
- $bundle_config_on_item : array<string|int, mixed>
-
The configuration of the bundle as stored on one of its items.
- $all_items_collection : array<string|int, mixed>
-
The collection of all cart or order items.
- $bundles_config_from_settings : array<string|int, mixed>
-
All configured bundle tiers from discount settings.
- $is_order_context : bool
-
True if checking order items, false for cart items.
Return values
bool —True if the bundle instance is applicable, false otherwise.
is_rest_api_context()
Check if the current request is a REST API context.
private
is_rest_api_context() : bool