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

Conversation

Projects
None yet
8 participants
@adamwathan
Member

adamwathan commented Jul 5, 2017

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) {

This comment has been minimized.

@lucasmichot

lucasmichot Jul 5, 2017

Contributor

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

@lucasmichot

lucasmichot Jul 5, 2017

Contributor

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

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

3 of 4 checks passed

continuous-integration/travis-ci/push The Travis CI build could not complete due to an error
Details
continuous-integration/styleci/pr The StyleCI analysis has passed
Details
continuous-integration/styleci/push The StyleCI analysis has passed
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
@taylorotwell

This comment has been minimized.

Show comment
Hide comment
@taylorotwell

taylorotwell Jul 6, 2017

Member

Event generation adjusted to handle this properly.

Member

taylorotwell commented Jul 6, 2017

Event generation adjusted to handle this properly.

@browner12

This comment has been minimized.

Show comment
Hide comment
@browner12

browner12 Jul 6, 2017

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?

Contributor

browner12 commented Jul 6, 2017

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

This comment has been minimized.

Show comment
Hide comment
@connectkushal

connectkushal Jul 6, 2017

Contributor

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

Contributor

connectkushal commented Jul 6, 2017

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

@BrandonShar

This comment has been minimized.

Show comment
Hide comment
@BrandonShar

BrandonShar Jul 6, 2017

Contributor

What about $listensFor instead of $hears?

Contributor

BrandonShar commented Jul 6, 2017

What about $listensFor instead of $hears?

@browner12

This comment has been minimized.

Show comment
Hide comment
@browner12

browner12 Jul 6, 2017

Contributor

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

Contributor

browner12 commented Jul 6, 2017

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

@BrandonShar

This comment has been minimized.

Show comment
Hide comment
@BrandonShar

BrandonShar Jul 6, 2017

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.

Contributor

BrandonShar commented Jul 6, 2017

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

This comment has been minimized.

Show comment
Hide comment
@browner12

browner12 Jul 6, 2017

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.

Contributor

browner12 commented Jul 6, 2017

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

This comment has been minimized.

Show comment
Hide comment
@BrandonShar

BrandonShar Jul 6, 2017

Contributor

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.

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

This comment has been minimized.

Show comment
Hide comment
@antonkomarev

antonkomarev Jul 6, 2017

Contributor

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.

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

This comment has been minimized.

Show comment
Hide comment
@connectkushal

connectkushal Jul 7, 2017

Contributor
  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 !

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

This comment has been minimized.

Show comment
Hide comment
@joshmanders

joshmanders Jul 7, 2017

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.

Contributor

joshmanders commented Jul 7, 2017

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

This comment has been minimized.

Show comment
Hide comment
@connectkushal

connectkushal Jul 7, 2017

Contributor

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

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