The before event will be executed before validation is executed. This can be handy if you want to check if multiple product id's exists in the database. Instead of querying the database per product id, you can query the database just once based on all product id's at once and store these to check if a product id exists in the array from product id's from the database.
You can use a closure
function or an object class as event handler.
use KrisKuiper\Validator\Blueprint\Events\BeforeEvent;
use KrisKuiper\Validator\Validator;
$data = [
'products' => [
['id' => 1, 'title' => 'Product 1'],
['id' => 2, 'title' => 'Product 2'],
['id' => 3, 'title' => 'Product 3'],
['id' => 4, 'title' => 'Product 4'],
]
];
$validator = new Validator($data);
//Attach a new before event listener
$validator->before(function (BeforeEvent $event) {
//All product id's should be an integer number
if($event->field('product.*.id')->isInt()->isValid() === false) {
return;
}
//Retrieve all product ids as an array
$ids = $event->getValue('product.*.id');
//Retrieve the products from a database
$products = $DB->getProductsByIds($ids);
//Store the ids in the validation storage for later use
$event->storage()->set('ids', $products->pluck('id'));
});
//Retrieve all product id's and validate the provided id's
$productIds = $validator->storage()->get('ids');//[1, 2, 3, 4]
$validator->field('product.*.id')->required()->isInt()->in($productIds);
//Execute validation
$validator->execute();
Create a new class CustomBeforeHandler
that implements the BeforeEventInterface
:
use KrisKuiper\Validator\Blueprint\Contracts\BeforeEventInterface;
use KrisKuiper\Validator\Blueprint\Events\BeforeEvent;
class CustomBeforeHandler implements BeforeEventInterface
{
public function handle(BeforeEvent $event): void
{
//All product id's should be an integer number
if($event->field('product.*.id')->isInt()->isValid() === false) {
return;
}
//Retrieve all product ids as an array
$ids = $event->getValue('product.*.id');
//Retrieve the products from a database
$products = $DB->getProductsByIds($ids);
//Store the ids in the validation storage for later use
$event->storage()->set('ids', $products->pluck('id'));
}
}
Use this class in the validation:
use KrisKuiper\Validator\Validator;
$data = [
'products' => [
['id' => 1, 'title' => 'Product 1'],
['id' => 2, 'title' => 'Product 2'],
['id' => 3, 'title' => 'Product 3'],
['id' => 4, 'title' => 'Product 4'],
]
];
$validator = new Validator($data);
//Attach the before event handler
$validator->loadBeforeEvent(new CustomBeforeHandler());
//Retrieve all product id's and validate the provided id's
$productIds = $validator->storage()->get('ids');//[1, 2, 3, 4]
$validator->field('product.*.id')->required()->isInt()->in($productIds);
//Execute validation
$validator->execute();
Note: The before
event is also attachable to blueprint validators.
Go to the previous section.
Go to the next section.