{"id":2771,"date":"2024-12-31T20:26:31","date_gmt":"2024-12-31T20:26:31","guid":{"rendered":"https:\/\/meetanshi.com\/blog\/learn-to-validate-condition-rules-in-a-custom-module-in-magento-2-using-rulefactory\/"},"modified":"2025-06-16T14:44:35","modified_gmt":"2025-06-16T09:14:35","slug":"validate-condition-rules-in-a-custom-module-in-magento-2","status":"publish","type":"post","link":"https:\/\/meetanshi.com\/blog\/validate-condition-rules-in-a-custom-module-in-magento-2\/","title":{"rendered":"Learn to Validate Condition Rules in a Custom Module in Magento 2 Using ruleFactory"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Are you looking for a method to&nbsp;validate condition rules in a custom module for Magento 2? Read this blog post to find the complete programmatic method.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/meetanshi.com\/blog\/add-magento-shopping-cart-price-rules\/\" target=\"_blank\" rel=\"noreferrer noopener\">Cart price rules in Magento 2<\/a>&nbsp;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\u2019re working on a custom Magento 2 module, which requires interacting with the checkout process, you may need to validate the condition rules.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">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&nbsp;<a href=\"https:\/\/meetanshi.com\/blog\/magento-2-module-development\/\" target=\"_blank\" rel=\"noreferrer noopener\">custom modules in Magento 2<\/a>. 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.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Let\u2019s see how to do it.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Method to Validate Condition Rules in a Custom Module for Magento 2<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In&nbsp;<a href=\"https:\/\/business.adobe.com\/products\/magento\/magento-commerce.html\" target=\"_blank\" rel=\"noreferrer noopener\">Magento 2<\/a>, 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&nbsp;<code>MagentoRuleModelRuleFactory<\/code>&nbsp;class in Magento 2.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">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&nbsp;<a href=\"https:\/\/meetanshi.com\/blog\/wp-content\/uploads\/Rule.rar\" target=\"_blank\" rel=\"noreferrer noopener\">rule.rar<\/a>&nbsp;file, and extract it inside the&nbsp;<code>app\/code\/Vendor\/Module\/Model\/<\/code>&nbsp;directory. Further, you\u2019ll also need to create&nbsp;<strong>message.php<\/strong>&nbsp;in the same directory with the following code:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?php\n\nnamespace Vendor\\Module\\Model;\n\nuse Magento\\Quote\\Model\\Quote\\Address;\nuse Magento\\Rule\\Model\\AbstractModel;\nuse Magento\\Framework\\Model\\Context;\nuse Magento\\Framework\\Registry;\nuse Magento\\Framework\\Data\\FormFactory;\nuse Magento\\Framework\\Stdlib\\DateTime\\TimezoneInterface;\nuse Magento\\SalesRule\\Model\\Rule\\Condition\\CombineFactory;\nuse Magento\\SalesRule\\Model\\Rule\\Condition\\Product\\CombineFactory as ProductCombineFactory;\nuse Magento\\Framework\\Model\\ResourceModel\\AbstractResource;\nuse Magento\\Framework\\Data\\Collection\\AbstractDb;\n\n\/**\n * Class Message\n * @package Vendor\\Module\\Model\n *\/\nclass Message extends AbstractModel\n{\n    \/** @var string *\/\n    protected $_eventPrefix = 'vendor_module';\n\n    \/** @var string *\/\n    protected $_eventObject = 'vendor_message';\n\n    \/** @var CombineFactory *\/\n    protected $condCombineFactory;\n\n    \/** @var ProductCombineFactory *\/\n    protected $condProdCombineF;\n\n    \/** @var array *\/\n    protected $validatedAddresses = [];\n\n    \/**\n     * Message constructor.\n     *\n     * @param Context $context\n     * @param Registry $registry\n     * @param CombineFactory $condCombineFactory\n     * @param ProductCombineFactory $condProdCombineF\n     * @param AbstractResource|null $resource\n     * @param AbstractDb|null $resourceCollection\n     * @param array $data\n     *\/\n    public function __construct(\n        Context $context,\n        Registry $registry,\n        CombineFactory $condCombineFactory,\n        ProductCombineFactory $condProdCombineF,\n        AbstractResource $resource = null,\n        AbstractDb $resourceCollection = null,\n        array $data = []\n    ) {\n        $this->condCombineFactory = $condCombineFactory;\n        $this->condProdCombineF = $condProdCombineF;\n        parent::__construct($context, $registry, $resource, $resourceCollection, $data);\n    }\n\n    \/**\n     * Define resource model\n     *\/\n    protected function _construct()\n    {\n        $this->_init(\\Vendor\\Module\\Model\\ResourceModel\\Message::class);\n        $this->setIdFieldName('id');\n    }\n\n    \/**\n     * @return \\Magento\\SalesRule\\Model\\Rule\\Condition\\Combine\n     *\/\n    public function getConditionsInstance()\n    {\n        return $this->condCombineFactory->create();\n    }\n\n    \/**\n     * @return \\Magento\\SalesRule\\Model\\Rule\\Condition\\Product\\Combine\n     *\/\n    public function getActionsInstance()\n    {\n        return $this->condProdCombineF->create();\n    }\n\n    \/**\n     * Check if address is already validated\n     *\n     * @param Address|int $address\n     * @return bool\n     *\/\n    public function hasIsValidForAddress($address)\n    {\n        return isset($this->validatedAddresses[$this->_getAddressId($address)]);\n    }\n\n    \/**\n     * Set validation result for address\n     *\n     * @param Address|int $address\n     * @param bool $validationResult\n     * @return $this\n     *\/\n    public function setIsValidForAddress($address, $validationResult)\n    {\n        $this->validatedAddresses[$this->_getAddressId($address)] = (bool) $validationResult;\n        return $this;\n    }\n\n    \/**\n     * Get validation result for address\n     *\n     * @param Address|int $address\n     * @return bool\n     *\/\n    public function getIsValidForAddress($address)\n    {\n        return $this->validatedAddresses[$this->_getAddressId($address)] ?? false;\n    }\n\n    \/**\n     * Get address ID\n     *\n     * @param Address|int $address\n     * @return int|null\n     *\/\n    private function _getAddressId($address)\n    {\n        return ($address instanceof Address) ? $address->getId() : $address;\n    }\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Once you\u2019ve created the required models in the custom module, you can access and validate condition rules.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now, let\u2019s say we want to validate Magento 2 custom rule condition on order placement. We can use&nbsp;<code>validate()<\/code>&nbsp;function, for example:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?php\n\nnamespace Vendor\\Module\\Observer;\n\nuse Psr\\Log\\LoggerInterface;\nuse Magento\\Quote\\Model\\QuoteFactory;\nuse Vendor\\Module\\Model\\RuleFactory;\nuse Magento\\Store\\Model\\StoreManagerInterface;\nuse Magento\\Sales\\Model\\OrderFactory;\n\n\/**\n * Class OrderPlace\n * @package Vendor\\Module\\Observer\n *\/\nclass OrderPlace implements \\Magento\\Framework\\Event\\ObserverInterface\n{\n    \/** @var LoggerInterface *\/\n    protected $logger;\n\n    \/** @var StoreManagerInterface *\/\n    protected $_storeManager;\n\n    \/** @var RuleFactory *\/\n    protected $_ruleFactory;\n\n    \/** @var QuoteFactory *\/\n    protected $_quoteFactory;\n\n    \/** @var OrderFactory *\/\n    protected $_order;\n\n    \/**\n     * OrderPlace constructor.\n     * \n     * @param LoggerInterface $logger\n     * @param QuoteFactory $quoteFactory\n     * @param OrderFactory $_order\n     * @param RuleFactory $ruleFactory\n     * @param StoreManagerInterface $storeManager\n     *\/\n    public function __construct(\n        QuoteFactory $quoteFactory,\n        RuleFactory $ruleFactory,\n        OrderFactory $_order,\n        LoggerInterface $logger,\n        StoreManagerInterface $storeManager\n    ) {\n        $this->logger = $logger;\n        $this->_storeManager = $storeManager;\n        $this->_ruleFactory = $ruleFactory;\n        $this->_quoteFactory = $quoteFactory;\n        $this->_order = $_order;\n    }\n\n    \/**\n     * Execute observer\n     *\n     * @param \\Magento\\Framework\\Event\\Observer $observer\n     *\/\n    public function execute(\\Magento\\Framework\\Event\\Observer $observer)\n    {\n        try {\n            $orderIds = $observer->getEvent()->getOrderIds();\n            $orderId = $orderIds[0];\n            $order = $this->_order->create()->load($orderId);\n\n            \/\/ Load custom rule condition model\n            $model = $this->_ruleFactory->create();\n\n            \/\/ Load quote from quote ID\n            $quoteId = $order->getQuoteId();\n            $quote = $this->_quoteFactory->create()->load($quoteId);\n\n            \/\/ Load address from quote for validation\n            $address = $quote->getShippingAddress() ?: $quote->getBillingAddress();\n\n            \/\/ Load quote items for validation\n            $items = $quote->getAllItems();\n\n            \/\/ Get all rules from the custom rule table\n            $ruleData = $model->getCollection();\n\n            foreach ($ruleData as $rule) {\n                \/\/ Validate address and items using custom rule\n                $validate = $rule->validate($address, $items);\n\n                \/\/ Add your code based on validate true or false\n            }\n\n            return true;\n        } catch (\\Exception $e) {\n            $this->logger->info($e->getMessage());\n        }\n    }\n}\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Note:&nbsp;<\/strong>Do not forget to replace&nbsp;<code>Vendor<\/code>&nbsp;and&nbsp;<code>Module<\/code>&nbsp;names in the above code.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So, that\u2019s it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Also you may need to&nbsp;<a href=\"https:\/\/meetanshi.com\/blog\/add-rule-condition-field-in-magento-2-admin-ui-component-form\/\">add rule condition field in Magento 2 admin UI component form<\/a>&nbsp;if you want to customize your own feature for making your shopping platform better because of the growing online stores.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You can use the above method to validate condition rules in a custom module for Magento 2.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">As the default Magento 2 does not offer custom validations, We have come up with a method to add <a href=\"https:\/\/meetanshi.com\/blog\/add-custom-js-validation-rule-in-magento-2\/\" data-type=\"link\" data-id=\"https:\/\/meetanshi.com\/blog\/add-custom-js-validation-rule-in-magento-2\/\">custom JS validation rule in Magento 2<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Did this tutorial help you? Share it with your developer friends via social media.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In case you still face any queries, feel free to comment. I would be happy to help you!  <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Thank you!  <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Are you looking for a method to&nbsp;validate condition rules in a custom module for Magento 2? Read this blog post to find the complete programmatic&#8230;<\/p>\n","protected":false},"author":13,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[34],"tags":[],"class_list":["post-2771","post","type-post","status-publish","format-standard","hentry","category-magento"],"acf":[],"_links":{"self":[{"href":"https:\/\/meetanshi.com\/blog\/wp-json\/wp\/v2\/posts\/2771","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/meetanshi.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/meetanshi.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/meetanshi.com\/blog\/wp-json\/wp\/v2\/users\/13"}],"replies":[{"embeddable":true,"href":"https:\/\/meetanshi.com\/blog\/wp-json\/wp\/v2\/comments?post=2771"}],"version-history":[{"count":5,"href":"https:\/\/meetanshi.com\/blog\/wp-json\/wp\/v2\/posts\/2771\/revisions"}],"predecessor-version":[{"id":16905,"href":"https:\/\/meetanshi.com\/blog\/wp-json\/wp\/v2\/posts\/2771\/revisions\/16905"}],"wp:attachment":[{"href":"https:\/\/meetanshi.com\/blog\/wp-json\/wp\/v2\/media?parent=2771"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/meetanshi.com\/blog\/wp-json\/wp\/v2\/categories?post=2771"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/meetanshi.com\/blog\/wp-json\/wp\/v2\/tags?post=2771"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}