Skip to content

Commit 2366121

Browse files
author
Skylear
authored
Merge pull request #6 from splashsky/allow-regex-constraints
No issues found in functionality after testing. Merging!
2 parents 80a4769 + 0890106 commit 2366121

File tree

1 file changed

+101
-4
lines changed

1 file changed

+101
-4
lines changed

src/Splashsky/Router.php

Lines changed: 101 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,18 @@
55
class Router
66
{
77
private static array $routes = [];
8+
private static array $constraints = [];
89
private static $pathNotFound;
910
private static $methodNotAllowed;
11+
private static string $defaultConstraint = '([\w\-]+)';
1012

1113
/**
1214
* A quick static function to register a route in the router. Used by the shorthand methods as well.
15+
*
1316
* @param string $route The path to be used as the route.
1417
* @param callable|string $action Either a callable to be executed, or a string reference to a method.
1518
* @param string|array $methods The HTTP verb(s) this route accepts.
19+
* @return Router
1620
*/
1721
public static function add(string $route, callable|string $action, string|array $methods = 'GET')
1822
{
@@ -21,43 +25,136 @@ public static function add(string $route, callable|string $action, string|array
2125
'action' => $action,
2226
'methods' => $methods
2327
];
28+
29+
return new self;
2430
}
2531

32+
/**
33+
* Shorthand function to define a GET route
34+
*
35+
* @param string $route
36+
* @param callable $action
37+
*/
2638
public static function get(string $route, callable $action)
2739
{
28-
self::add($route, $action, 'GET');
40+
return self::add($route, $action, 'GET');
2941
}
3042

43+
/**
44+
* Default function to define a POST route
45+
*
46+
* @param string $route
47+
* @param callable $action
48+
*/
3149
public static function post(string $route, callable $action)
3250
{
33-
self::add($route, $action, 'POST');
51+
return self::add($route, $action, 'POST');
3452
}
3553

54+
/**
55+
* Return all routes currently registered
56+
*
57+
* @return array
58+
*/
3659
public static function getAllRoutes()
3760
{
3861
return self::$routes;
3962
}
4063

64+
/**
65+
* Defines an action to be called when a path isn't found - i.e. a 404
66+
*
67+
* @param callable $action
68+
*/
4169
public static function pathNotFound(callable $action)
4270
{
4371
self::$pathNotFound = $action;
4472
}
4573

74+
/**
75+
* Defines an action to be called with a method isn't allowed on a route - i.e. a 405
76+
*
77+
* @param callable $action
78+
*/
4679
public static function methodNotAllowed(callable $action)
4780
{
4881
self::$methodNotAllowed = $action;
4982
}
5083

84+
/**
85+
* Redefine the default constraint for route parameters. Default is '([\w\-]+)'
86+
*
87+
* @param string $constraint The RegEx you want parameters to adhere to by default. Defaults to '([\w\-]+)'
88+
* @return void
89+
*/
90+
public static function setDefaultConstraint(string $constraint = '([\w\-]+)')
91+
{
92+
self::$defaultConstraint = $constraint;
93+
}
94+
95+
/**
96+
* Define a constraint for a route parameter. If only passing one parameter,
97+
* provide the parameter name as first argument and constraint as second. If
98+
* adding constraints for multiple parameters, pass an array of 'parameter' => 'constraint'
99+
* pairs.
100+
*
101+
* @param string|array $parameter
102+
* @param string $constraint
103+
* @return Router
104+
*/
105+
public static function with(string|array $parameter, string $constraint = '')
106+
{
107+
if (is_array($parameter)) {
108+
foreach ($parameter as $param => $constraint) {
109+
self::$constraints[$param] = $constraint;
110+
}
111+
112+
return new self;
113+
}
114+
115+
self::$constraints[$parameter] = $constraint;
116+
117+
return new self;
118+
}
119+
120+
/**
121+
* Tokenizes the given URI using our constraint rules and returns the tokenized URI
122+
*
123+
* @param string $uri
124+
* @return string
125+
*/
51126
private static function tokenize(string $uri)
52127
{
53-
return preg_replace('/(?:{([A-Za-z]+)})+/', '([\w]+)', $uri);
128+
$constraints = array_keys(self::$constraints);
129+
130+
preg_match_all('/(?:{([\w\-]+)})+/', $uri, $matches);
131+
$matches = $matches[1];
132+
133+
foreach ($matches as $match) {
134+
$pattern = "/(?:{".$match."})+/";
135+
136+
if (in_array($match, $constraints)) {
137+
$uri = preg_replace($pattern, '('.self::$constraints[$match].')', $uri);
138+
} else {
139+
$uri = preg_replace($pattern, self::$defaultConstraint, $uri);
140+
}
141+
}
142+
143+
return $uri;
54144
}
55145

146+
/**
147+
* Runs the router. Accepts a base path from which to serve the routes, and optionally whether you want to try
148+
* and match multiple routes.
149+
*
150+
* @param string $basePath
151+
* @param boolean $multimatch
152+
*/
56153
public static function run(string $basePath = '', bool $multimatch = false)
57154
{
58155
$basePath = rtrim($basePath, '/');
59-
$uri = parse_url($_SERVER['REQUEST_URI'])['path'];
60156
$method = $_SERVER['REQUEST_METHOD'];
157+
$uri = parse_url($_SERVER['REQUEST_URI'])['path'];
61158
$path = urldecode(rtrim($uri, '/'));
62159

63160
// If the path is empty (no slash in URI) place one to satisfy the root route ('/')

0 commit comments

Comments
 (0)