Usage

Basic value validation

<?php

use Flikore\Validator\Validators as v;

// Instantiate an existing validator
$v = new v\ExactValueValidator(5);

// Use the "validate" method to check if a value is valid
var_dump($v->validate(5));    // bool(true)
var_dump($v->validate(4));    // bool(false)
var_dump($v->validate(0));    // bool(false)
var_dump($v->validate(null)); // bool(true)
var_dump($v->validate(''));   // bool(true)

The validators ignores null values and empty strings. If you like to make sure a value is not empty, use the NotEmptyValidator.

<?php

use Flikore\Validator\Validators as v;

$v = new v\NotEmptyValidator();

var_dump($v->validate(null));    // bool(false)
var_dump($v->validate(array())); // bool(false)
var_dump($v->validate(''));      // bool(false)
var_dump($v->validate(0));       // bool(true)

Multiple validators

All must be true

If you want to check if multiple conditions apply, use the ValidationCombo class. It can join any number and validators and act as a validator itself (so it can also be use in other ValidationCombo).

<?php

use Flikore\Validator\Validators as v;

$combo = new Flikore\Validator\ValidationCombo();

$combo->addValidator(new v\ExactLengthValidator(5));
$combo->addValidator(new v\NotEmptyValidator());

var_dump($combo->validate('12345'));  // bool(true)
var_dump($combo->validate('1234'));   // bool(false)
var_dump($combo->validate('123456')); // bool(false)
var_dump($combo->validate(''));       // bool(false)
var_dump($combo->validate(null));     // bool(false)

Only one need to pass

If only one of validators is enough for the value to be valid, you may use the ValidationChoice class instead.

<?php

use Flikore\Validator\Validators as v;

// Use the ValidationChoice class to reunite validators with an "Or" condition.
$choice = new ValidationChoice(
  new v\NumericValidator(),
  new v\AlphaValidator()
  // May have any number of arguments
);

// First condition met (numeric)
var_dump($choice->validate('12345'));  // bool(true)
// Second condition met (alpha)
var_dump($choice->validate('abcdef')); // bool(true)
// None of them matches (mixed value)
var_dump($choice->validate('abc123')); // bool(false)
// Empty (ok as with any validator)
var_dump($choice->validate(''));       // bool(true)

Recursive validation

To apply a validator to every element in an array, use the RecursiveValidator class. It receives one validator in the constructor and checks the elements with such validator.

<?php

use Flikore\Validator\Validators as v;

// Recursive check every element in an array against a validator
// Use the RecursiveValidator class.
$v = new v\RecursiveValidator(new v\NotEmptyValidator);

// Example array
$ok = array(
    'this',
    'is',
    'ok'
);

var_dump($v->validate($ok)); // bool(true)

// Another example
$notOk = array(
    'this',
    'is',
    'not',
    'ok',
    'oops' => '', //<- this is empty
);

var_dump($v->validate($notOk)); // bool(false)

// To get the key where there was an error, use the %arrKey% template
$v->setErrorMessage('The key "%arrKey%" is empty.');
echo $v->getErrorMessage(); // prints: The key "oops" is empty.

Usage with exceptions

To throw an exception on a validation error, use the assert method instead of validate. It throws a ValidatorException with a custom message for each validator.

<?php

use Flikore\Validator\Validators as v;

$v = new v\ExactValueValidator(5);

// Throws a ValidatorException with the message:
// "The value must be exactly 5."
$v->assert(2);

Custom messages

The message of the exception can be set on the validator using the method setErrorMessage(). If the validator is a Combo, then the message setted with this method will be the message shown to any validation error (to avoid this behavior, set the messages of the validators inside the combo).

Each validator has a set of values that can be used in the message. The value named key exists in all validator and defaults to "value". Those keys replace the sequence %key% inside the message. To override a default value of a key, use the addKeyValue method (this can be used to set the key as the name of the form field, for example).

Example:

<?php

use Flikore\Validator\Validators as v;

$v = new v\ExactLengthValidator(5);

// Setting a new message template
$v->setErrorMessage('The %key% is not %length% %c% long as it should be.');

// Override the default key name
$v->addKeyValue('key', 'input');
// Create a custom key
$v->addKeyValue('c', 'characters');

// Captures the error
try
{
    $v->assert('Name');
}
catch (Flikore\Validator\Exception\ValidatorException $e)
{
    echo $e->getMessage(); // Shows "The input is not 5 characters long as it should be."
}

To get all messages of generated by a set error as an array, use the ValidatorException::getMessages() method.

Validating arrays and objects

Standard usage

The ValidationSet class can be used as a shortcut to test all the values in an array or the properties of an object all at once. The usage is pretty straightforward:

<?php

use Flikore\Validator\Validators as v;

$set = new \Flikore\Validator\ValidationSet();

// Add a single rule to a key
$set->addRule('name', new v\NotEmptyValidator());
// This rule is chained with the previous one, both must be valid
$set->addRule('name', new v\MinLengthValidator(5));

// Multiple rules can be added at once with an array
// Those rules will be *added* to the "name" key, and will not exclude the others.
$set->addRules('name', array(
    new v\MaxLengthValidator(30),
    new v\RegexValidator('/^[a-z ]+$/i'),
));

// Just call validate (or assert) to check if it's ok
var_dump($set->validate(array('name' => 'Cool Name'))); // bool(true)
var_dump($set->validate(array('name' => 'aaa')));       // bool(false) The minimum length is 5
var_dump($set->validate(array('name' => 'aa4a5')));     // bool(false) Doesn't match regex
var_dump($set->validate(array('name' => '')));          // bool(false) Can't be empty

// Another way is to construct the set with all the rules:
// ***Note: Even in this way, new rules can also be added later with the add methods.
$set = new \Flikore\Validator\ValidationSet(array(
    'name' => array(
        new v\NotEmptyValidator(),
        new v\MinLengthValidator(5),
    ),
    'age'  => new v\MinValueValidator(13),
));

var_dump($set->validate(array('name' => 'this is ok',          'age' => 14))); // bool(true)
var_dump($set->validate(array('name' => 'oops',                'age' => 14))); // bool(false)
var_dump($set->validate(array('name' => 'the age is not good', 'age' => 12))); // bool(false)

Partial validation

If you need to validate only a subset of fields (for, say, using in the onBlur event of an input element, without need to validate the whole form), set the second argument of validate (or assert) to the field or list of fields you want to actually validate. If there’s no rules for a given field, it’ll just be ignored.

Example:

<?php

// Create a set of rules.
$set = new ValidationSet(array(
    'name'  => array(
        new v\NotEmptyValidator(),
        new v\MinLengthValidator(5),
    ),
    'age'   => new v\MinValueValidator(13),
    'email' => new v\EmailValidator(),
));

// Creating a value
$value = array(
    'name'    => 'this is ok',
    'age'     => 12, // not ok
    'email'   => 'this_is_ok@example.com',
    'no_rule' => 'whatever',
);

// Validates only the name, so it's ok
var_dump($set->validate($value, 'name')); // bool(true)
// Validates the name and email
var_dump($set->validate($value, array('name', 'email'))); // bool(true)
// Validates the no_rule
var_dump($set->validate($value, 'no_rule')); // bool(true)
// Validates the name and age, so there's error
var_dump($set->validate($value, array('name', 'age'))); // bool(false)

You may also get the rules for external validation using the methods getAllRules() and getRulesFor($field).

Comparing with other keys

It’s also possible to use another key or attribute as the input value for a validator (e.g. validate if one field is equal to another). To do that, you need to use two other classes combined: ValidationValue and ValidationKey.

ValidationValue should be included in a set as it were a validator. Its constructor requires a validator as the first argument (can be a string with a FQCN or a dummy validator object) and the arguments to the validator constructor must follow it. To use a field from the validated object in the constructor, pass it as a ValidationKey object with it’s key property being the name of the attribute or key you want to grab from the value being validated.

Let’s make that clear with and example. To make sure the value of key1 is strictly equal to the value of key2 inside the same array, do like the following code:

<?php

use Flikore\Validator\ValidationKey;
use Flikore\Validator\ValidationSet;
use Flikore\Validator\ValidationValue;
use Flikore\Validator\Validators as v;

$set = new ValidationSet();

$set->addRule('key1',
        // The first argument is a dummy object (can also be a FQCN string).
        new ValidationValue(new v\EqualsValidator('dummy'),
        // The second argument is the first for the EqualsValidator constructor.
        // In this case, we want to grab the value of "key2", so we create a new
        // ValidationKey and specify "key2" as its key.
        new ValidationKey('key2'),
        // This is the third argument of ValidationValue, which will be passed as
        // the second argument to EqualsValidator constructor. This is "true", because
        // we want the comparison to be strict.
        true)
); // end addRule)

$ok = array(
    'key1' => 'equal',
    'key2' => 'equal',
);

var_dump($set->validate($ok)); // bool(true)

$notOk = array(
    'key1' => 'equal',
    'key2' => 'not equal',
);

var_dump($set->validate($notOk)); // bool(false)

$notStrict = array(
    'key1' =>  5,
    'key2' => '5',
);

var_dump($set->validate($notStrict)); // bool(false)

Keep in mind that the values that are passed to the validator are not checked in the ValidationValue constructor. So if there’s something wrong, it’ll only cause an error when the validation is taking place and the real Validator is constructed.

Note: this doesn’t work with ValidationCombo, but since you can add multiple rules to the same key, this should not be a problem.

Sets and exceptions

With a ValidationSet, exception messages work in a different way than with a Validator. The main exception has no message attached, but it contains an array of errors with the keys being the validated array keys (or object properties) and the values being the child validator exception.

Also, the key name you add to the set is also setted as the %key% template value in the error messages. To change that to another value, use the third argument of addRule() and addRules() methods with the value you want). This can be used if you want to change the language of the message or to specify a more user friendly form label.

Example:

<?php

use Flikore\Validator\Validators as v;

$set = new \Flikore\Validator\ValidationSet(array(
    'user_name' => array(
        new v\NotEmptyValidator(),
        new v\MinLengthValidator(5),
    ),
    'user_age'  => new v\MinValueValidator(13),
        ), 
    // Labels:
    array(
        'user_name' => 'Name',
        'user_age'  => 'Age',
));

try
{
    $set->assert(array('user_name' => 'oops', 'user_age' => 10));
}
catch (Flikore\Validator\Exception\ValidatorException $e)
{
    foreach ($e->getErrors() as $key => $innerException)
    {
        echo $key . ': ' . $innerException->getMessage() . PHP_EOL;
    }
    // Output:
    // user_name: The Name must have at least 5 characters.
    // user_age: The Age must be equal or greater than 13.
}

Nested arrays

To validate arrays inside arrays, it is possible to nest ValidationSet as a rule. So, in theory, there’s no limit to how much levels you can nest.

Example:

<?php

use Flikore\Validator\Validators as v;
use Flikore\Validator\ValidationSet;

// To validate arrays inside arrays, the validation sets can be nested.
$v = new ValidationSet();

// You may add a ValidationSet as a rule to some field.
// Here, let's create a set to validate the user name and email
$inner = new ValidationSet();
// And add the rules
$inner->addRule('name', new v\AlphaValidator);
$inner->addRule('email', new v\EmailValidator);

// Then, use this as the rule for the main set.
$v->addRule('user', $inner);

// Now, take this array:
$value = array(
    'user' => array(
        'name' => 'Ok name',
        'email' =>'this_is_ok@example.com',
    )
);

// And validate it
var_dump($v->validate($value)); //bool(true)

Api

For the API documentation for all the classes, check the versions page.