Exemplu de modul Magento 2 cu model de condiții și set de câmpuri (partea 2)
Publicat: 2019-12-16În articolul anterior, am aruncat o privire asupra codului care ne permite să creăm un model de reguli cu o interfață în Panoul de administrare. Aceasta a fost o parte semnificativă a modulului, care este inutilă în sine dacă nu înveți cum să-l folosești pe front-end. Astfel, este timpul să ne dăm seama de importanța regulilor și a condițiilor din ele.
Orice model de validare moștenește condiții care ajută la validarea unui obiect. Ca urmare, pe baza acestei verificări de validare, putem efectua anumite activități. În exemplul nostru, vom crea o regulă care permite definirea dacă în coșul de cumpărături există un articol cu valoarea atributului `greutate_grea` care este egală cu 1 (adevărat). În cazul în care un astfel de articol este găsit, vom afișa un bloc cu următorul mesaj „Aveți câteva articole grele în coș, vă rugăm să ne contactați pentru a discuta despre livrare”. pe pagina coșului de cumpărături.
*Este esențial să înțelegem că modul în care încărcăm modelul nostru Rule nu se va potrivi 100% într-un caz real. Acesta este motivul pentru care vom specifica cu claritate o regulă cu care trebuie încărcat ID -ul regulii . Pe baza acestuia, vom valida obiectul cunoscut cu articolele din coș – adresa de expediere. Într-un modul care nu a fost creat ca exemplu, obiectele Rules trebuie încărcate ca o clasă specială, care le va valida în raport cu compatibilitatea lor cu mediul curent, adică un magazin, un client și grupul acestuia, ora, data etc. Cu siguranță ne vom ocupa de această problemă într-o serie de articole înrudite. *
Notă laterală importantă:
Acum, codul modulului este disponibil gratuit în depozitul public de pe github.com. Astfel, nu mai trebuie să mai copiați și lipiți codurile din postările noastre de pe blog. Tot codul necesar este disponibil convenabil aici.
Mai întâi, să creăm o nouă regulă în panoul de administrare, care va ajuta la găsirea unui produs cu valoarea atributului specificată ca heavy_weight:
*Dacă nu vedeți atributul dvs. în lista de atribute în condiții, asigurați-vă că verificați mai întâi configurația acestui atribut. Se va face pentru a se asigura că opțiunea Utilizare pentru condițiile regulilor promoționale nu este dezactivată pentru aceasta.
Pentru a face asta, accesați Magazine > Atribute > Produs. Apoi, selectați atributul dvs. din listă > Proprietăți magazin >. Condițiile de utilizare pentru regulile promoționale trebuie setate ca „Da”. Vă rugăm să consultați captura de ecran de mai jos pentru mai multe detalii:
Regula mea are ID 1. În plus, o voi folosi pentru a facilita procesul de încărcare. Acum, să actualizăm aspectul paginii coș adăugând noul nostru bloc care afișează un nou mesaj.
`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> ```
După cum probabil ați observat din aspect, vom avea nevoie de încă 2 fișiere: un bloc și un șablon. Să le creăm:
`app/code/Vendor/Rules/view/frontend/templates/cart/example.phtml` ```php <?php /** @var \Vendor\Rules\Block\Cart\RuleExample $block */ ?> <?= $block->getMessage();?> ```
Totul este simplificat în șablon, adică doar un mesaj de ieșire. Dacă este necesar, puteți adăuga un aspect după cum este necesar.
Rețineți că, atunci când utilizați astfel de șabloane pe pagini de cache cu pagini întregi, rezultatele vor fi și ele memorate în cache. O abordare diferită ar trebui utilizată pentru astfel de pagini, care este descrisă în detaliu în documentele oficiale Magento dev.
Este timpul să adăugați clasa principală din exemplu. Iată clasa 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(); } } ```
Să ne oprim puțin asupra acestei clase, deoarece tocmai acolo este ascunsă validarea. Are o singură metodă publică pe care o folosim în șablonul nostru. Este metoda `getMessage()`. În cadrul metodei este specificată o regulă corectă (va valida coșul nostru), precum și adresa de expediere (va fi folosită pentru validare).
Obținem adresa de expediere folosind funcționalitatea standard de front-end, adică prin solicitarea acesteia din sesiunea de checkout. Populam regula din colecție folosind un filtru care se bazează pe ID. (După cum am menționat la începutul acestei postări, nu este cel mai bun mijloc și poate fi folosit doar ca exemplu. Asigurați-vă că descrieți metoda de obținere a regulii în modul care vi se potrivește cel mai bine). Când avem 2 obiecte obligatorii în blocul nostru, ne rămâne doar să verificăm ce va returna metoda `$rule->validate($shippingAddress)` a regulii noastre, adică adevărată sau falsă. Pe baza rezultatelor, creați (sau nu) un mesaj care va fi afișat pe pagina coșului din șablonul nostru. În interiorul modelului de regulă, funcționează după cum urmează:
```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); } ```
Această metodă există deja în clasa abstractă `Magento\Rule\Model\AbstractModel`, din care sunt moștenite regulile clasei `Vendor\Rules\Model\Rule`. Dacă aveți nevoie de validare personalizată, este întotdeauna posibil să adăugați metoda proprie `validate` la regulile clasei cu sau fără invocarea unei metode părinte.
Iată ce vom obține ca rezultat pe front-end:
*Valoarea atributului heavy_weight a produsului T1 Blue este egală cu 1:
![Produs valabil într-un coș]
*Valoarea atributului heavy_weight a produsului T1 Red este egală cu 0:
![Produs valabil într-un coș]
După cum puteți vedea în capturi de ecran, mesajul nostru din bloc este afișat pentru produsul T1 Blue sub eticheta coșului. Pentru cel roșu, dimpotrivă, mesajul nu se afișează. Aceasta înseamnă că regula funcționează corect.
Vă mulțumim tuturor pentru timpul acordat citirii articolului. Dacă aveți întrebări, nu ezitați să le împărtășiți în comentariile de mai jos. Voi fi bucuros să vă ajut.