Skip to content

Latest commit

 

History

History
executable file
·
117 lines (81 loc) · 3.56 KB

15.1 - Before validation event.md

File metadata and controls

executable file
·
117 lines (81 loc) · 3.56 KB

15.1 - Before event

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.

Using a closure function:

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();

Using a class object:

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.