Compare commits
10 Commits
1393e0face
...
053d4f30b2
Author | SHA1 | Date | |
---|---|---|---|
053d4f30b2 | |||
|
bf6da3b990 | ||
|
241d652283 | ||
|
6ecb416155 | ||
|
f85ca7666a | ||
|
ae61bee272 | ||
|
bf56160b33 | ||
|
227e5edc06 | ||
|
3dd5ddc83e | ||
|
d0bef18c59 |
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,4 +1,4 @@
|
||||||
.DS_Store
|
.DS_Store
|
||||||
._*
|
._*
|
||||||
/vendor/
|
/vendor/
|
||||||
/src/Splashsky/test.php
|
/test.php
|
|
@ -5,11 +5,11 @@ namespace Splashsky;
|
||||||
class Router
|
class Router
|
||||||
{
|
{
|
||||||
private static array $routes = [];
|
private static array $routes = [];
|
||||||
private static array $constraints = [];
|
|
||||||
private static $pathNotFound;
|
private static $pathNotFound;
|
||||||
private static $methodNotAllowed;
|
private static $methodNotAllowed;
|
||||||
private static string $defaultConstraint = '([\w\-]+)';
|
private static string $defaultConstraint = '([\w\-]+)';
|
||||||
private static string $currentPrefix = '';
|
private static string $currentPrefix = '';
|
||||||
|
private static string $lastInsertedRoute = '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A quick static function to register a route in the router. Used by the shorthand methods as well.
|
* A quick static function to register a route in the router. Used by the shorthand methods as well.
|
||||||
|
@ -26,12 +26,17 @@ class Router
|
||||||
$route = self::$currentPrefix.$route;
|
$route = self::$currentPrefix.$route;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$trimmed = self::trimRoute($route);
|
||||||
|
|
||||||
self::$routes[] = [
|
self::$routes[] = [
|
||||||
'route' => $route,
|
'route' => $trimmed,
|
||||||
'action' => $action,
|
'action' => $action,
|
||||||
'methods' => $methods
|
'methods' => $methods,
|
||||||
|
'constraints' => []
|
||||||
];
|
];
|
||||||
|
|
||||||
|
self::$lastInsertedRoute = $trimmed;
|
||||||
|
|
||||||
return new self;
|
return new self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,6 +107,12 @@ class Router
|
||||||
self::$defaultConstraint = $constraint;
|
self::$defaultConstraint = $constraint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static function trimRoute(string $route): string
|
||||||
|
{
|
||||||
|
$route = trim(trim($route), '/');
|
||||||
|
return "/$route";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Accepts a callable that defines routes, and adds a prefix to them.
|
* Accepts a callable that defines routes, and adds a prefix to them.
|
||||||
*
|
*
|
||||||
|
@ -130,15 +141,17 @@ class Router
|
||||||
*/
|
*/
|
||||||
public static function with(string|array $parameter, string $constraint = '')
|
public static function with(string|array $parameter, string $constraint = '')
|
||||||
{
|
{
|
||||||
|
$last = self::$lastInsertedRoute;
|
||||||
|
|
||||||
if (is_array($parameter)) {
|
if (is_array($parameter)) {
|
||||||
foreach ($parameter as $param => $constraint) {
|
foreach ($parameter as $param => $constraint) {
|
||||||
self::$constraints[$param] = $constraint;
|
self::$routes[$last]['constraints'][$param] = $constraint;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new self;
|
return new self;
|
||||||
}
|
}
|
||||||
|
|
||||||
self::$constraints[$parameter] = $constraint;
|
self::$routes[$last]['constraints'][$parameter] = $constraint;
|
||||||
|
|
||||||
return new self;
|
return new self;
|
||||||
}
|
}
|
||||||
|
@ -149,9 +162,9 @@ class Router
|
||||||
* @param string $uri
|
* @param string $uri
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
private static function tokenize(string $uri)
|
private static function tokenize(string $uri, array $constraints)
|
||||||
{
|
{
|
||||||
$constraints = array_keys(self::$constraints);
|
$constraintKeys = array_keys($constraints);
|
||||||
|
|
||||||
preg_match_all('/(?:{([\w\-]+)})+/', $uri, $matches);
|
preg_match_all('/(?:{([\w\-]+)})+/', $uri, $matches);
|
||||||
$matches = $matches[1];
|
$matches = $matches[1];
|
||||||
|
@ -159,8 +172,11 @@ class Router
|
||||||
foreach ($matches as $match) {
|
foreach ($matches as $match) {
|
||||||
$pattern = '{'.$match.'}';
|
$pattern = '{'.$match.'}';
|
||||||
|
|
||||||
if (in_array($match, $constraints)) {
|
if (in_array($match, $constraintKeys)) {
|
||||||
$uri = str_replace($pattern, '('.self::$constraints[$match].')', $uri);
|
// Do some voodoo to allow users to use parentheses in their constraints if they want
|
||||||
|
$constraint = '('.rtrim(ltrim(trim($constraints[$match]), '('), ')').')';
|
||||||
|
|
||||||
|
$uri = str_replace($pattern, $constraint, $uri);
|
||||||
} else {
|
} else {
|
||||||
$uri = str_replace($pattern, self::$defaultConstraint, $uri);
|
$uri = str_replace($pattern, self::$defaultConstraint, $uri);
|
||||||
}
|
}
|
||||||
|
@ -179,27 +195,23 @@ class Router
|
||||||
*/
|
*/
|
||||||
public static function run(string $basePath = '', bool $multimatch = false)
|
public static function run(string $basePath = '', bool $multimatch = false)
|
||||||
{
|
{
|
||||||
$basePath = rtrim($basePath, '/');
|
$basePath = self::trimRoute($basePath);
|
||||||
$method = $_SERVER['REQUEST_METHOD'];
|
$method = $_SERVER['REQUEST_METHOD'];
|
||||||
$uri = parse_url($_SERVER['REQUEST_URI'])['path'];
|
$uri = parse_url($_SERVER['REQUEST_URI'])['path'];
|
||||||
$path = urldecode(rtrim($uri, '/'));
|
$path = urldecode(self::trimRoute($uri));
|
||||||
|
|
||||||
// If the path is empty (no slash in URI) place one to satisfy the root route ('/')
|
|
||||||
if (empty($path)) {
|
|
||||||
$path = '/';
|
|
||||||
}
|
|
||||||
|
|
||||||
$pathMatchFound = false;
|
$pathMatchFound = false;
|
||||||
$routeMatchFound = false;
|
$routeMatchFound = false;
|
||||||
|
|
||||||
// Begin looking through routes
|
// Begin looking through routes
|
||||||
foreach (self::$routes as $route) {
|
foreach (self::$routes as $route) {
|
||||||
if ($basePath != '' && $basePath != '/') {
|
// If the basePath isn't just "root"
|
||||||
$route['route'] = $basePath.$route['route'];
|
if ($basePath != '/') {
|
||||||
|
$route['route'] = self::trimRoute($basePath.$route['route']);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare route by tokenizing.
|
// Prepare route by tokenizing.
|
||||||
$tokenized = '#^'.self::tokenize($route['route']).'$#u';
|
$tokenized = '#^'.self::tokenize($route['route'], $route['constraints']).'$#u';
|
||||||
|
|
||||||
// If the tokenized route matches the current path...
|
// If the tokenized route matches the current path...
|
||||||
if (preg_match($tokenized, $path, $matches)) {
|
if (preg_match($tokenized, $path, $matches)) {
|
Loading…
Reference in New Issue
Block a user