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