条件モデルとフィールドセットを使用した Magento 2 モジュールの例 (パート 2)
公開: 2019-12-16前回の記事では、管理パネルのインターフェースを使用してルールモデルを作成できるコードを見てきました。 これはモジュールの重要な部分であり、フロントエンドでの使用方法を学ばなければ、それだけでは役に立ちません。 したがって、その中のルールと条件の重要性を理解する時が来ました。
どの検証モデルも、オブジェクトの検証に役立つ条件を継承します。 その結果、この検証チェックに基づいて、特定のアクティビティを実行できます。 この例では、`heavy_weight` 属性値が 1 (真) のアイテムがショッピング カートにあるかどうかを定義できるルールを作成します。 そのような商品が見つかった場合は、「カートに重量のある商品がいくつかあります。配送についてご相談ください」というメッセージのブロックが表示されます。 ショッピングカートページに。
*ルールモデルをロードする方法は、実際のケースに 100% 適合しないことを理解することが重要です。 これは、ルールIDを読み込む必要があるルールをきちんと指定するためです。 それに基づいて、既知のオブジェクトをカートのアイテム (配送先住所) で検証します。 例として作成されていないモジュールでは、 Rulesオブジェクトを特別なクラスとしてロードする必要があります。これにより、現在の環境 (店舗、顧客とそのグループ、時間、日付など) との互換性が検証されます。この件については、今後の関連記事のシリーズで確実に扱います。 *
重要な補足事項:
現在、モジュールのコードは github.com のパブリック リポジトリで自由に利用できます。 したがって、ブログ投稿からコードをコピーして貼り付ける必要はもうありません。 必要なコードはすべてここで簡単に入手できます。
まず、管理パネルで新しいルールを作成しましょう。これは、属性値が Heavy_weight として指定された製品を見つけるのに役立ちます。
*条件の属性リストに属性が表示されない場合は、まずこの属性の設定を確認してください。 これは、[プロモーション ルール条件に使用] オプションが無効になっていないことを確認するために行われます。
これを行うには、[ストア] > [属性] > [製品] に移動します。 次に、リスト > Storefront のプロパティ > から属性を選択します。 プロモーション ルール条件の使用は「はい」に設定する必要があります。 詳細については、以下のスクリーンショットを参照してください。
私のルールの ID は 1 です。さらに、これを使用して読み込みプロセスを容易にします。 次に、新しいメッセージを表示する新しいブロックを追加して、カート ページのレイアウトを更新しましょう。
`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> ```
レイアウトからお気づきかもしれませんが、ブロックとテンプレートの 2 つのファイルが必要です。 それらを作成しましょう:
`app/code/Vendor/Rules/view/frontend/templates/cart/example.phtml` ```php <?php /** @var \Vendor\Rules\Block\Cart\RuleExample $block */ ?> <?= $block->getMessage();?> ```
テンプレートではすべてが単純化されています。つまり、メッセージ出力だけです。 必要に応じて、レイアウトを追加できます。
このようなテンプレートをフルページ キャッシュ ページで使用すると、結果もキャッシュされることに注意してください。 このようなページには別のアプローチを使用する必要があります。これについては、Magento の公式開発ドキュメントで詳しく説明されています。
例からメイン クラスを追加します。 ブロッククラスは次のとおりです。
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(); } } ```
このクラスには検証が隠されているため、このクラスについて少し説明しましょう。 テンプレートで使用する public メソッドは 1 つだけです。 それは`getMessage()`メソッドです。 メソッド内では、正しいルール (カートを検証します) と配送先住所 (検証に使用されます) が指定されます。
標準のフロントエンド機能を使用して、つまり、チェックアウト セッションから要求することにより、配送先住所を取得します。 ID に基づくフィルターを使用して、コレクションからルールを取り込みます。 (この投稿の冒頭で述べたように、これは最良の手段ではなく、例としてのみ使用できます。自分に最適な方法でルールを取得する方法を必ず説明してください)。 ブロックに 2 つの必須オブジェクトがある場合、ルールの `$rule->validate($shippingAddress)` メソッドが返すもの、つまり true または false を確認するだけです。 結果に基づいて、テンプレートのカート ページに表示されるメッセージを作成します (または作成しません)。 ルール モデル内では、次のように機能します。
```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); } ```
このメソッドは、`Magento\Rule\Model\AbstractModel` 抽象クラスに既に存在し、そこから `Vendor\Rules\Model\Rule` クラス ルールが継承されます。 カスタム検証が必要な場合は、親メソッドを呼び出すかどうかに関係なく、独自のメソッド `validate` をクラス ルールに追加することが常に可能です。
フロントエンドで結果として得られるものは次のとおりです。
*T1 Blue 商品の Heavy_weight 属性値は 1 です。
![カート内有効商品]
*T1 Red 製品の Heavy_weight 属性値は 0 に等しい:
![カート内有効商品]
スクリーンショットでわかるように、ブロックからのメッセージがカート ラベルの下の T1 Blue 製品に表示されます。 逆に赤いものはメッセージが表示されません。 これは、ルールが正しく機能することを意味します。
記事をお読みいただきありがとうございます。 ご不明な点がございましたら、以下のコメント欄でお気軽にお問い合わせください。 喜んでお手伝いさせていただきます。