Skip to content

Extend Discounts

By extending Discounts, you can increase flexibility and control over how promotions are applied to suit your unique business rules. Together with the existing events and the Discounts PHP API, extending discounts gives you the ability to cover additional use cases related to selling products.

Create custom conditions

With custom conditions you can create more advanced discounts that apply only in specific scenarios.

The following example create discounts valid for your customers only on the anniversary of their account creation. Having a custom condition allows you to model this scenario using a single discount, hiding all the complexity within the condition.

The logic for both the conditions and rules is specified using Symfony's expression language.

Available expressions

The following expressions are available for conditions and rules:

Type Name Value Available for
Function get_current_region() Region object of the current siteaccess. Conditions, rules
Function is_in_category() true/false, depending if a product belongs to given product categories. Conditions, rules
Function is_user_in_customer_group() true/false, depending if a user belongs to given customer groups. Conditions, rules
Function calculate_purchase_amount() Purchase amount, calculated for all products in the cart before the discounts are applied. Conditions, rules
Function is_product_in_product_codes() true/false, depending if the product is part of the given list. Conditions, rules
Variable cart Cart object associated with current context. Conditions, rules
Variable currency Currency object of the current siteaccess. Conditions, rules
Variable customer_group Customer group object associated with given price context or the current user. Conditions, rules
Variable amount Original price of the product Rules
Variable product Product object Rules

Custom expressions

You can create your own variables and functions to make creating the conditions easier. To create the condition checking the registration date, the following example will use an additinal variable and a function:

  • current_user, a variable with the current User object

To add it, create a class implementing the DiscountVariablesResolverInterface:

1
todo: verify

And mark it as a service using the ibexa.discounts.expression_language.variable_resolver service tag:

1
todo: verify
  • is_anniversary(), a function returning a boolean value indicating if the two dates passed as arguments fall on the same day.
1
todo: verify

Mark it as a service using the ibexa.discounts.expression_language.function service tag and specify the function name in the service definition.

1
todo: verify

Two new expressions are now available for use in custom conditions and rules.

Implement custom condition

Now, create the condition by creating a class implementing the DiscountConditionInterface.

1
todo: verify

The expression can evaluate to true or false depending on the custom expressions values. An additional variable, today, is defined to store the current date for comparison.

For each condition class you must create a dedicated condition factory, a class implementing the \Ibexa\Discounts\Repository\DiscountCondition\DiscountConditionFactoryInterface inteface.

This allows you to create conditions when working in the context of the Symfony service container.

1
todo

Mark it as a service using the ibexa.discounts.condition.factory service tag and specify the condition's identifier.

1
todo

Create custom rules

To implement a custom rule, create a class implementing the DiscountRuleInterface.

The following example implements a purchasing power parity discount, adjusting product's price in the cart based on buyer's region.

1
todo

As with conditions, create a dedicated rule factory.

1
todo

Mark it as a service using the ibexa.discounts.condition.factory service tag and specify the rule's type.

1
todo

Custom discount formatting

You can adjust how each discount type is displayed when using the ibexa_discounts_render_discount_badge Twig function by implementing a custom formatter.

To do it, create a class implementing the DiscountValueFormatterInterface and use the ibexa.discounts.value.formatter service tag:

1
todo
1
todo

Change discount priority

You can change the the defualt discount priority by creating a class implementing the DiscountPrioritizationStrategyInterface and aliasing to it the default implementation.

The example below decorates the default implementation to prioritize recently created discounts above all the others.

1
todo
1
todo

Form integration

Condition

Rules