Completed
Push — master ( acb828...319569 )
by Grégoire
12s
created

RouteCollection   A

Complexity

Total Complexity 33

Size/Duplication

Total Lines 275
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
wmc 33
lcom 1
cbo 1
dl 0
loc 275
rs 9.76
c 0
b 0
f 0

16 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
B add() 0 37 7
A getCode() 0 8 2
A addCollection() 0 8 2
A getElements() 0 8 2
A has() 0 4 1
A get() 0 12 2
A remove() 0 6 1
A clearExcept() 0 20 5
A clear() 0 6 1
A actionify() 0 14 3
A getBaseCodeRoute() 0 4 1
A getBaseControllerName() 0 4 1
A getBaseRouteName() 0 4 1
A getBaseRoutePattern() 0 4 1
A resolve() 0 8 2
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Sonata Project package.
7
 *
8
 * (c) Thomas Rabaix <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Sonata\AdminBundle\Route;
15
16
use Symfony\Component\Routing\Route;
17
18
/**
19
 * @author Thomas Rabaix <[email protected]>
20
 */
21
class RouteCollection
22
{
23
    /**
24
     * @var Route[]
25
     */
26
    protected $elements = [];
27
28
    /**
29
     * @var string
30
     */
31
    protected $baseCodeRoute;
32
33
    /**
34
     * @var string
35
     */
36
    protected $baseRouteName;
37
38
    /**
39
     * @var string
40
     */
41
    protected $baseControllerName;
42
43
    /**
44
     * @var string
45
     */
46
    protected $baseRoutePattern;
47
48
    /**
49
     * @param string $baseCodeRoute
50
     * @param string $baseRouteName
51
     * @param string $baseRoutePattern
52
     * @param string $baseControllerName
53
     */
54
    public function __construct($baseCodeRoute, $baseRouteName, $baseRoutePattern, $baseControllerName)
55
    {
56
        $this->baseCodeRoute = $baseCodeRoute;
57
        $this->baseRouteName = $baseRouteName;
58
        $this->baseRoutePattern = $baseRoutePattern;
59
        $this->baseControllerName = $baseControllerName;
60
    }
61
62
    /**
63
     * Add route.
64
     *
65
     * @param string $name
66
     * @param string $pattern   Pattern (will be automatically combined with @see $this->baseRoutePattern and $name
67
     * @param string $host
68
     * @param string $condition
69
     *
70
     * @return RouteCollection
71
     */
72
    public function add(
73
        $name,
74
        $pattern = null,
75
        array $defaults = [],
76
        array $requirements = [],
77
        array $options = [],
78
        $host = '',
79
        array $schemes = [],
80
        array $methods = [],
81
        $condition = ''
82
    ) {
83
        $pattern = $this->baseRoutePattern.'/'.($pattern ?: $name);
84
        $code = $this->getCode($name);
85
        $routeName = $this->baseRouteName.'_'.$name;
86
87
        if (!isset($defaults['_controller'])) {
88
            $actionJoiner = false === \strpos($this->baseControllerName, '\\') ? ':' : '::';
89
            if (':' !== $actionJoiner && false !== \strpos($this->baseControllerName, ':')) {
90
                $actionJoiner = ':';
91
            }
92
93
            $defaults['_controller'] = $this->baseControllerName.$actionJoiner.$this->actionify($code);
94
        }
95
96
        if (!isset($defaults['_sonata_admin'])) {
97
            $defaults['_sonata_admin'] = $this->baseCodeRoute;
98
        }
99
100
        $defaults['_sonata_name'] = $routeName;
101
102
        $this->elements[$this->getCode($name)] = function () use (
103
            $pattern, $defaults, $requirements, $options, $host, $schemes, $methods, $condition) {
104
            return new Route($pattern, $defaults, $requirements, $options, $host, $schemes, $methods, $condition);
105
        };
106
107
        return $this;
108
    }
109
110
    /**
111
     * @param string $name
112
     *
113
     * @return string
114
     */
115
    public function getCode($name)
116
    {
117
        if (false !== strrpos($name, '.')) {
118
            return $name;
119
        }
120
121
        return $this->baseCodeRoute.'.'.$name;
122
    }
123
124
    /**
125
     * @return RouteCollection
126
     */
127
    public function addCollection(self $collection)
128
    {
129
        foreach ($collection->getElements() as $code => $route) {
130
            $this->elements[$code] = $route;
131
        }
132
133
        return $this;
134
    }
135
136
    /**
137
     * @return Route[]
138
     */
139
    public function getElements()
140
    {
141
        foreach ($this->elements as $name => $element) {
142
            $this->elements[$name] = $this->resolve($element);
143
        }
144
145
        return $this->elements;
146
    }
147
148
    /**
149
     * @param string $name
150
     *
151
     * @return bool
152
     */
153
    public function has($name)
154
    {
155
        return array_key_exists($this->getCode($name), $this->elements);
156
    }
157
158
    /**
159
     * @param string $name
160
     *
161
     * @throws \InvalidArgumentException
162
     *
163
     * @return Route
164
     */
165
    public function get($name)
166
    {
167
        if ($this->has($name)) {
168
            $code = $this->getCode($name);
169
170
            $this->elements[$code] = $this->resolve($this->elements[$code]);
171
172
            return $this->elements[$code];
173
        }
174
175
        throw new \InvalidArgumentException(sprintf('Element "%s" does not exist.', $name));
176
    }
177
178
    /**
179
     * @param string $name
180
     *
181
     * @return RouteCollection
182
     */
183
    public function remove($name)
184
    {
185
        unset($this->elements[$this->getCode($name)]);
186
187
        return $this;
188
    }
189
190
    /**
191
     * Remove all routes except routes in $routeList.
192
     *
193
     * @param string[]|string $routeList
194
     *
195
     * @return RouteCollection
196
     */
197
    public function clearExcept($routeList)
198
    {
199
        if (!\is_array($routeList)) {
200
            $routeList = [$routeList];
201
        }
202
203
        $routeCodeList = [];
204
        foreach ($routeList as $name) {
205
            $routeCodeList[] = $this->getCode($name);
206
        }
207
208
        $elements = $this->elements;
209
        foreach ($elements as $key => $element) {
210
            if (!\in_array($key, $routeCodeList)) {
211
                unset($this->elements[$key]);
212
            }
213
        }
214
215
        return $this;
216
    }
217
218
    /**
219
     * Remove all routes.
220
     *
221
     * @return RouteCollection
222
     */
223
    public function clear()
224
    {
225
        $this->elements = [];
226
227
        return $this;
228
    }
229
230
    /**
231
     * Convert a word in to the format for a symfony action action_name => actionName.
232
     *
233
     * @param string $action Word to actionify
234
     *
235
     * @return string Actionified word
236
     */
237
    public function actionify($action)
238
    {
239
        if (false !== ($pos = strrpos($action, '.'))) {
240
            $action = substr($action, $pos + 1);
241
        }
242
243
        // if this is a service rather than just a controller name, the suffix
244
        // Action is not automatically appended to the method name
245
        if (false === strpos($this->baseControllerName, ':')) {
246
            $action .= 'Action';
247
        }
248
249
        return lcfirst(str_replace(' ', '', ucwords(strtr($action, '_-', '  '))));
250
    }
251
252
    /**
253
     * @return string
254
     */
255
    public function getBaseCodeRoute()
256
    {
257
        return $this->baseCodeRoute;
258
    }
259
260
    /**
261
     * @return string
262
     */
263
    public function getBaseControllerName()
264
    {
265
        return $this->baseControllerName;
266
    }
267
268
    /**
269
     * @return string
270
     */
271
    public function getBaseRouteName()
272
    {
273
        return $this->baseRouteName;
274
    }
275
276
    /**
277
     * @return string
278
     */
279
    public function getBaseRoutePattern()
280
    {
281
        return $this->baseRoutePattern;
282
    }
283
284
    /**
285
     * @return Route
286
     */
287
    private function resolve($element)
288
    {
289
        if (\is_callable($element)) {
290
            return \call_user_func($element);
291
        }
292
293
        return $element;
294
    }
295
}
296