2020-06-12 13:57:36 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace Benzine\Router;
|
|
|
|
|
|
2020-07-27 01:31:04 +00:00
|
|
|
use Cache\Adapter\Chain\CachePoolChain;
|
2020-06-12 13:57:36 +00:00
|
|
|
use Monolog\Logger;
|
2020-06-18 17:24:31 +00:00
|
|
|
use Slim\App;
|
2020-06-12 13:57:36 +00:00
|
|
|
|
|
|
|
|
class Router
|
|
|
|
|
{
|
|
|
|
|
/** @var Route[] */
|
2020-07-31 21:10:39 +00:00
|
|
|
private array $routes = [];
|
2020-07-27 01:31:04 +00:00
|
|
|
private Logger $logger;
|
|
|
|
|
private CachePoolChain $cachePoolChain;
|
|
|
|
|
private int $cacheTTL = 60;
|
2020-06-12 13:57:36 +00:00
|
|
|
|
2020-08-06 17:48:55 +00:00
|
|
|
private bool $routesArePopulated = false;
|
|
|
|
|
|
2020-07-27 01:31:04 +00:00
|
|
|
public function __construct(\Redis $redis, Logger $logger, CachePoolChain $cachePoolChain)
|
2020-06-12 13:57:36 +00:00
|
|
|
{
|
2020-07-27 01:31:04 +00:00
|
|
|
$this->logger = $logger;
|
|
|
|
|
$this->cachePoolChain = $cachePoolChain;
|
2020-06-12 13:57:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function weighRoutes(): Router
|
|
|
|
|
{
|
|
|
|
|
$allocatedRoutes = [];
|
|
|
|
|
if (is_array($this->routes) && count($this->routes) > 0) {
|
|
|
|
|
uasort($this->routes, function (Route $a, Route $b) {
|
|
|
|
|
return $a->getWeight() > $b->getWeight();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
foreach ($this->routes as $index => $route) {
|
2020-07-31 21:10:39 +00:00
|
|
|
if (($route->isInContainedInValidDomains() || !$route->hasValidDomains())
|
|
|
|
|
&& !isset($allocatedRoutes[$route->getHttpMethod().$route->getRouterPattern()])) {
|
2020-06-12 13:57:36 +00:00
|
|
|
$allocatedRoutes[$route->getHttpMethod().$route->getRouterPattern()] = true;
|
|
|
|
|
} else {
|
|
|
|
|
unset($this->routes[$index]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function populateRoutes(App $app)
|
|
|
|
|
{
|
2020-08-06 17:48:55 +00:00
|
|
|
if ($this->routesArePopulated) {
|
|
|
|
|
return $app;
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-12 13:57:36 +00:00
|
|
|
$this->weighRoutes();
|
|
|
|
|
if (count($this->routes) > 0) {
|
2020-07-31 21:10:39 +00:00
|
|
|
foreach ($this->getRoutes() as $route) {
|
2020-06-12 13:57:36 +00:00
|
|
|
$app = $route->populateRoute($app);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-06 17:48:55 +00:00
|
|
|
$this->routesArePopulated = true;
|
|
|
|
|
|
2020-06-12 13:57:36 +00:00
|
|
|
return $app;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function addRoute(Route $route)
|
|
|
|
|
{
|
|
|
|
|
$this->routes[$route->getUniqueIdentifier()] = $route;
|
|
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return Route[]
|
|
|
|
|
*/
|
|
|
|
|
public function getRoutes()
|
|
|
|
|
{
|
|
|
|
|
return $this->routes;
|
|
|
|
|
}
|
2020-07-27 01:31:04 +00:00
|
|
|
|
|
|
|
|
public function loadCache(): bool
|
|
|
|
|
{
|
|
|
|
|
$time = microtime(true);
|
|
|
|
|
$cacheItem = $this->cachePoolChain->getItem('routes');
|
|
|
|
|
if (!$cacheItem || null === $cacheItem->get()) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
$this->routes = $cacheItem->get();
|
|
|
|
|
$this->logger->debug(sprintf('Loaded routes from Cache in %sms', number_format((microtime(true) - $time) * 1000, 2)));
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function cache(): Router
|
|
|
|
|
{
|
|
|
|
|
$routeItem = $this->cachePoolChain
|
|
|
|
|
->getItem('routes')
|
|
|
|
|
->set($this->getRoutes())
|
|
|
|
|
->expiresAfter($this->cacheTTL)
|
|
|
|
|
;
|
|
|
|
|
$this->cachePoolChain->save($routeItem);
|
|
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
|
}
|
2020-06-12 13:57:36 +00:00
|
|
|
}
|