diff --git a/Annotation/Annotation.php b/Annotation/Annotation.php index 22243b68..4d79eae0 100644 --- a/Annotation/Annotation.php +++ b/Annotation/Annotation.php @@ -22,6 +22,9 @@ class Annotation extends Component private array $_annotations = []; + private array $_classes = []; + + private array $_targets = []; @@ -100,50 +103,99 @@ class Annotation extends Component */ private function getReflect(string $class, string $alias): array { - $reflect = Snowflake::getDi()->getReflect($class); - if (!$reflect->isInstantiable()) { + $reflect = $this->reflectClass($class); + if ($reflect->isInstantiable()) { + $object = $reflect->newInstance(); + foreach ($reflect->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) { + $tmp = $this->resolveAnnotations($method, $alias, $object); + + $this->_classes[$reflect->getName()][$method->getName()] = $tmp; + } + } + return $this->targets($reflect); + } + + + /** + * @param string $class + * @return ReflectionClass + * @throws ReflectionException + */ + private function reflectClass(string $class): ReflectionClass + { + return Snowflake::getDi()->getReflect($class); + } + + + /** + * @param $method + * @param $alias + * @param $object + * @return array + */ + private function resolveAnnotations($method, $alias, $object): array + { + $attributes = $method->getAttributes(); + if (count($attributes) < 1) { return []; } - $this->targets($reflect); - - $annotations = []; - $object = $reflect->newInstance(); - foreach ($reflect->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) { - $names = []; - $attributes = $method->getAttributes(); - if (count($attributes) < 1) { - continue; - } - foreach ($attributes as $attribute) { - $names[$attribute->getName()] = $this->instance($attribute); - } - - $tmp['handler'] = [$object, $method->getName()]; - $tmp['attributes'] = $names; - - $this->_annotations[$alias][] = $tmp; + $names = []; + foreach ($attributes as $attribute) { + $names[$attribute->getName()] = $this->instance($attribute); } - return $annotations; + + $tmp['handler'] = [$object, $method->getName()]; + $tmp['attributes'] = $names; + + $this->_annotations[$alias][] = $tmp; + + return $tmp; } + + /** + * @param $className + * @param string $method + * @return array + */ + public function getByClass($className, $method = ''): array + { + if (!isset($this->_classes[$className])) { + return []; + } + if (empty($method)) { + return $this->_classes[$className]; + } + foreach ($this->_classes[$className] as $_method => $class) { + if ($method == $_method) { + return [$class]; + } + } + return []; + } + + /** * @param ReflectionClass $reflect + * @return array */ - private function targets(ReflectionClass $reflect) + private function targets(ReflectionClass $reflect): array { + $name = $reflect->getName(); + if (!isset($this->_classes[$name])) { + $this->_classes[$name] = []; + } $attributes = $reflect->getAttributes(); - if (count($attributes) < 1) { - return; - } - - if (!isset($this->_targets[$reflect->getName()])) { - $this->_targets[$reflect->getName()] = []; - } - - foreach ($attributes as $attribute) { - $this->_targets[$reflect->getName()][] = $this->instance($attribute); + if (count($attributes) > 0) { + if (!isset($this->_targets[$name])) { + $this->_targets[$name] = []; + } + foreach ($attributes as $attribute) { + $this->_targets[$name][] = $this->instance($attribute); + } } + return []; } diff --git a/Annotation/RequestValidator.php b/Annotation/RequestValidator.php index edcc6c42..5e2ed4d7 100644 --- a/Annotation/RequestValidator.php +++ b/Annotation/RequestValidator.php @@ -4,6 +4,9 @@ namespace Annotation; +use Exception; +use validator\Validator; + /** * Class RequestValidator * @package Annotation @@ -14,6 +17,7 @@ namespace Annotation; /** * RequestValidator constructor. * @param array $validators + * @throws Exception */ public function __construct(public array $validators) { diff --git a/Annotation/Route/After.php b/Annotation/Route/After.php index cae2f41c..074a3698 100644 --- a/Annotation/Route/After.php +++ b/Annotation/Route/After.php @@ -4,6 +4,8 @@ namespace Annotation\Route; +use Snowflake\Snowflake; + /** * Class Interceptor * @package Annotation\Route @@ -15,9 +17,16 @@ namespace Annotation\Route; /** * Interceptor constructor. * @param \HttpServer\IInterface\After|\HttpServer\IInterface\After[] $after + * @throws */ public function __construct(public string|array $after) { + if (is_string($this->after)) { + $this->after = [$this->after]; + } + foreach ($this->after as $key => $item) { + $this->after[$key] = Snowflake::createObject($item); + } } } diff --git a/Annotation/Route/Interceptor.php b/Annotation/Route/Interceptor.php index 9277b289..a0ef0448 100644 --- a/Annotation/Route/Interceptor.php +++ b/Annotation/Route/Interceptor.php @@ -4,6 +4,8 @@ namespace Annotation\Route; +use Snowflake\Snowflake; + /** * Class Interceptor * @package Annotation\Route @@ -15,9 +17,16 @@ namespace Annotation\Route; /** * Interceptor constructor. * @param string|array $interceptor + * @throws */ public function __construct(public string|array $interceptor) { + if (is_string($this->interceptor)) { + $this->interceptor = [$this->interceptor]; + } + foreach ($this->interceptor as $key => $item) { + $this->interceptor[$key] = Snowflake::createObject($item); + } } } diff --git a/Annotation/Route/Limits.php b/Annotation/Route/Limits.php index d084d5ba..fd5e3080 100644 --- a/Annotation/Route/Limits.php +++ b/Annotation/Route/Limits.php @@ -4,6 +4,8 @@ namespace Annotation\Route; +use Snowflake\Snowflake; + /** * Class Limits * @package Annotation\Route @@ -15,9 +17,16 @@ namespace Annotation\Route; /** * Limits constructor. * @param string|array $limits + * @throws */ public function __construct(public string|array $limits) { + if (is_string($this->limits)) { + $this->limits = [$this->limits]; + } + foreach ($this->limits as $key => $item) { + $this->limits[$key] = Snowflake::createObject($item); + } } diff --git a/Annotation/Route/Middleware.php b/Annotation/Route/Middleware.php index 3ca0a5b1..d2086eb4 100644 --- a/Annotation/Route/Middleware.php +++ b/Annotation/Route/Middleware.php @@ -4,6 +4,8 @@ namespace Annotation\Route; +use Snowflake\Snowflake; + /** * Class Middleware * @package Annotation\Route @@ -15,9 +17,16 @@ namespace Annotation\Route; /** * Interceptor constructor. * @param string|array $middleware + * @throws */ public function __construct(public string|array $middleware) { + if (is_string($this->middleware)) { + $this->middleware = [$this->middleware]; + } + foreach ($this->middleware as $key => $item) { + $this->middleware[$key] = Snowflake::createObject($item); + } } } diff --git a/HttpServer/Route/Middleware.php b/HttpServer/Route/Middleware.php index c2c8350d..0d63b875 100644 --- a/HttpServer/Route/Middleware.php +++ b/HttpServer/Route/Middleware.php @@ -7,12 +7,15 @@ */ declare(strict_types=1); -// declare(strict_types=1); - namespace HttpServer\Route; +use Annotation\Route\After; +use Annotation\Route\Interceptor; +use Annotation\Route\Middleware as RMiddleware; use Exception; +use Annotation\Route\Limits; use HttpServer\Route\Dispatch\Dispatch; +use Snowflake\Snowflake; /** * Class Middleware @@ -51,12 +54,41 @@ class Middleware */ public function getGenerate(Node $node): mixed { + if (is_array($node->handler) && is_object($node->handler[0])) { + $this->set_attributes($node); + } return $node->callback = Reduce::reduce(function () use ($node) { return Dispatch::create($node->handler, func_get_args())->dispatch(); }, $this->annotation($node)); } + /** + * @param $node + * @throws Exception + */ + private function set_attributes(Node $node) + { + [$controller, $action] = $node->handler; + $attributes = Snowflake::app()->getAttributes(); + $annotation = $attributes->getByClass(get_class($controller), $action); + foreach ($annotation as $item) { + if ($item instanceof Interceptor) { + $node->addInterceptor($item->interceptor); + } + if ($item instanceof After) { + $node->addAfter($item->after); + } + if ($item instanceof RMiddleware) { + $node->addMiddleware($item->middleware); + } + if ($item instanceof Limits) { + $node->addLimits($item->limits); + } + } + } + + /** * @param Node $node * @return array