This episode is for members only

Level up with a premium membership

Join now
Already a member? Sign in to continue
Playing
42. Custom validation rules

Episodes

0%
Your progress
  • Total: 4h 32m
  • Played: 0m
  • Remaining: 4h 32m
Join or sign in to track your progress

Transcript

00:00
Now that we have validated the registration form, let's take a look at creating custom validation rules.
00:07
This is going to come in handy when we look at validating the email address to check if it already exists in the database so we can show the user that error. Let's just take a look at what we mean. So if I go ahead and register an account here,
00:21
let's go ahead and use the same email address I already have registered. And as you can see, we just get hit with an SQL error. We've already got that email address in the database, so it's not going to work. Now in production, when you have debug set to false,
00:34
the user won't see this, but it's not much help. We want to go ahead and redirect with an actual validation message. OK, so the process of creating out custom validation rules with the library that we're using is to create some sort of directory in your PSR-4 namespace directory.
00:52
So we're going to create our directory here called validation. And then we need two more directories under this. The first one is going to be for the rules themselves. And then we need to throw an exception, or the library will handle throwing an exception.
01:06
So we need to create an exceptions directory with an exception for that particular rule. OK, let's start with the rule. So we'll create our a class here. And we're going to go ahead and call this exists in database.
01:20
Let's create this out. And the first thing that we're going to do is extend the abstract rule from the respect validation library. Now this requires that we create out a validate method.
01:33
That takes in some input, and it returns a Boolean. So what we're going to do is always return true here, because this is going to trigger an error when we combine this with not. So we want to say it does not exist in the database.
01:46
If this returns true, it means it does exist. And then we want to fail the rule. OK, so this is our rule created. Before we look at registering this, let's go over to our exceptions directory
01:59
and create out an exception for this. So the way that we name this needs to be the rule name. So exists in database. And then just prepended or appended with exception on the end.
02:11
Now this needs to extend the base validation exception, again, from the respect validation library. And inside of here, rather than create any methods, we have a property called default template.
02:24
Now there's a bunch of stuff that you can do with this, depending on the types of rules that you're implementing. But the easiest and simplest way is to just use a default mode here. And then inside of here with self standard, we go ahead and add the rule.
02:39
So we're going to say in here that already exists in the database. We'll keep this really simple for now. And then we'll customize this with some fields once we're done. OK, so we've got our rule exists in database and our exception
02:55
exists in database exception. How do we register these? Well, it's going to be helpful to check out how the validation library actually works. So if we go over to the factory and come down to this rule method,
03:10
this is how a rule gets resulted. So as you can see, it will go through a bunch of namespaces. We can add to these namespaces and it will pluck out the name, the fully qualified name of the rule.
03:21
So it will be under the namespace that we give. By default, these all exist within the package. And then it goes ahead and uppercases the first letter of the rule name. For example, when we use this rule, it's going to look like this exists in database.
03:36
So that's going to uppercase the E, it's going to look inside the namespace that we are going to define. And once it finds that rule, it will resolve it using a PHP reflector and then it will return it to us.
03:48
So to go ahead and add to the namespaces that we want to look for, we're going to come over to our app service provider and we're going to use the respect validation factory to set a default instance. Basically, what this means is we can go ahead and new up a factory here
04:05
and we can assign where we want these rule namespaces to exist. This will basically just add to the namespaces from the package. So we're going to say with rule namespace and we're going to provide the namespace to our rules where we created them.
04:20
So this is under app, validation and rules. So we can get rid of that last double slash. We also want to tell this where the exceptions live. So we're going to say with exceptions,
04:33
so we're going to say with exception namespace and do pretty much the same thing. App validation and exceptions. Now that we've done this, this is globally set and this will look for our rules inside of this namespace as well as the default packages namespace.
04:50
OK, we're going to go ahead and use the rule now over in the register controller. So let's apply this to email. So we're going to say exists in database and we want to say it does not exist in the database. So we can wrap this in not and then we can use the class here to call that rule.
05:10
So we want to say it does not exist in the database and we should be good. OK, let's go ahead and hit register. As you can see, the error that we've got here is standard. Now, this is just because if we head back over to our validation exception,
05:25
so existing database exception, we've created a negative version of this rule. So what we need to do here is say mode negative, and then we add a specific validation error for when is not in the database. So let's go and hit that again.
05:40
And there we go. That already exists in the database. So this one will be that does not exist in the database. If we think about it, when we use that exists in database,
05:53
we want it to exist in the database. So the standard or default mode will be that it doesn't. And the negative when we use not will be that it already does exist in the database. OK, let's go over and actually implement the functionality we need to get this working.
06:09
So back over to our register controller, what do we need to pass through to here? Well, we want to pass through a table name and we want to pass through the column. So we want to look inside of the users table to check that the value that we get for this key in our data
06:24
does not exist under this email column. Now, if we run this, it's not actually going to work. We're going to end up with an existing database is not a valid rule name. That isn't necessarily the case.
06:34
There's just an error behind the scenes because it can't resolve the existing database class when we're passing through construct items. So what we want to do is go over to the existing database rule, and we just want to bring a constructor in here which gives us the table name.
06:51
So let's create out a string in here with the table name and we'll go ahead and create out a string in here with the column name. So that will be available to us now inside of this validate method, which we can use to check there.
07:05
So you'll see now that this does work. Obviously, we're just returning true. So now what we want to do is access our database and check within this table if that value already exists within that column.
07:17
Now, a little bit earlier when we set up our database under our database service provider. Remember, we added this to our container so we can either use models or we can use the database query builder directly. We want to use the database query builder directly
07:32
because we don't know what the model is going to be. We're specifically looking inside of a table. So what we can do is go ahead and grab the instance of our container. So we'll say get instance.
07:44
And then we're going to get the database manager out of here. And then we're going to say table this table. And then we can just chain on a where clause to check this. So we're going to say where and we need to look inside of that column.
08:05
So let's say this column. And then we can just say equals or we could do a count on this technically, but we already assume that this is unique. So we already know that there's only going to be one.
08:17
And then we want to take the value in. Now, where does the value come from? Let's just get rid of this for now. And let's dump on this input to see what we get.
08:26
OK, let's come over and I'm going to type in my email address, which we know already exists. And you can see that the input is just the string value. So we can just take that directly now, put it into our query builder.
08:37
And we should be good. So let's go ahead and take that input in there. And then we're going to come down here and we could even say count and check that that equals one.
08:47
Or we could say it's greater than or equal to one. OK, so now that we have got this, we should be good. Let's just try this out. So I'm going to go back over to the register page,
08:57
hit register. Of course, this doesn't work. Let's try and register with my email address that I have in the database already. And if we hit register, you can see that that already exists in the database.
09:09
Let's register a new user with a different email address, just so we know that this goes through. When we hit register, sure enough, we are signed in as that user. So you can tweak this, but this is the general way that we would go ahead
09:23
and create a custom validation rule that depends on something external. We grab our container instance, perform this query in the database. And of course, this is going to return true if that already exists. And the rule is going to fail.
50 episodes4 hrs 32 mins

Course overview

Starting completely from scratch, build a modern PHP framework with all the features you’d expect.

Whether you’re new to PHP or not, this is a great exercise for learning what happens under the hood, arming you with knowledge you can apply anywhere you use PHP.

We’ll cover routing, controllers, views, the container, accessing the database, models, authentication, config, CSRF protection, exception handling, pagination, validation, flashing messages and much more.

Let’s dive in and build a PHP framework, step-by-step!

Alex Garrett-Smith
Alex Garrett-Smith
Hey, I'm the founder of Codecourse!

Comments

No comments, yet. Be the first to leave a comment.