Trabajar con Events y Observers son uno de los métodos que tenemos para poder extender el Core de Magento2 sin necesidad de modificarlo.
Antes de ver un ejemplo práctico veamos que son y cual es su función.
Eventos
Los Eventos son enviados por los módulos cuando estos realizan una determinada acción y podrán pasarle datos al observador que esté controlándolo.
Magento también nos permite crear nuestros propios eventos.
1 2 3 4 5 |
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd"> <event name="catalog_controller_product_view"> <!-- aqui el observer --> </event> </config> |
Observer
Los Observers son Clases que nos permiten modificar el comportamiento general de la aplicación y la lógica del negocio de Magento.
Estas clases nos serán de utilidad para poder implementar acciones cuando se produzca un evento determinado.
Eventos personalizados
Para crear un Evento personalizado necesitamos crear un fichero llamado events.xml en el directorio etc/ de nuestro módulo y al que le indicaremos que observador reaccionará al producirse el evento.
Si queremos ser ordenados lo suyo es crear el Observer dependiendo de la función que realice en los directorios etc/adminhtml/ o etc/frontend/
Creando un Observer
Para crear un Observer creamos un directorio llamado Observer/ en el directorio raíz de nuestro módulo.
Todos los Obsersers usan la clase Magento\Framework\Event\Observer e implementan el interfaz Magento\Framework\Event\ObserverInterface y por supuesto necesitamos incluir un método execute()
Una de las ventajas de los Observers es que podremos pasarle parámetros a través del Evento.
Otra ventaja de los los Observers es que podemos configurarlos para observar ciertos eventos.
Los atributos de un Observer son:
- name: Un nombre único para el Observer
- instance: El nombre de la clase Observer
- disabled: Nos permite desactivar el Observer (por defecto es false)
- shared: El tipo de vida del objeto, si es único o se crean nuevas en cada petición (por defecto es false)
Veamos un ejemplo práctico de un observer:
1 2 3 4 5 |
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd"> <event name="catalog_controller_product_view"> <observer name="my_observer" instance="<vendor>\Desarrollo\Observer\MyObserver" disabled="false" /> </event> </config> |
Estamos creando un Evento del del controlador de vistas de producto del módulo Catalog de Magento.
Cuando esté Evento se ejecute vamos a crear una clase Observer para poder escuchar que sucede y así realizar una serie de cambios.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
<?php namespace <vendor>\Desarrollo\Observer; use Magento\Framework\Event\Observer; use Magento\Framework\Event\ObserverInterface; class MyObserver implements ObserverInterface { protected $_logger; /** * @param \Psr\Log\LoggerInterface $_logger */ public function __construct( \Psr\Log\LoggerInterface $logger ) { $this->_logger = $logger; } public function execute( Observer $observer ) { $product = $observer->getProduct(); // Comprobar métodos mágicos en Magento/Catalog/Model/Product $nombre = $product->getName(); // nombre del producto $precio = $product->getPrice(); // precio del producto $categorias = $product->getCategoryIds(); // categorias del producto $descuento = 5; // porcentaje de descuento a aplicar $categoria_descuento = '9'; // categoria a la que aplicamos un descuento // comprobamos que la categoria con descuento pertenezca al producto seleccionado if (in_array($categoria_descuento, $categorias, true)) { $precio_final = $precio-($precio*$descuento/100); $product->setPrice($precio_final); } else { $precio_final = $precio; } // Debug de mi Observer // $this->_logger->debug('test'); $writer = new \Zend\Log\Writer\Stream(BP . '/var/log/myObserverlog.log'); $logger = new \Zend\Log\Logger(); $logger->addWriter($writer); $logger->info( get_class($this), [ 'PRODUCTO' => $nombre , 'CATEGORIAS PRODUCTO' => $categorias, 'CATEGORIAS CON DESCUENTO' => $categoria_descuento, 'PRECIO INICIAL' => floatval($precio), 'PRECIO_FINAL' => floatval($precio_final) ] ); } } |
Este Observer captura los datos del producto y usando Métodos Mágicos que podremos encontrar en Magento/Catalog/Model/Product, aplica un descuento al producto si pertenece a una determinada categoría.
Por último he creado un Loguer que creará un nuevo fichero de Log en var/log/ llamado myObserverlog.log y que nos permite hacer debug de los datos del Observer.
1 2 3 |
$ tail -f ./var/log/myObserverlog.log 2019-01-07T18:33:12+00:00 INFO (6): <vendor>\Desarrollo\Observer\MyObserver {"PRODUCTO":"Mochila de estilo clásico, Rojo","CATEGORIAS PRODUCTO":"[\"9\",\"10\"]","CATEGORIAS CON DESCUENTO":"9","PRECIO INICIAL":18.99,"PRECIO_FINAL":18.0405} |
Y como veis hemos aplicado el descuento correctamente al producto que pertenece a la categoría indicada.