1# Feature Guide 2 3## Namespace import 4 5Respect\Validation is namespaced, but you can make your life easier by importing 6a single class into your context: 7 8```php 9use Respect\Validation\Validator as v; 10``` 11 12## Simple validation 13 14The Hello World validator is something like this: 15 16```php 17$number = 123; 18v::numeric()->validate($number); // true 19``` 20 21## Chained validation 22 23It is possible to use validators in a chain. Sample below validates a string 24containing numbers and letters, no whitespace and length between 1 and 15. 25 26```php 27$usernameValidator = v::alnum()->noWhitespace()->length(1, 15); 28$usernameValidator->validate('alganet'); // true 29``` 30 31## Validating object attributes 32 33Given this simple object: 34 35```php 36$user = new stdClass; 37$user->name = 'Alexandre'; 38$user->birthdate = '1987-07-01'; 39``` 40 41Is possible to validate its attributes in a single chain: 42 43```php 44$userValidator = v::attribute('name', v::stringType()->length(1,32)) 45 ->attribute('birthdate', v::date()->age(18)); 46 47$userValidator->validate($user); // true 48``` 49 50Validating array keys is also possible using `v::key()` 51 52Note that we used `v::stringType()` and `v::date()` in the beginning of the validator. 53Although is not mandatory, it is a good practice to use the type of the 54validated object as the first node in the chain. 55 56## Input optional 57 58On oldest versions of Respect\Validation all validators treat input as optional 59and accept an empty string input as valid. Even though a useful feature that 60caused a lot of troubles for our team and neither was an obvious behavior. Also 61there was some people who likes to accept `null` as optional value, not only an 62empty string. 63 64For that reason all rules are mandatory now but if you want to treat a value as 65optional you can use `v::optional()` rule: 66 67```php 68v::alpha()->validate(''); // false input required 69v::alpha()->validate(null); // false input required 70 71v::optional(v::alpha())->validate(''); // true 72v::optional(v::alpha())->validate(null); // true 73``` 74 75By _optional_ we consider `null` or an empty string (`''`). 76 77See more on [Optional](Optional.md). 78 79## Negating rules 80 81You can use the `v::not()` to negate any rule: 82 83```php 84v::not(v::intVal())->validate(10); // false, input must not be integer 85``` 86 87## Validator reuse 88 89Once created, you can reuse your validator anywhere. Remember `$usernameValidator`? 90 91```php 92$usernameValidator->validate('respect'); //true 93$usernameValidator->validate('alexandre gaigalas'); // false 94$usernameValidator->validate('#$%'); //false 95``` 96 97## Exception types 98 99* `Respect\Validation\Exceptions\ExceptionInterface`: 100 * All exceptions implement this interface; 101* `Respect\Validation\Exceptions\ValidationException`: 102 * Implements the `Respect\Validation\Exceptions\ExceptionInterface` interface 103 * Thrown when the `check()` fails 104 * All validation exceptions extend this class 105 * Available methods: 106 * `getMainMessage()`; 107 * `setMode($mode)`; 108 * `setName($name)`; 109 * `setParam($name, $value)`; 110 * `setTemplate($template)`; 111 * more... 112* `Respect\Validation\Exceptions\NestedValidationException`: 113 * Extends the `Respect\Validation\Exceptions\ValidationException` class 114 * Usually thrown when the `assert()` fails 115 * Available methods: 116 * `findMessages()`; 117 * `getFullMessage()`; 118 * `getMessages()`; 119 * more... 120 121## Informative exceptions 122 123When something goes wrong, Validation can tell you exactly what's going on. For this, 124we use the `assert()` method instead of `validate()`: 125 126```php 127use Respect\Validation\Exceptions\NestedValidationException; 128 129try { 130 $usernameValidator->assert('really messed up screen#name'); 131} catch(NestedValidationException $exception) { 132 echo $exception->getFullMessage(); 133} 134``` 135 136The printed message is exactly this, as a nested Markdown list: 137 138```no-highlight 139- All of the required rules must pass for "really messed up screen#name" 140 - "really messed up screen#name" must contain only letters (a-z) and digits (0-9) 141 - "really messed up screen#name" must not contain whitespace 142 - "really messed up screen#name" must have a length between 1 and 15 143``` 144 145## Getting all messages as an array 146 147The Markdown list is fine, but unusable on a HTML form or something more custom. 148For that you can use `getMessages()`. 149 150It will return all messages from the rules that did not pass the validation. 151 152```php 153try { 154 $usernameValidator->assert('really messed up screen#name'); 155} catch(NestedValidationException $exception) { 156 print_r($exception->getMessages()); 157} 158``` 159 160The code above may display something like: 161 162```no-highlight 163Array 164( 165 [0] => "really messed up screen#name" must contain only letters (a-z) and digits (0-9) 166 [1] => "really messed up screen#name" must not contain whitespace 167 [2] => "really messed up screen#name" must have a length between 1 and 15 168) 169``` 170 171## Getting messages as an array by name 172 173If you want to get specific message by name you can use `findMessages()` passing 174the names of the rules you want: 175 176```php 177try { 178 $usernameValidator->assert('really messed up screen#name'); 179} catch(NestedValidationException $exception) { 180 print_r($exception->findMessages(['alnum', 'noWhitespace'])); 181} 182``` 183 184The `findMessages()` returns an array with messages from the requested validators, 185like this: 186 187```no-highlight 188Array 189( 190 [alnum] => "really messed up screen#name" must contain only letters (a-z) and digits (0-9) 191 [noWhitespace] => "really messed up screen#name" must not contain whitespace 192) 193``` 194 195## Custom messages 196 197Getting messages as an array is fine, but sometimes you need to customize them in order 198to present them to the user. This is possible using the `findMessages()` method as well: 199 200```php 201$errors = $exception->findMessages([ 202 'alnum' => '{{name}} must contain only letters and digits', 203 'length' => '{{name}} must not have more than 15 chars', 204 'noWhitespace' => '{{name}} cannot contain spaces' 205]); 206``` 207 208For all messages, the `{{name}}` variable is available for templates. If you 209do not define a name it uses the input to replace this placeholder. 210 211## Message localization 212 213You're also able to translate your message to another language with Validation. 214The only thing one must do is to define the param `translator` as a callable that 215will handle the translation: 216 217```php 218$exception->setParam('translator', 'gettext'); 219``` 220 221The example above uses `gettext()` but you can use any other callable value, like 222`[$translator, 'trans']` or `you_custom_function()`. 223 224After that, if you call `getMainMessage()` or `getFullMessage()` (for nested), 225the message will be translated. 226 227Note that `getMessage()` will keep the original message. 228 229## Custom rules 230 231You also can use your own rules: 232 233```php 234namespace My\Validation\Rules; 235 236use Respect\Validation\Rules\AbstractRule; 237 238class MyRule extends AbstractRule 239{ 240 public function validate($input) 241 { 242 // Do something here with the $input and return a boolean value 243 } 244} 245``` 246 247If you do want Validation to execute you rule (or rules) in the chain, you must 248use `v::with()` passing your rule's namespace as an argument: 249 250```php 251v::with('My\\Validation\\Rules\\'); 252v::myRule(); // Try to load "My\Validation\Rules\MyRule" if any 253``` 254 255By default `with()` appends the given prefix, but you can change this behavior 256in order to overwrite default rules: 257 258```php 259v::with('My\\Validation\\Rules', true); 260v::alnum(); // Try to use "My\Validation\Rules\Alnum" if any 261``` 262 263## Validator name 264 265On `v::attribute()` and `v::key()`, `{{name}}` is the attribute/key name. For others, 266is the same as the input. You can customize a validator name using: 267 268```php 269v::date('Y-m-d')->between('1980-02-02', 'now')->setName('Member Since'); 270``` 271 272## Zend/Symfony validators 273 274It is also possible to reuse validators from other frameworks if they are installed: 275 276```php 277$hostnameValidator = v::zend('Hostname')->assert('google.com'); 278$timeValidator = v::sf('Time')->assert('22:00:01'); 279``` 280 281## Validation methods 282 283We've seen `validate()` that returns true or false and `assert()` that throws a complete 284validation report. There is also a `check()` method that returns an Exception 285only with the first error found: 286 287```php 288use Respect\Validation\Exceptions\ValidationException; 289 290try { 291 $usernameValidator->check('really messed up screen#name'); 292} catch(ValidationException $exception) { 293 echo $exception->getMainMessage(); 294} 295``` 296 297Message: 298 299```no-highlight 300"really messed up screen#name" must contain only letters (a-z) and digits (0-9) 301``` 302 303*** 304See also: 305 306- [Contributing](../CONTRIBUTING.md) 307- [Installation](INSTALL.md) 308- [License](../LICENSE.md) 309- [Validators](VALIDATORS.md) 310- [Changelog](../CHANGELOG.md) 311