Validation component to validate models, input data. Handle any data types - arrays, objects, scalars, getter methods. Easy to extend. Type hinting / autocompletion. Fluent syntax.
use Xtompie\Validation\Validation;
$result = Validation::of($input)
->key('email')->required()->email()
->key('password')->required()->min(3)
->group()
->main('password')->callback(fn($input) => $input['email'] != $input['password'])
->group()
->key('email')->callback(fn($email) => !inUse($email))
->result();
$result
is Xtompie\Result\Result
PHP >= 8.0
Using composer
composer require xtompie/validation
Validation subject can be provided by
Validation::of($input);
Validation::new()->withSubject($input);
Validation::new()->validate($input);
Validation::of($input)
/* Group 1 */
->group()
/* Group 2 */
->group()
/* Group 3 */
;
If an error occurs during group validation, subsequent groups will not be validated and validation will stop.
Validation::new()
->main() // validation will target main subject
->property($name) // when subject is an object, will target property named $name
->method($name) // when subject is an object, will target getter method named $name
->key($key) // when subject is an array, will target array value where key is $key
->take($callback) // custom target $callback, as first argument main subject will be given
;
Targets can be nested e.g.
$validation = Validation::of(['person' => ['name' => 'John']])
->key('person')
->nested()->key('name')->required()->lengthMin(10)
;
$validation->errors()->first()->space(); // person.name
After nested() function targets are related to last target.
Nested can be reset by unested()
, group()
or main()
target.
Nested can be composed in multiple levels downwards
Space in error is automaticly generated.
Filters are applied before validators
Validation::new()
->key('name')
->filter(fn($x) => ucfirst($x)) // custom callback filter
->trim()
;
Targets are optional by default. If target is required use required method.
Validation::new()
->key('name')->required()
;
Validation::new()
->key('name')
// raw validator, validator return Result
->validator(fn ($value) => strlen($value) !== 13 ? Result::ofSuccess() : Result::ofErrorMsg('Length can not be 13'))
// custom callback
->callback(fn ($value) => strlen($value) !== 13, 'Length can not be 13')
->notBlank('Fill name!')
;
All list validator in source
$ok = Validation::of($email)->required()->email()->success();
If no target is provided, then the main target, validation subject, will be used.
$v = Validation::new();
$v->result(); // Xtompie\Result\Result
$v->errors(); // Xtompie\Result\ErrorCollection
$v->error(); // ?Xtompie\Result\Error first error
$v->success(); // bool
$v->fail(); // bool
Component consists of 3 elements.
- ValidationValidator - builder and validator.
- ValidationCore - wrapper for the ValidationValidator. Gives fluent syntax, deals with validation subject.
- Validation - extends ValidationCore by inheritance. Gives concrete validations, filters, messages, keys.
Validation or ValidationCore can be extended by inheritance.
namespace App\Shared\Validation;
use App\Shared\Dao\Dao;
use Xtompie\Validation\Validation as BaseValidation;
class Validation extends BaseValidation
{
public function __construct(
protected Dao $dao,
) {}
protected function msgs(): array
{
return array_merge(parent::msgs(), [
'dao_not_exists' => 'Value {value} already exists',
]);
}
public function trim(): static
{
return $this->filter(fn($v) => trim($v));
}
public function digit($msg = 'Only digits allowed', $key = 'digit'): static
{
return $this->validator(fn($v) => ctype_digit($v) ? Result::ofSucces() : Result::ofErrorMsg($msg, $key));
}
public function daoNotExists(string $table, string $field, ?string $exceptId = null, ?string $msg = null)
{
return $this->validator(fn ($v) => $this->test(
!$this->dao->exists($table, [$field => $v, 'id !=' => $exceptId]),
'dao_not_exists',
$msg,
['{value}' => $v]
));
}
}
namespace App\User\Application\Service;
use App\Shared\Validation\Validation;
class CreateUserService
{
public function __construct(
protected Validation $validation,
) {}
public function __invoke(string $email): Result
{
$result = $this->validation->withSubject($email)
->required()
->email()
->daoNotExists('user', 'email')
;
if ($result->fail()) {
return $result;
}
// create user
return Result::ofSuccess();
}
}