WEBVTT

00:00.560 --> 00:04.190
Okay, guys, let's build an actual feature.

00:04.250 --> 00:08.480
Now, I know that we've been quite slow with building features.

00:08.480 --> 00:15.770
We've been mostly focusing on building up the boilerplate, the backbone of our app.

00:16.010 --> 00:17.450
It's time to change that.

00:17.450 --> 00:25.910
So in the home controller, we're gonna build a feature that will display the recent blog posts sorted

00:25.910 --> 00:28.130
by the creation date.

00:28.310 --> 00:30.590
We've got all the building blocks.

00:30.590 --> 00:34.070
First, let's get rid of this user creation.

00:34.070 --> 00:37.730
We're gonna be rendering using the same template.

00:37.970 --> 00:43.760
The data will be different here and what the data would be.

00:43.760 --> 00:48.800
So I'd like to fetch some posts using the post model.

00:48.800 --> 00:58.100
And I just want to get some recent blog posts so we don't have such method.

00:58.700 --> 01:03.230
I'd like to get five blog posts, we need to create it.

01:03.260 --> 01:08.660
So the concept of our models is similar to models in Laravel.

01:08.750 --> 01:16.580
If you need some special methods, some special queries, then you create them yourself.

01:16.790 --> 01:26.360
Otherwise, for basic stuff like getting all the records or one specific record, we've got ready methods.

01:27.080 --> 01:34.280
Now we can also think about this and maybe create a common method, but it's up to us.

01:35.180 --> 01:42.770
So we need get resent with the optional counter of how many of those that we want.

01:42.800 --> 01:45.230
So let's jump to the post model.

01:45.230 --> 01:53.420
So it will have all the methods that model offers and we can add more.

01:53.900 --> 01:56.870
So let's add this static method.

01:59.290 --> 02:03.070
That's get resent and it accepts a limit.

02:03.220 --> 02:04.930
I'm going to make it mandatory.

02:04.930 --> 02:08.290
So it's a little bit easier for us.

02:09.250 --> 02:14.470
We are getting the database using APT get database.

02:15.100 --> 02:17.440
Now we can help ourselves.

02:17.530 --> 02:21.430
Okay maybe let me first make sure we've got a use statement.

02:21.490 --> 02:29.470
We can help ourselves temporarily because the problem is we don't really get the method suggestions

02:29.500 --> 02:31.150
as you see right here.

02:31.660 --> 02:38.740
So we can optionally add a doc block here, which is just a PHP comment that starts with two asterisks

02:38.860 --> 02:42.850
so that IDs can have some type hinting.

02:43.960 --> 02:52.420
We need to add the var symbol and then come up with the namespace that's called database and the variable

02:52.450 --> 02:54.160
name is db.

02:54.520 --> 02:59.560
Then you might get some suggestions on the methods that you would like to use.

02:59.650 --> 03:04.630
So we are just getting the access to the database from container.

03:04.780 --> 03:08.980
And I'd like to run the fetch all method.

03:08.980 --> 03:12.760
That's just a method of the database class.

03:13.150 --> 03:18.490
And I need to come up with the SQL and with the parameters.

03:19.660 --> 03:22.540
Let's just write SQL right here.

03:23.440 --> 03:28.120
So we would need to select and we want to select everything.

03:28.120 --> 03:32.950
And we want to select everything from posts table.

03:33.010 --> 03:39.370
Or alternatively to make it more universal we might copy and paste at some place.

03:39.700 --> 03:43.300
I might just use the current table name.

03:43.300 --> 03:47.530
Then to order items I'm gonna use order by.

03:47.560 --> 03:52.210
That's just an SQL statement to order by specific column.

03:52.360 --> 03:57.270
And I want to order by Createdat in Descending order.

03:57.270 --> 04:02.400
So newest first and since we have this limit parameter let's use it.

04:02.400 --> 04:08.430
So I will limit how many records we're going to receive by adding this SQL limit keyword.

04:09.030 --> 04:12.960
There goes the parameters or just one parameter.

04:12.990 --> 04:16.500
I'm using the question mark, not a named parameters.

04:16.590 --> 04:18.870
That would be just simpler for us.

04:19.050 --> 04:22.380
And there I'm passing this limit integer.

04:23.460 --> 04:25.020
And there it is.

04:25.020 --> 04:29.460
So that's actually everything that we need.

04:31.020 --> 04:33.060
Finally let's just return that.

04:33.060 --> 04:37.020
Now that's a method of a database class.

04:37.020 --> 04:44.880
And I'm not sure if we would not have to adjust that because for some reason I went with PDF fetch object

04:44.880 --> 04:45.990
in this case.

04:46.590 --> 04:52.440
So I think that we might just go and see what do we get back.

04:52.920 --> 04:59.400
For now, let me just vardump the result of posts and die.

04:59.970 --> 05:07.440
Then just make sure your development server is running at a specific address and let's see that.

05:07.440 --> 05:08.340
So.

05:08.370 --> 05:09.000
Mhm.

05:09.030 --> 05:16.080
Okay so we've got the results that we get an array.

05:16.080 --> 05:21.450
And every single record seems to be an object.

05:21.660 --> 05:26.070
But this object is of the STD class.

05:26.070 --> 05:30.870
Not really our model not what we expected.

05:31.380 --> 05:38.760
So I think that we would prefer to have this as our own classes.

05:38.760 --> 05:47.790
So every single record should be of type post, not of type STD class, which is the default type of

05:47.790 --> 05:49.230
an object in PHP.

05:49.260 --> 05:54.480
If you don't have a specific class, you know what?

05:54.530 --> 05:57.080
Now, when I went back to the database.

05:57.260 --> 06:03.890
PHP file I think we might be having to change some of those methods here.

06:03.890 --> 06:05.960
For example, the fetch all.

06:05.960 --> 06:08.570
Let's find all the references to it.

06:09.200 --> 06:10.640
So that's the declaration.

06:10.640 --> 06:13.070
And it's only used once.

06:13.460 --> 06:16.910
That's the most recent method in the post model.

06:17.720 --> 06:21.080
What about the fetch method from the database mind.

06:21.110 --> 06:22.640
Not the model.

06:23.420 --> 06:26.120
It's not even used even once.

06:26.120 --> 06:30.650
And additionally, we are fetching them as objects here.

06:30.680 --> 06:33.050
Maybe that's not ideal.

06:33.560 --> 06:41.060
So I think we might simplify everything because additionally inside the model we've got this create

06:41.060 --> 06:42.500
from array method.

06:43.040 --> 06:51.470
And we might actually just go ahead and try to use fetch class and just specify the class we want to

06:51.500 --> 06:52.370
be used.

06:52.400 --> 06:57.200
Maybe we would be able to just remove this method altogether.

06:58.130 --> 06:59.480
So let's try this.

06:59.480 --> 07:01.850
I would go about that this way.

07:01.850 --> 07:11.660
So let's get a nullable argument called class name that also is default to null.

07:13.880 --> 07:18.110
And we're still going to get an array of classes.

07:20.000 --> 07:23.330
And let's do the same with fetch.

07:23.930 --> 07:26.660
We're also going to have a nullable class.

07:26.660 --> 07:33.260
And the fetch can return well mixed value.

07:33.260 --> 07:37.370
So let's go with mixed here as well.

07:39.380 --> 07:43.400
And what we would do right now is first.

07:46.850 --> 08:00.850
We would create a statement and Depending on whether the class name is specified or not, we would either.

08:02.860 --> 08:04.090
That's a wrong name.

08:04.090 --> 08:05.080
It's statement.

08:05.110 --> 08:06.790
So statement.

08:07.600 --> 08:17.410
So if the class name is defined we'd like to use fetch class and pass the actual class name.

08:18.880 --> 08:22.480
If it is not defined.

08:25.000 --> 08:28.300
Instead I'd like to do fetch all.

08:28.330 --> 08:34.840
But this time let me just get an associative array.

08:34.990 --> 08:43.030
That way we've got a method that's much more generic and can be used in different circumstances.

08:45.400 --> 08:50.050
Let's do the same in this method.

08:50.050 --> 08:51.100
So.

08:51.970 --> 08:54.820
first let's create a statement.

08:58.030 --> 09:06.670
Then based on whether the class name was provided we're going to go with statement.

09:10.750 --> 09:14.890
Fetch class passing the class name.

09:16.750 --> 09:25.450
And otherwise we're going to just default to fetching using the associative array.

09:26.290 --> 09:30.640
That way I think those methods would be much more usable.

09:30.640 --> 09:37.330
And by the way, we will greatly simplify the model class.

09:37.360 --> 09:37.870
Okay.

09:37.900 --> 09:43.030
Now quickly let's jump to model and we can burn this method.

09:44.170 --> 09:54.830
And then for defined we just grab the database instead of doing query, we're just going to do fetch.

09:59.090 --> 10:04.190
To which we pass the SQL, we pass the parameters and we pass the class name.

10:04.190 --> 10:07.730
This would be static class.

10:07.730 --> 10:16.760
So the class name can be figured out later on when this model class is extended and we can just remove

10:16.760 --> 10:19.100
this line code gets simpler.

10:20.450 --> 10:23.870
Let's just return this now.

10:23.870 --> 10:30.680
In the case of all methods as well, we can just return that.

10:30.710 --> 10:33.380
Get rid of this line.

10:35.030 --> 10:36.560
We're going to call fetch.

10:36.590 --> 10:39.770
All this line is gone.

10:40.610 --> 10:43.670
Let's see if there are any parameters with fetch all.

10:43.790 --> 10:46.190
So we optionally can have parameters.

10:46.190 --> 10:48.200
So we pass an empty array.

10:49.950 --> 10:55.350
And also we are passing the static class name.

10:57.030 --> 10:59.100
We have simplified the model class.

10:59.100 --> 11:06.420
Now let's jump to post where we can also use fetch all from the database.

11:06.420 --> 11:09.210
And also we can pass the class name.

11:09.210 --> 11:19.500
So I can do static class and I should get an array of objects of this specific post class.

11:19.590 --> 11:22.890
So we had to do some changes and adjustments.

11:22.890 --> 11:26.220
But that's actually a pretty normal thing.

11:26.370 --> 11:29.550
When you develop the apps you figure out some things.

11:29.550 --> 11:35.700
Maybe you forgot about something, or maybe you can just remove some code and make things simpler.

11:35.700 --> 11:39.690
I really like to do that, and to be honest, that's good.

11:39.690 --> 11:44.940
If you can remove some code, this means your app can be simpler.

11:45.150 --> 11:50.460
So now we have a base method that we can easily reuse.

11:50.490 --> 11:53.610
Now let's see what would be the output.

11:56.130 --> 11:58.350
So we've got an error.

11:58.650 --> 12:00.450
That's actually a notice.

12:00.450 --> 12:04.410
But we don't distinguish between notices and errors.

12:04.410 --> 12:06.630
And I think it's a good thing.

12:06.750 --> 12:08.850
We shouldn't really ignore notices.

12:08.850 --> 12:12.750
They often mean that something is really wrong.

12:12.780 --> 12:18.960
So I've mentioned that you shouldn't be setting properties on classes dynamically.

12:18.960 --> 12:27.780
It was deprecated since PHP 8.2 and this is where we can read here that creating of dynamic properties

12:27.810 --> 12:32.400
is deprecated, and there are two ways around that.

12:32.430 --> 12:36.480
One is to mark a specific class with an attribute.

12:37.560 --> 12:46.970
So from the PHP docs usage of dynamic properties, it is deprecated to create dynamic properties, But

12:46.970 --> 12:55.010
you can mark them with this special attribute and allow that it's only allowed to have dynamic properties

12:55.010 --> 12:56.570
on STD class.

12:56.570 --> 12:59.660
So this base type of all objects.

13:02.240 --> 13:09.620
I think that the best thing we can do, or the thing that at least I would do, is just to define the

13:09.620 --> 13:13.010
fields, the columns on every single model.

13:13.730 --> 13:17.630
So we always know what do we have and what is available.

13:17.630 --> 13:26.180
So I can do ID, user ID, the title, the content.

13:27.380 --> 13:34.730
I think we also have the views and we should have created AD.

13:34.970 --> 13:42.680
So the benefits of declaring all the columns is that we get the suggestions and type hinting every time

13:42.680 --> 13:44.390
we use this post model.

13:44.420 --> 13:46.310
I think that would be great.

13:47.690 --> 13:56.150
Now this is our app and we seem to be getting an array of objects of our post class.

13:56.150 --> 13:58.400
Maybe let me zoom in a little bit.

13:58.490 --> 14:01.850
That's exactly what we expect.

14:03.890 --> 14:14.810
Okay, so now let's jump back to the home controller and let me pass those posts.

14:16.880 --> 14:17.960
To the view.

14:18.860 --> 14:21.140
So we only got three in the database.

14:21.140 --> 14:24.170
But maybe we can generate more later on.

14:25.190 --> 14:29.000
And now we should modify the view.

14:29.000 --> 14:34.370
So this home index well it's displaying some kind of a message.

14:34.400 --> 14:41.150
Let's change this to just list the titles of those blog posts.

14:42.890 --> 14:50.140
So this would be a quick one Let's say something like welcome to my blog.

14:50.980 --> 15:01.570
Might zoom in a little bit, then we're gonna display the recent posts, and now we've got some template

15:01.570 --> 15:04.810
code we do for each recent posts.

15:04.810 --> 15:08.110
Or maybe I've just called this variable posts.

15:08.110 --> 15:09.880
I think that was it.

15:09.880 --> 15:11.920
So post as post.

15:12.070 --> 15:21.160
Then we need to close for each by using and for each and inside it.

15:21.160 --> 15:24.880
Maybe we can use article for every single one.

15:25.120 --> 15:27.700
Let's add an h3 element.

15:28.630 --> 15:32.710
I think this might be a link to the actual post in the future.

15:35.290 --> 15:46.450
So in here we're just going to use HTML special chars, and we're going to grab the post title.

15:48.310 --> 15:48.730
Okay.

15:48.730 --> 15:51.640
And right below let's add a paragraph.

15:51.670 --> 15:53.830
Let me copy paste that to be quicker.

15:53.830 --> 15:56.410
And I'm just going to display a content.

15:56.410 --> 16:00.280
But maybe not the whole content, just the part of it.

16:00.520 --> 16:05.590
Let's use the substring function passing the content.

16:05.590 --> 16:11.680
We're going to start at the first character and only get maybe first 150 characters.

16:11.860 --> 16:20.110
So then we're going to add three dots, meaning that there is more content after we save the changes

16:20.110 --> 16:28.270
and we jump to this page and I zoom out, it seems we've got everything displayed properly.

16:28.660 --> 16:30.100
Looks really fine.

16:30.340 --> 16:34.900
Okay, so the final thing I wanted to do is to change the style of this page.

16:34.900 --> 16:39.520
Just the fonts to look like this a little nicer, like a newspaper.

16:39.550 --> 16:46.890
So let's jump to the style CSS file and find this body definition.

16:47.970 --> 16:52.110
I think it should be somewhere at the start.

16:52.140 --> 16:53.070
There it is.

16:53.100 --> 16:56.340
And let me add the font family.

16:56.340 --> 17:03.720
And in VSCode I get a suggestion with such list and go with Cumbria.

17:05.520 --> 17:09.960
I think some of those fonts should be available on your system as well.

17:09.960 --> 17:11.670
Let me save the changes.

17:13.290 --> 17:14.220
And there it is.

17:14.220 --> 17:18.900
So those are the most recent posts on our website.

17:18.930 --> 17:27.060
Now in the future, we're gonna have the paginated list of posts on this posts page and a lot more features.

17:27.060 --> 17:28.950
But we are just starting.

17:28.950 --> 17:32.220
I think we did great and the page looks perfect.

17:32.220 --> 17:40.140
And by the way, we have really optimized some of the code we've created earlier, reusing things we've

17:40.140 --> 17:41.070
done before.
