Skip to content

A Symfony Validator wrapper that enables fluent-style validation for raw values, offering an easy-to-use and intuitive API to validate user input or other data in a concise and readable manner.

License

Notifications You must be signed in to change notification settings

programmatordev/fluent-validator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

34 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Fluent Validator

Latest Version Software License Tests

A Symfony Validator wrapper that enables fluent-style validation for raw values, offering an easy-to-use and intuitive API to validate user input or other data in a concise and readable manner.

Features

  • 🌊 Fluent-style validation: Chain validation methods for better readability and flow.
  • 🀘 Constraints autocompletion: Enables IDE autocompletion for available constraints.
  • πŸ”₯ Three validation methods: Use validate, assert, or isValid based on the context (i.e., collect errors or throw exceptions).
  • βš™οΈ Custom constraints: Easily integrate custom validation logic with Symfony's Validator system.
  • πŸ’¬ Translations support: Translate validation error messages into multiple languages.

Table of Contents

Requirements

  • PHP 8.2 or higher.

Installation

Install via Composer:

composer require programmatordev/fluent-validator

Usage

Simple usage example:

use ProgrammatorDev\FluentValidator\Validator;

// example: validate the user's age to ensure it's between 18 and 60
$errors = Validator::notBlank()
    ->greaterThanOrEqual(18)
    ->lessThan(60)
    ->validate($age);

if ($errors->count() > 0) {
    // handle errors
}

Constraints autocompletion is available in IDEs like PhpStorm. The method names match Symfony constraints but with a lowercase first letter:

  • NotBlank => notBlank
  • All => all
  • PasswordStrength => passwordStrength
  • ...and so on.

For all available constraints, check the Constraints section.

For all available methods, check the Methods section.

There is also a section for Custom Constraints and Translations.

Constraints

All available constraints can be found on the Symfony Validator documentation.

For custom constraints, check the Custom Constraints section.

Methods

validate

use Symfony\Component\Validator\Constraints\GroupSequence;

validate(mixed $value, ?string $name = null, string|GroupSequence|array|null $groups = null): ConstraintViolationListInterface

Returns a ConstraintViolationList object, acting as an array of errors.

use ProgrammatorDev\FluentValidator\Validator;

$errors = Validator::email()->validate('[email protected]');

if ($errors->count() > 0) {
    foreach ($errors as $error) {
        $message = $error->getMessage();
        // ...
    }
}

assert

use Symfony\Component\Validator\Constraints\GroupSequence;

assert(mixed $value, ?string $name = null, string|GroupSequence|array|null $groups = null): void

Throws a ValidationFailedException when validation fails.

use ProgrammatorDev\FluentValidator\Exception\ValidationFailedException;
use ProgrammatorDev\FluentValidator\Validator;

try {
    Validator::notBlank()->assert($name);
    Validator::notBlank()->email()->assert($email);
}
catch (ValidationFailedException $exception) {
    // exception message will always be the first error thrown
    $message = $exception->getMessage();
    // value that failed validation
    $value = $exception->getInvalidValue();
    // get access to all errors
    // returns a ConstraintViolationList object like in the validate method
    $errors = $exception->getViolations();
    
    // ...
}

isValid

use Symfony\Component\Validator\Constraints\GroupSequence;

isValid(mixed $value, string|GroupSequence|array|null $groups = null): bool

Returns a bool indicating if the value is valid.

use ProgrammatorDev\FluentValidator\Validator;

if (!Validator::email()->isValid($email)) {
    // handle invalid email
}

getConstraints

use Symfony\Component\Validator\Constraint;

/** @return Constraint[] */
getConstraints(): array

Returns an array with all added constraints.

use ProgrammatorDev\FluentValidator\Validator;

$constraints = Validator::notBlank()->email()->getConstraints();

It is useful for Composite constraints (i.e., a constraint that is composed of other constraints) and keeps the fluent-style validation:

use ProgrammatorDev\FluentValidator\Validator;

// validate that array should have at least one value
// and each value should be between 0 and 100
$errors = Validator::count(min: 1)
    ->all(Validator::range(min: 0, max: 100)->getConstraints())
    ->validate($value);

addNamespace

addNamespace(string $namespace): void

Used to add namespaces for custom constraints.

Check the Custom Constraints section.

setTranslator

use Symfony\Contracts\Translation\TranslatorInterface;

setTranslator(?TranslatorInterface $translator): void

Used to add a translator for validation error message translations.

Check the Translations section.

Custom Constraints

If you need a custom constraint, follow the Symfony Validator documentation: Creating Custom Constraints.

Example: Creating a ContainsAlphanumeric Constraint

1. Create a Constraint Class

This class defines the error message and configurable options.

namespace App\Constraint;

use Symfony\Component\Validator\Constraint;

class ContainsAlphanumeric extends Constraint
{
    // set configurable options
}

2. Create the Validator Class

The validator checks if the value complies with the constraint rules.

namespace App\Constraint;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

class ContainsAlphanumericValidator extends ConstraintValidator
{
    public function validate(mixed $value, Constraint $constraint): void
    {
        // custom validation logic
    }
}

3. Register the Constraint Namespace

Register the namespace where the custom constraints will be located in your project.

use ProgrammatorDev\FluentValidator\Validator;

Validator::addNamespace('App\Constraint');

Validator::notBlank()->containsAlphanumeric()->isValid('!'); // false
Validator::notBlank()->containsAlphanumeric()->isValid('v4l1d'); // true

You can have multiple constraints in the same namespace or have multiple namespaces.

Note

Custom constraints will not be suggested in IDE autocompletion.

Translations

Set a global translator to handle error message translations.

use ProgrammatorDev\FluentValidator\Translator\Translator;

// set translator to Portuguese (Portugal) locale
Validator::setTranslator(new Translator('pt'));

// now all error messages will be in Portuguese
Validator::notBlank()->validate('');

To add your own translations, you can integrate a custom translator.

Contributing

Any form of contribution to improve this library (including requests) will be welcome and appreciated. Make sure to open a pull request or issue.

License

This project is licensed under the MIT license. Please see the LICENSE file distributed with this source code for further information regarding copyright and licensing.

About

A Symfony Validator wrapper that enables fluent-style validation for raw values, offering an easy-to-use and intuitive API to validate user input or other data in a concise and readable manner.

Topics

Resources

License

Stars

Watchers

Forks

Languages