تماشای این درس نیاز به اشتراک حرفه‌ای دارد.

Exploring Register Flow0:00

Let's now figure out how Breeze registers a User. It's very simple. So if we come over to the RegisteredUsersController, as we learned in the last episode, that loads this register view. We've learned a bit about Blade components here, and we can also see this auth validation errors. So it sounds like if I try to register incorrectly, like I believe usually the minimum number of characters for a password is seven. So this should all fail validation, and it does. Yeah, we see it right up here at the top.

So this should all fail validation, and it does. Yeah, we see it right up here at the top. And that is thanks to this auth validationErrors component. So if we were to have a quick look at this, if you've ever handled failed validation in a Laravel app before, it's going to look something very similar to this. If we have any errors, then show a heading and then iterate over each of the errors and display the message within a list item. So this gets wrapped up within a component that's easy to understand. And then all you have to do is pass the errors to it. And don't forget, for every page load, there's going to be an errors variable, regardless

Tracing Register Routes1:01

And then all you have to do is pass the errors to it. And don't forget, for every page load, there's going to be an errors variable, regardless of if you have failed validation or not. Okay, but anyways, assuming validation doesn't fail, it looks like we're set up to submit a traditional POST request to this route called register. Okay, let's go to our routes file. And you'll remember it pulls in this auth routes file. And here's the name register. So it's submitting a POST request to /register. But notice this is set up for GET.

So it's submitting a POST request to /register. But notice this is set up for GET. It's okay, the URI is still the same. So instead, it's going to hit this one here, POST to that same URI. And it'll hit a store method on RegisteredUserController. Okay, let's have a look right down here. And again, this is about as simple as you can get, which I like. Validate the request. And then if validation fails, Laravel will automatically redirect back. But otherwise, if you get to this line right here, validation, of course, has succeeded.

User Creation and Hashing1:55

And then if validation fails, Laravel will automatically redirect back. But otherwise, if you get to this line right here, validation, of course, has succeeded. Anyways, we then create a User. And then we pass that newly created User to auth login, and we fire an event and redirect to the dashboard. Okay, so a couple things here. We can see that Laravel is setting the password here manually. Another option, which plenty of people often do, is on your User model, you could use a mutator. So for example, you could say whenever the password is set, set password attribute.

mutator. So for example, you could say whenever the password is set, set password attribute. So whenever we call effectively $user->password equals something, whenever you do that, it will automatically call this method. Or you could then say, okay, I'm going to manually set the password field or attribute equal to not just the value, but the encrypted version. And I can use this little helper bcrypt function, which is the same as hash make. Okay, so if you took that approach, you could then always just reference whatever the user typed in to that form, with the knowledge that as soon as you set it, it will automatically call this method where the value they type is hashed.

typed in to that form, with the knowledge that as soon as you set it, it will automatically call this method where the value they type is hashed. Okay, so that's an option, just showing you that you always have choices, and you can configure this however you want to because you own the code. Anyways, I'm going to bring this back to what we had earlier. Now we'll talk about the event in a minute, but I do want to touch upon something to consider. Depending upon where you come from, sometimes things like this seem laughably basic, as if something is missing. For example, you might think this should be in a UserCreator service. So you would then do something like, maybe you have a dependency called registration.

For example, you might think this should be in a User creator service. So you would then do something like, maybe you have a dependency called RegistrationService, and then you call a create method on that. Or maybe you have create from request. You know, have you ever seen things like this? And sometimes it makes us feel as if we are structuring things better, and maybe that's the case, depending upon the use case. But my recommendation would be, don't always default to things like this, because really, think about what you're actually doing here. It may feel good, because suddenly your Controller can remove all of this, and it's that much

think about what you're actually doing here. It may feel good, because suddenly your controller can remove all of this, and it's that much more simple. But think about it. What are you really doing here? You're taking all of this that was nicely in the controller, easy to consume, and you're extracting, we'll just do it here. You're extracting a service class that will have a create from request, like so, and we'll paste that in, like so. So yeah, think about it.

Registration Event Listener6:01

And I believe, yeah, this is one of the cases where you do not own this event, because you don't really need to. If we switch over to the sidebar, you can see this does live within the vendor directory. So you don't own this file. But on that note, that gives us something else to talk about. I'll show you. Let's go to your standard EventServiceProvider. And here we can see, all right, listen for the registered event that we just fired. And we're going to call this listener, sendEmailVerificationNotification. Here we go.

And we're going to call this listener, sendEmailVerificationNotification. Here we go. And again, this too is a file that you don't own. It exists in the vendor directory, because you don't really need to own it. But if you did, of course, just extend this class or create your own, and then update EventServiceProvider with your own class, and you're good to go. Anyways, let's have a look here. If the User implements the MustVerifyEmail interface, and they haven't already done that, then fire off a notification. So think about it.

then fire off a notification. So think about it. Just by looking at this code and browsing around, if you never knew that Laravel supported email verification out of the box, well, now you do. You can see, all right, it's checking to see if it implements an interface. Let's have a look. Does it implement the interface? No, it doesn't. Okay, so that means if we want email verification, of course, check the docs. But to get you started, you would implement the interface, MustVerifyEmail, all right?

Okay, so that means if we want email verification, of course, check the docs. But to get you started, you would implement the MustVerifyEmail interface, all right? Next it checks if the User has not already verified their email. Let's have a look here. This is the interface. Can I get to... Maybe not. PhpStorm should be able to find that, but it doesn't seem to. So let's find it directly on User. Actually, you should see where this comes from.

So let's find it directly on User. Actually, you should see where this comes from. So your User model extends Authenticatable, which is this right here, and you'll see your User model is almost always the thing that does the most things in a project. So you can see how Laravel divides these up. It splits them into traits. So for example, a User is authorizable. That's where you can do things like, well, if the User can certain ability, or can't, or cannot, all of those exist on this trait. The same would be true for resetting a password or verifying an email.

or cannot, all of those exist on this trait. The same would be true for resetting a password or verifying an email. So here's where we can find all of that logic. Okay. So now it's checking, has the User already verified their email? Well, we're looking at this emailVerifiedAtAttribute on the User model. And by the way, this has nothing to do with Breeze at this point. We've switched over to the Laravel framework, which is fine, or we're just kind of playing around here. But yeah, it's looking for this attribute.

around here. But yeah, it's looking for this attribute. And if it's populated with a timestamp, then the User, of course, has verified their email. So then, we're not going to continue much further down this, but you would want to ensure that your user migration does include a field for the emailVerifiedAt. And then you would need to add two or three different endpoints to handle email verification. But the main point here is by hunting through this code, and I'll switch back here, you're able to learn things that you may not have originally known. So with that in mind, why don't we send the email verification? Now to do that, we would first need to check our .env file.

Configuring Email Delivery9:16

So with that in mind, why don't we send the email verification? Now to do that, we would first need to check our .env file. And you can see by default, it's set to SMTP. It assumes you might want to use MailHog. If you want to do that, this is set up for using Laravel Sail, but you could also just do localhost here. If you don't have it, you could install it through Brew or visit the GitHub page for MailHog. You do something like this, and then you could boot it up from the command line, and it will give you a server at localhost:8025, or use whatever you prefer.

You do something like this, and then you could boot it up from the command line, and it will give you a server at localhost:8025, or use whatever you prefer. Okay, so now we are listening for incoming mail. The rest of these should be configured. So for example, port 1025 is fine. The from address, why don't we just do something like support@breeze.com. The from name we'll grab from up here. This is all perfectly fine. Okay, so let's think about it. When a User registers with Breeze, we validate the request.

Okay, so let's think about it. When a User registers with Breeze, we validate the request. We create a User in our database. We log that User in. We then dispatch an event, and then we saw in our EventServiceProvider, when that User is registered, we will check, well, should they verify their email? Have they not already done it? And if both of those are true, fire off a notification. And if you want to see technically what that's doing, again, you're just hunting around here. You're playing around.

And if you want to see technically what that's doing, again, you're just hunting around here. You're playing around. We're using Laravel's notification feature. So User notify new VerifyEmail. This is a simple notification that you can create yourself with php artisan make:notification. So it's effectively this. Now we can see these references to createUrl callback to mail callback. We'll talk about that in just a second to wrap up the video here. But this is the message here. We figure out the verification URL, and that just sets up a temporary signed route.

But this is the message here. We figure out the verification URL, and that just sets up a temporary signed route. And we say, please click the button below to verify your email address. Okay, so if everything is done correctly, Mailhog should receive a new email after we sign up. John Doe. And there we go. Let's switch over to Mailhog. And sure enough, we have a new email from Laravel that we need to verify our email address. Now what's cool here is because we're using Breeze, the stubs already have the necessary

And sure enough, we have a new email from Laravel that we need to verify our email address. Now what's cool here is because we're using Breeze, the stubs already have the necessary information and routing to handle email verification. For example, if we come on back to our auth routes, scroll on down. Yep, it's already set those up. So let's have a look here. I'm going to copy this link. So we have our app /verify-email/{id}, and then you have your long signed route with an expiration date. Okay, so we should see that.

route with an expiration date. Okay, so we should see that. Here it is. Verify email ID hash. Let's have a look here. This is a single action controller. So it uses __invoke. And yeah, if the User has verified their email address, there's nothing left to do. Otherwise, mark the email as verified. And all that's going to do is update that attribute with the current timestamp like

Otherwise, mark the email as verified. And all that's going to do is update that attribute with the current timestamp like we just talked about earlier. And then we fire a new event, and that's it. So let's see if it works. We're going to do php artisan tinker App\Models\User, we should only have one. They have not verified their email. But if we go ahead and do it, all right, let's do it again. And there you go. Email verification out of the box with Laravel Breeze.

Customizing Verification Email12:51

And there you go. Email verification out of the box with Laravel Breeze. But yeah, it's pretty cool. So now to wrap up, think about it. This email here, all of this formatting came from the verify email notification. However, this particular file, as you see here, you don't own. So what about the situations where you want to configure how this email appears? This can sometimes get tricky. How do you do it? If the notification is within a mailable, how can you allow the user to provide their

How do you do it? If the notification is within a Mailable, how can you allow the user to provide their own mail message? These are things as a package developer, you have to think about. Now I've never used this before, but if we have a look, you can see this mail callback here. And let's see where it's referenced. Okay, so when we build up the email, notice it will either default to creating this mail message here, or if that property is set, then we will call this anonymous function where you can build it on your own.

message here, or if that property is set, then we will call this anonymous function where you can build it on your own. Okay, let's figure out how to assign this. It's public, so you could just do it directly, but there's also a static method called toMail using. Okay, so let's think about this. I've never looked at this code before, to be honest, but if I call this method, it will update the property. And then when it builds up the email right here, it's going to check, well, did you call that method?

And then when it builds up the email right here, it's going to check, well, did you call that method? If so, we are going to call the function you give us and return that message instead of using our default. Okay, so now if you want to play with this, let's throw it in a simple service provider and we'll do it right down here. Verify email to mail using, and we'll give it a function here. And let's figure out what to expect here. So when does it call the function? It's going to call the function here, and then it's going to pass notifiable.

So when does it call the function? It's going to call the function here, and then it's going to pass notifiable. This is almost always the User, but there are ways to notify things that are not a User. So it uses that notifiable term, and then it gives us the signed route. Okay, let's go back. Accept the notifiable and then the URL. So I can paste all of this in here and we could say, hey there, change it up however you want. Please, we're going to be ultra polite, please verify the email address, whatever you want. So now we've learned that verifyEmail, that again, doesn't ship with Breeze, allows for

Please, we're going to be ultra polite, please verify the email address, whatever you want. So now we've learned that verifyEmail, that again, doesn't ship with Breeze, allows for overriding the mail message entirely, should you need to. And this is one way to get around the case where logic is stored in a package, but still needs to be configurable by the end user. All right, so let's try this one more time, and then we'll wrap up here. Log out, register a new Person, there we go, and notice this is the old one, verify your email address, but if we go back to our inbox, here is the new mail message that we built up. Kind of cool.

دوست دارید گاهی خبرهای Laracasts را ایمیل کنیم؟