Exemple de module Magento 2 avec modèle de conditions et ensemble de champs (partie 2)

Publié: 2019-12-16

Dans l'article précédent, nous avons examiné le code qui nous permet de créer un modèle de règles avec une interface dans le panneau d'administration. C'était une partie importante du module, qui est inutile en soi si vous n'apprenez pas à l'utiliser sur le frontend. Ainsi, il est grand temps de comprendre l'importance des règles et des conditions en leur sein.

Tout modèle de validation hérite des conditions qui permettent de valider un objet. Par conséquent, sur la base de ce contrôle de validation, nous pouvons effectuer certaines activités. Dans notre exemple, nous allons créer une règle qui permet de définir s'il y a un article avec la valeur d'attribut `heavy_weight` égale à 1 (true) dans le panier. Si un tel article est trouvé, nous afficherons un bloc avec le message suivant : "Vous avez des articles lourds dans votre panier, veuillez nous contacter pour discuter de la livraison". sur la page du panier.

* Il est essentiel de comprendre que la façon dont nous chargeons notre modèle de règle ne correspondra pas à 100 % à un cas réel. C'est pour cette raison que nous allons soigneusement spécifier une règle avec laquelle l' ID de règle doit être chargé. Sur cette base, nous validerons l'objet connu avec les articles du panier ― adresse de livraison. Dans un module qui n'a pas été créé à titre d'exemple, les objets Rules doivent être chargés en tant que classe spéciale, qui les validera par rapport à leur compatibilité avec l'environnement actuel, c'est-à-dire un magasin, un client et son groupe, l'heure, la date, etc. Nous traiterons sûrement de cette question dans une série d'autres articles connexes. *

Remarque importante :

Désormais, le code du module est disponible gratuitement dans le référentiel public sur github.com. Ainsi, fini le copier-coller de code depuis nos articles de blog. Tout le code requis est facilement disponible ici.

Tout d'abord, créons une nouvelle règle dans le panneau d'administration, qui aidera à trouver un produit avec la valeur d'attribut spécifiée comme heavy_weight :

Exemple de module Magento 2 avec modèle de conditions et ensemble de champs (partie 2) | Blog de MageWorx
Exemple de module Magento 2 avec modèle de conditions et ensemble de champs (partie 2) | Blog de MageWorx

*Si vous ne voyez pas votre attribut dans la liste des attributs dans les conditions, assurez-vous de vérifier d'abord la configuration de cet attribut. Cela doit être fait pour s'assurer que l'option Utiliser pour les conditions de la règle promotionnelle n'est pas désactivée pour cela.

Pour cela, rendez-vous dans Boutiques > Attributs > Produit. Ensuite, sélectionnez votre attribut dans la liste > Propriétés de la vitrine >. Utiliser pour les conditions de règle de promotion doit être défini sur "Oui". Veuillez vous référer à la capture d'écran ci-dessous pour plus de détails :

Exemple de module Magento 2 avec modèle de conditions et ensemble de champs (partie 2) | Blog de MageWorx

Ma règle a l'ID 1. De plus, je l'utiliserai pour faciliter le processus de chargement. Maintenant, mettons à jour la mise en page de la page du panier en ajoutant notre nouveau bloc qui affiche un nouveau message.

 `app/code/Vendor/Rules/view/frontend/layout/checkout_cart_index.xml` ```xml <?xml version="1.0"?> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> <referenceContainer name="checkout.cart.form.before"> <block class="Vendor\Rules\Block\Cart\RuleExample" name="custom_block_with_rules" template="Vendor_Rules::cart/example.phtml"/> </referenceContainer> </body> </page> ```

Comme vous l'avez peut-être remarqué dans la mise en page, nous aurons besoin de 2 fichiers supplémentaires : un bloc et un modèle. Créons-les :

 `app/code/Vendor/Rules/view/frontend/templates/cart/example.phtml` ```php <?php /** @var \Vendor\Rules\Block\Cart\RuleExample $block */ ?> <?= $block->getMessage();?> ```

Tout est simplifié dans le modèle, c'est-à-dire juste une sortie de message. Si nécessaire, vous pouvez ajouter une mise en page selon vos besoins.

Gardez à l'esprit que lorsque vous utilisez de tels modèles sur des pages de cache pleine page, les résultats seront également mis en cache. Une approche différente doit être utilisée pour ces pages, qui est décrite en détail dans les documents de développement officiels de Magento.

Il est temps d'ajouter la classe principale de l'exemple. Voici la classe de bloc :

 heckout\Model\Session as CheckoutSession; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\View\Element\Template; use Magento\Quote\Model\Quote\Address as QuoteAddress; use Vendor\Rules\Model\Rule; use Vendor\Rules\Model\ResourceModel\Rule\CollectionFactory as RulesCollectionFactory; /** * Class RuleExample */ class RuleExample extends Template { /** * @var RulesCollectionFactory */ private $rulesCollectionFactory; /** * @var string */ private $message; /** * @var CheckoutSession */ private $checkoutSession; /** * RuleExample constructor. * * @param Template\Context $context * @param RulesCollectionFactory $rulesCollectionFactory * @param CheckoutSession $checkoutSession * @param array $data */ public function __construct( Template\Context $context, RulesCollectionFactory $rulesCollectionFactory, CheckoutSession $checkoutSession, array $data = [] ) { $this->rulesCollectionFactory = $rulesCollectionFactory; $this->checkoutSession = $checkoutSession; $this->message = ''; parent::__construct($context, $data); } /** * @return string */ public function getMessage(): string { if ($this->message) { return $this->message; } $shippingAddress = $this->getShippingAddress(); if (!$shippingAddress) { return $this->message; } $rule = $this->getRule(); if ($rule && $rule->validate($shippingAddress)) { $this->message = __( 'You have some heavy weight items in your cart, please contact us to discuss delivery.' ); } return $this->message; } /** * @return Rule|null */ private function getRule(): ?Rule { /** @var \Vendor\Rules\Model\ResourceModel\Rule\Collection $rulesCollection */ $rulesCollection = $this->rulesCollectionFactory->create(); $rulesCollection->addFilter('rule_id', 1); /** @var Rule|null $rule */ $rule = $rulesCollection->getFirstItem(); return $rule; } /** * @return QuoteAddress|null */ private function getShippingAddress(): ?QuoteAddress { /** @var \Magento\Quote\Model\Quote $quote */ try { $quote = $this->checkoutSession->getQuote(); } catch (LocalizedException $exception) { return null; } if (!$quote) { return null; } return $quote->getIsVirtual() ? $quote->getBillingAddress() : $quote->getShippingAddress(); } } ```

Arrêtons-nous un peu sur cette classe car c'est justement là que se cache la validation. Il n'a qu'une seule méthode publique que nous utilisons dans notre modèle. C'est la méthode `getMessage()`. Dans la méthode, une règle correcte est spécifiée (elle validera notre panier), ainsi que l'adresse de livraison (elle sera utilisée pour la validation).

Nous obtenons l'adresse de livraison à l'aide de la fonctionnalité frontale standard, c'est-à-dire en la demandant à la session de paiement. Nous remplissons la règle à partir de la collection en utilisant un filtre basé sur l'ID. (Comme je l'ai mentionné au début de cet article, ce n'est pas le meilleur moyen et ne peut être utilisé qu'à titre d'exemple. Assurez-vous de décrire la méthode d'obtention de la règle de la manière qui vous convient le mieux). Lorsque nous avons 2 objets obligatoires dans notre bloc, il ne nous reste plus qu'à vérifier ce que la méthode `$rule->validate($shippingAddress)` de notre règle renverra, c'est-à-dire vrai ou faux. En fonction des résultats, créez (ou non) un message qui s'affichera sur la page du panier dans notre template. À l'intérieur du modèle de règle, cela fonctionne comme suit :

 ```php /** * Validate rule conditions to determine if rule can run * * @param \Magento\Framework\DataObject $object * @return bool */ public function validate(\Magento\Framework\DataObject $object) { return $this->getConditions()->validate($object); } ```

Cette méthode existe déjà dans la classe abstraite `Magento\Rule\Model\AbstractModel`, à partir de laquelle nos règles de classe `Vendor\Rules\Model\Rule` sont héritées. Si vous avez besoin d'une validation personnalisée, il est toujours possible d'ajouter la propre méthode `validate` aux règles de classe avec ou sans invoquer une méthode parent.

Voici ce que nous obtiendrons en conséquence sur le frontend :

*La valeur de l'attribut heavy_weight du produit T1 Blue est égale à 1 :

![Produit valide dans un panier]

Exemple de module Magento 2 avec modèle de conditions et ensemble de champs (partie 2) | Blog de MageWorx

*La valeur de l'attribut heavy_weight du produit T1 Red est égale à 0 :

![Produit valide dans un panier]

Exemple de module Magento 2 avec modèle de conditions et ensemble de champs (partie 2) | Blog de MageWorx

Comme vous pouvez le voir sur les captures d'écran, notre message du bloc s'affiche pour le produit T1 Blue sous l'étiquette du panier. Pour le rouge, à l'inverse, le message ne s'affiche pas. Cela signifie que la règle fonctionne correctement.


Merci à tous d'avoir pris le temps de lire l'article. Si vous avez des questions, n'hésitez pas à les partager dans les commentaires ci-dessous. Je serai heureux de vous aider.