Eventos y Listeners en Laravel

Laravel tiene un manejo limpio y sencillo de los eventos y listeners. Cuando estamos desarrollando una web en ocasiones necesitamos que cuando algo ocurra se dispare un evento que puede ser el envio de un email por que un usuario publicó algo nuevo en la web o por que se registró. En esta ocasión lo que haremos será enviar un email avisando de una nueva publicación, tambien podrias hacer inserciones a la base de datos con cosas referentes al evento.

Un lugar muy bueno para poner este tipo de eventos es por ejemplo en un bloque try catch, donde al saltar una excepción y entrar en juego el codigo del bloque catch no queremos que el script se detenga y enseñe información del error al usuartio normalmente lo redirigimos a una pagina de error 404 Not Found o a la página anterior con un mensaje de error, pues antes de redirigir al usuario de la web podemos crear dos eventos, el primero que nos avise via email de que en ese bloque try catch ha habido un problema y otro evento que guarde el error, si es que se ha podido capturar la excepción, en una tabla de Logs la base de datos, y poder consultar cuando y que ocurrió.

Yo llamaré al evento NewAdd pues se trata de una web app de anuncios de alquileres, vamos a la consola de comandos y ejecutamos los comandos siguientes para crear en la carpeta app/Events y en la carpeta app/Listeners los archivos necesarios.

php artisan make:event newAdd
php artisan make:listener SendNewAddNotification --event=NewAdd
Eventos-en-laravel
Eventos-en-laravel

con ello tendremos el archivo del evento newAdd.php al cual añadiremos el siguiente codigo. Ya sabeis que todo siempre se puede consultar en la documentación oficial de Laravel. Al contructor de la clase newAdd le voy a pasar una instancia del modelo de anuncio.

<?php

namespace App\Events;


use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
use App\Models\Anounces;

class newAdd
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $anounce;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct(Anounces $anounces)
    {
        $this->anounce = $anounces;
    }

    
}

Y el archivo SendNewAddNotification.php en la carpeta app/Listeners hemos de dejarlo de la siguiente manera para que se genere la logica del evento. y por su puesto tener la plantilla HTML en nuestra carpeta de resources/views/mail el archivo newAdd.blade.php, donde recogeremos las variables enviadas en $data con las dobles llaves, {{ $id }} y {{ $email }} para incluir la información en el mail.

<?php

namespace App\Listeners;

use App\Events\NewAdd;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Auth;

class SendNewAddNotification
{
    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Handle the event.
     *
     * @param  NewAdd  $event
     * @return void
     */
    public function handle(NewAdd $event)
    {
        // estos son los valores que enviaremos a la plantilla blade del email
        $data = [
            'id' => $event->anounce->id,// id del nuevo anuncio
            'email' => Auth::user()->email,// email de quien lo crea, en este caso el usuario que está registrado
        ];
 
        Mail::send('mail.newAdd', $data, function($message) use ($data) {
            $message->to('tu_email_va_aqui'])
                    ->subject('Anuncio nuevo publicado');
            $message->from('pedidos@azimutweb.es');
        });
    }
}

Despues para disparar el evento cuando queramos solo hemos de incluir esta linea en cualquier controlador que queramos, en este caso lo colocaré en el controllador que se encarga de publicar el anuncio justo despues de guardar el anuncion en la Base de datos. Y en la variable $anuncio, por su puesto, hay un modelo del anuncio recien creado.

event(new newAdd($anuncio));

Y con esto, cada vez que un usuario publica algo en la web me llegará un email notificandomelo.

Saludos.