aka Esdeveniments Laravel o també Application Hooks. Documentació oficial:
https://laravel.com/docs/master/events
Els esdeveniments Laravel proporcionen un implementació simple del patró de disseny observer permeten la subscripció i escolta d'esdeveniments a la nostra aplicació
Pot ser molt útil per crear codi més DRY per exemple:
https://laracasts.com/lessons/use-events
On veiem com evitem codi repetit als controladors i també evitem que els controladors tinguin més responsabilitats de les que pertoquen (vegeu Single Responsability Principle).
Un altre exemple típic, les accions a executar un cop s'ha logat un usuari:
Event::listen('user.login', function($user) { $user->last_login = new DateTime; $user->save(); }); $event = Event::fire('user.login', array($user));
Executant "només":
$event = Event::fire('user.login', array($user));
Al controlador complim tan el Single Responsability Principle com Open Closed ja que no haurem de modificar el controlador cada cop que decidim realitzar una tasca adicional durant el login de l'usuari.
En aquest sentit és molt interessant el vídeo:
https://laracasts.com/series/whip-monstrous-code-into-shape/episodes/3
I tota la sèrie a la que pertany que tracta sobre com evitar objectes God, és a dir objectes que tenen molt codi i el que es pitjor moltes responsabilitats. En aquest cas s'utilitzen els esdeveniments com una opció possible.
El registre dels event listeners es realitza al fitxer EventServiceProvider al array listen:
/** * The event listener mappings for the application. * * @var array */ protected $listen = [ 'App\Events\EventName' => [ 'App\Listeners\EventListener', ], ];
Cada element de l'array associatiu representa un parell de valors esdeveniment/listener:
Artisan ens ofereix múltiples generadors de codi relacionats amb els esdeveniments de Laravel:
$ php artisan | grep event event event:generate Generate the missing events and listeners based on registration make:event Create a new event class make:listener Create a new event listener class
Com podeu observar tenim tres comandes:
$ php artisan make:event MyEvent
Crea a partir d'un stub/plantilla un esdeveniment a la carpeta app/Events amb el nom de fitxer i classe MyEvent
$ php artisan make:listener MyListener
Crea a partir d'un stub/plantilla un listener a la carpeta app/Listeners amb el nom de fitxer i classe MyListener.
Amb
$ php artisan event:generate
es creen tant els esdeviments com els listeners a partit del declarat a l'array $listen del provider EventServiceProvider.
Una event class (classe esdeveniment) és simplement un contenidor de dades que conté la informació de l'esdeveniment. Vegeu un exemple:
Amb Laravel un cop hem executat:
$ php artisan make:event PodcastWasPurchased
L'esdeveniment pot ser similar a:
<?php namespace App\Events; use App\Podcast; use App\Events\Event; use Illuminate\Queue\SerializesModels; class PodcastWasPurchased extends Event { use SerializesModels; public $podcast; /** * Create a new event instance. * * @param Podcast $podcast * @return void */ public function __construct(Podcast $podcast) { $this->podcast = $podcast; } }
Com podeu veure l'objecte no conté cap lògica i simplement mitjançant la injecció de dependències conté un Model Eloquent amb el podcast que s'ha comprat. El trait SerializesModels facilita la serialització (persistència temporal de l'objecte) de l'objecte.
Amb:
$ php artisan make:listener
podem crear l'esquelet d'un listener. Continuant amb l'exemple de la compra d'un podcast:
<?php namespace App\Listeners; use App\Events\PodcastWasPurchased; class EmailPurchaseConfirmation { /** * Create the event listener. * * @return void */ public function __construct() { // } /** * Handle the event. * * @param PodcastWasPurchased $event * @return void */ public function handle(PodcastWasPurchased $event) { // Access the podcast using $event->podcast... } }
Com podeu veure ha de contenir un mètode handler que serà el mètode que s'executarà al ocorre l'esdeveniment (el que es coneix com un event handler). Observeu com es passa l'objecte esdeveniment com una injecció de dependències per mètode type-hinted
Per aturar la propagació d'un esdeveniment cal tornar false al mètode handler.
Simplement cal implementar la interfície ShouldQueue. Un exemple:
<?php namespace App\Listeners; use App\Events\PodcastWasPurchased; use Illuminate\Contracts\Queue\ShouldQueue; class EmailPurchaseConfirmation implements ShouldQueue { // }
Amb això Laravel ja s'encarregarà d'executar el handler de l'esdeveniment en segon terme.
https://laravel.com/docs/master/events#firing-events
3 opcions:
Un exemple:
<?php namespace App\Http\Controllers; use Event; use App\Podcast; use App\Events\PodcastWasPurchased; use App\Http\Controllers\Controller; class UserController extends Controller { /** * Show the profile for the given user. * * @param int $userId * @param int $podcastId * @return Response */ public function purchasePodcast($userId, $podcastId) { $podcast = Podcast::findOrFail($podcastId); // Purchase podcast logic... Event::fire(new PodcastWasPurchased($podcast)); } }
Amb helper:
event(new PodcastWasPurchased($podcast));
I finalment podeu veure un exemple de com Injectar dependència objecte event i executar esdeveniment fire a:
TODO
Vegeu Laravel Broadcasting Events
Un exemple de juguet de com fer-ho tot al fitxer routes.php i només amb Facades:
Event:fire('listen', function() { //Event handler here }); Event:fire('event');
Recursos: