tobento / app-validation
App validation support.
Requires
- php: >=8.0
- tobento/app: ^1.0
- tobento/app-migration: ^1.0
- tobento/service-message: ^1.0.1
- tobento/service-validation: ^1.0
Requires (Dev)
- nyholm/psr7: ^1.0
- phpunit/phpunit: ^9.5
- tobento/app-http: ^1.0.8
- tobento/app-translation: ^1.0
- tobento/app-view: ^1.0.1
- vimeo/psalm: ^4.0
Suggests
- tobento/app-http: Support for Http validation
- tobento/app-translation: Support for translating messages
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...