Forked from ismail1432/RequestValidatorListener.php
Created
December 25, 2022 20:05
-
-
Save graste/2e0c83e3d33313c590de1c81fed1da77 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\EventListener; | |
use Symfony\Component\EventDispatcher\EventSubscriberInterface; | |
use Symfony\Component\HttpFoundation\Request; | |
use Symfony\Component\HttpKernel\Event\RequestEvent; | |
use Symfony\Component\HttpKernel\KernelEvents; | |
use Symfony\Component\Validator\Validator\ValidatorInterface; | |
use Symfony\Component\Validator\Constraints; | |
use Symfony\Component\Validator\Constraint; | |
final class ValidatorRequestListener implements EventSubscriberInterface | |
{ | |
private ValidatorInterface $validator; | |
public function __construct(ValidatorInterface $validator) | |
{ | |
$this->validator = $validator; | |
} | |
public function onKernelRequest(RequestEvent $event = null) | |
{ | |
/** @var Request $request */ | |
$request = $event->getRequest(); | |
// we fetch the validator | |
$validator = $request->get('_validator'); | |
// Early return if we don't have defined a Validator or | |
// the method is not a POST,PUT or GET. | |
if (null === $validator || !in_array($request->getMethod(), ['POST', 'PUT', 'GET'])) { | |
return; | |
} | |
// We create a collection of constraint(s) with the constraints given in the defaults Route option. | |
$collection = []; | |
foreach ($validator as $propertyToValidate => $constraintName) { | |
// Hack to dynamically create the constraint | |
// ⚠️ My case is simple, I just have 1 constraint per property | |
// if you have an array of constraints for a property, you need to iterate on them | |
$fqcn = "Symfony\Component\Validator\Constraints\\${constraintName}"; | |
$constraint = new $fqcn; | |
if (!$constraint instanceof Constraint) { | |
throw new \LogicException("Only Constraint are allowed to validate value"); | |
} | |
$collection[$propertyToValidate] = new $constraint; | |
} | |
// If method is POST or PUT, we should get the payload from the request content | |
// otherwise we get it from query string | |
if (in_array($request->getMethod(), ['POST', 'PUT'])) { | |
$payload = \json_decode($request->getContent(), true); | |
} else { | |
// Retrieve the input from the query string. | |
$payload = $request->query->all(); | |
} | |
// We remove properties that should not have to be validated | |
$input = array_intersect_key($payload, $collection); | |
$errors = $this->validator->validate($input, new Constraints\Collection($collection)); | |
// We set errors in a key "_errors" that can be retrieve from | |
// the request object with $request->attributes->get('_errors'); | |
$request->attributes->set('_errors', $errors); | |
} | |
public static function getSubscribedEvents(): array | |
{ | |
return [ | |
KernelEvents::REQUEST => [['onKernelRequest', 31]], | |
]; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment