tobento/app-validation

App validation support.

1.0.1 2024-02-21 16:42 UTC

This package is auto-updated.

Last update: 2024-04-21 17:02:12 UTC


README

Validation support for the app.

Table of Contents

Getting Started

Add the latest version of the app validation project running this command.

composer require tobento/app-validation

Requirements

  • PHP 8.0 or greater

Documentation

App

Check out the App Skeleton if you are using the skeleton.

You may also check out the App to learn more about the app in general.

Validator Boot

The validator boot does the following:

  • installs validator translation files
  • validator and rules interfaces implementation
use Tobento\App\AppFactory;

// Create the app
$app = (new AppFactory())->createApp();

// Adding boots
$app->boot(\Tobento\App\Validation\Boot\Validator::class);

// Run the app
$app->run();

Validate Data

You can validate data using the ValidatorInterface::class. You can access the validator in several ways:

Check out the Validation Service - Validating section learn more about validating data in general.

Using the app

use Tobento\App\AppFactory;
use Tobento\Service\Validation\ValidatorInterface;

// Create the app
$app = (new AppFactory())->createApp();

// Add directories:
$app->dirs()
    ->dir(realpath(__DIR__.'/../'), 'root')
    ->dir(realpath(__DIR__.'/../app/'), 'app')
    ->dir($app->dir('app').'config', 'config', group: 'config')
    ->dir($app->dir('root').'public', 'public')
    ->dir($app->dir('root').'vendor', 'vendor');
    
// Adding boots
$app->boot(\Tobento\App\Validation\Boot\Validator::class);
$app->booting();

$validator = $app->get(ValidatorInterface::class);

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

// var_dump($validation->isValid());
// bool(true)

// Run the app
$app->run();

Using autowiring

You can also request the ValidatorInterface::class in any class resolved by the app.

use Tobento\Service\Validation\ValidatorInterface;

class SomeService
{
    public function __construct(
        protected ValidatorInterface $validator,
    ) {}
}

Adding Rules

The Default Rules are available by default. You may add more rules by the following way:

use Tobento\App\AppFactory;
use Tobento\Service\Validation\RulesInterface;

// Create the app
$app = (new AppFactory())->createApp();

// Add directories:
$app->dirs()
    ->dir(realpath(__DIR__.'/../'), 'root')
    ->dir(realpath(__DIR__.'/../app/'), 'app')
    ->dir($app->dir('app').'config', 'config', group: 'config')
    ->dir($app->dir('root').'public', 'public')
    ->dir($app->dir('root').'vendor', 'vendor');
    
// Adding boots
$app->boot(\Tobento\App\Validation\Boot\Validator::class);

// using the app on method:
$app->on(RulesInterface::class, function(RulesInterface $rules) {
    $rules->add(name: 'same', rule: new Same());
});

// Run the app
$app->run();

You may check out the Rules section to learn more about adding rules.

Message Translation

Simply, install the App Translation bundle and boot the \Tobento\App\Translation\Boot\Translation::class:

composer require tobento/app-translation
use Tobento\App\AppFactory;

// Create the app
$app = (new AppFactory())->createApp();

// Add directories:
$app->dirs()
    ->dir(realpath(__DIR__.'/../'), 'root')
    ->dir(realpath(__DIR__.'/../app/'), 'app')
    ->dir($app->dir('app').'config', 'config', group: 'config')
    ->dir($app->dir('root').'public', 'public')
    ->dir($app->dir('root').'vendor', 'vendor');
    
// Adding boots
$app->boot(\Tobento\App\Translation\Boot\Translation::class);
$app->boot(\Tobento\App\Validation\Boot\Validator::class);

// Run the app
$app->run();

Messages will be translated based on the Configured Translator Locale.

By default, the Default Rules error messages are translated in en and de.

Check out the Add Translation section to learn how to add translations.

Make sure you define the resource name validator for rule error messages as configured on the Message Translator Modifier. The Message Parameter Translator Modifier uses the * as resource name.

Http Validation

Http Requirements

The following app example shows the minimum requirements for the http validation.

First, install the App Http bundle:

composer require tobento/app-http

In addition, you may install the App View bundle for view support:

composer require tobento/app-view

Next, make sure the following boots are defined:

use Tobento\App\AppFactory;

// Create the app
$app = (new AppFactory())->createApp();

// Add directories:
$app->dirs()
    ->dir(realpath(__DIR__.'/../'), 'root')
    ->dir(realpath(__DIR__.'/../app/'), 'app')
    ->dir($app->dir('app').'config', 'config', group: 'config')
    ->dir($app->dir('root').'public', 'public')
    ->dir($app->dir('root').'vendor', 'vendor');
    
// HTTP boots:
// Required for request validation:
$app->boot(\Tobento\App\Http\Boot\Routing::class);
$app->boot(\Tobento\App\Http\Boot\RequesterResponser::class);

// Required for flashing input and messages:
$app->boot(\Tobento\App\Http\Boot\Session::class);

// VIEW boots:
// Optional boots for view support:
$app->boot(\Tobento\App\View\Boot\View::class);
$app->boot(\Tobento\App\View\Boot\Form::class);
$app->boot(\Tobento\App\View\Boot\Messages::class);

// VALIDATION boots:
// Default error handler for handling ValidationException.
// You may create your own handler or add one with higher priority.
$app->boot(\Tobento\App\Validation\Boot\HttpValidationErrorHandler::class);

$app->boot(\Tobento\App\Validation\Boot\Validator::class);

// Run the app
$app->run();

Using Validation Request

You may use the Tobento\App\Validation\Http\ValidationRequest::class for validating the request input.

By default, a Tobento\App\Validation\Exception\ValidationException::class will be thrown if validation fails. The exception will be handled by the Tobento\App\Validation\Boot\HttpValidationErrorHandler::class if booted. See Http Validation Error Handler Boot.

use Tobento\App\Validation\Http\ValidationRequest;
use Tobento\Service\Validation\ValidationInterface;
use Tobento\Service\Requester\RequesterInterface;
use Tobento\Service\Responser\ResponserInterface;
use Tobento\Service\Routing\RouterInterface;
use Psr\Http\Message\ResponseInterface;

class ProductController
{
    /**
     * Store a new product.
     */
    public function store(ValidationRequest $request): ResponseInterface
    {
        $validation = $request->validate(
            rules: [
                'title' => 'required|alpha',
            ],

            // You may specify an uri for redirection.
            redirectUri: '/products/create',

            // Or you may specify a route name for redirection.
            redirectRouteName: 'products.create',

            // If no uri or route name is specified,
            // it will be redirected to the previous url.

            // You may specify an error message flashed to the user.
            errorMessage: 'You have some errors check out the fields for its error message',

            // You may change the behaviour by a custom validation error handler though.
        );

        // The product is valid, store product e.g.

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

        // The following interfaces are available:
        var_dump($request->requester() instanceof RequesterInterface);
        // bool(true)

        var_dump($request->responser() instanceof ResponserInterface);
        // bool(true)

        var_dump($request->router() instanceof RouterInterface);
        // bool(true)

        // you may use the responser and router for redirection:
        return $request->responser()->redirect($request->router()->url('products.index'));
    }
}

You may check out the following links for its documentation:

Manually handling validation

use Tobento\App\Validation\Http\ValidationRequest;
use Psr\Http\Message\ResponseInterface;

class ProductController
{
    public function store(ValidationRequest $request): ResponseInterface
    {
        $validation = $request->validate(
            rules: [
                'title' => 'required|alpha',
            ],

            // you may disable throwing ValidationException on failure
            // and handling it by yourself.
            throwExceptionOnFailure: false,
        );

        if (! $validation->isValid()) {
            // handle invalid validation.
        }

        // ...
    }
}

Http Validation Error Handler Boot

The http error handler boot does the following:

  • handles Tobento\App\Validation\Exception\ValidationException::class exceptions.
use Tobento\App\AppFactory;

// Create the app
$app = (new AppFactory())->createApp();

// Adding boots
$app->boot(\Tobento\App\Validation\Boot\HttpValidationErrorHandler::class);

$app->boot(\Tobento\App\Validation\Boot\Validator::class);

// Run the app
$app->run();

When the incoming HTTP request is expecting a JSON response, the error handler will return a 422 Unprocessable Entity HTTP response with the following format:

{
    "message": "The exception message",
    "errors": {
        "email": [
            "The email is required."
        ]
    }
}

Otherwise, the error handler will return a redirect response by using the defined redirectUri parameter from the Tobento\App\Validation\Exception\ValidationException::class or if not defined using the Tobento\Service\Uri\PreviousUriInterface::class uri:

Furthermore, you may create a custom Error Handler or add an Error Handler With A Higher Priority of 3000 as defined on the Tobento\App\Validation\Boot\HttpValidationErrorHandler::class.

Live Validation

In progress...

Credits