Blog
Eventos y Observers en Magento 2
- diciembre 11, 2023
- Publicado por: admin
- Categoría: Magento 2
Bien, vamos a hablar de los Observer de Magento 2, EventManager, Listener todos estos conceptos que vienen de origen de Zend Framework fueron creados para solucionar un concepto en general, que mediante Observer (oyentes) se pudieran ejecutar ciertos Events (Eventos), pero como es de costumbre voy a tratar de desentramar toda la parte teórica para mostrarlo en mis propias palabras y pueda ser comprensible a mi forma de ver las cosas que hay detrás.
Los Observer de Magento utilizarán por detrás toda esta arquitectura que desde mi punto de vista no nos interesa saber, lo que interesaría es realmente cuál es el objetivo de que existan, en que pueden ayudar en mi proyecto de ecommerce, y finalmente cómo puedo implementarlo.
La principal razón de que existan en Magento 2 como Observers es para poder ampliar la funcionalidad de Magento de una forma más limpia comparado con la inyección de dependencias, sobrescribiendo clases nativas de Magento o extendiendo clases nativas de Magento, cada método tiene sus propios beneficios y están hecho para que la plataforma sea mucho más flexible y logremos resultados tal como los que estamos buscando.
Antes de pasar a la parte técnica entandamos esto, imaginemos que cuando un cliente llega a nuestra tienda hay un pequeño Bot de programación que está atento a lo que estamos haciendo, cuando estamos en el catálogo de productos él escucha cada petición y está atento por si necesitamos preguntar algo más, cuando agregamos un producto al carrito, cuando pasamos al checkout y cuando finalizamos nuestra compra en la tienda, éste pequeño Bot estuvo atento a todo pero de fondo fuera de un flujo básico no le preguntamos absolutamente nada, ahora bien supongamos que nos han pedido que antes de agregar un producto al carrito realicemos un par de comprobaciones, algo muy básico sólo contemos el número de productos y validemos que si la cantidad es mayor a 5 no le permitamos agregar más productos mandándole un mensaje que le indique que su límite máximo de compra es de 5 productos por cliente, supongamos que se trata de una venta cerrada a 5 productos por cliente.
Pues bien ¿cómo podríamos hacer esto? Si recordamos a nuestro amigo Bot de programación pues ahí está la respuesta. Si el está escuchando todo lo que estamos haciendo en una tienda de Magento pues bien podríamos decirle que antes de agregar un producto al carrito ejecute una clase de programación que ya contenga toda esa lógica y valide si puede seguir agregando o no.
¿Cómo podemos hacer esto? En primer lugar el Bot de programación es un EvenManager en Magento un pedazo de código que se ejecuta en cada una de las acciones de Magento, ya están ahí en las clases nativas y precisamente las agregaron para que fueran parte de una lista enorme de Eventos para que en el futuro programadores como tú y como yo pudiéramos saber que están ahí disponibles para cuando las necesitemos usar, estas fueron agregadas casi en todas partes, cuando hacemos acciones importantes y por lo general al inicio de una acción, durante la acción y al finalizar la acción, pero lo que al principio yo no entendía muy bien era saber si hay o no un evento que pueda tomar y utilizar justo para alguna acción que necesito. Pues bien hay diversos listados que muestran todos los eventos, pero yo me he tomado uno y lo he colocado en esta URL: Lista de eventos disponibles Magento 2.3 Aquí podrás encontrar un gran listado. Pues bien ahora ¿Cómo puedo elegir el que necesito? Para mi ejemplo lo que puedo hacer es buscar los eventos en el listado, recuerda que todo esos ya son nativos, ahora entendamos una cosa y es que Magento lo ha tratado de dejar lo más simple al nombrarlos a cada uno por su clase de acción, por ejemplo si estoy hablando de un evento que debo cachar antes de añadir un producto al carrito, pues buscaría algo como “Antes de Agregar un Producto al Carrito” claro que lo que no pensó Magento es en el lenguaje Español por eso hay que acostumbrarnos a las nomenclaturas en Inglés, entonces buscando en el listado que he compartido puedo ver que hay uno que encaja muy bien y es el siguiente “checkout_cart_product_add_before” y es justamente lo que busco, si miramos el código completo encontraremos algo como esto :
$this->_eventManager->dispatch( 'checkout_cart_product_add_before', ['info' => $requestInfo, 'product' => $product]);
Es una instrucción de código que indica un despachador de eventos en donde por un lado pasará el nombre del evento disparado y en el segundo parámetro enviará parámetros para que puedan ser usados cuando se cache este evento, que en este caso son dos atributos: info y product que la primera obtendrá información de resultado y la segunda los datos del producto que se está agregando. Si necesitas mirar a detalle que información encontrarás en cada uno de esos dos atributos puedes mirar la clase que también la he colocado en el listado de eventos disponibles en este caso sería la clase “checkout_cart_product_add_before”.
Bien ahora ya sabemos cuál es el nombre del evento que necesitamos cachar para posterior hacer nuestro trabajo personalizado pero, lo anterior solo nos mostró cómo podemos saber que evento podemos utilizar, pero en si aún no hemos indicado cómo podemos tomar justo el evento en el momento preciso y en ese momento poder ejecutar nuestro código personalizado, pues ahora es el turno de un Oyente o un escucha, y esto se realiza mediante un archivo XML de configuración.
Sin los oyentes o escucha todo esto de los eventos no tendría sentido porque no habría forma de indicarle a Magento cuando debe tomar un evento y ejecutar algo extra, así que esto es algo muy importante y como de costumbre lo voy a explicar a mi manera: Supongamos que ya sabemos que existen un gran listado de eventos nativos de Magento y hay un Bot de Programación que está atento a todo lo que está sucediendo en la tienda, pero en realidad ¿A quién le pregunta si hay o no algo que hacer antes de continuar con una acción? Pues es aquí en donde entran los Escucha de nuestro lado, veamos este escenario:
- Un cliente le da clic al botón de añadir un producto al carrito, la clase nativa de Magento se ejecuta y dentro se activan todos los eventos disponibles.
- El bot de programación revisa si hay un oyente o escucha que quiera utilizar el evento “checkout_cart_product_add_before” revisa los archivos XML de configuración personalizados y se da cuenta que si hay uno
- El archivo XML de configuración que registro el evento a escuchar valida cuantos Observer acciones tendría que ejecutar es un sub nodo que se localizara justo dentro del nodo de configuración principal.
- El archivo XML de configuración que registró el evento a escuchar valida cuantos Observer acciones tendría que ejecutar, es un subNodo que se localizará justo dentro del nodo de configuración principal.
- Una vez encontrado el Observer subNodo valida su id de registro que sea único y verifica cual será la instancia que deberá ejecutar, en este caso una clase que en automático ejecutara su método principal llamado execute.
- 5. Esta nueva ejecución podrá o bien realizar nuevas acciones personalizadas o bien continuar con el flujo de ejecución.
Ahora espero se haya podido comprender la parte teórica de cómo funcionan los eventos nativos dentro de Magento 2 mandándolos a llamar desde un componente de Magento llamado Observer, porque después de entender lo nativo cabe mencionar que también podemos registrar nuestros propios Eventos para que estos puedan mandar a llamarse desde un oyente o un escucha desde cualquier parte de nuestra tienda de Magento.
Supongamos que desarrollamos un módulo personalizado con una tabla propia que registre comentarios personalizados a productos desde el área de catálogo de productos, que muestre un pequeño ícono que al presionarlo se muestre un cuadro de área que permita dejar un comentario a ese producto desde el área de catálogo de productos, pues bien en las clases en donde coloquemos toda nuestra lógica de inserción podríamos agregar los bloque de código que registrarían nuestras acciones antes y al finalizar una inserción de comentario en nuestra tabla de comentarios personalizada, ahí es donde daríamos de alta eventos como comment_product_custom_add_before, comment_product_custom_add_after siguiendo la nomenclatura de Magento y el idioma en Inglés, habrá quien se esté preguntando ¿ y por qué no en español? y claro que lo puedes hacer nada te obliga a que no lo hagas por ejemplo así “antes_de_agregar_un _comentario_personalizado_a_nuestro_producto” bien podrías hacerlo pero para ser sincero me quedaría con la nomenclatura corta y en el idioma inglés es comprensible y va con la misma dinámica que ya maneja Magento.
El código final para nuestra clase bien podría ser un controlador o cualquier clase que maneje la lógica de acciones de nuestro componente personalizado quedaría así:
$this->_eventManager->dispatch( 'comment_product_custom_add_before', ['info' => $requestInfo, 'comment' => $dataComent]);
Este registro de evento ya estaría listo y disponible para que cualquier escucha lo pueda utilizar antes de realizar una inserción a la tabla personalizada de comentario de productos en la pantalla de catálogo de productos.
Ahora para cerrar con un ejemplo práctico del nuevo evento registrado del componente personalizado, supongamos que tenemos otro componente personalizado que valida los comentarios nativos de Magento realizados en el detalle de producto contra los comentarios agregados desde la vista de catálogo de productos desde esa sección nueva que muestra un campo de área para agregar un nuevo comentario en la tabla personalizada, pues bien para cachar ese evento desde nuestro nuevo módulo tendríamos que agregar un Oyente u escucha, un archivo de configuración XML llamado events.xml que deberíamos agregar en la estructura de nuestro nuevo módulo supongamos que el nuevo módulo se llama Validacomentarios que estaría dentro de nuestro espacio de nombres Marcgento/Validacomentarios dentro de este módulo y en la carpeta etc se podría encontrar nuestro escucha el events.xml pero aprovecharé para comentar algo que por buenas prácticas de Magento debemos aprender a organizar, y es nada más que en donde colocaremos este archivo de configuración, y bien cabe mencionar que pueden existir escuchas u oyentes tanto para el área de FrontEnddonde navegan los clientes o bien desde el BackEnd el área de administración de Magento así que dependiendo para que área lo necesitemos ahí debería ser donde lo almacenemos, por ejemplo si es un Escucha para el frontend del cliente debería quedar dentro de una carpeta llamada frontend y si es un escucha del lado del BackEnd seria dentro de una carpeta llamada adminhtml como resultado estas serían las rutas dependiendo para cual lo necesitemos esta para frontend app/code/Marcgento/Validacomentarios/etc/frontend/events.xml o para el BackEnd app/code/Marcgento/Validacomentarios/etc/adminhtml/events.xml , bien lo podrías dejar dentro de la carpeta etc y funcionaria para ambos pero no es lo correcto es mejor hacerlo como Magento nos lo está indicando.
La apariencia de ese XML quedaría como se muestra a continuación:
<!?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nonamespaceschemalocation="urn:magento:framework:Event/etc/events.xsd">
<event name="comment_product_custom_add_before">
<observer name="valida_comment_product" instance="MarcgentoValidacomentariosObserverValidacomentariosProduct">
</observer></event>
</config>