{"id":11439,"date":"2019-12-16T07:48:08","date_gmt":"2019-12-16T07:48:08","guid":{"rendered":"https:\/\/www.mageworx.com\/blog\/?p=11439"},"modified":"2022-05-20T12:20:11","modified_gmt":"2022-05-20T12:20:11","slug":"example-of-magento-2-module-with-conditions-model-and-fieldset-part-2","status":"publish","type":"post","link":"https:\/\/www.mageworx.com\/blog\/example-of-magento-2-module-with-conditions-model-and-fieldset-part-2","title":{"rendered":"Example of Magento 2 Module with Conditions Model and Fieldset (Part 2)"},"content":{"rendered":"\n<!-- SEO Ultimate (http:\/\/www.seodesignsolutions.com\/wordpress-seo\/) - Code Inserter module -->\n<!-- Google Tag Manager (noscript) -->\r\n<noscript><iframe src=\"https:\/\/www.googletagmanager.com\/ns.html?id=GTM-5DTCW7B8\"\r\nheight=\"0\" width=\"0\" style=\"display:none;visibility:hidden\"><\/iframe><\/noscript>\r\n<!-- End Google Tag Manager (noscript) -->\n<!-- \/SEO Ultimate -->\n\n<span class=\"span-reading-time rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">Reading Time: <\/span> <span class=\"rt-time\"> 4<\/span> <span class=\"rt-label rt-postfix\">minutes<\/span><\/span>\n<p>In the <a href=\"https:\/\/www.mageworx.com\/blog\/2016\/09\/magento-2-module-with-conditions-model-fieldset\/\">previous article<\/a>, we took a look at the code that allows us to create a <em>Rules<\/em> model with an interface in the Admin Panel. That was a significant part of the module, which is useless by itself if you don&#8217;t learn how to use it on the frontend. Thus, it\u2019s high time to figure out the importance of rules and conditions within them.<\/p>\n\n\n\n<p>Any validation model inherits conditions that help validate an object. As a result, based on this validation check, we can perform certain activities. In our example, we\u2019ll create a rule that allows defining if there is an item with the `heavy_weight` attribute value that equals 1 (true) in the shopping cart. In case such an item gets found, we will display a block with the following message \u2018You have some heavyweight items in your cart, please contact us to <a href=\"https:\/\/www.mageworx.com\/delivery-date-magento-2.html\" data-type=\"URL\" data-id=\"https:\/\/www.mageworx.com\/delivery-date-magento-2.html\">discuss delivery<\/a>.\u2019 on the shopping cart page.<\/p>\n\n\n\n<p>*It is critical to understand that the way we load our <em>Rule<\/em> model won\u2019t fit a real-life case 100%. This is for the reason that we\u2019ll neatly specify a rule with which the <em>Rule<\/em> <em>ID <\/em>must be loaded. Based on it, we will validate the known object with the items from the cart\u2015shipping address. In a module that has not been created as an example, <em>Rules <\/em>objects must be loaded as a special class, which will validate them against their compatibility with the current environment, i.e., a store, a customer and its group, time, date, etc. We will surely deal with this matter in a series of further related articles. *<\/p>\n\n\n\n<p><strong>Important side note:<\/strong><\/p>\n\n\n\n<p>Now, the code of the module is freely available in the public repository on github.com. Thus, no more code copy-pasting from our blog posts. All the required code is conveniently available<a href=\"https:\/\/github.com\/SiarheyUchukhlebau\/Vendor_Rules\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\"> here<\/a>.<\/p>\n\n\n\n<p>First, let\u2019s create a new rule in the Admin Panel, which will help find a product with the attribute value specified as heavy_weight:<br><\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/lh4.googleusercontent.com\/cJu1Suk2FrsVSMblJ2_-OPpimqcvuwG5oxLsg0tVBuuyBSQdr2PEZLIo-tAcvSfN78T2N1eLil1rO7jWZJDp_kWa1HpB_krWBZb7pOvX4uOXUDNDmyBmELdpwRiJ48c6dxLli3Vn\" alt=\"Example of Magento 2 Module with Conditions Model and Fieldset (Part 2) | MageWorx Blog\"\/><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/lh3.googleusercontent.com\/mJOk8ZTf2bcWKpoEVIUkfJ-FV5Fe-BYTZTuE8Y6aiBszHLVdD83QNpmgdvpsGoCjAYgKoPLlc9Qc6n3qLgkY9YmWn1sEA_c1UF9um0u_BcyAWY0yQVlNtCOzUYDKToniFWjmfcXS\" alt=\"Example of Magento 2 Module with Conditions Model and Fieldset (Part 2) | MageWorx Blog\"\/><\/figure><\/div>\n\n\n\n<p>*If you don\u2019t see your attribute in the attributes list in conditions, make sure to check this attribute\u2019s configuration first. It shall be done to ensure the<em> Use For Promo Rule Conditions<\/em> option is not disabled for it.<\/p>\n\n\n\n<p>To do that, go to Stores &gt; Attributes &gt; Product. Then, select your attribute from the list &gt; Storefront Properties &gt;. Use for Promo Rule Conditions must be set as \u2018Yes\u2019. Please, refer to the screenshot below for more details:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/lh3.googleusercontent.com\/UA8hRk5wrCfBzCxIoRW8hI8CPDyel_ivn8AVtUw6luS9oLvJFIKAvuS3Yf-2UwWsgenijK7I7Jz8Z8UwCxyj3PgF03Vx13hm1cqn9BfJNLmZ1VW-OJjKj_AHZjR7wuK69ddLd6q4\" alt=\"Example of Magento 2 Module with Conditions Model and Fieldset (Part 2) | MageWorx Blog\"\/><\/figure><\/div>\n\n\n\n<p>My rule has ID 1. Further, I\u2019ll use it to facilitate the process of loading. Now, let\u2019s update the layout of the cart page by adding our new block that displays a new message to it.<br><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>`app\/code\/Vendor\/Rules\/view\/frontend\/layout\/checkout_cart_index.xml`\n```xml\n&lt;?xml version=\"1.0\"?&gt;\n&lt;page xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"urn:magento:framework:View\/Layout\/etc\/page_configuration.xsd\"&gt;\n    &lt;body&gt;\n        &lt;referenceContainer name=\"checkout.cart.form.before\"&gt;\n            &lt;block class=\"Vendor\\Rules\\Block\\Cart\\RuleExample\" name=\"custom_block_with_rules\" template=\"Vendor_Rules::cart\/example.phtml\"\/&gt;\n        &lt;\/referenceContainer&gt;\n    &lt;\/body&gt;\n&lt;\/page&gt;\n```<\/code><\/pre>\n\n\n\n<p>As you might have noticed from the layout, we will need 2 more files: a block and a template. Let\u2019s create them:<br><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>`app\/code\/Vendor\/Rules\/view\/frontend\/templates\/cart\/example.phtml`\n```php\n&lt;?php\n\/** @var \\Vendor\\Rules\\Block\\Cart\\RuleExample $block *\/\n?&gt;\n&lt;?= $block-&gt;getMessage();?&gt;\n```<\/code><\/pre>\n\n\n\n<p>It\u2019s all made simple in the template, i.e., just a message output. If required, you can add a layout as needed.<\/p>\n\n\n\n<p>Keep in mind that when using such templates on full-page cache pages, the results will be cached as well. A different approach should be used for such pages, which is described in detail in the <a href=\"https:\/\/devdocs.magento.com\/guides\/v2.3\/extension-dev-guide\/cache\/page-caching\/private-content.html\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\">official Magento dev docs<\/a>.<br><\/p>\n\n\n\n<p>It\u2019s time to add the main class from the example. Here\u2019s the block class:<br><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>heckout\\Model\\Session as CheckoutSession;\nuse Magento\\Framework\\Exception\\LocalizedException;\nuse Magento\\Framework\\View\\Element\\Template;\nuse Magento\\Quote\\Model\\Quote\\Address as QuoteAddress;\nuse Vendor\\Rules\\Model\\Rule;\nuse Vendor\\Rules\\Model\\ResourceModel\\Rule\\CollectionFactory as RulesCollectionFactory;\n\/**\n * Class RuleExample\n *\/\nclass RuleExample extends Template\n{\n    \/**\n     * @var RulesCollectionFactory\n     *\/\n    private $rulesCollectionFactory;\n    \/**\n     * @var string\n     *\/\n    private $message;\n    \/**\n     * @var CheckoutSession\n     *\/\n    private $checkoutSession;\n    \/**\n     * RuleExample constructor.\n     *\n     * @param Template\\Context $context\n     * @param RulesCollectionFactory $rulesCollectionFactory\n     * @param CheckoutSession $checkoutSession\n     * @param array $data\n     *\/\n    public function __construct(\n        Template\\Context $context,\n        RulesCollectionFactory $rulesCollectionFactory,\n        CheckoutSession $checkoutSession,\n        array $data = &#91;]\n    ) {\n        $this-&gt;rulesCollectionFactory = $rulesCollectionFactory;\n        $this-&gt;checkoutSession        = $checkoutSession;\n        $this-&gt;message                = '';\n        parent::__construct($context, $data);\n    }\n    \/**\n     * @return string\n     *\/\n    public function getMessage(): string\n    {\n        if ($this-&gt;message) {\n            return $this-&gt;message;\n        }\n        $shippingAddress = $this-&gt;getShippingAddress();\n        if (!$shippingAddress) {\n            return $this-&gt;message;\n        }\n        $rule = $this-&gt;getRule();\n        if ($rule &amp;&amp; $rule-&gt;validate($shippingAddress)) {\n            $this-&gt;message = __(\n                'You have some heavy weight items in your cart, please contact us to discuss delivery.'\n            );\n        }\n        return $this-&gt;message;\n    }\n    \/**\n     * @return Rule|null\n     *\/\n    private function getRule(): ?Rule\n    {\n        \/** @var \\Vendor\\Rules\\Model\\ResourceModel\\Rule\\Collection $rulesCollection *\/\n        $rulesCollection = $this-&gt;rulesCollectionFactory-&gt;create();\n        $rulesCollection-&gt;addFilter('rule_id', 1);\n        \/** @var Rule|null $rule *\/\n        $rule = $rulesCollection-&gt;getFirstItem();\n        return $rule;\n    }\n    \/**\n     * @return QuoteAddress|null\n     *\/\n    private function getShippingAddress(): ?QuoteAddress\n    {\n        \/** @var \\Magento\\Quote\\Model\\Quote $quote *\/\n        try {\n            $quote = $this-&gt;checkoutSession-&gt;getQuote();\n        } catch (LocalizedException $exception) {\n            return null;\n        }\n        if (!$quote) {\n            return null;\n        }\n        return $quote-&gt;getIsVirtual() ? $quote-&gt;getBillingAddress() : $quote-&gt;getShippingAddress();\n    }\n}\n```<\/code><\/pre>\n\n\n\n<p>Let\u2019s dwell on this class a little as that\u2019s precisely where the validation is hidden. It has solely one public method that we use in our template. It\u2019s the `getMessage()` method. Inside the method, a correct rule gets specified (it will validate our cart), as well as the shipping address (it will be used for validation).<\/p>\n\n\n\n<p>We get the shipping address using the standard frontend functionality, i.e., by requesting it from the checkout session. We populate the rule from the collection by using a filter that is based on ID. (As I mentioned in the beginning of this post, it is not the best means and can be used solely as an example. Make sure to describe the method of getting the rule the way that suits you the best). When having 2 mandatory objects in our block, it\u2019s only left for us to check what the `$rule-&gt;validate($shippingAddress)`method of our rule will return, i.e., true or false. Based on the results, create (or not) a message that will be displayed on the cart page in our template. Inside the rule model, it works as follows:<br><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>```php\n    \/**\n     * Validate rule conditions to determine if rule can run\n     *\n     * @param \\Magento\\Framework\\DataObject $object\n     * @return bool\n     *\/\n    public function validate(\\Magento\\Framework\\DataObject $object)\n    {\n        return $this-&gt;getConditions()-&gt;validate($object);\n    }\n```<\/code><\/pre>\n\n\n\n<p>This method already exists in the `Magento\\Rule\\Model\\AbstractModel` abstract class, from which our `Vendor\\Rules\\Model\\Rule` class rules get inherited. If you need custom validation, it is always possible to add the `validate` own method to the class rules with or without invoking a parent method.<br><\/p>\n\n\n\n<p>Here\u2019s what we\u2019ll get as a result on the frontend:<\/p>\n\n\n\n<p>*The heavy_weight&nbsp; attribute value of the T1 Blue product equals 1:<\/p>\n\n\n\n<p>&nbsp;![Valid product in a cart]<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/lh3.googleusercontent.com\/gNwrOmeqPpQjTHCesXB56WAI6hSwz-HoQG3UbNSjp4AtKHhCFJdutQlT2VmuBwr1sfUSALeVvEx7xkrckhapjq3H7Re96UDQ2qLnxqmhpuC8rW_bcztDJ3nHeaEWTiPCpgNOyfzG\" alt=\"Example of Magento 2 Module with Conditions Model and Fieldset (Part 2) | MageWorx Blog\"\/><\/figure><\/div>\n\n\n\n<p>*The heavy_weight&nbsp; attribute value of the T1 Red product equals 0:<\/p>\n\n\n\n<p>&nbsp;![Valid product in a cart]<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/lh3.googleusercontent.com\/iTho6vPVgdGoXuF1UJVokNvLV-HOCqQSXoBYi_4t5zYa6Z4vKhsbktekSSvzA_CW_OVF9KsQdtRtgdpucvnD_z2Hh2lIfdg5PIuCZbne4JcqUeQnXj0xvBjRIUs9AwLHtkYaufpR\" alt=\"Example of Magento 2 Module with Conditions Model and Fieldset (Part 2) | MageWorx Blog\"\/><\/figure><\/div>\n\n\n\n<p>As you can see on the screenshots, our message from the block gets displayed for the T1 Blue product under the cart label. For the red one, conversely, the message does not get displayed. This means that the rule works correctly.<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p>Thank you all for taking the time to read the article. Should you have any questions, feel free to share them in the comments below. I\u2019ll be happy to assist.<br><\/p>\n","protected":false},"excerpt":{"rendered":"<p><span class=\"span-reading-time rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">Reading Time: <\/span> <span class=\"rt-time\"> 4<\/span> <span class=\"rt-label rt-postfix\">minutes<\/span><\/span>In the previous article, we took a look at the code that allows us to create a Rules model with an interface in the Admin Panel. That was a significant part of the module, which is useless by itself if you don&#8217;t learn how to use it on the frontend. Thus, it\u2019s high time to [&hellip;]<\/p>\n","protected":false},"author":15,"featured_media":12401,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[255,425],"tags":[436],"class_list":{"0":"post-11439","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-magento-2","8":"category-magento-how-tos","9":"tag-developer-diaries"},"_links":{"self":[{"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/posts\/11439","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/users\/15"}],"replies":[{"embeddable":true,"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/comments?post=11439"}],"version-history":[{"count":6,"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/posts\/11439\/revisions"}],"predecessor-version":[{"id":16086,"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/posts\/11439\/revisions\/16086"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/media\/12401"}],"wp:attachment":[{"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/media?parent=11439"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/categories?post=11439"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/tags?post=11439"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}