vendor/sylius/resource-bundle/src/Bundle/Controller/ParametersParser.php line 34

Open in your IDE?
  1. <?php
  2. /*
  3. * This file is part of the Sylius package.
  4. *
  5. * (c) Paweł Jędrzejewski
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. declare(strict_types=1);
  11. namespace Sylius\Bundle\ResourceBundle\Controller;
  12. use Sylius\Bundle\ResourceBundle\Provider\RequestParameterProvider;
  13. use Symfony\Component\DependencyInjection\ContainerInterface;
  14. use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
  15. use Symfony\Component\HttpFoundation\Request;
  16. use Webmozart\Assert\Assert;
  17. final class ParametersParser implements ParametersParserInterface
  18. {
  19. private ContainerInterface $container;
  20. private ExpressionLanguage $expression;
  21. public function __construct(ContainerInterface $container, ExpressionLanguage $expression)
  22. {
  23. $this->container = $container;
  24. $this->expression = $expression;
  25. }
  26. public function parseRequestValues(array $parameters, Request $request): array
  27. {
  28. return array_map(
  29. /**
  30. * @param mixed $parameter
  31. *
  32. * @return mixed
  33. */
  34. function ($parameter) use ($request) {
  35. if (is_array($parameter)) {
  36. return $this->parseRequestValues($parameter, $request);
  37. }
  38. return $this->parseRequestValue($parameter, $request);
  39. },
  40. $parameters,
  41. );
  42. }
  43. /**
  44. * @param mixed $parameter
  45. *
  46. * @return mixed
  47. */
  48. private function parseRequestValue($parameter, Request $request)
  49. {
  50. if (!is_string($parameter)) {
  51. return $parameter;
  52. }
  53. if (0 === strpos($parameter, '$')) {
  54. return RequestParameterProvider::provide($request, substr($parameter, 1));
  55. }
  56. if (0 === strpos($parameter, 'expr:')) {
  57. return $this->parseRequestValueExpression(substr($parameter, 5), $request);
  58. }
  59. if (0 === strpos($parameter, '!!')) {
  60. return $this->parseRequestValueTypecast($parameter, $request);
  61. }
  62. return $parameter;
  63. }
  64. /** @return mixed */
  65. private function parseRequestValueExpression(string $expression, Request $request)
  66. {
  67. $expression = (string) preg_replace_callback(
  68. '/(\$\w+)/',
  69. /**
  70. * @return mixed
  71. */
  72. function (array $matches) use ($request) {
  73. $variable = $request->get(substr($matches[1], 1));
  74. if (is_array($variable) || is_object($variable)) {
  75. throw new \InvalidArgumentException(sprintf(
  76. 'Cannot use %s ($%s) as parameter in expression.',
  77. gettype($variable),
  78. $matches[1],
  79. ));
  80. }
  81. return is_string($variable) ? sprintf('"%s"', addslashes($variable)) : $variable;
  82. },
  83. $expression,
  84. );
  85. return $this->expression->evaluate($expression, ['container' => $this->container]);
  86. }
  87. /** @return mixed */
  88. private function parseRequestValueTypecast(string $parameter, Request $request)
  89. {
  90. [$typecast, $castedValue] = explode(' ', $parameter, 2);
  91. /** @var callable $castFunctionName */
  92. $castFunctionName = substr($typecast, 2) . 'val';
  93. Assert::oneOf($castFunctionName, ['intval', 'floatval', 'boolval'], 'Variable can be casted only to int, float or bool.');
  94. return $castFunctionName($this->parseRequestValue($castedValue, $request));
  95. }
  96. }