Implemented changes requested by FuzeWorks\Application

- Added Priorities to the routes array. Routes can now be saved with priorities, making higher priority routes load before lower priorities
- Fixed bug where callable is not reset upon attempting routing a new route after another was not satisfied
This commit is contained in:
Abel Hoogeveen 2019-03-04 21:33:38 +01:00
parent be414aa2cd
commit f49c5dd882
No known key found for this signature in database
GPG Key ID: 96C2234920BF4292
2 changed files with 76 additions and 63 deletions

View File

@ -156,7 +156,14 @@ class Router
}
}
public function addRoute(string $route, $routeConfig = null, bool $prepend = true)
/**
* Add a route to the Router
*
* @param string $route
* @param null $routeConfig
* @param int $priority
*/
public function addRoute(string $route, $routeConfig = null, int $priority = Priority::NORMAL)
{
// Set defaultCallable if no value provided
if (is_null($routeConfig))
@ -165,23 +172,27 @@ class Router
// Convert wildcards to Regex
$route = str_replace([':any',':num'], ['[^/]+', '[0-9]+'], $route);
if ($prepend)
$this->routes = [$route => $routeConfig] + $this->routes;
else
$this->routes[$route] = $routeConfig;
if (!isset($this->routes[$priority]))
$this->routes[$priority] = [];
Logger::log('Route added at '.($prepend ? 'top' : 'bottom').': "'.$route.'"');
if (!isset($this->routes[$priority][$route]))
$this->routes[$priority][$route] = $routeConfig;
Logger::log('Route added with ' . Priority::getPriority($priority) . ": '" . $route."'");
}
/**
* Removes a route from the array based on the given route.
*
* @param $route string The route to remove
* @param int $priority
*/
public function removeRoute(string $route)
public function removeRoute(string $route, int $priority = Priority::NORMAL)
{
unset($this->routes[$route]);
if (!isset($this->routes[$priority][$route]))
return;
unset($this->routes[$priority][$route]);
Logger::log('Route removed: '.$route);
}
@ -194,17 +205,22 @@ class Router
*/
public function route(string $path)
{
// Check all the provided custom paths
foreach ($this->routes as $route => $routeConfig)
// Check all the provided custom paths, ordered by priority
for ($i=Priority::getHighestPriority(); $i<=Priority::getLowestPriority(); $i++) {
if (!isset($this->routes[$i]))
continue;
foreach ($this->routes[$i] as $route => $routeConfig)
{
// Match the path against the routes
if (!preg_match('#^'.$route.'$#', $path, $matches))
continue;
// Save the matches
Logger::log('Route matched: '.$route);
Logger::log("Route matched: '" . $route . "' with " . Priority::getPriority($i));
$this->matches = $matches;
$this->route = $route;
$this->callable = null;
// Call callable if routeConfig is callable, so routeConfig can be replaced
// This is an example of 'Dynamic Rewrite'
@ -243,6 +259,7 @@ class Router
return $output;
}
}
throw new NotFoundException("Could not load view. Router could not find matching route with satisfied callable.");
}
@ -387,12 +404,13 @@ class Router
/**
* Returns an array with all the routes.
*
* @param int $priority
* @return array
* @codeCoverageIgnore
*/
public function getRoutes(): array
public function getRoutes(int $priority = Priority::NORMAL): array
{
return $this->routes;
return $this->routes[$priority];
}
/**

View File

@ -120,19 +120,14 @@ class RouterTest extends MVCRTestAbstract
$testAppendRouteFunction = [function () {
}];
$this->router->addRoute('testRoute', $testRouteFunction);
$this->router->addRoute('testAppendRoute', $testAppendRouteFunction, false);
$this->router->addRoute('testAppendRoute', $testAppendRouteFunction, Priority::LOW);
// Test if the order is correct
$this->assertSame(
['testRoute' => $testRouteFunction, 'testAppendRoute' => $testAppendRouteFunction],
$this->router->getRoutes()
);
// First for Priority::NORMAL
$this->assertSame(['testRoute' => $testRouteFunction], $this->router->getRoutes(Priority::NORMAL));
// Test if the order is not incorrect
$this->assertNotSame(
['testAppendRoute' => $testAppendRouteFunction, 'testRoute' => $testRouteFunction],
$this->router->getRoutes()
);
// Then for Priority::LOW
$this->assertSame(['testAppendRoute' => $testAppendRouteFunction], $this->router->getRoutes(Priority::LOW));
}
/**