Planning comment spam management0:00
Okay, let's work on spam management, but for Comments. So we already have this for Ideas. If you don't remember, we can mark an Idea as spam. We can mark it as not spam as an admin. So this will reset the spam counter. And we also have this filter here on the main page, which allows us to show spam Ideas. So right now there's none. But if there was, it would show here and we can go into it and act accordingly and delete it if we need to. So let's do the same for Comments.
it if we need to. So let's do the same for Comments. So let me just remove this and go into one of these. And let's go ahead and start. So I'm going to move quickly here because it's pretty much the same as adding Ideas, which we've already done. So we'll do markAsSpam together. And then I might skip over the notSpam part. So first thing I'm going to do is add a column on the database like we did for ideas. So let's check our ideas here.
Adding spamReports column0:56
So first thing I'm going to do is add a column on the database like we did for ideas. So let's check our ideas here. So create ideas table. We have this spamReports field. So let's add that to our comments. Create comments table. Let's add it here. And let's go ahead and php artisan migrate:fresh --seed again. Sorry, I'm not in the folder. php artisan migrate --seed.
Building mark-as-spam UI1:41
Let's go into this one and let's add the menu item here. Actually it's here already, but we have to make it work like deleting comments. So let's do that. That would be an Idea Comment. So let's duplicate this one. Can delete comment. And let's get rid of this one, or we can grab this. Okay. And we don't need auth on this because anyone who's logged in can do this action. And we already have the auth directive on the entire div.
And we don't need auth on this because anyone who's logged in can do this action. And we already have the auth directive on the entire div. Okay. So we have to do the same trick we did for editing and deleting Ideas where we have to set the comment and that will set the comment based on whatever the user clicks here or whichever one they want to mark as spam. So let's name it setMarkAsSpamComment. Okay. And let's go ahead and make that Livewire component. So php artisan make:livewire mark-comment-as-spam.
And let's go ahead and make that Livewire component. So php artisan livewire:make MarkCommentAsSpam. Okay. So let's open that up. MarkCommentAsSpam, and this will be pretty much the same as deleteIdea or editIdea or comment. I mean, so let's grab this paste. And let's change these here. So markAsSpam comment was set. Comment was marked as spam.
So mark as spam comment was set. Comment was marked as spam. Let's say mark comment as spam. Okay. Are you sure you want to mark this comment as spam? And that should be fine. Don't need this sentence. Mark as spam for the button and mark as spam for the Livewire action. Okay. Now let's go into the Livewire class.
Implementing mark-as-spam logic4:07
Okay. Now let's go into the Livewire class. So mark Comment as spam, and I'm just going to grab some stuff from the deleteIdea or sorry, deleteComment. Keep saying idea. So let's grab all this. Okay. Let's go back here, paste that in. Let's import Comment. Okay.
Let's import Comment. Okay. Let's change this to setMarkAsSpamComment. Change this one to markAsSpamComment. Okay. And we still need to set it here. Let's say markAsSpamComment was set, and this method should be called markAsSpam. Okay. So for auth, we only need to make sure that the User is logged in so we can get rid of this.
So for auth, we only need to make sure that the User is logged in so we can get rid of this. Let's import response. And all we're doing is incrementing the column on the database. So we have our comment, this comment, we have that new field spamReports, and it's incremented. Okay. And we have to save that comment. So this comment save. Let's emit this event. Comment was marked as spam.
Let's emit this event. Comment was marked as spam. Comment was marked as spam. Okay. So let's grab this event and we have to add it in our success notification. Okay. Let's duplicate this. So Comment was marked as spam. And we also have to update our comment. So Idea comment.
And we also have to update our Comment. So Idea Comment. Actually we'll do that later. Let's just see if it works for now. And I think I forgot to render it. So in our Idea model or models container, I mean, you have to add it here. So let's just duplicate this one and render the mark as or mark Comment as spam. Okay. So let's try that out. Let's mark this one as spam.
So let's try that out. Let's mark this one as spam. Okay. Model comes up, everything looks correct. And let's go ahead and mark it as spam. The success notification comes up. But we still want to show the number of spam comments in here. If we are an admin, actually, first, let's check if that worked. So let's go into our database. We are in our comments and let's see if any of them are 1.
So if you don't remember, we have this that shows only when you're an admin. Okay, so let's do that. Let's grab it from our Idea show. Let's look for spam here. And there it is. So we have to be an admin and there has to be at least one spam report. So let's grab that. Let's go to our Idea Comment and look for the body and we can paste that in here. Okay. So that should render now.
So right now it doesn't. So at this point, it should be three. And if I do refresh, it will update, but I want it to update automatically. So let's do that. Let's go into our Idea Comment and sorry, the class. And let's add that event. Let's say, what was it called? Comment was marked as spam. So let's grab this, duplicate this, paste this, and we are refreshing the Comment and this should work.
Adding spam comments filter9:12
The only difference is only the admin can do that functionality. So I'll be back when it's done. Okay. I've gone ahead and added markAsNotSpam. So if I click this, we can reset the spamCounter as an admin and I am logged in as my admin account. So the next thing I did was I added this filter, like I said earlier, so we have this spamIdeas filter and it filters the ideas by if they have spam or not, and then we can go into it and delete it if we need to. So let's do something similar for comments, but it's a bit different because this lists
go into it and delete it if we need to. So let's do something similar for Comments, but it's a bit different because this lists out Ideas, but we want to show Ideas that have at least one spam Comment in them. So we can make use of Laravel's has method. So we can query relationship existence. The example they have here is get all the Posts. If there are at least one Comment, and this is similar to what we want, but we want a condition on it. So for this, we can make use of the whereHas method. So for us, it's going to be Idea whereHas comments and the spam report has to be at
So for this, we can make use of the whereHas method. So for us, it's going to be Idea whereHas comments and the spamReport has to be at least zero or at least one. I mean, so let's go ahead and do that. So let's add that new filter. It's called ideas or it's within ideas.index, I believe, or let's add it in the view first. So ideas.index. And we have this one for spam ideas. Let's add a new one called spamComments. And now it's going to ideas.index the class.
Let's add a new one called spamComments. And now it's going to ideas.index the class. Let's add that new one underneath spamIdeas. So here, let's copy this, paste it in and say spamComments. And like I said, we can make use of the whereHas method. So Post or sorry, Idea whereHas comments and we have this callback. So let's do that. So query whereHas comments and the second parameter is a callback. So it's a function query and we can do something like this. Say query whereSpamReports is greater than zero.
So it's a function query and we can do something like this. Say query where spamReports is greater than zero. OK, so hopefully this works. So let's give that a try. Actually, let's add some spamReports first. So let's go back to noFilter. It's going to a few of these and add some comments with spam. So let's mark a few as spam here. So that's one Idea. Let's go for this one as well.
So that's one Idea. Let's go for this one as well. Doesn't matter which Comment. And let's do one more. So there should be three here. Or three Ideas with at least one Comment that has been marked as spam. OK, so let's try this out. Let's go to that new filterSpamComments. And we do have three, so it is working. So if I were to reset the spam counter on those Comments,
Writing tests for features14:05
So it will only disappear if there are no comments that are marked as spam. Back here and it's empty. Cool. OK, for tests, I'm going to do that behind the scenes as well as it's pretty much the same as what we have for the Ideas. So we have, I don't know what I named it, markIdeaAsSpam. Do I have a test for that? I named it SpamManagementTest and it has tests for both marking the idea as spam and not spam. So like I said, it's pretty much the same thing, but for comments.
the idea as spam and not spam. So like I said, it's pretty much the same thing, but for comments. So I'm not going to make you watch me do that, but I will do it behind the scenes and the code will be available. Actually, we have a FiltersTest for the filters as well. So we have this other FiltersTest so we can make a test for that new filter. And I already have it in my clipboard. Let's name it SpamCommentsTest. Let me just paste in the test. So we have a User.
Let me just paste in the test. So we have a User. We have three Ideas. OK. And what's going on here? Idea or Comment one and Comment two have spam reports. And we are going to that ideas index component. We are filtering by that new filter. I think that name is wrong. It's spam comments.
I think that name is wrong. It's spam comments. So let's change that. And we're just asserting that there are two ideas with at least one spam comment. So that's because commentOne belongs to ideaOne and commentTwo belongs to ideaTwo. And they both have spamReports. So that should be two. So if you run this test. It does pass. Cool.
It does pass. Cool. So I'll add the tests for marking as spam and not spam behind the scenes. And I will be back when it's done. OK. So I've added the commentsSpamManagementTest, which you can take a look at. But like I said, it's pretty much the same as the test for marking Ideas as spam. So again, this will be available in the source code. Let's run this entire file. And everything is passing.
Fixing UI and delete bugs16:32
Let's run this entire file. And everything is passing. Cool. Before we finish up this video, I want to make a few changes that I missed in the previous videos. So the first one is editComment. I believe there's a placeholder in here, which should be for comments. Or comment. So that would be in here. So let's go to my ideas.
So that would be in here. So let's go to my ideas. Or this is not to be my idea. It has to be my comment. Sorry. So let's make a new comment. And I forgot to add the placeholder. So now it's in there. And if I remove this, there should be a placeholder. Cool.
And if I remove this, there should be a placeholder. Cool. I want to make that a bit longer. Let's see. Let's say type your comment here. Okay. Next is in our model confirm. Here we're checking if there's a Livewire component or if it's an Alpine component. And I should have just used the other one here, event to open model. So it's going to be either or.
And I should have just used the other one here, event to open model. So it's going to be either or. So let's just use the variable instead. So if it's this, it's an Alpine component we're listening for. But if not, it's a Livewire event we're listening for. And let's make sure that still works. So this one is Alpine. Okay. So it still works. And the last thing is a bug on deleting comments here.
So it still works. And the last thing is a bug on deleting Comments here. So let me show it to you. So let's make two Comments without refreshing the page. So one Comment here. There it is. Let's make another one second Comment. Okay. And if we delete one of the Comments, let's go ahead and do that. This will work.
And if we delete one of the Comments, let's go ahead and do that. This will work. But if I try deleting another Comment before refreshing the page, this will not work. There we go. We get this 404. So what we have to do is go to delete comment here. So the problem has to do with this variable here. So at this point, we are deleting the Comment, but it still exists on this instance over here. So all we want to do is set it to null, and that should fix the problem.
Not sure why that happens. So I'm going to make another Comment because we have to delete two. Say third Comment. Okay. So we have two Comments here. Let me hard refresh again. And let's delete this one first. Should work. Okay. So we have this error because I type hinted the Comment.
Okay. So we have this error because I type hinted the Comment. So we have to remove that because we want it to be null at some points. Okay. Actually, I think if we add a ? here, this should allow null values if I'm not mistaken. So let's try that one more time. Let's add one more Comment. So we have to fourth Comment. Okay.
So we have to fourth comment. Okay. And let's try deleting them now without refreshing. Okay. Okay. So it does work. And let's try the second one here and hopefully this works too. And it looks like it does work now. Awesome. So we did fix that bug.
Awesome. So we did fix that bug. So that's it for this video. Let's go ahead and make a commit as always. This is episode 56, git add, git commit, episode 56, comment spam management.
