xtompie / validation
Validation component
Installs: 3 670
Dependents: 0
Suggesters: 0
Security: 0
Stars: 1
Watchers: 1
Forks: 0
Open Issues: 0
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(); } }