Beispiel für ein Magento 2-Modul mit Condition Model und Fieldset (Teil 2)
Veröffentlicht: 2019-12-16Im vorherigen Artikel haben wir uns den Code angesehen, der es uns ermöglicht, ein Regelmodell mit einer Schnittstelle im Admin-Panel zu erstellen. Das war ein bedeutender Teil des Moduls, das an sich nutzlos ist, wenn Sie nicht lernen, wie man es im Frontend verwendet. Daher ist es höchste Zeit, die Bedeutung der darin enthaltenen Regeln und Bedingungen herauszufinden.
Jedes Validierungsmodell erbt Bedingungen, die bei der Validierung eines Objekts helfen. Als Ergebnis können wir basierend auf dieser Validierungsprüfung bestimmte Aktivitäten durchführen. In unserem Beispiel erstellen wir eine Regel, die es ermöglicht zu definieren, ob es einen Artikel mit dem Attributwert „heavy_weight“ gibt, der gleich 1 (wahr) im Einkaufswagen ist. Falls ein solcher Artikel gefunden wird, zeigen wir einen Block mit der folgenden Meldung an: "Sie haben einige schwere Artikel in Ihrem Einkaufswagen, bitte kontaktieren Sie uns, um die Lieferung zu besprechen." auf der Warenkorbseite.
*Es ist wichtig zu verstehen, dass die Art und Weise, wie wir unser Regelmodell laden, nicht zu 100 % auf einen realen Fall passt. Aus diesem Grund geben wir eine Regel an, mit der die Regel- ID geladen werden muss. Auf dieser Grundlage validieren wir das bekannte Objekt mit den Artikeln aus dem Warenkorb – Lieferadresse. In einem Modul, das nicht als Beispiel erstellt wurde, müssen Rules -Objekte als spezielle Klasse geladen werden, die sie auf ihre Kompatibilität mit der aktuellen Umgebung validiert, dh ein Geschäft, ein Kunde und seine Gruppe, Uhrzeit, Datum usw Wir werden uns sicherlich in einer Reihe weiterer verwandter Artikel mit diesem Thema befassen. *
Wichtige Randnotiz:
Jetzt ist der Code des Moduls im öffentlichen Repository auf github.com frei verfügbar. Somit entfällt das Kopieren und Einfügen von Code aus unseren Blog-Beiträgen. Alle erforderlichen Codes sind bequem hier verfügbar.
Lassen Sie uns zunächst eine neue Regel im Admin-Bereich erstellen, die dabei hilft, ein Produkt mit dem als heavy_weight angegebenen Attributwert zu finden:
*Wenn Sie Ihr Attribut nicht in der Attributliste unter Bedingungen sehen, überprüfen Sie zuerst die Konfiguration dieses Attributs. Es muss sichergestellt werden, dass die Option „ Für Bedingungen der Werbeaktion verwenden “ nicht deaktiviert ist.
Gehen Sie dazu zu Stores > Attributes > Product. Wählen Sie dann Ihr Attribut aus der Liste > Storefront-Eigenschaften > aus. Nutzung für Aktionsregel-Bedingungen muss auf „Ja“ gesetzt werden. Bitte beachten Sie den Screenshot unten für weitere Details:
Meine Regel hat die ID 1. Außerdem werde ich sie verwenden, um den Ladevorgang zu erleichtern. Aktualisieren wir nun das Layout der Warenkorbseite, indem wir unseren neuen Block hinzufügen, der eine neue Nachricht anzeigt.
`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> ```
Wie Sie vielleicht anhand des Layouts bemerkt haben, benötigen wir 2 weitere Dateien: einen Block und eine Vorlage. Lassen Sie uns sie erstellen:
`app/code/Vendor/Rules/view/frontend/templates/cart/example.phtml` ```php <?php /** @var \Vendor\Rules\Block\Cart\RuleExample $block */ ?> <?= $block->getMessage();?> ```
In der Vorlage ist alles einfach gemacht, dh nur eine Nachrichtenausgabe. Bei Bedarf können Sie bei Bedarf ein Layout hinzufügen.
Beachten Sie, dass bei Verwendung solcher Vorlagen auf ganzseitigen Cache-Seiten die Ergebnisse ebenfalls zwischengespeichert werden. Für solche Seiten sollte ein anderer Ansatz verwendet werden, der in den offiziellen Magento-Entwicklerdokumenten ausführlich beschrieben wird.
Es ist an der Zeit, die Hauptklasse aus dem Beispiel hinzuzufügen. Hier ist die Blockklasse:
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(); } } ```
Lassen Sie uns ein wenig auf diese Klasse eingehen, da genau dort die Validierung verborgen ist. Es hat nur eine öffentliche Methode, die wir in unserer Vorlage verwenden. Es ist die `getMessage()`-Methode. Innerhalb der Methode wird eine korrekte Regel angegeben (sie validiert unseren Warenkorb) sowie die Lieferadresse (sie wird zur Validierung verwendet).
Wir erhalten die Lieferadresse über die Standard-Frontend-Funktionalität, dh indem wir sie während der Checkout-Sitzung anfordern. Wir füllen die Regel aus der Sammlung aus, indem wir einen Filter verwenden, der auf der ID basiert. (Wie ich am Anfang dieses Beitrags erwähnt habe, ist dies nicht das beste Mittel und kann nur als Beispiel verwendet werden. Stellen Sie sicher, dass Sie die Methode zum Erhalten der Regel so beschreiben, wie es Ihnen am besten passt). Wenn wir 2 obligatorische Objekte in unserem Block haben, müssen wir nur noch prüfen, was die `$rule->validate($shippingAddress)`-Methode unserer Regel zurückgibt, dh wahr oder falsch. Erstellen Sie basierend auf den Ergebnissen eine Nachricht (oder nicht), die auf der Warenkorbseite in unserer Vorlage angezeigt wird. Innerhalb des Regelmodells funktioniert es wie folgt:
```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); } ```
Diese Methode existiert bereits in der abstrakten Klasse „Magento\Rule\Model\AbstractModel“, von der unsere Klassenregeln „Vendor\Rules\Model\Rule“ geerbt werden. Wenn Sie eine benutzerdefinierte Validierung benötigen, ist es immer möglich, die eigene Methode „validate“ zu den Klassenregeln mit oder ohne Aufruf einer übergeordneten Methode hinzuzufügen.
Folgendes erhalten wir als Ergebnis im Frontend:
*Der Wert des Attributs heavy_weight des T1 Blue-Produkts ist gleich 1:
![Gültiges Produkt im Warenkorb]
*Der Wert des Attributs heavy_weight des Produkts T1 Red ist gleich 0:
![Gültiges Produkt im Warenkorb]
Wie Sie auf den Screenshots sehen können, wird unsere Nachricht aus dem Block für das T1 Blue-Produkt unter dem Warenkorbetikett angezeigt. Beim roten hingegen wird die Meldung nicht angezeigt. Das bedeutet, dass die Regel korrekt funktioniert.
Vielen Dank, dass Sie sich die Zeit genommen haben, den Artikel zu lesen. Sollten Sie Fragen haben, können Sie diese gerne in den Kommentaren unten teilen. Ich helfe gerne.