Authentication component with PHP | Sebastian Sulinski | Skillshare

Authentication component with PHP

Sebastian Sulinski

Play Speed
  • 0.5x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 2x
29 Lessons (7h 57m)
    • 1. Introduction

    • 2. Set up

    • 3. Session manager

    • 4. Session drivers

    • 5. Session component under test

    • 6. Kernel

    • 7. Application

    • 8. Controller

    • 9. Cookie component

    • 10. Cookie component under test

    • 11. Migration

    • 12. User class

    • 13. User under test (Part 1)

    • 14. User under test (Part 2)

    • 15. Guard class

    • 16. Guard under test

    • 17. Validator

    • 18. Validator rules

    • 19. Validator under test

    • 20. Abstract Controller

    • 21. Login Controller

    • 22. Register controller

    • 23. Mail component (Part 1)

    • 24. Mail component (Part 2)

    • 25. Smtp transport

    • 26. Account activation

    • 27. Forgot Password

    • 28. Reset password

    • 29. Refactoring


About This Class

During this course we'll learn how to build a simple framework with functionality to register new account, login, reset password and restrict access to sections of our website.


1. Introduction: welcome to this new serious where we learned how to kill the registration, logging forgot and reset password forms as well as restrict access based on whether the user is logged in or not. Our log inform. Apart from having the obvious email and password, Fields will also have a remember ME option to keep users logging until they log out or clear their cookies. The registration form will be programmed the way so that you can eat a. Send the activation email and keep account inactive until the link in email sent to the registrant has been clicked. Or allow registration without activation, where, after submitting the form user gets automatically logged into the system, we will cut it the way so that you'll be able to change it at any time by just changing the value off the configuration variable. The forgot password will work pretty much the same way it works with any other system where you provide a registered email address and on submission. Email with a link to the reset form is sent to that email address. After clicking the link in email, you are taken to the reset password form, which is where you can update your passwords before you start this course, you'll need the following local server environment any of the lamb stocks such as mom, Wamp, Zampa or homesteads. If you're not familiar with it, please check our course titled Setting Up Local Environment or Post A comment under this video, and I'll point you in the right direction are strongly recommend that you have a virtual host set up for this project to avoid any unnecessary problems. Again, all this is explained in a setting up local environment. Course your discourse. We will make use of a number off publicly available packages which were will install via composer. Therefore, if you don't have a composer installed, please refer to the course mentioned before now. I think it's a good time to move on to the next video where we start setting up our project . 2. Set up: so the first thing we need to do is to download the exercise. Fans and exercise farms are velvet get Hub did come forth slash ss the hyphen tutorials. And at the moment, the repository that we are interested in is the 1st 1 But obviously with the time that's gonna go lower down the least, so you can search for it by simply filtering the results at typing register hyphen log in and there we go. That's the only one now displayed on. At least if you click on this one and you can eat a four kid and then clone it to your local machine, all simply down or disease are fine. This is what I'm going to do. So if we click on download zip now, if you go back to our file browser and if we double click it to unzip the files that we go , one thing you will notice. If we scroll up here, we'll see that we don't see this dot e and video example in dot get ignored. If you're on Windows, you probably see these files. But on the marquee won't be able because all find, starting with a full stop on the mark are hidden fast. So if we open our terminal and I'm going to navigate to my downloads directory So tilled symbol and four slash downloads l s to see all the files and directories, and this is what we have there. So I'm going to navigate to this director, which you've just extract it. So seedy register logging and so on. Now l s here. We have accounts. It is invisible funds. But if I do l s hyphen A. And I'm going to also add l flag because I want them listen as a least. And there we go. You can see now we have this dot envied out example and dot gets ignored. Now, don't get ignore. You may not need, but I will keep it because I will be saving things Project to the repository after each video to keep track off the of all the changes a dot e n v dot example is the one that you definitely need. So we need to copy all this farce to our project route direction. And how are we going to do it? Let's quickly go back to I find her brows. Obviously, if you on Windows. You can pretty much drug everything across Teoh projects through directory because you will see that distort, envy, indulge, getting. And also you can obviously selling them as well and then drug them across on Mark obviously is going to be slightly different. So what we can do now is I need to navigate my projects through a directory. First of all, which is going to be called logging. As you can see at the moment is an empty It's an empty directory. And what I want to do is first of all, find out what the path to these directories. So I'm going to open a new time, no window, and I'll simply go back to the find there and rock this directory onto the terminal. And that tells me, did precise path to this director. Okay, so I copy this directory and then what I'm going to do is to move all these files over there. So I'm going to use the M v ah comment with star symbol this while character because I want to select all of the farm and then the path to where I want to send them. No. One thing that's going to happen when I'm going to heat return. It will copy nearly all of the files because by default, move dozen. Select the hidden fast. So don't envy example. Does it get? Ignore Won't be copies copies, in the sense that obviously is going to be moved is going to be cut and paste it into this new director. So I'm gonna hit return. And if we do now, l s a a l you'll see that the east to this hidden files are still here. So what I'm going to do now, it's strictly specified, and I want is not e n v and dot get signal. Toby also moved to this Daraji so envy, common again by distant, specifying exactly which funds after the space, I want to move to which directory destination Director. So he returned now. And if we do now, l s a l. You'll see the director is empty so we can go up one level. And if we do l as again there we go our director in a zipped falling see as well so we can remove them. Also R m r f our flock to make sure that it's remotely recursive Lee because obviously this is a direct treat. This is not just the funds and is to remove all the files from within the directors. Well, f because I don't want to be prompt asking whether I'm sure I want to do it. And then whites character after the space, actually. Rather, let's just start register logging and so on. And then white character. So it's only actually going to remove the fines that start with this long string, which is going to apply to only these two. If you have any other fires within this director, they won't be removed and he'd return. And now l s, as you can see, Directories empty. Okay, Now I'm going to navigate to the directory where my project They saw CD called in my case and then CD logging, which is the director. Ah, when im story keeping my project. And now if I do l s a l. You'll see that all of the farms are listed here. We have to start envy Example. Adult get ignores. Well is dealt. Idea is just bicycle because I'm using PHP storm. It generates this director on its own. Don't worry about is you probably won't see it if you use any other Ah, i d. And then obviously all the other funds that were within the repository. Now, if you are unsure about all this terminal interactions here now, what you could alternatively does copy oldest finds by dragging and dropping them into your projects through director and then just click on this, go back to this repository, click on this dot envy example creative fire with this name and then simply copy Waltz within this far, Just select everything and copy this a little. The content into this file Same for the getting. Know if you're going to use it. If you can ignore this file together, but we definitely need this. Don't envy. Don't example. Okay, so now I'm going to navigate back to my project and my project now has all these files, obviously, which we copied earlier. The first thing we need to do is to install all the dependencies which are stored within the composer dot Jason, let me just quickly explain what these dependencies are. The 1st 1 eliminate database is basically eloquent object relational mop, which which is a simple, active record implementation will allow us to easily interact with the data base rather than us right in the new database class and so on. We have everything else of the box. The next thing is the element support, which comes with a collection really nice way off, playing with the rays and so on. And then it also will provide some string, some methods which allow us to generate some random strings and song. Then we have the http package which allows us Teoh interact with the request getting whatever is being sent to the application when it's through, get post or anything else. This package will handle all this for us. Then we have this string converter string converter will allow us to convert between different string four months. Then we have dealt E NV, which allows us to register and interact with the environment variables, retrieving them, checking if they exist and so on. Then we have Blade package, which will allow us to render our views using blades template ng n jing And then we have Swift Mailer to process all our email distribution and then we have Nesbitt Carbon, which is basically going to allow us to play with dates former them in a specific way and so on. And then we have development dependencies. PHP. You needs to write some of the test that we're going to write for our application. So these are all our PHP dependencies. We cannot close the composer that Jason. We also have package the Jason, which stores allow a JavaScript dependencies and what I'm going to be using amusing, actually foundation sites for this project again, you can use any styling you want. I'm using gulp packages so I can actually. Prose is my satisfies because I'm using saucy Africa. Go to resources, then assets, SCS says director, and you'll see older fonts, which are I'm using here. If you want to modify anything, feel free and then just run. Gulp. We have a goal file ready as well, with all this farce included and so on. And then I'm using J Query and SS the form, which is a Jake. We're applauding for validating and submitting form using Ajax. So if we close this, but again, if you if you family awaits, let's save you are Angula GSO any? Are there any other Jake were applied in anything else that you prefer over what I'm going to be using here. Feel free. Obviously, that's not that important. When it comes to this course, the PHP side is what's actually going to be processing everything, and that's everything when it comes to all the dependencies. So let's quickly install our composer PHP dependencies first by going to the terminal and from within the root of our project pwd just to make sure that I mean inside of the root of my project. And I am this locking directory, he, as you can see, So what? I'm going to do this Ron composer in stone, and this will take a few seconds doing stole. There we go. Everything is done. Command K on my keyboard to clear the screen. And when I refreshed the project, you can see that the vendor directory has been added with all these dependencies and then composer look has also been generated. So our dependence is for the composer now installed. Let's now go back and install all our and PM dependencies and P M install, and this will take a little bit longer that will generate the note. Underscore Modules directory on the left. Inside, you'll see just the second, and all this has already installed as well. So I can clear the screen command K again, as again see note modules directories listed here. So if I wanted to change any of the styling, for instance, of a go to resource is assets as CSS changed some colors or anything like it obviously feel free to play with all these colors and settings and then even go to obviously layout. If you know happy with something and change accordingly. Then just run gope from within the terminal from within the root of your project. Just gulp hit return, and that will obviously process all the funds generate new CSS and JavaScript. Okay, Now, let's quickly open a browser and navigate to wherever wherever you set up your virtual host s. I've set it up already off shown this so many times. If you're not sure how to set up rituals, Police place Jake, one of my previous courses. If you're unsure where it is, just ask the question under the video, and I'll point you in the right direction again. Okay, Mine. One is going to be looking dot deaf and at the moment is just a blank page because what I have here is inside of the public directory. I have this index, which is completely blank. This is what it's pointing. So my virtual host isn't actually pointing to the logging directory. It points to the public Director. This is the route by sickly growth in a sense that our index dot PHP file which should be fetched when we actually calling the domain off. In our case visuals, domain is going to be pointing. So not logging. Its going to be within their logging public direction. And let me just quickly show you how you do it. On Mom, for instance, I've got mum pro install here, just a plus symbol server name I wanted to be say log, indulge, death and then document root. If I click on this directory here, you can see I can now navigate to my project which is logging. And then within this project, we have this public director, which is where our index dot PHP Yes, I'm choosing this directory for the documentary It. Then you cannot basically save and start the month problem. But I'm not using mom prime actually using homesteads. So if I go back to the terminal and for the homestead. I'm just going to quickly use my short cut. He on to edit Helms that file. Basically, if I scroll down, you can see I have it already set up its logging that death and it points to home Vague Grant called and then logging directory and a public direct crude in this project. So that's how I got my house that set up here. Okay, we have HD access file here already as well for moldy, right, If you on a parching. I'm writing this on Homestead. Some on changing to that file doesn't really matter here. But if young Apache you again all set, you don't have to play with any rewriting on things like this. Then we have assets, obviously, which are generating, generated when we are running, gulp, common. So every time you change something within the CSS files or JavaScript files and then run, gulp, this farce will be regenerated. And that's pretty much it's in this video. I think we've got everything set up. So we ready to start working with the coat, which is where we going to start doing in the following video 3. Session manager: Let's no copy our dot e n v dot example file and what we are going to do. So rename it to just thought E N v. So we have that dot example, which can be pushed to the git repository if you decide to keep its ah, basically within the repository, which doesn't have any sensitive information, and they are just very Abel's with some default values and don't envy is the one that's actually going to be kept on your machine all when you're installing the project. When you publishing the project on the server, you will need this file as well. Now a few open adult get ignore. You'll see that dot envy is not going to be pushed. Ah, with your comet to them onto the repository. That's why I'm keeping this, not ignore. Get ignored, because I will be pushing all this changes to the repository eventually. If you are not working with the gate, then don't worry about this. You don't have to have this dot getting the dots in e envied out example. But you will have to have this don't envy, because this is where our credential for the database, our credentials for them, for the SMTP will come from and so on. So first of all, what I'm going to do is to set up my A database variables A. I'm going to be using my SQL database and then for the House it's 1 to 7001 which is the equivalent off local house like and they use this I p or just type locals now for the database have created database logging. If I open sequel Pro Amusing sequel Pro Here with Homestead If using Wamp Mambo example Probably have access to either sickle pro If you're on the mark All PHP my helping Ah, please create a new database And obviously I have some credentials ready to obviously specify here within your conflict file as well. In order to be able to access this database eso for the database and name we going to have logging for user name because I'm using Homestead is going to be homestead on dance secret for the password. I'm going to leave these credentials for SMTP off. I will feel them in behind the scenes, but please make sure that you have some SMTP credentials, so you can actually again associate is vice with the variables here. Now for the business name. I'm going to put in between a single double quotes as as the space tutorials. If you don't have spaces, you can ignore this single double quotes on both sides. But if there is a space, make sure they rubbed them within either single double quotes. Now for the business email, I'm going to use info. SSD tutorials don't come, and this Both of these variables will later on be used. When we go into sent email email such as, for instance, registration activation are reset password email. So this these two will be used and displayed within their from field off the email sent to the recipient. Okay, environment up in e envious local because we working on them on the project later on when it's published, you can change it to life session driver. We're going to be using file by default Dense session path. This is what I want to store my sessions, which was going to be disease, the storage and session directory, then cookie driver file as well. Both of this will be over written if we open PHP unit when we going to be testing. As you can see, session drivers said to array and cookie drivers also said to array. And then male driver is set to test because when we testing, we don't actually want to use the actual ah file system in our case for session or cookie. We also don't want to actually distribute emails using this service provided any SMTP We just want to test it in a sense that it's going to fake that did the distribution. That's why we're using the test. And we look at this later on as well, when we actually creating this component and now for the data based connection when we going to be testing will use sq light rather than my SQL and database itself will be memory , which allows us to bicycle rather than using the file again database file to run all the squares in memory. In other words, we know going to be actually interacting with the with the database file itself, So that's for the PHP unit. And then we have verification true verification, as you saw in the introduction video. This is the variable that will a specify what sort of behavior for the registration form he wants to set. If it's set to true, it will send the activation Email and account will be inactive until this link within the activation email is clicked, at which point will change the status of the account from active, false, too active troops. If we set this to false, then registration will not require activation. And after the registration you use, it will automatically be locked into the system. So you will be able to easily change it later on here whichever way you gonna prefer. You can change it at any time, so you can have system running it with the activation. Then at some point you say Okay, I don't want to use it the activation anymore. And he just changed his very able and that's that Solar is going to work straight away. OK, so this is our dot gmv file. Now ready. As I said, I will feel this male starting where male underscore Vari Ables later on behind the scenes because I don't want to reveal any credentials, my SMTP credentials. You make sure that obviously you feel dese valuables yourself as well. Okay, so that's the adult envy. Fall next thing we going to do if you open our ah, compose it with Jason. You'll see that for the out a loud PSR forests, the way we're going to be out all over the our files, we using up and named Space, and this up points to the up directory. So let's create this directory and this is the director with all our files, classes will be, ah, located so up. And this is all our utilities are models and everything will be there. So that's the first thing we need to do. Then test. We need the test director as well. So directory deaths. And I think that's everything for now so we can close the composer. The next thing we're going to do is to create the bootstrap director directory, both strap, and if we a open our public directory and then if we open index dot PHP right after the opening PhD Pitak, What we going to do is require once and if I we want to require, rather than requiring the outer loaded that's actually within the vendor directory. First of all, we're going to actually required the fire going up while level and then to the bootstrap directory. And within this booster of director, we're going to create a separate out all of this out or load dot PHP. We don't have this file, so let's quickly created within this new directory. So PHP fall out or load dot PHP. And within this file, what I'm going to do, first of all, is to require this outer loader from within the vendor. So basically rather than inside of the index required, is bootstrap out a lot. And then vendor out a lot we only required is bootstrap and bolster will take care of making sure that we have this vendor out a load of Elbaz well, so require once a swell we're going to use. Actually, we're going to use the brackets here, and we use riel path function, which will take part of the current directory. And obviously that points to this bootstrap director. Now we need to get out. One level points to the vendor and to the ad this outlawed adult PHP far So what I'm going to disco in coordinate it in between a double quote starting with the Ford Slash, then two full stops for one slash then vendor and then after this outer load dot PHP And this really path will make sure another full path is that the absolute path to this file is correct. Is basically taking this full stops as going out from this dark current directory, then vendor directory and find out about dot PHP. So now we have our outlawed file available. The next thing we want to do is to, um instance, she eight dot e NV, so dot e n v very able equals and we start new dot e envy, and this one will take path to our environment file this one which was just being playing with a moment ago. Eso riel path again, and we going to do the same directory concurred in a tid, which we're going to go out one level and then after this file name dot e NV. So that's now the constructive for this dot Envy has now loaded this file. The next thing we need to do is to use don't envy and committed overload. Overload will basically overwrite any Vari ables that are specified within this file. That may have already Beene defined, so if there's any very able environment variable that already exists then is going to be overreaching with what we have. We have in this dot envy far. Next thing dot e N v. We need to specify some requirements. Sorry, quiet. And that's taking the array. And we telling that for this system to work correctly, we need de following vitals and I'm going to split the screen here so I can copy them db Connection is what I need for sure. The next one I need for shares a session driver as well. So these are required if one off them ah won't be available than this requirement that will throw an exception, insists. And obviously system won't run. And next time and the next thing we're going to need is database hostess. Well, we could put them all, but I'm just going to put a few most important ones database using them impossible. And I think that's going to be enough and then db password. Okay, so that's Oh, now I'm going to close this dealt envy found because we don't need it anymore. Here. I'm going to import this dot envy. Now the next thing I need is to start the session, but we obviously don't have the session component yet. So inside of the ab directory, I'm going to create a new one called Utilities and inside of this you till it is another directory Cold session. And within this director, I'm going to start with the farm PHP class called session Manager. And the name space for this one will be. As you may remember, up Directory has up named space associated with it. Then we have utilities and session, so it's going to be up. Backslash utilities, then box last session. And what this class will implement is a magic method called cold static. This method will allow us to delegate all static method calls to the classes that we going to be using. S session drivers in our case is going to be either file or a ray session. So let's create this call. Static methods never goes. So does the structure off this method public static function to underscores coal static. It takes name and arguments s two arguments to this method, and then we're going to start with this session variable, and this one will simply call another method within the same class so static it's going to be static because obviously we are calling it from within a static method and from within a static methods you cannot use Sudo very able this to refer to non static method. So it has needs to be a starting method. If he wants Toe referred to any method within the same class, then class name. We don't have this method yet, so let's quickly create it and what this method will. Britain is basically the name off the class representing their given session based on the session driver that we specified inside of this dot e n v fall. As you can see session driving we by default it's filed. But when we going to be testing session, driver will be said to a race. So we need to implementations one for the array and one for the far. Let's quickly. First of all, creators name off the class, so driver I'm going to start with equals and then dot e N V package. It has this get method which allows us to get the valley associated with the given valuable environment variable, some going to use the session driver here and a second argument that we can pass to this method is the default value. If this variable this environment variable doesn't have any value associated with it, that's what I want to return. And by default I'm going to set it to file. So now we have a name. Now return. We're going to use magic, constant name space, which basically points to the name Spain's nice space off the class from within. You call this constant, then we can coordinate its in between a double quotes to back slashes. One will escape the closing double quote, and the other is to actually have a backslash representing the obviously a separator within the name space. And then you see first function which will create convert the first letter off this driver into capital Letter. So we passed driver as argument and then conquered in a tid with this session. So the name off any of these drivers will be, for instance, for file is going to be filed. Session for Array is going to be array session. That's how this far is going to be called. Okay, so our class name now returns what we want. Let's quickly are the dog blocks. It retains string and what it actually does get qualifying class, name or session driver net class them session driver, class name. Okay, let's dub looks to call static as well. It's will delegate coal to a method off death chosen session, session class. I think that that makes perfect sense apart from the fucking obviously. Misspell it again. Okay, so and it will return more. Will it return? It will return mix because we don't really know what is going to return. We can call any of the methods some of them return something with them. May return string into J flow. They may return void. In other words, they don't return anything. So that's why we specify this and as mixed. Okay. And the next thing that we that we have there fully qualifying name, including named Space, do their file that's going to be uses. Our session driver. We simply return, and we used a function coal user funk array and the culpable is going to be new session, which is basically going to be whatever class that's going to return class name that's going to return. So instance, creating it and then calling the method, which is God is represented by the first argument of this cold, static method. So methods on this session driver and then any argument, any potential arguments that could be passed through as the second arguments to this call user funk array. And if you're not familiar with this function, please visit dot PHP dot net based their name in the search bar, and it is going to basically give you the specification for it. Okay, so I think our session manager is now completed. I'm just going to clean up the space. Is he a little bit and not sit? I think we can save and close the file. And in the next video, we actually going to create a contract and then two implementations one final session and D and one cold air a session. 4. Session drivers: our session component will have to implementations one file session, which is going to use the actual file system and the other one air a session which is going to be used for testing now because we have two implementations, you would expect them to have exactly same interface. That's why we're going to start with a simple contract interface contract is the name of the contract that we actually going to be using with our session implementations. So let's create a new class and call it contract. Now, this is going to be an interface. I'm going to just select the interface if you know, using PHP. Storm simply specified the name space and then interface contract. And that's all you need for now. And this file needs to reside within the session, Director. Okay, so we're going to start with specifying what methods we expect both of the implementations to provide. The first method that we definitely needs is them way off starting the session, so public function start, and because we are within the interface, we specify in just the individuals the method that we expect the implementation to have we don't actually provide any implementation is just a method. Name two brackets and semicolon, a deviant. So let's provide some dog blocks for this method. It will return void. There's no going to be any value returned from this method and start session is what this method will do. Next method that both of the implementation implementations will have to provide is a method that will return all of this session. So method name, perhaps old. It's a public function 02 brackets again and semi colons. And this one will return array because both sessions will be stored within the array and get all sessions for the summary off the method. Okay, next methods. And let me just create a few new lines so it can shift it up a little bit. So next methods will be The methods which checks whether they're key actually has been set within the session. So public function has and it will take one argument which is going to be the key, and dog block will return bullion either truffles with it exists or not, and the key will be off a string type and summary for this method. Check if session has a given key. There we go so dance that has method. The next methods will be the method that will allow us to set the sessions of public function set. And it will take two arguments. 1st 1 will be the key and then the value we want to associate with this keep and again don't books it will return void set method will not return anything. The value might be anything so mixed. The key was specified as us. It might be a string. It could also be an inter. Jess, I'm just going to put mixed as well, okay. And then session summer is going to be simply set session. And after this set session, now that we can set the value, we should also be able to obtain that value from within the session. So the get method seems quite reasonable here, so spa blick function get and we're going to specify what Kiwi wants to get bicycle value set associated with which key and this one can return mix because we don't know if it's going to be string into Jeb. Anything else floating point or anything like that and the key will be again mix as well because of my being to j might be string and so on, so on mixed for this as well. And this one simply gets so get session. And the next method that we need to have available on both implementation is the way of removing a given session by case of public function. Remove. We specified the key, and now we are going to again use mixed for the key. It will return void, meaning it more return any value and then remove session by key. And the last one will be to destroy social complete session completely, basically resetting everything, uh, removing all of the sessions. So Group's president, starting with the dull books that just specify public function, destroy. And that's now up the dog blocks return void. It won't return anything. And summer is going to be destroy session. There we go. So that's all methods that both of our implementations have to have. So I'm going to save and close this fall, and now within the session directory, I'm going to start with the air a session. So new class ray session and this one I'm just going to remove the spaces will implement dis contract into face as you can see highlights everything straightaway because it knows that their methods that we need to implement methods that this contract requires that any class that implements has them has the implementation off off them. So I'm going to quickly our methods stops, which is going to basically out all these methods without an implementation with them. So you can see we have start. We have all we have has said get remove and destroy. If you know again, if you know is in PHP Storm, you don't have this sort of macro is just simply type this methods by hand and then obviously follow with the videos so that we can actually are these implementations okay, within the session, where we going to start with the race session? I'm going to start with the private static property called Session, and I was going to be set to array and that's just out the dog block. Just with of our talk, okay, To start the session, where I'm going to do is static and use our property session equals every. So we start in the new session. If you want to return all of the values stored within now, this race session. Then we simply return static session because it's an array. It's going to return all of them and return Talk tells us that it returns array. Then we have has with checking if the given key exists within our session. So we going to return it's set and then static session and we check for a given key. Or we could simply do every key exists. It's entirely up to, you know, one thing about it said, if we just open our browser, navigate up to the PHP adult net and let's check What is said Does is set. And how does it differ from actually array? Key exists, determined if variable is set and is not know. So if we associate it, no wit our session key, then this one would return. False. So perhaps rather than is that if you know that you know, going to be associating no values than a says, it's fine. But if you're not sure, then use array key exists, and in that case, we're going to put key is the first argument and then the array, which is our session, and I think this is going to be slightly better approach Okay, Next we are going to have the set method so set mattered simply you static session puts the key and value that we want to associate with this key announce old that the set method off this array session will do now for the get method. We are going to first check if the value exists if the key exists actually on our array. So if an exclamation mark dis has which reckon if it has not, they basically if it doesn't have because we have this exclamation mark here doesn't have this given Ah kee. Then we return. No. Otherwise we simply return static session and we passed the key to obtain the value associated with this key. Now, for the remove method, we are going toe unset, static session and then key. So that's going to remove the given entry by the given key and then destroy What we need to do is simply static session and said it array to to an empty array. Again, we could buy sickly call starts this they start rather than doing the same thing again. But let's just stick with this for now, OK, so that's our array implementation. We can use it with the test, but I'm going to ride the test, actually, at D End once we have the implementation done this summer going to do it the other way around rather than starting with session with the test, I'm actually going to write it once we have it already. Okay, so let's save this. And next implementation will be the file array, so file every which is going to be used with the life system. Okay, let's remove all this and again, it implements our contract. So all these methods that we declared within the contract have to be available now with the far session. What we going to do first for start? What we want to do is to use this session under sculpts start function, and it takes an optional associative array off options that will override the currently set session configuration directives. I'm going to Onley, specify one and leave all the remaining ones as default. And that one I want to set is safe on this call path because I don't want to store my sessions within the default directory that the system has set. I want to store it within my storage and then session director, so I can easily check them whenever I want. Remove them whenever I want. And so on. Remember our public directories where all the request from the outside of our network will be sent so they won't have access to the story of charity. Because outside of the public director, this is what everyone's going to have access to. Basically, so to our CSS JavaScript files and our index dot PHP. But outside of this directory is the zone where they don't have access to. So then we have storage and session. This is where I want to save them all. So riel path we start with again D i r constant magic constant. And then we wants to get out from this director, which we currently in which this session to utilities says one level, then second level, toe up and third level to logging, which is the root of our project. So one level second level, third level, and then I'm going to concatenation with dot e n v and get again method. And where do we store the path to our storage session storage? If we check our envy, you may remember, we have this session path, which points to storage and then session director. So let's copy the name of this valuable based in and then if it's not declared, if it hasn't got any value associated with it, let's just overwrite it by using storage for its launch section. So that's what we want to save all our sessions. Our session will start here, and it will save all of the sessions to this direction. So that's hours. Sessions start fall. They're filing a It shouldn't be actually file A rate should be far session, so let's quickly rename it file session. So rename the file and then rename the class as well. File session file area. Okay, then we have old methods and all method will simply return the Super global session because Super Global's all race. So that's going to return. Obviously, the session array, which were interested in then four, has we're going to return, and again we could return lower case we could use its said by Let's Do Ray Key exists again . We passkey is the first argument, and session is the second. As you can see, it's pretty much the same way as when we were working with Array because of this is Super Global's all array. So that's why that's why it's going to works exactly the same way as as with young one. And now, if again, for the sorry for set, We have session key, lower case, and we associate value with it. So that's setting decision, Dan to get the session. We're going to the exactly same checkers before, so we check in if our session actually exists. But using a has method and passing the keys argument if it doesn't, then we return No. Otherwise we return session and value by its key a cave to remove the session, same situations before we unset session and then the key and to destroy the session. We have a function called session under skull destroy. And that's our file session implementation also completed. So we can now save this file and close it. We can close this dot envious well in our session component is now ready. Now, in the next video, we're going to actually write tests to make sure that this this component actually does what it's supposed to 5. Session component under test: so in a previous video with finished with our session component. But we haven't actually written any tests to make sure that it actually does what it's supposed to. So in this video, we're going to ride a test for this component. Before we do anything, I want you to open a composer to Jason and have a look at the outer load death section. As you can see, I've name Spaced. All the tests are basically our test directory has its name spaces. Well, in our case is going to be up test. So that's how we going to write our tests to make sure that we actually names, pacing them in for inside of the test director. I'm going to create a new directory, cold unit and inside of this unit, we are going to have a directory called Utilities to reflect the structure of our up directory and inside of the utilities. Rather than having session director. We going to have one fire, which will basically test decision components. So it's going to be just new class called session best, and we need to specify the name space, so it's going to be name space. It's up test. Then we have unit. Then we have Utd t's Aereo. So that's our name space. And now, before we do anything, I'm going to create a base case files again PHP classes base case And this one will be just within the name space test. Sorry up test because right on the details directory And this one will extend PHP unit framework desk case and I'm going to quickly import it as well. Okay, for the time being, that's how I'm going to leave this base class. This is going to be the class that we're going to be actually extending from all our tests so we can close this base case and now extends base case. And obviously we need to import this class is well, eso up test base case. Okay. From within a session test, the first test will check whether we can set and get the session. So public function, Ken under skull set and get session. And let's make sure that the PHP unit knows that it's a test by adding the test talk and we're going to start with session manager and then we call methods start and now you might be wanting ring already. What am I doing? OK, let me just explain exactly how old this is working. I'm importing this session manager here, and this is going to be op, utility session and session manager. That goes down to the one we interested in. And now how am I? Cohen started hours session manager doesn't actually have this methods. Now you may remember we've created this magic method called call static. Now, Cole static magic method is triggered whenever we are trying to statically called and methods on the given class, that does not exist within this class. So in our case, this first call was to the methods start and obviously session manager doesn't doesn't doesn't have this method. And we calling this method statically. That's why this skull static gets Trickett and this cold static takes two Argument is may remember name an argument name represents their name off. The method that we're trying to trigger that we're trying to call and arguments is an array that would represent any potential arguments that we would pass to this method. Now, in our case, obviously our ness starts a method. Doesn't have any arguments of this argument is just going to be an empty rate, but name obviously will contain the string start. And now what happens next? First of all, we obtaining the session driver class name. So we are looking at their session on the environment. Variable. In our case, if you go back here, we have this session driver by default, it's fire. But because we are running tests here from within the session test, we are going to be running tests through this configuration. Ph puny dot xml Where we actually overriding this variable and we setting this to array so that will this Methodist class name will return full path up utilities session ray session and when we are running theatric ation within the live environment is going to be up Utilities session file session. So we store this full ah class name, including name space within the session, viable. Then we are using this coal use a funk array which will trigger any call a ball. Instance in our case is going to be method on the object because it also can be just there closure, just the function. And then we passing the arguments to this method on this instance So in our case, we're going to create a new instance off the class air a session or in a life environment file session and then call the method with this name, which is going to be in our case. Start here and pass any arguments that we could potentially pass through when we're calling this method statically on this session. Manager. So that's how this structure here works. The delegates calls toe whatever method we actually trying to call to the specific session driver file. I hope that makes sense. OK, so we starting the session here, the next thing we need to do is to set this session because that's what we testing for. So session manager and we use the method set, which is going to be available on both implementations, as you may remember, because this contract that the implement requires them to have it, we have this set we have get. We have This has all and so on, which is obviously what we have done in the previous year. Okay, so we want to set the session with the key test and let's give it some volley. 123 So this is where we setting the values now to make sure that this actually has been said, Let's try and assert whether it exists so this assert true and we are going to say session manager and in method has test key. So we checking whether this specific session has been set. So whether it exists, in other words, with this has method and then if it did not if it doesn't return true, this has method. That means the obviously session has been hasn't been set. So we going to put some, um, some message saying Session has returned false after calling session set and semicolon after the succession. Let's no save it. Open our termino and within the terminal I'm just going to trick that I'm in the right direction. Pwd in my logging director, which is my project, which is great. Okay, so from within this directory, I can now run PHP units And there we go. We've got one test and one a session, and it returns green with the okay. Meaning everything works fine. So our test passes. Let's now go back to our editor and we are going to out another Alsatian. I'm just going to create a few new lines here. The second Alsatian will check whether the value equals to what we've set it. So this assert equals. And this someone two threes were we expecting? And now let's try and obtain the value. So session manager and then get method test. This should return this 123 because that's what we've said. It, too. And the message, if it fails a session, get returned Incorrect value after calling session set and in semicolon Indians. So we now have one test with to a sessions. Let's quickly go back to the terminal, run the PHP unit again, and then we go one test to assertions both of them are passing. That's great. Let's go back to the year it says. So that's the 1st 1 So we know that our session driver, in our case it's going to be a ray session sets and get their values correctly, and it also has method works fine as well, because it returns Boolean true or false, depending on whether the session has been set or not, Next test we are going to create is going to be called can remove sessions of public can remove session because we want to check with our session components can actually remove the session, so test again. And now, because we've already started the session and we've said this session in a previous test, what we can do, rather than setting it up again, is to use the depends. Stock depends on can set and get session what that means. It means that this test relies on the output off this one. So, in essence, we obviously started the session. We said it. We check if it exists and what value returns, but it still set. So we can use now whatever is being set in this previous test and use it in this one. So that's what we going to do. We're going to start with the session manager and now cold method. Remove with the argument test. So we trying to remove previously set ah, session within this can set and get session test. And now we're going to check this Assert folds, and we're going to check if this test session exists. Session manager has method, and we pass the name off the session double looking for, and then the message will say in case this assertion fails. Session has returned false after calling session removed and then semicolon India. And so basically, we've said the session and now we removing it. And if we check whether it exists, it's should rich and false. If it didn't, then obviously something's not right. So let's go back to the terminal. Let's run PHP unit again. And now we have to test three assertions. All of them are passing. So obviously this remove method works fine as well. Okay, Another thing we going to do is to check how many sessions are there actually within session itself. So this assert count should now have zero sessions on we're passing session manager. All method which returns are old sessions and dense session. All did not return zero after calling session remorse. Ah, session. All did not return zero records. Perhaps after calling session Remove. That sounds a little bit better. Okay, so we check in how many sessions are here because of this Also section manager all will return array and then assert count can count number of items in disarray. It should be set. It should be issued return. No, busy. Really not the case. In other words. Okay. So back to the terminal. That's test it. We have to test for sessions, all of which are passing. So all these methods seem to be working. Fine. Okay. The last test for our session component will check if we can destroy the sessions of public function can destroy session. And now let's do on the test stuck. This time we're going to start fresh. We not relying on the output of the previous test. So session manager start, Then we're going to set new sessions. Obsession manager set, test and this time, distressed. I'm going to set, as in the ray is going to be 123 d n a b c. And then this assert a true and it's going to be session manager. It's not this one. We're looking for this up. Utilities session No illuminated session session manager has test, so it should return. True because this should now be set and we go for session. Has returned false after calling session set with array. So let's check if that passes BHP unit and its interview, or do you find we have three tests? Five assertions. That's all good. And the next assertion this assert equals no m t equals. There we go. And it should equal 123 and den ABC when we try and obtain the session. So Sachin manager get test. So that's what we should get back when we are trying to obtain it back. And if it doesn't and message will be session get returned. Incorrect value after calling session set with array A bit verbals. Obviously it puts exactly what we've done here. Something It makes sense. Okay, let's give it a try as well again. Now, three tests with six a sessions, everything passes, which is great. And then now it's time to test this. Destroy methods off session manager and destroy method. And now this Assert count. Now we expect to be it to basically have now know sessions at all. In other words, when we try and count them, they should returns here. So, session. Many Jeff all methods should now, when counted, the output of this method should equal zero. And if it doesn't in the message of recession Oh, did not return zero records after calling session destroy. Okay, lets test this again. And now we have three tests. Seven assertions, all of them pass and we've now tested all of the methods declared within our contract and implemented within our session components. So that's are where session tests completed. We cannot close it and move the next video. 6. Kernel: in a previous video with completed Our session components. So let's now use it in order to stop the session for application, we start with opening a bootstrapped, an out alot dot PHP and right before the instigation of dot envy. Let's start with their session manager and let's make sure that we're using the right one. This is this our beauty latest session and then start methods. Let's imported here as well. So import, let's move it down. And that's pretty much everything that we need to do within our out aloud, which is within the bootstrap director. So now our session has started. We closed this. The next thing we're going to do now is skill to public index PHP and after they require ones this bus trip out alone. Let's start with the container container equals new con tain and is going to be discussing illuminate container, which is basically that I O. C. Container. When we are going to bind instances off certain classes so that later on we can actually pull them directly from this container. So container instance, and we start with the request. This is how he wants to later on. Be able to pull this request by using this name request, and the instance will be request. This illuminates illuminates http request and we call the capture method, which will get the request at the same time as its instance creating the new requests. So we're going to have an instance of this request available within the container when we call it. When we pulled it by request and everything, all the requests that have been submitted using any of the methods will be available to us . Then the next one will be contained. Instance. This time we're going to are the guard. We don't have the guard class yet, but let's just audit new guard for now. And let's create this class under death up. Then we go to the utilities, run the session just under. The villages were going to have the new class cult guard and this class for the time being , we're just going to leave it empty. We're not going to be doing anything at the moment. This class will handle all user authentication. Bat eggs are all their authentication methods will be within this guard class. Okay, then we start with the up equals new and again class. Which we don't have yet, Colonel. And we pass the container to it to its constructor. Now, let's create this Colonel. This colonel will also be within their utilities. So nuke BHP class Colonel. And we've for gotten too. Aren't there name space he had to the Gardas? Well, so it's going to be up. Uh, name space up. Ah, you t the t's. There we go. So that's just the name space It was Save. It closes saying for the colonel. And obviously now we need to import both of these import and the same for the Colonel Utilities Colonel. That's right. Now, on this instance of the Colonel we are going to later on colon method called Make, which we don't have yet. But before we does this make method will take two arguments. These will be the paths to our views. Basically, the HTML that's will be displayed in the browser and then path to the cash director where cashed views will be stored. So we start with the views equals and that's used riel both. And we go on, I use current directory. So on this card disco, the i r on this card disco and then we are going to concatenation it, which we need to get out from the current directory. We are dealing with the index of PHP which is within the public. So we get out of this public to the main route off our project. And from here, we need to navigate to resource is and views. Director, this is a director. When we have what we will start all our music. As you can see, we have pages here. We have template as well and so on. It's old, basically going to use blades template ing engine to deal with this. And then I'm going to duplicate this line renamed the Variable to Cash. And the second director will be cash. So there we go. So go car. Shia obviously views here. Okay, So now lastly, when we need to do so, echo up and there will be the method. We don't have this method, obviously. Yet because we only have an empty colonel class make we pass views as the first argument, then cash as the second argument. And on this instance, off another class, we will call the method render Now it is this vehicle to actually go and created these classes first, because obviously they all connected in certain way. So that's why I'm trying to do index the PHP first, and then we're going to go through all these classes. So we definitely need make methods on the colonel. We need the constructor, which will take this container. And then this make method will return instance of another class which will have this random method on it. Okay. And this is everything that we need without within our index dot PHP. All this will display the relevant page when we request it through the browser. Okay, we can no safe and close our index of PHP. And let's start with our colonel. The colonel will start with a private property container, which is going to be passed through is an argument container. And it's the illuminates container. And then we said, the constructor and the container is going to be passed. There is an argument, and we ST we bind its to our property. Then we use container, eliminate container to set the instance off itself. So this containing a what will this do when we set the instance on the container? That means there later on, we will be able from anywhere within our application to do something like this container, Uh, inner get instance make and let's say request. And then any method that's with then if I just open this index dot PHP again on this request. Instance. Because this capture will return the instance of request we will have access to all these methods. So now we can call any of this myth Let's say, for instance, get and then just past the name off the import and so on. So using this set instance, it sets the instance on the static property off this container. And then we can get instance of this container and pull whatever. We bound it to it like we will have rebound, too. It's like request and guard these other two ones that we actually bound here. So that's what we're going to be able to do by just setting this instance here. And right after this, we're going to make a call to the Method database. Let's out this database methods, and this method will be responsible for configuring the database and booting the eloquence object relational mop. So we start with their cop Sue, Which will be that's going to store an instance off the manager database. Capsule Manager. So it's probably first imported here. Right to the top use manager Data base camp So and we are going to be o l e s its ass cop Sue. Come sold. There we go. So let's copy the name here and is going to be new capsule and we pass the instance off the container to it. So corn tain So whatever is being passed through as an argument A constructor. We are passing to smell to this capsule manager. Okay, we start with the capsule now, and we art connection to our database, not takes on the ray off. All options for the database. We start with a driver which will equal dot e N V. We use the get method on it. And if we open our e n v file, all these items are start here. I'm going to close the file, browse on the left so we start with the driver, the driver will be start within this Devi connection variable. Let me just move a little bit. So it's all in one line. Then the next one will be. I'm just going to duplicate this line, change the index to host and is going to be DB host. Next one is going to be database and it will take this value associated with a D D B database environment Variable. Next one will be user name, which will be DB user name. Then we have password DB password. And after this, we're going to have Harr set and I want this to beauty F eight. Then a correlation which will be utf eight on the skull. General under Skull C I and last thing prayer fix. We are going to set to an empty string. We don't want any prefixes on it so we can save it. And after the at connection method, we're going to start with the capsule again. This time set s global and more This will do is basic. It's going to allow us to access the capsule globally via static methods and then we need to put the eloquence so cap so boot eloquent. And lastly, let's said date and time to UT ut CEO Whatever times on your in the date, default times on set and it's going to be ut see for myself. Obviously. Make sure that you specify that times on that. Your in. Okay, lets closes dot envy file database Lets aren't the dog block to this method as well. Uh, config euro gone gear the database and boot airlock. Who and and it doesn't return anything. So it's just put return void. Okay, After the database, we need this. Make Methodism may remember from within the index recalling this make method on the current instance. So let's create a smitten make methods public function make and it takes two arguments you may remember we path way passed through the viewers path and cash bath. So let's take them blade views and blade kahsh. So now return and we are going to return an instance off the class up, new up and this one will take this container again and then new blades. This package that we've installed Elia as well and this package takes this views. So Blade View and then cars director as well. Blake kash in the last thing that it sex is the containers. Well, they all want the container. So there we go and this class obviously does not exist yet, But before we actually create this class lets out some dog blocks. This one's going to be string. This is also going to be a string and some summary get instance off up. And this up will basically do all the routing in the sense that it's going to fetch the right concern controller and then obviously, output. Wherever this control is returning, let's open our five browser within the up utilities. We're going to art this up. Ah, class. So up that we go name spaces. Find this sign. Let's just remove this redundant spaces. So our Karen L Class is now completed. We can save it. So, basically, just just if we have a look at this again, I'm going to move these. It's up here so it looks a little bit better. Okay, so we first of all the constructed takes a container. We associate the container without property, and then we set instance of itself on the containers so that later on, we can call it statically and retrieve all the bindings. Then we call the database method from within the constructor, and the database method basically sets the database connection and boots the eloquent and then also says the default times on Then we have this make methods which will call return the new instance off the up class. Ah, we passing the container and then the blade. Ah instance as well. So we can use this Blades templates with the output. And that's pretty much everything that Colonel does. And in the following video will have a look at this AP Class. 7. Application: in a previous video. We've created our current class and with creating an empty class up in this video, we actually going to provide the implementations off the methods for this up so that we can actually load the right controller and from within, the controller obviously returned a correct view. Okay, so to start with, we're going to create to private properties private container and then it's just art. The dog book here is going to be an instance off the illuminate container and in private Blade, which will be instance off the late It's moving up here, okay, and Danica on Instructor, which will bind dese two to our properties, which are passed through as an argument we opened Colonel, You may remember we've passed the container inside of the container and an instance off blade, which is what we receiving here through this constructor. And now that we have a constructed done, let's move down and it's created a new method public, a function called Render, which is the one that's called from within the index dot PHP. And this is where we calling when this make method pretends the instance of this up class okay from within the render. We are going to wrap up a code within a try and catch statement. It's going to catch exception. Lets import this exception stray away. So that's use exception at the top here, then as e. And we're going to leave this catch for the time being. We going to process this a little bit later on eso within the try block what we're going to start with. First of all, we need to get the name of the comptroller. Comptroller equals this control, our method. Let's creatives control method and from within this controller methods we are going to start with a controller equals this container make and we want to pull request and then on this request, we want to get the segment one. Let me explain what this exactly That's so we if we go back to our index PHP instance hated this container, then we bound their request to it as an instance off the request which has already captured everything that there waas from the request. Either it's get boast on the other type off request. So all these options are already within the instance of this request. So now we are pulling this request from within this container, and on this container we call method segment. If we open this request itself and search for the segment method, you'll see that what it does, it takes the index and then within the segments. And if we click on segments, basically, it's It's just a part of that in the u. R L. It gets me the right one. So basically it splits them using this explode before slash. Obviously, let's say we have something like this. After the domain we have, let's say a categories. Ah, one, for instance, or something like this. Then a segment one will fetch the first item from the from the U R L segments to with French there second item and so on. So that's what this segment method on the request does. So let's go back to up. We can close this index as well, obviously. So here we're going to fetch the first item in the U. N. L. Then what we going to do with this item? We're going to check if it's empty, because obviously, when the when the page for his Lord's, when our site for its loads, it doesn't have anything in the U. L other than the domain name. So that would indicate that obviously the there is no the segment one is going to return? No, pretty much so. If we check empty controller, then what we are going to do is set the controller manually to lock in. This is the control I want too long. It's going to be logging controller. If the page for his lost sight first loads and there's nothing in the u N L T O to fetch the first segment from Okay, so that's the controller set. Then we check controller equals this controller name and we passed the controller that we French from the U. R I. And let's create this method. And this method will basically format the string received from the U. R I n re transit in a controller for months. So return and we going to use this string converter package factory string converted. There we go, a hyphen to class name, and we passed this controller as an argument. Actually, we can probably rename it to just name rather than controller. So if we have anything like, let's say, uh, can't agree, idea or anything like this, then obviously hyphens will be converted to something like Category I D. Class name. That's how this US hyphen to class thing would basically converted. Let's just move it up here. Okay? So now control the name leads straight away. Aren't Death dog look here and that's going to be a string returns a string as well. And what we going to say about it? Get controller class name. That's pretty much it's now going back to our render methods, Actually, Sorry, not men render method our controller method our control method. Now that we have the class name, we need to prepare the name space to this class as well. So controller equals. And in between the double quotes to back slashes up than two bucks lashes, controllers and then two bucks lashes and the name off the controller class. That's the fully qualifying name off the controlling out. Now we obviously don't have control. It's under there. The AB directory it. So let's create the director controllers and we know that the default one will be logging controller so that stray away create this one class logging controller and it's under the name space up controllers. We leave it like this for the time being, and I think that's pretty much it lets now check if exclamation mark class exists, in other words, of class does not exist because we have this exclamation mark and we passed through their fully qualifying name, including the name Space, then what? We want to do it, said the controller to the default controller, which is going to be up controllers page controller. And why are we doing this? This way is because certain sections of the website will require specific controllers modules basically which, like, let's say, news, module contact page module. You have to submit the form on things like this. But every other requests won't have because if you have any, any, any dynamically generated pages within your CMS, then obviously, you know gonna you know, going to be creating controller for each single page that someone's going to gent generate dynamically through the CMS, for instance. In that case, you're going to have a page control and it's quickly created, and here you're going to put older logic for returning the right page, fetching their content of the page from a database and so on I won't be going anywhere Failure with Paige, Controller Because we only focus here on their logging, registration, reset password and so on. We we don't really build a CMS here, but you can already put all your logic within the speech controller, and it will work just fine. Okay, so now after this check, we know that obviously, if that felt in other words, if the class exists, then we can obviously return it. So return controller. And that will give us the full path to the control. Okay. Lets out some dog brooks here to this controller method as well. Ah, return string. That's right. And then get controller name with name space. Okay. And I think that's it. Let's go back to our brandy method Now, from within the hour Miranda method, we're going to continue controller equals new controller. And we passed through two arguments this blade and in this container. So what? Controllers will take blade and container as constructor arguments and then we create the method variable this method uh, this method method within our up class which were creating just a second. And then we passed the instance off our new controller. OK, So let's of this methods methods, and this is going to be an instance off the controller. We don't have it yet, so let's quickly actually aren't this controller. This is going to be a super class, which all of the controllers are going to extensive control or and let's make it an obstruction freeway. Save it, close it and thats imported here. Controller. Now we go. Let's just move it down after all these dependencies, okay? And so that's what we're going to receive then from within this methods we're going to start with. Method equals this container again. We call in the week fetching the request from this container and then segment. So this time, so over the second item in the what I is is going to represent the methods. And again, if it's empty, then we need some default method. So methods. If empty method didn't return the default, one will be index, so every controllers should potentially have an index, because when we call the U. N I, let's say something like categories. Then the default index method will be called on this categories controller. And obviously, if we passed second argument, let's say submit then obviously some it will represent the methods is going to be controller Denver method after that. So basically control in action. Okay, so default one will be index. But rather than returning it, let's just make it method basically associated with it. And then we go for method equals this method name same thing as we did before with controller we passed through the methods and this methods will do the same thing as we did with controller name. So private function, method name It takes string the name off the methods and it would send factory a string converted factory. And this time is going to be hyphen to ah Kamil because methods in If I posit this name three is an argument because methods my being as we have them here, basically lower case, the first word and then all the following words, starting with the first letter in capital in common case. Okay, and let's just out the dog blocks to this one as well. Name is going to be a string on which will return string and what we're going to put for the summary for the summer. We probably can put something like get method name, So that's our method. Name methods completed. Next. What we going to do is check if method exists on the controller and the method names some method. So if it doesn't exist, what we going to do? Simply throw an exception? Throw new exception, saying invalids invalid method coal. And then what we going to do is the space here, and I'm going to conquer. Detonate it with get class from the instance of the class of that's going to give us the class name and then concatenation twit to Colon's indicating the scope resolution operator . And in between brackets are without them. You just put them method very able to indicate what method were trying to call own this class. And obviously, if that fails, in other words, there method exists on this controller on this glass. Then we return this method name. That's everything for our method method. Let's at the dog blocks returns string air throws exception. It takes control Instance and then get method name. Okay, so now going back to our render methods we've got now method here their last thing we need to do it simply return controller and on this controller we want to call this method so we can do, like, this method and then brackets all you can again remove these bracket this curly brackets item to use them. It's just a thing that I got used to. Okay, Now for the exception, if there's any exception to Rome, then what we want to do is basically return something back to the end user. And what we going to return is going to be the coal to the methods on the air controller. So we're going to create a new controller here, air controller, controller, and within this control, we're going to have a public function index, the default method, and this index will take the message. And we leave it like this for no, because we're going to be working with controls a little bit later on. So we return. And now, rather than first instance, she ate in the instance of the class on associating with a very But I'm just going to do it in line some wrapping this new statement within the brackets and new error controller, and this controller will take this blade and then this container, which is a water the controller class will take on. All of these controllers will extend it. But again, we're going to work with this other bill later on. And I'm going to put on a new line and called to the index method and this index methods, as you saw earlier takes one argument, which is the message that we want to display. Display eso. We are going to delegate it to another method, air or message, and we paused there. The exception through as an argument, this exception represented by this evil evil. Okay, error message. Let's did actually right here after right after this render method. So it's going to be private function there a message, and we take the exception. There is an argument so exception as he again, and the first thing we're going to do is to check whether the application is in a life or development melt, and how are we going to do its Let's open this dot e N V. As you can remember, we have this up on this court, E N V set to local. When the site will go, life is going to be changed to life, so we're going to check if exclamation mark dot e N V s method on this instance of don t envy a up on the scope e n v variable has value sets to life. In other words, it doesn't because obviously we using this exclamation mark. So that would mean that we are in a development environment, at which point we will return. Whatever this exception, actually, the message that this exception, uh, throws so get message method on this exception. Otherwise, we're going to return some nice message to the end user saying something like, You know, that the error has occurred or something like this, but without any details on what file, what line in filing a service because they don't want to know this life arrow message. We don't have this message, this thing's method. So let's quickly created after this error message private, functional life error message. And let's just return something that you want. L, uh you are the page you are trying to access. We are trying to access does not exist, and that's all they need to know if we are in the development environment. If we are working on the application locally, then we obviously want to know exactly what the message is. So this is what we're going to return here. Otherwise, we're going to just return this message to the end user when the applications in a lifeboat . Okay, so let's just get some Doug looks for this error message, and I'm going to say, here, get for four message And then for the life we're going to say it will return string and what we're going to put you get for old, for message for life environment. And I think that's everything within our up close. Let's just check if we've missed anything. We've got some dog looks here for the render. So it return string and summary cold methods on the controller, and I think that's going to be it. Okay, we can Let's just put this down here. We can save and close this up. We can close this deal T and V and moved in next video 8. Controller: in a previous video of created this up class. And if you're trying to load the page in a browser by now, you would see this fatal error on cult type era. Argument. One past two up method must be instance. Off controller instance Off page controller given Know what's happening here. Let's quickly go back to our Edison. Have look of the up, the first of all, we obtaining their controller name with the name space. So let's go to this controller method and controlling methods. First takes argument from them, the segment from the request. And if we go back to the browser, we don't have anything. We only have the domain name, so we don't have any indication of what controller We should have you going back to our editor. So that would mean that we are within the empty section here so this empty controller would evaluate to True. In other words, we would override this controller with their logging. So then we passed this logging to this controller name and control the name or it does. It simply converts wherever we got from the your eye into the class name, and I've just noticed that I've for gotten to actually upend here controller to this class name because when we pass in this instance, it would be just a lower case logging. So we passing this as an argument here so that will be cut will be converted using this hyphen, the class name to the logging. But we obviously need to upend the control as well, because all our controllers will have control at the end. So logging controller is what disc untrue Oler is going to Artis locking. That's what we would retain. So that's what we are going to obtain here. So at this point, we have looking control it. Then we prepare and their names space to this looking controller and because we do have logging control. And now this match message should change to the problem that was here originally, I was referring to the fact that we didn't have upended this controller. So now this page controller will changed to locking control look refreshing hesitancy. It tells me that obviously we still have a problem. But this son, brother and page controller, it's a lock in control occurs. It's loading this logging control. But what happens if we know because of the returning instance off the slugging controller. But if we open lugging controller, it does not extend this controller yet. So when we are actually, if we just go up here passing this controller instance to the method method which expects the controller, this obviously logging comptroller does not represent the controller because it doesn't extend it or it doesn't implement any contract with the name of controller idea. Okay, so what we need to do first is extend their controller from here. There we go, controller, for save it. Go back to the browser, refresh the page and now we have a blank page. Now, why do we have a blank page? Well, if we have a look at this, we checking for the method here. So we getting the segments to obviously returning empty string or no. And that obviously evaluates to True, at which point we over right in this method variable with index. And then we get the method name, which will just return index because there's nothing There's no concatenation is with any hyphens anything like this in the u. R l. This is just a straight lower case string. So that's going to be name of the method. And if method doesn't exist controller on this controller, then this exception is thrown and obviously from within our if we go back to the render we catching this exception with the error controller. So Air Controller has this index message index method which we are calling from within this up here. And then we passed the message to it as argument, but from within error controller, we don't do anything. So that's where we see the blank which, if I was to s a ah return message. If we go back to the browser and there we go, this is what we get here. Invalid method. Call up controllers Logging controller index. And because obviously we don't have index method on the logging controller yet. Let's go back to the looking control and let's quickly create this methods of public function index. And for the time being, I'm just going to return hello from we being logging controller just so we know that it's loaded correctly. So if we now refresh, there we go. We know that we obviously loved the index method on the logging control so that all works fine. OK, we can. For now. Let's just closest, Index because we're going to get back to this eligible later on. Our up is now have fixed as well, obviously, because we've for gotten this. I've for gotten this controller after the name of the controller name so we can close. This class is well, let's open the controller class and what we going to do here? I'm going to start with the the new construct so you construct it will take several arguments. It's going to 1st 1 is going to be blade late, and the 2nd 1 is going to be calm. Tainer content and let's bind them to our properties. Let's create this property straight away that we go and now they should probably be protected so we can access them from any sub classes. So that's the first thing we're going to do. And next we're going to do is to create another property. This guard equals container make guard. And how do we get this? Let's just others property, and I'm going to show you in a moment where it comes from protected guard and is going to represent uh, no mixed. That is a guard instance our utilities up Utilities guard, we just move it down here. Packages separate from our own components. Eso that's the guard And where it is this guard coming from If we open our public index dot PHP, you may remember that I bound here this guard instance of a guard at the moment, it's just an empty class. We will worked with this later on. So basically, when we are calling this make methods on the container, we are getting the instance off this guard that we bound here to this container. So that's what happens basically on this line, okay, And then the next one is going to this request because we're going to be using disquiet often. So let's destroy straightaway, have the property ready container make request. And that's exactly same thing was with the guard. Obviously, here we have instance off the request and the last thing we going to do is call the method this constructor. It is the method that will allow us to art any additional constructor, the actions that we wants to art to the the main constructor rather than then calling construct parting constructor from within any of the controllers. We just basically override this constructor method and by default this method is going to be empty. So I'm just going to put it all in line by default. Nothing's going to be executed within this matters. So let's Aren't there some Doug Brooks here for the control? Are we going to other problems? Parham, Blade blades. And then we have Parham Container container. And for the constructor here, we're going to say art to parent constructor and then return void. So basically, why am I doing this this way? Have a look at this. If we let's say from within, their air controller would like to have a constructor, he as well we will have to do something like this new constructor. And then again, we would have to put in these dependencies and then passed these dependencies to the parent constructors or part and constructor construct, then blade container and so on. But I don't want to do this. I just want to have a simple method which is automatically appended to the existing constructor off their parent class. So that's where we have this constructed. Now if I want to add something to the constructor, I only called this method. Obviously where I've made it private obviously wrong should be protected so that we can actually access it from any sub classes. And again, let's extend controller here from within that the air controller. So now what I could do it simply is protected function constructor. And just add whatever I want here. If I want to add any verification authentication to check, restrict access to the page, for instance, I can just do it straight away from here. And this is going to be run right after the constructor has processed all these items. This method will be called bicycle ever we have within this method. So that's a little bit easier and cleaner. We don't have to obviously called the party constructor and pass all these arguments that required for this specific constructor. OK, so that's our control. Just the just the beginning of our controlling. The next thing I want to do here is to art Dave you method so that we can actually return the view from within all of our controllers so protected function. We call it view and it will take three arguments first time. The 1st 1 is a view by default, it's going to be no. Then data, which is data that we want to pass the view. And then the last one is the merge data, which is the argument that comes by default with illuminate views by seeking the views that you would use with the blade within lot of L. So return this blade and then view, and we parcel this arguments in the same order. So view data and then merge data. Let's art some Doug Block's There we go. Let's import these views here. This class is funk. True there. Go and get view instance. So that's what this view method will do now going back to our air control, I'm going to remove the spaces, and what I'm going to do here now is return this view and then I'm going to pass the view which I want to use, and if we go to our resource is we have views, we have Bages, and there is this arrow blades. If we open it, it's basically using URL and then the message within the square brackets, which we need to obviously change, but lets first indicate that this is the view that we actually want toe return. So viewpoint to the views directory. And how do I know this? Because if you go back to the index PHP, that's where we specified as this views variable riel path to the director where our index of PHP s. So it's public then, from this director, we went out to the roots of our project. Then we went to resources and then to the views. So this instant, at this point here, this view already knows that it needs to fetch farce from this views Director. So what we need to do now here to indicate which five wants to fetch is just at pages and then arrow. We don't need to adult blades to it. It will automatically upend it, so don't worry about it. I'm just putting semicolon at the end here. Eso this view is going to be fetched and returned and with method will allow us to pass some arguments to this view message and the message will be bicycle. Ever. We've received as an argument by default, let's set it to know as well because we may not have any message that so that's will be passing to our view now if we opened this era blade file, and what we need to do now is rub our message within a set off to Kelly brackets something like this and then the name of the variable message, which comes from this with method. So this is how we want to call our variable, and that's how we passing this through. But this is a content. This is how we want to go to refer to it within our view. And you can read more about blades template ing engine. If you go to a lot of l dot com, then documentation. And on the left hand side you'll find blades, templates link. And this is the whole specification, so you can read through how you can create your templates, how you can display dates on how you can includes other files and so on is there's lots and lots of information here. Okay, let's go back to our project. However, refresh the page we have is still on the log in page. But if I put something that we don't have as a controller, let's say some air or and then let's art there because if I just run it like this is going to call the page controller and obviously, page control. If we go back to our editor by open page controller, you'll see that we still obviously don't extend to control it. That's why it's failing, extends controller. And if I go back and I will refresh the page now, it displays the year or pages you can see with them message that I've both through as an argument, and it tells me that involved method call on the page controller. We don't have index methods, and as you can see, it's automatically displaying this in the correct view because obviously have prepared all these views together with the exercise fire so you don't have to play with this now extends . It just tells you which templates we are using templates, and the template is within. As you can see template layout again, it's it's pointed to the views automatically and then from views, which where is your template? So we go into the templates director, and then we have layout gold plate and again, we don't have to append dog played here, and this is the entire template. If you want to modify it in any way, Obviously you can do it. Yield method. It tells me where I want with my contents to be put in this case content because I've used the content as well. He also Now I can use the section and Rupp the content that I want to put in between this dif talks here into this content section. So section content my content and then to end this section to indicate that the section is closing now just end section talk and that's all going to be replaced here in this place to that. But again, as I said, guilty lateral to come and and read about blades template ing a lot more if you obviously wants to learn more about it. Okay, so our error pages now done. Let's just out some dog block here, perhaps for this index met method and it rather than returns, this is going to return illuminate view. That's the one ill omen interview of you. That's what we're returning here. Message would might be no and then index control. Now one thing before we wrap it up. Let's just open don't envy file and what I'm going to do if you go back to our browser Refresh the page was still see this message. But now if I changed this to life environment, look what's going to happen. We go back, refresh the page, and then we get this default message. So if it's in life, our environment, obviously we don't want users to know exactly what methods work classes we have on this other sensitive information that could be displayed in the browser. We want them just to know that I was There is some problem. We're going to deal with it. Okay, let's go back to where it wants, which was local. Refresh the page and again we see the exact message they want to see because obviously this tells us exactly what the problem is. There's one last thing that we need to do with our air controller. Now, if I open my developer tools in crumb and reload this page, you'll see that even though it is actually 404 should display for for their response that I'm getting is 200. The status here is 200 which is okay, which is not right. Obviously, because it's not 200 it's not OK. It's fall fall, so if we go back to our editor. One thing we need to do. Before we actually returned this view, let's use their at the H T T P on this call response code and put in four old falls on the head. There would four for status killed is retained. So for now, saving and refresh the page you can see now it's retaining the correct status coat four for no foot not found. So that's it in this video, let's move to the next one. 9. Cookie component: in a previous video with other the functionality which allows us to get the right controller and called the method on this controller based on what we actually have in our requests. You know, where you are out in this video. What we going to start with, Ace? Get rid off this arrow because it simply says that we obviously don't have index made it on the page controller. And then we are going to start building the cookie. Um, component. Let's go back to our any time I have my page controller open. As you can see, the index method does not exist on this controller. So let's quickly add it Public Function index. And within this method, water I can do is it's basically down to you how you're going to implement it, how you want your pages to be fetched from the database and so on. We know going to be covering this within discourse. Discourse is purely father logging registration, reset passwords and restrict access. Ah, but just to give you a tip here, we could have We could create a variable. It's a slack equals and then get from the request. Get the segment one which is going to be whatever's right after the domain name and then the past. This lock to the database, find record by this lack, return it and then obviously display content on the page and what I'm going to do here. I will only return this view, and the view will be within pages directory and then, ah, it's called basically page dot blade dot PHP. So if we open, our resource is we have views pages and then we have this page Don't blade the PHP and oh, let's say says basically it Zagato heading saying page and then bar graph dynamic paint content if we wanted, so we could pass this log onto it as well. I I don't really think there is a need for these bullets. Just do it so with and then slack and we positive slack as the argument here and now. What we can do is dynamic page content for page with slack and then in between a double Kelly brackets slack and that should display dislike on the peso for a fresh. Now you can see there we go page dynamic page content for Page, which, like era, which is what we get as the first segment in the U. R l if I was to change it to something else Ah and me, for instance. And Debbie Gilda obviously changes according Okay, so now we can go back to the yet itself. We can close this page view, and we can also let's just out some dog books here. Uh, we don't return this. We returned view. Uh, there we go and we're going to say, Ah, show Page. I think that's nuts. All that we can aren't here. Obviously, it can expand on this. If you if you feel like OK, we can save and close this control as well. The next thing we're going to be working on is the new component that I'm going to close Concert Controllers directory, which is going to be very seeming out of this session. It's going to be to basically manage the cookies. So we're going to create a new doctor trend of the utilities called Cookie, and within this directory, going to start with first of all contract and the name space here is name, space up. You Teeley t's and it's kooky. So we've got a contract. This contract is not a class is actually an interface inter face, so we save it for now and then the next one is going to be called cookie manager on. That's fine. Then we are going to have just created a new class is going to be a ray cookie. As against the structure looks very similar to what we had with a session. They're a cookie and then we are going to have another one, which is going to be file cookie and again, array Cookie is going to be used with the test. Fire cookie is going to be used within a life environment and file quickly. Cook Cookie will implement contract the cookie one and then Ray Cookie will also implement the same contract. So contract the cookie one. Okay, we're going to start with the contract within the contract. We will have the following methods public function all to get all of the cookies and let's other dog block here. It's going to return array and we're going to aunt as gets all cookies. Then what are their methods? Any class dots implements this interface has to have well method that checks whether the the given cookie exists or public function has, and then it takes the key and again doc Block, it will return Boolean. True or false, the key is going to be off the string type and then check if kooky has a given key off the cookie with a given key exists. Um, yeah, nothing. That's that's going to be fine. Okay, Next one is going to be public function set so that we can actually said the cookie Sochi with value and it's going Teoh return void because it doesn't return anything. Let me just create a few new allies. We can see things better. Okay, Key is going to be a string and then the value is going to be mixed because it might be anything eso set cookie. Then after set, we're going to have methods to obtain it. So public function get with the key and the dark blocks string for key and mixed return mixed. Yes, because we don't know what it might be might be anything because we setting this he has makes. Obviously we can return, get back mix as well, and that's going to be gets kooky. And the next method after this one is going to be public function removed and we also passed. The key is argument, and we are passing key, which is going to be a string, and this one doesn't return anything's avoid for each Zantac. And I think we have all of the methods that we need for our ah classes so we cannot save the contract. Seven. Close this contract and go to cookie Manager and cookie manager. Well, have we implement this underscore on this card call static method, which will return the instance of a given cook implementation. Okay, so we're going to start with there. Cookie equals static class name. Pretty much the same way is with a session. So let's create this method straightaway and he are we going to go for the driver equals dot e n v Get and we're looking for the valuable. Let's just go to e n v. Don t envy in Cookie Driver. Let's just copy this one so we know which one we're looking for. Otherwise, if it's not set, we're going to use the different one which is going to be filed, which is going to be used basically in life environment and then return. We use the same name spaces Aziz we are currently using, which is going to be this op utilities cookie, then concatenation with and between a double quotes to back slashes. Then you see first. So first let's in capital off the driver. So in that case, if it's a far friends is going to be far with a capital F and then concatenation did with Cookie. So, in other words, what we going to have is that the name space, which is up utilities Cookie, then backslash again and either array, Cokie or file cookie. That's where we going to get from this class name. Let's other dog look to it as well. It returns a string, gets quality firing class, name and then so that this point we have the full name off the class we want to use with the name space. So now all we need to do is return Go user funk array and we possum instance off this cookie and then method name as the second argument to this first arguments to the to this dysfunction, and then any are potential arguments that we might might be passing through. So called this name on this instance of the class which is going to be represented by this string here and pass any arguments through to this method. OK, so that's our called static implementation name is going to be a string arguments off the ray type mixed my be void to my be stream I'd be anything pretty much so mixed for the return talk and then delegate called to a method off the chosen cool key. Ah, class. And that's our cookie manager completed so it can save and close this file. And now obviously, we have this contract here for the array cookie and file cookies against its automatically highlighted in red here. So we're going to start with the You're a cookie. I'm going to automatically out. The method stops so he returned. And there we go. So all these methods now, he obviously we need to provide implementations. But we going to start with their private static property cult cookie, which is going to be off, and I m an empty array type. That's just aren't dog lucky as well. So get local kiss will simply be return static and then cookie is this property we just said then fall that has methods we're going to check. Return it's set and then static cookie with this key, then for the set methods, we want to set it so static cookie and then with the key dance with the value we wants to this specific one to have. Then for the get method. We want to get it out off their off this cookie array. So it's going to be festival. We're going to check if and then this has and then a key as an argument. So if we don't have this the cookie with this key, then return no. Otherwise, return static cookie and put the key in a bracket. So we get the right item by its index and then for the remove one. It's simply on setting it. So onset static cookie and then Dickie and that's our ray cookie class implementation completed. We can save it and close it. Let's do the same with our final cooking, so out method stops. And obviously, if you don't have these markers which automatically adding methods, stop simply type it by hand public function than obviously the the name of the method curly brackets and then obviously implementation goes in between. So for all we're going to return this time Super global cookie, then to check if the key exists, are we going to return? ISS set again using the super global cookie and we looking for the given key and then for the set method. We are going to start another argument here, call duration, even though the contract doesn't have it. But as long as we associate the default value with it, we're going to be fine, and it's added to them dog blocks as well, and it will return void. So it's going to be an integer their land. How long we want this to cookie to last. And, ah, we are going to you set cool key, a function which takes key, then value. We wants to associate with this a duration and then path, and we could probably out a few more. But let's quickly have a look at this documentation for set cooking. So open our browser, navigate a PHP dot net, and if we stipe in set cookie in a search and hit it dead together, there quite a few arguments. As you can see, we've only used four of them, which is the name value than expire and path. Let's have a look at this before we have a name of the cookie in the value of the cookie and then the expire, which is a time the cookie expires. This is a UNIX timestamp. So is in a number of seconds scenes the people, people state stands for them. First of January 1970 midnight. Basically source from that time. Number of seconds. Ah, represented by this third argument. In other words, you most likely said this with a time function, plus the number off seconds before you wanted to expire. Because time is going to function is going to give you current time. So then you can add to it, which is basically going to give you the time way. You want this given cookie to expire, or you might use make time function as well. Then way. Have an example. Time plus 60 times 60 time 24 time. 30 Will said the cookie to expire in 30 days. Why? Because time it's now. Then plus 60 times 60 which is 60 seconds time, 60 minutes. Then we have time. 24 which is giving up to the 60 times 60 gives us And now we're time. 24 hours time, 30 days. That's what we getting. If set to zero are meted, the cookie will expire. D end off the session when the browser is close and then we have a path The path on the server in which the cookie will be fl born If said to afford slash cookie will be available within the entire domain. If said to four, for instance, the cookie will only be available within their full directory and all sub directors such as full bar off the given domain the default values the current directory dot the cookie is being set in. Okay, so let's go back to our editor. So we've got this set cookie. So by default, the session will expire. When we close the browser, Then we have the get method. And within the get method, we again going to check with you first. Have it So this has key. If it doesn't because of the reason this exclamation mark here, then we return. No. Otherwise we're going to return using the super global cookie, the item by its key and then fall the remove methods. What we going to do it again. You set cookie. We use the same key, and then value doesn't matter because we actually removing it by the time we're going to use time minus, say, 1000. So that's going to be in a past indicating that this cookie should now be removed. Basically, that's what it does. Okay. And then again, obviously, path to make sure that we refrain, sing the same the same path. So that's our where file, Cokie Class. Also complete it. So in the next video, we're going to ride the tests for this cookie component. 10. Cookie component under test: in a previous video with Killed It This cookie component. Now it's time to right some tests to make sure they obviously dance exactly what we wanted to. So if we open test unit utilities under the utilities, let's create a new class called Cookie Test, and this class will extend the base case. The up test based case. And we are going to start with the first test, which is going to check whether we can set and get the cookie so public function can set and get cookie. And let's market. It's test test. There we go. And now, before we do anything just to remind you if you open PHP unit when we are testing up to this PHP unit will be fetched. And all these valuables, this environment variables will be over everything with what we have within this PHP and an E N V. Within the interview tax and for cookie driver, we set it to a racer. When we are testing, we are going to use this array cookie when it's the life environment within our Dottie envy file, we have it set to files is going to be working with this fight cookie Okay, so starting with this this first test, I'm going to start with a cookie manager and use the set methods test, and I want to set it to 123 So our new Cokie called tests should now have the value once or three. And it's been imported here, just in case your I d doesn't import automatically. Make sure they obviously put these to use statements here. Okay, so we've said that cooking. Now we're going to run the assertion days, assert true. And, uh, cool key manager has test cookie. And if a dozen Dan, let's ah, 10. Some message cookie has returned. Uh, false after calling Corky set. Obviously we calling this on them cookie manager, and it's not quite a cookie. So that's probably yeah, let's just change it to cookie Manager. Probably a little bit better. Okay, so let's save it and open our terminal. And make sure that you're in the correct directory. Obviously are should be within this log in. So let's just check PWD. And that's where I am, which is great. So now I can run PHP units. And if we only want to test cookie test, let's specify the path. So tests you need utilities and then cookie test. And there we go. We've got one test, one this ocean and the air passing. So it's all good. So sets and has seemed to be working fine. Next, what we going to do is run. Another assertion this time assert equals and we are going to check if the cookie actually equals to what we've said it. So So 123123 here and then cookie manager get test and not should return this 123 Otherwise , we're going to say Cool key manager Ah get returned. Incorrect value after calling cool key manager set and then semicolon a DNC. And let's around this test as well. And there we go to assertions they are passing. So it's all working fine. And let's now create another test. Public function can get, oh, cookies and test that's crawl up a little bit. Can get old cookies. Let's said the cookie again. So cookie managers set Say test 123 and then it's out. Another one said Tests to 345 and now we run. This assert equals and we passed the array off items the 1st 1 will be Let's put on new lines. So test is going to be 123 and then Test two is going to be 345 So that's what we expected to have done. Cokie Manager all method. And if it doesn't return that, then cool key manager all returned. Incorrect value after Colding. Cool key manager set. Okay, let's save it. Run the test And there we go. We have to test three Alsatians, all of which are passing. So that's great. So we know that set, get and has and all are working fine. The last test we're going to write is going to check whether we can remove the cooking so public function can remove Cokie and it's a test so kooky. Many jam remove test. And now what? I'm going to do ISS because I don't want to set it again. We can use what we have in the previous method by using the talk Depends on the specific tests to continue from this test, and we're going to pass the name off this despot use massacres can get all cookies. So at this point, when we run in this test we already have these two cookies set. Okay, So what we going to do is we removing just a single cookie? So we're going to run? This assert falls when we call Cookie Manager again. This time has and we're checking for test. It should not have it because we've just remove it. And the message in case it fell. School key manager uh has returned. Falls so returned True after calling kooky manager removed because that's the opposite. We are expecting false, but if it obviously fails, then it will return. Must have returned. Boolean true, So let's save it. Preview preview. Let's run the test and we have three tests for a sessions. The old passing. So that's great. Let's now do another station this assert count and let's run cookie manager. We going to get all items at this point actually before we need to actually specify what we expecting. It should be one item only because we've removed one. Then kooky manager All did not return one. After calling Cookie a manager remove and I think that's going to be it. Let's run it and we have some syntax Aero committed in the on re call my forgotten the comma here after this one. Let's clear it and run again and everything works. Fine. Let's now just to make sure that everything where is the way it shoot? Let's remove this last, uh, cookie test to as well. And now, let's assert false. Actually. Let's just run this count again. This time we should have zero. So assert count zero this time, Cookie. Manage. It did not return. Zero after calling cookie manager remove. Ah, the second time. If we save it, run a test. And there we go. Three tests, six sensations. All of them are passing our cookie components not completed and test it We can move to next video. 11. Migration: in this episode, we're going to create the migration for our users stable and know what migration is is like a set of instructions, which, when you run, will automatically generate the table in the database table for you. So let's start by opening up directory. Then we are going to create a new director here called Migration. Within this directory, I'm going to create a new file PHP class called Table Contract. And rather than having this is a class, it's going to be an interface in the name space for this one is going to be up and then migration. So if you don't have these options, this dialogue copies to make sure that unnamed spaces up backslash migration, an interface table contract. Okay. And this fire will have two methods that will be required on any classes that actually implement this contract. So public function up and let's other dog block. It's going to return to avoid, so there's nothing to be returned from this method run migration, and then the other method will be also public function down, obviously public because in interfaces you can only declare public contract methods and done will also return void and is going to be roll buck migration. Okay, we can save and close this interface because that's all we have within the specific filed. Then we going to create another phone this time is going to be a PHP class called migration . The names, the name space stays the same size up migration because it's within the same directory and this one will have a public function up, which will from within which we will be able to add as many migrations as we want. We will only have one migration for user. If you have pages, you could other he as well and so on, so up and then the other public function was going to be down pretty much what we have within this contract. But it's not basically the class that will implement this contract, even though the methods, obviously much we could call these methods wherever we want. This contract is for any migrations that we actually will be calling from within this migration class. So before we aren't anything, I'm going to stray away at the dog looks here. It's going to be run migrations because it may be multiple ones, then return void as well. It's nothing to be returned from within this method. And then, uh, roll Bach Migrations, return avoid as well. And before we actually aren't anything to this methods, let's create a new directory within the migration directory called Tables. And on this one, where within this director, we're going to create a new our new class cold user, and it's going to be under up migration and den tables. So that's the unnamed space, and this class will implement our contract table contract. Let's add, the method stops automatically. So there we go. We've got up and down methods that we need to implement and using Illuminate Database package, which we've installed. Elia. Let's use the database capsule manager to start with. So manager database capsule manager. And that's God's automatically important here. Just in case you don't have a dramatic in imports enabled within your I. D. Make sure that you use illuminate database capsule manager, and we're gonna go for schema methods on this, uh, on this class and then create. We want to create stable users, the name of the table girls first and then function, which takes a blueprint, which is this illuminate database schema. So blow print and we going to name it table. That's our second argument. And again, that's got imported here. Illumina Database schema Blueprint Eso no On this table, we can set table. We want increments first, which is basically outer incremental. Ah, I d off the record, which will The column name will be i. D. So that's the first table column. Den Table. Next one is going to be tiny into Jeff and I want this column name to be active, whether their records active or not, and by default will set it to zero. So it's going to be inactive. Then we have table string type off the column. Ah, off the column data type and it's going to be named off the user Dan table. So I know this table another string, which is going to be email, and it needs to be unique, so unique method as well on its den table, another string Ah, password, which is the column when we going to be storing the password for the given record. Now we could pass the second argument for all the stream method CIA indicating how Maney heart is. We want this Varta because it's going to be a virtual type. This field, how many characters we want to specify. But I'm just going to leave it as default s two or 55 and then table next one is also going to be a string which will contain a token. Whenever we just said the password, This is where our token is going to be stored and by default is going to be NeuLevel, meaning they. Obviously, when we create a new user record and the value isn't required, ask so this field can be empty. Okay, then we have table string again. This summer is going to be remember Tall can when we have this check box with the Loggins with with the logging form. Obviously, if we want the user to be remembered on this computer, then obviously this is where our token for this Remember me eyes going to be stored, and again we're going to give it its to 55 characters and no second argument and also renewable because it might be empty. And then the last thing we want to art is table time stamps. So what this time stamp? It does. Basically this one will at the time stamps. It's time stumps like this is going is going to art created at an updated it. So whenever the record is created, the times that's going to be put into this created at field and then updated at every time we're going to update the record, this value is going to be updated as well, so we can keep track, obviously off when the record has been created. And then when it was lastly, last updated. Okay, And that's pretty much are where schema it is called for our migration off the users stable now for the down method we need to provide the means off, destroying all those that we actually creating with the up method. So in this case, we're going to again use this manager database, capsule manager and schema method and and on that we're going to cop called Drop if exists table users. So that's what we want to do. If table users have bean manually, for instance, removed all no longer exists for any other reason, then it's just not going to throw any years when we and exceptions when we actually calling this because they own will only drop it if it exists. So when migration far is ready, let's now open our client for the database we're going to be using. I'm using my SQL here with Homestead. I've created the database logging. There are no tables at the moment is just a database. If using PHP mild me, make sure that I use to create the database is well or if you are using Terminal two created a database, make sure that you've got a database to work with and then update yo a dot e n v file to make sure that obviously, this db starting variables obviously reflect your local environment. So database name. In my case, it's logging that I'm using using them hamster than password default password on hopes that this secret Okay, so everything is set up now. We could do it. We could run this migration many different ways. But before we actually do anything, let's make sure that this migration file now has eyes making the cold to this up method on this user instance. So what we going to do from within this migration? I'm going to just do it in line rather than associating them new instance off the user with the variable. I'm just going toe Drop it with the brackets. So, new user And here I want to call up method. So when we calling up on the migration, Dad's going to automatically call this up method on the user. And if we have in any other tables that want to do obviously could create, as many migration called them all from within just the migration up. And for the down, we're going to do the same. Just new User and Dan just down method. So in that case, we can run all of the migration and migrations by just running a single method on on a single instance of the of the class. Okay, so im migration file is also completed. We can close it. We can close this user migration as well and close the migration direction altogether. We could call it directly from within the index that PHP. But I think I'm going to create a new controller for this specific purpose. And I'm going to call it my great controller. That's what I'm going to call this file, Okay? So, obviously, in order to run it, if I want to run it within the browser. All I have to do it after the domain name. Just put my great and this is where this migrate control is going to be called without any additional segments is going to call the index method, which we don't have yet. So let's created Public Function Index and from within this method I'm going to simply again in line it new migration this time. And on this migration instance, I want to call method up, which will run all of the migrations. So if we have any more, obviously you can art another one. That's safer. Pages follow the same obviously structure as we have for this user migration, then added to the migration up. Just another line, for instance, here on art page, obviously migration up. Then make sure that you are wanted for for the down method as well. We have done have the page migration. So we only deal with the user one. And then obviously, by calling this migration up, we're going to run all of these migrations in mongo. Okay, so again, I've use this migration here, make sure that you imported up migration, migration, eso what we can do now I'm just going toe Aren't the dog block it returns, return void and run migrations. So if we now go back to our browser and what I'm going to do is here after the remaining for a slash migrate heap return and we have some aero operative this up methods Mars be an instance off control instance off. My great controller given again. Same problems before I'd for gotten to extend that controller Troller. There we go up controllers. Now, if you save it privy in the browser Ritz, refresh the page And if we check our database refresh. There you go. Our table is now created, and as you can see, all of them table columns are also are that we've got everything that we specifies I said earlier because we didn't specify the second argument for string We all of these string of our Charles Basically, columns have then off to 55 and so on. Obviously, this, uh, increments on created the the table column with the interject length 10 unsigned, and it's a primary key automatically, which is also incrementally as well as you can see, he has its proper primary key. Okay, so we've got our table. Um, our migrations done. Obviously, if we wanted to destroy everything that's create another methods public function down, for instance, the default will be generating the tables about. We are second segments to this migrate path, a called down that's going to call this methods. And I'm going to Aren't Doc Block here again? The return void Roll buck migrations and I'm going to do the same in line. It's so new migration. And on this migration I want to run down. So if we now review it in the browser and after my great just do four slash down, run it. And now check our database. Refresh it. You can see the our table is gone. If you run, migrate with doubt. The second segment again does going to regenerate the table and there we go. Our table is back in our logging database 12. User class: in this episode, we're going to create our user model. So under the AB, direct true begun to greet the new one. This time, we're going to call it models and all of I models will be stored that we will only create one for this serious. But obviously, if you're going to have Paige model later on as well for your CMS and many others, then this would be the place. Where you going to put them in? Okay, we're going to create our user Mulder now. So new PHP class user, it's going to be within up. Backslash models name space because up obviously represents this up direction and models, obviously, is the next one up. Eso dots our new user class, and it will extend model. The eloquent model eloquent model is, well, a lot of other uses as well. So if you're familiar with lot of none of the things that I'm going to here will be new to you. Ah, we are going to start with a couple of properties. 1st 1 we protect it table to indicate which table this user is associated with, and it is going to be the only trouble that we have, which is users. Then we're going to have another protected property cult. Feel a ble. And as you can see, my idea automatically, uh, gives me a new option to select from one of my typing. And this is because these properties actually exists on this model. If we go to this model, this abstract model classic and so we have table. And then we have and those girl down feel a ball and the attributes that our must assign about What does it mean? It means that when we actually going to be creating new model updating it, we can actually pass in the rate as an argument of, rather than associating each property separately with the new value before we save it. So we want to be able Teoh a must sign name. Then we have email. Then we have password. Then we have talk and as well, we also have remember dull can and actually be full name. We have are active. I think we just quickly check our migration tables. User, we have Yeah. We have active name email, password to talking and remember talking. So that should be it. Let's just art some dog blocks here. That's a string. And this is in the ray. We don't need summary for these. Okay, The next thing we're going to create is that method that automatically harsh is the password. Because we don't want to store passwords as a string. We want to make sure that it's encrypted. So public functions set password our tribute. And then we passed the password as argument, and I'll explain all this in just a moment. What happens when we actually create this sort of method return? This attributes, then password is the attribute. Double wants to change hush class, which would create in just a moment and then make methods on this class, and we pass password as argument. Now, before we create this harsh class, let me explain what this method actually does. Within the eloquent, we can use our setters like this. So these are starting with set an end with our tribute. So whatever attributes you want to modify when you actually associating either by associating it with a property, let's say we have user at password and then you pass a stream. It's a secret if we do something like this and then we save it. It's a user safe. Then what's going to happen is that when we saving before the object is going to be saved, it will check for all these setters for methods would start with set. Then they have attribute the Basically the name off the field that we want to modify is starting with a capital letter and ends with the attribute. And if it finds method like this, then it runs this property. Throw it so basically, it's going to modify whatever column field, obviously property on on the given object we want to modify. So it's going to convert this password, which is by default, going to be sent as string because we're going to associate with this as a string or pass is in the ray off, see of a key and values, and we going to modify using this harsh glass with make method. Once all this set of methods have been executed, then it's going to go ahead and safe records to the database now away. What? We also can do it. If we want to modify, let's say name, we could do as well using simply public functions. Set name our tribute and now obviously passed name through and you could do whatever you want with this Saturday is now. Why do we actually refer to this attributes array? This is because eloquent uses array to store all of our properties off the objects So all of the properties are within the area. If you click on this model with, we scroll down, you'll see we have this attribute and this is models are trapeze basically. So whenever you do something like to go back here, lets a user boss work. It's simply you, sir attributes passport. That's what it refers to behind the scenes and it uses magic methods to later on. Obviously access these properties and we go back to the model. Let me just quickly show them to you. So we've got gets sad finds. If you want to set it, it sets attribute. So we've got a key and values of, for instance, password and then whatever despots where you want to be and then set attributes what? It does it bicycle check if it has mutated, which means if we have this set, a method which have discussed the aliens you can see here has mutate our first of all checks and has mutated. Basically, checks if we just click on has imitates a method exist and the method name is set. Then string of the Stahle boats The first letter off the given key to capital. As I explain and then appends attributes. So in our case, it will be set. Passwords are tribute, which is the name off the method that we've created here. And if we go back to this set, attribute and then it creates this method and then simply runs and because this method from within this matter, we actually pretend whatever we associating. So apart from the fact that we associating whatever we going to do with the given on attribute with the given value, we're associating this with the obviously index on this tributary. We also returning it. So at the same time, we get obviously here the value modified value and we retaining as well. So we get this on the on the attributes array as well as we retaining this at the same time . So that's how it works, obviously. And then we have other checks. If it's a date and so on, and then we'd returning the instance of itself obviously associating again value with the key. But at this point, obviously, if we have imitator this set method, then obviously this is when we a set attributes end obviously its execution because he from here, we returning already the value. Okay, so that's what this thesis Ettus are doing. So if you need to modify anything before it gets safe to the database, create a setter in the following four months. And obviously you can do whatever you want with the value before you associate with the property. Okay, so now harsh method. Let's quickly create the new class, which is going to be under utilities. We're going to create the class hush, and the name space is correct because it's up utilities and this harsh will have only two methods. 1st 1 will make the harsh. The other one will verify it. So public static function make we take a string. And this string was simply return password Harsh. We passed string through as an argument and then password default constant. And if we save it, if you want to check documentation so let's copy the name of the function. Go to PHP. Net. Never And there we go Password hush and he creates a password. The password hash creates a new password harsh using a strong one way hushing argument Password Harsh is compatible. Crypt therefore, pass work harsh is created with crypt can be used with password harsh And then we have the following constructs the algorithms and we've used this password default Used the big crypto algorithm on its defaulters of PHP 5.5 and know that this constant is designed to change over time as new and stronger. Our gardens are other to PHP. For that reason, the length off the result from using this identify can change over time. Therefore, it is recommended to start the result in a database column that can expand beyond 60 heart Er's 255 Heart is would be a good church, which is what we've got. Obviously without Varta in the table for the password with the land off to 55 Okay, so let's go back to our editors. So here we encrypting hashing our password. Let's out them dog block. It takes a string which is going to be a string, and it returns string, which is harsh and then we go harsh string for the summary, and the next method will verify it. So public static function verify. And we take this string and den hushed script string as well. Uh, let's just put harsh here, and I think that sits and then we are going to return. Password Verify We passed String Service String and Dender Harsh. This basically it's possible. Verify again. You can go to PHP got need to check what it does, but it that basically takes the string and then the string, which has been harshly with the same string. And then it tells you whether they are the same because thes this password harsh will generate the new unique hush every time, even with the same string, so it's never going to be the same. Okay, now, very file. It's at the dog blocks here we passing string through Hush is also going to be of a string type bullion for the return, tired because he's going to tell us where they it's valid or not, and then very fire string against the harsh and that's all within our harsh class. So let's quickly ride the writer test void as well Under utility sleds just create a new test called Harsh Test. The name space is fine and we are extending base case off the up test and we start with public function, correctly, makes and verifies harsh. And let's make it a test. Okay, so now what we going to do? Harsh. We start with and then harsh. The utility wants make method and it's passed secret as string. And now let's verify it by routing it through the assertions. So assert true and hush verify. We passed secret and then has hushed secret source harsh and not should return true, because obviously secret is a secret. And then harsh shoot obviously represent the harsh value. Okay, so harsh. Make a very fi failed, if if for any reason this method did not return trip. Okay, let's go to our terminal and make sure the obviously we on the correct directory within the root of our project. And let's wrong Ph unit. Let's go to this specific tests or you test you need utilities and harsh test and then we go. One test wanna station all works fine. So we make made the harsh and then we verified everything seems to be working Fine. Okay, let's close this harshness and harsh class. Now it's imported to our model using modem, and it's up. Utilities hush. So if you haven't got automated imports, then obviously make sure that you are this use statement here up. Utilities hush. Okay, so this is our settle. Its art Some Ah, dog looks to it as well. It takes password, which will be of the string time, and it returns a string as well in harsh pass word for summary. Okay, so this is the first method. Then the next method I'm going to have on this model is going to be using this harsh verify methods to make sure that we when we passed the password through that it actually verifies it automatically is a public function. Verify password and we pass said, Ah, since password as arguments here and return Hush. Verify passport dupes. Ah, password against this past ward property, which is going to be hushed because we're going to start harsh version off the password within a database somewhere Pull. It is a property does the harsh and that's the past. What are we going to receive from the logging form as a string, which is where we going to be able to verify it. Okay, lets off the dog Brookie as well. Password will be of the string type and dan of refight password for the summary. So that's the next methods and other methods on. Now we're going to use them query scope, which will allow us to pull the record by AEG given, ah, email and query scopes in eloquent start with keywords scope. And then, however, we want to call this method and let me just demonstrate it. So public function scope by email and we going to have a builder eloquent billed as first argument, and I'm going to call it Query, and then whatever argument I want to pass to this to this method whenever I'm going to be calling it. So why our argument is going to be simply an email, and all this will become a little bit more clear when we actually start using it. But I'll try and explain as much as I can. So return query and we go into art where, close to our SQL query email field equals email. We could do it either this way or if you prefer you can Boots are equal symbol here and then comma. If you owe me the second argument and you only have two arguments, then where close automatically assumes that you actually trying to make sure that the item that filled equals wherever the values, otherwise you could also do like you could also do, say, more than and so on. All these operators are still available as a second argument. If you passed three arguments through, if you only pass two of them, it's always going to use equal symbol for for the work loss. So whatever our clothes is going to be select all from, say, table users, where email equals emails of this scope, basically, by email later on, when we going to be trying to fetch the user using the following statement user, which is our class and then by email and now have a look at what happens here, I'm going to pass even, let's say in four SSD tutorials dot com. Ah, and then we just going to add to this first method to fetch dissident because up to this point we building a query and then wants to get it out of the database. So first would be the option for us if we only obviously wants to retrieve one user. And in this case, we will. Because obviously email field is the unique field. So you will only have one user with the given email within a database. So that's how you would call it. So when you creating them at the query scope, you use the scope than capital letter for the next word the capital, it for the first capital letter for the following and so on. And then when you call it, you remove this cope, you lower the face letter off first, let off the following word which in our case is by and then follow the same camel case as you've got for the rest of the method. So by email will be represented by the query scope methods sculpt by email. So that's how you would use a later. But we will get there any way we will use this method later on. So you will be able to see it basically, how it works. Okay, lets out some dog looks here. Eso it takes the builder as the first argument and by the way, is this. Obviously, I only passed their email because the square a bill that will automatically be injected to this method when it's executed. We don't have to pass it. We only passed the second argument and whatever other arguments we might be using. So going back one user by email, we passed our email address so in for, say, a sous de tutorials dot com. That's all we are passing through as an argument, which is going to be a second argument right after the square, a builder here on and obviously the eloquent will make sure that their argument, obviously this builder is injected apart from the all the arguments that we might be passing through to this to this method. Okay, s So that's our scope. Email A. Let's move next one. The next minute method we going to need is going to be another acquires cope. Ah, when we can obtain record by a token so public functions cope by token and we going to pass again Builder, eloquent builder query and we pass talking as the second argument and this song we're going to return query where token So Ken equals token, and that's quickly dog looks again. Token will be off a string type, and here we've for gotten for the email as well. It's going to be string and what we're going to have here. And let's just quickly click on this where Method, what it returns, returns this. And what is this? Actually scroll up to the top. This this is represented by the builders, so we can either either leave it as this. But this here doesn't really mean much to our user class or just simply put, builder. So builder is what we returning the eloquent builder. So let's change in here and for the same for this sculpt by email. So it's closes. Build a class as the deaths by token and someone is going to be get record by token. What do we put here? We didn't put anything for the email, so get record by email. Very fight password. We've got the summary that so that's fine. Okay, the next Another query scope will be by remember talking. So when we actually trying to refer to retrieve their user by the remember token public function scope by, remember, jokin and again billed as the 1st 1 this is the eloquent builder query and then, uh, talking again. And this time return query where remember dog can equals our token. Remember? There, there we go. Let's aren't the dog block again And he also returns. Build their this eloquent build there and the token is going to be of the string type and get record by Remember me talking and let's just scroll up because I want to make sure that you importing the correct classes he answer. We've got this illuminate database eloquent model, which is what we extending from within this. Use a glass and then this builder is the illuminate database. Eloquent, be builder, which is what we are injecting. And then what? We are returning as well. Okay, so we've got scope by remember token. Then another few helping methods. 1st 1 will be to reset the token. So whenever we're going to send them, let's say, with you reduced that just of the new user. And if we've decided to use their the activation process of the first, receive an email, they have to click on the link with an email and den deactivate the account. This is where this token is going to be reset. So public function reset talk, and this is going to happen when they register and before we send an email because this is a token that we're going to actually sent in this email appended to the U R L which they have to click. So we set token, we're going to set this token equals end the five Let's use here and this email and then this safe, which is going to save this stoke into the database, this new token and then we're going to return this token. So what we doing here? We generating the new token and we saving the records. So user will have this new token, which is basically their email run through the empty five methods to hush it. And we are going to return this soak in the same time with this reset a token method. So let's out some dog blocks, it will return string and it set so set and get reset. Dokan actually sets and get token rather resets token. Okay, so reset token and next method where the helper, which is going to help us later on, is going to be called is active to check whether the user is active so public function is active and we simply check return and I'm going Teoh typecast it to interject. Make sure that whatever I'm returning through there property this active is often indigent type. It will be. But I want to make sure that I can use actually the triple equal symbol for a check for equality data type as well, in this case, and equals one into Joe one. So is active will basically tennis whether the user has activated their account. So check if user has active account. Okay, so this is one of the methods. Next method will make the user active. So when they return from the activation process, the ones they've clicked on this activation email Ah, activation link. Within the email, they they will be redirected to the activation page, and dis method will be used to make their the record active. So public function make active and we're going to go for this active equals one. So we said this from zero, because by default it's going to be inactive, represented by integer zero. And when it's active, it will change to one. Then this token will set to know we no longer need this token and then this safe to make sure that all this data is safe to the database with the record. And then we return this so we can change it, Feather, if we need to. Okay. And Doug Block's returns This which is basically use it. Let's just keep it. It's this because now we refrain to the actual class that we are within and then activate user account. So as the next method Dan, another two methods that we're going to create one of them is going to be to update the password eso public function update password we pass password were through is an argument. And then this, First of all, active, we are going to automatically set to one. Why? Because this update password will be used with the reset password functionality. So first of all, the process starts when you seeing the forgot password form where you type in your email address. Once you've submitted this form, the email with the activation with basically with the link to the reset Passwords form will be sent to this email address. If you've clicked on this email address, you obviously receive this email and this intelligence is valid at this point whether the account was active or not. Let's make it active stray away because we know that obviously you've received email and this email is valued anyway. Okay, so this token, we're going to set to know and then this password because token will also be generated for update passwords because so that we can identify the record later on when we re setting it and pass what will be said to whatever password has been passed, there is an argument. And again, we are associating the string with the property password. But we know that behind the things we have this Ceta which will automatically make a harsh out of it So we don't have to worry about this and then this safe. So the record gets safe to the database and we return instance of itself this so that we can change feather if we need to. And again, let's other dog blocks it returns. This password will be off the string type and what it dance it Bicycle updates possible. So update pass word. So after update password, the next method will be to update remember tokens, public function update. Remember Dokan and this remember Remember, token equals harsh. And let's just do S h A our grid 256 And then we used this string eliminates class with the random just a random string and we hush It s a S h a to 56 Ahlgren again, and then we simply save it to the database safe. So whatever we've associated with this property will then be saved to the database. Okay? Again, we can return this if we want to change it. Any fed there and it's our dog blocks here returns this and update Remember me toe can and this method will be used when we see that the user who is trying to lock in has checked this. Remember me check box. At this point, we're going to generate this. Remember me talking, saving to the database and send it back as a cookie. So later on, we can identify him, but by this given talking, OK, so that's our user mother complete. It's. And in the next video, we're going to ride a set of tests to make sure that everything works the way Shoot 13. User under test (Part 1): in a previous video with Created Our User Model. In this video, we're going to ride a test to ensure everything works as expected. So under the unit director, we are going to creating new directory called Models, and this is where all our model related tests will be stored. We're going to start with a new PHP class called User Test, and it's going to be within the name space, up test and den mall. Sorry, unit first, and then models close all this, remove the space here and is going to extend base case the up test one. And because our user model interacts with the database, we may have to make sure that before each test, we have regenerated the table structure. And when I say regenerate is exactly what I mean, because we don't want to deal with the same data when you get from one test to the other, and we'll do it with help off the set up and tear down methods which are part off the PHP unit. Ah, framework test case. If we go here, you'll see we have this set up methods which is run, which is called before a test is executed and then we have tear down method, which is called after the test is executed. So before each death, the set up method will be run. And after each dance of the tear down with brown, what we going to do from within these methods is run our methods from within the migration . If we open the migration for set up, we're going to run up and full tiered. Now we going to run down. So before each test, we're going to have a fresh set off tables generated for us. And after each test, we're going to remove all of these tables. And that's going to be for each test within our that set now because we want to use it for this test specifically for this user test, it's probably a good idea to put into a trade because the same trait can then be transferred onto any other model that what we might be using that requires database interactions. So let's create within the test director. Let's create a new directory and call it traits and within the Strait director, what I'm going to do is create their new BHP class called Database, and it's going to be a trade rather than class trade within the name space up test because directly are actually not just up test. It's within the trades. Directors are up test, which is pointed to the test director and then trades for the trades director. Okay, so there we go. This is our name, space and the name off their trade database. Remember, it's a trade, not just a class. And now we're going to start with public function, my great database. And from here, I'm going to in line it rather associate the instance off the new migration with the variable. So new migration. We doubt the brackets because we don't need any constructive and we going to call method up . So all of the tables that are required will be migrated, will be created. And then for another methods public function, roll buck database, which will simply do the same new migration, but rather than up is going to call method down so all tables will be removed. Make sure you obviously import the migration up migration, migration, and let's out some dog blocks here. Ah, my great database before each test and then return void because we know, returning any value and then roll back migrations after each test and again return void. Now, how do we actually get these methods executed rather than actually using set up directly on this user test? What would be nice it to have it automatically executed, automatically called when we include the trade and we can do it. Let's just open our base case class now and from within the base place. What we are going to do is create the new, uh, protected, a function called set up, which overrides the parent one. So before we actually do anything from within the set up, let's just call parent set up to make sure that if there's anything within the parents set of method, it gets first executed and then we're going to check this. If class uses this this class referring to itself, database and trades and class, then this my great database. No, let me explain what happens here, so we check in. First of all, if dis class in our case, it's going to be user test uses database class, which is the straight because classes you basically world this class after them. Scope Resolution operator tells us returned the full path, including the name space to this class, which is going to buy security in all this. So if this class uses this trait, then run my great database because then you're gonna have access to this method, obviously using the straight. So when the given test uses this straight run to my great database when the set up method is executed, which is going to bicycle before each test, and then we're going to do the same protected function, tear down we over right in the pint one. So it's called Parent one first parent tear down and then we're going to check again the same thing if class uses this class referring to itself database class if it uses this trait than this role Bok data base. If it uses the straight, make sure that after the test you've called this method, which would roll back all the migrations and lets out some Doug Block's set up environmental before each test and it returns avoid and then, ah, tear down environ ment after each test and this one also returns nothing so avoid. Okay, so that should know work. Just find for our user tests all we need to do from within the user test in order to make sure that each test with then this class will have access to the data to the database tables our tables will be there for its ready to interact with is to use the straight so use data base. And that's all. And now I know that whichever test I'm going to write it will have set of tables ready for it to play with. Okay, so this is just set up. Now it's time to start actually creating our tests. We going to start with a private property called proper T's, and it's going to be over in a great time. And by default, we going to associate some data with the properties off the user class or, in other words, columns off the user stable. So, for active by default, I want to set it to zero, then name by default. I want to set it to my own Sebastian Selenski, then for email. I'm going to set it to info SSD tutorials Don't come Then for password, I'm going to set it secret den ful token are said it to know by default and remember Token will also be said to know by default. So these other properties which I'm going to use when I create the record and this will be the default ones. But we need the way off off over writing this if we need to override them from within our tests. So let's now start with the method which will create in return than you uses a public function make user, and we pass in array off. Let's call it items they still refer to the properties. But let's call it items by default is going to be an empty re, and what I do is return user create method on the user. Instance. Create method basically creates new method within the table off the on the given model instance, Let's import issues as well. So we're looking for the up models user So again DOT gets art it to the top here, and we created passing this items and then we passed this items argument through and let's have a look at what this items method will do. Its generate the stop for it, and at the dog looks to make user and what it returns, it will return not started, he will return user instance, and here we're going to say Create end return, new user instance and items bicycle. But it will dio and again I'm going to type painted here by default and empty array, I Thames will check. First of all, if this items raised empty. So if empty items then simply return whatever is associated with our properties property. So this properties, so default values that we defined here. Otherwise, what we want to do, you might be passing some items which you want to override. So what we're going to do is return array, underscore marriage, and then we pass this properties and then, we say, are the second argument, which is the items that have been sent. There is an argument which will overwrite any properties with the same name from the first array. So if we pass, let's say to this make user. We passed array off this. Let's say we're going to pass something like active equals one. Then this active will become one rather than zero. When we are emerging it, it will overwrite any existing properties within the properties array with the custom defined once, so let's other dog blocks here as well. To this items methods, it returns already. It takes in the ray and merge pro for peace. Okay, if we scroll down and now it's time to write our first test. So we're going to start with public function on we're going to start with. The one doubt verifies that we can create and fund and you use a record so can create and find new user record. And let's make it a test. As you can see, all these methods that we've created up until now don't have a test tax so they won't be executed assessed there, just stunned at helping if it's okay, So from within the steps, we going to start by creating the new user. And this is where this make use a method comes into play. So we start with this make user, but we will not pass any arguments, and we will not associated with any viable, Even though it returns the instance of user, you don't want to catch it. We don't want this because what I want to do is to make sure that I contest to find method on the user's well so user Now I create the user instance by calling user and then find method passing the idea of the record. Dia want to find this record by and find by default checks for the I D field. So I d with the value one in this case because obviously we have a new set of tables before this test generated using this set up method. That's why I know this is going to the first record when I called. This make user is going to be the first record, and it's definitely going to be off the of the I. D one. Okay, now let's start by. Doing items equals this items, and that's all we not passing anything through for this specific example. We don't want any anything over written because we haven't actually over written this one. We created the users, so the new user that's been generated that's been added to the database has all these properties. All this table column set to these values on the right. So now we've got these items and what I'd want to do this this, assert ik. Actually, before we start doing assert equals, let's the first make sure that we actually get the instance off the user. When we called this user find method, eso assert Instance off and we looking for user a class to return the full class name with the name space and then passed that user variable, which should now store this instance off the user. And if a dozen, then we go into it in the message user find did not return. Instance off user. Okay, we haven't used this Items array yet, but we will in just a moment if we're now run our tests of PHP unit tests, we go to unit models and user tests. We ran it. You'll see we get this air culture a member function connection. This is because we haven't said the database connection for our test yet. We using the migrations, but we don't actually have access to the database object. So let's quickly have a look at how we did it before, because we already have it set for their front. And so if we open the index of PHP, you'll see that we first generate creative content instance of the container. Then we bind, request and guard to it, and then we posit to the colonel and within the Karinna. What happens? We, first of all, associate that contained with a container property make sure that it's accessible statically by setting it's instance to itself. And then we run this database method, which is where we actually configure the database and boot and the eloquent s. So we need to do a similar things, a similar thing from within our base case so that later on we can use it with any test that actually requires database connection. So let's go back to our base case now. We could do it from within a set, but I think it would be a little bit excessive are trying to run it before each test. There is another methods available with the PHP Unit framework test case. If I just go there, it's called Set Up before Class, which means this one will be called before the first test off the given class. So we are going to use this method in order to set up the database connection. Let's just go buck before the set up method, I'm going to start public, and this one is a static methods or public static function called Set Up before class and from within this class, when I'm going to do is check if we've already created the database connection and I'm going to do it by using this static property protected one static container, and this is going to be an instance off the illuminate container contain It's a container illuminate container container. You can see that's no imported here. This line used lamented contact container. Let's scroll down and what we are going to do First, we're going to check if there's any value there isn't. Then this is where we going to actually said the database connection. So if exclamation mark static and in container Dan, we want to start with a static container equals new container. We dealt any brackets because we don't have any gun instructor arguments that we want to pass through dance static again, Container instance. Request the same way as we did before Rick Worst illuminate http request capture method which would return the instance off the request and then another instance that we want to bind, which is going to be guard, and this one will simply be from new guard. We obviously don't have any implementation of this class and we only have a class empty class so far. But we will work with this guard very soon. And then after this, we're going to and within the brackets, I don't want to instance she ate it. I don't want to associate with any viable, so I'm just going to in line it new Colonel on and I'm going to pass. This static container is argument because that's what this corner requires. So now we should have access to this database insects to do the eloquent. If we have a look it up here, you see exactly what we are using. I'm just moving this one here because from a separate package, we have this illuminate age to be request, which also has been important here off sell these trades and so on. OK, so that's our set up before class. Let's quickly out some dog blocks to it as well. And this method is called before the first test off the desk class is run and returns void . So rather in terms of return void, and that should now run our tests just fine. So if we go back to the terminal and now run the same test and then we go. We've got one test, one ascension. But now we can run it because we have instance off the eloquent already booted, and we can now interact with our models. Okay, so we can clearly close our base case. We know going to be making any more changes to this class we can close. Colonel, we can close index dot PHP. So this was the first assertion. So now that we know that this find method returns instance off the user now let's very find that we get what we actually said. This feels for that the table use a stable or user properties off the user object, in other words, So this assert equals fold their name e items name. This is what we passed through. So that's what we should get with a user. So user name. That's what we should have. If it doesn't have this valued, then we're going to say user create did not art record with the correct name. Let me just ah, show you what we doing here? Bicycle. We complain that obviously, this is what we passed through when we make this user, because when we make in the user. We fetched the I temps and items because we didn't pass any arguments. We didn't overwrite anything. Simply returned this array associate with the properties, property and name Here is bicycle Sebastian Selenski. Some just fetching this name item from this items which should return Sebastian Stravinsky and very find that this user name property basically is exactly what's on within this associated with this item off these items arrange. So let's quickly save it on again. Rana test and then we go to our stations. All fine, that's great. Next one, I'm going to duplicate this one. This time I'm going to verify email against email property. So use it created not our record with correct email address. If it was to fail back to the terminal Run it. Three Alsatians, all are passing. Looks like record has been other correctly with all these data. Then off the email, we have broken and then token. So it did not record with a correct token against save it. Test it for our sessions. All are passing Buck, let's now duplicated again. You can probably see that I've already missed the password. This is because past what is going to be very fighting a different way because obviously the password as a string is not going to march the harsh password. So we have to verify it a little bit differently. So talking after the token, we have remember dull Ken ah, against the remember token property with the correct remember token, Save it, run the test, and then we go five pulsations or fine. And now, after Remember, talk is when we're going to verify the password. So I'm going to, rather than having this assert equals this summer arm going to assert. True, because the method that I'm going to use will should return true bullion truffles. So this assert true and what I'm checking against its user verify a fi password I Thames and passed worth, which is basically password as string that has been sent to the create method in order to battle to save it as a harsh password. Okay, And if it doesn't work, then obviously user create did not art record with the correct correct boss wort. Okay, And in semi colons, let's now run it. And there we go. One test six s oceans, all of which are passing. So we all good. So we know that now our user model can art their records and obviously, then we can fetch it by its I. D. Okay, so that's all fine. But what I'm thinking, because I will be very fine, oldest with another method. It's probably worth to move all this cult starting from these items down to the password verification to its own method, and that's exactly what we're going to do. So let's just cut all this from within that can create and find new user records. And above this test, let's create the new method. And let's call it, for instance, verify users so public, actually not probably because we don't need to access it outside of this class. So let's make it private, private function, verify user, and it will take user instance as the first argument, and then it will take a ray off items by default. There it will be an empty ring, and I'm going to paste everything that I just count from the other methods. And what I will do here is by just by passed this items of rain case, we want to pass. Any custom dates are to this items method which is obviously when they're going to override the default values within the properties. Um Ah, property. Okay, lets ard it some summary here. So user array of attempts and den for summary verify user. So now what I'm going to do is go back to my method and from within this method, I will simply call it as this verify user past user as an argument and everything should work exactly same way. So if we go back to terminal, run it and then we go one test success sessions. But now next this I'm going to write, Ah, I will be able to use exactly same structure. But the only difference will be really is the way how I'm a fetching their user records. So let's go and create the second test. Public function gets user by email decided, which is where we testing this cope by email methods so fast and we start with the same thing as we did before. Also, this make user we not passing any data through then user equals user by email, and I'm going to use the email that we have within our properties here. The default one, which is going to be invited. De tutorials don't come. We can either type it by hand or we can use the property. So it's going to be this properties email. And then after this, we need to fetch this record because up to now we only have the the SQL statement with building the SQL statement. And now we need to say that we actually want to fetch it from a database. So 1st 1st record, Okay? And now we just do this verify user, and we pass this user to make sure that obviously, first of all, we obtain the instance of the record. Then that obviously this instance off the user, all these properties much what we actually we're expecting to have within the database because that's where you passed through his arguments. So let's save it and run the test. And there we go. We go to test 12 sessions. But as you can see now, rather than rewrite all this art in the same thing to another methods, we just call another method which has all the same test without basically duplicating all these ELISA sessions. Okay, so that's trying to get the user by email and let's ride the remaining test in the following video 14. User under test (Part 2): so the next test will verify that we can reset the token and then get the user by this token. So let's start with public function gets user by Tolkien and resets Token and make. Let's make it a test scroll up. We're going to start by creating and user some make use at this time. We passed the argument. We want token Toby over written. We don't want to talk in Toby. No, we wanted to be a B C and then we instance shaitan You use that by calling user by Tolkien and then we passed a be seeing this is it so can we want to use to get the user and again first methods to get the using thereby token again query scope If we go back to up model user, you may remember if we scroll up, we have scope. By token, we have scope by remember tokens of by colonised By remember talking this method is going to be executed and just by email we've already tested. Now we testing this Esko by token, which is going to others where close where token equals where every pastor is an argument. So now once we've got the instance of this user, We're going to first verify it. So verify user we pass user through isn't first argument and then obviously the token that we've overridden so talking, which will equal ABC doubts what it should be. So if we save it and run the test and then we go three tests, 18 0 stations. All of them are Parsons a command k on a keyboard to clear the screen. And now if we go back now that we know that we've been able to add the user winning Utah can, uh and we obviously have been able to get that user out of the database again. Now we get we do user reset token. So now this soaking should be changed. We going to get new user buys or uses equals again user find this time by I d. So, user, I d. I could obviously type in one here because we know that what we see, we only have one user because the tables have been recreated before this test. But that's just used the the the user and then I d property, which is obviously going to start the idea of this user So we over written this user variable having the new instance, which is the same the same user, obviously. But now it should be with this new token and now we're going to do it. This assert not equals to what we wakes having before so ABC and in user toe can. It should not be ABC now because we called this reset token, which should reset it to something different. That's where we check in A certain melt equals. And then if it does, then obviously something's wrong. So user set token did not reset the token. Okay, if we save it, run a test and we go. Three tests, 19 Alsatians. Everything seemed to be working. Fine. Great. OK, so that was this. Ah, we now know that we can reset the token and obviously find a user by the token. So the next method will be by the remember talking. So let's start with this public function gets user by. Remember, Dole can And again let's make it a test and we start with this Make user we pass, remember under skeletal can equals and let's make it 555 for instance. And then we get user equals user this time by remember dull Ken and we passed 555 his argument and then first. And then we get this verify user, we pass user instance and then the argument which is going to be this Remember, under skull token, which should equal 555 Okay, let's run it. And then we go for test 25 associations, all of which are passing. So we'll remember token by remember, token method works flying as well. The next test will verify that our is active and make active methods are working fine. So public function and we're going to call it identifies and makes user active and then test. Obviously you can call these methods however you want. This is just my understanding off the of actually the problem that I'm testing so user equals this make user again. This one is going to be with default data by default. We know that activists set to zero So this assert false when we run user is active and if it returns true, which it shouldn't, then obviously it would fell In which case we going to return The message user is active returned true with inactive user. So let's save it, run the test and then we go five test 26 a sessions, all of which are passing. Next I'm going to make it active. So user and then method make active. And at this point, we can now, because we could obviously use the same instance. But I want to verify that obviously it's been safe to the database because this make active could just change the property on the object but not save it. So I need to verify it. Obviously, that works as well. So, user, we go into creating year back, basically obtained the new instance of the user class a user find and again by ideas. So, user, I d using the previous instance off this user. So we know over writing it to the same user. But now we obviously fetched for a fresh record from a database this assert true, and we go for user is active. This summit should retain show. So if it doesn't, then we're gonna type something like user is active, returned false with active user. Okay, let's save it, Run it And we have five test 27 assertions and again all of them are passing. So it's all goods. I think dot that does it for now, when it comes to is active and make active methods. So the next method will verify that we can actually update a password. So public function updates password and let's make it a test again. And we're going to start with making a new user by safeguarding user to the database same ways before again with default data, we're going to start with user equals user. Find the 1st 1 We could also obviously use user equals and den Just use use their i d. Either way, it's gonna be fine, because again, we start with a fresh table. So there is no records that at all we had in the first record, obviously it's going to have I d one. Okay, so what we want to do, he eyes first, very fighter. The password is what it should be and what it should be when we create in the when you're using make is without passing any argument that should be said to secret if we scroll right to the top secret is waltz default password associate with the properties array. So let's try this and this Assert true. Then we're going to start with user Ah, verify Password should be secret. And obviously it's going to check against their The harsh boss would start within the database. And if it doesn't work, then obviously user create did not our record with the correct hushed boss wort. But we save it and let's run this test and then we go. Six tests. 28 Alsatians said that seem to be working Fine. So the password has been harsh and then we when we very fight obviously it verify dogs this string much is it? Okay, then we're going to start user update password. We want to change it to, say password. You can obviously use whatever you want and again we're going to start user, We fetch the new instance user find by user by D and then we're gonna go This assert true user were no very fine password again. But this time it should be passed Worth obviously is going to be hushed again, but it should verify it against this string password. If it doesn't in user update Password did not update that pass word. Let's save it. Run it And there you go 29 Alsatians, all of which are passing Buck to the editor. I think that concludes the thing. We know thou that we can obviously verify the password and then we can update the password , which also works when we very fine this again, that's all fine. The next methods will check and that we can actually update the remember token. So public function updates remember Duncan and Doc test. And now we're going to do Is this make use again with default data, then user equals user, find 10 again, we can do the same as we did before. Let's associate this output of the make user method with the user and then is just use the property idea on this user. So, user i d so get used by deciding. And so we over writing bicycle walk. This will make you sir returned by getting a fresh user from the database. Okay? And this this assert no user remember talking because by default dots being said to know within our array associate with properties property And if it's not northern, obviously there's something right user create did not art record with the remember talk and said to know Let's save it, run it and we go seven test 30 Alsatians, all of which are passing. That's great. Next, we're going to run this update, Remember? Token methods. So user update, remember, Dull Ken. And after this, we're going to fetch new User to make sure that we get the fresh copy user. Ah, find Use it by user. I d. And now we're going to verify same thing. I'm just going to time this, Assert not no this time, User. Remember, on the sculpt token And if it obviously is? No. Then that would indicate update. Remember, talking method didn't work. So user update, remember, Token did not update the Remember Duncan. Let's save it, Run it! And there we go. Everything passes. So that sits in this video. We have No, I'm just going to remove this space is here. We've now tested our user model, so we are now ready to start working on the way guard class 15. Guard class: in the previous video with Created the user model. And then we've written the tests to make sure that obviously they're using model works as expected. Now, in this video, we're going to start working on the guard class. Now, Guard Class is going to be used to authenticate the user to lock the user in a log mouth, save the remember me token and so on. So everything that's to do with the authentication is going to be stored within this guard class. We're going to start with going so up. Then we're going to go to utilities, and we've got already our guard class here. Now, one thing that we need to start with Ace to create two constants. First constant will be called session name, and it will contain a string which is basically going to ah, define what name our session will have. And I'm going to set it to simply off. And then we're going to have another constant called Remember me. And this is going to be the name of the cookie that will store the remember me talking. Okay, we can handsome duck books here. Uh, far that string. This one is also string after the so Kens. We're going to start with a method that checks whether the user is off indicated so public function and we're going to call it is authenticated and we started the session variable equals and then we use session manager that we've written earlier than method get. And we are going to look for the session with the name associated with this session named Constants Yourself and then session name. Next thing we're going to do, we're going to check if empty, empty this session, meaning that obviously recession hasn't been set, it's not available. In that case, we're going to return this and the Method week, which will create in just a moment eyes going to be called ISS re Ma'am Bert. So if we don't have a session, check, if we have remember me token. So then we can find a user by this token argument. And let me just greet the few new lines. And after this we know the obviously there is a session, at which point we simply return hush with the method verify, because we're going to start this session. The idea of the user end in the harsh version off this idea as well. So we're going to verified session I d and then session hush just to make sure that they obviously much OK, so that's our is authenticated method. That's just not something Blocks here is going to return. Bully intro Fallston. Check if user is logged in. Okay, The next method we're going to be working on is this is remembered. So if we aren't this method and we're going to start with if and Denver exclamation mark variable token, we're going to create and then straight were associated with this. Remember, talk and method which will get asked there the talk in the valley associated with the talking If it's it basically, if we cannot find us, remember me talking what is going to be start within the cookie, then we return false. Now, if you're not familiar with this statement, he have This statement isn't quite clear. Basically, we have the exclamation mark, a busy checking for negative output on and then we at the same time as we are checking using this remember token method we associate in the value returned from this method to within this variable. So we later on we can actually use it if this fails. Eso Let's quickly on this. Remember talking before we actually continue with this method And remember, token will simply return. And we use this cookie manager this sign get method as well Self And then remember me Constant. So we're looking for the cookie with this were ever stored within this constant in our case is going to be Remember me string So that's going to return it. If it can find the cookie with this name, then obviously this is going to evaluates to True, at which point we're going to return False. Because if we get to this point to call this method, we know it that the session is empty. So there was no session off the logged in user on. Obviously, if there was no session than the last thing that we can check, it's for this. Remember me talking, which is what we do. And if that fails, then obviously there was definitely no no session set for for the user at all. Okay, so let's continue with our is remembered method after we've checked on. Obviously, if we get the point that we after this if condition that means that that was the talking has been found. So we're going to set this health and dedicated equals user by remember token. And we passed this stock and through and let's said this authenticated property I'm going to make it public so we can access it from outside of this class and that's going to store the instance off there. Use them, although, and obviously make sure that you import this user model here. Also Cookie and session manager eso we are basically trying to find a user. By this token, we have this sculpt by remember token on the user class. If we just open this, let's check for these copes here. So we have skull by talking. We have scope by Remember talking. This is where we using this by remember talking. So we are trying to find a user by token. But after this remember, by token method, we also need to call first methods to get the first record That much is this talking? Okay, so now we check if IHS no this off indicated then obviously user by the Stoke and could not be found in at which point we going to return false. And then if the user has been found, what we going to job is to lock in this users. So this logging And then we passed this off indicated, and then we return True to indicate, obviously the the is authenticated returns bullion. Okay, we don't have this logging method. So let's quickly Aren't this method as well now logging methods? If we just, um, type hint this argument here by user and then the the last argument because we're going to add another argument here, which is going to be remember, set to falls by default. So when we actually call it here from within, this is remembered, we didn't pass it through by default is going to be false eso here and we need to make this method probably cause we might want to use it outside of this class as well. So we helped have this authenticated using rather than authenticate. I'm going to just simply call it user as an argument here to logging method. We're going to start with session manager and we're going to use the set method self and then session name, which is going to be the name of the session that we trying to set now and then array. The first item will be i d. And it's going to be user I d. And then harsh, which is going to be harsh make and then user I d as well this is why If I just scroll up here, you can see we are very fine. Their session i d against session harsh. And this verify method would tell us whether the string marches the harsh version of the same string. Okay, so that's and the session that's going to be set when we look in, so that later on, when we get to next page, we know that this session set and the log in the obviously the user is logged in and then we check if I remember. If it's set to true, then we also you static. This time method called set re men better, and we're going to pass user as argument. Let's quickly aren't this set remember method as well, and it's going to be part of a private start. IQ functions is going to move it down right to the bottom because some stranger and just went up to the top of the class. So we have this logging and then set, remember, user bread side hint it with the user claws. There we go. And TL were we going to do is first of all, user, we going to call method update, remember, token And let's quickly have a look at what this method does. So just to remind ourselves it says they remember token on this instance off the user class to this harsh Maskell using this algorithm S h a to 56 some random string and then saves it to the database of STD's remember token will be regenerated if if it was already said to something and then it returns instance of itself. So user of date, remember token. And then we're going to use cookie manager set and see nothing as we did with that session . We start with a constant self, and we have this constant of remember me and then user remember, uh, token. We said the basically it's cookie called Remember me to this talking which have just saved with this user and then date when we want this to expire, I'm going to use carbon here package and then now, which is current date and then we want toe odd year to it because we want this cookie to expire in a year time and then time stump property. This is going to return the correct date that we want this cookie to expect him. OK, so that's our set. Remember, private static function and let's just Cole, it's set. Remember token. And so we are going back to the logging dislodging that is also completed now. So we can at some dark blocks and all Thin dick eight use. Actually, it's no authenticate logged in user lock in user log, user in flunky user in I think that sounds a little bit better. Okay, Another method that we needs to have and I'm going to add it right after this. Remember soaking and actually just remember talking. Need some dog brooks as well. So returns either string or no. If there's no cookie with this name, get Remember me Tolkien. Let's just check it. We've got no, we haven't got forties. Remember, we have in God's Dr Oxide there is going to return bullion, so check if user has a cookie set to keep de profile log in order to keep him logged in him her locked in. And I think that's going to do for this one. Do we have authenticated? Yes, we've got. So after this, remember talking. We need to provide the means for us to be able to forget the token as well. So private function. Forget don't kin. And it's going to be cookie. Kooky manager remove. We don't return anything that is going to be void function self. And we use this same constant. Remember me? So this one will be able to remove this cookie. And obviously, the session, if it was relying on a cookie, will also expire. Okay, Uh, remove. Remember me talkin and return. Voight doesn't return any value. Okay, so forgets tolkien after this. If I scroll down Logan, we have set remember method. We also need the method to which will allow us to log out. So let's provide. Smith is going to be public method log outs and then session manager. Are we going to sir comment at the rim move and itself and session name. So this is the session that we wants to remove. And then we will also call this method which which which we've just created this. Forget talking and let's not some dog books as well. We start with Log Out, user and then return void doesn't return any value. Haida. Okay, next methods will get us the authenticated user. Instance. So public function user and we check if exclamation mark this is off indicated. Obviously we check in if it's not authenticated because we have this exclamation mark proceeding this cold, this method, then we return. No. If it was all off indicating that we returned and again another static method which will create in just a second, it's going to be called Get user. Let's quickly on this method. But before we do this and against for some strangers and aesthetic methods are going right to the top of the class A. Let's just aren't the dog blocks to this user method. It returns no, all it returns instance of the user. And then we get instance off the authenticated user. And now here from within. This gets use a method. We're going to check if session manager Hess and then self session name. If the session with this name exists den return user find. And now the idea that we need is going to be stored within the session manager get and then against self session name that this is going to give us death session. But this session, obviously out, is often ray time because it's go I d and hush. And we need to get just the i d. So I d after this gift method. Okay, so this is going to return the user on Lee when we have this session. So when the user has locked in and a session is active, otherwise we return this authenticated property. Why do we return it? Actually, this shouldn't be static here. It should be just a normal meth, not static. This get users. Sorry, because obviously wouldn't be able to call this if it was a static method. Okay, so why do we return? Volley? Associate it with this property Now have a look. At what? How how we went through it, starting from this user method. So first we checked is authenticated. And one what happens with this is authenticated method. If we scroll up is authenticated checks with the recession exists. If it doesn't, it calls. This is remembered method. And now this is remembered methods. If the talking doesn't exist in stray, where returns fold. But if it does exist, then it gets user instance and associates it with this authenticated property. This is when we could potentially have the user instance associated with this authenticated . That's why if we don't have a session, then we return value associated with this property. Okay, so let's quickly out some dog looks here. It returns user and get user instance by session. Or remember me talkin and I think that sit within this class, Let me just quickly check off. We haven't missed anything, Log out said. Remember logging for guilt token? Ah, yet everything seems fine. So let's move to the next video when we are writing a test for this guard class. 16. Guard under test: So in a previous video, we've created this guard class, and in this video we're going to write tests for it. So under the test unit utilities, let's create the new class Cold Guard test task that we go and the name space is going to be up test unit utilities. And let's extend base case this up test this one here and the first thing we going to do issues the trade database because we're going to be interacting with the database when we using the user class and then protected function set up. Let's first called parents set up. And then we're going to start this session session manager start so that we know that each test has recession available to it. Okay, And I'm going to create a few new allies to shift it up a little bits, and we're going to start. The first public function is oh, thin. Take a Ted Ah! Returns falls without authenticated user. This is authenticated methods. Maybe you should just say it's authenticating. Method returns false without authenticated user. Okay, and let's make it a test. So lets out this test stock and what we're going to do. He has this assert false and we're going to use part and container then make method on this container. We're looking for the guard, and then Cole Method is all thin, dedicated. And if it fails, then Gert is authenticated. Returned true without user being authenticated. Okay, let me just go through this line because I know it may be a little bit confusing if we open our base case, which disclose obviously extends. So if I just get them, you'll see we have this container property you may remember from the previous videos from within this set up before class, which is run within each class once before there any of the tests? A we check whether this static container has any value associated with it. With this exclamation mark, we checking for the opposite. If it's not, then obviously that would indicate that we haven't set it's to anything yet. So we set in this container to the new content to the instance of the new container. Then we bind to, um, items to this container. The request which is basically insist off the illuminated request and then instance off the guards which is instance off this guard class which would just create it. And then we don't Karen l obviously and passed this container through. So what we doing here? We get this container, and in order to get back what we bound to the container, we need to use this make method. And then ah passed through the argument off the item that we want to pull out of the container and in this case, is this guard. So there's basically going to be the instance off this guard class and on this guard class , Then we call this is authenticated because obviously, this is one of the methods of go back to the guards which have created in the previous video. So this method on this specific class instance is being called here when we calling this parent container make guard and then is authenticated. So let's ah, give it a try. Let's see if it's passing So buck to the terminal. Make sure that you're in the correct directors. Will P W. D. I'm in a cold logging, which is where I should be. And now PHP units and I'm going to run just this test. So tests, then units at then Utd T's and guard test and we go. We've got some problem here. OK? Tells me Dad's called toe Undefined methods session manager start. Let's just quickly go back here. We've imported session manager, but we don't seem to have the session start method. Um, well, of course, because I've imported the wrong session. Manager illuminates session Package also contains the session manager class, so that's not the one that we actually want. Let's just import the correct one, Which is this up Utilities session session manager. The one that we've created? Actually, no there one that comes with the limited package. So if you run this test again, let's clear the screen commands K on the keyboard and there we go. We've got one test wanna station and it passes. So obviously this is authenticated Method returned False, which it should, because we didn't indicate any. Use it. So what we're going to do next from within another method. Let's create a new test. Public function logs user in and is all thin dick aided method returns true. So this time we're going to lock the user in and then run the same methods which this time should return true. So again, let's make it a test and we're going to start with user equals and then user create. Let's pass in the ray off items here and let's import this user class and it's going to be up models user. So that should be at it right here at the top and full The name we going to say Bastion Selenski fall the email we going to say in four s's deaky torrey else that come and for the password would just say secrets. And now what we going to do? Sparkle parent again? Container Make a guard. So again, at this point, we have instance off the guard class pulled out out of the container, and now we call logging method to lock this user in. We pass user instance as an argument, so that should log in the user. And now when we run this assert true in this case, and let me just call the same thing that we had here because that's exactly same thing that we need. So he called this parent containing make guard is authenticated this time should return show otherwise we're going to say guard is all thin indicated returned fulls with authenticated user Okay. I hope that makes sense. Let's now go back to the terminal. Ron noticed again. And there we go. We go too tense to assertions, all of which are passing. So what we've managed Teoh proof here is that when we log in the user, then is authenticated returns. True. When we don't look in the user, it all then is authenticators will return falls, which is exactly how we want it. Okay, so the next test next test Well, get us the instance off the user after we've locked the user in so public function returns user instance off there, log in and then test sock and we're going to start user equals. Actually, you know what? Why am I going to be typing the same thing over and over again? Let's just copy what we've got here, including this logging method. Cold to this methods. Today we go, we've got this user, and then we're going to go for the guard equals pi Arent. Then we called container make guard again. And on this instance of a guard, we going to call you a method user which should return instance off the user. So rather than calling every user which would override this previous variable. Recall it Gardner, which also obviously represents instance of a user. And now we're going to do this, assert equals and we're going to pass through to erase. We're going to compare them to get a so basically properties off the user instance before we lock the user in and after we lock the user when we actually fetch the same user, basically for through the guard user method. So we're going to stop user I d. Then user name down. We have user email and then we have user password. This should march guard I d. Guard name, guard email and guard password. So these should be exactly to exactly same race, because these values should be exactly saying, because that she's supposed to be the same user after the locking. Okay, so what we going to do before we actually tested lets out the message in case it fails? Guard user does not return Correct user user instance. Okay, let's save its and test it. There we go. And we got three tests. Three Alsatians, which means they're all passing great. So the next methods and the last test off this class is going to check whether the user has been locked out. So public function Lookout logs user out, and it's making it test again and scroll up so we can actually see what we doing. And we start again with same thing. So let's just copy this stuff. So user, and then we log user in Let's paste it here. We could probably extracted to another method, but let's just keep it here. It's only three methods for that Use it than this, assert true and again parents container make guards and then is authenticated just to make sure that we definitely ah, log then although we've checked this with tested for it already. But before we actually run the following decision, I want to make sure that, yes, we definitely have the instance of the use of that. Okay, guards logging did not log user in if in case it felt so let's just test this first. So there we go and we go full test for assertions. Now we're going to up another session after we've called log out methods. So parent container make guard and on this guard instance, we want to call method log out. And no, if I copy this previous a session, but this summer, other than sure it's going to be false. That's what we expecting and message will say. A log. Let's just call this God log out. They did not log user out. So first of all, we'll be doing creating the user. Then we loved this user in, at which point this is authenticated should return true. Then we love the user out and obviously the assertion. Then we're setting that it's going to be false when we call is authenticated, because that's what it should return after we've locked these out. Okay, let's save it and test it and we should have it. And there we go. We've got full test and five stations, all of which are passing. Which tells us that our Gert class is acting the way we wanted it to. Okay, I think that's it for this video. We've covitz, our guard class and its associated test, so let's move to the next one 17. Validator: So we are now ready. Teoh. Create our validation component. So under the utilities up utilities, we're going to create the new directory called Volley Data. And inside of this valley, they took director regard to create another class called Var the data back to the same name . And then let's give it a name, Space up, utilities and then it's going to be volley data. There we go. Okay, so that's our Valley data. We going to start the Prophet property Cold rules by default. AIDS. Actually, let's not associate anything with it by default. It's going to be an instance off the collection, and it's going to be illuminate support collection and let me just quickly show you we can read a little bit more about these collections. So if you go to a lot of elders, come then. If I click on documentation and scroll on the left inside you have collection, click this link that's going to take you to this collection speech, and you can read the introduction for the class provides a fluent, convenient rapid for working with a raise of data. For example, check out there following cold will use collect help in this case, but when you're using, this is a package outside of a lot of you. Simply use new collection class, then to create new collection instance from the array. And then we can obviously run anything we want from within this helping methods that are on this collection. So we've got much, for instance, which, in using the traditional PHP approach, you would probably use a Rehm up A. But it's got plenty off this really nice methods. Here. You can you can work with the erased in the way that you've never seen before. I sic. Okay, so this is the collection read a little bit more if you want. So I'm going back to the editor and we're going to continue with our Valley data class private input, and then we're going to have this as a collection as well. So collection illuminates support collection to make sure that you obviously important this package here. So we've got limited support collection and then we have public errors, and that's going to be just a standard array. There we go. Okay, let's create funeral lines here and after these errors, we going to start the constructor and constructor will take rules and inputs and associate them with our properties as we got here. So basically takes this collection rules and collection in port and associates them with our properties. Okay, After the constructor, we're going to have the method that checks where the our request is valid. So public function is valid and we start with if this rules is empty and this is empty method because we calling this rules on this collection instance is empty method. If we go back to the collections, let's check for is empty here. If we he's empty. There we go. I'm going to open. This is the new top. What it does, basically is empty. Method returns to effective the collections empty. Otherwise, returns are false. Pre kind off, self explanatory, if you ask me. OK, so if there are no items within this collection, then we return true because it's going to be violated. Their obviously no items mean there's something not right. Otherwise, this rules and we go into coal method each on it, which is going to do something similar. What for? Each lope would do. And then we're going to delegate the coal to a specific method within our class too executes the validation, basically, and we going to start with this within the array to indicate which class we wants to use, which is ourselves, by sickly this validation by the data class Indyk Using this this pseudo variable And then what method on this classic on to use, it's going to be volley date method. So each of the items within this collection it's going to be a ray pass to this collection class should go to the validation of this valley date methods and then we check return empty. This errors, if errors are empty then is valid. Wilder. It's and true. If there are some errors within this errors array, then it's going to return. False, obviously. Okay, lets out some Douglas here it will return bullion and then we go into art. Some summary validate in boat. Okay, so lets out this validate method. It needs to be public because for because Because we using these methods here in order for its method to be able for us to be able to access this methods from within his methods, we obviously need to make them public so public function, validate, then we pass rules and key as an argument because with each what happens, we are going to get basically their value and the key off each item within this collection , which is basically like an array Barbie. See, it's an object eso is going to pass value as the first argument and the key as the second. So now we're going to check if empty rules because that might also happen. Then we simply return nothing. In other words, we going to go to the next iteration and then we go for rules equals new collection. We creating new collection now. But what we're going to do is basically explode these rules because thes rules later on, you'll see we can have multiple rules pair given input, and we're going to explode them using their this vertical bar, Hector, and then rules as the second argument. So I think that's going to create, say, with these rules, start something like required, for instance, and then email. So obviously we split them. We're using this vertical bar, so we're going to have to items within this collection required an email, and now we're going to do the same as we did with the rules in the first place, We're going to go. I used this Each method on on this collection so rules, then each methods. And this time we're just going to use the closure with rule as an argument and then you statements so that we can actually parse very able name to this closure. And it's going to be the key which has been passed, arisen argument. And I'm going to go through this through all this in just a second. Eso We can actually have a clear understanding what's happening here and then from within this each, um, closure here we going to do this, evaluate rule rule and then the key as the second argument, and let me actually do this evaluate, rule, and then I'm going to go through this Valley day Exactly. Starting with is valid method, so everything is gonna be a little bit clear. Okay, so this evaluated rule is going to be a private function value eight rule, and it's going to take rule and then key. And here we're going to check para meters first, do by default. We said it to know, and then we're going to get the class name equals explodes by colon and den rule. Then we're going to do this. Check if count class name is more than one, then this would indicate that we obviously had this Cullen. And on each side, there was some value and parameters will equal class Name one. Then we're gonna go for class. Name equals dis Valley, data class, class name and index zero. And then if exclamation mark and I'm going to in line it new class, class name and in between brackets, we're going to go for this inputs, then key and then party meters and validate method on this volley date. Then this errors we pass key. And because there might be more than one error forgiven key, we going to upend another set of bracket the square brackets and then rule which felt okay , lets out this validator class, and that's going to be simply a rule brother than I NT is going to be rule. And here we're going to return name space because we basically creating the name of the class with the name space or existing name space. And then we are rules. And then we're going to concatenation with a string. I think it's a factory which is going to be the string. Convert a factory on their score to class, name and then rule s argument. Okay, let's go through all these methods right from its up. So is valid. First of all, we check if the rules and imagine these rules, even though it's an instance of a class, it is going to be represented when we actually passed this rules through the constructed of this class is going to be something like this. Let's say name equals required and say minimum to ha rictus or something like this all. It's an email, for instance, if it was that if he was there email field. So we have name off their input field from the form, and then what validation rules we want to associate with it. It cannot be empty when it's required, and it also has to validate. It has to have a valid email format, for instance, and all these rules would be separated by this vertical lines so you can have multiple wants per in given import. So let's actually keep this year so we can reference all these items were as we going through through it. So here we obviously know that there are no rules. It's also validation returns. True means everything's fine because we didn't really require anything any off. These items that have been submitted through the form have been required. They may all be empty, for instance, so that there's no validation that needs to be done on them. Okay, so after this, we are looking through each of the items. So first, we will go, For instance, For through this first item, which will be email, the key is going to be email, and then we have two validation rules here. So when we passing this to this validate method here, what we get and I'm just going to cut it so we can actually I constantly see it on the screen. Okay, so here we get key is going to be this email and then rules is going to be the string here , so required then this pipe and email. So we check in if empty rules which would indicate that this email didn't have anything associate it, then we'd return without any value. Which means that from here we're going to go to the next iteration within this each other. If there was another item in disarray Dots, that's what would start evaluating. OK, but obviously, no me, you would. If you add anything to this record, this rules array, then you obviously would have something appreciated on the right hand side of this key. Okay, so here what we do next week, take these rules, which, in our case, we are looking at this stringy. And these two items separated with this vertical line and we exploding at them using this vertical line, creating an array. So now, at this point, and this area is automatically I passed through a zone argument to this collection. So we going to have another instance of the collection so it can use all these nice methods on it. So if he out, basically this explode will generate something like this required and then email. So what happens now? We are going through each of these items again. So first one's going to be email for the first iteration. Then we go. So the 1st 1 is going to be required. Then we're going to go through email and to make sure that we have access to actually the key The input name we passed use. We use this use keyword here with disclosure to pass it through to this to each off this iteration it Aeration. So So what we're going to have here when we passing this it when we running this evaluator , we passing in the first instance. When the first iteration goes through, we're going to have required as this role and email as this key. So this is what's happening next. Let me just again copy all this to the next line here, And this one is what we're dealing here with. As Wells, I'll just type of the Okay. So evaluate rule. We have this required as rule email is key perimeters by default? No. Then we exploding their rule because some of these rules may have something like this. Was this email? If we were to check a exists as well on table, for instance, users, you could do something like this. Ah, At this point, we obviously would be able to divide this given rule with this column because we can check if the email exists on the table users there many ways. We can obviously do the validation, but this is how it works. It's very similar way that actually lot of l does it. So we are exploding this. If there's only if one of these items obviously has any column. So discount class name here, Woods evaluated to fall, so wouldn't be more than one item. So perimeters would only be basically this the name off their off there also would be required. So then we overwrite in this passing the argument zero, which is going to be still required to this validator class so required is now passed through this validator class. So we creating the name of the class name space, which is going to point toe up utilities validator den rules. We can actually straightaway create this directory because this is where the rules are going to be. Start roll classes basically rules. And within this director, we're going to have a class with the given name. So it's going to be required with a capital letter at the beginning. So it's going to be something like re required dot PHP does going to be the file. So obviously required class is going to represent the required role and this factory underscored to class if there were any underscore city. Sometimes thes rules may have underscored as well and so required once or something like this. Then obviously that would confidence underscores and convert this type off entry to for something like required once as the name of the class. But obviously, that's not what we going to have here because we have required and email. So we passing their role as an argument of this required would goes an argument, and this whole string would return. Something like this is very data cracked. Glass would return something like this name space up, then would have utilities. Then we would have volley data then would have rules and required that will be the full name off the class, together with the name space. That's what This method with return fold. It's first iteration when we have run through the required for email would just be email with a capital E at the beginning, obviously, with the name space as well. Okay, So, uh, here we have the full class name, which would be dis required with the name space. And then we check exclamation mark class names so that we instance she ate in this class. We passing the import and inputs. If we scroll up, There we go. This is the input. So is this second argument second collection These girls is the first argument. Then we give the key. In our case it would be email and then para meters which would either be no Ato beginning here we associate know where this argument with us or with this variable all if we had any colon and then any values after this for a given rule, it would return the string wherever we have after the council. Let's just say we have required exists and then users. So what would be passed through as this perimeters? Obviously, in that case, we would have modern one item with this within this class name after exploding it with this column. So this he exists Colon SRE comma user would be passed through as the third argument here. But obviously that's not the case. We only have a single string without any columns here. So that's that's this Parliament is definitely going to be no for for this specific scenario. Obviously they my be different rules passed through to this class. Okay, so let's remove old is redundant code here, basically these examples and it's out some dog Brookstone methods. So I'm going to start with the validate method. Validate Method will have rules which are going to be off a string type, and the key is also going to be a string. And then what is going to say Values volley date in Port Item validates input. Yeah, let's keep it like this. I think that makes sense. Okay, And then, for the evaluator rule, we are going to have a rule against string and then the key off the string type as well. And it's going to return anything that it doesn't return anything. So a value eight validation rule. And then we go into the validator class Valley data class. We are going to aren't rule, which is going to be of a string type return string and get class name with name space. And let's just remove this these redundant lines here as well save the file. We cannot close it because complete it's And in the next video we are going to create these different validation rules 18. Validator rules: another hour. Validator classes ready. It's time to right some rules that this Valley data will use later on to validate Given rose off the on the import. Okay, so inside of the Rules directory, let's create their abstract class called Room, which is going to be acting as a point class for all rules for the value data, and this one is going to be within the name Space up. Then we have Utd t's. Then we have volley datum and rules, okay, and let's just remove the spaces and then obstruct obstruct rule. And we're going to start with the protected input, which is going to be the instance off the collection again. And it's illuminates support collection, so make sure they imported here at the top as well. Down we have protected key, which is going to be of a string type. And after the key, we have protected para Mi authors, and that's going to be also off. They're actually this one is going to be no all a collection, and let's just create again guns. Great. If in your lines so we can see things better, let's create a constructor and constructor will take all three of these end associating with our properties. Now the collection is the 1st 1 key and perimeters. And if we go open our validate of his girl right to the bottom, you may remember, here we instance, she ating This class is given role and then we call validate method on it. So we passing this input which has been passed through to this folly, dates or class as the second argument, We then associating this with them input property, which is obviously off the collection type than the key in our case and might be any off the field names off the form and then perimeters, which might be either no or anything. That's bean after the column for a given rural. Okay, so this is what we passing here. We associated this with our properties and then next methods are we going to have is going to be called Bob Asai Private function process, par round meters, and we're going to take power meters through us by default, normal, and actually here we not associating anything yet. We're going to actually make call to this process parameters and pass parameters as argument because from within this process parameters is when we actually going to associate them with this property. So what we going to start with this check? If is no para meters, then all we need to do is simply return. And that's this method done. Nothing else is going to be executed. If it isn't no. Then we going to do this para meters equals and we start with a new collection on this support collection. Illuminate support collection and we pass their explode function to it. We divide all these parameters with comma because thes perimeters after, let's say again, let's have a look at what we might have there. So let's say required Sorry, not like this not required. It will be, for instance, exists. And then we have this colon and then we have within the table say users and then all these additional items would be separated by commas. So, for instance, I d something and so on. So this is where we exploding this part which has been passed the rest perimeters with discover. So we generate in the array by six. So let's forget about this exist for now. So now we would have an array off a users and I d fines is users and I d That's what would happen after we exploded with this common and we obviously generating the new collection because off this as passing this whatever this explode is going to output and then parliament as the second argument. This explode obviously, because we need this string, which we're going to explode with this comma. And after this, what we going to do is call them up method, which ah, was going to use the trim function for all of these items. So basically, each item within disparate meter string once it's converted to in the race. So let's say we're going to have a re off something say users than I d. We want to make sure that each of these parameters is strained because they might be some space as well. Me, my might have have the my pipe Half had a string like users, for instance. Then comma end space I d. So we need to make sure that to this space is at a more because otherwise we're going to have this item in the air A with the space as well. So each of these items were trimming using the trim function, using this basically mop methods on this collection. And again, I'm in lining here rather than doing this as, for instance, creating the very able than associating new collection some in nine everything. But we could also do it this way, for instance, and it's just perhaps, if we do it this way is going to be a lot easier to understand. So we have, say, par meter equals now, exploding them first. So you basically over right in the string with the array now on and then create new collection. So will be collection equals new collection, and we passed this para meters through as an argument. And then on this collections on this collection, we run this mutt method and we say that we want to use the standard beach between function to remove any any basically white Spain's spaces from the beginning and the end of the string. And then we associated with that primates. I think this makes it a little bit clear here. Okay, Eso That's anything. Everything from within the pyre process parameters. So let's aren't there, doc block to this same method as well Out returns parameters no or it might also be a string and then pro cess Barra meters for the summary. Okay, on. And the last thing we need to do is to declare abstract function called validate because, as you may remember, we are calling this validate method on this new instance. Off this role class, obviously role class will be one of those that subclass is that actually extend this main obstruct rule class. So abstract public function validates, and this is a contract that every child needs to adhere to. So they have to have this method within them. And it's going to return bullion true or false, because it's just basically going to evaluate, given condition to make sure that the value associate with the given failed by representing the given role is valid. So validate input for the summary. And let's remove this redundant space again. We can save it, and we can close this fight for now. Next, we're going to create a common for, and we're going to start with confirmed role confirmed. So things like, for instance, when we have a we have a password for the registration, especially when you have a password, you have to also have another film confirmed prospect for us that this is This is where we going to compare with two input values are the same confirmed extends rule And obviously make sure that we are in the correct name Spaces up utilities, validator role sentence to be obviously within this director here as well. And we have this red line because we haven't got this contract implemented yet. So now we've other this public function validates and its value that method we here, we're going to start with confirmation equals this key and then concatenation with underscore confirmation. So let me just explain what this does. If we had, say password field in our form, then we would also have to have passed word confirmation field because this confirmed method eso discomfort class role will ensure that we also have this other field. When we associate is confirmed rule with the password field, Dace confirmed rule will check whether there is a password confirmation filled and and obviously if the values of both are marching So here we're going to return any between the brackets because we're going to have more than one statement this import and we are looking for a bicycle. First we need to check if has the item called confirmation vote? Basically, in our case, whatever this key is going to reprint because it doesn't have to be password in my beef. For instance, email, email, confirmation and so on. So whatever this string here returns combine basically a key combined with this underscore confirmation. So does it have this sort of filled with this name? Ah, and then also so double and symbol, this input and then we looking for this keys of this key equals this input and this confirmation kings and I see both values. So if we again, I'm going to use this password as an example here. And let me just put it actually lower here so we can see a little better. Okay, so we have saved passwords, field input with the passwords as a name attribute and then password confirmation. So it's checks whether there value associate with this password field here because the key would be password and then value associate with password confirmation are the same. So wherever these import store, they have to have the same value. Bicycles confirmed will check the field with this name also exists within the request and then that values for both are the same. And that's everything for this confirmed rule. Let's now create another one there, one for email. So class email and again this one also extends the ah rule class extends rule and it's found this methods stop here and validate method here will simply use return statement with filter var. And we go for that This input, we get this key and then the flag that we want to use is going to be the constant fielder volley date email a mask. This field of are we telling is that we want to validate the given string that we passing through is the first argument. Ah, using this field to validate email which checks for evolved email address. So will tell us whether this string evaluates as valid email address. Basically Okay, that's everything for our email rule. And the last true we are going to use with our exercise is going to be required just to check whether the field is empty. So you re quiet 10. There we go. Remove the space extent rule are the methods stop And here we go into return. Isn't empty this input, and then the field that we are looking for is going to be within that this key. And also we just checking if the input with this name, wherever this property will store, isn't empty. So if it's required, it needs to have some value, and that's it. So if we save, it closes, we can also close this Valley data, and we are now done with our Valley data component. Obviously can add morals if he wants to check whether their record exists in the table and so on. It's entirely up to you can create as many as you want you've got. Obviously, he had this composition. You've got Valley data, which were you passing everything through. And then these rules are going to be picked based on Walt Collection. You going? What's what Rules are you going to pass through as arguments to this validated constructor ? Okay, so in the next video again, we're going to write some tests to make sure that our validator component works as expected 19. Validator under test: in a previous video. We've written our Valley data component. Let's now right the test for its So under that test unit utilities, Let's create the new test. It's going to be called volley daito test, and it's within the up test unit. Utilities Name space. Let's extend base case up test and we're going to start with public function of validation fails with inputs, missing values. Let's make it a test again, and we go for rules. Will be new collection illuminates support collection. Make sure they import this class here. And then we passed through an array of items, So we're going to have a name field, and I want this field to be required so non empty. Then we got to have email field, which will be required but also needs to be a valid email address soul, this vertical line pipe or whatever you want to call it and an email. So these are obviously rules. Here is the name of the input and on the right hand side within this area, the values of the array are representing the rules. Then we have password, which will be required but also needs to be confirmed and as you may remember we've created is confirmed. If we go back to utilities, validate our rules. Confirmed will make sure that obviously the password underscored confirmation is present, first of all, and then there's the value associated with both of them. The password and possible confirmation, Uh, the same. So that's for the password. And then we're going to have this password on the skull confirmation, which is just required. So these are the rules fields as case and rules as values off this array, which were passing through to the collection, creating the collection object instance. And then input will be new collection as well. And this will take name empty, then same for email. It's going to be empty. So we as if we didn't put anything within their form fields, then password is also going to be empty. And then password confirmation is also going to be empty. Okay, let me just create a few in your lines again. And now we're going to start with volley. Data equals new volley dater this AARP utilities validator and we're going to pass the rules as first argument, an input as second again. Make sure that you import this validator here appear. Let's just put this element package above these custom components that we've created. So we have this Valley data. We passed the rules and import they want to validate, and then we go for this. Assert fulls when we run validator is valid. This should return falls because we passed the rules and the rules say that name is required so I cannot be in empty email cannot be required and needs to be often email type past what is required and needs to have that confirmed confirmation field as well. We have this possible confirmation, which is also required. None of these have any value, so it's definitely going to fail. This is valid method, and if it wants for any reason to pass and say that it's true when we call this is valid method on this Valley data, then we need to return some message. Validation returned True wit Rick West containing empty in boots. So let's save. It's, I think we've got there just ready. If we go back to their terminal, that's around PHP unit on this class only. So test again. Let's point to this file units Utilities validates so test and we go One test wanna session , which is passing. So that's great. And let's also check this assert Same and we're going to pass, name required and it within the array. Then we got to have email required e mail. Tell me exactly what it what is going to do in just a second. Past Swart will also be as in the raid, Rick. Quiet, then password. It's not this one. Confirmation required. And what should contain this sort of format? Our volley dates are errors. Property. That's how he would start the stairs. We open our value data up. Utilities, validator, valley data. This is when we are doing desired him. So we have name off them, uh, field as key passages array. And then we create an array and passed the rule to it. So this is why we have these items reupped within the air 80 square brackets by six on each of these items. Because these obviously are passing for these rules. Okay, So harassed. And if it doesn't march, demag unsee validation. Errors differ with empty in boots. So they are not what we expect them to be. In other words, Okay. Let's run the test again and we go one test to Alsatians, both of which are passing, which is great. Okay, next test. Let's just scroll up a little bit. A public function validation fails with invalid email. Let's just make it a test, and we're going to start with Rules equals new collection, support collection, and we pass just one item email and it's going to be required and email for months. We expect so and then imports valuable, which is also going to be new collection. And this one will have email but in the incorrect former. So we're just going to put some string so they required will pass. But the email should fail because it's not a valid email address. And then again, volley dates equals new validator. This utilities validated Valley data, and we pass rules as first argument and then import as the 2nd 1 Now we go for this assert false when we run volley data is valid and validation returned true with request containing involved email address. This message will obviously only going to be visible within our test when we ran the test. If for any reason this is valid, did not return. False. Okay, so it save it, run a test, and we're going to test three Alsatians, all of which are passing, which is fantastic. Next we go into the same as we did beef. Also, we are certain that both of the things are the same. US Same. And we go for this array, we should get email s email in the array. And that's the only item when we call volley data and property errors. This area should contain this sort of format. Okay? And if it doesn't, then we're going to say validation errors do not much involved. Email address and again, cynical on a D and save it. Ron IDs and a your four stations for two tests and the opossum. Okay, next test. Let's just scroll up. And it was gonna be public function called Validation fails with involved conformation in boat. So now we tested for the confirmation role test and regards not rules new collection. And again, if I'm a little bit too fast, please feel free to pause. The video obviously retype everything I do as well to make sure. Obviously, we we on the same page, basically okay, passwords and we go for required, then we also need this to be confirmed. In other words, we need this possible confirmation field to be present as wells and then password confirmation. We want to be required. And then let's just copy this. And we renamed this rules here with imports and for password, we are going to put ABC Value and for possible confirmation we're going to have the F, which should by the hour is valid should fell because obviously they are not much in. They're not the same values, even though we have password confirmation. But the values are different, so we're going to start with volley Data equals a new volley data and down. We pass rules as 1st 1 first argument and then import as the 2nd 1 So now, without a validator, we can run the assertion, assert false. When we Ron validator is valid and if find reason, it returned true then obviously something's not right. Validation returned true with request containing invalid confirmation. Save it, then we know Run the test three Test five Alsatians. Everything works fine. Okay, let's do the same as we did before. Let's just assert same as well this assert same and what this heiress property now should contain, it should contain password confirmed, so volley dates are heiress property. And if it doesn't, then validation errors do not much involved confirmation. Save it again. Back to the terminal. Run a test and we have six Alsatians with three tests, all of which are passing Buck to the editor. So that's this test completed. And now it's right. The last test we have for our validation component. And let me just scroll up again. Public function validation passes with valid input. Now for change. Let's make it a test, and we're going to start with rules again. And let me just copy some of this because I can't be typing so so many times the same thing . Okay, let's base that here. We're going to start with name here. We're going to prepared it required. And then we got to have email, which is required yet and instead email, then password confirmation requiring a friend and possible confirmation required. And now, for the values for import. We got to go from name Sebastian. So then ski for email. We're going to have info SSD tutorials that come for password. We're going to go for Seacrets and same for the buzzword confirmation. So everything should validate. Fine now, because we are complying with all these rules. The name has the value, the email has the value and it is a valid email address. The password is has a value and it has the confidence would confirmation field as well, which both of which are much in the same value. So everything should pass just fine. So now we start with the volley data again equals new volley dater, and we are passing rules again as the first argument and input is the second. And then this assert True, when we run, validator is valid And if it didn't validate, then validation returned false with request containing valid in boat Let's quickly run this test. There we go for test seven assertions Let's ride the last a session within this test. This assert count this time should have no items. When we try and count items on validator errors should be an empty array. So if we use count on it not shooter 10 0 and validation errors the for with valid input. So basically, if the if we if we get something else than zero from this Valley Data heirs. When we run, count function on it, then obviously there's something wrong. Okay, let's save it. Run a test. And there we go. Full test. Eight sessions, all of which are passing. And now we know that our validator component is working. Fine. Okay. We can save and called the test saved this valley data and moved in exurbia. 20. Abstract Controller: so now that we have most of other components ready to use A let's start working with our controllers. We're going to start with the parents control a class, the the abstract one which all of the controllers extend. And let's just girl down. We have three properties at the moment, but I've for gotten to art this request property, which we are here. Instance she ating, obviously, by pulling their requests from within the container. So let's aren't this property as well protected request and it's an instance off the request this alone minute http one. Make sure, obviously this is also imported. Let's just put all these illuminate components together this way on. If we scroll down, the next one we need is going to be the one for validators or protected validator. And it's going to be an instance off the value data this AARP utilities validator and again the shoot out the name space. Let's just so yeah, import the class here. Let's just move it down here, okay? After the valley data, we're gonna go for protected input, and that's simply going to be a collection, which is this illuminates support collection. And again, let's just make sure that they're all together here. After the inputs, we will have the rules protected rules, which is going to be a simple array. Ah, ray end. And the last one is going to be also a bray and it will start all off the air. So protected errors, an array, and we got So that's all of the properties now. Now lift with scroll down, we have constructor, which we can art to, and then it's going to be included within the main constructor. And then we have their view method. After the view methods, we are going to create the method that will authorize, basically restrict access to a givens sections of our website, and we're going to call it authorize protected function authorized. And within this method, I'm going to check if this guard is authenticated. Then we return. No, I mean, obviously we were happy to allow whoever's viewing the page to to go to the page basically annexes the content. Otherwise, we're going to return new redirect responses, illuminates HDP re direct response. We're going to pass there path to our log in page, which is going to be in my case, is going to be just for its large because it's directly under depth. Ah, after to the main. And then a method sent. This is going to redirect the user to this location. So obviously, in our case, if I open the page, we have locking the deaf, and that's where the use is going to be redirected. If they try to access the page that has this method in the method of the controller fold, this given location okay, lets out some dog blocks here, and that returns this response. Let's just import this class and again make sure that that thing is symphony once. Let's put them under the illuminate. Not once a swell in this regard. Rick Response we can have here. There we go. Okay, we scroll down. Let's at the summary to this one. Also, Rice request. So, after authorized methods, we're going to create one for redirecting the user if it's already locked in. So for let's say, someone logged in and try to access log in page, they shouldn't see the logging patient should be redirected back to the page. That's after the logging, so we're going to call it redirect if locked in and again. It's going to be protected method because we only need to access this method from within. The controllers that extended this class so protected function redirect if logged in and within this methods and again, I'm going to shift it up a little bit. Within this method, we are going to check if exclamation mark this time this guard is authenticated. It's not off indicated then return. No, now, this time we were working this way because obviously, if the user is not authenticated, it should be able to access pages like logging or registration. Otherwise, we return the same thing as before new redirect response. And this time we're going to redirect them to the Dash board, which is going to be the default page after the logging and then sent method to trigger this redirect. And let's Doug looks as well. It's going to pretend this response or no and then re direct if a user is logged in Direkt . If there we go so the next methods is going to check. Whether the methods are used for the given request is off a post Sipes or protected function IHS posed, and we're going to check battery return Boolean truffles. This request methods and we triple equal symbol Check for the capital Pulsed. So basically, when you submit the form, you can sum it is weird to get opposed and we check in with it. If the post has been used, basket the method post. Okay, the dog blocks it will return Boolean true or false. And we go for a check if shake If request method is post and after this methods the next one is going to restrict any other request, then pulse so it will only allow the post request otherwise is going to throw an exception . So protected function boast request on Lee and then we check if it is not this post. No matter that which created just a moment ago, then we throw new but request a si to be exception and an invalid Riku West methods and exclamation mark. There we go again. It's out. Some Doug looks here as well. Only allow now boast request method. And if we scroll up just to show you this about request http. Exception is part of the symphony package. So obviously make sure they also imported right. He has a symphony component actually care No exception about request has to be exception. You can use just a standard exception the one that comes with PHP Just a normal one, if you prefer to. Okay s after this method and that's just aren't return void on throws. But request actually be exception And next methods is going to collect the request. Basically get the request and put into a collection. Ah instance, so protected function collect request and we take an argument off items as in Ray, we need to know what items we wants to fetch. And there we go. For this input equals new collection illuminate support collection and then we pass through as an argument this request, We only want the following items and we passed the items through as an argument. And I think here we should actually remove this default value because if we are requesting some items that we should perhaps always have some items in misery eso no default value for this one. Okay, and let's out. Some dog blocks were going to say collect request items so that this input is now an instance of the collection with all these items collected from the request, so the next method will take care of validating their request. It's going to be called Validate Request protected function again. Validate a request and we're going to start with validator equals new volleyed a term this op utilities validated Valley data on which have created Elian and this 162 collections. As you may remember, the 1st 1 is going to be rules, and the 2nd 1 is going to be in port. The rules at the moment are just a simple array. So we need to convert this these rules to a collection of very simple, because we start with new collection, make sure there's this illuminate support collection, and we passed these rules as arguments to it. So this rules and the next one, we already half as collection because that's where this collection request is going to convert the request into this collection. Instance, which is basically this this input basically input property off this class. So now our validators instance she ate it. Now we're going to check if and an exclamation mark. This validator is valid, which would say, in other words, if this request is not valued because we've seen this exclamation mark The beginning. Then what we want to do is associate whatever errors we have with these This errors property. So errors equals and we're going to measure because we might have added some Eros already to this Paris array. This property which we have on this controller. So we're going to Magic Array, merge. And we going to pass this errors first, and then we go toe emerge it with this Valley Data heirs. So if we want to aren't any errors, Aziz, we go is well outside of the Valley data. We can also add them to this arranging. They all going to be merged. OK, so that's our validate request. Let's now quickly out some dog blocks as well. Validate request and it returns avoid so return void. There's no value returned from this method. Now, the last method is basically going to add item to this Peristeri. So we can Actually, As I said earlier, we can manually out some items as well protected function at Errol. And this method takes two arguments. The key which is the name of the field, and then the rule, which causes the problem. Yeah, So we're going to check first. If Ray Key exists and we go for the key within this errors and in array rule within this dis heirs with this key, then that means that we already have this role for this field within this a rosary. So we don't have to add it, at which point we simply he'd return. And that said that this basically the method will terminate here. Otherwise, we're going to add it. So this errors And we passed the key field name in the in other words. And then we got another set of brackets to indicate that it's one of the items in this array. And then we passed the rule. So, for instance, what we could have here is something like this email, which felt for required but also for email field by instance. That's why we check in. If this rule is already in this Ariza rate in this errors with the email array within this ray basically before we actually add it. OK, so that's our arts air methods completed. Let's just quickly out dog blocks as well. There we go for the key. It's going to be a string type at ST for that rule. It's also going to be a string and then it's aren't some summary here. So art item two errors and that's everything within our main control. A class eso. We can move to next video and start working with our logging controller. 21. Login Controller: in a previous video have finished our main abstract control a class in this video, we're going to start working our logging control. Up until now, we only returned hello from within logging controller on this index method of we preview the page in the crowds. Obviously, there's nothing fancy here, just a bit of a string. But that's obviously not what we want from this logging controller to return. So what we're going to start with is, first of all, we're going to create the property rules protected rules. And this is when we going to declare what sort of validation we want on our logging form and we going to have for email field. What I would like to have is to make sure that it's not empty, so required and then pipe and email by pipe. I mean this vertical line basically, so I want to make sure that it's not empty and it that it's also off the correct email for months, and then we're going to go for the passport, which should be really quiet. It cannot be empty. So these are the rules that I want to apply to the validation off our logging form. Okay, then after the rules, what I'm going to do issues this protected function constructor. I'm going to overwrite it because if we go back to the controller by defaults is just an empty method and it's being called from within the constructor. So rather than we ask reading the new constructed calling the parent constructor, we have this method available just to make sure that when we load, they're locking controller when it's instant. She hated that this method is added to the main constructed basically, so whatever we post here is going to run together with constructor. So from within this one, what I want to do is to make sure that if the uses already already locked in that it doesn't access this control at all. So this redirect, if logged in method, you may remember, have created this method in the previous video for scroll down here. Redirect if logged in and it checks. If user is not off indicated, then return. No, another case. In other words, user will remain on this page. Otherwise, we're going to redirect them to the dashboard page after the logging because we know it's logged in. It shouldn't see the logging screen if it's locked in. Okay, so we make sure that obviously log in pages only for those who are not locked in. And let's just quickly out there. Dog losses actually copied his dog block for his dog. Look, from this method, just copy this here and then we get outside response. We should probably import. This response is Well, that's this informing symphony component. HDP foundation response. I'm just going to paste it. Not here. Rights above dislodging controller responds and its use statement. And there we go. So that's the one we after and as the one that's being returned from this constructor. Okay, s So that's our constructor. And now the next thing that I want to do is to make sure that obviously we can see our form . So from within the index method, which is what's being called when we actually accessing the our logging page, which is without any arguments in there in the u. N. L. Ah. Then we simply returned this view and the view is on the pages and locking. And that's all we need to return. Let's just quickly out. Dog looks as well here on again that returns view. So let's imported factory as well. Let's keep it like this. And then we're going to say display logging form. That's just actually remove this factor. Let's just keep it as if you, because that's what we expect to receive. Yeah, it's just from Otis Factor. So illuminates eliminates view, view. And then, obviously this response for the same from the symphony package. Okay, so if we know, save it and previewed in the browse there, refresh the page and we go our logging form. Something shows up if we hit on logging, its automatically validating using JavaScript. Eso Let's go back to the editor and it's actually have a look at this log in page. So we go to this resource is of use pages and then this log indulge played a huge me. I'm going to close the browser here on the left, so let's have a look at what we've got here. We've got this form which submits the request, using the Poles to method. Then we have the action is going to be logging polls, so it's going to call logging control again, and method is going to be called posed. Then we have some data attributes which are basically being used with this. Assess the form Jake we're applying. That's use with this with this exercise. Obviously, if you using different sort of validation in some mission, they're not. You can You can obviously remove these two arguments here and obviously with this properties and create your own ones, whatever you are using for submitting the form. Okay, then we have for the validation. We have a block here. If we return required, then this message is going to be shown if we if errors will contain email, this message is going to be shown. If invalid, this message is going to show if inactive, then we're going to show the message that your account has been active. It has not been activated, and then we show the link to resend. The activation in this is only in the case. In case if we just open our file browser open E envy. If this verification set to true, because in that case we will have to send a verification email user have to click this email in order to activate the account. But if they didn't very five, I just close this and close this response is, Well, if they didn't verify the account, then the account is still going to be there. It's just they won't be able to log in, at which point we're going to show them. This message of is that the account isn't active. It's there, but it's not active, so you cannot access it. Police make sure that you activated. Just click on this link that will resend the activation email and you will be able to activate it. Okay, and then we have some technical problems. For any reason something happened. Then we catch you and obviously display this technical. Then we have Obviously our imports, which has type is going to be email name and I D email as well. And then data validate is where our validation rules are placed again. Required an email for this one for password. We have validation only required if it's going to be empty. Doubts measure is going to be shown, and it's type of the password name and I d passwords, and obviously for data validates the rule is to require, too to be required. My second cell that the import is an empty then we have the check box. Remember me? This one doesn't have any validation in may be checked or unchecked. It doesn't really matter. Then, obviously, based on whether we receive it with the request, we will said this Remember me token or using cookies? And then we have this input summit button, which is the trigger that you see when you actually preview there. Logging formed by once the submission started, we going to hide this baton. And this second Barton pending one data summit bending is going to be shown, which has this spinner, which is rotating, and bicycle labels saying processing. And then the data confirmation is if we need to. I don't think this specific form uses it because this is where we showing by their confirmation, that should the form fights out and there and then whatever message has been returned with the Ajax Coal, it's going to be put into this paragraph and displayed on the page instead of the form but a swift with scroll up. You'll see that for the behavior we have redirect. So we could probably remove this this paragraph. Well, let's just leave it there for the time being because after we've managed to log in, we will be automatically redirected to our dashboard page. OK, so that's our form. So now we know what we've got within this form. Let's just close it. We have our index based body that were formed, displayed on the page as well, Which is great. Let's just go back. So what happens when we submit the form we need to create this post method? Because this is where we go into process. Actually, they requested data and bicycle verified that the user exists and lock them in regard to the dashboard. Okay, so we're gonna start with a public function, boast? No, both requests on the just boast. And here we're going to start with this post request only because we only allow for this method. We only allow post request if it if we've basically went. If we just go back, Actually, now that we have dismounted this call to this method, if we go back, and if I just go in use, get request, use it, but basically trying to access log in post path heat return and they go, we've got involved request method as a conceit because when we loading the page through the browser without actually submitting it using the polls request, which you could do with obviously form. Then that's just a simple get request. But we need a post request. We are actually restricting access to this bath to the post only. And now we're going to use the try and catch statement, Karch, and we going to cash just the standard exception. And it's just import this exception as well here. So no generates import. There we go. If you scroll. Obviously this exception is here at the top. Okay, so we're going to start with this collect request, and we passed what items we want to collect from this request. So we want email, We want password, and we also want remember me item. So basically, when we hit the submit button ones, the fields are filled in. We send this request with all these data that we have within the form to this post method. In other words, we check if the request was supposed and it will be because if we open this lock in a zoo made remember method baseball sets to post here, and then we go to this tryst section. We collect the items that we want from this request, which is email password. And remember me. We go back to the form we have this field email with the name email with the name, password and checkbooks. Remember me? So these are the only items that we want to collective. Someone maliciously wanted to summon some other items. They will be ignored. And then were we going to do is validate this request. So this validate request. And when we call this validate request, if we go back to this method, we first instance she ate in the validator. We passed the role suite which we want, which are the rules that actually are associated with this property rules. We over Britain, the default property rose on the controller on we are Did these items here and then import is what we've collected calling this collect request method. So there we go. This is our input. We put the request items which will pass through as an argument on Lee These items into the collection creed in the collection on this simple property. So we now validating it. And if it didn't validate, then obviously if we go back. Just check this validate request. What's going to happen if it didn't validate that we going toe art these errors from within the validator to the areas property. And we're going to imagine if there are any other errors. Obviously, within this airs property. Then they got going to be merged with the ones from within the validator. So if we pass this validate request coal, then that means does it? Our data is all validated and so good, at which point we can log in the users. So this guard, which we pulled already from within the container in the main controller. So if we go back, check our constructor. Here we have this guard here, which we pulled from within the container. So on this guard, we are going to call logging method. And we passed this verify user method which would create in just a moment. And then this input get Ah, remember me talking if it's going to be anything that is going to be about basically and no otherwise is going to return the obviously that this item is within within the request. And if we click on the slogging just to remind ourselves what it's got has got the second argument. Remember me where they said too true or false if it's going to be within the request. In other words, if we check this check books, it's going to be basically representing bullying. True. At which point we going to set this? Remember, talking otherwise is just going to be ignored. And when won't send this one said this cookie. Okay, so verify Use a method. Let's quickly create this one. It should be verified. Should be verifying. Always helps if you spell it right. Okay. So verify, user. What we going to do here is basically create the news instance, or user equals user, but we're going to try and find it by email. You remember this scope by email method which check which searches for the user records by its email. So this inputs, we pull item email from it, and then we try to get the first item that matches the record with this email. Then there will be only one item anyway. Okay, let's import this user model, which is up model models, user. If we scroll up just to make sure that we obviously have it, I'm just going to put our custom components separate for many packages. Eso is going to be here on new line as so now we check in user by email. We get this email item from within the input we call it as an array, even though it's a collection. We could also do something like this get and then used there used the index passing name of the field they want to get from within this collection. We can do it this way or the other. It doesn't really matter, and then we're going to check. This if is not, is no user. That means that we found the user, which is great. That's what we wanted to dio. And then we return this and another method. Check user passwords of this at this point word. At this point, we're going to validate disuse or whether the password actually matches the password that has been submitted with the form. So first we get in the user by email. Once we've got the instance off the user by email, then we're going to validate its password, the password that we've submitted with same request. But before I do, I go ahead and create this check user password method. Let's simply return this in volleyed credentials methods, which is going to basically return response back to the user if the credentials were invalid. Okay, so what we going to? Well, it's not going to actually return the response. It it's going to throw an exception in art error to the heirs arrayed this property errors on the controller. Let's start with this check user password methods. So let's add it. And he had This user is going to be user instance. So let's I painted as well, user. There we go. So you know exactly what we did in within our i d knows what methods are available in this instance on. We go to start if is not user and we call method verify passwords. And now we are passing the input this input and then we can again use get methods on it, and we want to get item password from our request. So if it doesn't very find in deficit, that means start the credentials were invalid. So we cannot allow this user basically to to log in and we're going to again. Delegate is to another method. Actually know another method. The same editors we've got here this invalid credential. So this invalid in volley, it's ah, invalid credit, then shots at despots. Obviously, we know at this point the password was incorrect. Returned the same thing as you feel would return when we couldn't find the user by email. Now, otherwise, we're going to return the call to another method cult check if active, and we pass user as argument. So once again, let's try and see what we do in here. We are trying to pass this verify user to the logging method, which take a which takes instance off the user class and then remember me talking So this verify user should return user instance potentially. But it may fell, obviously, while it's trying to do so. So let's quickly return user. We're going to keep it like this, and then it will throw exception. And let's just say verify, user. That's what this method, Gus. Okay, so what we do in here now this verify, use a first of all tries to obtain the instance off the user by email by this using this line here, we see scope by email method, and if this user is no is not know, then obviously we know the user have been found has been found in a database by this email address. So we have instance off the user here. Otherwise we returned invalid credentials because of issues that could not be found. So we definitely don't have user by this email within our database. But if we do, then we check user passwords next to make sure that the password does the user submitted with this email also is also valid. So we check in here. If user verified password is not correct with this exclamation mark, then we obviously know that the credentials submitted were incorrect. Their email was correct because we got directly use a record, but the password was not correct. So again, we're going to return the call to this invited credentials method. And then if we pass this conditional here, that means that the user has been found and that the password was valued. At which point we going to do another lot. One last check to check whether the account is active, whether the flak that the active table cell basically has value one which would indicated that uses active. But obviously, within this active methods, we need to check whether first of all, our system is set to accept verification. If it's going t be set to false, then it's going to ignore this active field altogether. But that's all that's going to happen within this check if active method before we get to this check. If active, let's just create this invalid credentials methods so that we at least we have this one sorted. Okay, Invalid credentials is simply going to run this art ero, and we want the era for the email field, and the message that we want to show within our form is going to be this invalid in valid credentials. We don't want to say whether it's it's email or password. You don't want to let them know exactly which ones are wrong. Just tell them that the credentials there's something that I invalid, so we're going to use invalid as the value. And then we need to throw the exception to terminate the execution off their off the chain . Basically here. So throw new exception and we passed the message just saying user note found at this point when we obviously return one of these invited credentials, either here or here. Ah, this methods will obviously terminate. We want log in the user because this will fail. Obviously with this exception and we're going to be redirected. Exception block here. So let's maybe before we go any further, let's just deal with this exception here So we can't this exception. What would we want to do if there's obviously invalids request? If we dated Invalidate, let's return instance off the new Jason Response and we talking about the illuminate HDP Jason Response and we pass. Ah, here errors as our arguments of this errors, which is going to be the array, which we come onto converts to the Jason format. And the second argument is going to be status couch, which is going to pretend with this response and you know a case. I'm going to use 4 to 2. But rather than hard typing this year, I'm going to use the response that we already have here this component age to be foundation response. And he's one of the Constance, which is called a JVP unprofitable entity. If we I'm just going to put the actually semi column for the time being because we're not finished yet. I'm going to click on this Constance to take us to this class, and you can see there's a long list off status codes esque represented by the Constance you can use, whichever one you want. I think that using the verbals approach like this it's a little bit better because it tells us exactly what the problem is. Okay, so I put the semi colon here, But before we put the semi column, we have to run the Method cult sent headers and then get contents to return. The Jason did basic the returned response in the Jason. Former buck to the client. Okay, so this is our exception. At this point, our errors will be converted into adjacent response, and then, obviously our form will react to it. According any of it is through this JavaScript plugging this Jake wear black. It's close to start envy file and let's finish this methods. So after the logging, we want to return Jason responses Well, but with slightly different data. So return and again I'm in lining this. You could obviously do something like this. For instance, response equals new Jason response and then obviously parcel these arguments and then change it at all. But I'm going to in line it the same way I did. He s I'm just in between a brackets. I put statement, knew Jason response. And here I'm going to put the valleys. I'm going to actually type in the array. It's going to be redirect. This is when I want to redirect the user. And again, this is going to be passed through a back to decline in adjacent former. So they will get this redirect item with where we want the redirect to redirect the use after the logging, and we want to redirected them to the dashboard. And then again, same thing. Sent Heather's and get content. And that's all that we need to return. So when we managed to verify the user and we look them in, we redirect them to the dashboard. Otherwise, we are going to return a old the years in the Jason form of back to the client so they can deal with it, basically showing their validation messages accordingly. Okay, so let's scroll down. We have this verify user completed as well. Let's out. Doug looks to the Czech user password. It takes user throws exception. If there's something wrong and it's a check password, then if we scroll down, we have this involved credentials as well. For the involved credentials we have, it throws exception and then involved cred. Then shells exception. Yeah, I think that makes sense. OK, after this, we need to create this check if active methods. So let's just at it. And, user, it's I painted as user. So we have all of the methods available from within the idea automatically. And before we are the dog blocks. Let's just do the implementation of this methods we check if don't e n v iss and then we check the vory verification set to true. This is method on them dot Envy package will tell us whether this very able has value said too true. And then we check end exclamation mark User is active, which would say, if user is not active, then we know that user should be active, but it's not, at which point we simply say return this and then we go into, uh, create another method in just a second called E knock teeth, which is going to be basically something like this invalid credentials. It will up the euro to the Year two deed to the Errors Array and Danton's property, and then throw the exception so we can actually return there the errors back to the users so they can show the message within their form. Otherwise, we know everything is fine and we can proceed with the redirection to the dashboard and obviously logging in the user So we'd return this user instance. Let's other dog look here Now we're going to say check if user is active and this will throw an exception as well. It returns you somebody wealth, rose, exception. It doesn't know it yet because we don't have this inactive method. But from within this inactive method, we will throw the exception eso. Obviously this method will also throw this exception ones. This inactive three gives it okay from within the inactive. We're going to run this art ero. We're looking for the email field and then inactive. I attempts if we go back to the logging, we have this inactive. So this is going to be shown to the user. This your account has not been activated. We've got this account, but it's an active click on this link To resend the activation email, you will receive a jealousy click on and so on. Let's go back to this logging. And the last thing is that all the row. New exception to make sure. Obviously, we won't log in. They use eventually. User not active. And I think that's enough. Let's out some Doug Brooks here. Those exception and inactive exception I think that's enough, OK, and let's remove these redundant lines here. And I think our lugging control is nearly completely leads. Justice one. Squeaking for something. Let's are returned. Talk here, return user avoid. Does return void involved credentials. Its exceptions that will only return user or, throughout the exceptions, that there is no void really here. A. Okay, and I think that's days. Let's just check all of the methods we have in goats dog blocks for the post method here. So let's quickly add it. Return string. It's not really is I mean, so Jason Response. Let's just put Jason response rather than string because a bit confusing and then pro cess request and then we have index and all these properties and constructive method, and I think that's everything. So let's now go back to the browser. And if we removal, we've got here in the u R l love logging pulse. If we remove this and logging load just the logging form. If we hit on this log in Baton. Obviously the validation shows up, and I'm going to open deaf tools here and a crumb to see what we going to be getting when we something the former just going to put in for acidity. Choice. We obviously don't have any records in the database yet. Let's just open a database by refresh. You see, there are no records, so we won't be able to log in any way until we have this registration form done on. Let's just put some passwords create finds that heat return and there we go. We go, too. Let's have a look at what their response got us here. We've got disposed it. Got this status fall to two unprofitable entity, as you can see and let's see the preview we have. This Jason format with email indicated that invalids flux should be shown within their within the form, and that's the one that's been shown here as you can see invalid credentials if we try and hit it again. Another requests with the same response by six. I cannot find email. Basically record with this email. This is the 1st 1 that if we go back to the editor and scroll down to disposed and then verify user May 3rd. So this is basically what it fails because it could not find using returned no when we tried to find user by email. So check use a password. Sorry, it's not check user password. It's invalid credentials because here we checking that the user actually exists. If it's not. So if we go to this invited credentials art your aired with for the email field, the the item is going to be involved and this is what's being shown here. Invited, Invited credentials by sick. That's how all this works. Okay, so our logging control over logging from is now completed. We will have a chance to test it a little bit better later on when we actually have some records within a user stable. But for now, that's it. Let's move next video. When we start with the registration form 22. Register controller: in a previous video with Completed our logging controller, and in this one we are going to have a look at their registered controller. Now, before we do this, let's just go back to our looking control because I've for gotten to the A few things here . As you can see this constructor, it's supposed to return Newell or response, but we don't actually return anything. So let's proceed this call to the redirect if logged in with the return statement and then if we scroll down, you will see that this Jason response here, when we actually click on this, get content, you'll see it actually returned string. So if we go back here and change this Jason, retain Jason, respond to simply string. That should also Arum of this highlighting off the code. And I think that's everything. Everything else seem to be fine, so we cannot save and close our logging controller. Let's open the file browser and it's creating new control at this time. We are going to call it register controller and it is within the same name space, which is this up controllers. It will also extend the main controller. Ah Troller. There we go up controller and we are going to start with a protected rules. Property and registration form will have the following fields name, which will be required. Then we're going to have email field, which will also be required, but it also needs to validate as an email. Then we're going to have passwords which will be required. But it will also need to have the confirmation field so con firmed and then the password confirmation, which simply needs to be required now. This confirmed, as you may remember, will check if the field with the same name and upended underscore confirmation exists within their request, and values of both are equal. Let's let's not some dog lucky on this is in the ray. And if we now aren't protected function constructor, which will overwrite it will also return this redirect if locked in because we don't want anyone to be able to access registration form when they are already locked in the system and lets out some don't block again. It returned response. That's import this response and then art to a parent constructor. When I said import, obviously, if you don't use PHP stone on, don't have this marker, which imports classes automatically. Make sure that you, uh, this year's statement with symphony component. Http Foundation response about the class definition. Okay, so the next method will be our index one. So Public function index and this wall was simply return this view and it's going to be pages read g Easter. And it's also out some dog look here it returns views so it's imported. We can remove. This factor is just keep us view and again, importing illuminate view of you. And let's out some dog block on this play registration form. Okay, if we now save it and privy everything that browser. And if you click on the Register link, you'll see takes us to the register path. And that laws this register controller, which now displays Dave you. And that's Kevin. Look at the view file as well. So if we go to our resource is of use and then page and we have this register one, you'll see we're going to be posting to this register controller to the post method using the post method. And if we scroll down, we have this heading. Obviously feel free to amend all these options as you wish. Obviously, keep the fields because we're gonna need them. And then the validation here for required. And if the registration fails for any reason, There we go. We've got name. We've got email, which is off the email type. Same validation rules. He has all required an email. Then we have password, which needs to be confirmed. So we have this password confirmation field, and then we have just a button and that's it. So that's our registration form. If we go back to the Register Control and let's now create this post method that will process there submitted requests, I'm just going to create the fuel lines here because we start with a public function post and we're going to start with this post request on Lee because we only want to allow post method when we submit in the form. We don't want to allow the get method. And what I mean by this once again is post is when our form of his scroll up uses the post method. Otherwise, method could be get, but we obviously want to send everything with the post. We don't want to reveal all this information that we sending in the U. S. A. Which is what would happen if we used get method. Okay, so I'm just going to close the file browser on the left s. Oh, now we're going to rub the remaining part off this method within the try and catch block and catch will catch just a standard exception represented with e valuable on its import. This exception he as well. So import class and again, scroll up is just use exception and we are going to start with the try block. First of all, we're going to collect their request. So this collect request and the items we are interested in our name, then email, then password, then password confirmation. So these are the items that want to collect. Once we've collected them, let's validate the request. So this validate request. So now we know that all these items are valid. Then we are also going to validate email and this method we don't have it yet. Will bicycle check if the submitted email address is already in the database? Basically, if the record for this email already exists, so if we just quickly of this methods and within this method, we first try and create obtained the user instance by calling User, and it's going to be up models and then method by email. We passed this input and we get item email from this request, and then we want to get first records. So first item, if we find records off the user by submitted email address, that means that this user already exists. And we obviously need to return some ah, validation message back to the client. So we're going to check if is not, is no, which would indicate that obviously, this is a valid instance of the user model, meaning that we found the user. So, user, there we go. If it's not know, then we are going Teoh this art error and we go into out there a full day email field and ah, validation message they want to trigger is going to be taken. And now, to terminate the execution off the remaining called within this tribe block, we need to also throw the exception. Throw ah, new exception and we're going to say email address already in use. So that's validate email done. That's just quickly out some dog blocks here. It throws exception and returns void. So return void. And for the summary, let's just say check if email is already taken, perhaps email address is already taken. OK, so if we pass this line, then that means that our request all of this fields validate that we don't have dissimilar address within their database yet. So what we need to do next is removed this password confirmation because we know going to be adding this to the database so input. And on this simple because it's, ah collection Elmina collection. We can use the method called off set onset in order to remove the Given Index and our index name is password Underscore confirmation. This is what we want to remove from this collection. And the next thing we go into this return this art user method, we don't have this user and we will provide the implementation for this method in just a moment. I'm just going to add methods stop here just in empty method. But before we do anything else, I'm going to return from within the catch block New Jason responds. This eliminates a should be Jason response, and for this response, I'm going to put in first item this errors, which will basically send all of the errors in the Jason format and then responds and then unprofitable. Eight. Entity This. Http, underscore unprofitable underscore entity which is fall to to stay, to sculpt, okay and semicolon at the end. And that's our where pulse method completed. So it's quickly out some dog looks here as well. We are going to say that it returns rather than response. It returns string and it doesn't return void. It returns string only because avoid a would return from this email validate email. But because we throw exception, it would go to this catch block and obviously was still returned. This Jason response So we only returned string, okay. And then we're going to say, Hey, bro says request. I think that says l Okay, if we now scroll down to our are the user method from within our user, we're going to first check if we can create the user, and we will instance she ate this user at the same time. So we check if and within the brackets, exclamation mark, Then we are creating the variable user equals and then user create. And we passed the attributes which is going to be this import to a ray because we need array by default. This input is all the collection instance. But if we run this methods to array with will return all these collected items at in the air a former so we can pass them on to this create methods on the user instance. And when we create the new user, the new user instance which we've just created will also be returned so we can associate it with a very able here. And if it doesn't which we were able to create it, then what we do And I'm just going to create two new lines. We go. Actually, I'm going to all these lines here as well and copy what I've got within this validate email . And this time when we going to say return the aero for the name field because it's the first field and this is what I want. This validation methods to be displayed, its failed. If we now just go back to our register blade, you'll see we have this felt item here, so record could not be at it if it couldn't be at arts added for any reason in this message will be displayed on this above this name field. Okay. And obviously the message for the exception, what we can say could note art new user record, and I think dot sit for this exception. Now, if dis method fails, then we will have instance off the user associated with with this variable. So we will be able to use this user after this if statement. So we then check if dot e NV is and then we check verification variable if we just open our browser. And if we open our e n v file, you remember, we have this verification, which is basically bullying, which represents bullion. Trough also tells us whether we want to verify user by sending them the activation email first or not. So we're going to check if this verification is set to true. Then we are going to return this Arctic invasion, and we pass user as argument. Let's know out this method stop. We know going to be working on this method. Yetta, Let's tie painted as well. It's going to be using model Using model is what we inject into this method. So after this check here, we are going for this guard and we're going to log in dis user we passed users. Argument is you may remember our guard class has this logging method. We passed the user and then remember talking as well, whether we want to remember the user or not. But in our case, because we register used rather than an user being locked in on its own, we don't want to provide any talking because we don't simply don't have it. So we won't be passing second argument to this logging method here. Okay? And after this, what we need to do is return again. Return between the brackets knew Jason response and the constructive for this class takes array is the first argument which is going to be pretty direct. We want to redirect to user once we've locked them in to the dashboard. And then we call, sent headers methods and lastly get content as well. So we tend string from this methods using just get content. Ah, method. Let's just aren't some dog blows because our art using method is now completed. It does not return void. So just a string and then we going for art new user for the summary. Let's just quickly look at the code again if we haven't missed anything So let's just go through the sculpt one small. So first of all, we check in If we've created the user, if we've created the user and this user variable will store the instance off that new user , If we don't then obvious we are the new error. And we terminate the execution of this method which if we go back, this abuser will take us to this catch block when we going to return to response with all the errors and 4 to 2, I think Waas Ah yes, Fortune to this http, on possible entity for the state of skulls A cult A If this if condition felt then that means the obviously we've created a user. We have now associate ID this instance off the season with this very able so we can then pass it to the activation on Lee when the verification variable in the dot envy file is set to chew and by default we said it to true anyway, So this activation would be what's going to be called obviously returned with this art user now otherwise If we're to set this verification toe false, that means we don't want to send the activation email once they uses Hit, Submit, register. Basically baton, the form gets submitted. We verified all the information. It's all good, added the record to the database. Let's log this user in and redirect into the dashboard pitch. Now. At this activation, methods will be used with two different calls. First goal will be made from within. This aren't user method, which is what we typed here just a moment ago. And the second useful, this method is going to be free. Open resource is use pages and then a logging blade. You'll see that we have this validation, a message here for Active, which says your account has not been activated and then we have recent activation email, and then we have cold to this register and then activation action method, which is this one here. So let's just change the visibility for this methods to public. And what I'm also going to do is to, by default, said this argument. He had to know also my be an instance off the user all my simply be known because obviously , when we calling this directly from within argues that we will have instance of a user, at which point this user will actually be an instance off that user class. However, when we are going to click on this register activation link, you can see we have this idea. Recent activation. Let's open Resource is assets Js and Abdel Gs, and I'm going to close this file browser so I can see things a little bit better. We have this recent activation email, which is later on cold from within this in it and in it is called, obviously when the page loads. So what happens here when we click the item with the idea recent activation, which is going to be this link here, and then we trigger dysfunction disclosure. We are getting the value from within the email field. So if we just go back to our lock infield logging finally can see we have this idea email field here, which is basically when we go into type our email address for the logging. And then we are pending this email to our u R l. So basically, wherever we are sent in, U R L is basically trigger property a Trevor and Triggers basically our button. This instance. So property a draft. So this is the U. R L? Then we are upending question mark. So we have acquired string here with the email equals And then obviously whatever has been typed into this email field, then we send it obviously to this activation methods. So let's quickly, I'm just going to close all these funds because we don't need them anymore. Eso from within this activation method What we are going to do, we're going to wrap everything within again, try and catch block, and we're going to catch exception as e. And we we deal with this catch block a little bit later on. Let's first focus on actually getting the instance of the users. So we check if is no user. This would indicate that this call has been made when we actually clicked on this link from within their log in screen. Okay, so we are trying to First of all, I find the user by this email address, which can be fined within the query string, so user equals user by email, and then we get this request and get we trying to get email from this request. And then we want to forget the first records that we confined by this email should be only one okay, and then we check if it's still no is no user, then this would indicate that we don't have this record at all. So what we going to do is again this art error, we going toe out email and then invalid, and we throw new exception with the message involved it email address. Okay, so let me just go through this once again. So we're checking if we passed through a valid instance off the user than this condition well returned, false. And so obviously this line will be ignored otherwise, if we click on this link, which contains the email address within the U. N. L. So if we just go back to the file we had opened before the slogging, so it would be register activation, then question mark email, and it that would equal whatever we've typed into this log in email field that would indicate that obviously we can get this email from the query string. This is when we get in this from the request season. There's get method and we indicate which query item we want to get the value off and then we check we obviously, if whether we can find this user by this email if we couldn't, If this coal here still returns, no services variable would be known. Then we are to errors, and we throw the exception. If we pass this line, that means that we have a valid instance off the user associate it with the variable. So next thing, we're going to do this. If exclamation mark this send activation email methods, we don't have it yet, and we pass user as an argument. If we couldn't send it, Then again, we are going to arts to errors and throw the exception. So I'm just going to copy this and we're going to display this above the email field again . And the message we want to display is going to be Tank Andy Cole. And if we just go back to our logging blade, you'll see we have this data case. He and his validation man method for this technical index and it simply say's technical problem. Find a reason we couldn't send the email, then obviously dance the message we're going to display. And for the exception leads. Just say email could not be send. Okay, lets up there. This sent activation. Email methods Stop. We will work with this method a little bit later on. Okay, So next thing I'm going to do is to create the variable cold message which is going to contain the message that I wanted to display after the form has faded out. And then obviously indicating that their message that email has been sent and what to do next. So please check your email for instructions on how to activate your account and full stop. And after this, let's just return again within the bracket. Knew Jason response. And then we gonna cold methods, sent headers and then get content. And for the constructor of this Jason response, we are going to pass our message. So message and then message. Now we know passing the second argument after this Ah, array for the Jason response. Constructive. We click on this Jason response. You'll see. The second argument is the status which by default is 200. So we don't have to specify it. If everything is OK, we only go into specified this second argue provider. Second argument, If there's some problem, Okay, so now for the exception, what we're going to do Hey, have this catch block. We are going to also return new Jason Response and again we're going to send Heather's and get content. But this time, for the first argument, we are going to pass. Actually, rather than doing this every manually, we just put errors here, which is already off the rate type. And then the second item and I'm going to put both of these on new lines is going to be started skilled, which is going to be response and is going to be unprofitable entity indicating that something's wrong. Something didn't validates quite right. OK, so that's our where activation method done. That's just at some dog blocks, and what we're going to hear returns a string. It takes user instance or no, and then for the message we're going to the pro cess activation email. Let's go through this method once again, so we checking. If they're the argument, is no. If it's know we trying to obtain the record off the user by the email of Taken From the U. R. L. From the crazed query string. If we still cannot obtain it, if it's still no, then we simply are the air and throw the exception, which would take us directly to this catch block, and we would return. Basically all the errors in the Jason for melts together the status coat off for 22 For this Asian, be impossible and details Just click on this. Once again, you can see it's associated with the fortune to start a scout. Okay, then, if all this passes we have instance off the user, then we check if we cannot send activation, email and exactly same situation if we cannot send it than art to errors for the email field technical problem and then exception again, it takes us straight to the Scotch block. Otherwise, we prepared the message and then pass it through with the response again in adjacent formats. That message associated with the index massive so I can be displayed on the page so that sits air for this activation methods. Now, in the next video, we are going to start working on the scent activation email method 23. Mail component (Part 1): continuing where we've left in the previous video. Let's now our implementation off this sent activation email method. First of all, it's type in disuse argument. It's going to be e. Instance off the user class and what it will return is going to be bullion. So let's just out some dog blocks here. It takes parameter user returns bullion, and we will simply say, Send octave ation email. Now, within this methods, we are first going to reset the token on the users. So user reset talking. So let's quickly have a look at what this method does. As you may remember, we obviously created this matter in one of the previous videos. We are setting the token field to email address, which is around through this MD five function, and then we save it. So that's, ah, record this persistent to the database. So now we have this token within the database associated with this given user, and we retain this token so you can actually use it with whatever else we my need outside of this method. But in this specific case, we don't need to start it in any variable. We just want to reset it and we ignore whatever dismantle returns. So after this, we going to return this, send email, and we passed this user through as an argument. So again, another method. Let's just aren't there. Method stop because we won't be working with this method until we actually create the male component for our system. I'm going to just type into this argument again here with user, and I'm going to other dog blocks. So they are already for when we are going to be ready to work with its it returns bullion and the summer will simply say, Send email. Okay, we can now save and closest register controller. We can save this user. Open the file browser, navigate to our tests. We're going to start with the unit Dan Utilities, And this time, when you test is going to be called male, test some mail test. He returned. Make sure that it's within the up test unit utilities named Space, and it extends our base case. Now, before we do anything else, let's open up direct trade. Then we have utilities, and under the utilities, we are going to create a new directory called Mail, which is where our male component is going to be located now. We're going to start with a new PHP class called Male Manager, and it's within their up within the up on then you Teeley t's and male name space. I want male Manager will work as a bashing factory for us to generate the instance off the new A male class. So we're going to start with a public static function called Make. It will take an array off parameters by default is going to be an empty, eerie and then we go to start the class name equals and then static glass name the method, which we create stray away as well. So this private static class name methods will simply take the driver first of all, which will be taken from dot e n V get and then index. If we just scroll up open to stop envy, you'll see we have a male driver here by default. It's set to SMTP if I just copy this male driver and I'm going to show you something just a moment, and if it doesn't exist, if we cannot finish them, the value associated with this very able then we're going to set it by default toe s m t p And let me just show you another thing. If we are within the testing environment, if we open this PHP unit, you will see that male driver he has sent to test. So within the life environment we have SMTP But when we are testing it, this variable will be overridden and it's going to be set to test. So we get in the driver which is going to be basically string lower case or letters. And now let's return their name Space comb coordinated with two box lashes and then you see first for the driver. So this will convert this SMTP for instance to s mtp and test would be converted test and then we can coordinated with male and that's going to be the name off the class that will represent at a given driver. So, for instance, for something, he is going to be s m t p male full test. It's going to be test male and obviously prepared ended with the full name space. So we have now the class name space associated with variable. But before we do this, let's continue with this. Let's just off the dog book here, get qualifying class. Name s so we have a class name now we're going to return new class name and we passed any parameters that we want to pass to the constructor off this class. That's everything from within this Male Managers just quickly arts them dog blocks as well , and more will return each off. This male classes will extend the mayor class. So I'm going to art mail here. This class will be within the same directory, so let's just quickly create it, Male. And I'm going to leave this class for the time being just like this. And for the summer of this method, I'm going to get instance off the male class. Kellett save its and closed the smell manager because that's all we need to do for from within this class. We only need a dis factor method which will return the instance off them. Correct. Male class will have either SMTP or the test male, so let's just create this tray ways. Well, it's going to be SMTP mail which will extend mayor class who can save it and close it and then we're going to half best male which will also extend this male class. Okay, save it and close it. So now what we can do is to register a binding for this male component with the container. And I'm going to do this within the base clock, A case class from within this set up before class method. When we have this instances off there, the other objects bind it to them to the container. And now instance, if I just click on this methods just so you understand what this instance method does, it registers an existing instance as shared in a container. What that means is that every time you are going to call, contain a make and then provide the index, for instance, request or guard, it will give you the same instance off the class. Now, what I want to do for the mayor class, because every time we're going to send mail, I want to have a new instance of the class I need to use the bind method instead. So static container then bind. And I wants to identify this item by index male, and I'm going to use the closure here, function toe, basically return a male manager and then make method which will get me what I want, which will get Give me the instance off the mayor class every time I'm going to call contain a make with the mail as an argument, I'm going to get the new one because closure here will returned the new class every time I call it, rather than having the same instance as we with the request and God would request. And the guard a single instance is just fine because we don't need toe rare. Instance she ate this class is every time we we call them. One instance is just fine to use with the application. But when it comes to the male, obviously, every time you create a new male, you would like to have a new instance off the male class. Okay. In the same time, same thing. Now, while we at it, let's just open our public index dot PHP and also audit here. So container bind male and then disclosure function. And from within this function, we're going to return mail manager make without any arguments, and I'm going to import this male manager here, so we have it right at the top. Okay, and knots everything from within this index. The beach be so this can save it and closest. So now when we are within our test glass, we can create a new test and then call it static container make male, and that will give us the instance The new instance off the mayor class every time we call it like this. So the first test we're going to write will verify that we can actually set there from property on the male instance. So public function correctly sets from property. Let's make it out test and we start with male static container make male. And now we have an instance off a new mayor class. We start with male art. From there we go for in four from inform SSD tutorials that come and then SST tutorials. First we check in that we can set it as two separate strings and then we go for this assert equals and we're expecting to get in for S S d t tall. Yeah, else don't come associated with SST tutorials and we expect to get it when we call it me. Just moving on new line. Let's invent it when we call mail get from method. And if it fails, then we're going to say single male out from cold failed to set their from property single because it's the 1st 1 that we are adding to the list off from Fields. You can have multiple ones. So let's ah, run this test, which will obviously fail. So PHP unit and we're going to run just this one. So tests unit utilities, male test and there we go, obviously culture and to find a method art from Okay, so let's open. I'm just going to close this base case. Let's open our mail class. The first thing we are going to do from within our mayor glass is to convert it to an abstract one. So abstract class mail. We weren't being satiating this class on its own. It's always going to be through one of those sub classes. See this SMTP maaloul test mail and we're going to start await protected from field, which is going for a property which is going to be off the the array type. And I'm going to other constructor constructor Will. They're select none here. Constructor will take array off properties and let's just add it to the dog blocks as well and from within the construct of what I'm going to do. Sybron this bind method and it will pass through new collection illuminates support collection, and we passed this properties through as an argument. Now we don't have this bind method, but this bind method could potentially be used with many other classes. So what I'm going to do is to create a trait which will have this method in it. Under there, the up director. Let's create a new directory called Trades, which is where all our trades will be start, and the first trait we are going to create is going to be called Binder and the name spaces of Easy Up and then traits. Okay, and this is not a class. It's a trait like it can be used with many different classes, and from within this binder we're going to start with this protected function bind. It takes collection of items. This collection illuminates support one. So ah, let's go for a collection and what we're going to do here is check if collection is empty, then there's nothing for us to do. Suggest to return and otherwise what we going to do is run through those through This collection is a collection filter, and the callable will be the method within this trade. So this and the method name will be filter bindings. And then once we have the correct records, once we felt it, all these properties and Dan, what we want to run is each method on all of these values again delegating this to the internal method called Bind Pro per teas. And that's it from within. Our bind method lets out thes additional methods, so but filtered bindings. First of all, it's going to be a public function field. The bindings We're going to have a value as the first argument and in key as the second. And what we need to do is to check whether the property with this with name, which is going to be stored within the key, exists on the given object. Instance. So return array. Sorry. No, every property exists and we give the instance of the object and then name off the property that we after so key and the other methods. So this will basically eliminate any interests within our the year aid that we passed through is an argument to this constructor, which aren't represented by the property on the male class instance. Obviously SMTP and tests as well, because they will extend this mayor class. Okay, so that's filter bindings. The other one is buying properties, so the other one is going to be public function. Bind properties and we have value again. End a key as well. And here we simply do this. Then, in between a curly brackets or without, it's up to you. I will use Kelly Black. It's here key, which is going to be representing the property name and then the value we want to associate with it. And that's everything with the straight. So that's just quickly out some Doug books for its It takes collection and it doesn't return anything. So return, avoid and bind properties. Then we have field to bindings, a returns bullion. If using PHP seven. You can art bully and he as well, obviously I started discourse without this return statements. I just continue the same way and then we have the key will be of a string time. Their value might be anything so mixed, and somebody will get Onley items that represent existing pro for T's and and for the bind properties it the parameters will be value will be mixed again. Key is going to be of a string type and summary is going to be bind Vaal View to that pro purty with the property on to the property. I'm going to give it like this. OK, so that's our binding completed. So let's now save it and close it now from within the May classy lets users bindis. So use binder. There we go. Make sure that you import does bind at the top. My idea automatically did it. So as you can see now, this bind method isn't highlighted anymore because we have access to it now what happens with our tests? We still haven't got this art from and get from methods. So we've got a constructive sorted within our male class. Let's now art this art from and get from methods which is basically a set and get because our properties are all protected. So in order to get the valley associated with the given property, we need to have basically mutates and access er oak set and get her. Let's start with a public function. Art from their first argument is going to be email, and the second will be named, which, by default is going to be said to know email is going to be required. Name not. And then we go into delegate the cult of this email name methods. And we passed email as first argument that name a second argument ended the property we want to associate it with. So this from we don't have this email name method yet, But before we do this, let's create this getter as well. For this Ah, from property public function Get from And this will simply return this from Let's out some dog blocks to it as well. It takes email, which is off a string type name is going to be even know off string as well. And we are going to say out from option no art from No, I think I'm going to keep it like this. Okay. And then returns Ray, get from option. Okay, so lets out this email name effort, But before we do this, I've just noticed this email. It's, um, attribute Might be of a string tie, but it might also be in the rain. So let's put the pipe here and specified in my being areas. Well, okay, email name. And I'm going to move this method before this art from And what we going to have? He s email name is going to be no by default, and then this from we're going to convert to property, but it will be passed through is a reference or property so that we can actually affect whatever we are passing through a zoo. This third argument, Sophie, passing this property here, then we will be able to art to this property bicycle to this array. Okay, so from here, we're going to check if ISS array. I would drink this email actually got the email. Let's make it emails and the same here for this from emails, emails, emails. Because it might be, they might be more to multiple emails than just one. So if it's an array, then we're going to delegated this to another methods email name, array. And we passed this e mails through as an argument and then just a property because we know going to be bothered with the name at this point. If it's in the raid and we know the second arguments. Not gonna be there. Okay? And after this, we just hit return. So we terminate here. Otherwise we're gonna go for name equals. If iss not Exclamation mark is no name, then we use it. So name. Otherwise, we're going to use emails. So we basically going to later on associated with the property? E mails equals name. So in this case, obviously, if it's in the ray, we going to delegated to another methods. But if it's not, then we check if the name is not know, at which point we are going to use it. Otherwise, we're going to use email basic. So if we pass through Justin email, then we're going to have it for the key and the value. Okay, Lets out this email name every methods up, private function, email name, Ray. And this one will take array off emails. This time we know it's in the ray at this point. And then again, reference property. Okay, And here we're going to do is run before each Ah, emails s email equals name and the brackets. And the first thing we're going to do here is trek. If their key which is this email here is off a string type. So if if it's not string email, then we are going to use the name as email. So email equals name, and Dan was simply associated with the property. So property email on name. Let me just explain what happens here. So we looking through these emails and we could pass these emails. Aziz, this first argument to this email name in the falling format, We could have it as in for me dot com, for instance, and then name. We could also pass. It s just email address. We could have obviously passed this string as well, which obviously would then trigger this following statements on Azzan array. We can have have it either as a single ah array item all have it. Associate it with the value so it could have email is the key, and in name is value. If you pass it like this, then obviously this email here will be represented by this index and name will be represented by the name. At this point, this will fail and was simply passed the email to as a key and the name as the value of this array for the products, obviously property, whichever property were passing through at this point, we are in this specific case we for the art from were passing this from property. But if we pass it on Lee as an email without associating strictly associate in any case, then this condition here isn't string will be will evaluate to True, because by default, a PHP will associate numerical value for the key. At which point, obviously, this email here key will be over written with the name which a name now is represented by this image is because values I represent when we don't have a multi dimensional race, then obviously keys on the miracle and values are wherever we are passing through. So this name now becomes this email. And this is why we associating this name with the email to then pass it as a key. And then we would have bicycle email equals email in this case. Okay, so that's what this method does. Let's now out some Douglas here. Ah, Ray off emails. Property is going to be off theory type as well. And what it does s so she ate a ray off email pro purty types. And for our email name some Doug Brooks here as well. Property is going to be off the ray type. Name is going to be the new or string e mails is going to be either string all Ray and for the summer list at associate email property type. Okay, so now, at this point, our way out from and get from shoot work. So let's run the test again and we go one test one a session. Let's now go back to our test and out all these other case and I So we are going to a new one. I'm going to duplicate this out from undead assertion and for the art. From this time, I'm going to only pass email address and what I expect to get. It's not going to be informed because we already have this index I'm going to outset now, and what I should have at this point is Sepp equals Cepsa. Email equals email, and this is Cole to set the second property from property. Let's save it and run it. Then we go one test to a session, so that works fine. Now if we try again, let's duplicate this the next ah way that we can pass values through as arguments is going to be using the array like this. And let's change this name to say Nathan now equals Nathan Selenski, for instance, and how we are expecting to get it now with the previous records, it should be like this with passing key and in the value, and that's how it should be as we should. And let's just change the message, said Death, Third from Property. Let's run the test and we go three associations, all of which are passing, which is great. Back to the the editor. The next way that we can actually pass this value through would be as just email address within the array. So let's do it like this. Now it's change name to say, Crease, so we would expect it to be this way, and that's fourth attempt. Save it tested. There we go for assertions, and the last one we're going to test if you just out duplicate all this, we haven't say beats and then another one after this comma, let's say Josh, So what we should have now would be Pete equal speed and then Josh schools, Josh, Dairy and nuts there for fifth attempt. Okay, save it. Run the test. And all of these are working just fine. So, as you can see, there are so many different ways that you can pass argument to this art from method now, and they all should work just fine. 24. Mail component (Part 2): in a previous video. We've written a test and the implementation for two methods Way one which sets, and the other one which obtains the value stored within from property off the male class. In this video, we're going to do very similar thing about this time for the two property. So let's first of all, what I'm going to this copied this entire test here that we've done in the previous video. So just duplicate it. I'm going to rename it correctly, set to property, and this time, rather than having out from, we're going to have art to. And let's just replace it everywhere we have here, so get from is going toe become get to as well, and that's renamed the message Es are single male art to call failed. And if we scroll down, not to get too and not to out to get to and aren't too same here and not super the message and one small get to and not to. And if we open the terminal and try and run the test, there we go. We've got cold, too. Undefined methods are too, so let's open our mail class and let's create this public function art to. It's going to take e mails and the name same thing as we had with our art. From and down is going to run this team male name. It's going to go for e mails, then name. And the last thing is going to be This sum is going to be to property, which we don't have yet. So let's quickly audit after our from property another protected 12 which is off the array type as well. Okay, if we scroll down now, let's art. Some dog looks here, so it's going to say name is going to be No. All string e mails is going to be string all array and for the summary, what did we do? Hear art from option We're going to say art two option and then to obtain a value stored within this to property, we're going to have public function get to which simply returns this to and again dog looks And if we say get to option and if we know open terminal and run noticed again and there we go. We have to tests 10 assertions, all of which are passing. So that was pretty quick as you can see. Okay, The next property we're going to work with is going to be a subject of the email. So protected subject and it's going to be a string type. Solve our string scroll down. We need to get We need to art the set and get her for this property as well. So, public function set subject, subject as argument here. And we're going to go for this subject, uh, equals subject. And let's out. Some dough blocks are subject is going to be a string type. It returns avoid. We're gonna go for set subject off the message, and then we're going to have a getter. So public function, get subject return this subject and the doc block will say, get subject off the message. Okay, Now, let's quickly right. Some test fully as well. So back to male test scroll down, create a few new lines, and we're going to start with public function correctly. SATs subject property and let's make it a test scroll up. Okay, We're going to start again with a male ah, static container make mail. And now on this male, we are going to set subjects or set subject and we're going to set. It's a test subject, and now we're going to do is drawn. The association's assert equals and should be test subject when we try to obtain that by using Male and then get subject and in the message will say, Mail said Subject. Cole failed to set the subject property. So object, There we go. Okay, now, if we save it and around the test again anyway, here we have three tests, 11 assertions. So that's our subject property. And let's quickly create another test, this time for the body properties of public function. Call directly sets body property and we don't again. Let's make it a test three way and let's start with again. I'm going to copy what we've got here, and I just rename all this. So rather than sitting this subject, the method will be said body and is going to be, say, test body and should get test body when we co get body method and a message should say a male set body. Cole failed to sit there body property. And while we own it, let's scroll up. Obviously, for this to correctly sets to a property I've forgotten to update these messages correctly because we have the method, right? But then coal fell to said there rather than from should be to property and against second to property, third to property, fourth to property and fifth to property. Okay, so this test is now ready. Let's run. Obviously, it's going to fail. Turning as the said body, a method does not exist. So let's go back to our mail a class, and we are going to start with you, Maitham going to create a few new allies as well. Here, we're going to start with public functions. Set body with sake. Body is argument is the first argument that 2nd 1 is going to be HTM l by default, we going to set it to true so that all our emails, by default will be in html format. So we start with this body equals body, and then this HTML equals html and let's out some dog blocks here. Body is going to be of a string type, and HTML is going to be off them. A bullion type lets out. Some summer has set body off that message, and now I'm going to quickly split the screen scroll up as that I can. Aren't this body in HTML properties so protected body? It's going to be a string type and then we have protected HTM l, which is going to be bullion. And let's set it by default to True as well. Okay, so now one thing, if I just say that enclosed this split screen here, one thing that might come useful is when we run this setter methods. We could probably return the instance off itself so that we can change them rather than actually putting using the instance off the object on the next line and then associating there Call with the method. So what I'm going to do here, starting with art from I'm going to simply return this so returning itself. And let's update the dog blocky as well. Let's end. This is going to copy this for art to the same thing and lets the updated dog look as well set subject exactly same thing, and it's going to brother returned. Void is going to be this. And then we have said body, we going to do the same thing and it will return itself is well okay now for to obtain the values stored within the body. Property regard. Teoh, Create public function, get body and it's going to simply return this body. And then let's just not dog block. It will return. String and summary should say Get body off the message, you know, save it, run a test again and we have full tests. 12 sessions, all of which are passing. So let's not go back to our any term. And the next method we going to answer where male class is going to be protected function H T M L, which will simply return string on all based on whether our html property it's truffle. So if it's true, what we going to return is going to be Text html otherwise will return. No. Okay, so that's just duck looks he as well and get content type. This is going to be a second argument later on, when we going to be using swift mail to pass through to the said body method. Okay. Ah, public function reset, which will on our story set all properties. So this from equals Justin Empty array. Then we have this two equals and empty a. Then we have this subject will equal, just know. And this body would also be no by default. And then this HTML it will be true by default as well. Okay, let's just not some dog look here. Ah, written is avoid so return void every set, all properties off the objects. Now the next method we're going to create will be called validates or protected function. Validate. This method will basically take care of validating a message before it's going to be sent. So we're going to sir first check if exclamation mark this check, then we going to throw and you exceptions saying message is incomplete. Let's just import this exception. So just to show you what's helping here when I imported this obviously this ah use statement has been at its right before the class declaration. Okay, now this check methods, let's just out the method stops just to go through this valley date once again. So if check didn't pass, then we're going to throw exception. That's what this valley that method will, though, So let's not some don't block straight away as well. It's ah will return void because it doesn't return anything. Check if message is valid and now the check here. We are going to return any between the brackets. I'm we're going to have several conditions. Exclamation mark empty if isn't empty. This from property and isn't empty this to property and isn't empty. This subject property and is an empty this body property. All of them have to have values. Associate it if we want to send an email, otherwise this will fail and a the exception is going to be thrown. Okay, lets out some dog Lucky as well returns bullion So we go for check if message is ready to be sent and the last method is going to be an abstract methods Ah, any class dart extends this male close will have to implement it so abstract Ah, public function sent and implementation details will be down to the class that extends in this subclass is so and it really will return interject indicating a number of messages that have been sent zero will indicate that the scent has felt so sent a message and that's it for this male classify. Just remove this redundant space here Let's save and close this file and continue in the following video 25. Smtp transport: Let's no open the SMTP mail, which will find under the up utilities mail directory SMTP mail. And as you can see, it's automatically highlighted by my i d saying that obviously class must be declared abstract or implement method send, which is obviously contract on this abstract male class. So let's just add the methods stop here and we are going to start with there, try and catch statements so catch and from within the couch we going to count just the standard exception represented by the variable, and I'm going to import this exception straight away. So we have this use statement right before the class declaration, okay, from within the try, we're going to start with this validate before we send anything we need to make sure the obviously to from subject and body properties have valleys associated. That's why we call in this validate method and then we're going to return this execute. And then we passed this message to it. And before we create both of these methods, let's just go to the their catch statement, and we're going to simply do this exception. We go into our disprove it in just a moment. We're going to get the message from the exception. So get message why the message has been returned with the exception and then return zero indicating that obviously this send method felt. And this exception I'm going to add to the male class because we might be using the same thing with them with the other classes that will extend this male class so protected, exceptional is going to be just a string. So string save it and close this mayor class. And now let's aren't methods. Steps for this execute and the message methods, and this execute will take a message, which is going to be off this whiffed message. Instance. Let's import this class as well. So that's the use statements out before the classes were again. And what we're going to do from here is going to be Mailer. We instance she ate the new Melissa Swift, Underscore Mailer new instance, and we passed this transport ah to it as an argument methods which will create in just a moment as well and now swift male. If we just import this class as well so that we can swift Male, I write it up and now what? I'm going to do is simply return. Male ever sent and message, which has been passed through, is an argument. Let's quickly our dog blocks for this method as well. And we say pro says message, then for the message itself. What we going to do here is actually, before we do the messages that this transport, perhaps we start with the transport equals are swift, swift on the skull, SMT peak transport and then a new instance. And we going to then use this transport instance and chains set of methods set host first, and it's going to be taken from the environment. Variables You may remember if we opened this dot PNV file, you'll see that we have this male driver host, part user name, password and encryption and these variables that we're going to be using here. So we start with adult envy, get methods, and we go for male on the skull host and then we chainat ah ah set port, which has gone to adult E n V again, get and distant of are you boys male on this cold point? Then we have set user name, which is going to be adult and the get mail. You know, I'm just going to open this file here, and I'm going to call copy oldest cause I have a tendency off misspelling things and then duplicate this line set. Ah, boss word. And I'm just going to copy this male passwords valuable, he as well. And after this one, I'm going to this check if isn't empty, and then encryption very able. And we associated with dot e n v get. And we're gonna try and get the very able this male encryption through. And if it's not empty them, we are going to use this transport and then set encryption method passing this encryption viable through as an arguments. Now, what happened here? Basically, we check in with the whether it's not empty bicycles variable, and at the same time, we associating the value off it with this encryption valuable, which gives us an option to stray away, use it if from within these brackets, or if we want to use it. Obviously, outside of this, if statement as well, okay. And then at the end, we going to return at this transport instance so I can then be passed in this new instance method off this swift mailer. Okay, lets import this SMTP transport as well. So again we have it up here and ah no, it's just got some good books and return swift SMTP transport and get transport Instance. And the last methods we have this message he are we going to start with message equal swift ? Ah, message and again new instance We don't pass any arguments and then we start with them Message set from And we passed this from property and then again, we're going to change it here, set to this to property den Set. Uh, said subject, it's going to be this subject and the last one is going to be set body and we're going to do this body and then our dis HTM l methods which will return if we just go back to this method. If html property has been set to true, it will return text html indicating that we want to send a message to HTML. Otherwise it's going to return, nor which will indicates just a plain text email, Okay? And the last thing we need to return here is the message. So this return message There we go. And let's just out some Doug book here as well returns message and build message for the summary and not should. Now our work just fine Now for the testing. We need this test mail to do exactly same thing. Obviously, rather than processing email, we are going to just fake that we're sending it. So I'm just going to close all these files open test male. And from within the test May we're going to start the same way as we did in SMTP mail. We just create descend methods and again try and catch statement with the exception and from within exception. Same thing as we did in the other ones of this exception, we associate the message which has been thrown, so get message and then return zero, indicating that obviously execution of this method has felt. And from here, we're going to do again validations of validates about rather than processing them male. We just return Count off this to to say the harmony that many emails have been sent by city depending on how many emails there are associated with this to property that many we go into. The number of is indicating how many were going to return from within this tribe Lock on this. Obviously, validation fails. At which point we're going to return. No. OK, so that's our test male. Let's knock saving close it and open our test. So going back to tests, units, utilities and male test and we're going to first asked whether the send met it fell So public function are sent fails with involved para meters test and we are going to start again with the instance station off them male components a male equals static. Ah, container make mail and l'm Iran. This assert equals zero when we run mail sent because we obviously didn't associate any properties, any values with the properties. So a message is going to say mail send did not return falls with involved Paara meters. This is obviously when this cessation fails, so let's save it. Run a test and we go five test 39 stations which indicates that it works fine. Next decision is going to be this assert equals and the message that we should get, which is going to be message is incomplete when we run mail when we call male and then the exception property on it. But now I just remembered that if we go bark, open our utilities mail and the mail class, you'll see that our exception property is actually protected. Let's make it public. So we can access is from the outside on message will say a male sent did not set exception property on failure. If we save it. Rana, test again. Five test 40 No stations, all of which are passing, which is great. So next we're going to test with a message, actually sends an email and it passes. So succeeds, in other words, so public function Send sex seeds. Ah, with volleyed para meters and test stock. Let's scroll up a little bit, Um, and what we're going to start with again the same thing. So I'm just going to actually copy this instance station and then we run straight on it, actually, weaken chain it. So let's just go for it. Art from we going to art in for SST tutorials Don't come with the name s is the tutorials. Then I'm going to add in Actually, no, let's go for art. So which is going to go to Sepp SSD? Tutorials don't come and it's going to be Sebastiano Solden ski and I'm going to duplicate this. We're gonna have to recipients is going to be Nathan eyes going to be a 2nd 1 So, Nathan, then we are going to have set subject test email and last thing, we're going to have a set body which is going to body. I'll test body, never go. And then assertion dis assert equals and we should have to Recipients passing mail sent. And then the message should be mail sent. Did not return. Ah, true. Would volleyed Barra meters. Okay, lets try and run this test. And we have six test 15 Alsatians, all of which are passing. So our tests are now completed. Our male component is ready to work with. So in the following video we are going to go back to our registration controller. 26. Account activation: now, with our male component ready, Weiqing, continue with our bridges to control it. First thing I'm going to check this Send email is actually going to return integer because our send method will do that. The same thing for this sinned. Activation email. It's not going to be bullion is going to be an interject, but that's all fine. If we check our previous method, which is this activation, it checks for negativity of this sent activation email which will return into Jeffrey zero . This will still, uh, evaluates to true, because zero when converted Teoh bullion, it returns false. Okay, so let's go back to our send mail methods and from within the send mail method, what we going to do it? Simply return. And then this container, we're going to get instance of the male components on make and then mail, and we going to stray away chainat using art from methods. And we're going to art adult e envied and get. And we have if we just open our envy file, we have business name and email. So email ghost first here. So get business email and comma and get business name. So this is going to be a send that email and name. Obviously, you can fetch it from a database if you have a system in place which stores this sort of details in the database all anywhere else, we are fetching this directly from this. Don't envy back from the environment variables which this dotty envy file. Obviously, uh, when it's parts on when we actually bootstrapping our application, it's obviously setting these variables. Okay, next is going to be art to the recipient is going to be user and this user's email address or email property and then user its name. Then we're gonna go for set subject and subject of this message will simply be activate account. Then we're gonna go for set, body and body will be. We will get their content of the body from within the internal method again, a message body. And we pass user as an argument here. And Dan was simply call send methods on it. So now let's out this message body method and it's sex use instance all its type, ain't it, user? And from within this method, we going to start with the u r l that we want to send with air within this email. It's going to be this request and we get route, which is going to give us our domain name. Proceeded with the protocol and and colon and to Ford's lashes and then activate, which is going to refer toa, the activate controller and then token as square string, which is going to be user and then talking, which we obviously, if we just scroll up, you'll see with just reset. Reset it on this user instance before we pass it through as an argument to the Sendmail and then obviously subsequently to this message body. OK, so that's our u R l. And then out variable we're going to start with. We can start with a paragraph, please click the link below in order to activate your account. It's a closing partner, and then let's concatenation did. And I'm going to close the file browser on the left. Ah, with the uncle Talk with a treff, which is going to link to this u R L R l. And then concatenation disclosed the a trip talk. Then Target said it to Blunk. And let's close the opening uncle talk than out you want l is going to be displayed in between the opening and closing Uncle Zach and then outlets close it. So that's our link with the message above. And we can obviously now return this out. Variable the case. That's our complete message. Let's now are some dark books again? Returned stream takes use as argument. Get message body. Okay, so I wear register. Control is now completed. I'm just going to remove these redundant space here and in order to test it if we know, save it and close it. Make sure that you feel in this section here, you need to obtain some SMTP credentials in order to be able to deliver your email address . Without this, your email distribution will fail and obviously your registration activation email will not be delivered. Now before we go in, test it of one thing that I've noticed the for. Gotten to do it within the register controller. A post method. If we scroll down this catch exception statement rather than just returning new Jason response should also call method, send headers and then get content. Otherwise, it's not gonna work as expected. So fleece now, save it and close it. We can go back to the browser and feeling a where registration form with some data on. Then we go on go dictatorial, some password hit return and there we go. It's processing. This should now send an email and gives us a message, as expected, to figure back toe a mailbox. There we go, our message with the activation link. If you click on this link, obviously we don't have this activate control yet. That's why we see the dynamic page. Let's go back to our editor and that's creatives controller quickly sunder than the up controllers. Let's create a new one. Let's call it, Activate controller and it's under up control his name space. It extends our controller main controller, and what we going to do next is start with the public function index, which is the default action that's going to be triggered. Then we're going to go for this activate method, and then we're going to return this view, and the view is going to be pages activate. We obviously don't have this activate method yet. It's going to be a very simple methods. Well, first of all will be going to just obtain the token from the request, so token and this request get token, which has Bean sent through as a query string. And then we're going to check if empty Dokan or is no. And then we create instance of the user. We associate it with a user. By token, we passed this token through is an argument, and then we get the first the record. Let me just explain in just a second what's happening here again. I'm going to import this up models user. So first of all, we checking whether the token is found within their career string. If we go back to the browser, you'll see we have this. So can item here with the token. So now we're trying to identify the record of the user with this token. So if we go back to them the editor s O, If it's empty, then obviously there's something wrong or we cannot find the user. By this token, if it's know if this user, by token, first returns No, we associate industry, where with the variable here. So we have instance in case that fails and obviously the user has been found. Eso, if that happens, will be going to this throw the exception. So throw new exception. Just stand at one involved request. If we just import this exception as well, he also right here. That's help, Okay? And obviously, if that fails, that means the user has been found. The token is there, and we simply use this instance off the user and make this is active. Some make active method, which was created in one of the previous videos, and now, just before we actually call it, Let's just have the dog blocks. But also it's going to return a view. Let's import this class. I'm not bothered with this factor. He just of you. And for the summer we're going to say Display our activation page. Then for the activate methods we are going to have throws. Exception returns void because there's nothing being returned from this method and then activate user. There we go. OK, so that's our controller. Activates controller completed. Let's before. Actually, we do anything. Let's go back to our database to refresh the page. Refresh the table. The year user stable. You can see activists set to no zero passwords. Then we have this token by which we later on trying to identify the record. If we go back to our Bradley. See, this is the token which has been obviously associated with Stoke in property here. So now if I refresh this page there we go Account activated. If I go back to our table reference, the record you can see active has been said to one. The token has been said to know and the record is no active, so you should be able to log in if you just go try and log in. So it was s. The Tories was just passed. Word heat return And there we go. We are redirected to the dashboard, so registration and logging works just fine. Now one other thing. Let's now I'm going to go back. Remove this record from the table. So we have We don't have any records here. Now. If we were trying to log out by clicking this local button, it will take us to the local roots, obviously, but it will not lock us out. That's the only problem. So let's go back to the editor. Let's creating new control. I called log out controller. So log out, controller! And on this controller, we going Let's just quickly extent controller and lets out. The only method is going to be within this controller, which is going to be index So Public function index, which is obviously the default action that's triggered when we call the controller. Then this guard. We're going to use a log out so we look the user out and then the return new redirect response and we're looking for this illuminate HDP response. We passed the path where we want to redirect the user, which is going to be just affords large to the plane domain and then send method to execute it. And let's just out some dog blocks. Here it returns this symphony component HDB Foundation response. So import this class and log user out and redirect to the log in page. Save it, close it. We can also close this activate controller if we go back to the browse. And now, if I refresh the page bean on the law, guilt roads are just by clicking. Log out again. You'll see that that logged me out and redirected me back to their logging screen. So what I want to test now is this option where we trying to register with the email address that's already within the database. And then, obviously we get this link to resend the activation email. Let's try and register again. And if we hit register, don't shoot out the records of database and sent an email again. And if we check our mailbox, there we go. Email is here, but I'm going to ignore this. First email. Check our database. Refresh the table. There we go. We've got inactive record here. Let's go back and try and register again with the same debt details. So I'm just going to use the same email and password they were going. If I hit register, you see that? This tells me this intelligence is already taken, but it doesn't tell me anything about the activation email, and this is because of Register form. Doesn't have this option. It's only when we actually get to the logging skin. If I now try and log in with the same email address and just use password hit return and there we go, your account has not being activated, so register form will tell us that this team is already taken, so someone's okay. So I'm going to the looking screen now because it's already registered. If you provide the email and password A on the inactive account, This will give you this message so you can click on this recent activation email. If you click on this one, you'll see that what will happen in just a second. There we go. We've got this confirmation message. Let's go back to our mailbox. And there we go. We've got two emails now, So we have. This is the latest one. This zero minutes ago. There we go. So if we expand it, you can see we have obviously this email with the talk. And if I click on this one now, I can obviously activate it. So with the logging, if you've forgotten to activated with the registration, you can still get dis activation. Ah, email. When you try and log in in the last thing I want to test is this registration without sending this activation email. So let's go back to the database, make sure that you've removed older records. So any records that you going to be using for testing, then back to the editor, open our dot e n v file, and we are going to change the value associated with this verification variable too false this time. So that means obviously, we don't want Ah, the activation email to be sent. Just a registered them are the records of the database and lock the user straight in. OK, and I'm again going to feeling this form with same data. Any food register. Now you'll see that's much quicker. We stray away, see the dashboard page. If we check our mailbox, there's no email here. We are obviously locked in. If we just go back to the previous page, you can see that if we access register page, we automatically redirected to the dashboard paid because we have this method from within. Both off the controllers logging controller. We have this for the constructor. We have this redirect, a flocked in and same goals for this register controller, which means, obviously, if you are, if they use is locked in, make sure that they can't access log in a registration page. So if we save register and logging on, if we check our database refresh, you can see activists still said to know 20 talking. It's said to no, but now we obviously don't require activation because we strictly said it to false is verification. That's why our logging now doesn't carry of the ah, the active field has flock. Sits to one all zero. Okay, so that's it. In this video, our registration and logging are now completed. In the next video, we're going to have a look at the four goat password section. 27. Forgot Password: before we start working on our for guilt password controller, let's first have a look at what we actually get when we are on the dashboard page. And at the moment it just loads this dynamic page content for page with slag dashboard. And it is because we don't have our dashboard controller created yet. So let's quickly go back to our at its, um, and if we create a new controller and call it dashboard, control him and it is within the name space up Controllers and proceed extends our stand up controller. And what we're going to have here is just a public function index, and then this authorized to make should. Obviously we have access to the dartboard because if you click on this, authorized what it does, it checks if uses authenticated. And if it is, it's simply returns. No. But if it's not authenticated, in other words, if it's not lock, then then it rid our eggs them back to their logging page. So first of all, we obviously have to make sure that we restrict access to this page and then return this view. We pass pages dash Bert, then with user, and we're gonna set this guard user to deceive you so we can use this user variable. Okay, let's now are some dog blocks returns of you and what it's we're gonna sit here, index. Actually, no index. Um display dash board page. Okay. And let's quickly go to the resource is to see what we actually have in his views of use pages and dodge birth. And what it say has hereby, Stickley's this heading with the Dodge. But and then welcome back and we have using name in brackets. So that's convert. It's too the ah blade brackets and then have this user which instance is going to be sent through to this view when we used this with methods on the view and then user name. Let's do it like this. Okay, save it. Now go back to the Browns to refresh the page. And there we go. Dashboards. Welcome box about things, Sunnis. And there we go. So that's how with dashboard page completed, Obviously you cannot as many things as you want here. But for the for this simple exercise, that's all we're going to do with the dashboard. Okay? We cannot save and close all these files. Now the next controller that we need to create is there for goat controllers. So new PHP class for gold controller. And this one will also extend control. Our forgot password form will have only one fields which is where user will be able to put in at their registered registered in l. A. Just so protected rules will be in the ray off. Only one item email and validation Rules are it needs to be presence are required and and pipe. It also needs to be a valid email address or email. And in semicolon, let's aren't some dark block here is in the ray. Okay, then for the constructor when the constructors called protected function con structure. But this one we are going to make sure that obviously you can only access this page if you are not locked in. If you are logged in, you shouldn't be able to access it. So redirect if locked in and again, that's not some dog. Look here, it returns void, and then the message will be aren't to parent constructor. Okay on now, next thing is the index methods of Public Function Index, and I'm just going to screw up a little bit on and from within the index. What I'm going to do simply return this view is going to be pages for God's. And it's about Doug looks as well. It returns. View Guntram off this factor from here and then display for gold password form. Save it and just make sure that we see you import. This eliminates view of you here at the top as well and go back to the browser. If we go to forgot password now, we obviously cannot access it because I'm still locked in. If I click on, log out and now access the forgot password, you see that we we can see this form if I could sum it without adding anything in, Obviously, validation kicks in. If we go back to Dan de Edits El Re sources views pages and den dis for gold blades dot PHP You can see action for this form is for God polls, so we will have to have dispose method them. Then after submission, it will fall. Fade out with the message and this is the form. Obviously our label with validation obviously a mass suggest an import and batons, plus the confirmation container. OK, so that's our form. Ready? No. Next thing we need to do is to out this post methods. So let's start with public function. Post polls. There we go. And what we going to the first round? This post request on Lee. We don't want to allow any other request methods on the pulse of there's a get not should throw the exception. Then try catch block and we're going to be catching exception represented by Vardy Able E Let's import this exception as well. Here. There we go, Right, it's up. Okay. And now, from within the exception from this couch statement, we're going to return new Jason response, and this one will take this errors. And the second argument will be response the symphony components because we have it already imported here and then unprocessed herbal. So H TTP unprocessed herbal entity, which is fall to two. And after this, we're going to call, sent Heather's and then get content. So that's our catch statement for the try. We're going to start with this collect request and the items we're interested in is just email from now that we have data collected. Next thing we need to do is validate that data. So this validate request, then we're gonna go for user equals this volley date email method, which we don't have yet. So let's quickly add it. We are This method now validates email simply needs to check if this email exists. So we check if IHS no. And then we associate the returned instance of the user with the user viable equals user. And then we call method by email. We passed this input, which would just collect it email address from the input. And then we want to get the first records off first record on this user class on the Caesar , a model that's now import this user as well. So up models, user right here at the top. It's girl down. So if it's not know, then that means that obviously the user has been found. But if it is no, then obviously use is not found. In other words, someone's trying to reset password for non existing records. So this art error and we go for email field. So it's going to be despite about the email field in the form and an invalid flock. So once again, if I opened this forget for gold file here. This view you can see invalid means email not found. You can change this message of it to whatever else you'd like to. And then let's throw the exceptions of throw new exception. Any exception will say email does not exist. And otherwise, if a user is not know, that means we found the user by this email address. We going to simply return this user, and we can do it this way because again here, when we actually checking, if it's know, we automatically instance she ating this and associating this with the valuable users so we can return it here after all. Okay, lets aren't just some dog looks here. Ah, it throws exception returns user instance and a volley date email address. Okay, going back. What we need to do now Once we've got the instance of the user. If exclamation mark this sent email and then we pass user instance through is an argument. Then again, we go into this art arrow and December going to say email again above the email fields technique cold. That means the embassy email, for some strange reason, couldn't be sent and then we throw the exception again. Exception, and we're going to say sending email failed. And after this, we know that email has been sand so we can return the message. So return new Jason Response and this Jason response will have. Let's put the ray here with a message saying Police, check your email, Full your mailbox, perhaps mailbox for instructions on how to reset your password and full stop. And after this, let's just again sent Heathers and then get content, so that's pretty much it. We obviously don't have this sent email method. Yesalis quickly at it. Now it's the instance off the user that we getting through as an argument, and now here I was going to be very similar to what we had, some with the registration. So we start with return statement, then this container on this container from this container. Rather, we'd like to get the instance of the male components on Make Male, and then we can change it. So we're going to go for Utt from and is going to be again, same thing dot e n v get and a key, and it's if I just open this file again it's going to be business email, and then we're going to have the same but this some rather than business email. We're going to have business name. So that's, uh, who's sending this email basically the from field, then art to, and that's going to be user and his email address and then user and his name. So this is where we sending this email to. Then we have subjects or set subject and subject will be password reset request. And then we have set body and the body will be this message body and we pass user as an argument again. And then we simply want to send this message. So that's called the send Method. Now let's out some dog blocks and what we're going to say here, it's going to return. Interject As you may remember, the center method will return interject, So send email with instructions on how to reset your password. We can probably move this onto this line here. There we go. Ok, now we just don't have this message body. This is when we go on to create the message that we want to sense a user again and this one will be again u R l We're going to start because we need this link to click to take us to the reset password form this request we get root again, which is again going to give us the the protocol together with the domain name. Then reset question mark token equals and we're going to associate a new token at the same time as we actually resetting it. So user reset token. And if we opened this Elvis semi colony the end. If we go to this reset token, it says the token saves it to the database and then returns it. That's what we can do it in one go basically associates and reset at the same time. Okay, So then what we do is create our message again. Out is going to be within the paragraph. Please click the link. Be low in order to reset your password. Full stop closing paragraph, Semicolon tea and out again We concatenation this with and I'm going to close the far Browse on the left. So we have a little more room here we can coordinating this with the age eight talk h ref, and then out. Ah way. You aren't l then out again. Concatenation with closing double quote for the atria. Attribute targets on the scope blank Closed the opening A talk. Then out we go for U R L. I'll closing a tuck and then simply return it all. So that's our message. Now I'm going to remove all these one done in space because this is the last method within this controller. And let's out some dog. Look here as well, and we have string user and get message body. Okay, so ah, where Forgot Controller should now work just fine. So if we now go back to the browser on and before we do anything, just make sure that you have the existing record for which you want to reset password. And I'm going to stop me. This email address that I've been using Jr scores AC, heat on sub meats. And there we go. This is processing, So that should send an email in just a second. If we go back to check the mailbox, there we go. Password reset requests. If I check this email, you can see we have a link pointing to the reset, controlling them with a token, obviously. So if I click on this link. We, at the moment get just a dynamic page, and this is because we don't have this reset controller yet. Let's have a look at this in the following video. 28. Reset password: in a previous video of completed our Forgot password control and Needs video. We need to create this reset password, which is where uses redirected after clicking the link that's been sent through to the mailbox are using this forgot password form. Okay, so let's go back to their to the editor. We go into creating new controller. This one is going to be called a reset controller. And again, I needs to be within this name. Space up controllers. It extends controller, and the first thing we're going to do is to set the rules for the validation protected rules, which is in the ray. It's going to have password, which is required so required and pipe. It needs to be confirmed, meaning he needs to have this other field called password confirmation. And this possible confirmation is just re quiet. That's a look. And then what we going to do is override the constantly parent constructor cell protected function Constructor, we are to the constructor again. We need to make sure that whoever accessing this reset route is not already logged in. So we're going to call redirect if logged in, and it's our dog looks to this as well. It returns void and art to parent constructor. And after this one, we're going to have our index methods. Let's just shift it up a little bit. So Public Function Index and from within this method, we're going to start with a user equals this get user and then we're going to return this view. I was going to be pages reset and we going to art user decile with He was there as to user . So that's our index method of which we don't have this get use their methods. So let's just aren't this method stop what I'm going to do. He has just mounts the doc block returns view, which is this imminent view of you and display reset password form. And it also will ferro exception, and this is going to be handled. This exception will potentially be returned from within this get to use it method. Now he out. What I'm going to do is start with their token equals this request Get token and it's soaking again is taken from the query string. If you go back to the browser, you may remember we have this token within the query string. So if you go back to the editor once we've obtained the soaking, we're going to check if empty token. Ah ah is no. And in a user variable we associating instance of user so user models. By token, we passed this stock and through is an argument And then we want to obtain the first get the first record by the tokens of first. And if it's no off talking empty, then what we going to do this this art ero for password field? And, uh, basically, the aero message should be associated with a toke and index. And if we opened his research pages, we said So resource is views pages reset file. You'll see we have this token here which will say involved so can basically. And this form will submits for send the request basically reset controller to the pulse method with the given token. And we'll have a look at this in just a second. Now, obviously, we have this user here sent through to this view. So what we can do from within this view is to simply replace this talking within the square brackets with our blades, moustache stocks and use this user and then obviously token associated with this given user so that will upend this given token associated with this token entity within their Aquarius string. Okay, so we a lot of this era for the password. And then we also throw the exception to terminate, uh, this script so exception. And then we're going to say involved request and after this week, simply return user. No, if we got some dog blocks here as well, so throws exception returns, user instance and summary should say, get user. Instance No one thing if we scroll up and open and activate Controller. And I'm just going to split views here so you can see things a little bit better. You'll see that we have this activate method which uses very similar cult. We first obtained the token from the request. Then we check if token is empty. And if the user by this token is also no, and then we throw the exception from within the activate method on the activate controller . But on the get user, we throw the exception. But before this week, art error. So what we could probably do is extract chunk of disco this specific two lines he have 1st 1 when we actually pertaining to token from the request. And then when we checking for this token and whether the user is no. So perhaps we could extract it to a to a parent constructor and then used the methods within this. Activate and get user. Let's open our I'm going to Teoh close this split screen here. Let's open our control and what I'm going to do right to the bottom. I'm going to add a new protected function called get user buy tokens, a protected function. Get user by token and what I'm going to start here and I'm just going to go back to reset control. I'm going to copy what I have here, pasted within this method. Now, rather than throwing the exception Nothing Aero. What I'm going to do simply return no for this condition. So return No. So if the token is empty or user cannot be found by this talk and then we're going to return. Otherwise we're going to return this user instance which we have obviously associated with this very able when we check in this condition here, let's import this use as well to the cone control I scroll up of Is this your statement is now oddity. I'm going to move it together with all these application specific imports. So now we can use this. Get user by talking about before this. Let's just art some dog looks young. Conserve return user all new and then get user by Tolkien. Okay, lets no save this file and close it. And what I'm going to do now is removed this first line here, and I'm going to also check. This is no in this, Simon, rather than having this calling this used by token, I'm going to use this. Get use it by talking. It looks a little bit cleaner to me. And the same thing will now go for this. Activate control. And so if we open this one room of this line with a token from of this empty and den fall is no, we're going to associate it with the same methods. So there we go. So let it be better. Chunk of a cold is extracted. Obviously jazz because of this specific art ero Ah, we didn't throw actually the exception from this methods I think it's going to work a little bit better this way. So you can obviously modify this however you want from any method. Okay, so we can close this Activate controlling reset controller. Our get using methods is now also done. So the next thing we need to do is to basically open our browser and check if we can actually see this view. So refresh the page and there we go. Reset password form is now obviously available to us. If we inspect it, you'll see that obviously the we check the form. There we go. The token has been upended from this user. Instance as I can close this, if we obviously keep update without anything, it prompts us to provide a new password. So let's put the new passwords. Let's say password to password, too. Heat update. Obviously, nothing happens here because we don't have this pulse method. So let's quickly go back to the editor and after the get user methods, if I just scroll up a little bit, let's create a public function post, and from within this function we're going to start with Post request on Lee. We only wants to accept post request methods, then try and catch statement with the exception e and from within the couch. Let's Trey, where it's in new Jason Response and this response will return errors and then responds. It's going to be, uh, http on Process herbal Entity. Then we call methods, sent Heather's and get content. So that's our card block from within the trial. We're going to start with, user this, get a user. And now if we go back to this, get using method because I think quite explain, actually want this aren't errors here. For now, you can see the obviously from within the index. We don't really work with the form yet, so there's no sir errors to art to, but because we using the same methods from within the post, that's what we've added. This Art Harris of the nature on these messages are visitors. Validation indexes can be sent box to back to the view and display the relevant validation message. Now it doesn't hurt us to have it here on the index. Ah, that's why we have it stray away within this method rather than having a separate method then for for the post, obviously action. Okay, so once we've got the instance of the user Now we need to collect request items and the request items. We want our password and password confirmation. Then we need to validated. So this validate request. Now, once it's validated, we need to unset this password confirmation because we don't want this. So this input offset onset on. Let's just copy this possible confirmation. And after this, we are ready to update our password. But rather than putting the whole logic A I'm just going to delegate it to another method. This update password and I'm going to pass the instance of the user through is an argument . And then we're going to return new Jason response again. Ah, and we are going to past Ray with a message saying something like, Your password has been updated successfully and obviously updated is which this way and then be are you can now look in Let's just actually extracted to If Ari able, I'm going to create the very clear message equals and then all this we can con coordinated rather than having such a long lines so message, then concatenation like this. Logging and logging. Let's make this a links or h ref with the Ford Slash, because that's where our logging screen is and closing attack. Okay, now we can pass. It is very able through so message and then a We just sent Heather's as well and get content. So now update possible method. Let's out this method before we actually do this. Let's art dog looks to deposed method because this one is already finished. So completed basically so pro cess request. And if we scroll down to our update passwords, we get in the instance of the users. So let's tie painted here and what I'm going to do from within its check if exclamation mark user update passwords we're passing through this inputs gets and want to get passwords that's been sent through. If it didn't updated, then we're going to again. This art errors and we're going to add it's above Password Fields Index is going to be failed. And if we go back to this reset, the felt has the message possible, could not be updated, and then we just throw and you exception saying involved No ah, pass word could note be updated as well. Doesn't really matter. We put in this exception because this exceptions aren't really going to be visible on the front end anyways, just to terminate bicycle the execution. But it always makes obviously sense to put something meaningful here. Okay, so for the double look update user passwords. So that's Ah, Done, obviously. What we doing here? We check in. If this update passwords felt if it failed, then we are the year and we terminate the script. So a to this point, our past, what should be updated? And we should get this message with the logging links. So let's test their within the browser. If I hit update now, there we go. That's being processed in my passport has been updated. Its click on this logging Lincoln. Try and log in with this new credentials A password to heat return. And there we go. We're locked in. 29. Refactoring: in this video, we're going to the summary factoring of the coat we've already done. So let's have a look at this. Forgot passwords. If I try and reset, my password has just quickly some me deformed. You'll see that What's going to happen if I open my email? The token is to D. C E and so on, because what we doing when we actually resetting the password? If I open the user model, you see that reset token simply puts their email address off the user into this MD five function, which then returns the empty five heartstring. Now, what's going to happen next time I'm going to reset the talking, Let's try again. You'll see that the token. If I open, not here now go buck open both of these messages. You see that the token is exactly the same as you can see. Anyone who knows the U. R. L for the reset password or registration activation page could easily do it without actually receiving any email. Just pulled their email address within the empty five and appended to a token which is definitely no, something we would like to allow. So let's go back to the editor, and what we going to do is replace oldest this empty file with email, with their function called Unique I D. And we're going to coldest meth, a function without any arguments. So now if we test it, if we go back to our forgot password if we tested with the same email address on now, if we check our email there we go should receive it in just a second. There we go. So as you can see, talking is completely different. It's shorter, but its unique. So if you have a look at this and now, if I try and reset it again with the same email address and if we check our email, there we go. You can see that now. Obviously, this string is different. The beginning is similar, but then DND is completely different. That should work a little bit better. If you would like to art even more than obviously, you can still use this MD five and upend this email. So let's do that email and if we try with this string is going to be a little bit longer as well. So if we try again, forgot password. Same email address submits. And if we check our email, there we go. The string is now longer. And obviously this is definitely unique because the ending of the strings MD five off the unique email address on a system that won't be too same Two accounts with the same images. So just this is already unique. But then we also propelled this unique i d results to it. So the number this this string is definitely going to be ah, unique. There won't be too accounts with the same token. Okay, so that's Ah, one improvement. Now, next thing, if you go back to the editor, closed this user. Ah, class. And what I want to show you as well is if we opened this control is I mean, if we start with the register controller, One thing that I want to get rid off is ah, this this method was scrolled down to send email and together with the message body because we are using very similar approach. If you have a look at this forgot password, we also have descend met email and then message body. It would be nice to have perhaps a component that takes care of it. And then, rather than calling, this sent email and then sent email then calls this message body, perhaps we could just instant she ate new class. And then Cole method send on its or something like this and then oldest is going to be done outside of the control and rather than politics controller with additional method. So the way I'm thinking about doing this is to have a some sort off event. Dispatchers say at any point, if I want to trigger something, I can just call this event dispatcher, pass it an object, and this object will then trigger. I mean, this dispatcher will then trigger given method on this object, and it may be just a single event since single job that I want to dispatch, or maybe a collection of array off jobs. So to start with, let's just open this utilities director. And under this director, I'm going to create event Dr Tree And within this event, director, I'm going to create the new class cold event, this Sparta, and it's going to be within up then utilities and then event name space, okay. And this class will have method public method despots, a Public function dispatch, and this one will take events and will be either array or a single job. That's why I'm not sigh painting this with any data time. Okay, I'm going to add some dog block stray away here. It will take Baram events, which will be either job or array off jobs. And now we don't have job yet. So under the event, less creators interface this time it's going to be an interface, and we're going to call it job again. It's within the same name space, AARP Utilities event. And it's an interface and out this interface with simple interface will have just one method requirement, which is going to be public function. Honda. All we want 200 given job When we are passing this job to this event, despite chipped will return mix because we don't know that might be different jobs, they may return values. Some may just returned voids. It may be anything. That's why I returned mix and humble their job for the summary. Off this method, Gilligan's closed this saving close this interface now back in our even dispatcher and for the summary, we're going to say that's at this barge Jope all jobs and then it will return mixed as well because we in my day return bullion from when we going to be calling air a walk on their If if this argument is in the rain, otherwise in the return, wherever there, the method, this 100 method off, the job will return. So we're going to start If what if ISS ray events, then we are going to delegate it to this mold. People, events and we pass these events is an argument. Otherwise we return this single event and we also passed this events through. Now here we need to return statement and now we need to all this multiple events, methods and then single event. Now for multiple events. We know this is a race so we can type hinted and we're going to the return array walk and we want to walk through this events and the cold back we want to use is going to be within the same instance of the off the object within this event dispatcher and the method will be called single event. So basically, we are delegating this to the single event method and here I'm going to do is simply return on. Now this events here, I'm going to actually rename Teoh job and I'm going to type hinted as job. So it's going to be an instance off the job, and it's going to be called jobs. A job and then humble method we know is that this contract requires dis handle methods to be available from any instance that implements this contract. This interface. That's what we can call it straightaway here. Okay, lets out some dog blocks because that's our event. Dispatch it completed. So this one will return bullion. We pass in the array 100 all multiple jobs and and for this one, handle single Gelpi and it will return. Makes because we don't know this handle method can return anything. OK, so that's our event. Dispatcher them now for us to have access to this event dispatcher. Probably the best thing will be to register this part unit container. So let's open our public directory and index dot PHP. And right before this, a bind Male After the guard, let's duplicate this line and we go into called Event, and it's going to be instance of a new event. Dispatcher Deb again let's import this class as well. So we have it right at the top here. So now if we go back to our controller can save it and close it. We can also close this even dispatcher. Now, if we go back to our controller from within the controller, what I'm going to do, scroll up to the top and right after the Container Guard request after request, I'm going to create the new proper tickle protected event. And it's going to be an instance off the event dispatcher make should obviously that classes now important here as well. And I'm going to move it to the classes for our application. And now from within the constructor, I'm just going to duplicate this request, rename its two event and we are pulling the event instance from the container here. So now we have this event available right in the bottom off this control that I'm going to cut a new methods and just to help us so that we can easily dispatch an event we want from within our controllers. So the method is going to be protected function dispatch and it will take a an event or events so I'm just going to call it E vents. And from here we just returned this event instance and then dispatch method, passing the events through as an argument. Let's out some dog blocks here so it may return anything. So it's mixed events might be an instance of a job. All in my be every. And then it's just art here that they'll block the spots events. And if we scroll up to the top, make sure that obviously this job is also important here. Okay, if can we can now save and close the controller now, the first job that I'm going to create is going to be within the new subsection here. I'm going to create Notifications directory. And within this notifications, director, I'm going to create the 1st 1 which is going to be activation email and is going to be with thin hopes. Once again, activation email is going to be within up and then notifications Dara trip okay, and it implements job. So now, now that we implemented this job, we need to add this handle method. So let's quickly out the implementation and let's go back to our register control method now from within our sinned. Activation email. We are first resetting the token. Then we passing the instance off the user to dissent, email and send email than takes care off, distributing the email of its increase, getting this message as well. So what I'm going to do is to copy whatever is inside of this sent email method and paste it within the humble method Here and now, From within this handle method, you can see straightaway that we first of all, need to import. Obviously this dot envies to have access to this valuables. But then we have a container that we need. We need user as well. And later on, if you have a look at our message body, we also need the requests. I'm just going to Carter distant time at this message body and pace it within this activation email job. Now a import this use. Actually, we won't need their use. And now, as an argument, because we will have access to the property user. And this is going to be because I'm going to create the constructor and this constructor will take instance off the user, first of all, then it will take insist off the mail as well up utilities mail, and it will take an instance off. The HDP request illuminates HTP requests request and let's update the dog blocks and let's initialize this fields all three of them. So now you can see we have this properties, user mail and requests. So when we pass them through as an argument is constructed, there will be associated with this properties. And because of this, we will have access to the smells. And now we don't have to pull it from within the container. We can simply I'm just going to move this first line and I'm going to cold cern this male and then art from and so on. Now, user now becomes this user. We don't have to pass users an argument because we have access to it as a property. So now from here, we can call this user. But rather than token, I'm thinking we don't really have to reset this soaking before we pass it to dissent email method. In this case, basically, we are going to remove the sent email method and coal in this parched this activation email . So what I'm going to do is call this user resets token from within this activation email. So now resets token because we're set token, as you may remember, it resets the token, saves it to the database and then returns it so we can do it all in one. Go here Now requests we have access directly to as well, because it's been sent through is an argument associated with our property. And that's everything within our activation email so we can save and close this far back to our register control from within the register controller. We can now remove this sent email and our send activation email. What we should do now it's called is dispatch method and passed this events on new activation email and this activation email. Take this throughout three arguments. 1st 1 is the user. Instance. 2nd 1 is the instance off the mayor components off this container, make mail, and then the last one is going to be instance off the requests. I'm going to duplicate this last line and replace Male with the request. So we pulling the mail and requests from the container and passing it as arguments to this activation. So that's as you can see. This has now allowed us to remove these two redundant methods, Put them in a separate class, which takes care off this whole email distribution. So if we now save the file open on adult envy, make sure that verification set to true. So we actually receive this activation email. I'm going to close this file open you database. Make sure that the record with the knowledge is there going to be trying to register. Obviously, I've got one here, so I'm just going to truncate this table to make sure that this record does not exist, so I can actually greatest there again. Now back to the register, form heat on register. That should now send email the same way as it'd be false. If I go back to my mailbox, you can see males here click on activation talking. Everything works as expected. Now I'm going to be able to log in hit return And there we go. I'm now locked in and redirected to the dashboard. So now back to our editor. And now they're control adults. Ah, should probably use this approach would be the forgot controller, which is the second case when we actually distributing email. When we send in email to the visitor. Let's go back to this forgot controller. We have the same message. Body We have sent email here, so let's what I'm going to do. Actually opened this activation off. One thing I've noticed this handle here doesn't return. Makes it actually returns into Jessa. Let's make sure that this return statement has interview here on what I'm going to do is actually duplicate this entire activation email class. And so copy. And I'm going to create a new one called Reset Password email. Got to copy the name. So now the new class has been created, obviously. And make sure that the class name is also changed to the same as the file name. And I'm going toe reorganize this You statements here to make sure that they all grouped a little bit differently. The outside packages together and then application specific to get as well. Okay, so reset Password email takes exactly same constructor, same properties, same job. But if we go back to forgot control, I'm going to close the file browser on the left. I'm going to split the screen here. What? We have different here. If we look at this 100 method against the scent user. Is there subject subject changes here to password reset request. It's going to use the user email name as well. Exactly. Same thing now, message is going to be different. So what I'm going to do cut this message from within there for God controlling. Baste it with then override basically over this existing one within their set passwords email. And I'm just going to close this. Move it to this window. So we have everything in the same window. There we go now. Message. But it does not take any argument because we have a property user already. So now let's change it to this user resets token. And everything else stays exactly same way as it s so now this job is also a finished so we can save in closest reset passwords email from within. The four gold controller. We not going to remove this sent email because this is actually the method that's being called from within this pulse. As you can see here. If send email returns false, then we are to Aaron Throw the exception. So back to this send email from within the said email We're going to return this on the spark. And we want to Despont the job New reset password email. And this one takes the same arguments or user than this container on the contain from a container. We want to get the mail component first, and then the request the same way as before. Some male request. Okay, so that's all from within this forgot control of his saving closes. Fine. We can close this register controller as well. If we go back to the browser, Let's now log out, go to the forgot password and see if it's going to still work just fine. And if we now check email there we go. Password reset. Seemed to be working Fine. Let's just put password to password to update. That works fine. If we not try and log in a password to under, we go back to the dashboard. No one last thing Before we finish this course I want to show you that this remember me. Option also works if we try and log in without deception. So passed word to here it's in and were redirected to Dodge Bird. Now, if I try and click register, it takes me back to the dashboard. Same for forgot password for logging because if once you are logged in, you should be able to access these sections. And now, if I close the browser completely so command Q on the keyboard on the mark and now reopen it and navigate to our project. You'll see that I'm now locked out. But if I try and log in with this, remember me this time heat return. I'm logged in as well. But if I open the console here and an application under the cookies for this looking deaf, you'll see that we have this remember me with the value off our off the talking that has been now saved with my record. If I go back to database, refresh their record, you'll see the Remember Me token has now the same value here. So now our system can identify me next summer, going to open this browser and navigates to our logging the deaf. I now close the browser command Q on a keyboard and now reopen it chrome and navigates to log in the death. You'll see that I'm automatically logged in and go straight to the dashboard. So this remember me token works just as expected. So you can obviously log out in one side logged out. Now, if we check if we still have this cookie, you'll see that this cookie is gone. And next time I'm going to try and log in without using this. Remember me On and pass were two. You'll see that when I close the browser, it will vote me out, sir. Command que reopen Crumb Locking the death. And you see that I need to log in again. Because when Clive close the browser, this session has been removed and obviously had No, I'm no longer long thing. So this is the last video off this course. I hope you enjoyed it. If you have any questions or suggestions, perhaps please use on the common section under this video.