Introducing Auto-Discovery0:00
I really love new features that streamline your typical workflow. So check this out. In Laravel 5.8.9, we now have automatic event listener registration. Let's make an event. Something typical, like a UserRegistered event. And then we need a listener for that. Okay, how about SendWelcomeEmail. Very typical. And the event associated with that is UserRegistered. Okay, so now we have an event for an action that took place in our system.
Old Manual Registration0:23
And the event associated with that is UserRegistered. Okay, so now we have an event for an action that took place in our system. And we have an event listener that handles when that action occurs. Now, in older versions of Laravel, and actually real quick, we'll say, send the welcome email. Just to prove that we are calling this method. But anyways, in past versions of Laravel, you had one final step. You needed to visit your providers directory and register the event and event listener grouping, or lookup table. So for example, right down here, we could say listen for
register the event and event listener grouping, or lookup table. So for example, right down here, we could say listen for when a User is registered, and then Laravel should trigger these listeners. And in this case, we just have one, sendWelcomeEmail. And you'd have to do that every single time. So if I add a new event listener, we'd have to return to this file and update this array, and it would work. So if I put up php artisan tinker, and then we run, or we emit an event, userRegistered, sure enough, the listener is triggered. But that's the old way.
Enable Event Discovery1:21
we emit an event, User registered, sure enough, the listener is triggered. But that's the old way. You can still do this if you want, but I prefer to have it automatically wired. So I can delete this entirely. At least for now, we need to turn on this functionality. I'll create a shouldDiscoverEvents method, and simply return true. And again, this is our way of telling Laravel, I'd instead prefer that you look in this directory and automatically figure them out. But because this is a patch release for Laravel 5.8, you have to manually turn it on.
But because this is a patch release for Laravel 5.8, you have to manually turn it on. So potentially with Laravel 5.9 or Laravel 6 down the road, this may no longer be necessary. We'll see. But anyways, if I give it another shot, and we emit the event, notice it happens automatically. So let's play around. Let's add a new event listener. I'll scroll up a few times.
Add Listener Without Registering2:12
Let's add a new event listener. I'll scroll up a few times. And what else should happen when a User registers? Maybe, I don't know, recordAchievement, something like that. It doesn't matter. Something that should take place when a User registers. Okay, so now once again, I will just represent that with recordAchievement. And take a look, I'm done. I no longer have to register it. So if we give it another shot, we emit the event, and
I no longer have to register it. So if we give it another shot, we emit the event, and now we trigger all of those listeners. Again, these are small updates, but in my opinion, they make a big difference. Because it streamlines a workflow that you do over and over again. Now that's the new addition, but if you'd like to stick around and figure out, well, how does this work? Take a look. You'll see this should discoverEvents method. Let's go to Laravel, and we'll look for where it's triggered.
How Discovery Works Internally2:55
You'll see this should discover events method. Let's go to Laravel, and we'll look for where it's triggered. All right, it's in the foundations EventServiceProvider. Okay, so you'll see right here, it's going to find the discovered events. And we can see, well, if they're cached, then just return the cached events. So that means, there's probably a little bit of work here. There's probably some Reflection API usage going on there. And for production, we don't want to do that for every page load. So that means, if I run php artisan, I bet we'll find an optimizer here. And there it is, event:cache.
Caching Discovered Events3:23
So that means, if I run php artisan, I bet we'll find an optimizer here. And there it is, event cache. Discover and cache the application's, events, and listeners. So you want to make sure that you add this command to your list of commands to run when you deploy. So we can run that here, and now they're cached. And Laravel no longer has to continue on to this next step. So take a look. This would only happen locally. So Laravel is going to discover the events if you have declared this to be true.
This would only happen locally. So Laravel is going to discover the events if you have declared this to be true. All right, let's quickly breeze through it. So it's going to figure out, well, where should we discover the events? All right, well, by default, it's going to look in the listeners directory. But note, if you want, you can just override this yourself if you want to store them somewhere else. Or if you have an array of places where you have listeners, you can override that method, and now Laravel will use that instead. Okay, so it's going to look in the listeners directory.
you can override that method, and now Laravel will use that instead. Okay, so it's going to look in the listeners directory. It's going to reject anything within the array that is not a directory, okay? Then it's going to merge and create a list of listeners. So it looks like it delegates to this new discoverEventsWithin method. Let's go to there, all right? So listenerPath will be app/listeners, and let's see. So we use Symfony's Finder class to find all of the files within the listeners directory. So that'll give it this, and then we're going to call getListenerEvents, okay?
within the listeners directory. So that'll give it this, and then we're going to call getListenerEvents, okay? So yes, notice, in order to do this, Laravel's going to use the reflection API. And it will look at all of the methods in those listeners, specifically for the ones that start with handle. So this can be a little tricky if you're not familiar with the reflection API. But to be brief, here's what it's doing. It's loading this class, it's getting the handle method, it's looking at the parameter list, and it's finding out what this is. So it's going to ignore any method that does not begin with handle.
it's looking at the parameter list, and it's finding out what this is. So it's going to ignore any method that does not begin with handle. At least, that's the current functionality at the time of this recording. So find the listener, look at the methods, find the one that starts with handle, and then figure out what the class name is of the event. Then that gets returned. So let's see, for each listener get method, so get all of the methods within the class. If the method does not begin with handle, continue, move on. Otherwise, take a look right here, method get parameters.
If the method does not begin with handle, continue, move on. Otherwise, take a look right here, method get parameters. So the parameters would be, in this case, event, all right? Then get the class of that event, UserRegistered. And then it updates this listener events. But that'll do it, that's all you need to know here. So if you want in Laravel 5.8 to automatically discover events, make sure you're at least on Laravel 5.8.9. If not, do a composer update, and then be sure to create this method on your EventServiceProvider, and you're all set to go.
If not, do a composer update, and then be sure to create this method on your EventServiceProvider, and you're all set to go. I love it.
