Completed
Pull Request — 3.x (#127)
by Joschi
02:04
created

Map::__call()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 5
ccs 3
cts 3
cp 1
rs 9.4285
cc 1
eloc 3
nc 1
nop 2
crap 1
1
<?php
2
/**
3
 *
4
 * This file is part of Aura for PHP.
5
 *
6
 * @license http://opensource.org/licenses/bsd-license.php BSD
7
 *
8
 */
9
namespace Aura\Router;
10
11
use ArrayIterator;
12
use IteratorAggregate;
13
14
/**
15
 *
16
 * A collection of route objects.
17
 *
18
 * @package Aura.Router
19
 *
20
 */
21
class Map implements IteratorAggregate
22
{
23
    /**
24
     *
25
     * An array of route objects.
26
     *
27
     * @var array
28
     *
29
     */
30
    protected $routes = [];
31
32
    /**
33
     *
34
     * A prototype Route.
35
     *
36
     * @var Route
37
     *
38
     */
39
    protected $protoRoute;
40
41
    /**
42
     *
43
     * Constructor.
44
     *
45
     * @param Route $protoRoute A prototype Route.
46
     *
47
     */
48 22
    public function __construct(Route $protoRoute)
49
    {
50 22
        $this->protoRoute = $protoRoute;
51 22
    }
52
53
    /**
54
     *
55
     * Proxy unknown method calls to the proto-route.
56
     *
57
     * @param string $method The method name.
58
     *
59
     * @param array $params The method params.
60
     *
61
     * @return $this
62
     *
63
     */
64 3
    public function __call($method, $params)
65
    {
66 3
        call_user_func_array([$this->protoRoute, $method], $params);
67 3
        return $this;
68
    }
69
70
    /**
71
     *
72
     * IteratorAggregate: returns the iterator object.
73
     *
74
     * @return ArrayIterator
75
     *
76
     */
77 5
    public function getIterator()
78
    {
79 5
        return new ArrayIterator($this->routes);
80
    }
81
82
    /**
83
     *
84
     * Sets the array of route objects to use.
85
     *
86
     * @param array $routes Use this array of routes.
87
     *
88
     * @return null
89
     *
90
     * @see getRoutes()
91
     *
92
     */
93 1
    public function setRoutes(array $routes)
94
    {
95 1
        $this->routes = $routes;
96 1
    }
97
98
    /**
99
     *
100
     * Gets the route collection.
101
     *
102
     * @return Map
103
     *
104
     * @see setRoutes()
105
     *
106
     */
107 3
    public function getRoutes()
108
    {
109 3
        return $this->routes;
110
    }
111
112
    /**
113
     *
114
     * Adds a pre-built route to the collection.
115
     *
116
     * @param Route $route The pre-built route.
117
     *
118
     * @return $this
119
     *
120
     * @throws Exception\RouteAlreadyExists when the route name is already
121
     * mapped.
122
     *
123
     */
124 21
    public function addRoute(Route $route)
125
    {
126 21
        $name = $route->name;
127
128 21
        if (! $name) {
129 1
            $this->routes[] = $route;
130 1
            return;
131
        }
132
133 20
        if (isset($this->routes[$name])) {
134 1
            throw new Exception\RouteAlreadyExists($name);
135
        }
136
137 20
        $this->routes[$name] = $route;
138 20
    }
139
140
    /**
141
     *
142
     * Gets a route by name.
143
     *
144
     * @param string $name The route name.
145
     *
146
     * @return Route
147
     *
148
     */
149 12
    public function getRoute($name)
150
    {
151 12
        if (! isset($this->routes[$name])) {
152 1
            throw new Exception\RouteNotFound($name);
153
        }
154
155 11
        return $this->routes[$name];
156
    }
157
158
    /**
159
     *
160
     * Adds a generic route.
161
     *
162
     * @param string $name The route name.
163
     *
164
     * @param string $path The route path.
165
     *
166
     * @param mixed $handler The route leads to this handler.
167
     *
168
     * @return Route The newly-added route object.
169
     *
170
     */
171 21
    public function route($name, $path, $handler = null)
172
    {
173 21
        $route = clone $this->protoRoute;
174 21
        $route->name($name);
175 21
        $route->path($path);
176 21
        $route->handler($handler);
177 21
        $this->addRoute($route);
178 21
        return $route;
179
    }
180
181
    /**
182
     *
183
     * Adds a GET route.
184
     *
185
     * @param string $name The route name.
186
     *
187
     * @param string $path The route path.
188
     *
189
     * @param mixed $handler The route leads to this handler.
190
     *
191
     * @return Route The newly-added route object.
192
     *
193
     */
194 1
    public function get($name, $path, $handler = null)
195
    {
196 1
        $route = $this->route($name, $path, $handler);
197 1
        $route->allows('GET');
198 1
        return $route;
199
    }
200
201
    /**
202
     *
203
     * Adds a DELETE route.
204
     *
205
     * @param string $name The route name.
206
     *
207
     * @param string $path The route path.
208
     *
209
     * @param mixed $handler The route leads to this handler.
210
     *
211
     * @return Route The newly-added route object.
212
     *
213
     */
214 2
    public function delete($name, $path, $handler = null)
215
    {
216 2
        $route = $this->route($name, $path, $handler);
217 2
        $route->allows('DELETE');
218 2
        return $route;
219
    }
220
221
    /**
222
     *
223
     * Adds a HEAD route.
224
     *
225
     * @param string $name The route name.
226
     *
227
     * @param string $path The route path.
228
     *
229
     * @param mixed $handler The route leads to this handler.
230
     *
231
     * @return Route The newly-added route object.
232
     *
233
     */
234 1
    public function head($name, $path, $handler = null)
235
    {
236 1
        $route = $this->route($name, $path, $handler);
237 1
        $route->allows('HEAD');
238 1
        return $route;
239
    }
240
241
    /**
242
     *
243
     * Adds an OPTIONS route.
244
     *
245
     * @param string $name The route name.
246
     *
247
     * @param string $path The route path.
248
     *
249
     * @param mixed $handler The route leads to this handler.
250
     *
251
     * @return Route The newly-added route object.
252
     *
253
     */
254 1
    public function options($name, $path, $handler = null)
255
    {
256 1
        $route = $this->route($name, $path, $handler);
257 1
        $route->allows('OPTIONS');
258 1
        return $route;
259
    }
260
261
    /**
262
     *
263
     * Adds a PATCH route.
264
     *
265
     * @param string $name The route name.
266
     *
267
     * @param string $path The route path.
268
     *
269
     * @param mixed $handler The route leads to this handler.
270
     *
271
     * @return Route The newly-added route object.
272
     *
273
     */
274 1
    public function patch($name, $path, $handler = null)
275
    {
276 1
        $route = $this->route($name, $path, $handler);
277 1
        $route->allows('PATCH');
278 1
        return $route;
279
    }
280
281
    /**
282
     *
283
     * Adds a POST route.
284
     *
285
     * @param string $name The route name.
286
     *
287
     * @param string $path The route path.
288
     *
289
     * @param mixed $handler The route leads to this handler.
290
     *
291
     * @return Route The newly-added route object.
292
     *
293
     */
294 3
    public function post($name, $path, $handler = null)
295
    {
296 3
        $route = $this->route($name, $path, $handler);
297 3
        $route->allows('POST');
298 3
        return $route;
299
    }
300
301
    /**
302
     *
303
     * Adds a PUT route.
304
     *
305
     * @param string $name The route name.
306
     *
307
     * @param string $path The route path.
308
     *
309
     * @param mixed $handler The route leads to this handler.
310
     *
311
     * @return Route The newly-added route object.
312
     *
313
     */
314 1
    public function put($name, $path, $handler = null)
315
    {
316 1
        $route = $this->route($name, $path, $handler);
317 1
        $route->allows('PUT');
318 1
        return $route;
319
    }
320
321
    /**
322
     *
323
     * Attaches routes to a specific path prefix, and prefixes the attached
324
     * route names.
325
     *
326
     * @param string $namePrefix The prefix for all route names being attached.
327
     *
328
     * @param string $pathPrefix The prefix for all route paths being attached.
329
     *
330
     * @param callable $callable A callable that uses the Map to add new
331
     * routes. Its signature is `function (\Aura\Router\Map $map)`; $this
332
     * Map instance will be passed to the callable.
333
     *
334
     * @return null
335
     *
336
     */
337 4
    public function attach($namePrefix, $pathPrefix, callable $callable)
338
    {
339
        // retain current prototype
340 4
        $old = $this->protoRoute;
341
342
        // clone a new prototype, update prefixes, and retain it
343 4
        $new = clone $old;
344 4
        $new->namePrefix($old->namePrefix . $namePrefix);
345 4
        $new->pathPrefix($old->pathPrefix . $pathPrefix);
346 4
        $this->protoRoute = $new;
347
348
        // run the callable and restore the old prototype
349 4
        $callable($this);
350 4
        $this->protoRoute = $old;
351 4
    }
352
}
353