Completed
Push — utc-datetime-storing ( 6fbf75...e1fcef )
by Kamil
25:51
created

ParametersParser::parseRequestValue()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 26
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 26
rs 8.439
c 0
b 0
f 0
cc 5
eloc 13
nc 5
nop 2
1
<?php
2
3
/*
4
 * This file is part of the Sylius package.
5
 *
6
 * (c) Paweł Jędrzejewski
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Sylius\Bundle\ResourceBundle\Controller;
15
16
use Symfony\Component\DependencyInjection\ContainerInterface;
17
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
18
use Symfony\Component\HttpFoundation\Request;
19
use Webmozart\Assert\Assert;
20
21
/**
22
 * @author Paweł Jędrzejewski <[email protected]>
23
 * @author Dosena Ishmael <[email protected]>
24
 */
25
final class ParametersParser implements ParametersParserInterface
26
{
27
    /**
28
     * @var ContainerInterface
29
     */
30
    private $container;
31
32
    /**
33
     * @var ExpressionLanguage
34
     */
35
    private $expression;
36
37
    /**
38
     * @param ContainerInterface $container
39
     * @param ExpressionLanguage $expression
40
     */
41
    public function __construct(ContainerInterface $container, ExpressionLanguage $expression)
42
    {
43
        $this->container = $container;
44
        $this->expression = $expression;
45
    }
46
47
    /**
48
     * {@inheritdoc}
49
     */
50
    public function parseRequestValues(array $parameters, Request $request): array
51
    {
52
        return array_map(function ($parameter) use ($request) {
53
            if (is_array($parameter)) {
54
                return $this->parseRequestValues($parameter, $request);
55
            }
56
57
            return $this->parseRequestValue($parameter, $request);
58
        }, $parameters);
59
    }
60
61
    /**
62
     * @param mixed $parameter
63
     * @param Request $request
64
     *
65
     * @return mixed
66
     */
67
    private function parseRequestValue($parameter, Request $request)
68
    {
69
        if (!is_string($parameter)) {
70
            return $parameter;
71
        }
72
73
        if (0 === strpos($parameter, '$')) {
74
            return $request->get(substr($parameter, 1));
75
        }
76
77
        if (0 === strpos($parameter, 'expr:')) {
78
            return $this->parseRequestValueExpression(substr($parameter, 5), $request);
79
        }
80
81
        if (0 === strpos($parameter, '!!')) {
82
            $parameter = explode(' ', $parameter);
83
84
            $parser = trim($parameter[0], '!').'val';
85
86
            Assert::oneOf($parser, ['intval', 'floatval', 'doubleval'], 'Variable can be parsed only to int, float or double.');
87
88
            return $parser($request->get(substr($parameter[1], 1)));
89
        }
90
91
        return $parameter;
92
    }
93
94
    /**
95
     * @param string $expression
96
     * @param Request $request
97
     *
98
     * @return string
0 ignored issues
show
Documentation introduced by
Should the return type not be array? Also, consider making the array more specific, something like array<String>, or String[].

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
99
     */
100
    private function parseRequestValueExpression(string $expression, Request $request)
101
    {
102
        $expression = preg_replace_callback('/(\$\w+)/', function ($matches) use ($request) {
103
            $variable = $request->get(substr($matches[1], 1));
104
105
            if (is_array($variable) || is_object($variable)) {
106
                throw new \InvalidArgumentException(sprintf(
107
                    'Cannot use %s ($%s) as parameter in expression.',
108
                    gettype($variable),
109
                    $matches[1]
110
                ));
111
            }
112
113
            return is_string($variable) ? sprintf('"%s"', $variable) : $variable;
114
        }, $expression);
115
116
        return $this->expression->evaluate($expression, ['container' => $this->container]);
117
    }
118
}
119