Last active
December 25, 2022 20:05
-
-
Save ismail1432/f0db7c799b048c542dc48302b0bc69b7 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