xtompie / validation
Validation component
Installs: 5 066
Dependents: 0
Suggesters: 0
Security: 0
Stars: 1
Watchers: 1
Forks: 0
Open Issues: 0
pkg:composer/xtompie/validation
Requires
- php: >=8.0
 - xtompie/result: ^1.0
 
Requires (Dev)
- phpunit/phpunit: ^9.5
 
README
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
Requiments
PHP >= 8.0
Installation
Using composer
composer require xtompie/validation
Docs
Subject
Validation subject can be provided by
Validation::of($input); Validation::new()->withSubject($input); Validation::new()->validate($input);
Groups
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.
Targets
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 ;
Nested Target
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
Filters are applied before validators
Validation::new() ->key('name') ->filter(fn($x) => ucfirst($x)) // custom callback filter ->trim() ;
Required/Optional
Targets are optional by default. If target is required use required method.
Validation::new() ->key('name')->required() ;
Validators
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
Scalars
$ok = Validation::of($email)->required()->email()->success();
If no target is provided, then the main target, validation subject, will be used.
Validation feedback
$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
Extending
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.
 
Inheritance
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(); } }