Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel listener listen to multiple event

So according to the laravel event doc, when defining listeners, it can receive the event instance in their handle method and perform any logic necessary:

public function handle(FoodWasPurchased $event)

So if my FoodWasPurchased event is defined as below (assumed EventServiceProvider is set):

public function __construct(Food $food)
{
    $this->food = $food;
}

I could access the $food in event from listener by doing:

$event->food->doSomething();

But now my question is what if a listener listen to multiple events?

Event FoodWasPurchased -> Listener Bill
Event DrinksWasPurchased -> Listener Bill

What I did now is I did not specify the event instance in the listener handle method:

public function handle($event)

where I can later use an if condition to check what is received in the $event:

if (isset($event->food)) {

    // Do something...

} elseif (isset($event->drinks)) {

    // Do something else...

}

I'm sure there is a better way.

Or the best practice is ensure that one listener only listens to one single event ?

like image 918
Park Lai Avatar asked Jul 10 '15 16:07

Park Lai


2 Answers

You can listen to multiple events by using Event Subscribers which are placed in the Listeners folder but are capable of listening to multiple events.

<?php

namespace App\Listeners;

class UserEventListener{
    /**
     * Handle user login events.
     */
    public function onUserLogin($event) {}

    /**
     * Handle user logout events.
     */
    public function onUserLogout($event) {}

    /**
     * Register the listeners for the subscriber.
     *
     * @param  Illuminate\Events\Dispatcher  $events
     * @return array
     */
    public function subscribe($events){
        $events->listen(
            'App\Events\UserLoggedIn',
            'App\Listeners\UserEventListener@onUserLogin'
        );

        $events->listen(
            'App\Events\UserLoggedOut',
            'App\Listeners\UserEventListener@onUserLogout'
        );
    }

}
like image 106
jagzviruz Avatar answered Sep 20 '22 18:09

jagzviruz


If your events conform to a contract or interface it seems you can pass as many as you like to a listener...

class MyEventOne extends Event implements MyEventInterface

Then in the EventServiceProvider you connect up your events and listeners as so...

protected $listen = [
    'App\Events\MyEventOne' => [
        'App\Listeners\MyListener',
    ],
    'App\Events\MyEventTwo' => [
        'App\Listeners\MyListener',
    ],
];

And finally in your listener you type hint your handler to accept the event object based on the contract/interface...

public function handle(MyEventInterface $event)

I've unit tested this, it may not be appropriate for every scenario, but it seems to work. I hope it helps.

like image 26
RobDW1984 Avatar answered Sep 20 '22 18:09

RobDW1984