WEBVTT

00:00.650 --> 00:05.750
Okay guys, so let me outline the plan for the couple of next videos.

00:05.750 --> 00:11.240
So you know, what features are we going to build and why this would be useful to you.

00:12.050 --> 00:18.320
So my plan is to build, let me call that two features and add one concept.

00:18.350 --> 00:26.720
Let me start with the features as they actually revolve around SQL around writing database queries.

00:26.750 --> 00:29.060
The first is the search feature.

00:29.060 --> 00:34.580
So we are going to add a blog page with all the posts.

00:34.760 --> 00:41.810
And there I'd like us to be able to search by the title and content.

00:41.810 --> 00:50.510
So it might be interesting to see how this can be done, but then we will add another feature on this

00:50.510 --> 00:52.940
post page which is pagination.

00:53.390 --> 01:03.860
This is just dividing the data into chunks of five, 10 or 2 posts per page, which has some goals.

01:03.890 --> 01:11.750
Actually, it will optimize the data fetching so you don't have to fetch everything that you have inside

01:11.750 --> 01:14.150
the database, mind you.

01:14.690 --> 01:22.400
It's possible you're going to write a lot, and you might have a couple hundred posts that might not

01:22.400 --> 01:28.220
be the best choice to to having to always read them all every single time.

01:28.250 --> 01:31.940
And another reason for pagination is the recency.

01:32.600 --> 01:39.980
So I think we should assume that no one really cares about the posts we wrote five years ago.

01:40.970 --> 01:43.850
And the recency is very important.

01:44.000 --> 01:48.920
And the concept that I'd like to introduce is the view partials.

01:48.950 --> 01:56.480
Sometimes we might have some chunks of code that should not really be part of a specific template.

01:56.480 --> 01:58.610
Instead they should be reusable.

01:58.610 --> 02:04.160
In this case, the list of blog posts I think is such case.

02:04.160 --> 02:12.410
It is a good use case for view partials, because we might be displaying the same list of blog posts

02:12.410 --> 02:16.250
on the home page and then on the blog post page.

02:16.280 --> 02:20.510
Okay, so having explained, what are we gonna do next?

02:20.540 --> 02:26.570
Let's jump to the first of those features, which is the search functionality.

02:27.650 --> 02:29.480
So let's jump to the project.

02:29.480 --> 02:33.080
And the first step is inside the post controller.

02:33.080 --> 02:35.630
We don't have any logic at all.

02:36.170 --> 02:40.790
Now I'm gonna just copy paste what we have inside the home controller.

02:40.820 --> 02:44.810
This is just because it would be kind of similar.

02:44.810 --> 02:47.660
So it would give us a quick start.

02:48.140 --> 02:52.730
We just need to remember that we need to change the path to the view.

02:52.760 --> 02:55.190
That's post index.

02:56.450 --> 03:04.610
And inside the views folder we need to remember about creating the index page view which also would

03:04.610 --> 03:11.150
just get everything what we have inside the home index view, only to be modified later.

03:12.950 --> 03:16.970
So to see the difference, I'm just going to say all posts.

03:18.200 --> 03:24.740
So as you see, both pages display the same thing, but well at least we have something.

03:24.770 --> 03:34.850
So now on this post page we should start by adding a form for searching for specific content, right?

03:36.770 --> 03:39.920
Which means this view needs to get a little different.

03:39.920 --> 03:44.570
Before we display the posts, we should add a form.

03:46.580 --> 03:48.980
Now the form needs to have an action.

03:48.980 --> 03:53.240
I will leave this empty, which means just send to the current URL.

03:53.240 --> 03:55.910
If you would skip the action, it would do the same.

03:55.910 --> 03:57.560
And this is what we want.

03:57.590 --> 04:06.170
Also, we want to use the get action so that there will be a URL query parameters, not data sent through

04:06.170 --> 04:07.790
the Post request.

04:07.820 --> 04:13.250
We actually want the search query to be part of the URL.

04:14.540 --> 04:20.240
This will be important later on when we will introduce the pagination feature.

04:20.270 --> 04:28.670
So this input needs to be of type text and the name should be just search.

04:29.600 --> 04:35.210
We might have to provide the initial value but that's for later.

04:35.360 --> 04:43.250
And let's add a placeholder saying search posts like this.

04:43.250 --> 04:46.610
And then let me add a button.

04:46.610 --> 04:52.250
We don't have to specify the type because by default it would be a submit button.

04:52.250 --> 04:59.420
And now we've got another difference that on this post page you can actually search for something.

04:59.450 --> 05:04.670
If I hit search you can see that this parameter is added to the URL.

05:04.670 --> 05:08.450
If I type something like welcome.

05:10.130 --> 05:16.760
This is inside the URL, which is super important because this lets us share the search results with

05:16.760 --> 05:17.210
someone.

05:17.210 --> 05:23.840
I can now copy this and send the link to someone else, and he can also see the search results.

05:25.790 --> 05:27.140
So now we have the form.

05:27.140 --> 05:34.970
Next up, we need to implement the actual logic that will read the value of this search parameter and

05:35.000 --> 05:37.070
apply a specific query.

05:38.450 --> 05:47.210
So back in the post controller, the first thing we should get is the value of this search query parameter.

05:47.240 --> 05:50.240
We can just get it through the super global.

05:51.860 --> 05:55.730
If none was specified, we default to an empty string.

05:55.880 --> 06:05.600
And now let's pass it to the view so that if someone visits a page that had this search parameter in

06:05.630 --> 06:10.890
the URL, it would be populated in the input as well.

06:11.850 --> 06:18.330
Okay, now jump back to the view and let's fill out this value.

06:18.660 --> 06:22.740
So let's do HTML special chars search.

06:27.240 --> 06:29.160
Okay let's try that.

06:29.160 --> 06:31.560
So I'm gonna refresh this page.

06:31.560 --> 06:35.760
And it's not being populated after refreshing.

06:35.790 --> 06:36.450
Okay.

06:36.450 --> 06:38.130
So there was a typo.

06:38.760 --> 06:40.380
The parameter name is search.

06:40.410 --> 06:41.700
After refreshing.

06:41.820 --> 06:43.200
Well it's there.

06:44.430 --> 06:48.810
Okay so we have the search parameter but nothing is happening with it.

06:48.810 --> 06:55.020
That's why we need to jump to the get resent method of the model and make some changes.

06:55.050 --> 07:01.260
At least I think it is a good idea to modify this method instead of creating another one.

07:01.320 --> 07:08.820
So with the changes, I'd like to make this parameter nullable, which would mean it is optional.

07:08.850 --> 07:16.110
Now, this shouldn't be a problem with modern PHP because we can use the named parameters.

07:16.110 --> 07:20.700
And another new parameter here would be search.

07:20.760 --> 07:23.970
It would also be initialized with null.

07:24.000 --> 07:31.440
Now if you skip the limit, you can still search for something or the other way around.

07:32.400 --> 07:35.370
So now we have this simple query.

07:35.640 --> 07:39.540
It might get a little bit more complex.

07:41.730 --> 07:51.120
Okay so let me start by moving the query into a separate string because we might have to construct it

07:51.120 --> 07:52.260
conditionally.

07:53.430 --> 07:56.430
So we will always have this part.

07:57.840 --> 08:02.010
We are selecting everything from the table.

08:03.660 --> 08:06.540
Now let's also create the parameters array.

08:07.020 --> 08:09.450
And the first condition.

08:09.540 --> 08:18.300
So if the search is anything but null, then we need to append something to the query.

08:18.300 --> 08:24.900
So we use the shortcut concatenate equals which would just append to the query variable.

08:24.900 --> 08:27.000
And this something is.

08:27.030 --> 08:37.950
We need to add a word statement checking if the title is like the parameter or the content column is

08:37.950 --> 08:39.540
like the parameter.

08:39.690 --> 08:47.070
Now the like keyword in SQL is for searching for a text within some specific columns.

08:47.970 --> 08:50.790
It lets you use some simple patterns.

08:51.450 --> 08:53.430
Okay, so this is our query.

08:53.460 --> 08:58.950
Now we would have to add something to the parameters since it's empty.

08:58.980 --> 09:02.310
At this point we will just add something.

09:02.640 --> 09:09.090
So I'd like to add the value of search surrounded by Percents.

09:10.500 --> 09:17.670
This means that we expect that there might be something before the search query or after.

09:17.700 --> 09:20.160
That's why we had to add those percent signs.

09:20.160 --> 09:27.720
We don't want an exact match, and we just add it twice because we search both in the title and the

09:27.720 --> 09:28.560
content.

09:28.560 --> 09:35.580
That's why we supply two parameters and that's an equal sign.

09:35.610 --> 09:36.060
Okay.

09:36.060 --> 09:38.220
So we've got the search covered.

09:38.220 --> 09:44.730
And then we add something to the query always because this is ordering.

09:44.730 --> 09:47.880
So we do order by Createdat.

09:47.910 --> 09:50.640
This method is called get resent.

09:50.640 --> 09:56.850
So we always expect to sort using descending order.

09:56.850 --> 09:59.400
And then we check for the limit.

09:59.400 --> 10:11.400
So if the limit is different than null then to the query we add a limit with a parameter.

10:11.400 --> 10:15.150
So this would just limit the amount of results that we receive.

10:16.260 --> 10:19.980
And then we add something to the params.

10:21.450 --> 10:24.150
And that's just the limit.

10:24.480 --> 10:30.330
Now at this point we just pass the query.

10:30.330 --> 10:36.210
And we need to replace this array here with the params.

10:36.630 --> 10:42.690
So maybe we can simplify that and just put everything into one line.

10:43.710 --> 10:46.710
Should be readable and should fit the line.

10:47.100 --> 10:50.160
Okay, so the logic of the model is complete.

10:51.120 --> 10:52.770
Let's go back to the controller.

10:54.030 --> 10:54.270
Okay.

10:54.300 --> 10:59.430
So let's assume that we always want maximum five results.

11:00.480 --> 11:03.240
And here let me pass the search variable.

11:03.240 --> 11:06.270
And then let's see how does it work.

11:08.520 --> 11:08.820
Okay.

11:08.820 --> 11:11.070
So if we search for an empty string.

11:11.070 --> 11:17.010
All posts are displayed if I type welcome.

11:17.220 --> 11:25.110
We've got this post, and this also suggests that the search is not case sensitive because the title

11:25.110 --> 11:30.030
is uppercase and my query is lowercased.

11:30.120 --> 11:36.360
So there is no really a clear button, but if you want to clear the results, you can jump to posts.

11:36.360 --> 11:38.880
So I think this might be fine.

11:39.090 --> 11:41.490
Let me search for tips.

11:41.640 --> 11:42.210
Okay.

11:42.240 --> 11:43.800
One was found.

11:43.920 --> 11:48.660
Do we have anything that will contain the same word?

11:48.660 --> 11:50.010
Let me look for it.

11:50.070 --> 11:52.260
Maybe if I type we.

11:53.520 --> 11:56.040
Okay so we've got two results.

11:56.040 --> 11:58.920
So this confirms that this works fine.

11:58.920 --> 12:01.560
And also you can share this URL with anyone.

12:01.560 --> 12:08.760
And when they visit this page this will give them the same results as we did, which I think is pretty

12:08.760 --> 12:11.730
useful feature when talking about the search.
