Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Self-registering event listeners #19917

Merged
merged 1 commit into from
Jul 6, 2017
Merged

Self-registering event listeners #19917

merged 1 commit into from
Jul 6, 2017

Conversation

adamwathan
Copy link
Contributor

This is still just an early idea, but was talking through it with Taylor and thought it'd be a good idea to open a PR for discussion.

The general idea is to allow you to specify which events your listeners listen to in the listener itself instead of creating a mapping in your EventServiceProvider. Then all you'd need to do is throw your listeners in an array in the service provider to register them.

Here's what your EventServiceProvider might look like:

class EventServiceProvider extends ServiceProvider
{
    protected $listeners = [
        \App\Listeners\SendFulfillmentFailedEmail::class,
        \App\Listeners\AttemptFulfillment::class,
    ];

    public function boot()
    {
        parent::boot();
    }
}

And here's what a listener would look like:

class SendFulfillmentFailedEmail
{
    public static $hears = [
        \App\Events\FulfillmentFailed::class,
    ];

    public function handle($event)
    {
        Mail::to($event->makerEmail())->send(new FulfillmentFailedEmail($event->purchase));
    }
}

We'd want to support backwards compatibility with the old approach, which this implementation does as far as I have tested.

Things to explore/figure out:

  • How does this affect the generators?
  • Friendlier error handling

@@ -54,6 +54,12 @@ public function register()
*/
public function listens()
{
return $this->listen;
return array_merge_recursive(collect($this->listeners)->flatMap(function ($listener) {
return collect($listener::$hears)->map(function ($event) use ($listener) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe $listener::$hears ?? [] ?

@taylorotwell taylorotwell merged commit 7dd75ee into laravel:master Jul 6, 2017
@taylorotwell
Copy link
Member

Event generation adjusted to handle this properly.

@browner12
Copy link
Contributor

could this have gone to 5.4? doesn't seem like we're breaking anything since we're just merging the two events, right?

@connectkushal
Copy link
Contributor

connectkushal commented Jul 6, 2017

use $watches, $tracks or $detects instead of $hears maybe ?

@BrandonShar
Copy link
Contributor

What about $listensFor instead of $hears?

@browner12
Copy link
Contributor

people, let's not bike shed this. the name is fine.

@BrandonShar
Copy link
Contributor

I disagree; naming things is hard and worth a conversation. Might be better for me to just open a PR with the suggestion though instead of discussing it here.

@browner12
Copy link
Contributor

i agree wholeheartedly that naming things is important. problem here is you're going from an OK name to another OK name. so all of these suggestions are completely subjective.

if you can provide some objective evidence why $hears is bad or causes a problem, then let's definitely discuss it.

@BrandonShar
Copy link
Contributor

BrandonShar commented Jul 6, 2017

Good point, I should've justified it instead of just tossing out a name.

The reason I prefer $listensFor instead of $hears is that $listensFor is more active; it describes something that the object is actively doing, whereas $hears feels more passive. If I say I "hear" a particular sound, you would assume that I happen to be in the area when some sound is occurring. If I say I "listen for" a particular sound, you would assume that I am actively attentive while waiting for that sound to occur. We're setting up objects that specifically listen for certain events (and actively wait for them to occur), not just that hear the event activity around them.

Great new feature regardless, though! One less level of indirection when tracing code.

@antonkomarev
Copy link
Contributor

antonkomarev commented Jul 6, 2017

I like listensFor method name because it sounds more natural to me.

With $hears

Q: What is this listener doing?
A: It hears events.

With $listensFor

Q: What is this listener doing?
A: It listens for an events.

@connectkushal
Copy link
Contributor

connectkushal commented Jul 7, 2017

  1. Event listeners hears an event.
  2. Event listeners detects an event.
  3. Event listeners listensFor an event.
  4. Event listeners tracks an event.

I think hears sound most out of line of all the following. I like tracks or detects as they are appropriate terms for events.

Other than that, its a nice pr. Thnx !

@joshmanders
Copy link
Contributor

If we're gonna bikeshed about this, I'd like to throw my suggestion into the ring.

$listener::$stalks or $listener::$creepsOn

Thank you.

@connectkushal
Copy link
Contributor

connectkushal commented Jul 7, 2017

Still better than hears :P ... I'm afraid a simple suggestion is leading this pr towards becoming a troll thread... Sry about that 😬

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants