WEBVTT

00:00.800 --> 00:06.830
Okay, so last time I've mentioned that the remember token needs to be rotated.

00:06.920 --> 00:19.910
And this just means that once we use such token, we should replace the token value and extend the expiry

00:19.940 --> 00:20.630
date.

00:21.980 --> 00:30.110
Now those tokens that we set for let's say 30 days, they are fine to use.

00:30.110 --> 00:40.250
But the problem is that if they end up in the wrong hands and anyone will just get access to the value

00:40.250 --> 00:49.640
of this token, it would be super easy for a person that gets his hands on the token to just use it

00:49.640 --> 00:56.870
to take over an account, and that's the reason we should be replacing the value of the token every

00:56.870 --> 00:58.310
single time we use it.

00:58.310 --> 01:01.130
Just for the security purposes.

01:02.370 --> 01:06.810
So let me start here by adding a method.

01:06.990 --> 01:13.440
This time it would be a method that is on the object instance, not a static one.

01:14.520 --> 01:24.870
And it's to be used when we have a loaded token can be just called rotate and it can return itself,

01:24.870 --> 01:28.200
meaning this remember token instance.

01:32.430 --> 01:34.590
That's why we use this keyword.

01:34.590 --> 01:37.800
And we'd like to replace the token.

01:38.490 --> 01:41.100
So we're gonna generate a new one.

01:42.900 --> 01:47.610
Then we also would like to get the new expiry date.

01:47.610 --> 01:50.760
That's why we'll also generate a new one.

01:53.520 --> 01:57.450
And we return this.

01:58.380 --> 01:58.650
Okay.

01:58.680 --> 02:00.390
So we can do that.

02:00.390 --> 02:09.380
We can change the value of the fields But it doesn't mean that this data will be stored in the database.

02:09.830 --> 02:19.010
So currently we represent the records from the database through instance of classes like this.

02:19.010 --> 02:21.890
Remember token object.

02:22.100 --> 02:28.280
But there is no way for us really to save changes easily.

02:28.700 --> 02:34.700
We've got a create method that is static, but it requires the input to be an array.

02:35.090 --> 02:45.770
And this means that we should really add the model method that can get all the fields from the model,

02:45.770 --> 02:54.290
which we have to define anyway, and just try and perform a database query.

02:54.290 --> 02:59.600
And I'd like it to be able to do two things.

02:59.600 --> 03:09.390
One, if the ID column has a value, then it needs to perform an update just updating the values of

03:09.390 --> 03:11.130
other columns.

03:11.490 --> 03:24.150
But if the ID is not specified, this means that certain entity model wasn't saved yet doesn't have

03:24.150 --> 03:25.680
a record in the database.

03:25.680 --> 03:34.920
Then we need to perform an insert and models should just have a save method.

03:34.920 --> 03:41.970
That's something also present in Laravel, where you can just save a class and it will know whether

03:41.970 --> 03:45.720
it needs to insert or update a record.

03:45.930 --> 03:51.960
So this method does not exist, which means we need to jump to the model and implement one.

03:51.960 --> 03:54.540
And this is what we're gonna do right now.

03:54.780 --> 03:59.130
So this is public function.

03:59.130 --> 04:00.360
Save.

04:04.710 --> 04:08.090
And it might return the current model.

04:09.860 --> 04:11.420
So here's what we can do.

04:11.450 --> 04:18.260
The first is to get the database object using the application container.

04:19.160 --> 04:29.510
And another step is to get the values of this current object fields, which can be done using get object

04:29.510 --> 04:30.380
vars.

04:30.560 --> 04:38.840
A little handy function that when you pass an object to it, it will give you all the fields of that

04:38.870 --> 04:45.590
object and also the field values, and it will return an array.

04:47.480 --> 04:52.490
So it returns an associative array with all the defined object.

04:52.520 --> 04:55.760
Non-static properties exactly what we need.

04:55.790 --> 05:01.310
We only need the instance properties, not static ones.

05:01.430 --> 05:14.490
And by having this, we can now check if the id is set on this model because if it's not, it means

05:14.490 --> 05:19.440
this database record doesn't exist in the database.

05:19.590 --> 05:29.670
So our first step in this case would be to remove the value of id, which would be null anyway.

05:29.670 --> 05:36.210
And we can just return the call to static create passing the data.

05:36.240 --> 05:43.980
So as a quick reminder this create is a method a static method in the model which from the given associative

05:43.980 --> 05:47.340
array constructs an insert query.

05:52.200 --> 05:54.750
And then we just have an alternative.

05:54.750 --> 06:01.500
So if the ID is actually set then we need to perform an update.

06:03.780 --> 06:10.480
So in this case we also would have to remove the ID from the data.

06:12.970 --> 06:16.270
Then we need to construct the SQL.

06:17.530 --> 06:20.620
So we've already used the update statement.

06:21.490 --> 06:29.410
So we write update followed by the table name which we're going to read from this static property.

06:29.650 --> 06:33.340
This is followed by the set keyword.

06:34.630 --> 06:40.930
Then we need to say which columns we update and with what values.

06:43.540 --> 06:46.930
So let me assume this would be somewhere over here.

06:46.930 --> 06:54.610
But then eventually since we are updating one specific record, we need to make sure we add an if statement.

06:54.610 --> 06:56.710
So the where statement.

06:56.710 --> 07:00.850
And we pass the ID of the model that we want to update.

07:04.210 --> 07:13.020
Then we need to grab all the values that should be updated because we are making a prepared statement.

07:13.020 --> 07:16.590
So we use array values from the data.

07:23.040 --> 07:25.650
And the last parameter is this one.

07:25.650 --> 07:28.560
That's the last question mark in the query.

07:29.580 --> 07:37.830
That's why to the parameter we need to append the value of this class this object id.

07:42.870 --> 07:51.600
And now we can run the database query using this SQL and the values.

07:51.600 --> 07:55.170
And we just return this object.

07:55.740 --> 07:59.880
So the thing missing is constructing this part.

07:59.910 --> 08:02.580
What to update and how.

08:03.210 --> 08:06.060
Let me call this set parts.

08:09.270 --> 08:12.910
And let's use array Map.

08:14.800 --> 08:18.190
So we're going to go over the keys from the data.

08:18.220 --> 08:22.270
That's why I'm getting the array keys from the data.

08:22.300 --> 08:28.570
Basically we're going to get all the column names except ID which we have just removed.

08:29.740 --> 08:30.520
Okay.

08:30.940 --> 08:35.860
And next up let me add an arrow function.

08:38.830 --> 08:49.810
So with every key or rather column I'm going to construct an SQL part where I'm going to do column equals

08:49.810 --> 08:56.530
question mark which basically stands for prepared statement parameter.

08:56.770 --> 09:03.340
Now remember that those prepared statement parameters when you use question marks you just pass them

09:03.340 --> 09:04.120
in order.

09:04.120 --> 09:09.160
And this is also why we had to add the id as the last parameter.

09:09.160 --> 09:12.160
Because values is essentially the parameters.

09:12.160 --> 09:13.990
I might even call this params.

09:13.990 --> 09:19.350
So maybe this would be a little bit more understandable.

09:20.790 --> 09:25.470
And this place here is where we should add the set parts.

09:25.470 --> 09:28.740
So set parts is an array.

09:30.690 --> 09:33.630
And this is why we should convert it to a string.

09:33.630 --> 09:38.700
We can do that using PHP implode where the separator is a comma.

09:39.060 --> 09:42.300
And here we pass the set parts.

09:42.720 --> 09:48.810
Maybe I can reformat this so it would be more readable.

09:48.810 --> 09:53.400
What are the specific parts of the query that we are using.

09:53.400 --> 10:05.550
So we are updating a table using set here we've got those columns equals a placeholder for parameter.

10:06.960 --> 10:07.920
We implode.

10:07.920 --> 10:11.160
So we generate a string from an array.

10:11.520 --> 10:19.600
And last we've got this where statement to just make sure we just update this single model, not anything

10:19.600 --> 10:20.470
else.

10:22.000 --> 10:24.910
Okay, let me move that to multiple lines.

10:25.840 --> 10:31.960
So the editor does not like that we use a property that is undefined.

10:31.990 --> 10:38.650
Now I think we can assume that we will always going to have the ID property on the model.

10:38.680 --> 10:42.130
This is basically the assumption that we create.

10:42.160 --> 10:49.270
So that's something that we force that every database needs an ID column.

10:49.900 --> 10:51.280
By the way this is not used.

10:51.280 --> 10:53.350
So this can be made configurable.

10:53.380 --> 10:57.730
But we try to keep things simple and manageable.

10:57.760 --> 11:00.760
That's why we had to make some assumptions.

11:01.420 --> 11:07.030
So by adding this field it no longer complains that it is undefined.

11:07.420 --> 11:09.610
So I hope this is understandable.

11:09.640 --> 11:11.650
It might go through this again.

11:11.650 --> 11:13.450
So we get the database.

11:13.450 --> 11:20.910
We get the values and names of all the fields on an object, all the public properties that are non-static,

11:20.910 --> 11:24.750
which is what we want because those are columns on our model.

11:25.680 --> 11:27.030
ID is not set.

11:27.060 --> 11:30.750
This means we can just use create and insert a new record.

11:31.230 --> 11:36.300
Otherwise, we need to construct an SQL query that will perform an update.

11:36.330 --> 11:44.940
We collect the prepared statement parameters because we never want to just run raw SQL without the prepared

11:44.940 --> 11:45.720
statements.

11:45.750 --> 11:54.810
Not to be vulnerable to SQL injection, we add the ID as the last parameter because we know it is the

11:54.810 --> 11:55.620
last parameter.

11:55.650 --> 11:59.790
Here we run it and we just return the object itself.

12:00.390 --> 12:01.110
Do this.

12:01.140 --> 12:10.140
Now if we jump back to our remember token, we just can be sure that this token rotation will just work.

12:10.410 --> 12:18.690
Save will always, in our case, perform an update because we only rotate a token that has an ID.
