Completed
Push — scalar-types/resource ( 4814fd )
by Kamil
23:02
created

OptionsParser::parseOption()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 20
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 20
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 10
nc 5
nop 3
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\Grid\Parser;
15
16
use Symfony\Component\DependencyInjection\ContainerInterface;
17
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
18
use Symfony\Component\HttpFoundation\Request;
19
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
20
21
/**
22
 * @author Grzegorz Sadowski <[email protected]>
23
 */
24
final class OptionsParser implements OptionsParserInterface
25
{
26
    /**
27
     * @var ContainerInterface
28
     */
29
    private $container;
30
31
    /**
32
     * @var ExpressionLanguage
33
     */
34
    private $expression;
35
36
    /**
37
     * @var PropertyAccessorInterface
38
     */
39
    private $propertyAccessor;
40
41
    /**
42
     * @param ContainerInterface $container
43
     * @param ExpressionLanguage $expression
44
     * @param PropertyAccessorInterface $propertyAccessor
45
     */
46
    public function __construct(
47
        ContainerInterface $container,
48
        ExpressionLanguage $expression,
49
        PropertyAccessorInterface $propertyAccessor
50
    ) {
51
        $this->container = $container;
52
        $this->expression = $expression;
53
        $this->propertyAccessor = $propertyAccessor;
54
    }
55
56
    /**
57
     * {@inheritdoc}
58
     */
59
    public function parseOptions(array $parameters, Request $request, $data = null): array
60
    {
61
        return array_map(function ($parameter) use ($request, $data) {
62
            if (is_array($parameter)) {
63
                return $this->parseOptions($parameter, $request, $data);
64
            }
65
66
            return $this->parseOption($parameter, $request, $data);
67
        }, $parameters);
68
    }
69
70
    /**
71
     * @param mixed $parameter
72
     * @param Request $request
73
     * @param mixed $data
74
     *
75
     * @return mixed
76
     */
77
    private function parseOption($parameter, Request $request, $data)
78
    {
79
        if (!is_string($parameter)) {
80
            return $parameter;
81
        }
82
83
        if (0 === strpos($parameter, '$')) {
84
            return $request->get(substr($parameter, 1));
85
        }
86
87
        if (0 === strpos($parameter, 'expr:')) {
88
            return $this->parseOptionExpression(substr($parameter, 5), $request);
89
        }
90
91
        if (0 === strpos($parameter, 'resource.')) {
92
            return $this->parseOptionResourceField(substr($parameter, 9), $data);
93
        }
94
95
        return $parameter;
96
    }
97
98
    /**
99
     * @param string $expression
100
     * @param Request $request
101
     *
102
     * @return string
103
     */
104
    private function parseOptionExpression(string $expression, Request $request): string
105
    {
106
        $expression = preg_replace_callback('/\$(\w+)/', function (array $matches) use ($request) {
107
            $variable = $request->get($matches[1]);
108
109
            return is_string($variable) ? sprintf('"%s"', $variable) : $variable;
110
        }, $expression);
111
112
        return $this->expression->evaluate($expression, ['container' => $this->container]);
113
    }
114
115
    /**
116
     * @param string $value
117
     * @param mixed $data
118
     *
119
     * @return mixed
120
     */
121
    private function parseOptionResourceField(string $value, $data)
122
    {
123
        return $this->propertyAccessor->getValue($data, $value);
124
    }
125
}
126