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

Remove Controller and Route0:00

Alright, so we moved pretty quickly in this mini-series. Let's take one last episode to go over everything and make any final adjustments. And while we're here, we'll also write at least one test to confirm that our notification is sent when we dispatch a job. Okay, so first up, the controller. That was mostly for an example. In real life, I will send a User an invoice, again, as the result of an artisan command that I trigger myself or through a webhook event listener. So with that in mind, I'm going to delete this. And then real quick, in my routes file, we should also get rid of the corresponding route.

Refine Artisan Command0:32

So with that in mind, I'm going to delete this. And then real quick, in my routes file, we should also get rid of the corresponding route. Okay, so that leaves me with a php artisan send:latest-invoice command. We can have a look at that here. Get rid of the constructor. And let's ask the User for their email. We track them down. We send the latest invoice, and then we provide some feedback. Now I think this is honestly pretty fine, but if you want, we could even have a user method where I grab this, like so.

Now I think this is honestly pretty fine, but if you want, we could even have a user method where I grab this, like so. So we'll just have one method that requests the User and then tracks them down. So that would return our User. Yeah, and then up here, we could just say user, like so. Send their latest invoice, and then grab their email. Or actually, this is a good use case for tap. Grab the User, accept it, and then send the latest invoice, provide some feedback. And yeah, something like that would be an option if you want. Honestly, I don't think this is necessarily better or worse than what we had before.

Make sendInvoice Flexible1:36

And yeah, something like that would be an option if you want. Honestly, I don't think this is necessarily better or worse than what we had before. It's just a different way we could prepare it. Anyways, that's good for the mini-series. Let's now switch over to sendLatestInvoice. And yeah, you'll remember in the last episode at the end, we ran into this issue where maybe we want to send the latest Invoice, or maybe we have a different Invoice entirely. So maybe with that in mind, let's say sendInvoice, and this will accept an Invoice. But we won't require it. So I could say here, $invoice, or make it the user's latest Invoice.

Review Job and Notification2:12

But we won't require it. So I could say here, invoice, or make it the user's latest invoice. Yeah, so this makes it just a little bit more flexible. If you call sendInvoice with no arguments, we'll just assume, okay, you probably mean the user's most recent one. Otherwise, if you give us a specific invoice object, we will use that instead. Okay, so that looks good to me. Next, let's go into the Job itself. This Job and its constructor will accept any invoice and any User. And you know what?

This job and its constructor will accept any Invoice and any User. And you know what? We might even want to change it to not accept a User object, but a user email. That way, you could send it to a Lericast user, or maybe you need to send the invoice to the boss of the Lericast user. We can make it more flexible if we get rid of that. And then, yeah, down here, instead of calling user->notify(), there should be a, what is it called, anonymous notifiable. I think this is what we would use. This is when you want to send a notification, not to an existing User, but to any arbitrary.

I think this is what we would use. This is when you want to send a notification, not to an existing user, but to any arbitrary email address. Okay, but we're not going to worry about that. So let's go over this. Just make sure everything looks okay. Yeah, we added this HTML method. Maybe I should do one more here. Let's play around for a minute. Save invoice as PDF, maybe.

Let's play around for a minute. Save invoice as PDF, maybe. And let's bring that up here. Let's see how this looks. Yeah. And then, method name of HTML. Even though that's right, maybe I should call it view instead. Even though I'm technically rendering the view as HTML, so that is right to call it HTML. Maybe this reads better to me.

HTML. Maybe this reads better to me. Give me the rendered view, and then we'll pass that to BrowserShots HTML method. Yeah. And then, let's do this. Let's just move that out, like so. And then return it as a string. Okay, so when we save an Invoice as a PDF, we take a snapshot of it, basically. We save it, and then we return the path to where it was saved. Okay, so now my handle method looks like this.

Clean Up PDF Path4:17

We save it, and then we return the path to where it was saved. Okay, so now my handle method looks like this. We call saveInvoiceAsPDF, but notice it returns a path to the invoice, which might be a little weird. Then also notice when we instantiate our Notification, we give it the path again to the invoice rather than an Invoice object itself. Maybe a little strange. So what I would really rather do is something like this. The Notification simply expects an Invoice, like so. And if we took that approach down here, when we attach the path, hmm, let's see.

The notification simply expects a invoice, like so. And if we took that approach down here, when we attach the path, hmm, let's see. This invoice, and what do we call it? Maybe something like downloadPath, or pdfPath, or something like that. Yeah, maybe we should do that instead. Okay, so let's make it work. Right up here, invoicePaid, we'll just give it the existing invoice. This no longer needs to return anything, which makes sense to me. And then down here, hmm. Let's see.

And then down here, hmm. Let's see. The path, maybe the Invoice should be in charge of that. So what if we did this? Let's go over to my Invoice class, down at the bottom, and we'll say, what did we call it? downloadPath, and we'll let the class be responsible for where the download should be. Okay, so now if I switch back, I can get rid of this. I can save it to this invoice downloadPath.

Okay, so now if I switch back, I can get rid of this. I can save it to this invoiceDownloadPath. And I don't know, what do you think? Is that a little bit cleaner? I'll let you take a look at that, yeah. Save the invoice as a PDF, then notify the User that the invoice was paid. It reads pretty well, I think. The Notification now accepts the invoice, and if we scroll on down, it will attach the file at this downloadPath. Yeah, I think I like that just a little more.

file at this download path. Yeah, I think I like that just a little more. So let's finish up by trying it one last time. php artisan send:latest-invoice. We want housers. And it fails. Send latest invoice on the command, oh yeah, we forgot this. Let's go to sendLatestInvoice, and we changed it to sendInvoice. And you'll remember, we can give it an existing object, or if we don't give it anything, it'll fetch the most recent one for the User.

You were just waiting for me to run into that, weren't you? Okay, cross your fingers for real this time. Hauser. And we're in business now. Okay, so if I come back, there's the email. It was sent to Hauser. It has the PDF. I think we're in business. Okay, so we're basically done, but one last little thing I want to take a look at is back on my user object, it occurred to me that we are sending the invoice from user, but

Move Sending to Invoice7:28

Okay, so we're basically done, but one last little thing I want to take a look at is back on my User object, it occurred to me that we are sending the invoice from User, but I think I might rather do that from Invoice itself, so I could write something along the lines of that. I think that reads better. Okay, so let's go into Invoice. And again, at the bottom is fine. When we call a send method, that will simply defer to the job. And let's see, we're going to send the current Invoice, and we need a User, or again, that's something that could be, that could default to the authenticated User.

And let's see, we're going to send the current Invoice, and we need a User, or again, that's something that could be, that could default to the authenticated User. So we'd have something like that. But yeah, it's just a slight tweak to how we organize things, but I do like that I'm able to call invoice->send(). And when we call that method, it simply defers to the job. Cool. Okay, in the next episode, let's finish up by writing some tests.

Refactor ClassMethod Affordances

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