PHP code example of tobento / service-validation

1. Go to this page and download the library: Download tobento/service-validation library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

tobento / service-validation example snippets


use Tobento\Service\Validation\Validator;
use Tobento\Service\Validation\ValidatorInterface;
use Tobento\Service\Validation\ValidationInterface;

$validator = new Validator();

var_dump($validator instanceof ValidatorInterface);
// bool(true)

$validation = $validator->validating(
    value: 'foo',
    rules: 'alpha|minLen:2',
    data: [],
    key: null
);

var_dump($validation instanceof ValidationInterface);
// bool(true)

use Tobento\Service\Validation\Validator;
use Tobento\Service\Validation\ValidatorInterface;
use Tobento\Service\Validation\ValidationInterface;

$validator = new Validator();

var_dump($validator instanceof ValidatorInterface);
// bool(true)

$validation = $validator->validate(
    data: [
        'title' => 'Product',
        'color' => 'blue',
    ],
    rules: [
        'title' => 'alpha',
        'color' => 'in:blue:red:green',        
    ]
);

var_dump($validation instanceof ValidationInterface);
// bool(true)

use Tobento\Service\Validation\Validator;
use Tobento\Service\Validation\ValidatorInterface;
use Tobento\Service\Validation\ValidationInterface;

$validator = new Validator();

var_dump($validator instanceof ValidatorInterface);
// bool(true)

$validation = $validator->validate(
    data: [
        'title' => 'Product',
        'meta' => [
            'color' => 'blue',
        ],
    ],
    rules: [
        'title' => 'alpha',
        'meta.color' => '

use Tobento\Service\Validation\Validator;

$validation = (new Validator())->validate(
    data: [
        'title' => 'Product',
    ],
    rules: [
        'title' => 'minLen:2|alpha',
    ]
);

use Tobento\Service\Validation\Validator;

$validation = (new Validator())->validate(
    data: [
        'title' => 'Product',
    ],
    rules: [
        'title' => [
            // single or multiple rules
            'eters and custom parameters.
            ['minLen', [3], 'error' => 'Custom error message'],
        ],
    ]
);

use Tobento\Service\Validation\Validator;
use Tobento\Service\Validation\Rule\Same;

$validation = (new Validator())->validate(
    data: [
        'title' => 'Product',
    ],
    rules: [
        'title' => [
            // single or multiple rules
            'stom error message'],
            
            // lazy rule with unresolvable class params:
            // [[Rule::class, ['name' => 'value']], [3], 'error' => 'Custom error message'],
        ],
    ]
);

use Tobento\Service\Validation\Validator;
use Tobento\Service\Validation\Rule\Length;

$validation = (new Validator())->validate(
    data: [
        'title' => 'Product',
    ],
    rules: [
        'title' => [
            // single or multiple rules
            '     
            // lazy rule with unresolvable class params:
            [[Length::class, 'min', ['name' => 'value']], [3], 'error' => 'Custom error message'],
            
            // lazy rule with unresolvable class params without method to call:
            // [[Rule::class, ['name' => 'value']], [3], 'error' => 'Custom error message'],
        ],
    ]
);

use Tobento\Service\Validation\Validator;
use Tobento\Service\Validation\Rule\Length;

$validation = (new Validator())->validate(
    data: [
        'title' => 'Product',
    ],
    rules: [
        'title' => [
            [
                'minLen:3',
                'error' => ':attribute must at least contain :parameters[0] chars',
                
                // you might want a custom value for the attribute:
                ':attribute' => 'The TITLE',
                
                // you might need a custom value:
                ':parameters[0]' => 3,
                
                // global modifier parameters:
                'limit_length' => 100,
            ],
        ],
    ]
);

use Tobento\Service\Validation\Validator;
use Tobento\Service\Validation\Rule\Length;

$validation = (new Validator())->validate(
    data: [
        'title' => 'Product',
    ],
    rules: [
        'title' => [
            // single or multiple rules
            'es:
            ':attribute' => 'The TITLE',
            
            // global modifier parameters:
            'limit_length' => 100,
        ],
    ]
);

use Tobento\Service\Validation\Validator;
use Tobento\Service\Validation\ValidatorInterface;
use Tobento\Service\Validation\RulesInterface;
use Tobento\Service\Validation\RulesParserInterface;
use Tobento\Service\Validation\RulesAware;
use Tobento\Service\Message\MessagesFactoryInterface;

$validator = new Validator(
    rules: null, // null|RulesInterface
    rulesParser: null, // null|RulesParserInterface
    messagesFactory: null // null|MessagesFactoryInterface
);

var_dump($validator instanceof ValidatorInterface);
// bool(true)

var_dump($validator instanceof RulesAware);
// bool(true)

use Tobento\Service\Validation\ValidatorInterface;
use Tobento\Service\Validation\ValidationInterface;
use Tobento\Service\Collection\Collection;

interface ValidatorInterface
{
    public function validating(
        mixed $value,
        string|array $rules,
        array|Collection $data = [],
        null|string $key = null
    ): ValidationInterface;
    
    public function validate(mixed $data, array $rules): ValidationInterface;
}

use Tobento\Service\Validation\RulesInterface;

interface RulesAware
{
    public function rules(): RulesInterface;
}

use Tobento\Service\Validation\ValidationInterface;
use Tobento\Service\Validation\RuleInterface;
use Tobento\Service\Message\MessagesInterface;
use Tobento\Service\Collection\Collection;

interface ValidationInterface
{
    public function isValid(): bool;
    
    public function errors(): MessagesInterface;  
    
    public function data(): Collection;
    
    public function valid(): Collection;
    
    public function invalid(): Collection;
    
    public function rule(): null|RuleInterface;
}

use Tobento\Service\Validation\Validator;
use Tobento\Service\Message\MessagesInterface;

$validation = (new Validator())->validate(
    data: [
        'title' => 'Pr',
        'color' => 'green',
    ],
    rules: [
        'title' => 'minLen:3|alpha',
        'color' => 'in:blue:red',        
    ]
);

$errors = $validation->errors();

var_dump($errors instanceof MessagesInterface);
// bool(true)

use Tobento\Service\Message\MessageInterface;

$errors = $validation->errors();

$error = $errors->key('title')->first();

var_dump($error instanceof MessageInterface);
// bool(true)
    
echo $error;
// The title must at least contain 3 chars.

use Tobento\Service\Message\MessageInterface;

$errors = $validation->errors();

foreach($errors->key('title')->all() as $error) {
    var_dump($error instanceof MessageInterface);
    // bool(true)
}

$errors = $validation->errors();

var_dump($errors->key('title')->has());
// bool(true)

use Tobento\Service\Validation\Validator;

$validation = (new Validator())->validate(
    data: [
        'title' => 'Pr',
        'color' => 'green',
    ],
    rules: [
        'title' => [
            'alpha',
            ['minLen', [3], 'error' => ':attribute must contain at least :parameters[0] chars!']
        ],
        'color' => 'in:blue:red',        
    ]
);

$errors = $validation->errors();

echo $errors->key('title')->first();
// The title must contain at least 3 chars!

use Tobento\Service\Validation\Validator;

$validation = (new Validator())->validate(
    data: [
        'title' => 'Pr',
        'color' => 'green',
    ],
    rules: [
        'title' => [
            'alpha',
            [
                'minLen',
                [3],
                ':attribute' => 'The TITLE',
                ':parameters[0]' => 3,
                'error' => ':attribute must contain at least :parameters[0] chars!'
            ]
        ],
        'color' => 'in:blue:red',        
    ]
);

$errors = $validation->errors();

echo $errors->key('title')->first();
// The TITLE must contain at least 3 chars!

use Tobento\Service\Validation\Validator;

$validation = (new Validator())->validate(
    data: [
        'title' => 'Pr',
        'color' => 'green',
    ],
    rules: [
        'title' => [
            'minLen:3|alpha',
            ':attribute' => 'The TITLE',
            // you might even set a global message for all rules.
            'error' => ':attribute is invalid',
        ],
        'color' => 'in:blue:red',
    ]
);

$errors = $validation->errors();

echo $errors->key('title')->first();
// The TITLE is invalid.

use Tobento\Service\Validation\Validator;

$validation = (new Validator())->validate(
    data: [
        'title' => '',
        'color' => 'green',
    ],
    rules: [
        'title' => [
            ''title')->first();
// The title is 

use Tobento\Service\Validation\Validator;
use Tobento\Service\Collection\Collection;

$validation = (new Validator())->validate(
    data: [
        'title' => 'Pr',
        'color' => 'green',
    ],
    rules: [
        'title' => 'minLen:3|alpha',
        'color' => 'in:blue:red',        
    ]
);

// all validated data:
var_dump($validation->data() instanceof Collection);
// bool(true)

// all valid data:
var_dump($validation->valid() instanceof Collection);
// bool(true)

// all invalid data:
var_dump($validation->invalid() instanceof Collection);
// bool(true)

use Tobento\Service\Validation\RulesInterface;
use Tobento\Service\Validation\RuleInterface;
use Tobento\Service\Validation\RuleNotFoundException;
use Tobento\Service\Validation\InvalidRuleException;

/**
 * RulesInterface
 */
interface RulesInterface
{
    /**
     * Add a rule.
     *
     * @param string $name
     * @param mixed $rule
     * @return static $this
     */
    public function add(string $name, mixed $rule): static;

    /**
     * Returns the rule based on the specified rule.
     *
     * @param mixed $rule
     * @return RuleInterface
     *
     * @throws RuleNotFoundException
     * @throws InvalidRuleException
     */
    public function get(mixed $rule): RuleInterface;
}

use Tobento\Service\Validation\DefaultRules;
use Tobento\Service\Validation\RulesInterface;
use Tobento\Service\Validation\RuleFactoryInterface;

$rules = new DefaultRules(
    ruleFactory: null, //null|RuleFactoryInterface
);

var_dump($rules instanceof RulesInterface);
// bool(true)

use Tobento\Service\Validation\DefaultRules;
use Tobento\Service\Validation\AutowiringRuleFactory;

// Any PSR-11 container
$container = new \Tobento\Service\Container\Container();

$rules = new DefaultRules(
    ruleFactory: new AutowiringRuleFactory($container);
);

use Tobento\Service\Validation\DefaultRules;
use Tobento\Service\Validation\RulesInterface;
use Tobento\Service\Validation\AutowiringRuleFactory;
use Tobento\Service\Validation\Rule\Same;
use Tobento\Service\Validation\Rule\Type;

// Any PSR-11 container
$container = new \Tobento\Service\Container\Container();

$rules = new DefaultRules(
    ruleFactory: new AutowiringRuleFactory($container);
);

$rules = new DefaultRules();

$rules->add('same', new Same());

// Lazy:
$rules->add('same', Same::class);

// Custom method:
$rules->add('bool', [new Type(), 'bool']);

// Lazy custom method:
$rules->add('bool', [Type::class, 'bool']);

// Lazy custom method with unresolvable parameters:
// $rules->add('rule', [Rule::class, 'bool', ['name' => 'value']]);

// Lazy with unresolvable parameters:
// $rules->add('rule', [Rule::class, ['name' => 'value']]);

use Tobento\Service\Validation\DefaultRules;

class CustomDefaultRules extends DefaultRules
{
    protected function getDefaultRules(): array
    {
        $rules = parent::getDefaultRules();
        
        // adding or overwriting rules.
        $rules['bool'] = [\Tobento\Service\Validation\Rule\Type::class, 'bool'];
        
        return $rules;
    }
}

$rules = new CustomDefaultRules();

use Tobento\Service\Validation\Html\HtmlAttributesFactory;

$factory = new HtmlAttributesFactory();

$attributes = $factory->createAttributes(
    rules: 'errors',
    
    // or you may disable it at all:
    // messageDataAttributeName: null,
);

var_dump($attributes);
// array(3) {[0]=> string(8) "

use Tobento\Service\Tag\Attributes;
use Tobento\Service\Validation\Html\HtmlAttributesFactory;

$factory = new HtmlAttributesFactory();

$attributes = $factory->createAttributes(
    rules: 's='{"maxlength":"The Title must at most contain 150 chars."}'" 

use Tobento\Service\Validation\RuleInterface;

/**
 * RuleInterface
 */
interface RuleInterface
{
    /**
     * Skips validation depending on value and rule method.
     * 
     * @param mixed $value The value to validate.
     * @param string $method
     * @return bool Returns true if skip validation, otherwise false.
     */
    public function skipValidation(mixed $value, string $method = 'passes'): bool;
    
    /**
     * Determine if the validation rule passes.
     * 
     * @param mixed $value The value to validate.
     * @param array $parameters Any parameters used for the validation.
     * @return bool
     */
    public function passes(mixed $value, array $parameters = []): bool;
    
    /**
     * Returns the validation error messages.
     * 
     * @return array
     */
    public function messages(): array;    
}

use Tobento\Service\Validation\Rule\Passes;

$validation = $validator->validating(
    value: 'foo',
    rules: [
        // rule does pass:
        new Passes(passes: true),
        
        // rule does not pass:
        new Passes(passes: false),
        
        // rule does pass:
        new Passes(passes: fn (mixed $value): bool => $value === 'foo'),
        
        // using static new method:
        Passes::new(passes: true),
    ],
);

use Tobento\Service\Validation\Rule\Passes;
use Tobento\Service\Validation\ValidatorInterface;
use Tobento\Service\Validation\ValidationInterface;

$rule = new Passes(passes: function(
    mixed $value,
    array $parameters,
    ValidatorInterface $validator,
    ValidationInterface $validation): bool
{
    return true;
});

use Tobento\Service\Validation\Rule\Passes;

$rule = new Passes(passes: function(mixed $value, SomeService $service): bool {
    return true;
});

use Tobento\Service\Validation\Rule\Passes;

$rule = new Passes(passes: fn (string|int $value): bool {
    return true;
});

// you may deactivate it, but then you will need to declare the value type as mixed:
$rule = new Passes(
    passes: fn (mixed $value): bool {
        return true;
    },
    verifyDeclaredType: false,
);

use Tobento\Service\Validation\Rule\Passes;

$rule = new Passes(
    passes: true,
    errorMessage: 'Custom error message',
);

$validation = $validator->validating(
    value: 'foo',
    rules: [
        // skips validation:
        new Passes(passes: true, skipValidation: true),
        
        // does not skip validation:
        new Passes(passes: true, skipValidation: false),
        
        // skips validation:
        new Passes(passes: true, skipValidation: fn (mixed $value): bool => $value === 'foo'),
    ],
);

use Tobento\Service\Validation\Rule;

class ListRule extends Rule
{
    /**
     * The error messages.
     */
    public const MESSAGES = [
        'passes' => ':attribute must be in list :parameters',
    ];
    
    /**
     * Determine if the validation rule passes.
     * 
     * @param mixed $value The value to validate.
     * @param array $parameters Any parameters used for the validation.
     * @return bool
     */
    public function passes(mixed $value, array $parameters = []): bool
    {
        return in_array($value, $parameters);
    }
}

use Tobento\Service\Validation\RulesParserInterface;
use Tobento\Service\Validation\ParsedRule;
use Tobento\Service\Validation\RulesParserException;

interface RulesParserInterface
{
    /**
     * Parses the rules.
     * 
     * @param string|array $rules
     * @return array<int, ParsedRule>
     *
     * @throws RulesParserException
     */
    public function parse(string|array $rules): array;
}

use Tobento\Service\Validation\Message\MessagesFactory;
use Tobento\Service\Message\MessagesFactoryInterface;
use Tobento\Service\Message\MessageFactoryInterface;
use Tobento\Service\Message\ModifiersInterface;
use Psr\Log\LoggerInterface;

$messagesFactory = new MessagesFactory(
    messageFactory: null, // null|MessageFactoryInterface
    modifiers: null, // null|ModifiersInterface
    logger: null, // null|LoggerInterface
);

var_dump($messagesFactory instanceof MessagesFactoryInterface);
// bool(true)

$modifiers = $messagesFactory->modifiers();

var_dump($modifiers instanceof ModifiersInterface);
// bool(true)

use Tobento\Service\Message\Modifiers;
use Tobento\Service\Validation\Message\RuleParametersModifier;
use Tobento\Service\Message\Modifier\ParameterReplacer;

$modifiers = new Modifiers(
    // maps :attribute, :value, :parameters
    // based on the rule parameters
    new RuleParametersModifier(),
    
    // Default parameter replacer
    new ParameterReplacer(),
);

use Tobento\Service\Validation\Validator;
use Tobento\Service\Validation\Message\MessagesFactory;
use Tobento\Service\Validation\Message\RuleParametersModifier;
use Tobento\Service\Translation;
use Tobento\Service\Message\Modifier\Translator;
use Tobento\Service\Message\Modifier\ParameterTranslator;
use Tobento\Service\Message\Modifiers;
use Tobento\Service\Message\Modifier\ParameterReplacer;

$translator = new Translation\Translator(
    new Translation\Resources(
        new Translation\Resource('*', 'de', [
            'The :attribute must only contain letters [a-zA-Z]' => ':attribute muss aus Buchstaben [a-zA-Z] bestehen.',
            'title' => 'Titel',
        ]),       
    ),
    new Translation\Modifiers(),
    new Translation\MissingTranslationHandler(),
    'de',
);

$messagesFactory = new MessagesFactory(
    modifiers: new Modifiers(
        new Translator(translator: $translator, src: '*'),
        new RuleParametersModifier(),
        new ParameterTranslator(
            parameters: [':attribute'],
            translator: $translator,
            src: '*'
        ),
        new ParameterReplacer(),
    )
);

$validator = new Validator(messagesFactory: $messagesFactory);

$validation = $validator->validate(
    data: [
        'title' => 'P3',
    ],
    rules: [
        'title' => 'alpha',      
    ]
);

$errors = $validation->errors();

var_dump($errors->key('title')->first()->message());
// string(44) "Titel muss aus Buchstaben [a-zA-Z] bestehen."
date
date
$value