vendor/friendsofsymfony/rest-bundle/Request/ParamFetcher.php line 38

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the FOSRestBundle package.
  4.  *
  5.  * (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace FOS\RestBundle\Request;
  11. use FOS\RestBundle\Controller\Annotations\ParamInterface;
  12. use FOS\RestBundle\Exception\InvalidParameterException;
  13. use FOS\RestBundle\Util\ResolverTrait;
  14. use FOS\RestBundle\Validator\Constraints\ResolvableConstraintInterface;
  15. use Symfony\Component\DependencyInjection\ContainerInterface;
  16. use Symfony\Component\HttpFoundation\Request;
  17. use Symfony\Component\HttpFoundation\RequestStack;
  18. use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
  19. use Symfony\Component\Validator\Constraint;
  20. use Symfony\Component\Validator\ConstraintViolationList;
  21. use Symfony\Component\Validator\Validator\ValidatorInterface;
  22. use Symfony\Component\Validator\Exception\ValidatorException;
  23. use Symfony\Component\Validator\ConstraintViolation;
  24. /**
  25.  * Helper to validate parameters of the active request.
  26.  *
  27.  * @author Alexander <iam.asm89@gmail.com>
  28.  * @author Lukas Kahwe Smith <smith@pooteeweet.org>
  29.  * @author Jordi Boggiano <j.boggiano@seld.be>
  30.  * @author Boris GuĂ©ry <guery.b@gmail.com>
  31.  *
  32.  * @final since 2.8
  33.  */
  34. class ParamFetcher implements ParamFetcherInterface
  35. {
  36.     use ResolverTrait;
  37.     private $container;
  38.     private $parameterBag;
  39.     private $requestStack;
  40.     private $validator;
  41.     public function __construct(ContainerInterface $containerParamReaderInterface $paramReaderRequestStack $requestStackValidatorInterface $validator null)
  42.     {
  43.         if (null === $validator) {
  44.             @trigger_error(sprintf('Using no validator is deprecated since FOSRestBundle 2.6. The `$validator` constructor argument of the `%s` will become mandatory in 3.0.'__CLASS__), E_USER_DEPRECATED);
  45.         }
  46.         $this->container $container;
  47.         $this->requestStack $requestStack;
  48.         $this->validator $validator;
  49.         $this->parameterBag = new ParameterBag($paramReader);
  50.     }
  51.     /**
  52.      * {@inheritdoc}
  53.      */
  54.     public function setController($controller)
  55.     {
  56.         $this->parameterBag->setController($this->getRequest(), $controller);
  57.     }
  58.     /**
  59.      * Add additional params to the ParamFetcher during runtime.
  60.      *
  61.      * Note that adding a param that has the same name as an existing param will override that param.
  62.      */
  63.     public function addParam(ParamInterface $param)
  64.     {
  65.         $this->parameterBag->addParam($this->getRequest(), $param);
  66.     }
  67.     /**
  68.      * @return ParamInterface[]
  69.      */
  70.     public function getParams()
  71.     {
  72.         return $this->parameterBag->getParams($this->getRequest());
  73.     }
  74.     /**
  75.      * {@inheritdoc}
  76.      */
  77.     public function get($name$strict null)
  78.     {
  79.         $params $this->getParams();
  80.         if (!array_key_exists($name$params)) {
  81.             throw new \InvalidArgumentException(sprintf("No @ParamInterface configuration for parameter '%s'."$name));
  82.         }
  83.         /** @var ParamInterface $param */
  84.         $param $params[$name];
  85.         $default $param->getDefault();
  86.         $default $this->resolveValue($this->container$default);
  87.         $strict = (null !== $strict $strict $param->isStrict());
  88.         $paramValue $param->getValue($this->getRequest(), $default);
  89.         return $this->cleanParamWithRequirements($param$paramValue$strict$default);
  90.     }
  91.     /**
  92.      * @internal
  93.      */
  94.     protected function cleanParamWithRequirements(ParamInterface $param$paramValuebool $strict$default)
  95.     {
  96.         $this->checkNotIncompatibleParams($param);
  97.         if (null !== $default && $default === $paramValue) {
  98.             return $paramValue;
  99.         }
  100.         if (null === $this->validator) {
  101.             throw new \RuntimeException('The ParamFetcher requirements feature requires the symfony/validator component.');
  102.         }
  103.         $constraints $param->getConstraints();
  104.         $this->resolveConstraints($constraints);
  105.         if (empty($constraints)) {
  106.             return $paramValue;
  107.         }
  108.         try {
  109.             $errors $this->validator->validate($paramValue$constraints);
  110.         } catch (ValidatorException $e) {
  111.             $violation = new ConstraintViolation(
  112.                 $e->getMessage(),
  113.                 $e->getMessage(),
  114.                 [],
  115.                 $paramValue,
  116.                 '',
  117.                 null,
  118.                 null,
  119.                 $e->getCode()
  120.             );
  121.             $errors = new ConstraintViolationList([$violation]);
  122.         }
  123.         if (count($errors)) {
  124.             if ($strict) {
  125.                 throw InvalidParameterException::withViolations($param$errors);
  126.             }
  127.             return null === $default '' $default;
  128.         }
  129.         return $paramValue;
  130.     }
  131.     /**
  132.      * {@inheritdoc}
  133.      */
  134.     public function all($strict null)
  135.     {
  136.         $configuredParams $this->getParams();
  137.         $params = [];
  138.         foreach ($configuredParams as $name => $param) {
  139.             $params[$name] = $this->get($name$strict);
  140.         }
  141.         return $params;
  142.     }
  143.     /**
  144.      * @internal
  145.      */
  146.     protected function checkNotIncompatibleParams(ParamInterface $param)
  147.     {
  148.         if (null === $param->getValue($this->getRequest(), null)) {
  149.             return;
  150.         }
  151.         $params $this->getParams();
  152.         foreach ($param->getIncompatibilities() as $incompatibleParamName) {
  153.             if (!array_key_exists($incompatibleParamName$params)) {
  154.                 throw new \InvalidArgumentException(sprintf("No @ParamInterface configuration for parameter '%s'."$incompatibleParamName));
  155.             }
  156.             $incompatibleParam $params[$incompatibleParamName];
  157.             if (null !== $incompatibleParam->getValue($this->getRequest(), null)) {
  158.                 $exceptionMessage sprintf(
  159.                     '"%s" param is incompatible with %s param.',
  160.                     $param->getName(),
  161.                     $incompatibleParam->getName()
  162.                 );
  163.                 throw new BadRequestHttpException($exceptionMessage);
  164.             }
  165.         }
  166.     }
  167.     /**
  168.      * @param Constraint[] $constraints
  169.      */
  170.     private function resolveConstraints(array $constraints)
  171.     {
  172.         foreach ($constraints as $constraint) {
  173.             if ($constraint instanceof ResolvableConstraintInterface) {
  174.                 $constraint->resolve($this->container);
  175.             }
  176.         }
  177.     }
  178.     private function getRequest(): Request
  179.     {
  180.         $request $this->requestStack->getCurrentRequest();
  181.         if (null === $request) {
  182.             throw new \RuntimeException('There is no current request.');
  183.         }
  184.         return $request;
  185.     }
  186. }