- WIP on native attributes

This commit is contained in:
Dave M. 2023-01-19 01:46:58 +00:00
parent 3bebb66ad4
commit 83858164dc
4 changed files with 122 additions and 18 deletions

View File

@ -24,6 +24,8 @@ class Route implements \Notes\Annotation {
public string $classMethod;
public bool $currentRoute = false;
public function __construct($route = null, $name = null, $method = null)
{
if ( $route !== null ) {
@ -55,4 +57,8 @@ class Route implements \Notes\Annotation {
public function isRoute(string $name) {
return $this->name === $name;
}
public function currentRoute(bool|null $value = null ) {
return is_null($value) ? $value : $this->currentRoute = $value;
}
}

View File

@ -0,0 +1,38 @@
<?php
namespace Notes\Route\Attribute\Method;
#[\Attribute]
class Route implements \Notes\Attribute {
public function __construct(
public string $name,
public string $route,
public string|array $method = [ "GET", "POST" ],
public string $base = "",
public ? string $class = null,
public ? string $classMethod = null,
public bool $currentRoute = false,
) {}
public function getRoute() : string
{
return rtrim("/" . trim(isset($this->base) ?
"/" . trim($this->base, "/") . "/" . ltrim($this->route, "/")
:
"/" . ltrim($this->route, "/"), "/"), '/');
}
public function matchRouteName(string $name) : bool
{
return strtolower($this->name) === strtolower($name);
}
public function isRoute(string $name) {
return $this->name === $name;
}
public function currentRoute(bool|null $value = null ) {
return is_null($value) ? $value : $this->currentRoute = $value;
}
}

View File

@ -0,0 +1,11 @@
<?php
namespace Notes\Route\Attribute\Object;
#[\Attribute]
class Route implements \Notes\Annotation {
public function __construct(
public string|array $method = [ "GET", "POST" ],
public string $base = "",
){}
}

View File

@ -7,6 +7,10 @@ use RuntimeException, DirectoryIterator, Generator, Closure;
class RouteFetcher {
public array $list = [];
protected bool $debug;
protected array $folderList;
protected Closure $callback;
@ -15,8 +19,11 @@ class RouteFetcher {
protected array $annotations;
public function __construct(?Closure $callback = null, ?array $folderList = null, ?array $annotations = null)
public function __construct(?Closure $callback = null, ? array $folderList = null, ? array $annotations = null, bool $debug = false)
{
// Handles if we must fetch or store in cache
$this->debug = $debug;
if ($callback !== null) {
$this->callback = $callback;
}
@ -36,6 +43,18 @@ class RouteFetcher {
}
}
public function __destruct() {
if ($this->debug) {
foreach ($this->list as $key => $item) {
$cacheKey = sprintf("%s:routes.%s", basename(__CLASS__), $key);
if (function_exists('apcu_enabled') && apcu_enabled()) {
apcu_store($cacheKey, $item, 3600);
}
}
}
}
public function addFolder($folder) : void
{
$this->folderList[] = $folder;
@ -68,8 +87,14 @@ class RouteFetcher {
}
}
public function compile() : Generator
public function compile(null|array $annotations = null) : array
{
$annotations ??= $this->annotations;
if ( $cacheValue = $this->fetchFromCache($this->generateListKey($annotations)) ) {
return $cacheValue;
}
foreach($this->scan() as $namespace => $file) {
if ( $file->getExtension() !== "php" ) {
continue;
@ -79,10 +104,9 @@ class RouteFetcher {
$class = $this->generateClassname($file->getBasename(".php"), $namespace);
$methods = $this->defaultMethods;
# Should generate an equivalent of Ulmus's object reflection here !
$objectResolver = new ObjectResolver($class, true, true, false, true);
if ( null !== ( $object = $objectResolver->getAnnotationFromClassname( $this->annotations['object'] ) ) ) {
if ( isset($annotations['object']) && (null !== ( $object = $objectResolver->getAnnotationFromClassname($annotations['object']) )) ){
if ( $object->methods ?? false ) {
$methods = $object->methods;
}
@ -90,26 +114,51 @@ class RouteFetcher {
$base = $object->base ?? "";
}
$routeList = $objectResolver->getAnnotationListFromClassname( $this->annotations['method'] );
if ( isset($annotations['method']) ) {
$routeList = $objectResolver->getAnnotationListFromClassname( $annotations['method'] );
foreach($routeList as $func => $routes) {
foreach($routes as $route) {
$route->base = $base;
$route->class = $class;
$route->classMethod = $func;
foreach($routeList as $func => $routes) {
foreach($routes as $route) {
$route->base = $base;
$route->class = $class;
$route->classMethod = $func;
if (false === ($route->methods ?? false)) {
$route->methods = $methods;
if (false === ($route->methods ?? false)) {
$route->methods = $methods;
}
if (false !== ($this->callback ?? false)) {
call_user_func_array($this->callback, [ $route ]);
}
$list[] = $route;
}
if (false !== ($this->callback ?? false)) {
call_user_func_array($this->callback, [$route]);
}
yield $route;
}
}
}
return $this->debug ? $this->list[$this->generateListKey($annotations)] = $list : $list;
}
protected function fetchFromCache(string $key) : array|null
{
if (! $this->debug) {
if (!isset($this->list[$key]) && function_exists('apcu_enabled') && apcu_enabled()) {
$cacheKey = sprintf("%s:routes.%s", basename(__CLASS__), $key);
$fetch = apcu_fetch($cacheKey, $success);
if ($success) {
return $fetch;
}
}
}
return $this->list[$key] ?? null;
}
protected function generateListKey(array $annotations) {
return ($annotations['object'] ?? "") . ($annotations['method'] ?? "");
}
protected function generateClassname($file, $namespace)