Csatlakozz a Slack chatre
Hocza József / 1 éve

Laravel - Események (Events)

Hogy mik az Eventek, és hogyan tehetik jobbá/szebbé a kódodat? Íme.

Tapaszatalatom szerint a fejlesztők nagy része lebecsüli vagy fel sem ismeri a jelentőségét az Eventeknek. Az eventek helyett pedig Controller functionök nagyobb mennyiségű kódot tartalmaznak, mint amennyit kellene. Ráadásul minden alkalommal amikor bővíteni szeretnéd, hogy mi történjen egy bizonyos szituációban, hát visszamész a Controllerhez és megtoldod.
A végén pedig ott állsz egy olyan hosszú Controller function felett, ami akár több száz soros és borzasztóan átláthatatlan.

Na de itt vannak ezek az Eventek és Listenerek. Mi is ez?

Történik valami, például a csomag kiszállításra került (ez egy Event). Erről kell egy értesítő e-mailt küldeni az ügyfélnek (ez egy Listener).

Ehhez fel kell rögzítenünk az EventServiceProvider-ben ezeket.

protected $listen = [
    'App\Events\OrderShipped' => [
        'App\Listeners\SendShipmentNotificationViaEmail',
    ],
];

Az artisannal létre is tudod hozni az itt meghatározott Eventeket és Listenereket: php artisan event:generate

(Az alábbiban én már beleraktam az Order modelt)

<?php

namespace App\Events;

use App\Events\Event;
use App\Models\Order;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;

class OrderShipped extends Event
{
    use SerializesModels;

    public $order;

    /**
     * Create a new event instance.
     *
     * @param Order $order
     */
    public function __construct(Order $order)
    {
        $this->order = $order;
    }

    /**
     * Get the channels the event should be broadcast on.
     *
     * @return array
     */
    public function broadcastOn()
    {
        return [];
    }
}

És így fog kinézni a Listener (persze ez is már általam bővítve)

<?php

namespace App\Listeners;

use App\Events\OrderShipped;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;

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

    /**
     * Handle the event.
     *
     * @param  OrderCreated  $event
     * @return void
     */
    public function handle(OrderShipped $event)
    {

        if($event->order && filter_var($event->order->email, FILTER_VALIDATE_EMAIL))
            \Mail::send("emails.orderCashOnDelivery", ["order" => $event->order], function ($message) use($event) {
                $message->from('info@cegem.hu', "Könyvesbolt Cégem");

                $message->subject('Rendelését a futár a mai napon felvette.');

                $message->to($event->order->email);
            });
    }
}

És a megfelelő Controllerben eldurrantjuk az Eventet: event(new App\Events\OrderShipped($order));

Természetesen nekem is megfordul a fejemben, hogy mennyivel egyszerűbb lenne az e-mailes részt beszúrni a function végébe.
Na de mi történik, ha kell egy e-mailt küldeni az Adminisztrátornak is, amelynek a tartalma merőben másabb (tehát egy CC hozzáadásával nem végezheted el). Hozzáraksz még egy Mail::send-et?
És mi van akkor, ha kell SMS-t is küldeni, a megrendelőnek na meg az adminisztrátornak is?
Majd 1 hónap múlva a főnök kitalálja, hogy ekkor kellene csak levonni a leltárból azt a könyvet.
Majd...

Tehát mint látod előbb utóbb ha csak bővíted és bővíted az az egy functiont a Controllerben, ott fogod magadat találni, hogy ránézel és egy kész katyvasz van előtted. És utána amikor hozzá kellene nyúlni... :)

Na most ha használod az Event Servicet, egy event(new ...) -nál több nem lesz a functionödben, és lesz egy átlátható kódod arról, hogy mikor mi is történik az alkalmazásodban.

protected $listen = [
    'App\Events\OrderShipped' => [
        'App\Listeners\SendShipmentNotificationViaEmail',
        'App\Listeners\SendShipmentNotificationViaSMS',
        'App\Listeners\SendShipmentNotificationViaEmailToAdministrator',
        'App\Listeners\SendShipmentNotificationViaSMSToAdministrator',
        'App\Listeners\ReduceInventory',
    ],
];

Nyilván csinálhatnánk egy Notification Interfacet, hogy akár 1 Listenerrel elintézhessük az értesítéseket és még lehet mit pofozni rajta. :)

Szerintem ez egy egész klassz dolog, amit out of the box megkapunk a Laravellel.

Cimkék:    tutorial    events    laravel
 Vissza a cikkekhez