Passed
Branch dev (6ce9d7)
by Alex
02:42
created
src/Collectors/ControllerCollectorTrait.php 1 patch
Indentation   +217 added lines, -217 removed lines patch added patch discarded remove patch
@@ -26,223 +26,223 @@
 block discarded – undo
26 26
 trait ControllerCollectorTrait
27 27
 {
28 28
 
29
-    abstract public function getWildcards();
30
-    abstract public function set($method, $pattern, $action);
31
-
32
-    /**
33
-     * Define how controller actions names will be joined to form the route pattern.
34
-     *
35
-     * @var string
36
-     */
37
-
38
-    protected $controllerActionJoin = "/";
39
-
40
-    /**
41
-     * Maps all the controller methods that begins with a HTTP method, and maps the rest of
42
-     * name as a path. The path will be the method name with slashes before every camelcased 
43
-     * word and without the HTTP method prefix, and the controller name will be used to prefix
44
-     * the route pattern. e.g. ArticlesController::getCreate will generate a route to: GET articles/create
45
-     *
46
-     * @param string $controller The controller name
47
-     * @param string $prefix
48
-     *
49
-     * @throws \ReflectionException
50
-     * @return Group
51
-     */
52
-
53
-    public function controller($controller, $prefix = null)
54
-    {
55
-        $controller = new ReflectionClass($controller);
56
-        $prefix     = $prefix === null ? $this->getControllerPrefix($controller) : $prefix;
57
-        $methods    = $controller->getMethods(ReflectionMethod::IS_PUBLIC);
58
-        return $this->collectControllerRoutes($controller, $methods, "/$prefix/");
59
-    }
60
-
61
-    /**
62
-     * Maps several controllers at same time.
63
-     *
64
-     * @param string[] $controllers Controllers name.
65
-     * @throws \ReflectionException
66
-     * @return Group
67
-     */
68
-
69
-    public function controllers(array $controllers)
70
-    {
71
-        $group = new Group;
72
-        foreach ($controllers as $controller)
73
-            $group->set($this->controller($controller));
74
-        return $group;
75
-    }
76
-
77
-    /**
78
-     * Alias for Collector::controller but maps a controller without using the controller name as prefix.
79
-     *
80
-     * @param string $controller The controller name
81
-     * @throws \ReflectionException
82
-     * @return Group
83
-     */
84
-
85
-    public function controllerWithoutPrefix($controller)
86
-    {
87
-        $controller = new ReflectionClass($controller);
88
-        $methods = $controller->getMethods(ReflectionMethod::IS_PUBLIC);
89
-        return $this->collectControllerRoutes($controller, $methods, "/");
90
-    }
91
-
92
-    /**
93
-     * Alias for Collector::controllers but maps a controller without using the controller name as prefix.
94
-     *
95
-     * @param string[] $controllers
96
-     * @throws \ReflectionException
97
-     * @return Group
98
-     */
99
-
100
-    public function controllersWithoutPrefix(array $controllers)
101
-    {
102
-        $group = new Group;
103
-        foreach ($controllers as $controller)
104
-            $group->set($this->controllerWithoutPrefix($controller));
105
-        return $group;
106
-    }
107
-
108
-    /**
109
-     * @param ReflectionClass $controller
110
-     * @param ReflectionMethod[] $methods
111
-     * @param string $prefix
112
-     *
113
-     * @return Group
114
-     */
115
-
116
-    protected function collectControllerRoutes(ReflectionClass $controller, array $methods, $prefix)
117
-    {
118
-        $group = new Group;
119
-        $controllerDefaultStrategy = $this->getAnnotatedStrategy($controller);
120
-
121
-        foreach ($methods as $method) {
122
-            $name = preg_split("~(?=[A-Z])~", $method->name);
123
-            $http = $name[0];
124
-            unset($name[0]);
29
+	abstract public function getWildcards();
30
+	abstract public function set($method, $pattern, $action);
31
+
32
+	/**
33
+	 * Define how controller actions names will be joined to form the route pattern.
34
+	 *
35
+	 * @var string
36
+	 */
37
+
38
+	protected $controllerActionJoin = "/";
39
+
40
+	/**
41
+	 * Maps all the controller methods that begins with a HTTP method, and maps the rest of
42
+	 * name as a path. The path will be the method name with slashes before every camelcased 
43
+	 * word and without the HTTP method prefix, and the controller name will be used to prefix
44
+	 * the route pattern. e.g. ArticlesController::getCreate will generate a route to: GET articles/create
45
+	 *
46
+	 * @param string $controller The controller name
47
+	 * @param string $prefix
48
+	 *
49
+	 * @throws \ReflectionException
50
+	 * @return Group
51
+	 */
52
+
53
+	public function controller($controller, $prefix = null)
54
+	{
55
+		$controller = new ReflectionClass($controller);
56
+		$prefix     = $prefix === null ? $this->getControllerPrefix($controller) : $prefix;
57
+		$methods    = $controller->getMethods(ReflectionMethod::IS_PUBLIC);
58
+		return $this->collectControllerRoutes($controller, $methods, "/$prefix/");
59
+	}
60
+
61
+	/**
62
+	 * Maps several controllers at same time.
63
+	 *
64
+	 * @param string[] $controllers Controllers name.
65
+	 * @throws \ReflectionException
66
+	 * @return Group
67
+	 */
68
+
69
+	public function controllers(array $controllers)
70
+	{
71
+		$group = new Group;
72
+		foreach ($controllers as $controller)
73
+			$group->set($this->controller($controller));
74
+		return $group;
75
+	}
76
+
77
+	/**
78
+	 * Alias for Collector::controller but maps a controller without using the controller name as prefix.
79
+	 *
80
+	 * @param string $controller The controller name
81
+	 * @throws \ReflectionException
82
+	 * @return Group
83
+	 */
84
+
85
+	public function controllerWithoutPrefix($controller)
86
+	{
87
+		$controller = new ReflectionClass($controller);
88
+		$methods = $controller->getMethods(ReflectionMethod::IS_PUBLIC);
89
+		return $this->collectControllerRoutes($controller, $methods, "/");
90
+	}
91
+
92
+	/**
93
+	 * Alias for Collector::controllers but maps a controller without using the controller name as prefix.
94
+	 *
95
+	 * @param string[] $controllers
96
+	 * @throws \ReflectionException
97
+	 * @return Group
98
+	 */
99
+
100
+	public function controllersWithoutPrefix(array $controllers)
101
+	{
102
+		$group = new Group;
103
+		foreach ($controllers as $controller)
104
+			$group->set($this->controllerWithoutPrefix($controller));
105
+		return $group;
106
+	}
107
+
108
+	/**
109
+	 * @param ReflectionClass $controller
110
+	 * @param ReflectionMethod[] $methods
111
+	 * @param string $prefix
112
+	 *
113
+	 * @return Group
114
+	 */
115
+
116
+	protected function collectControllerRoutes(ReflectionClass $controller, array $methods, $prefix)
117
+	{
118
+		$group = new Group;
119
+		$controllerDefaultStrategy = $this->getAnnotatedStrategy($controller);
120
+
121
+		foreach ($methods as $method) {
122
+			$name = preg_split("~(?=[A-Z])~", $method->name);
123
+			$http = $name[0];
124
+			unset($name[0]);
125 125
  
126
-            if (strpos(Collector::HTTP_METHODS, $http) !== false) {
127
-                $action   = $prefix . strtolower(implode($this->controllerActionJoin, $name));
128
-                $dynamic  = $this->getMethodConstraints($method);
129
-                $strategy = $this->getAnnotatedStrategy($method);
130
-
131
-                /** @var \Codeburner\Router\Route $route */
132
-                $route = $this->set($http, "$action$dynamic", [$controller->name, $method->name]);
133
-
134
-                if ($strategy !== null) {
135
-                       $route->setStrategy($strategy);
136
-                } else $route->setStrategy($controllerDefaultStrategy);
137
-
138
-                $group->set($route);
139
-            }
140
-        }
141
-
142
-        return $group;
143
-    }
144
-
145
-    /**
146
-     * @param ReflectionClass $controller
147
-     *
148
-     * @return string
149
-     */
150
-
151
-    protected function getControllerPrefix(ReflectionClass $controller)
152
-    {
153
-        preg_match("~\@prefix\s([a-zA-Z\\\_]+)~i", (string) $controller->getDocComment(), $prefix);
154
-        return isset($prefix[1]) ? $prefix[1] : str_replace("controller", "", strtolower($controller->getShortName()));
155
-    }
156
-
157
-    /**
158
-     * @param \ReflectionMethod
159
-     * @return string
160
-     */
161
-
162
-    protected function getMethodConstraints(ReflectionMethod $method)
163
-    {
164
-        $beginPath = "";
165
-        $endPath = "";
166
-
167
-        if ($parameters = $method->getParameters()) {
168
-            $types = $this->getParamsConstraint($method);
169
-
170
-            foreach ($parameters as $parameter) {
171
-                if ($parameter->isOptional()) {
172
-                    $beginPath .= "[";
173
-                    $endPath .= "]";
174
-                }
175
-
176
-                $beginPath .= $this->getPathConstraint($parameter, $types);
177
-            }
178
-        }
179
-
180
-        return $beginPath . $endPath;
181
-    }
182
-
183
-    /**
184
-     * @param ReflectionParameter $parameter
185
-     * @param string[] $types
186
-     * @return string
187
-     */
188
-
189
-    protected function getPathConstraint(ReflectionParameter $parameter, $types)
190
-    {
191
-        $name = $parameter->name;
192
-        $path = "/{" . $name;
193
-        return isset($types[$name]) ? "$path:{$types[$name]}}" : "$path}";
194
-    }
195
-
196
-    /**
197
-     * @param ReflectionMethod $method
198
-     * @return string[]
199
-     */
200
-
201
-    protected function getParamsConstraint(ReflectionMethod $method)
202
-    {
203
-        $params = [];
204
-        preg_match_all("~\@param\s(" . implode("|", array_keys($this->getWildcards())) . "|\(.+\))\s\\$([a-zA-Z0-1_]+)~i",
205
-            $method->getDocComment(), $types, PREG_SET_ORDER);
206
-
207
-        foreach ((array) $types as $type) {
208
-            // if a pattern is defined on Match take it otherwise take the param type by PHPDoc.
209
-            $params[$type[2]] = isset($type[4]) ? $type[4] : $type[1];
210
-        }
211
-
212
-        return $params;
213
-    }
214
-
215
-    /**
216
-     * @param ReflectionClass|ReflectionMethod $reflector
217
-     * @return string|null
218
-     */
219
-
220
-    protected function getAnnotatedStrategy($reflector)
221
-    {
222
-        preg_match("~\@strategy\s([a-zA-Z\\\_]+)~i", (string) $reflector->getDocComment(), $strategy);
223
-        return isset($strategy[1]) ? $strategy[1] : null;
224
-    }
225
-
226
-    /**
227
-     * Define how controller actions names will be joined to form the route pattern.
228
-     * Defaults to "/" so actions like "getMyAction" will be "/my/action". If changed to
229
-     * "-" the new pattern will be "/my-action".
230
-     *
231
-     * @param string $join
232
-     */
233
-
234
-    public function setControllerActionJoin($join)
235
-    {
236
-        $this->controllerActionJoin = $join;
237
-    }
238
-
239
-    /**
240
-     * @return string
241
-     */
242
-
243
-    public function getControllerActionJoin()
244
-    {
245
-        return $this->controllerActionJoin;
246
-    }
126
+			if (strpos(Collector::HTTP_METHODS, $http) !== false) {
127
+				$action   = $prefix . strtolower(implode($this->controllerActionJoin, $name));
128
+				$dynamic  = $this->getMethodConstraints($method);
129
+				$strategy = $this->getAnnotatedStrategy($method);
130
+
131
+				/** @var \Codeburner\Router\Route $route */
132
+				$route = $this->set($http, "$action$dynamic", [$controller->name, $method->name]);
133
+
134
+				if ($strategy !== null) {
135
+					   $route->setStrategy($strategy);
136
+				} else $route->setStrategy($controllerDefaultStrategy);
137
+
138
+				$group->set($route);
139
+			}
140
+		}
141
+
142
+		return $group;
143
+	}
144
+
145
+	/**
146
+	 * @param ReflectionClass $controller
147
+	 *
148
+	 * @return string
149
+	 */
150
+
151
+	protected function getControllerPrefix(ReflectionClass $controller)
152
+	{
153
+		preg_match("~\@prefix\s([a-zA-Z\\\_]+)~i", (string) $controller->getDocComment(), $prefix);
154
+		return isset($prefix[1]) ? $prefix[1] : str_replace("controller", "", strtolower($controller->getShortName()));
155
+	}
156
+
157
+	/**
158
+	 * @param \ReflectionMethod
159
+	 * @return string
160
+	 */
161
+
162
+	protected function getMethodConstraints(ReflectionMethod $method)
163
+	{
164
+		$beginPath = "";
165
+		$endPath = "";
166
+
167
+		if ($parameters = $method->getParameters()) {
168
+			$types = $this->getParamsConstraint($method);
169
+
170
+			foreach ($parameters as $parameter) {
171
+				if ($parameter->isOptional()) {
172
+					$beginPath .= "[";
173
+					$endPath .= "]";
174
+				}
175
+
176
+				$beginPath .= $this->getPathConstraint($parameter, $types);
177
+			}
178
+		}
179
+
180
+		return $beginPath . $endPath;
181
+	}
182
+
183
+	/**
184
+	 * @param ReflectionParameter $parameter
185
+	 * @param string[] $types
186
+	 * @return string
187
+	 */
188
+
189
+	protected function getPathConstraint(ReflectionParameter $parameter, $types)
190
+	{
191
+		$name = $parameter->name;
192
+		$path = "/{" . $name;
193
+		return isset($types[$name]) ? "$path:{$types[$name]}}" : "$path}";
194
+	}
195
+
196
+	/**
197
+	 * @param ReflectionMethod $method
198
+	 * @return string[]
199
+	 */
200
+
201
+	protected function getParamsConstraint(ReflectionMethod $method)
202
+	{
203
+		$params = [];
204
+		preg_match_all("~\@param\s(" . implode("|", array_keys($this->getWildcards())) . "|\(.+\))\s\\$([a-zA-Z0-1_]+)~i",
205
+			$method->getDocComment(), $types, PREG_SET_ORDER);
206
+
207
+		foreach ((array) $types as $type) {
208
+			// if a pattern is defined on Match take it otherwise take the param type by PHPDoc.
209
+			$params[$type[2]] = isset($type[4]) ? $type[4] : $type[1];
210
+		}
211
+
212
+		return $params;
213
+	}
214
+
215
+	/**
216
+	 * @param ReflectionClass|ReflectionMethod $reflector
217
+	 * @return string|null
218
+	 */
219
+
220
+	protected function getAnnotatedStrategy($reflector)
221
+	{
222
+		preg_match("~\@strategy\s([a-zA-Z\\\_]+)~i", (string) $reflector->getDocComment(), $strategy);
223
+		return isset($strategy[1]) ? $strategy[1] : null;
224
+	}
225
+
226
+	/**
227
+	 * Define how controller actions names will be joined to form the route pattern.
228
+	 * Defaults to "/" so actions like "getMyAction" will be "/my/action". If changed to
229
+	 * "-" the new pattern will be "/my-action".
230
+	 *
231
+	 * @param string $join
232
+	 */
233
+
234
+	public function setControllerActionJoin($join)
235
+	{
236
+		$this->controllerActionJoin = $join;
237
+	}
238
+
239
+	/**
240
+	 * @return string
241
+	 */
242
+
243
+	public function getControllerActionJoin()
244
+	{
245
+		return $this->controllerActionJoin;
246
+	}
247 247
 
248 248
 }
Please login to merge, or discard this patch.
src/Route.php 2 patches
Indentation   +601 added lines, -601 removed lines patch added patch discarded remove patch
@@ -23,614 +23,614 @@
 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 string|array|\Closure
46
-     */
44
+	/**
45
+	 * @var string|array|\Closure
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 string|array|\Closure
106
-     */
107
-
108
-    protected $controllerCreationFunction;
109
-
110
-    /**
111
-     * @param Collector $collector
112
-     * @param string $method
113
-     * @param string $pattern
114
-     * @param string|array|\Closure $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 on callables. eg. routes action controller#action
175
-     * syntax allow to use the variables to build the string like: {controller}@{action}
176
-     *
177
-     * @param string|array|\Closure $callable
178
-     * @return string|array|\Closure
179
-     */
180
-
181
-    private function parseCallable($callable)
182
-    {
183
-        if (is_string($callable) && strpos($callable, "@")) {
184
-            $callable = explode("@", $callable);
185
-        }
186
-
187
-        if (is_array($callable)) {
188
-            if (is_string($callable[0])) {
189
-                   $callable[0] = $this->parseCallableController($callable[0]);
190
-            }
191
-
192
-            $callable[1] = $this->parseCallablePlaceholders($callable[1]);
193
-        }
194
-
195
-        return $callable;
196
-    }
197
-
198
-    /**
199
-     * Get the controller object.
200
-     *
201
-     * @param string $controller
202
-     * @return Object
203
-     */
204
-
205
-    private function parseCallableController($controller)
206
-    {
207
-        $controller  = rtrim($this->namespace, "\\") . "\\" . $this->parseCallablePlaceholders($controller);
208
-
209
-        if ($this->controllerCreationFunction === null) {
210
-               return new $controller;
211
-        } else return call_user_func($this->controllerCreationFunction, $controller);
212
-    }
213
-
214
-    /**
215
-     * Parse and replace dynamic content on route action.
216
-     *
217
-     * @param  string $fragment Part of callable
218
-     * @return string
219
-     */
220
-
221
-    private function parseCallablePlaceholders($fragment)
222
-    {
223
-        if (strpos($fragment, "{") !== false) {
224
-            foreach ($this->params as $placeholder => $value) {
225
-                if (strpos($fragment, "{" . $placeholder . "}") !== false) {
226
-                    $fragment = str_replace("{" . $placeholder . "}", ucwords(str_replace("-", " ", $value)), $fragment);
227
-                }
228
-            }
229
-        }
230
-
231
-        return $fragment;
232
-    }
233
-
234
-    /**
235
-     * Execute the route action with the given strategy.
236
-     *
237
-     * @throws BadRouteException
238
-     * @return mixed
239
-     */
240
-
241
-    private function callWithStrategy()
242
-    {
243
-        if ($this->strategy instanceof StrategyInterface) {
244
-            if ($this->strategy instanceof MatcherAwareInterface) {
245
-                $this->strategy->setMatcher($this->matcher);
246
-            }
247
-
248
-            return $this->strategy->call($this);
249
-        }
250
-
251
-        $strategy = get_class($this->strategy);
252
-        throw new BadRouteException("`$strategy` is not a valid route dispatch strategy, ".
253
-            "it must implement the `Codeburner\\Router\\Strategies\\StrategyInterface` interface.");
254
-    }
255
-
256
-    /**
257
-     * @return Collector
258
-     */
259
-
260
-    public function getCollector()
261
-    {
262
-        return $this->collector;
263
-    }
264
-
265
-    /**
266
-     * @return string
267
-     */
268
-
269
-    public function getMethod()
270
-    {
271
-        return $this->method;
272
-    }
273
-
274
-    /**
275
-     * @return string
276
-     */
277
-
278
-    public function getPattern()
279
-    {
280
-        return $this->pattern;
281
-    }
282
-
283
-    /**
284
-     * @return string[]
285
-     */
286
-
287
-    public function getSegments()
288
-    {
289
-        return explode("/", $this->pattern);
290
-    }
291
-
292
-    /**
293
-     * @return string|array|\Closure
294
-     */
295
-
296
-    public function getAction()
297
-    {
298
-        return $this->action;
299
-    }
300
-
301
-    /**
302
-     * @return string
303
-     */
304
-
305
-    public function getNamespace()
306
-    {
307
-        return $this->namespace;
308
-    }
309
-
310
-    /**
311
-     * @return string[]
312
-     */
313
-
314
-    public function getParams()
315
-    {
316
-        return $this->params;
317
-    }
318
-
319
-    /**
320
-     * @param string $key
321
-     * @return string
322
-     */
323
-
324
-    public function getParam($key)
325
-    {
326
-        return $this->params[$key];
327
-    }
328
-
329
-    /**
330
-     * @return array
331
-     */
332
-
333
-    public function getDefaults()
334
-    {
335
-        return $this->defaults;
336
-    }
337
-
338
-    /**
339
-     * @param string $key
340
-     * @return mixed
341
-     */
342
-
343
-    public function getDefault($key)
344
-    {
345
-        return $this->defaults[$key];
346
-    }
347
-
348
-    /**
349
-     * @return array
350
-     */
351
-
352
-    public function getMetadataArray()
353
-    {
354
-        return $this->metadata;
355
-    }
356
-
357
-    /**
358
-     * @param string $key
359
-     * @return mixed
360
-     */
361
-
362
-    public function getMetadata($key)
363
-    {
364
-        return $this->metadata[$key];
365
-    }
366
-
367
-    /**
368
-     * @return string|null
369
-     */
370
-
371
-    public function getStrategy()
372
-    {
373
-        if ($this->strategy instanceof StrategyInterface) {
374
-            return get_class($this->strategy);
375
-        }
376
-
377
-        return $this->strategy;
378
-    }
379
-
380
-    /**
381
-     * @inheritdoc
382
-     */
383
-
384
-    public function getMatcher()
385
-    {
386
-        return $this->matcher;
387
-    }
388
-
389
-    /**
390
-     * Verify if a Route have already been blocked.
391
-     *
392
-     * @return boolean
393
-     */
394
-
395
-    public function getBlock()
396
-    {
397
-        return $this->blocked;
398
-    }
399
-
400
-    /**
401
-     * Blocking a route indicate that that route have been selected and
402
-     * parsed, now it will be given to the matcher.
403
-     *
404
-     * @param bool $blocked
405
-     * @return self
406
-     */
407
-
408
-    public function setBlock($blocked)
409
-    {
410
-        $this->blocked = $blocked;
411
-        return $this;
412
-    }
413
-
414
-    /**
415
-     * @param string $method
416
-     * @return Route
417
-     */
418
-
419
-    public function setMethod($method)
420
-    {
421
-        $this->forget();
422
-        $this->method = $method;
423
-        return $this->reset();
424
-    }
425
-
426
-    /**
427
-     * @param string $pattern
428
-     * @return Route
429
-     */
430
-
431
-    public function setPattern($pattern)
432
-    {
433
-        $this->forget();
434
-        $this->pattern = $pattern;
435
-        return $this->reset();
436
-    }
437
-
438
-    /**
439
-     * @param string $pattern
440
-     * @return self
441
-     */
442
-
443
-    public function setPatternWithoutReset($pattern)
444
-    {
445
-        $this->pattern = $pattern;
446
-        return $this;
447
-    }
448
-
449
-    /**
450
-     * @param string $action
451
-     * @return self
452
-     */
453
-
454
-    public function setAction($action)
455
-    {
456
-        $this->action = $action;
457
-        return $this;
458
-    }
459
-
460
-    /**
461
-     * @param string $namespace
462
-     * @return self
463
-     */
464
-
465
-    public function setNamespace($namespace)
466
-    {
467
-        $this->namespace = $namespace;
468
-        return $this;
469
-    }
470
-
471
-    /**
472
-     * @param string[] $params
473
-     * @return self
474
-     */
475
-
476
-    public function setParams(array $params)
477
-    {
478
-        $this->params = $params;
479
-        return $this;
480
-    }
481
-
482
-    /**
483
-     * @param string $key
484
-     * @param string $value
485
-     *
486
-     * @return self
487
-     */
488
-
489
-    public function setParam($key, $value)
490
-    {
491
-        $this->params[$key] = $value;
492
-        return $this;
493
-    }
494
-
495
-    /**
496
-     * @param mixed[] $defaults
497
-     * @return self
498
-     */
499
-
500
-    public function setDefaults(array $defaults)
501
-    {
502
-        $this->defaults = $defaults;
503
-        return $this;
504
-    }
505
-
506
-    /**
507
-     * @param string $key
508
-     * @param mixed $value
509
-     *
510
-     * @return self
511
-     */
512
-
513
-    public function setDefault($key, $value)
514
-    {
515
-        $this->defaults[$key] = $value;
516
-        return $this;
517
-    }
518
-
519
-    /**
520
-     * @param mixed[] $metadata
521
-     * @return self
522
-     */
523
-
524
-    public function setMetadataArray(array $metadata)
525
-    {
526
-        $this->metadata = $metadata;
527
-        return $this;
528
-    }
529
-
530
-    /**
531
-     * @param string $key
532
-     * @param mixed $value
533
-     *
534
-     * @return $this
535
-     */
536
-
537
-    public function setMetadata($key, $value)
538
-    {
539
-        $this->metadata[$key] = $value;
540
-        return $this;
541
-    }
542
-
543
-    /**
544
-     * @param null|string|StrategyInterface $strategy
545
-     * @return self
546
-     */
547
-
548
-    public function setStrategy($strategy)
549
-    {
550
-        $this->strategy = $strategy;
551
-        return $this;
552
-    }
553
-
554
-    /**
555
-     * @inheritdoc
556
-     */
557
-
558
-    public function setMatcher(Matcher $matcher)
559
-    {
560
-        $this->matcher = $matcher;
561
-        return $this;
562
-    }
563
-
564
-    /**
565
-     * Set a constraint to a token in the route pattern.
566
-     *
567
-     * @param string $token
568
-     * @param string $regex
569
-     *
570
-     * @return self
571
-     */
572
-
573
-    public function setConstraint($token, $regex)
574
-    {
575
-        $initPos = strpos($this->pattern, "{" . $token);
576
-
577
-        if ($initPos !== false) {
578
-            $endPos = strpos($this->pattern, "}", $initPos);
579
-            $newPattern = substr_replace($this->pattern, "{" . "$token:$regex" . "}", $initPos, $endPos - $initPos + 1);
580
-            $wildcards = $this->collector->getWildcardTokens();
581
-            $newPattern = str_replace(array_keys($wildcards), $wildcards, $newPattern);
582
-            $this->setPatternWithoutReset($newPattern);
583
-        }
584
-
585
-        return $this;
586
-    }
587
-
588
-    /**
589
-     * Set a function to create controllers.
590
-     *
591
-     * @param string|array|\Closure $callable
592
-     * @throws BadRouteException
593
-     * @return self
594
-     */
595
-
596
-    public function setControllerCreationFunction($callable)
597
-    {
598
-        if (!is_callable($callable)) {
599
-            throw new BadRouteException(BadRouteException::WRONG_CONTROLLER_CREATION_FUNC);
600
-        }
601
-
602
-        $this->controllerCreationFunction = $this->parseCallable($callable);
603
-        return $this;
604
-    }
605
-
606
-    /**
607
-     * @param string $key
608
-     * @return bool
609
-     */
610
-
611
-    public function hasParam($key)
612
-    {
613
-        return isset($this->params[$key]);
614
-    }
615
-
616
-    /**
617
-     * @param string $key
618
-     * @return bool
619
-     */
620
-
621
-    public function hasDefault($key)
622
-    {
623
-        return isset($this->defaults[$key]);
624
-    }
625
-
626
-    /**
627
-     * @param string $key
628
-     * @return bool
629
-     */
630
-
631
-    public function hasMetadata($key)
632
-    {
633
-        return isset($this->metadata[$key]);
634
-    }
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 string|array|\Closure
106
+	 */
107
+
108
+	protected $controllerCreationFunction;
109
+
110
+	/**
111
+	 * @param Collector $collector
112
+	 * @param string $method
113
+	 * @param string $pattern
114
+	 * @param string|array|\Closure $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 on callables. eg. routes action controller#action
175
+	 * syntax allow to use the variables to build the string like: {controller}@{action}
176
+	 *
177
+	 * @param string|array|\Closure $callable
178
+	 * @return string|array|\Closure
179
+	 */
180
+
181
+	private function parseCallable($callable)
182
+	{
183
+		if (is_string($callable) && strpos($callable, "@")) {
184
+			$callable = explode("@", $callable);
185
+		}
186
+
187
+		if (is_array($callable)) {
188
+			if (is_string($callable[0])) {
189
+				   $callable[0] = $this->parseCallableController($callable[0]);
190
+			}
191
+
192
+			$callable[1] = $this->parseCallablePlaceholders($callable[1]);
193
+		}
194
+
195
+		return $callable;
196
+	}
197
+
198
+	/**
199
+	 * Get the controller object.
200
+	 *
201
+	 * @param string $controller
202
+	 * @return Object
203
+	 */
204
+
205
+	private function parseCallableController($controller)
206
+	{
207
+		$controller  = rtrim($this->namespace, "\\") . "\\" . $this->parseCallablePlaceholders($controller);
208
+
209
+		if ($this->controllerCreationFunction === null) {
210
+			   return new $controller;
211
+		} else return call_user_func($this->controllerCreationFunction, $controller);
212
+	}
213
+
214
+	/**
215
+	 * Parse and replace dynamic content on route action.
216
+	 *
217
+	 * @param  string $fragment Part of callable
218
+	 * @return string
219
+	 */
220
+
221
+	private function parseCallablePlaceholders($fragment)
222
+	{
223
+		if (strpos($fragment, "{") !== false) {
224
+			foreach ($this->params as $placeholder => $value) {
225
+				if (strpos($fragment, "{" . $placeholder . "}") !== false) {
226
+					$fragment = str_replace("{" . $placeholder . "}", ucwords(str_replace("-", " ", $value)), $fragment);
227
+				}
228
+			}
229
+		}
230
+
231
+		return $fragment;
232
+	}
233
+
234
+	/**
235
+	 * Execute the route action with the given strategy.
236
+	 *
237
+	 * @throws BadRouteException
238
+	 * @return mixed
239
+	 */
240
+
241
+	private function callWithStrategy()
242
+	{
243
+		if ($this->strategy instanceof StrategyInterface) {
244
+			if ($this->strategy instanceof MatcherAwareInterface) {
245
+				$this->strategy->setMatcher($this->matcher);
246
+			}
247
+
248
+			return $this->strategy->call($this);
249
+		}
250
+
251
+		$strategy = get_class($this->strategy);
252
+		throw new BadRouteException("`$strategy` is not a valid route dispatch strategy, ".
253
+			"it must implement the `Codeburner\\Router\\Strategies\\StrategyInterface` interface.");
254
+	}
255
+
256
+	/**
257
+	 * @return Collector
258
+	 */
259
+
260
+	public function getCollector()
261
+	{
262
+		return $this->collector;
263
+	}
264
+
265
+	/**
266
+	 * @return string
267
+	 */
268
+
269
+	public function getMethod()
270
+	{
271
+		return $this->method;
272
+	}
273
+
274
+	/**
275
+	 * @return string
276
+	 */
277
+
278
+	public function getPattern()
279
+	{
280
+		return $this->pattern;
281
+	}
282
+
283
+	/**
284
+	 * @return string[]
285
+	 */
286
+
287
+	public function getSegments()
288
+	{
289
+		return explode("/", $this->pattern);
290
+	}
291
+
292
+	/**
293
+	 * @return string|array|\Closure
294
+	 */
295
+
296
+	public function getAction()
297
+	{
298
+		return $this->action;
299
+	}
300
+
301
+	/**
302
+	 * @return string
303
+	 */
304
+
305
+	public function getNamespace()
306
+	{
307
+		return $this->namespace;
308
+	}
309
+
310
+	/**
311
+	 * @return string[]
312
+	 */
313
+
314
+	public function getParams()
315
+	{
316
+		return $this->params;
317
+	}
318
+
319
+	/**
320
+	 * @param string $key
321
+	 * @return string
322
+	 */
323
+
324
+	public function getParam($key)
325
+	{
326
+		return $this->params[$key];
327
+	}
328
+
329
+	/**
330
+	 * @return array
331
+	 */
332
+
333
+	public function getDefaults()
334
+	{
335
+		return $this->defaults;
336
+	}
337
+
338
+	/**
339
+	 * @param string $key
340
+	 * @return mixed
341
+	 */
342
+
343
+	public function getDefault($key)
344
+	{
345
+		return $this->defaults[$key];
346
+	}
347
+
348
+	/**
349
+	 * @return array
350
+	 */
351
+
352
+	public function getMetadataArray()
353
+	{
354
+		return $this->metadata;
355
+	}
356
+
357
+	/**
358
+	 * @param string $key
359
+	 * @return mixed
360
+	 */
361
+
362
+	public function getMetadata($key)
363
+	{
364
+		return $this->metadata[$key];
365
+	}
366
+
367
+	/**
368
+	 * @return string|null
369
+	 */
370
+
371
+	public function getStrategy()
372
+	{
373
+		if ($this->strategy instanceof StrategyInterface) {
374
+			return get_class($this->strategy);
375
+		}
376
+
377
+		return $this->strategy;
378
+	}
379
+
380
+	/**
381
+	 * @inheritdoc
382
+	 */
383
+
384
+	public function getMatcher()
385
+	{
386
+		return $this->matcher;
387
+	}
388
+
389
+	/**
390
+	 * Verify if a Route have already been blocked.
391
+	 *
392
+	 * @return boolean
393
+	 */
394
+
395
+	public function getBlock()
396
+	{
397
+		return $this->blocked;
398
+	}
399
+
400
+	/**
401
+	 * Blocking a route indicate that that route have been selected and
402
+	 * parsed, now it will be given to the matcher.
403
+	 *
404
+	 * @param bool $blocked
405
+	 * @return self
406
+	 */
407
+
408
+	public function setBlock($blocked)
409
+	{
410
+		$this->blocked = $blocked;
411
+		return $this;
412
+	}
413
+
414
+	/**
415
+	 * @param string $method
416
+	 * @return Route
417
+	 */
418
+
419
+	public function setMethod($method)
420
+	{
421
+		$this->forget();
422
+		$this->method = $method;
423
+		return $this->reset();
424
+	}
425
+
426
+	/**
427
+	 * @param string $pattern
428
+	 * @return Route
429
+	 */
430
+
431
+	public function setPattern($pattern)
432
+	{
433
+		$this->forget();
434
+		$this->pattern = $pattern;
435
+		return $this->reset();
436
+	}
437
+
438
+	/**
439
+	 * @param string $pattern
440
+	 * @return self
441
+	 */
442
+
443
+	public function setPatternWithoutReset($pattern)
444
+	{
445
+		$this->pattern = $pattern;
446
+		return $this;
447
+	}
448
+
449
+	/**
450
+	 * @param string $action
451
+	 * @return self
452
+	 */
453
+
454
+	public function setAction($action)
455
+	{
456
+		$this->action = $action;
457
+		return $this;
458
+	}
459
+
460
+	/**
461
+	 * @param string $namespace
462
+	 * @return self
463
+	 */
464
+
465
+	public function setNamespace($namespace)
466
+	{
467
+		$this->namespace = $namespace;
468
+		return $this;
469
+	}
470
+
471
+	/**
472
+	 * @param string[] $params
473
+	 * @return self
474
+	 */
475
+
476
+	public function setParams(array $params)
477
+	{
478
+		$this->params = $params;
479
+		return $this;
480
+	}
481
+
482
+	/**
483
+	 * @param string $key
484
+	 * @param string $value
485
+	 *
486
+	 * @return self
487
+	 */
488
+
489
+	public function setParam($key, $value)
490
+	{
491
+		$this->params[$key] = $value;
492
+		return $this;
493
+	}
494
+
495
+	/**
496
+	 * @param mixed[] $defaults
497
+	 * @return self
498
+	 */
499
+
500
+	public function setDefaults(array $defaults)
501
+	{
502
+		$this->defaults = $defaults;
503
+		return $this;
504
+	}
505
+
506
+	/**
507
+	 * @param string $key
508
+	 * @param mixed $value
509
+	 *
510
+	 * @return self
511
+	 */
512
+
513
+	public function setDefault($key, $value)
514
+	{
515
+		$this->defaults[$key] = $value;
516
+		return $this;
517
+	}
518
+
519
+	/**
520
+	 * @param mixed[] $metadata
521
+	 * @return self
522
+	 */
523
+
524
+	public function setMetadataArray(array $metadata)
525
+	{
526
+		$this->metadata = $metadata;
527
+		return $this;
528
+	}
529
+
530
+	/**
531
+	 * @param string $key
532
+	 * @param mixed $value
533
+	 *
534
+	 * @return $this
535
+	 */
536
+
537
+	public function setMetadata($key, $value)
538
+	{
539
+		$this->metadata[$key] = $value;
540
+		return $this;
541
+	}
542
+
543
+	/**
544
+	 * @param null|string|StrategyInterface $strategy
545
+	 * @return self
546
+	 */
547
+
548
+	public function setStrategy($strategy)
549
+	{
550
+		$this->strategy = $strategy;
551
+		return $this;
552
+	}
553
+
554
+	/**
555
+	 * @inheritdoc
556
+	 */
557
+
558
+	public function setMatcher(Matcher $matcher)
559
+	{
560
+		$this->matcher = $matcher;
561
+		return $this;
562
+	}
563
+
564
+	/**
565
+	 * Set a constraint to a token in the route pattern.
566
+	 *
567
+	 * @param string $token
568
+	 * @param string $regex
569
+	 *
570
+	 * @return self
571
+	 */
572
+
573
+	public function setConstraint($token, $regex)
574
+	{
575
+		$initPos = strpos($this->pattern, "{" . $token);
576
+
577
+		if ($initPos !== false) {
578
+			$endPos = strpos($this->pattern, "}", $initPos);
579
+			$newPattern = substr_replace($this->pattern, "{" . "$token:$regex" . "}", $initPos, $endPos - $initPos + 1);
580
+			$wildcards = $this->collector->getWildcardTokens();
581
+			$newPattern = str_replace(array_keys($wildcards), $wildcards, $newPattern);
582
+			$this->setPatternWithoutReset($newPattern);
583
+		}
584
+
585
+		return $this;
586
+	}
587
+
588
+	/**
589
+	 * Set a function to create controllers.
590
+	 *
591
+	 * @param string|array|\Closure $callable
592
+	 * @throws BadRouteException
593
+	 * @return self
594
+	 */
595
+
596
+	public function setControllerCreationFunction($callable)
597
+	{
598
+		if (!is_callable($callable)) {
599
+			throw new BadRouteException(BadRouteException::WRONG_CONTROLLER_CREATION_FUNC);
600
+		}
601
+
602
+		$this->controllerCreationFunction = $this->parseCallable($callable);
603
+		return $this;
604
+	}
605
+
606
+	/**
607
+	 * @param string $key
608
+	 * @return bool
609
+	 */
610
+
611
+	public function hasParam($key)
612
+	{
613
+		return isset($this->params[$key]);
614
+	}
615
+
616
+	/**
617
+	 * @param string $key
618
+	 * @return bool
619
+	 */
620
+
621
+	public function hasDefault($key)
622
+	{
623
+		return isset($this->defaults[$key]);
624
+	}
625
+
626
+	/**
627
+	 * @param string $key
628
+	 * @return bool
629
+	 */
630
+
631
+	public function hasMetadata($key)
632
+	{
633
+		return isset($this->metadata[$key]);
634
+	}
635 635
 
636 636
 }
Please login to merge, or discard this patch.
Braces   +3 added lines, -1 removed lines patch added patch discarded remove patch
@@ -208,7 +208,9 @@
 block discarded – undo
208 208
 
209 209
         if ($this->controllerCreationFunction === null) {
210 210
                return new $controller;
211
-        } else return call_user_func($this->controllerCreationFunction, $controller);
211
+        } else {
212
+        	return call_user_func($this->controllerCreationFunction, $controller);
213
+        }
212 214
     }
213 215
 
214 216
     /**
Please login to merge, or discard this patch.