ParamConverterManager::apply()   A
last analyzed

Complexity

Conditions 3
Paths 4

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 10
ccs 6
cts 6
cp 1
rs 9.9332
c 0
b 0
f 0
cc 3
nc 4
nop 2
crap 3
1
<?php
2
3
namespace Drupal\controller_annotations\Request\ParamConverter;
4
5
use Drupal\controller_annotations\Configuration\ConfigurationInterface;
6
use Drupal\controller_annotations\Configuration\ParamConverter;
7
use Symfony\Component\HttpFoundation\Request;
8
9
/**
10
 * @author Fabien Potencier <[email protected]>
11
 * @author Henrik Bjornskov <[email protected]>
12
 */
13
class ParamConverterManager
14
{
15
    /**
16
     * @var array
17
     */
18
    protected $converters = [];
19
20
    /**
21
     * @var array
22
     */
23
    protected $namedConverters = [];
24
25
    /**
26
     * Applies all converters to the passed configurations and stops when a
27
     * converter is applied it will move on to the next configuration and so on.
28
     *
29
     * @param Request $request
30
     * @param array|object $configurations
31
     */
32 13
    public function apply(Request $request, $configurations)
33
    {
34 13
        if (is_object($configurations)) {
35 1
            $configurations = [$configurations];
36
        }
37
38 13
        foreach ($configurations as $configuration) {
39 7
            $this->applyConverter($request, $configuration);
40
        }
41 11
    }
42
43
    /**
44
     * Apply converter on request based on the given configuration.
45
     *
46
     * @param Request $request
47
     * @param ParamConverter $configuration
48
     */
49 7
    protected function applyConverter(Request $request, ParamConverter $configuration)
50
    {
51 7
        $value = $request->attributes->get($configuration->getName());
52 7
        $className = $configuration->getClass();
53
54
        // If the value is already an instance of the class we are trying to
55
        // convert it into we should continue as no conversion is required
56 7
        if (is_object($value) && $value instanceof $className) {
57 1
            return;
58
        }
59
60 6
        if ($configuration->getConverter()) {
61 3
            $this->applyNamedConverter($request, $configuration);
62
63 1
            return;
64
        }
65
66 3
        foreach ($this->all() as $converter) {
67 3
            if ($converter->supports($configuration)) {
68 2
                if ($converter->apply($request, $configuration)) {
69 3
                    return;
70
                }
71
            }
72
        }
73 3
    }
74
75
    /**
76
     * @param Request $request
77
     * @param ParamConverter $configuration
78
     */
79 3
    protected function applyNamedConverter(Request $request, ParamConverter $configuration)
80
    {
81 3
        $converterName = $configuration->getConverter();
82 3
        if (!isset($this->namedConverters[$converterName])) {
83 1
            throw new \RuntimeException(
84 1
                sprintf(
85 1
                    "No converter named '%s' found for conversion of parameter '%s'.",
86 1
                    $converterName,
87 1
                    $configuration->getName()
88
                )
89
            );
90
        }
91
92 2
        $converter = $this->namedConverters[$converterName];
93
94 2
        if (!$converter->supports($configuration)) {
95 1
            throw new \RuntimeException(
96 1
                sprintf(
97 1
                    "Converter '%s' does not support conversion of parameter '%s'.",
98 1
                    $converterName,
99 1
                    $configuration->getName()
100
                )
101
            );
102
        }
103
104 1
        $converter->apply($request, $configuration);
105 1
    }
106
107
    /**
108
     * Adds a parameter converter.
109
     *
110
     * Converters match either explicitly via $name or by iteration over all
111
     * converters with a $priority. If you pass a $priority = null then the
112
     * added converter will not be part of the iteration chain and can only
113
     * be invoked explicitly.
114
     *
115
     * @param ParamConverterInterface $converter A ParamConverterInterface instance
116
     * @param int $priority The priority (between -10 and 10).
117
     * @param string $name Name of the converter.
118
     */
119 13
    public function add(ParamConverterInterface $converter, $priority = 0, $name = null)
120
    {
121 13
        if ($priority !== null) {
122 13
            if (!isset($this->converters[$priority])) {
123 13
                $this->converters[$priority] = [];
124
            }
125
126 13
            $this->converters[$priority][] = $converter;
127
        }
128
129 13
        if (null !== $name) {
130 2
            $this->namedConverters[$name] = $converter;
131
        }
132 13
    }
133
134
    /**
135
     * Returns all registered param converters.
136
     *
137
     * @return array An array of param converters
138
     */
139 4
    public function all()
140
    {
141 4
        krsort($this->converters);
142
143 4
        $converters = array();
144 4
        foreach ($this->converters as $all) {
145 4
            $converters = array_merge($converters, $all);
146
        }
147
148 4
        return $converters;
149
    }
150
}
151