# Validation Part of a model's responsibility in an MVC application is to be the gatekeeper for the data it handles. While a great deal of a model's functionality deals with fetching and relating data, validation is an important part of keeping your data clean and secure. This section focuses on validation in the model layer, as well as covering Lithium's core utility class `Validator`. ## Setting up the Model Because it's likely the most common case, we'll start with a simple model data validation example based around an HTML form. Let's consider an application that handles user registration. We'll define a `User` model and create some simple validation logic in order to make sure submitted user information is complete and in the correct form. Validation is done by defining a special property on the model object called `$validates`. Lithium inspects this property and validates data to be saved against this set of rules. Let's create a simple `User` model, and begin with a few simple validation rules. {{{ <?php namespace app\models; class User extends lithium\data\Model { public $validates = array( 'username' => array( array( 'notEmpty', 'required' => true, 'message' => 'Please supply a username.' ) ), 'password' => array( array( 'notEmpty', 'required' => true, 'message' => 'Please supply a password.' ) ) ); } ?> }}} Note: for a complete list of built-in validation rules, see the `Validator` API: [http://lithify.me/docs/lithium/util/Validator](http://lithify.me/docs/lithium/util/Validator) This initial example shows how rules are defined. First, each set of rules is keyed by the model field name. Each field is then assigned an array of rules, where the first value is the name of the rule, and the subsequent keys define additional information about each rule. In addition to the rule name, there are a number of special keys you can use to modify a rule: - `message`: The error message displayed if this rule fails. - `required` (boolean): Specifies that data for this field _must_ be submitted in order to validate. Defaults to `true`. - `skipEmpty` (boolean): Causes the rule to be skipped if the value is null or empty. Defaults to `false`. - `format`: The name of the rule format required to validate the data, or `any` or `all`. You may also declare multiple rules per field. Here, we add an additional rule to the username field in order to ensure usernames are alphanumeric. {{{ <?php namespace app\models; class User extends lithium\data\Model { public $validates = array( 'username' => array( array( 'notEmpty', 'message' => 'Please supply a username.' ), array( 'alphaNumeric', 'message' => 'A username may only contain letters and numbers.' ) ), 'password' => array( array( 'notEmpty', 'message' => 'Please supply a password.' ) ) ); } ?> }}} ## Form Validation Here's a simple form we might use to collect user data. This would be contained in `app/views/users/add.html.php`: {{{ <?= $this->form->create($user); ?> <?= $this->form->text('username'); ?> <?= $this->form->password('password'); ?> <?= $this->form->submit('Save User'); ?> <?= $this->form->end(); ?> }}} Once that data is submitted to the controller, we handle it like this: {{{ <?php namespace app\controllers; class UsersController extends lithium\action\Controller { public function add() { if($this->request->data) { $user = Users::create($this->request->data); if($user->save()) { $this->redirect('/users/home'); } } } } ?> }}} If there's submitted data to this action, we create a new user with it. If a save is successful, we redirect to a landing page. The implicit logic here is that validation rules are checked, and `save()` returns a false if any rules fail. Since the action's view contains the HTML form we just built using the `Form` helper, if there are any validation problems, the HTML form is rendered again, this time with the errors displayed inline. The `Form` helper methods we used automatically display the error messages as part of the form, but you can use the `error()` method of the `Form` helper as well to customize where those messages display. If you need to know about model validation problems before the application renders the view, you can inspect errors on the `Entity` object you're working with. Get the last errors by calling `errors()`: {{{ <?php namespace app\controllers; class UsersController extends lithium\action\Controller { public function add() { if($this->request->data) { $user = Users::create($this->request->data); $user->save(); $errors = $user->errors(); // Redirect or perform other logic here // based on contents of $errors. } } } ?> }}} Note: you can also manually invalidate model fields by calling `errors()` and supplying key/value pairs to denote problems. While you'll usually want to create custom rules (covered next), this is sometimes a helpful trick to use in model filters, etc. ## Creating Custom Rules While the validator features a number of handy rules, you'll inevitably want to create your own validation rules. This done (at runtime) by calling `Validator::add()` to specify new rule logic. The simplest form of rule addition is by Regular Expression: {{{ <?php Validator::add('zeroToNine', '/^[0-9]$/'); ?> }}} If you need more than pattern recognition, you can also supply rules as anonymous functions: {{{ <?php Validator::add('usernameTaken' function($value) { $result = Users::findByUsername($value); return count($result) > 0; }); ?> }}} Once a rule as been defined, it can be referenced by name in a model `$validates` property or direct use of the `Validator` class magic methods: {{{ <?php Validator::add('zeroToNine', '/^[0-9]$/'); Validator::isZeroToNine('7'); ?> }}}