Directly support route annotations via Doctrine annotation reader.

This commit is contained in:
Buster "Silver Eagle" Neece 2020-09-07 04:47:25 -05:00
parent f5eaff1961
commit 710a291950
No known key found for this signature in database
GPG key ID: 6D9E12FF03411F4E
3 changed files with 95 additions and 0 deletions

View file

@ -27,6 +27,7 @@
"cache/array-adapter": "^1.0",
"cache/chain-adapter": "^1.0",
"cache/redis-adapter": "^1.0",
"doctrine/annotations": "^1.10",
"duncan3dc/fork-helper": "^2.0",
"friendsofphp/php-cs-fixer": "^2.0",
"fzaninotto/faker": "^1.9",

31
src/Annotations/Route.php Normal file
View file

@ -0,0 +1,31 @@
<?php declare(strict_types=1);
namespace Benzine\Annotations;
use Doctrine\Common\Annotations\Annotation\Required;
/**
* @Annotation
*
* @Target("METHOD")
*/
class Route
{
/** @var array */
public array $methods = ['GET'];
/**
* @Required
* @var string
*/
public string $path;
/** @var string */
public string $access = \Benzine\Router\Route::ACCESS_PUBLIC;
/** @var int */
public int $weight = 100;
/** @var array */
public array $domains = [];
}

View file

@ -3,6 +3,8 @@
namespace Benzine\Router;
use Cache\Adapter\Chain\CachePoolChain;
use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\Common\Annotations\AnnotationRegistry;
use Monolog\Logger;
use Slim\App;
@ -22,6 +24,67 @@ class Router
$this->cachePoolChain = $cachePoolChain;
}
public function loadRoutesFromAnnotations(
array $controllerPaths,
string $baseNamespace = null
): void {
AnnotationRegistry::registerLoader('class_exists');
$reader = new AnnotationReader();
foreach ($controllerPaths as $controllerPath) {
foreach (new \RecursiveDirectoryIterator($controllerPath) as $controllerFile) {
if ($controllerFile->isDot() || !$controllerFile->isFile() || !$controllerFile->isReadable()) {
continue;
}
$fileClassName = str_replace('.php', '', $controllerFile->getFilename());
$expectedClasses = [
$baseNamespace . '\\Controllers\\' . $fileClassName,
'Benzine\\Controllers\\' . $fileClassName,
];
foreach ($expectedClasses as $expectedClass) {
if (!class_exists($expectedClass)) {
continue;
}
$rc = new \ReflectionClass($expectedClass);
if ($rc->isAbstract()) {
continue;
}
foreach ($rc->getMethods() as $method) {
if (!$method->isPublic()) {
continue;
}
$routeAnnotation = $reader->getMethodAnnotation($method, \Benzine\Annotations\Route::class);
if (!($routeAnnotation instanceof \Benzine\Annotations\Route)) {
continue;
}
foreach($routeAnnotation->methods as $httpMethod) {
$newRoute = new Route($this->logger);
$newRoute
->setHttpMethod($httpMethod)
->setRouterPattern('/' . ltrim($routeAnnotation->path, '/'))
->setCallback($method->class . ':' . $method->name)
->setWeight($routeAnnotation->weight);
foreach ($routeAnnotation->domains as $domain) {
$newRoute->addValidDomain($domain);
}
$this->addRoute($newRoute);
}
}
}
}
}
}
public function weighRoutes(): Router
{
$allocatedRoutes = [];