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
author

Barn2 Plugins support@barn2.com

license

GPL-3.0

copyright

Barn2 Media Ltd

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

Properties

$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
inheritdoc
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
inheritdoc
Return values
array<string|int, mixed>

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
inheritdoc
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_settings()

Get the settings for this discount type.

public static get_settings() : array<string|int, mixed>
Tags
inheritdoc
Return values
array<string|int, mixed>

get_slug()

Get the slug for this discount type.

public static get_slug() : string
Tags
inheritdoc
Return values
string

get_tooltip()

Get the tooltip for this discount type.

public static get_tooltip() : string
Tags
inheritdoc
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
inheritdoc
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
Return values
bool

Search results