Okay guys.
So finally, let's go back to having some fun and building features that we probably will be building
at work or in our personal projects.
So, uh, the next thing I'd like to add is the commenting features for the blog posts.
So we've been waiting for that and now we can safely implement this.
We need the CSF protection.
We also need the authentication system.
And in this video we're going to be implementing this commenting feature.
But only authenticated users will see the form.
Everyone else will see a link to go and sign in.
And also on the form handling code inside the new controller we're going to create, we're gonna check
the CSRF token.
And if the user is authenticated let's get to work okay guys.
So maybe let's begin with the form I think we can actually add the form directly inside the show view
that displays this post and the comments.
So what would what would you say about the form being added?
Maybe here right below this comments subheader but above the actual comments.
So we're gonna use an if statement.
Remember, we've got this magical user variable.
If it is available then someone is signed in, otherwise someone isn't.
So if there is no one sign in, we're gonna display a paragraph with a link to a login page saying login
to comment with a dot.
So it's not visible because I am signed in.
And the alternative is to add a form.
So let's come up with the URL.
So this can be.
Let it be posts.
And let's echo the post id.
And after that let's have comments.
So this would be our URL.
The method is obviously post, as we are sending a form that will change something in the back end server.
Here, let's echo the CSRF token which would render the whole field, and then let's have a text area.
The name is content and it's required.
And then we've got a button of type submit, which is the default anyway.
And we're going to say add comment.
So now when I refresh that it looks like this.
Okay.
So for some reason the text area is not being displayed.
Let's just see what's happening.
So we've got the form.
And it seems that I haven't properly closed the tag where we rendered the token the CSRF token.
Let's jump to this function.
And it seems to be the case.
There is no self-closing here.
So I had to add this self-closing of the element should be fine now.
Well, that's one huge text area.
I think we can set the number of columns using calls.
Let's set it to three.
Sorry, that's not columns.
This would be rows.
I meant rows, so I like shorter comments.
Let's put it this way.
So we've got the form.
Now we need the form handling.
So we need to create a controller, add a route for it and make sure we verify the user is signed in
and that the CSRF token is valid.
So the next sensible step after adding this form is to add a route.
Let me add it right here.
I'm going to add a route that uses the post method.
And it's posts the id parameter of a post, so we know to which post we should add it.
And then it was comments.
The controller is command controller.
Method name is store as we typically do when we store a new resource, like in case of logging in as
well.
Now we have to create this controller.
So let's jump to the controllers folder and create the command controller.
PHP like that.
And then we add the namespace.
This is app
controllers and the class is the command controller.
And for now it has only one action one method which is called store.
And it's going to have one parameter.
Let's call it post id.
Okay guys.
So a quick reminder here.
What needs to happen in this store method.
Can you guess that what we need to deal with when we have a form.
So the first thing is yes, the CSRF token validation.
So let's check for every of those steps separately.
First step is CSRF validation.
Make sure you add this use statement and call the verify class.
Sorry.
The verify method on CSRF class.
If this fails we should do router page expired again.
As I've said, we shouldn't be really doing this manually.
This should happen automatically.
We're gonna get to that later in some subsequent videos.
The next step if the token is fine obviously, and we are using defensive programming here, which should
also simplify the code and should simplify the basically the way to follow the code.
So it's much simpler to see that if something fails, we basically stop at this point, then just having
nested if else statements.
So the next step is to get the user.
So we are using another class called auth which has the user static method.
So if user is falsy which would be the case if the user would be null, then we've got the not found
page expired.
Well we are missing a method.
We should have another one that can be
unauthenticated.
Have I spelled this right?
An authenticated?
Okay, I think that this code is for a one.
So this means that some specific page specific resource needs you to be signed in.
So when I jump to the status codes on this same website, which is super cool, by the way, it's being
described as unauthorized.
Maybe let's use this name.
I wasn't really able to spell the unauthenticated anyway.
So let me just use unauthorized.
And it's exactly what we need.
It's an error that is typically thrown or returned.
However, you phrase that when we have not invalid credentials, so this sounds fine.
Yeah, I think it is fine when we are not authenticated because there is another code called 403 forbidden,
which just means that you are not allowed to perform an action, which means rather that your privileges
are insufficient.
And this is different.
This means that you are not authorized the entry in the first place.
Again, we would have to add a view which we don't have right now, which is 401 PHP.
As usual, let me quickly create that by using a method called copy pasting.
This is an okay, I'm gonna just copy that because this is a tough word for me to spell.
And let's say you are not authorized to do this.
And let's just direct people optionally to the login page.
Let's close this one.
Let's close that one.
And we are returning the right error and rendering the right view.
Okay let's go back to the controller.
So if there is no user we do unauthorized which basically stops the execution.
So nothing else to do here.
And next up we're going to get the content from the post.
And I think we've got everything.
So at this point we can use the comment model create method and pass some data into it.
So to connect it to the post we're just going to pass the post ID, which we have it because it's part
of the URL parameter and that's why we needed it.
It's super handy to just have the post ID at hand.
Next up we need the user ID.
Where do we get this from?
Well we have the user model.
So this is where we get it from.
And the content is the only thing that is actually sent through a form.
And after we start the comment we can just do a redirect.
So we do router redirect and let's construct the URL.
This is posts.
Then we're gonna use the post id.
And I'm not sure if we've got this ID comments.
Well, we're gonna see anyway.
Let's redirect someone to the post page first.
Then we're gonna see what can we do later on.
All right.
I think this looks fine.
And it's about time that we see if it works.
So let me refresh the page.
So we have the fresh CSRF token.
And let's say we are testing if this works or not.
Okay guys I think the issue is that inside the comment controller I should really use exactly the same
names as we have defined in the root.
I think that's the case.
So let's see.
Let me replace the post ID with just ID and let's refresh the form.
Seems that now it worked.
So I think you can see my comment right here.
So what can I say?
It worked perfectly and we were redirected to the right page.
All right.
Now let's also jump to this show page.
And if I will add the ID on this header like that.
Comments.
Then when the comment is added I can also redirect to the comments so that you can see your comment
as it was added instead of seeing the post first.
So we can just quickly verify that you were indeed successful and basically this functionality is completed.
We can add comments.