Passed
Branch master (60a40e)
by Alex
03:08
created
src/Resource.php 1 patch
Indentation   +155 added lines, -155 removed lines patch added patch discarded remove patch
@@ -20,160 +20,160 @@
 block discarded – undo
20 20
 class Resource extends Group
21 21
 {
22 22
 
23
-    /**
24
-     * @inheritdoc
25
-     * @throws \BadMethodCallException
26
-     */
27
-
28
-    public function setMethod($method)
29
-    {
30
-        throw new \BadMethodCallException("Resources can't chance they http method.");
31
-    }
32
-
33
-    /**
34
-     * Remove the routes without the passed methods.
35
-     *
36
-     * @param string|string[] $methods
37
-     * @return self
38
-     */
39
-
40
-    public function only($methods)
41
-    {
42
-        $this->filterByMethod((array) $methods, false);
43
-        return $this;
44
-    }
45
-
46
-    /**
47
-     * Remove the routes with the passed methods.
48
-     *
49
-     * @param string|string[] $methods
50
-     * @return self
51
-     */
52
-
53
-    public function except($methods)
54
-    {
55
-        $this->filterByMethod((array) $methods, true);
56
-        return $this;
57
-    }
58
-
59
-    /**
60
-     * Forget the grouped routes filtering by http methods.
61
-     *
62
-     * @param string[] $methods
63
-     * @param bool $alt Should remove?
64
-     */
65
-
66
-    private function filterByMethod(array $methods, $alt)
67
-    {
68
-        $methods = array_flip(array_map('strtolower', $methods));
69
-
70
-        foreach ($this->routes as $route) {
71
-            if (isset($methods[$route->getAction()[1]]) === $alt) {
72
-                $route->forget();
73
-            }
74
-        }
75
-    }
76
-
77
-    /**
78
-     * Translate the "make" or "edit" from resources path.
79
-     *
80
-     * @param string[] $translations
81
-     * @return self
82
-     */
83
-
84
-    public function translate(array $translations)
85
-    {
86
-        foreach ($this->routes as $route) {
87
-            $action = $route->getAction()[1];
88
-
89
-            if ($action === "make" && isset($translations["make"])) {
90
-                $route->setPatternWithoutReset(str_replace("make", $translations["make"], $route->getPattern()));
91
-            } elseif ($action === "edit" && isset($translations["edit"])) {
92
-                $route->setPatternWithoutReset(str_replace("edit", $translations["edit"], $route->getPattern()));
93
-            }
94
-        }
95
-
96
-        return $this;
97
-    }
98
-
99
-    /**
100
-     * Add a route or a group of routes to the resource, it means that
101
-     * every added route will now receive the parameters of the resource, like id.
102
-     *
103
-     * @param Route|Group $route
104
-     * @return self
105
-     */
106
-
107
-    public function member($route)
108
-    {
109
-        $resource = new Resource;
110
-        $resource->set($route);
111
-        $this->nest($resource);
112
-    }
113
-
114
-    /**
115
-     * Nested routes capture the relation between a resource and another resource.
116
-     *
117
-     * @param Resource $resource
118
-     * @return self
119
-     */
120
-
121
-    public function nest(Resource $resource)
122
-    {
123
-        /** @var self $resource */
124
-        foreach ($this->routes as $route) {
125
-            if ($route->getAction()[1] === "show") {
126
-                $this->set($resource->forget()->setPrefix($this->getNestedPrefix($route->getPattern()))); break;
127
-            }
128
-        }
129
-
130
-        return $this;
131
-    }
132
-
133
-    /**
134
-     * Nest resources but with only build routes with the minimal amount of information
135
-     * to uniquely identify the resource.
136
-     *
137
-     * @param Resource $resource
138
-     * @return self
139
-     */
140
-
141
-    public function shallow(Resource $resource)
142
-    {
143
-        /** @var self $resource */
144
-        $newResource = new Resource;
145
-        $resource->forget();
146
-        $routes = $resource->all();
147
-
148
-        foreach ($routes as $route) {
149
-            if (strpos("index make create", $route->getAction()[1]) !== false) {
150
-                $newResource->set($route);
151
-            }
152
-        }
153
-
154
-        return $this->nest($newResource);
155
-    }
156
-
157
-    /**
158
-     * Resolve the nesting pattern, setting the prefixes based on
159
-     * parent resources patterns.
160
-     *
161
-     * @param string $pattern
162
-     * @return string
163
-     */
164
-
165
-    protected function getNestedPrefix($pattern)
166
-    {
167
-        $segments = explode("/", $pattern);
168
-        $pattern = "";
169
-
170
-        foreach ($segments as $index => $segment) {
171
-            if (strpos($segment, "{") === 0) {
172
-                   $pattern .= "/{" . $segments[$index - 1] . "_" . ltrim($segment, "{");
173
-            } else $pattern .= $segment;
174
-        }
175
-
176
-        return $pattern;
177
-    }
23
+	/**
24
+	 * @inheritdoc
25
+	 * @throws \BadMethodCallException
26
+	 */
27
+
28
+	public function setMethod($method)
29
+	{
30
+		throw new \BadMethodCallException("Resources can't chance they http method.");
31
+	}
32
+
33
+	/**
34
+	 * Remove the routes without the passed methods.
35
+	 *
36
+	 * @param string|string[] $methods
37
+	 * @return self
38
+	 */
39
+
40
+	public function only($methods)
41
+	{
42
+		$this->filterByMethod((array) $methods, false);
43
+		return $this;
44
+	}
45
+
46
+	/**
47
+	 * Remove the routes with the passed methods.
48
+	 *
49
+	 * @param string|string[] $methods
50
+	 * @return self
51
+	 */
52
+
53
+	public function except($methods)
54
+	{
55
+		$this->filterByMethod((array) $methods, true);
56
+		return $this;
57
+	}
58
+
59
+	/**
60
+	 * Forget the grouped routes filtering by http methods.
61
+	 *
62
+	 * @param string[] $methods
63
+	 * @param bool $alt Should remove?
64
+	 */
65
+
66
+	private function filterByMethod(array $methods, $alt)
67
+	{
68
+		$methods = array_flip(array_map('strtolower', $methods));
69
+
70
+		foreach ($this->routes as $route) {
71
+			if (isset($methods[$route->getAction()[1]]) === $alt) {
72
+				$route->forget();
73
+			}
74
+		}
75
+	}
76
+
77
+	/**
78
+	 * Translate the "make" or "edit" from resources path.
79
+	 *
80
+	 * @param string[] $translations
81
+	 * @return self
82
+	 */
83
+
84
+	public function translate(array $translations)
85
+	{
86
+		foreach ($this->routes as $route) {
87
+			$action = $route->getAction()[1];
88
+
89
+			if ($action === "make" && isset($translations["make"])) {
90
+				$route->setPatternWithoutReset(str_replace("make", $translations["make"], $route->getPattern()));
91
+			} elseif ($action === "edit" && isset($translations["edit"])) {
92
+				$route->setPatternWithoutReset(str_replace("edit", $translations["edit"], $route->getPattern()));
93
+			}
94
+		}
95
+
96
+		return $this;
97
+	}
98
+
99
+	/**
100
+	 * Add a route or a group of routes to the resource, it means that
101
+	 * every added route will now receive the parameters of the resource, like id.
102
+	 *
103
+	 * @param Route|Group $route
104
+	 * @return self
105
+	 */
106
+
107
+	public function member($route)
108
+	{
109
+		$resource = new Resource;
110
+		$resource->set($route);
111
+		$this->nest($resource);
112
+	}
113
+
114
+	/**
115
+	 * Nested routes capture the relation between a resource and another resource.
116
+	 *
117
+	 * @param Resource $resource
118
+	 * @return self
119
+	 */
120
+
121
+	public function nest(Resource $resource)
122
+	{
123
+		/** @var self $resource */
124
+		foreach ($this->routes as $route) {
125
+			if ($route->getAction()[1] === "show") {
126
+				$this->set($resource->forget()->setPrefix($this->getNestedPrefix($route->getPattern()))); break;
127
+			}
128
+		}
129
+
130
+		return $this;
131
+	}
132
+
133
+	/**
134
+	 * Nest resources but with only build routes with the minimal amount of information
135
+	 * to uniquely identify the resource.
136
+	 *
137
+	 * @param Resource $resource
138
+	 * @return self
139
+	 */
140
+
141
+	public function shallow(Resource $resource)
142
+	{
143
+		/** @var self $resource */
144
+		$newResource = new Resource;
145
+		$resource->forget();
146
+		$routes = $resource->all();
147
+
148
+		foreach ($routes as $route) {
149
+			if (strpos("index make create", $route->getAction()[1]) !== false) {
150
+				$newResource->set($route);
151
+			}
152
+		}
153
+
154
+		return $this->nest($newResource);
155
+	}
156
+
157
+	/**
158
+	 * Resolve the nesting pattern, setting the prefixes based on
159
+	 * parent resources patterns.
160
+	 *
161
+	 * @param string $pattern
162
+	 * @return string
163
+	 */
164
+
165
+	protected function getNestedPrefix($pattern)
166
+	{
167
+		$segments = explode("/", $pattern);
168
+		$pattern = "";
169
+
170
+		foreach ($segments as $index => $segment) {
171
+			if (strpos($segment, "{") === 0) {
172
+				   $pattern .= "/{" . $segments[$index - 1] . "_" . ltrim($segment, "{");
173
+			} else $pattern .= $segment;
174
+		}
175
+
176
+		return $pattern;
177
+	}
178 178
 
179 179
 }
Please login to merge, or discard this patch.
src/Route.php 2 patches
Indentation   +615 added lines, -615 removed lines patch added patch discarded remove patch
@@ -23,628 +23,628 @@
 block discarded – undo
23 23
 class Route
24 24
 {
25 25
 
26
-    /**
27
-     * @var Collector
28
-     */
26
+	/**
27
+	 * @var Collector
28
+	 */
29 29
 
30
-    protected $collector;
30
+	protected $collector;
31 31
     
32
-    /**
33
-     * @var string
34
-     */
32
+	/**
33
+	 * @var string
34
+	 */
35 35
 
36
-    protected $method;
36
+	protected $method;
37 37
     
38
-    /**
39
-     * @var string
40
-     */
38
+	/**
39
+	 * @var string
40
+	 */
41 41
 
42
-    protected $pattern;
42
+	protected $pattern;
43 43
     
44
-    /**
45
-     * @var callable
46
-     */
44
+	/**
45
+	 * @var callable
46
+	 */
47 47
 
48
-    protected $action;
48
+	protected $action;
49 49
     
50
-    /**
51
-     * @var string
52
-     */
53
-
54
-    protected $namespace = "";
55
-
56
-    /**
57
-     * @var string[]
58
-     */
59
-
60
-    protected $params = [];
61
-
62
-    /**
63
-     * Defaults are parameters set by the user, and don't
64
-     * appear on the pattern.
65
-     *
66
-     * @var array
67
-     */
68
-
69
-    protected $defaults = [];
70
-
71
-    /**
72
-     * Metadata can be set to be used on filters, dispatch strategies
73
-     * or anywhere the route object is used.
74
-     *
75
-     * @var array
76
-     */
77
-
78
-    protected $metadata = [];
79
-
80
-    /**
81
-     * @var string|StrategyInterface
82
-     */
83
-
84
-    protected $strategy;
85
-
86
-    /**
87
-     * Blocked routes are dynamic routes selected to pass by the matcher.
88
-     *
89
-     * @var boolean
90
-     */
91
-
92
-    protected $blocked = false;
93
-
94
-    /**
95
-     * The matcher that dispatched this route.
96
-     *
97
-     * @var Matcher $matcher
98
-     */
99
-
100
-    protected $matcher;
101
-
102
-    /**
103
-     * The function used to create controllers from name.
104
-     *
105
-     * @var callable
106
-     */
107
-
108
-    protected $controllerCreationFunction;
109
-
110
-    /**
111
-     * @param Collector $collector
112
-     * @param string $method
113
-     * @param string $pattern
114
-     * @param callable $action
115
-     */
116
-
117
-    public function __construct(Collector $collector, $method, $pattern, $action)
118
-    {
119
-        $this->collector = $collector;
120
-        $this->method    = $method;
121
-        $this->pattern   = $pattern;
122
-        $this->action    = $action;
123
-    }
124
-
125
-    /**
126
-     * Clone this route and set it into the collector.
127
-     *
128
-     * @return Route
129
-     */
130
-
131
-    public function reset()
132
-    {
133
-        return $this->collector->set($this->method, $this->pattern, $this->action)->nth(0)
134
-                               ->setStrategy($this->strategy)->setParams($this->params)
135
-                               ->setDefaults($this->defaults)->setMetadataArray($this->metadata);
136
-    }
137
-
138
-    /**
139
-     * Remove this route from the collector.
140
-     *
141
-     * @return self
142
-     */
143
-
144
-    public function forget()
145
-    {
146
-        $this->collector->forget($this->method, $this->pattern);
147
-        return $this;
148
-    }
149
-
150
-    /**
151
-     * Execute the route action, if no strategy was provided the action
152
-     * will be executed by the call_user_func PHP function.
153
-     *
154
-     * @throws BadRouteException
155
-     * @return mixed
156
-     */
157
-
158
-    public function call()
159
-    {
160
-        $this->action = $this->parseCallable($this->action);
161
-
162
-        if ($this->strategy === null) {
163
-            return call_user_func_array($this->action, array_merge($this->defaults, $this->params));
164
-        }
165
-
166
-        if (!is_object($this->strategy)) {
167
-            $this->strategy = new $this->strategy;
168
-        }
169
-
170
-        return $this->callWithStrategy();
171
-    }
172
-
173
-    /**
174
-     * Seek for dynamic content in one callable. This allow to use parameters defined on pattern on callable
175
-     * definition, eg. "get" "/{resource:string+}/{slug:slug+}" "{resource}::find".
176
-     *
177
-     * This will snakecase the resource parameter and deal with as a controller, then call the find method.
178
-     * A request for "/articles/my-first-article" will execute find method of Articles controller with only
179
-     * "my-first-article" as parameter.
180
-     *
181
-     * @param callable $callable
182
-     * @return callable
183
-     */
184
-
185
-    private function parseCallable($callable)
186
-    {
187
-        if (is_string($callable) && strpos($callable, "::")) {
188
-            $callable = explode("::", $callable);
189
-        }
190
-
191
-        if (is_array($callable)) {
192
-            if (is_string($callable[0])) {
193
-                   $callable[0] = $this->parseCallableController($callable[0]);
194
-            }
195
-
196
-            $callable[1] = $this->parseCallablePlaceholders($callable[1]);
197
-        }
198
-
199
-        return $callable;
200
-    }
201
-
202
-    /**
203
-     * Get the controller object.
204
-     *
205
-     * @param string $controller
206
-     * @return Object
207
-     */
208
-
209
-    private function parseCallableController($controller)
210
-    {
211
-        $controller  = rtrim($this->namespace, "\\") . "\\" . $this->parseCallablePlaceholders($controller);
212
-
213
-        if ($this->controllerCreationFunction === null) {
214
-               return new $controller;
215
-        } else return call_user_func($this->controllerCreationFunction, $controller);
216
-    }
217
-
218
-    /**
219
-     * Parse and replace dynamic content on route action.
220
-     *
221
-     * @param string $fragment Part of callable
222
-     * @return string
223
-     */
224
-
225
-    private function parseCallablePlaceholders($fragment)
226
-    {
227
-        if (strpos($fragment, "{") !== false) {
228
-            foreach ($this->params as $placeholder => $value) {
229
-                if (strpos($fragment, "{" . $placeholder . "}") !== false) {
230
-                    $fragment = str_replace("{" . $placeholder . "}", ucwords(str_replace("-", " ", $value)), $fragment);
231
-                }
232
-            }
233
-        }
234
-
235
-        return $fragment;
236
-    }
237
-
238
-    /**
239
-     * Execute the route action with the given strategy.
240
-     *
241
-     * @throws BadRouteException
242
-     * @return mixed
243
-     */
244
-
245
-    private function callWithStrategy()
246
-    {
247
-        if ($this->strategy instanceof StrategyInterface) {
248
-            if ($this->strategy instanceof MatcherAwareInterface) {
249
-                $this->strategy->setMatcher($this->matcher);
250
-            }
251
-
252
-            return $this->strategy->call($this);
253
-        }
254
-
255
-        throw new BadRouteException(str_replace("%s", get_class($this->strategy), BadRouteException::BAD_STRATEGY));
256
-    }
257
-
258
-    /**
259
-     * @return Collector
260
-     */
261
-
262
-    public function getCollector()
263
-    {
264
-        return $this->collector;
265
-    }
266
-
267
-    /**
268
-     * @return string
269
-     */
270
-
271
-    public function getMethod()
272
-    {
273
-        return $this->method;
274
-    }
275
-
276
-    /**
277
-     * @return string
278
-     */
279
-
280
-    public function getPattern()
281
-    {
282
-        return $this->pattern;
283
-    }
284
-
285
-    /**
286
-     * @return string[]
287
-     */
288
-
289
-    public function getSegments()
290
-    {
291
-        return explode("/", $this->pattern);
292
-    }
293
-
294
-    /**
295
-     * @return callable
296
-     */
297
-
298
-    public function getAction()
299
-    {
300
-        return $this->action;
301
-    }
302
-
303
-    /**
304
-     * @return string
305
-     */
306
-
307
-    public function getNamespace()
308
-    {
309
-        return $this->namespace;
310
-    }
311
-
312
-    /**
313
-     * @return string[]
314
-     */
315
-
316
-    public function getParams()
317
-    {
318
-        return $this->params;
319
-    }
320
-
321
-    /**
322
-     * @param string $key
323
-     * @return string
324
-     */
325
-
326
-    public function getParam($key)
327
-    {
328
-        return $this->params[$key];
329
-    }
330
-
331
-    /**
332
-     * Return defaults and params merged in one array.
333
-     *
334
-     * @return array
335
-     */
336
-
337
-    public function getMergedParams()
338
-    {
339
-        return array_merge($this->defaults, $this->params);
340
-    }
341
-
342
-    /**
343
-     * @return array
344
-     */
345
-
346
-    public function getDefaults()
347
-    {
348
-        return $this->defaults;
349
-    }
350
-
351
-    /**
352
-     * @param string $key
353
-     * @return mixed
354
-     */
355
-
356
-    public function getDefault($key)
357
-    {
358
-        return $this->defaults[$key];
359
-    }
360
-
361
-    /**
362
-     * @return array
363
-     */
364
-
365
-    public function getMetadataArray()
366
-    {
367
-        return $this->metadata;
368
-    }
369
-
370
-    /**
371
-     * @param string $key
372
-     * @return mixed
373
-     */
374
-
375
-    public function getMetadata($key)
376
-    {
377
-        return $this->metadata[$key];
378
-    }
379
-
380
-    /**
381
-     * @return string|null
382
-     */
383
-
384
-    public function getStrategy()
385
-    {
386
-        if ($this->strategy instanceof StrategyInterface) {
387
-            return get_class($this->strategy);
388
-        }
389
-
390
-        return $this->strategy;
391
-    }
392
-
393
-    /**
394
-     * @return Matcher
395
-     */
396
-
397
-    public function getMatcher()
398
-    {
399
-        return $this->matcher;
400
-    }
401
-
402
-    /**
403
-     * Verify if a Route have already been blocked.
404
-     *
405
-     * @return boolean
406
-     */
407
-
408
-    public function getBlock()
409
-    {
410
-        return $this->blocked;
411
-    }
412
-
413
-    /**
414
-     * Blocking a route indicate that that route have been selected and
415
-     * parsed, now it will be given to the matcher.
416
-     *
417
-     * @param bool $blocked
418
-     * @return self
419
-     */
420
-
421
-    public function setBlock($blocked)
422
-    {
423
-        $this->blocked = $blocked;
424
-        return $this;
425
-    }
426
-
427
-    /**
428
-     * @param string $method
429
-     * @return Route
430
-     */
431
-
432
-    public function setMethod($method)
433
-    {
434
-        $this->forget();
435
-        $this->method = $method;
436
-        return $this->reset();
437
-    }
438
-
439
-    /**
440
-     * @param string $pattern
441
-     * @return Route
442
-     */
443
-
444
-    public function setPattern($pattern)
445
-    {
446
-        $this->forget();
447
-        $this->pattern = $pattern;
448
-        return $this->reset();
449
-    }
450
-
451
-    /**
452
-     * @param string $pattern
453
-     * @return self
454
-     */
455
-
456
-    public function setPatternWithoutReset($pattern)
457
-    {
458
-        $this->pattern = $pattern;
459
-        return $this;
460
-    }
461
-
462
-    /**
463
-     * @param string $action
464
-     * @return self
465
-     */
466
-
467
-    public function setAction($action)
468
-    {
469
-        $this->action = $action;
470
-        return $this;
471
-    }
472
-
473
-    /**
474
-     * @param string $namespace
475
-     * @return self
476
-     */
477
-
478
-    public function setNamespace($namespace)
479
-    {
480
-        $this->namespace = $namespace;
481
-        return $this;
482
-    }
483
-
484
-    /**
485
-     * @param string[] $params
486
-     * @return self
487
-     */
488
-
489
-    public function setParams(array $params)
490
-    {
491
-        $this->params = $params;
492
-        return $this;
493
-    }
494
-
495
-    /**
496
-     * @param string $key
497
-     * @param string $value
498
-     *
499
-     * @return self
500
-     */
501
-
502
-    public function setParam($key, $value)
503
-    {
504
-        $this->params[$key] = $value;
505
-        return $this;
506
-    }
507
-
508
-    /**
509
-     * @param mixed[] $defaults
510
-     * @return self
511
-     */
512
-
513
-    public function setDefaults(array $defaults)
514
-    {
515
-        $this->defaults = $defaults;
516
-        return $this;
517
-    }
518
-
519
-    /**
520
-     * @param string $key
521
-     * @param mixed $value
522
-     *
523
-     * @return self
524
-     */
525
-
526
-    public function setDefault($key, $value)
527
-    {
528
-        $this->defaults[$key] = $value;
529
-        return $this;
530
-    }
531
-
532
-    /**
533
-     * @param mixed[] $metadata
534
-     * @return self
535
-     */
536
-
537
-    public function setMetadataArray(array $metadata)
538
-    {
539
-        $this->metadata = $metadata;
540
-        return $this;
541
-    }
542
-
543
-    /**
544
-     * @param string $key
545
-     * @param mixed $value
546
-     *
547
-     * @return $this
548
-     */
549
-
550
-    public function setMetadata($key, $value)
551
-    {
552
-        $this->metadata[$key] = $value;
553
-        return $this;
554
-    }
555
-
556
-    /**
557
-     * @param null|string|StrategyInterface $strategy
558
-     * @return self
559
-     */
560
-
561
-    public function setStrategy($strategy)
562
-    {
563
-        $this->strategy = $strategy;
564
-        return $this;
565
-    }
566
-
567
-    /**
568
-     * @param Matcher $matcher
569
-     * @return self
570
-     */
571
-
572
-    public function setMatcher(Matcher $matcher)
573
-    {
574
-        $this->matcher = $matcher;
575
-        return $this;
576
-    }
577
-
578
-    /**
579
-     * Set a constraint to a token in the route pattern.
580
-     *
581
-     * @param string $token
582
-     * @param string $regex
583
-     *
584
-     * @return self
585
-     */
586
-
587
-    public function setConstraint($token, $regex)
588
-    {
589
-        $initPos = strpos($this->pattern, "{" . $token);
590
-
591
-        if ($initPos !== false) {
592
-            $endPos = strpos($this->pattern, "}", $initPos);
593
-            $newPattern = substr_replace($this->pattern, "{" . "$token:$regex" . "}", $initPos, $endPos - $initPos + 1);
594
-            $wildcards = $this->collector->getWildcardTokens();
595
-            $newPattern = str_replace(array_keys($wildcards), $wildcards, $newPattern);
596
-            $this->setPatternWithoutReset($newPattern);
597
-        }
598
-
599
-        return $this;
600
-    }
601
-
602
-    /**
603
-     * Set a function to create controllers.
604
-     *
605
-     * @param callable $callable
606
-     * @throws BadRouteException
607
-     * @return self
608
-     */
609
-
610
-    public function setControllerCreationFunction($callable)
611
-    {
612
-        if (!is_callable($callable)) {
613
-            throw new BadRouteException(BadRouteException::WRONG_CONTROLLER_CREATION_FUNC);
614
-        }
615
-
616
-        $this->controllerCreationFunction = $this->parseCallable($callable);
617
-        return $this;
618
-    }
619
-
620
-    /**
621
-     * @param string $key
622
-     * @return bool
623
-     */
624
-
625
-    public function hasParam($key)
626
-    {
627
-        return isset($this->params[$key]);
628
-    }
629
-
630
-    /**
631
-     * @param string $key
632
-     * @return bool
633
-     */
634
-
635
-    public function hasDefault($key)
636
-    {
637
-        return isset($this->defaults[$key]);
638
-    }
639
-
640
-    /**
641
-     * @param string $key
642
-     * @return bool
643
-     */
644
-
645
-    public function hasMetadata($key)
646
-    {
647
-        return isset($this->metadata[$key]);
648
-    }
50
+	/**
51
+	 * @var string
52
+	 */
53
+
54
+	protected $namespace = "";
55
+
56
+	/**
57
+	 * @var string[]
58
+	 */
59
+
60
+	protected $params = [];
61
+
62
+	/**
63
+	 * Defaults are parameters set by the user, and don't
64
+	 * appear on the pattern.
65
+	 *
66
+	 * @var array
67
+	 */
68
+
69
+	protected $defaults = [];
70
+
71
+	/**
72
+	 * Metadata can be set to be used on filters, dispatch strategies
73
+	 * or anywhere the route object is used.
74
+	 *
75
+	 * @var array
76
+	 */
77
+
78
+	protected $metadata = [];
79
+
80
+	/**
81
+	 * @var string|StrategyInterface
82
+	 */
83
+
84
+	protected $strategy;
85
+
86
+	/**
87
+	 * Blocked routes are dynamic routes selected to pass by the matcher.
88
+	 *
89
+	 * @var boolean
90
+	 */
91
+
92
+	protected $blocked = false;
93
+
94
+	/**
95
+	 * The matcher that dispatched this route.
96
+	 *
97
+	 * @var Matcher $matcher
98
+	 */
99
+
100
+	protected $matcher;
101
+
102
+	/**
103
+	 * The function used to create controllers from name.
104
+	 *
105
+	 * @var callable
106
+	 */
107
+
108
+	protected $controllerCreationFunction;
109
+
110
+	/**
111
+	 * @param Collector $collector
112
+	 * @param string $method
113
+	 * @param string $pattern
114
+	 * @param callable $action
115
+	 */
116
+
117
+	public function __construct(Collector $collector, $method, $pattern, $action)
118
+	{
119
+		$this->collector = $collector;
120
+		$this->method    = $method;
121
+		$this->pattern   = $pattern;
122
+		$this->action    = $action;
123
+	}
124
+
125
+	/**
126
+	 * Clone this route and set it into the collector.
127
+	 *
128
+	 * @return Route
129
+	 */
130
+
131
+	public function reset()
132
+	{
133
+		return $this->collector->set($this->method, $this->pattern, $this->action)->nth(0)
134
+							   ->setStrategy($this->strategy)->setParams($this->params)
135
+							   ->setDefaults($this->defaults)->setMetadataArray($this->metadata);
136
+	}
137
+
138
+	/**
139
+	 * Remove this route from the collector.
140
+	 *
141
+	 * @return self
142
+	 */
143
+
144
+	public function forget()
145
+	{
146
+		$this->collector->forget($this->method, $this->pattern);
147
+		return $this;
148
+	}
149
+
150
+	/**
151
+	 * Execute the route action, if no strategy was provided the action
152
+	 * will be executed by the call_user_func PHP function.
153
+	 *
154
+	 * @throws BadRouteException
155
+	 * @return mixed
156
+	 */
157
+
158
+	public function call()
159
+	{
160
+		$this->action = $this->parseCallable($this->action);
161
+
162
+		if ($this->strategy === null) {
163
+			return call_user_func_array($this->action, array_merge($this->defaults, $this->params));
164
+		}
165
+
166
+		if (!is_object($this->strategy)) {
167
+			$this->strategy = new $this->strategy;
168
+		}
169
+
170
+		return $this->callWithStrategy();
171
+	}
172
+
173
+	/**
174
+	 * Seek for dynamic content in one callable. This allow to use parameters defined on pattern on callable
175
+	 * definition, eg. "get" "/{resource:string+}/{slug:slug+}" "{resource}::find".
176
+	 *
177
+	 * This will snakecase the resource parameter and deal with as a controller, then call the find method.
178
+	 * A request for "/articles/my-first-article" will execute find method of Articles controller with only
179
+	 * "my-first-article" as parameter.
180
+	 *
181
+	 * @param callable $callable
182
+	 * @return callable
183
+	 */
184
+
185
+	private function parseCallable($callable)
186
+	{
187
+		if (is_string($callable) && strpos($callable, "::")) {
188
+			$callable = explode("::", $callable);
189
+		}
190
+
191
+		if (is_array($callable)) {
192
+			if (is_string($callable[0])) {
193
+				   $callable[0] = $this->parseCallableController($callable[0]);
194
+			}
195
+
196
+			$callable[1] = $this->parseCallablePlaceholders($callable[1]);
197
+		}
198
+
199
+		return $callable;
200
+	}
201
+
202
+	/**
203
+	 * Get the controller object.
204
+	 *
205
+	 * @param string $controller
206
+	 * @return Object
207
+	 */
208
+
209
+	private function parseCallableController($controller)
210
+	{
211
+		$controller  = rtrim($this->namespace, "\\") . "\\" . $this->parseCallablePlaceholders($controller);
212
+
213
+		if ($this->controllerCreationFunction === null) {
214
+			   return new $controller;
215
+		} else return call_user_func($this->controllerCreationFunction, $controller);
216
+	}
217
+
218
+	/**
219
+	 * Parse and replace dynamic content on route action.
220
+	 *
221
+	 * @param string $fragment Part of callable
222
+	 * @return string
223
+	 */
224
+
225
+	private function parseCallablePlaceholders($fragment)
226
+	{
227
+		if (strpos($fragment, "{") !== false) {
228
+			foreach ($this->params as $placeholder => $value) {
229
+				if (strpos($fragment, "{" . $placeholder . "}") !== false) {
230
+					$fragment = str_replace("{" . $placeholder . "}", ucwords(str_replace("-", " ", $value)), $fragment);
231
+				}
232
+			}
233
+		}
234
+
235
+		return $fragment;
236
+	}
237
+
238
+	/**
239
+	 * Execute the route action with the given strategy.
240
+	 *
241
+	 * @throws BadRouteException
242
+	 * @return mixed
243
+	 */
244
+
245
+	private function callWithStrategy()
246
+	{
247
+		if ($this->strategy instanceof StrategyInterface) {
248
+			if ($this->strategy instanceof MatcherAwareInterface) {
249
+				$this->strategy->setMatcher($this->matcher);
250
+			}
251
+
252
+			return $this->strategy->call($this);
253
+		}
254
+
255
+		throw new BadRouteException(str_replace("%s", get_class($this->strategy), BadRouteException::BAD_STRATEGY));
256
+	}
257
+
258
+	/**
259
+	 * @return Collector
260
+	 */
261
+
262
+	public function getCollector()
263
+	{
264
+		return $this->collector;
265
+	}
266
+
267
+	/**
268
+	 * @return string
269
+	 */
270
+
271
+	public function getMethod()
272
+	{
273
+		return $this->method;
274
+	}
275
+
276
+	/**
277
+	 * @return string
278
+	 */
279
+
280
+	public function getPattern()
281
+	{
282
+		return $this->pattern;
283
+	}
284
+
285
+	/**
286
+	 * @return string[]
287
+	 */
288
+
289
+	public function getSegments()
290
+	{
291
+		return explode("/", $this->pattern);
292
+	}
293
+
294
+	/**
295
+	 * @return callable
296
+	 */
297
+
298
+	public function getAction()
299
+	{
300
+		return $this->action;
301
+	}
302
+
303
+	/**
304
+	 * @return string
305
+	 */
306
+
307
+	public function getNamespace()
308
+	{
309
+		return $this->namespace;
310
+	}
311
+
312
+	/**
313
+	 * @return string[]
314
+	 */
315
+
316
+	public function getParams()
317
+	{
318
+		return $this->params;
319
+	}
320
+
321
+	/**
322
+	 * @param string $key
323
+	 * @return string
324
+	 */
325
+
326
+	public function getParam($key)
327
+	{
328
+		return $this->params[$key];
329
+	}
330
+
331
+	/**
332
+	 * Return defaults and params merged in one array.
333
+	 *
334
+	 * @return array
335
+	 */
336
+
337
+	public function getMergedParams()
338
+	{
339
+		return array_merge($this->defaults, $this->params);
340
+	}
341
+
342
+	/**
343
+	 * @return array
344
+	 */
345
+
346
+	public function getDefaults()
347
+	{
348
+		return $this->defaults;
349
+	}
350
+
351
+	/**
352
+	 * @param string $key
353
+	 * @return mixed
354
+	 */
355
+
356
+	public function getDefault($key)
357
+	{
358
+		return $this->defaults[$key];
359
+	}
360
+
361
+	/**
362
+	 * @return array
363
+	 */
364
+
365
+	public function getMetadataArray()
366
+	{
367
+		return $this->metadata;
368
+	}
369
+
370
+	/**
371
+	 * @param string $key
372
+	 * @return mixed
373
+	 */
374
+
375
+	public function getMetadata($key)
376
+	{
377
+		return $this->metadata[$key];
378
+	}
379
+
380
+	/**
381
+	 * @return string|null
382
+	 */
383
+
384
+	public function getStrategy()
385
+	{
386
+		if ($this->strategy instanceof StrategyInterface) {
387
+			return get_class($this->strategy);
388
+		}
389
+
390
+		return $this->strategy;
391
+	}
392
+
393
+	/**
394
+	 * @return Matcher
395
+	 */
396
+
397
+	public function getMatcher()
398
+	{
399
+		return $this->matcher;
400
+	}
401
+
402
+	/**
403
+	 * Verify if a Route have already been blocked.
404
+	 *
405
+	 * @return boolean
406
+	 */
407
+
408
+	public function getBlock()
409
+	{
410
+		return $this->blocked;
411
+	}
412
+
413
+	/**
414
+	 * Blocking a route indicate that that route have been selected and
415
+	 * parsed, now it will be given to the matcher.
416
+	 *
417
+	 * @param bool $blocked
418
+	 * @return self
419
+	 */
420
+
421
+	public function setBlock($blocked)
422
+	{
423
+		$this->blocked = $blocked;
424
+		return $this;
425
+	}
426
+
427
+	/**
428
+	 * @param string $method
429
+	 * @return Route
430
+	 */
431
+
432
+	public function setMethod($method)
433
+	{
434
+		$this->forget();
435
+		$this->method = $method;
436
+		return $this->reset();
437
+	}
438
+
439
+	/**
440
+	 * @param string $pattern
441
+	 * @return Route
442
+	 */
443
+
444
+	public function setPattern($pattern)
445
+	{
446
+		$this->forget();
447
+		$this->pattern = $pattern;
448
+		return $this->reset();
449
+	}
450
+
451
+	/**
452
+	 * @param string $pattern
453
+	 * @return self
454
+	 */
455
+
456
+	public function setPatternWithoutReset($pattern)
457
+	{
458
+		$this->pattern = $pattern;
459
+		return $this;
460
+	}
461
+
462
+	/**
463
+	 * @param string $action
464
+	 * @return self
465
+	 */
466
+
467
+	public function setAction($action)
468
+	{
469
+		$this->action = $action;
470
+		return $this;
471
+	}
472
+
473
+	/**
474
+	 * @param string $namespace
475
+	 * @return self
476
+	 */
477
+
478
+	public function setNamespace($namespace)
479
+	{
480
+		$this->namespace = $namespace;
481
+		return $this;
482
+	}
483
+
484
+	/**
485
+	 * @param string[] $params
486
+	 * @return self
487
+	 */
488
+
489
+	public function setParams(array $params)
490
+	{
491
+		$this->params = $params;
492
+		return $this;
493
+	}
494
+
495
+	/**
496
+	 * @param string $key
497
+	 * @param string $value
498
+	 *
499
+	 * @return self
500
+	 */
501
+
502
+	public function setParam($key, $value)
503
+	{
504
+		$this->params[$key] = $value;
505
+		return $this;
506
+	}
507
+
508
+	/**
509
+	 * @param mixed[] $defaults
510
+	 * @return self
511
+	 */
512
+
513
+	public function setDefaults(array $defaults)
514
+	{
515
+		$this->defaults = $defaults;
516
+		return $this;
517
+	}
518
+
519
+	/**
520
+	 * @param string $key
521
+	 * @param mixed $value
522
+	 *
523
+	 * @return self
524
+	 */
525
+
526
+	public function setDefault($key, $value)
527
+	{
528
+		$this->defaults[$key] = $value;
529
+		return $this;
530
+	}
531
+
532
+	/**
533
+	 * @param mixed[] $metadata
534
+	 * @return self
535
+	 */
536
+
537
+	public function setMetadataArray(array $metadata)
538
+	{
539
+		$this->metadata = $metadata;
540
+		return $this;
541
+	}
542
+
543
+	/**
544
+	 * @param string $key
545
+	 * @param mixed $value
546
+	 *
547
+	 * @return $this
548
+	 */
549
+
550
+	public function setMetadata($key, $value)
551
+	{
552
+		$this->metadata[$key] = $value;
553
+		return $this;
554
+	}
555
+
556
+	/**
557
+	 * @param null|string|StrategyInterface $strategy
558
+	 * @return self
559
+	 */
560
+
561
+	public function setStrategy($strategy)
562
+	{
563
+		$this->strategy = $strategy;
564
+		return $this;
565
+	}
566
+
567
+	/**
568
+	 * @param Matcher $matcher
569
+	 * @return self
570
+	 */
571
+
572
+	public function setMatcher(Matcher $matcher)
573
+	{
574
+		$this->matcher = $matcher;
575
+		return $this;
576
+	}
577
+
578
+	/**
579
+	 * Set a constraint to a token in the route pattern.
580
+	 *
581
+	 * @param string $token
582
+	 * @param string $regex
583
+	 *
584
+	 * @return self
585
+	 */
586
+
587
+	public function setConstraint($token, $regex)
588
+	{
589
+		$initPos = strpos($this->pattern, "{" . $token);
590
+
591
+		if ($initPos !== false) {
592
+			$endPos = strpos($this->pattern, "}", $initPos);
593
+			$newPattern = substr_replace($this->pattern, "{" . "$token:$regex" . "}", $initPos, $endPos - $initPos + 1);
594
+			$wildcards = $this->collector->getWildcardTokens();
595
+			$newPattern = str_replace(array_keys($wildcards), $wildcards, $newPattern);
596
+			$this->setPatternWithoutReset($newPattern);
597
+		}
598
+
599
+		return $this;
600
+	}
601
+
602
+	/**
603
+	 * Set a function to create controllers.
604
+	 *
605
+	 * @param callable $callable
606
+	 * @throws BadRouteException
607
+	 * @return self
608
+	 */
609
+
610
+	public function setControllerCreationFunction($callable)
611
+	{
612
+		if (!is_callable($callable)) {
613
+			throw new BadRouteException(BadRouteException::WRONG_CONTROLLER_CREATION_FUNC);
614
+		}
615
+
616
+		$this->controllerCreationFunction = $this->parseCallable($callable);
617
+		return $this;
618
+	}
619
+
620
+	/**
621
+	 * @param string $key
622
+	 * @return bool
623
+	 */
624
+
625
+	public function hasParam($key)
626
+	{
627
+		return isset($this->params[$key]);
628
+	}
629
+
630
+	/**
631
+	 * @param string $key
632
+	 * @return bool
633
+	 */
634
+
635
+	public function hasDefault($key)
636
+	{
637
+		return isset($this->defaults[$key]);
638
+	}
639
+
640
+	/**
641
+	 * @param string $key
642
+	 * @return bool
643
+	 */
644
+
645
+	public function hasMetadata($key)
646
+	{
647
+		return isset($this->metadata[$key]);
648
+	}
649 649
 
650 650
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -208,7 +208,7 @@
 block discarded – undo
208 208
 
209 209
     private function parseCallableController($controller)
210 210
     {
211
-        $controller  = rtrim($this->namespace, "\\") . "\\" . $this->parseCallablePlaceholders($controller);
211
+        $controller = rtrim($this->namespace, "\\") . "\\" . $this->parseCallablePlaceholders($controller);
212 212
 
213 213
         if ($this->controllerCreationFunction === null) {
214 214
                return new $controller;
Please login to merge, or discard this patch.
src/Strategies/RequestAwareTrait.php 1 patch
Indentation   +64 added lines, -64 removed lines patch added patch discarded remove patch
@@ -22,69 +22,69 @@
 block discarded – undo
22 22
 trait RequestAwareTrait
23 23
 {
24 24
 
25
-    /**
26
-     * @var RequestInterface
27
-     */
28
-
29
-    protected $request;
30
-
31
-    /**
32
-     * @var ResponseInterface
33
-     */
34
-
35
-    protected $response;
36
-
37
-    /**
38
-     * RequestResponseStrategy constructor.
39
-     *
40
-     * @param RequestInterface $request
41
-     * @param ResponseInterface $response
42
-     */
43
-
44
-    public function __construct(RequestInterface $request, ResponseInterface $response)
45
-    {
46
-        $this->request = $request;
47
-        $this->response = $response;
48
-    }
49
-
50
-    /**
51
-     * @return RequestInterface
52
-     */
53
-
54
-    public function getRequest()
55
-    {
56
-        return $this->request;
57
-    }
58
-
59
-    /**
60
-     * @param RequestInterface $request
61
-     * @return self
62
-     */
63
-
64
-    public function setRequest(RequestInterface $request)
65
-    {
66
-        $this->request = $request;
67
-        return $this;
68
-    }
69
-
70
-    /**
71
-     * @return ResponseInterface
72
-     */
73
-
74
-    public function getResponse()
75
-    {
76
-        return $this->response;
77
-    }
78
-
79
-    /**
80
-     * @param ResponseInterface $response
81
-     * @return self
82
-     */
83
-
84
-    public function setResponse(ResponseInterface $response)
85
-    {
86
-        $this->response = $response;
87
-        return $this;
88
-    }
25
+	/**
26
+	 * @var RequestInterface
27
+	 */
28
+
29
+	protected $request;
30
+
31
+	/**
32
+	 * @var ResponseInterface
33
+	 */
34
+
35
+	protected $response;
36
+
37
+	/**
38
+	 * RequestResponseStrategy constructor.
39
+	 *
40
+	 * @param RequestInterface $request
41
+	 * @param ResponseInterface $response
42
+	 */
43
+
44
+	public function __construct(RequestInterface $request, ResponseInterface $response)
45
+	{
46
+		$this->request = $request;
47
+		$this->response = $response;
48
+	}
49
+
50
+	/**
51
+	 * @return RequestInterface
52
+	 */
53
+
54
+	public function getRequest()
55
+	{
56
+		return $this->request;
57
+	}
58
+
59
+	/**
60
+	 * @param RequestInterface $request
61
+	 * @return self
62
+	 */
63
+
64
+	public function setRequest(RequestInterface $request)
65
+	{
66
+		$this->request = $request;
67
+		return $this;
68
+	}
69
+
70
+	/**
71
+	 * @return ResponseInterface
72
+	 */
73
+
74
+	public function getResponse()
75
+	{
76
+		return $this->response;
77
+	}
78
+
79
+	/**
80
+	 * @param ResponseInterface $response
81
+	 * @return self
82
+	 */
83
+
84
+	public function setResponse(ResponseInterface $response)
85
+	{
86
+		$this->response = $response;
87
+		return $this;
88
+	}
89 89
 
90 90
 }
Please login to merge, or discard this patch.
src/Strategies/RequestJsonStrategy.php 1 patch
Indentation   +27 added lines, -27 removed lines patch added patch discarded remove patch
@@ -25,32 +25,32 @@
 block discarded – undo
25 25
 class RequestJsonStrategy implements StrategyInterface
26 26
 {
27 27
 
28
-    use RequestAwareTrait;
29
-
30
-    /**
31
-     * @inheritdoc
32
-     * @throws RuntimeException
33
-     * @return ResponseInterface
34
-     */
35
-
36
-    public function call(Route $route)
37
-    {
38
-        try {
39
-            $response = call_user_func($route->getAction(), $this->request, $route->getMergedParams());
40
-
41
-            if (is_array($response)) {
42
-                $this->response->getBody()->write(json_encode($response));
43
-                $response = $this->response;
44
-            }
45
-
46
-            if ($response instanceof ResponseInterface) {
47
-                return $response->withAddedHeader("content-type", "application/json");
48
-            }
49
-        } catch (HttpExceptionAbstract $e) {
50
-            return $e->getJsonResponse($this->response);
51
-        }
52
-
53
-        throw new RuntimeException("Unable to determine a json response from action returned value.");
54
-    }
28
+	use RequestAwareTrait;
29
+
30
+	/**
31
+	 * @inheritdoc
32
+	 * @throws RuntimeException
33
+	 * @return ResponseInterface
34
+	 */
35
+
36
+	public function call(Route $route)
37
+	{
38
+		try {
39
+			$response = call_user_func($route->getAction(), $this->request, $route->getMergedParams());
40
+
41
+			if (is_array($response)) {
42
+				$this->response->getBody()->write(json_encode($response));
43
+				$response = $this->response;
44
+			}
45
+
46
+			if ($response instanceof ResponseInterface) {
47
+				return $response->withAddedHeader("content-type", "application/json");
48
+			}
49
+		} catch (HttpExceptionAbstract $e) {
50
+			return $e->getJsonResponse($this->response);
51
+		}
52
+
53
+		throw new RuntimeException("Unable to determine a json response from action returned value.");
54
+	}
55 55
 
56 56
 }
Please login to merge, or discard this patch.
src/Strategies/RequestResponseStrategy.php 1 patch
Indentation   +22 added lines, -22 removed lines patch added patch discarded remove patch
@@ -24,27 +24,27 @@
 block discarded – undo
24 24
 class RequestResponseStrategy implements StrategyInterface
25 25
 {
26 26
 
27
-    use RequestAwareTrait;
28
-
29
-    /**
30
-     * @inheritdoc
31
-     * @return ResponseInterface
32
-     */
33
-
34
-    public function call(Route $route)
35
-    {
36
-        try {
37
-            $response = call_user_func($route->getAction(), $this->request, $this->response, $route->getMergedParams());
38
-
39
-            if ($response instanceof ResponseInterface) {
40
-                return $response;
41
-            }
42
-
43
-            $this->response->getBody()->write((string) $response);
44
-            return $this->response;
45
-        } catch (HttpExceptionAbstract $e) {
46
-            return $e->getResponse($this->response);
47
-        }
48
-    }
27
+	use RequestAwareTrait;
28
+
29
+	/**
30
+	 * @inheritdoc
31
+	 * @return ResponseInterface
32
+	 */
33
+
34
+	public function call(Route $route)
35
+	{
36
+		try {
37
+			$response = call_user_func($route->getAction(), $this->request, $this->response, $route->getMergedParams());
38
+
39
+			if ($response instanceof ResponseInterface) {
40
+				return $response;
41
+			}
42
+
43
+			$this->response->getBody()->write((string) $response);
44
+			return $this->response;
45
+		} catch (HttpExceptionAbstract $e) {
46
+			return $e->getResponse($this->response);
47
+		}
48
+	}
49 49
 
50 50
 }
Please login to merge, or discard this patch.