Okay, guys, let's build an actual feature.
Now, I know that we've been quite slow with building features.
We've been mostly focusing on building up the boilerplate, the backbone of our app.
It's time to change that.
So in the home controller, we're gonna build a feature that will display the recent blog posts sorted
by the creation date.
We've got all the building blocks.
First, let's get rid of this user creation.
We're gonna be rendering using the same template.
The data will be different here and what the data would be.
So I'd like to fetch some posts using the post model.
And I just want to get some recent blog posts so we don't have such method.
I'd like to get five blog posts, we need to create it.
So the concept of our models is similar to models in Laravel.
If you need some special methods, some special queries, then you create them yourself.
Otherwise, for basic stuff like getting all the records or one specific record, we've got ready methods.
Now we can also think about this and maybe create a common method, but it's up to us.
So we need get resent with the optional counter of how many of those that we want.
So let's jump to the post model.
So it will have all the methods that model offers and we can add more.
So let's add this static method.
That's get resent and it accepts a limit.
I'm going to make it mandatory.
So it's a little bit easier for us.
We are getting the database using APT get database.
Now we can help ourselves.
Okay maybe let me first make sure we've got a use statement.
We can help ourselves temporarily because the problem is we don't really get the method suggestions
as you see right here.
So we can optionally add a doc block here, which is just a PHP comment that starts with two asterisks
so that IDs can have some type hinting.
We need to add the var symbol and then come up with the namespace that's called database and the variable
name is db.
Then you might get some suggestions on the methods that you would like to use.
So we are just getting the access to the database from container.
And I'd like to run the fetch all method.
That's just a method of the database class.
And I need to come up with the SQL and with the parameters.
Let's just write SQL right here.
So we would need to select and we want to select everything.
And we want to select everything from posts table.
Or alternatively to make it more universal we might copy and paste at some place.
I might just use the current table name.
Then to order items I'm gonna use order by.
That's just an SQL statement to order by specific column.
And I want to order by Createdat in Descending order.
So newest first and since we have this limit parameter let's use it.
So I will limit how many records we're going to receive by adding this SQL limit keyword.
There goes the parameters or just one parameter.
I'm using the question mark, not a named parameters.
That would be just simpler for us.
And there I'm passing this limit integer.
And there it is.
So that's actually everything that we need.
Finally let's just return that.
Now that's a method of a database class.
And I'm not sure if we would not have to adjust that because for some reason I went with PDF fetch object
in this case.
So I think that we might just go and see what do we get back.
For now, let me just vardump the result of posts and die.
Then just make sure your development server is running at a specific address and let's see that.
So.
Mhm.
Okay so we've got the results that we get an array.
And every single record seems to be an object.
But this object is of the STD class.
Not really our model not what we expected.
So I think that we would prefer to have this as our own classes.
So every single record should be of type post, not of type STD class, which is the default type of
an object in PHP.
If you don't have a specific class, you know what?
Now, when I went back to the database.
PHP file I think we might be having to change some of those methods here.
For example, the fetch all.
Let's find all the references to it.
So that's the declaration.
And it's only used once.
That's the most recent method in the post model.
What about the fetch method from the database mind.
Not the model.
It's not even used even once.
And additionally, we are fetching them as objects here.
Maybe that's not ideal.
So I think we might simplify everything because additionally inside the model we've got this create
from array method.
And we might actually just go ahead and try to use fetch class and just specify the class we want to
be used.
Maybe we would be able to just remove this method altogether.
So let's try this.
I would go about that this way.
So let's get a nullable argument called class name that also is default to null.
And we're still going to get an array of classes.
And let's do the same with fetch.
We're also going to have a nullable class.
And the fetch can return well mixed value.
So let's go with mixed here as well.
And what we would do right now is first.
We would create a statement and Depending on whether the class name is specified or not, we would either.
That's a wrong name.
It's statement.
So statement.
So if the class name is defined we'd like to use fetch class and pass the actual class name.
If it is not defined.
Instead I'd like to do fetch all.
But this time let me just get an associative array.
That way we've got a method that's much more generic and can be used in different circumstances.
Let's do the same in this method.
So.
first let's create a statement.
Then based on whether the class name was provided we're going to go with statement.
Fetch class passing the class name.
And otherwise we're going to just default to fetching using the associative array.
That way I think those methods would be much more usable.
And by the way, we will greatly simplify the model class.
Okay.
Now quickly let's jump to model and we can burn this method.
And then for defined we just grab the database instead of doing query, we're just going to do fetch.
To which we pass the SQL, we pass the parameters and we pass the class name.
This would be static class.
So the class name can be figured out later on when this model class is extended and we can just remove
this line code gets simpler.
Let's just return this now.
In the case of all methods as well, we can just return that.
Get rid of this line.
We're going to call fetch.
All this line is gone.
Let's see if there are any parameters with fetch all.
So we optionally can have parameters.
So we pass an empty array.
And also we are passing the static class name.
We have simplified the model class.
Now let's jump to post where we can also use fetch all from the database.
And also we can pass the class name.
So I can do static class and I should get an array of objects of this specific post class.
So we had to do some changes and adjustments.
But that's actually a pretty normal thing.
When you develop the apps you figure out some things.
Maybe you forgot about something, or maybe you can just remove some code and make things simpler.
I really like to do that, and to be honest, that's good.
If you can remove some code, this means your app can be simpler.
So now we have a base method that we can easily reuse.
Now let's see what would be the output.
So we've got an error.
That's actually a notice.
But we don't distinguish between notices and errors.
And I think it's a good thing.
We shouldn't really ignore notices.
They often mean that something is really wrong.
So I've mentioned that you shouldn't be setting properties on classes dynamically.
It was deprecated since PHP 8.2 and this is where we can read here that creating of dynamic properties
is deprecated, and there are two ways around that.
One is to mark a specific class with an attribute.
So from the PHP docs usage of dynamic properties, it is deprecated to create dynamic properties, But
you can mark them with this special attribute and allow that it's only allowed to have dynamic properties
on STD class.
So this base type of all objects.
I think that the best thing we can do, or the thing that at least I would do, is just to define the
fields, the columns on every single model.
So we always know what do we have and what is available.
So I can do ID, user ID, the title, the content.
I think we also have the views and we should have created AD.
So the benefits of declaring all the columns is that we get the suggestions and type hinting every time
we use this post model.
I think that would be great.
Now this is our app and we seem to be getting an array of objects of our post class.
Maybe let me zoom in a little bit.
That's exactly what we expect.
Okay, so now let's jump back to the home controller and let me pass those posts.
To the view.
So we only got three in the database.
But maybe we can generate more later on.
And now we should modify the view.
So this home index well it's displaying some kind of a message.
Let's change this to just list the titles of those blog posts.
So this would be a quick one Let's say something like welcome to my blog.
Might zoom in a little bit, then we're gonna display the recent posts, and now we've got some template
code we do for each recent posts.
Or maybe I've just called this variable posts.
I think that was it.
So post as post.
Then we need to close for each by using and for each and inside it.
Maybe we can use article for every single one.
Let's add an h3 element.
I think this might be a link to the actual post in the future.
So in here we're just going to use HTML special chars, and we're going to grab the post title.
Okay.
And right below let's add a paragraph.
Let me copy paste that to be quicker.
And I'm just going to display a content.
But maybe not the whole content, just the part of it.
Let's use the substring function passing the content.
We're going to start at the first character and only get maybe first 150 characters.
So then we're going to add three dots, meaning that there is more content after we save the changes
and we jump to this page and I zoom out, it seems we've got everything displayed properly.
Looks really fine.
Okay, so the final thing I wanted to do is to change the style of this page.
Just the fonts to look like this a little nicer, like a newspaper.
So let's jump to the style CSS file and find this body definition.
I think it should be somewhere at the start.
There it is.
And let me add the font family.
And in VSCode I get a suggestion with such list and go with Cumbria.
I think some of those fonts should be available on your system as well.
Let me save the changes.
And there it is.
So those are the most recent posts on our website.
Now in the future, we're gonna have the paginated list of posts on this posts page and a lot more features.
But we are just starting.
I think we did great and the page looks perfect.
And by the way, we have really optimized some of the code we've created earlier, reusing things we've
done before.