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

Abandoned Cart Emails0:00

Now, something you often see with web shows as well is something called an abandoned card email. When your customer is on your store and it starts adding products to his or her cart, they might continue browsing, but never place an actual order. Now, to incentivize them to buy something, you often get a reminder after a day, for example, saying, like, hey, you left a few things in your cart. Are you sure you don't want to order them? This is actually a great way to ensure customers place an order to increase your revenue. So I thought it would be fun to build a feature like this as well. As you can see, I already have a cart, I already have an item here as well.

Scheduling Reminder Command0:39

So I thought it would be fun to build a feature like this as well. As you can see, I already have a card, I already have an item here as well. So the first thing we have to do is to make a scheduled job, which will run once a day, and we're going to check whether there is a card which has been updated one day ago, and we'll send them an email to this user to notify them. Okay, you still have some things in your card. Click here to place your order. So let's head over to our editor and let's clean this up a little bit. So the first thing is going to be creating a scheduled command. So run php artisan make:command AbandonedArt.

So the first thing is going to be creating a scheduled command. So run php artisan make:command, and we'll call it AbandonedArt. So now we can head over to our Console, to our Kernel, and here we can reference our new command. And we'll set it to run daily. And, like, it does make sense to send them an email at, like, the middle of the night. So we could, for example, email them at the start of the afternoon. So now we can go over to our command itself. Let's update the description. Look for abandoned cards and notify their owner.

Let's update the description. Look for abandoned cards and notify their owner. So now we can write a query. So we want to get all our cards that has a User attached, and we can say where date, we can say today, and remove one day. So we're going to create a Card that has a User attached to it. We're going to check if the updated_at column is equal to yesterday. In that case, it will match the query. And we want to email the User which is associated to that specific Card. So let's quickly verify that this command is working.

And we want to email the User which is associated to that specific card. So let's quickly verify that this command is working and that the query is correct by returning the count of the query. And currently it returns zero. Let's use php artisan tinker. Let's grab our first User and cart. That works. And we're going to update the cart. And we're going to change updated_at and set it to yesterday. There we go.

And we're going to change updated_at and set it to yesterday(). There we go. So now if we run the command again, we should get one, and it matches. So we have our cards. Now we can simply loop through each of them. And now we can send out the email. Now if we do cartUser, this is going to do another query because this only checks whether it has a user but it doesn't load the actual User object. So what we can do is with whereHas,

Creating Reminder Email3:13

but it doesn't load the actual User object. So what we can do is with whereHas, and this will make sure the cart has a User, and if the cart has a User, it will also load the user relationship. So this won't cause any additional queries. So let's create a new Mail. And let's call it AbandonedCartReminder. Now here we're going to use our Mail facade. We are going to send it to our cart User. And we're going to send our AbandonedCartReminder.

We are going to send it to our User. And we're going to send our Abandoned Cart Reminder. And we're going to pass our cart to the email. So we still have our preview route set up. So if we head over to our web.php routes file, now we can utilize this. So we'll leave the preview route here. We'll update this to our Abandoned Cart Reminder email. And let's grab the cart from our User. So now if we hit the preview route,

And let's grab the cart from our User. So now if we hit the preview route, we should get a blank page, or an error in this case because we haven't defined a view yet. So let's open up our AbandonedCartReminder. Let's use a similar approach before. Let's use Markdown. So we're going to return a blade file that contains Markdown. And by updating this from view to Markdown, we're also instructing Laravel to render Markdown instead.

And by updating this from view to Markdown, we're also instructing Laravel to render Markdown instead. So let's head back into our resources directory, views, emails. And let's create a new email. And let's call it AbandonedCartReminder. And let's make sure that we reference this here. Now I see I made a little typo here. So let's make sure that we update this class name. Let's add a new subject.

So let's make sure that we update this class name. Let's add a new subject. Let's add a subject like You still have items in your cart. Now we're going to update the constructor because this is going to be our cart. Let's make it a public property that way we can access it from our Blade file. Okay. Let's copy and paste our order confirmation email

Okay. Let's copy and paste our order confirmation email because this already has all the components. We can remove the table. And now we can say cart user name. You still have items in your cart. Click the button below to continue your checkout. And we'll update the button to set to continue checkout. We'll update the route.

And we'll update the button to set to continue checkout. We'll update the route to be set to the cart. Now let's also fix the typo that I made in the file name of our blade file. And there you go. We now get a nice email with our name and our message that we still have items in our cart. And if we click continue to checkout we get redirected to our cart.

And if we click continue to checkout we get redirected to our cart. Now that we are on the subject of our cart you may recall that we are creating a cart based on either the user ID or the session ID. So whenever someone visits the store and starts adding things to the cart but this user never logs in and leaves the website.

but this User never logs in and leaves the website the session disappears but there is still a cart in the database. So we want to ensure that we clean up our database to remove any carts that have a User associated with it anymore because it is session based and the session expires after a few hours when the User is no longer active on our store.

and the session expires after a few hours when the User is no longer active on our store. So let's open up a terminal and let's create a new command and we'll call it removeInactiveSessionCarts Oh, and one thing before I forget so we're sending out reminder emails based on the updated ad column on our cart. So if we switch to table plus

Updating Cart Timestamps6:44

on our cart. So if we switch to TablePlus you can see that we have one cart right here but if we add a new product to our cart and check the database you can see that the column wasn't updated so we need to make sure that whenever we add a new product to our cart the parent is updated.

add a new product to our cart the parent is updated. So how we can do this is by going to our editor and let's open the CartItem now we are going to add a protected property called touches which accepts an array and here we can simply reference our cart relationship which we still need to define.

our cart relationship which we still need to define so we'll say public function carts, this is going to return a belongsTo relationship and we'll reference our Cart model there we go so now when we add a new cart our timestamp should be updated so now it's at

our timestamp should be updated so now it's at 12.37 let's add a new product and it didn't change anything so this has to do because the touches property only works whenever the save method is used on Eloquent so if we head to our

is used on Eloquent so if we head to our product library component and head over to our addProductorIntoCart action we can update this to be item and now we'll move this piece of code here so we'll increment the quantity but we'll also instruct Eloquent

so we'll increment the quantity but we'll also instruct Eloquent to update the timestamps so now if we head back to our store and click add our product was added to our cart now if we switch to the table you can see that the timestamp was updated let's move on with cleaning up these session based carts

Cleaning Up Session Carts8:25

let's move on with cleaning up these session based carts so we created this removeInactiveSessionParts command so let's move over to our Console\Kernel and let's make this a scheduled command as well and let's run this weekly let's update the description of our command

let's update the description of our command and we'll say cart doesn't have a user and we want to fetch the cart where the date is minus one day so basically yesterday so let's wrap this in an info callback so we can run the command and see the output

so let's wrap this in an info callback so we can run the command and see the output of the count of carts that has been found so let's give this a try let's run the command and it returns four results let's take a look and yes we have four different sessions now let's see what happens if we set one of these carts

now let's see what happens if we set one of these carts to today, in this case the value should go down to three and that worked, ok so now for each of these carts we can loop through them and we're going to say cartItems->delete(), and finally we're going to delete the cart itself so if we run this command

delete, and finally we're going to delete the cart itself so if we run this command those three carts should be removed from our database and they have been removed

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