Ejemplo de Módulo Magento 2 con Modelo de Condiciones y Conjunto de Campo (Parte 2)
Publicado: 2019-12-16En el artículo anterior, echamos un vistazo al código que nos permite crear un modelo de Reglas con una interfaz en el Panel de administración. Esa fue una parte importante del módulo, que es inútil por sí mismo si no aprende a usarlo en la interfaz. Por lo tanto, ya es hora de darse cuenta de la importancia de las reglas y condiciones dentro de ellos.
Cualquier modelo de validación hereda condiciones que ayudan a validar un objeto. Como resultado, en base a esta verificación de validación, podemos realizar ciertas actividades. En nuestro ejemplo, crearemos una regla que permita definir si hay un artículo con el valor del atributo `heavy_weight` igual a 1 (verdadero) en el carrito de compras. En caso de que se encuentre un artículo de este tipo, mostraremos un bloque con el siguiente mensaje: "Tiene algunos artículos pesados en su carrito, contáctenos para discutir la entrega". en la página del carrito de compras.
*Es fundamental comprender que la forma en que cargamos nuestro modelo de reglas no se ajustará al 100 % a un caso de la vida real. Esto se debe a que especificaremos claramente una regla con la que se debe cargar el ID de la regla . En base a ello, validaremos el objeto conocido con los artículos del carrito—dirección de envío. En un módulo que no se ha creado como ejemplo, los objetos de Reglas deben cargarse como una clase especial, que los validará contra su compatibilidad con el entorno actual, es decir, una tienda, un cliente y su grupo, hora, fecha, etc. Seguramente trataremos este asunto en una serie de artículos adicionales relacionados. *
Nota importante al margen:
Ahora, el código del módulo está disponible gratuitamente en el repositorio público en github.com. Por lo tanto, no más copiar y pegar código de nuestras publicaciones de blog. Todo el código requerido está convenientemente disponible aquí.
Primero, creemos una nueva regla en el Panel de administración, que ayudará a encontrar un producto con el valor de atributo especificado como heavy_weight:
*Si no ve su atributo en la lista de atributos en condiciones, asegúrese de verificar primero la configuración de este atributo. Se debe hacer para garantizar que la opción Usar para condiciones de regla de promoción no esté deshabilitada para ello.
Para ello, vaya a Tiendas > Atributos > Producto. Luego, seleccione su atributo de la lista > Propiedades de escaparate >. El uso para condiciones de regla de promoción debe configurarse como 'Sí'. Por favor, consulte la captura de pantalla a continuación para obtener más detalles:
Mi regla tiene ID 1. Además, la usaré para facilitar el proceso de carga. Ahora, actualicemos el diseño de la página del carrito agregando nuestro nuevo bloque que muestra un nuevo mensaje.
`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> ```
Como habrás notado en el diseño, necesitaremos 2 archivos más: un bloque y una plantilla. Vamos a crearlos:
`app/code/Vendor/Rules/view/frontend/templates/cart/example.phtml` ```php <?php /** @var \Vendor\Rules\Block\Cart\RuleExample $block */ ?> <?= $block->getMessage();?> ```
Todo está simplificado en la plantilla, es decir, solo una salida de mensaje. Si es necesario, puede agregar un diseño según sea necesario.
Tenga en cuenta que al usar dichas plantillas en páginas de caché de página completa, los resultados también se almacenarán en caché. Se debe usar un enfoque diferente para tales páginas, que se describe en detalle en los documentos oficiales de desarrollo de Magento.
Es hora de agregar la clase principal del ejemplo. Aquí está la clase de bloque:
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(); } } ```
Detengámonos un poco en esta clase, ya que es precisamente donde se oculta la validación. Solo tiene un método público que usamos en nuestra plantilla. Es el método `getMessage()`. Dentro del método, se especifica una regla correcta (validará nuestro carrito), así como la dirección de envío (se utilizará para la validación).
Obtenemos la dirección de envío utilizando la funcionalidad de interfaz estándar, es decir, solicitándola desde la sesión de pago. Rellenamos la regla de la colección mediante un filtro basado en ID. (Como mencioné al comienzo de esta publicación, no es el mejor medio y puede usarse únicamente como ejemplo. Asegúrese de describir el método para obtener la regla de la manera que más le convenga). Al tener 2 objetos obligatorios en nuestro bloque, solo nos queda verificar qué devolverá el método `$rule->validate($shippingAddress)` de nuestra regla, es decir, verdadero o falso. Según los resultados, cree (o no) un mensaje que se mostrará en la página del carrito en nuestra plantilla. Dentro del modelo de reglas, funciona de la siguiente manera:
```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); } ```
Este método ya existe en la clase abstracta `Magento\Rule\Model\AbstractModel`, de la cual se heredan nuestras reglas de clase `Vendor\Rules\Model\Rule`. Si necesita una validación personalizada, siempre es posible agregar el método propio `validar` a las reglas de la clase con o sin invocar un método principal.
Esto es lo que obtendremos como resultado en la interfaz:
*El valor del atributo heavy_weight del producto T1 Blue es igual a 1:
![Producto válido en un carrito]
*El valor del atributo heavy_weight del producto T1 Red es igual a 0:
![Producto válido en un carrito]
Como puede ver en las capturas de pantalla, nuestro mensaje del bloque se muestra para el producto T1 Blue debajo de la etiqueta del carrito. Para el rojo, por el contrario, el mensaje no se muestra. Esto significa que la regla funciona correctamente.
Gracias a todos por tomarse el tiempo de leer el artículo. Si tiene alguna pregunta, no dude en compartirla en los comentarios a continuación. Estaré encantado de ayudar.