🔥 Just Launched! Werra Premium Template for HyväSee it in Action

Learn to Validate Condition Rules in a Custom Module in Magento 2 Using ruleFactory

By Jignesh ParmarUpdated on Jun 16, 2025 5 min read

Are you looking for a method to validate condition rules in a custom module for Magento 2? Read this blog post to find the complete programmatic method.

Cart price rules in Magento 2 are useful for offering discounts based on conditions. It helps merchants get more sales by crafting discount offers strategically. The Magento platform validates the conditions and applies the discount offers on eligible orders. If you’re working on a custom Magento 2 module, which requires interacting with the checkout process, you may need to validate the condition rules.

Recently, I faced a similar situation while working on a custom module. I wanted to get all the cart price rules and validate them through custom modules in Magento 2. On my first try, I was able to get the list of custom price rules, but it does not seem to validate the rules. Later on, I found a working method to validate condition rules in Magento 2 custom module.

Let’s see how to do it.

Method to Validate Condition Rules in a Custom Module for Magento 2

In Magento 2, the Rule Factory class is used to create rule objects for various conditions, such as shopping cart price rules, catalogue price rules, and promotion rules. This can be done by using the MagentoRuleModelRuleFactory class in Magento 2.

You need to create models to load the available rules and validate them through Rule Factory. This ensures that only a valid cart price is applied to the quote. To do that, download this rule.rar file, and extract it inside the app/code/Vendor/Module/Model/ directory. Further, you’ll also need to create message.php in the same directory with the following code:

<?php

namespace Vendor\Module\Model;

use Magento\Quote\Model\Quote\Address;
use Magento\Rule\Model\AbstractModel;
use Magento\Framework\Model\Context;
use Magento\Framework\Registry;
use Magento\Framework\Data\FormFactory;
use Magento\Framework\Stdlib\DateTime\TimezoneInterface;
use Magento\SalesRule\Model\Rule\Condition\CombineFactory;
use Magento\SalesRule\Model\Rule\Condition\Product\CombineFactory as ProductCombineFactory;
use Magento\Framework\Model\ResourceModel\AbstractResource;
use Magento\Framework\Data\Collection\AbstractDb;

/**
 * Class Message
 * @package Vendor\Module\Model
 */
class Message extends AbstractModel
{
    /** @var string */
    protected $_eventPrefix = 'vendor_module';

    /** @var string */
    protected $_eventObject = 'vendor_message';

    /** @var CombineFactory */
    protected $condCombineFactory;

    /** @var ProductCombineFactory */
    protected $condProdCombineF;

    /** @var array */
    protected $validatedAddresses = [];

    /**
     * Message constructor.
     *
     * @param Context $context
     * @param Registry $registry
     * @param CombineFactory $condCombineFactory
     * @param ProductCombineFactory $condProdCombineF
     * @param AbstractResource|null $resource
     * @param AbstractDb|null $resourceCollection
     * @param array $data
     */
    public function __construct(
        Context $context,
        Registry $registry,
        CombineFactory $condCombineFactory,
        ProductCombineFactory $condProdCombineF,
        AbstractResource $resource = null,
        AbstractDb $resourceCollection = null,
        array $data = []
    ) {
        $this->condCombineFactory = $condCombineFactory;
        $this->condProdCombineF = $condProdCombineF;
        parent::__construct($context, $registry, $resource, $resourceCollection, $data);
    }

    /**
     * Define resource model
     */
    protected function _construct()
    {
        $this->_init(\Vendor\Module\Model\ResourceModel\Message::class);
        $this->setIdFieldName('id');
    }

    /**
     * @return \Magento\SalesRule\Model\Rule\Condition\Combine
     */
    public function getConditionsInstance()
    {
        return $this->condCombineFactory->create();
    }

    /**
     * @return \Magento\SalesRule\Model\Rule\Condition\Product\Combine
     */
    public function getActionsInstance()
    {
        return $this->condProdCombineF->create();
    }

    /**
     * Check if address is already validated
     *
     * @param Address|int $address
     * @return bool
     */
    public function hasIsValidForAddress($address)
    {
        return isset($this->validatedAddresses[$this->_getAddressId($address)]);
    }

    /**
     * Set validation result for address
     *
     * @param Address|int $address
     * @param bool $validationResult
     * @return $this
     */
    public function setIsValidForAddress($address, $validationResult)
    {
        $this->validatedAddresses[$this->_getAddressId($address)] = (bool) $validationResult;
        return $this;
    }

    /**
     * Get validation result for address
     *
     * @param Address|int $address
     * @return bool
     */
    public function getIsValidForAddress($address)
    {
        return $this->validatedAddresses[$this->_getAddressId($address)] ?? false;
    }

    /**
     * Get address ID
     *
     * @param Address|int $address
     * @return int|null
     */
    private function _getAddressId($address)
    {
        return ($address instanceof Address) ? $address->getId() : $address;
    }
}

Once you’ve created the required models in the custom module, you can access and validate condition rules.

Now, let’s say we want to validate Magento 2 custom rule condition on order placement. We can use validate() function, for example:

<?php

namespace Vendor\Module\Observer;

use Psr\Log\LoggerInterface;
use Magento\Quote\Model\QuoteFactory;
use Vendor\Module\Model\RuleFactory;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Sales\Model\OrderFactory;

/**
 * Class OrderPlace
 * @package Vendor\Module\Observer
 */
class OrderPlace implements \Magento\Framework\Event\ObserverInterface
{
    /** @var LoggerInterface */
    protected $logger;

    /** @var StoreManagerInterface */
    protected $_storeManager;

    /** @var RuleFactory */
    protected $_ruleFactory;

    /** @var QuoteFactory */
    protected $_quoteFactory;

    /** @var OrderFactory */
    protected $_order;

    /**
     * OrderPlace constructor.
     * 
     * @param LoggerInterface $logger
     * @param QuoteFactory $quoteFactory
     * @param OrderFactory $_order
     * @param RuleFactory $ruleFactory
     * @param StoreManagerInterface $storeManager
     */
    public function __construct(
        QuoteFactory $quoteFactory,
        RuleFactory $ruleFactory,
        OrderFactory $_order,
        LoggerInterface $logger,
        StoreManagerInterface $storeManager
    ) {
        $this->logger = $logger;
        $this->_storeManager = $storeManager;
        $this->_ruleFactory = $ruleFactory;
        $this->_quoteFactory = $quoteFactory;
        $this->_order = $_order;
    }

    /**
     * Execute observer
     *
     * @param \Magento\Framework\Event\Observer $observer
     */
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        try {
            $orderIds = $observer->getEvent()->getOrderIds();
            $orderId = $orderIds[0];
            $order = $this->_order->create()->load($orderId);

            // Load custom rule condition model
            $model = $this->_ruleFactory->create();

            // Load quote from quote ID
            $quoteId = $order->getQuoteId();
            $quote = $this->_quoteFactory->create()->load($quoteId);

            // Load address from quote for validation
            $address = $quote->getShippingAddress() ?: $quote->getBillingAddress();

            // Load quote items for validation
            $items = $quote->getAllItems();

            // Get all rules from the custom rule table
            $ruleData = $model->getCollection();

            foreach ($ruleData as $rule) {
                // Validate address and items using custom rule
                $validate = $rule->validate($address, $items);

                // Add your code based on validate true or false
            }

            return true;
        } catch (\Exception $e) {
            $this->logger->info($e->getMessage());
        }
    }
}

Note: Do not forget to replace Vendor and Module names in the above code.

So, that’s it.

Also you may need to add rule condition field in Magento 2 admin UI component form if you want to customize your own feature for making your shopping platform better because of the growing online stores.

You can use the above method to validate condition rules in a custom module for Magento 2.

As the default Magento 2 does not offer custom validations, We have come up with a method to add custom JS validation rule in Magento 2

Did this tutorial help you? Share it with your developer friends via social media.

In case you still face any queries, feel free to comment. I would be happy to help you!

Thank you!

Jignesh Parmar Full Image
Article byJignesh Parmar

An expert in his field, Jignesh is the team leader at Meetanshi and a certified Magento developer. His passion for Magento has inspired others in the team too. Apart from work, he is a cricket lover.