Skip to content

Commit 022ed45

Browse files
author
Alex Rohleder
committed
Merge pull request #23 from codeburnerframework/dev
pull minor features and patchs
2 parents 300e850 + 709f371 commit 022ed45

File tree

9 files changed

+383
-136
lines changed

9 files changed

+383
-136
lines changed

src/Collector.php

Lines changed: 70 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
* because the routes will not be used until the collector is used.
2020
*/
2121

22+
if (!class_exists(Parser::class, false)) {
23+
include __DIR__ . "/Parser.php";
24+
}
25+
2226
include __DIR__ . "/Route.php";
2327
include __DIR__ . "/Group.php";
2428
include __DIR__ . "/Collectors/ControllerCollectorTrait.php";
@@ -36,14 +40,6 @@ class Collector
3640
use Collectors\ControllerCollectorTrait;
3741
use Collectors\ResourceCollectorTrait;
3842

39-
/**
40-
* These regex define the structure of a dynamic segment in a pattern.
41-
*
42-
* @var string
43-
*/
44-
45-
const DYNAMIC_REGEX = "{\s*(\w*)\s*(?::\s*([^{}]*(?:{(?-1)}*)*))?\s*}";
46-
4743

4844
/**
4945
* All the supported http methods separated by spaces.
@@ -73,24 +69,23 @@ class Collector
7369
protected $dynamics = [];
7470

7571
/**
76-
* Some regex wildcards for easily definition of dynamic routes. ps. all keys and values must start with :
72+
* The pattern parser instance.
7773
*
78-
* @var array
74+
* @var Parser
7975
*/
8076

81-
protected $wildcards = [
82-
":uid" => ":uid-[a-zA-Z0-9]",
83-
":slug" => ":[a-z0-9-]",
84-
":string" => ":\w",
85-
":int" => ":\d",
86-
":integer" => ":\d",
87-
":float" => ":[-+]?\d*?[.]?\d",
88-
":double" => ":[-+]?\d*?[.]?\d",
89-
":hex" => ":0[xX][0-9a-fA-F]",
90-
":octal" => ":0[1-7][0-7]",
91-
":bool" => ":1|0|true|false|yes|no",
92-
":boolean" => ":1|0|true|false|yes|no",
93-
];
77+
protected $parser;
78+
79+
/**
80+
* Collector constructor.
81+
*
82+
* @param Parser|null $parser
83+
*/
84+
85+
public function __construct(Parser $parser = null)
86+
{
87+
$this->parser = $parser ?: new Parser;
88+
}
9489

9590
/**
9691
* @param string $method
@@ -105,8 +100,8 @@ class Collector
105100

106101
public function set($method, $pattern, $action)
107102
{
108-
$method = $this->parseMethod($method);
109-
$patterns = $this->parsePattern($pattern);
103+
$method = $this->getValidMethod($method);
104+
$patterns = $this->parser->parsePattern($pattern);
110105
$group = new Group;
111106

112107
foreach ($patterns as $pattern)
@@ -205,87 +200,6 @@ public function forget($method, $pattern)
205200
} else unset($this->dynamics[$this->getDynamicIndex($method, $pattern)][$pattern]);
206201
}
207202

208-
/**
209-
* Determine if the http method is valid.
210-
*
211-
* @param string $method
212-
* @throws MethodNotSupportedException
213-
* @return string
214-
*/
215-
216-
protected function parseMethod($method)
217-
{
218-
$method = strtolower($method);
219-
220-
if (strpos(self::HTTP_METHODS, $method) === false) {
221-
throw new MethodNotSupportedException($method);
222-
}
223-
224-
return $method;
225-
}
226-
227-
/**
228-
* Separate routes pattern with optional parts into n new patterns.
229-
*
230-
* @param string $pattern
231-
* @return array
232-
*/
233-
234-
protected function parsePattern($pattern)
235-
{
236-
$withoutClosing = rtrim($pattern, "]");
237-
$closingNumber = strlen($pattern) - strlen($withoutClosing);
238-
239-
$segments = preg_split("~" . self::DYNAMIC_REGEX . "(*SKIP)(*F)|\[~x", $withoutClosing);
240-
$this->parseSegments($segments, $closingNumber, $withoutClosing);
241-
242-
return $this->buildSegments($segments);
243-
}
244-
245-
/**
246-
* Parse all the possible patterns seeking for an incorrect or incompatible pattern.
247-
*
248-
* @param string[] $segments Segments are all the possible patterns made on top of a pattern with optional segments.
249-
* @param int $closingNumber The count of optional segments.
250-
* @param string $withoutClosing The pattern without the closing token of an optional segment. aka: ]
251-
*
252-
* @throws BadRouteException
253-
*/
254-
255-
protected function parseSegments(array $segments, $closingNumber, $withoutClosing)
256-
{
257-
if ($closingNumber !== count($segments) - 1) {
258-
if (preg_match("~" . self::DYNAMIC_REGEX . "(*SKIP)(*F)|\]~x", $withoutClosing)) {
259-
throw new BadRouteException(BadRouteException::OPTIONAL_SEGMENTS_ON_MIDDLE);
260-
} else throw new BadRouteException(BadRouteException::UNCLOSED_OPTIONAL_SEGMENTS);
261-
}
262-
}
263-
264-
/**
265-
* @param string[] $segments
266-
*
267-
* @throws BadRouteException
268-
* @return array
269-
*/
270-
271-
protected function buildSegments(array $segments)
272-
{
273-
$pattern = "";
274-
$patterns = [];
275-
$wildcardTokens = array_keys($this->wildcards);
276-
$wildcardRegex = $this->wildcards;
277-
278-
foreach ($segments as $n => $segment) {
279-
if ($segment === "" && $n !== 0) {
280-
throw new BadRouteException(BadRouteException::EMPTY_OPTIONAL_PARTS);
281-
}
282-
283-
$patterns[] = $pattern .= str_replace($wildcardTokens, $wildcardRegex, $segment);
284-
}
285-
286-
return $patterns;
287-
}
288-
289203
/**
290204
* @param string $method
291205
* @param string $pattern
@@ -326,16 +240,33 @@ protected function getDynamicIndex($method, $pattern)
326240
return crc32(strtolower($method)) + substr_count($pattern, "/");
327241
}
328242

243+
/**
244+
* Determine if the http method is valid.
245+
*
246+
* @param string $method
247+
*
248+
* @throws MethodNotSupportedException
249+
* @return string
250+
*/
251+
252+
protected function getValidMethod($method)
253+
{
254+
$method = strtolower($method);
255+
256+
if (strpos(self::HTTP_METHODS, $method) === false) {
257+
throw new MethodNotSupportedException($method);
258+
}
259+
260+
return $method;
261+
}
262+
329263
/**
330264
* @return string[]
331265
*/
332266

333267
public function getWildcards()
334268
{
335-
$wildcards = [];
336-
foreach ($this->wildcards as $token => $regex)
337-
$wildcards[substr($token, 1)] = substr($regex, 1);
338-
return $wildcards;
269+
return $this->parser->getWildcards();
339270
}
340271

341272
/**
@@ -344,7 +275,7 @@ public function getWildcards()
344275

345276
public function getWildcardTokens()
346277
{
347-
return $this->wildcards;
278+
return $this->parser->getWildcardTokens();
348279
}
349280

350281
/**
@@ -354,7 +285,7 @@ public function getWildcardTokens()
354285

355286
public function getWildcard($wildcard)
356287
{
357-
return isset($this->wildcards[":$wildcard"]) ? substr($this->wildcards[":$wildcard"], 1) : null;
288+
return $this->parser->getWildcard($wildcard);
358289
}
359290

360291
/**
@@ -366,7 +297,33 @@ public function getWildcard($wildcard)
366297

367298
public function setWildcard($wildcard, $pattern)
368299
{
369-
$this->wildcards[":$wildcard"] = ":$pattern";
300+
$this->parser->setWildcard($wildcard, $pattern);
301+
return $this;
302+
}
303+
304+
/**
305+
* @return Parser
306+
*/
307+
308+
public function getParser()
309+
{
310+
return $this->parser;
311+
}
312+
313+
/**
314+
* @param Parser $parser
315+
*
316+
* @throws \LogicException
317+
* @return self
318+
*/
319+
320+
public function setParser(Parser $parser)
321+
{
322+
if (!empty($this->statics) || !empty($this->dynamics)) {
323+
throw new \LogicException("You can't define a route parser after registering a route.");
324+
}
325+
326+
$this->parser = $parser;
370327
return $this;
371328
}
372329

src/Collectors/ControllerCollectorTrait.php

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@
1212

1313
use Codeburner\Router\Collector;
1414
use Codeburner\Router\Group;
15+
use Codeburner\Router\Parser;
1516
use ReflectionClass;
1617
use ReflectionMethod;
1718
use ReflectionParameter;
18-
use Reflector;
1919

2020
/**
2121
* Methods for enable the collector to make routes from a controller.
@@ -26,7 +26,20 @@
2626
trait ControllerCollectorTrait
2727
{
2828

29-
abstract public function getWildcards();
29+
/**
30+
* @return Parser
31+
*/
32+
33+
abstract public function getParser();
34+
35+
/**
36+
* @param string $method
37+
* @param string $pattern
38+
* @param callable $action
39+
*
40+
* @return Group
41+
*/
42+
3043
abstract public function set($method, $pattern, $action);
3144

3245
/**
@@ -128,7 +141,6 @@ protected function collectControllerRoutes(ReflectionClass $controller, array $m
128141
$dynamic = $this->getMethodConstraints($method);
129142
$strategy = $this->getAnnotatedStrategy($method);
130143

131-
/** @var \Codeburner\Router\Route $route */
132144
$route = $this->set($http, "$action$dynamic", [$controller->name, $method->name]);
133145

134146
if ($strategy !== null) {
@@ -201,7 +213,7 @@ protected function getPathConstraint(ReflectionParameter $parameter, $types)
201213
protected function getParamsConstraint(ReflectionMethod $method)
202214
{
203215
$params = [];
204-
preg_match_all("~\@param\s(" . implode("|", array_keys($this->getWildcards())) . "|\(.+\))\s\\$([a-zA-Z0-1_]+)~i",
216+
preg_match_all("~\@param\s(" . implode("|", array_keys($this->getParser()->getWildcards())) . "|\(.+\))\s\\$([a-zA-Z0-1_]+)~i",
205217
$method->getDocComment(), $types, PREG_SET_ORDER);
206218

207219
foreach ((array) $types as $type) {

src/Collectors/ResourceCollectorTrait.php

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,12 @@
1010

1111
namespace Codeburner\Router\Collectors;
1212

13-
use Codeburner\Router\Resource;
13+
/**
14+
* Just a fix to phpstorm parser, as it intends that Resource is
15+
* a datatype of php7 and not a class in router package.
16+
*/
17+
18+
use Codeburner\Router\Resource as RouteResource;
1419

1520
/**
1621
* Methods for enable the collector to be resourceful and make
@@ -49,15 +54,15 @@ abstract public function set($method, $pattern, $action);
4954
* @param array $options Some options like, "as" to name the route pattern, "only" to
5055
* explicit say that only this routes will be registered, and
5156
* "except" that register all the routes except the indicates.
52-
* @return Resource
57+
* @return RouteResource
5358
*/
5459

5560
public function resource($controller, array $options = array())
5661
{
5762
$name = isset($options["prefix"]) ? $options["prefix"] : "";
5863
$name .= $this->getResourceName($controller, $options);
5964
$actions = $this->getResourceActions($options);
60-
$resource = new Resource;
65+
$resource = new RouteResource;
6166

6267
foreach ($actions as $action => $map) {
6368
$resource->set($this->set($map[0], $this->getResourcePath($action, $map[1], $name, $options), [$controller, $action]));
@@ -70,12 +75,12 @@ public function resource($controller, array $options = array())
7075
* Collect several resources at same time.
7176
*
7277
* @param array $controllers Several controller names as parameters or an array with all controller names.
73-
* @return Resource
78+
* @return RouteResource
7479
*/
7580

7681
public function resources(array $controllers)
7782
{
78-
$resource = new Resource;
83+
$resource = new RouteResource;
7984
foreach ($controllers as $controller)
8085
$resource->set($this->resource($controller));
8186
return $resource;

0 commit comments

Comments
 (0)