WEBVTT

00:00.470 --> 00:06.500
Okay, guys, I think that next up we can implement this show action that should display one single

00:06.500 --> 00:07.640
blog post.

00:07.820 --> 00:14.810
So we've got the list of the recent blog posts already, and I think that we can create a link that

00:14.810 --> 00:18.230
will display one single blog post together with a comment.

00:18.260 --> 00:20.120
That should be pretty interesting.

00:20.120 --> 00:24.170
We've already got the controller, so let me list the steps.

00:24.170 --> 00:28.460
So we need to fetch the blog post.

00:28.490 --> 00:31.760
Now if it's non-existing.

00:32.150 --> 00:42.950
So for whatever reason the link is incorrect, then we would need to display a not found page and then

00:42.950 --> 00:49.160
we need to load any comments if there are any related to this blog post, obviously.

00:49.400 --> 00:55.100
Next up we should increment the view number.

00:55.610 --> 01:02.310
So we are counting the views of every single blog post and this would be pretty simple With every single

01:02.310 --> 01:05.880
visit, we just increment the counter by one.

01:05.880 --> 01:10.410
And finally we render the blog post with the comments.

01:12.270 --> 01:15.330
So the first part is pretty easy to do.

01:15.360 --> 01:23.640
We've got the post model which just has the find method, and we can just pass the ID and get the post.

01:24.030 --> 01:33.180
So the step number two if the post variable is falsy, which probably means it's just null and that

01:33.180 --> 01:41.940
means the post wasn't found, we should use the router class and just return a not found response.

01:41.970 --> 01:48.180
Now I'm not seeing a static not found method and I think we would need that.

01:48.360 --> 01:53.070
I don't see us creating the router instance just for that.

01:53.070 --> 01:56.430
Just to return a 404 response.

01:56.730 --> 01:59.280
Let's find the not found method.

01:59.280 --> 02:00.090
There it is.

02:00.090 --> 02:05.700
For some reason it's not static, so we need to create an object first.

02:06.060 --> 02:07.470
We can change that.

02:07.470 --> 02:10.710
However let's see what are the references to it.

02:10.710 --> 02:13.920
So it means where is it used.

02:15.030 --> 02:18.570
We can quickly see on the right in the results.

02:18.570 --> 02:22.980
It's just used inside this patch method.

02:24.600 --> 02:27.600
That means I can make it static.

02:27.930 --> 02:29.760
So I'm going to make it static.

02:29.760 --> 02:31.770
And in this place.

02:33.960 --> 02:36.870
I'm just going to do static not found.

02:38.550 --> 02:46.050
And by changing this I can now call this method inside my controller action.

02:46.080 --> 02:50.250
Now as you see this returns the not found text.

02:50.250 --> 02:54.600
So while we are here, why don't we just fix this?

02:54.750 --> 02:59.520
So instead I think we should just echo something else.

02:59.520 --> 03:08.410
I think we should use the view class instead and its static render method, and render one of the errors.

03:08.410 --> 03:09.880
This is 404.

03:09.910 --> 03:12.790
In this case, let's skip the layout.

03:12.820 --> 03:20.260
The exit should stay as we want to make sure that's the last thing that is run in this script.

03:20.620 --> 03:22.120
We don't have this view.

03:22.150 --> 03:23.530
Let's create it quickly.

03:23.530 --> 03:27.490
So inside the errors let's make 404 PHP.

03:29.380 --> 03:37.240
And this should just have a header that can say 404 page not found.

03:38.320 --> 03:47.410
We can also say the page you are looking for could not be found.

03:49.480 --> 03:53.770
And as a last thing, there should be some way to recover.

03:54.040 --> 04:03.910
That means I'm going to add a link to a home page that will say Return To home page.

04:04.720 --> 04:07.300
Okay, now let's go back to the router.

04:09.520 --> 04:11.440
And now to the post controller.

04:11.440 --> 04:13.000
We've got that solved.

04:13.180 --> 04:16.600
The next step is to load the comments.

04:16.780 --> 04:17.620
Okay.

04:19.090 --> 04:26.080
So we won't be loading all the comments and then filtering for this specific post ID.

04:26.260 --> 04:31.720
As all the comments have the post ID column, we could do that.

04:31.750 --> 04:34.180
That would be very ineffective though.

04:35.140 --> 04:42.610
We might have maybe thousands or even hundreds of thousands of comments in our system.

04:42.910 --> 04:50.470
And the most effective way to fetch the comments for this post is to do it on the query level.

04:50.680 --> 05:00.970
This means I will use the comment model, but instead we need another method we can call it for posts

05:01.300 --> 05:05.120
and just pass the post ID it's non-existing.

05:05.120 --> 05:06.470
We need to add it.

05:07.280 --> 05:11.780
Let's add it right away so it won't be very complicated.

05:11.840 --> 05:18.530
It's static code for post accepting an ID.

05:18.800 --> 05:21.410
Let's not worry about the types yet.

05:21.440 --> 05:23.690
We can figure this out later on.

05:23.840 --> 05:27.740
And it returns an array.

05:29.720 --> 05:31.400
Now we need to write a query.

05:31.400 --> 05:34.400
But first we need to get access to the database.

05:34.400 --> 05:38.690
So we use app get database.

05:39.890 --> 05:46.070
And recently we have modified the fetch all method of the database class.

05:46.640 --> 05:51.980
So it gives us some interesting possibilities out of the box.

05:52.010 --> 05:53.720
So let me write the query.

05:53.750 --> 05:55.160
We did that before.

05:55.160 --> 06:03.800
We fetch all columns from comments table, we add some filters using the where statement and we check

06:03.800 --> 06:06.950
if the post ID is the question mark.

06:06.950 --> 06:11.360
So we're going to be using the prepared statements.

06:11.360 --> 06:19.280
We also want to order those comments by createdat date using descending order.

06:19.610 --> 06:21.140
Nothing fancy here.

06:21.140 --> 06:26.930
We just want to have the comments that have the post ID set to our post.

06:27.230 --> 06:30.620
We are passing the parameters in the specific order.

06:30.620 --> 06:37.730
We've just got one single parameter here, and this third parameter of fetch all optional.

06:37.730 --> 06:41.000
One is which class should we use?

06:41.090 --> 06:45.710
Well, we should use the current class, which is the comment.

06:46.280 --> 06:48.740
And finally we just need to return that.

06:50.750 --> 06:52.280
Okay we can go back.

06:52.280 --> 06:55.940
And here we just got the comments.

06:56.270 --> 06:59.570
Next up we need to increment the view count.

07:00.980 --> 07:06.150
I think we can also add new methods to the post model.

07:06.510 --> 07:14.370
Let me call this increment views and we are just passing the model ID.

07:14.400 --> 07:17.190
So this method does not exist.

07:17.220 --> 07:18.060
We need to add it.

07:18.060 --> 07:23.280
So we are jumping to the post and we are adding it.

07:23.610 --> 07:27.540
So this is public static function.

07:27.540 --> 07:32.580
So a public static method called increment views.

07:32.790 --> 07:38.670
And it is accepting an ID and it doesn't return anything.

07:38.670 --> 07:43.050
Or optionally later on we might return the new value of the views.

07:43.650 --> 07:49.410
So first we are getting the database from the container.

07:50.070 --> 07:52.950
Then we are just running a query.

07:52.950 --> 07:54.690
So we are not fetching anything.

07:54.690 --> 07:56.640
Here we are running a query.

07:56.640 --> 07:59.760
This time it would be an update query.

07:59.760 --> 08:08.560
I don't think we've ever run an update query before, and the update query is supposed to change an

08:08.560 --> 08:11.530
existing record in a database table.

08:11.620 --> 08:21.430
So we would like to change the posts table record and the set keyword follows which basically says which

08:21.430 --> 08:23.200
columns should be modified.

08:23.230 --> 08:26.110
We'd like to modify the views column.

08:26.110 --> 08:27.970
How would we like to modify it.

08:28.000 --> 08:35.320
Well I'm going to assign a new value to it, which is the value of the views column plus one.

08:35.320 --> 08:38.350
We can do such things inside SQL.

08:38.380 --> 08:44.830
But the most important thing is to add a where query to say which records do we mean?

08:44.830 --> 08:52.210
Because if we don't add the where query, every single record inside posts will be updated with the

08:52.210 --> 08:53.740
new view count.

08:53.770 --> 08:55.870
Never skip this.

08:56.020 --> 08:58.300
And the ID is.

08:58.300 --> 09:06.580
The prepared statement parameter goes at the end of the query and we pass the value for that parameter,

09:06.580 --> 09:07.630
which is the id.

09:08.980 --> 09:11.020
So nothing is being returned from here.

09:11.020 --> 09:15.550
And this would just update one single post views.

09:16.630 --> 09:16.960
All right.

09:16.960 --> 09:18.760
So we've got this implemented.

09:18.760 --> 09:24.610
Finally we just return the view class render.

09:25.300 --> 09:25.810
Okay.

09:25.810 --> 09:30.730
So the template here is.

09:32.800 --> 09:39.550
The posts show same as the controller plus an action name.

09:39.580 --> 09:41.020
Action is the method.

09:41.050 --> 09:43.480
Then we've got the layout.

09:43.840 --> 09:51.400
This would be layouts forward slash main and the data.

09:52.330 --> 09:53.890
This is an array.

09:54.400 --> 09:57.670
And here we will be having two.

09:58.000 --> 10:02.560
So the post is our post and the comments.

10:03.460 --> 10:06.800
The comments variable semicolon.

10:06.800 --> 10:17.120
And we are almost done because what we are missing is the view for this post controller show action.

10:17.120 --> 10:19.040
So let's add a new folder.

10:19.070 --> 10:26.060
Let's add the post folder inside it, a missing show php file.

10:26.120 --> 10:29.870
And the final step is to just implement this template.

10:29.870 --> 10:37.550
So we might be moving pretty fast, but my goal is to show you how quickly we can move if we have solid

10:37.550 --> 10:40.910
foundations using our own framework.

10:40.910 --> 10:46.880
So let me add an article tag in here and start with H1.

10:49.640 --> 10:55.400
So let's use HTML special characters and get the post title.

10:58.760 --> 11:03.110
The next thing would be the views.

11:03.110 --> 11:07.610
So we've got the views And here we don't think.

11:07.610 --> 11:09.560
I don't think we need to escape anything.

11:09.560 --> 11:18.110
Let's just display the views and then let's add maybe another paragraph.

11:21.320 --> 11:31.370
And here I'd like to do HTML special chars for the post content.

11:32.570 --> 11:34.010
Let me close that.

11:34.100 --> 11:38.690
But additionally I'd like to wrap that with something else.

11:38.690 --> 11:47.150
So I'd like to use NL two BR, which would convert all the new lines that might have been entered using,

11:47.150 --> 11:53.300
for example, a text area input when someone has added the blog post.

11:53.300 --> 12:01.190
So those new lines would be then converted to BR elements, which would be nicely displayed as new lines.

12:01.220 --> 12:03.770
Okay, so that's the article.

12:03.770 --> 12:06.090
Now we need the comments.

12:08.070 --> 12:10.890
Let's just add a section for it.

12:11.070 --> 12:14.670
Let me add an H2 element.

12:14.790 --> 12:17.010
And let's say comments.

12:18.840 --> 12:20.760
We might have more than one comment.

12:20.760 --> 12:22.950
That's why I'm using for each.

12:22.950 --> 12:25.980
So we go over every comments.

12:28.230 --> 12:32.370
Then let me add a close and for each.

12:35.700 --> 12:41.310
And inside we are just displaying this specific comment.

12:44.640 --> 12:46.200
So a paragraph.

12:46.200 --> 12:54.870
And here I'd like to output using also NL to be our HTML special chars.

12:54.960 --> 12:59.730
And we are getting the comment I think it's called content.

13:01.710 --> 13:03.990
So that's the comment content.

13:04.510 --> 13:09.460
Then let's use the small element and just say when this was posted.

13:09.460 --> 13:11.380
So let's say posted on.

13:11.380 --> 13:16.120
And here I'm just using command created at.

13:18.850 --> 13:24.730
In the future we're going to have a link here to the sign in form, because you need to be logged in

13:24.760 --> 13:26.200
to leave a comment.

13:26.440 --> 13:31.810
And if the user would be authenticated already would be signed in.

13:31.840 --> 13:35.680
He would see a form to add his own comment to this post.

13:35.680 --> 13:42.520
I think we are ready to try out this page, but before we do on the home page we.

13:42.550 --> 13:49.030
We are listing the blog posts and I've mentioned that we might wrap this with a link, so let's do that.

13:50.410 --> 13:55.420
So this would be a link and the title would be the link.

14:00.010 --> 14:04.900
So first off this needs to be I think the root is post.

14:04.900 --> 14:06.160
Let's see that.

14:06.190 --> 14:07.600
Yes that's posts.

14:07.630 --> 14:09.880
Okay so this is posts.

14:09.880 --> 14:14.080
And here we need to output the post ID.

14:15.940 --> 14:18.310
Now we are ready to try this out.

14:18.970 --> 14:19.240
Okay.

14:19.240 --> 14:20.560
So we are on the main page.

14:20.560 --> 14:22.720
Let's see how does this work.

14:23.500 --> 14:23.920
Hmm.

14:23.950 --> 14:25.450
Something went wrong.

14:25.450 --> 14:28.420
So PDO statement fetch argument.

14:28.420 --> 14:31.750
Second must be of type int.

14:32.320 --> 14:35.500
Okay so let's jump to database.

14:36.820 --> 14:37.180
PHP.

14:37.180 --> 14:40.180
So the problem is with the fetch method.

14:40.180 --> 14:48.040
As we can see in the stacktrace that we are in the post controller, we are trying to find the model

14:48.040 --> 14:49.450
with id one.

14:51.190 --> 14:53.620
So this has to be post.

14:54.040 --> 15:00.250
And yeah I think I've just mistakenly used the wrong parameters.

15:00.250 --> 15:03.190
So fetch is a little different than fetch.

15:03.190 --> 15:10.070
All I forgot about this And I've assumed that the second argument would be the class name, and that's

15:10.070 --> 15:11.120
not the case.

15:11.450 --> 15:21.260
So I forgot about another method of the statement, which is set fetch mode, where we can well set

15:21.260 --> 15:25.220
the mode depending on whether the class name is passed or not.

15:26.720 --> 15:28.340
So we need to change that.

15:28.340 --> 15:35.900
So if the class name is specified the fetch mode needs to be fetch class.

15:35.900 --> 15:40.610
Otherwise it needs to be fetch associative array.

15:40.640 --> 15:47.840
Then the set fetch mode accepts a second argument which is defaulting to null, and that would be the

15:47.840 --> 15:48.710
class name.

15:48.710 --> 15:54.410
Since our parameter is also defaulting to null, we can just pass it.

15:54.440 --> 16:02.660
If someone would not like to have an object returned from this method, then he can skip this parameter.

16:02.660 --> 16:05.060
So let's leave it like this.

16:05.090 --> 16:08.420
And instead we can just.

16:09.560 --> 16:15.410
I think we can just go statement fetch because everything was already prepared.

16:15.440 --> 16:26.180
Oh, and it seems that I just need to add a semicolon here and instead just call this on the statement

16:26.210 --> 16:28.490
object like that.

16:29.390 --> 16:31.310
Okay, so we are setting the fetch mode.

16:31.310 --> 16:33.080
We are setting the class properly.

16:33.080 --> 16:36.110
We are fetching properly I guess.

16:37.940 --> 16:40.160
Let me refresh that again.

16:40.160 --> 16:46.520
We've got the same problem as with the post with creating dynamic properties that weren't defined.

16:47.450 --> 16:56.150
This means I need to jump to the comment and add all the fields that match the columns.

16:56.210 --> 17:07.320
So we've got Createdat, I think we've got the content and we probably got the post ID.

17:08.160 --> 17:10.410
Let me see if there is anything else.

17:10.410 --> 17:19.320
I just honestly don't remember the other columns, so there is user id and post ID additionally.

17:20.520 --> 17:22.680
Okay, so that's post ID.

17:22.980 --> 17:25.200
Let's also make it a user ID.

17:25.980 --> 17:27.600
So it's time to test.

17:27.600 --> 17:32.370
The first problem that I see here is apparently we don't have a template.

17:33.630 --> 17:34.500
Okay.

17:34.680 --> 17:38.310
Let's take a look at the post controller.

17:39.540 --> 17:41.430
All right I see what the problem is.

17:41.430 --> 17:48.540
So I've assumed that the folder would be called posts and it is post without the s.

17:49.410 --> 17:50.820
Let's quickly fix that.

17:50.820 --> 17:52.710
Not a big problem.

17:53.790 --> 17:54.120
Okay.

17:54.150 --> 17:59.850
Next up we've got some parse error inside the template line 19.

18:00.000 --> 18:02.010
Okay, let's take a look.

18:03.180 --> 18:04.380
Um, yes.

18:04.380 --> 18:04.830
Right.

18:04.830 --> 18:08.790
I probably should use the full BHP starting tag.

18:11.940 --> 18:13.200
Let's refresh.

18:13.230 --> 18:16.230
It's looking better, but.

18:16.350 --> 18:17.100
Hmm.

18:17.130 --> 18:25.800
Okay, we are attempting to read property content on an array on the template on line 14.

18:27.750 --> 18:29.340
The content is read here.

18:29.370 --> 18:30.810
Okay, this makes sense.

18:30.810 --> 18:32.820
I am accessing the array here.

18:32.820 --> 18:36.840
This should be just the comment variable, not comments.

18:37.050 --> 18:40.290
I think it might fix everything.

18:41.550 --> 18:45.360
Okay, so finally everything is looking good.

18:45.360 --> 18:47.460
We've got the content of the post.

18:47.460 --> 18:51.750
I can see that views are increasing every time I refresh.

18:51.750 --> 18:54.570
And then there are some comments.

18:54.780 --> 18:58.950
Let me take a look at another post.

18:58.980 --> 19:02.550
This also looks great and that one also looks great.

19:02.790 --> 19:07.620
Okay, so we are done and I think this wasn't very hard to do.
