This commit is contained in:
2020-12-14 19:03:05 +08:00
parent e284c5d324
commit 4549364baf
9 changed files with 389 additions and 2 deletions
+33
View File
@@ -0,0 +1,33 @@
<?php
namespace Annotation;
use Closure;
#[\Attribute(\Attribute::TARGET_METHOD)] class After
{
/**
* Middleware constructor.
* @param string|array $handler
*/
public function __construct(
private string|array $handler
)
{
}
/**
* @return array|string
*/
public function getMiddleware(): array|string
{
return $this->handler;
}
}
+161
View File
@@ -0,0 +1,161 @@
<?php
namespace Annotation;
use ReflectionAttribute;
use ReflectionException;
use Snowflake\Abstracts\Component;
use Snowflake\Snowflake;
/**
* Class Annotation
* @package Annotation
*/
class Annotation extends Component
{
private array $_annotations = [];
private array $_targets = [];
/**
* @param string $path
* @param string $alias
* @return $this
* @throws ReflectionException
*/
public function readControllers(string $path, string $alias = 'root'): static
{
foreach (glob($path . '/*') as $dir) {
$this->scanDir($dir, $alias);
}
return $this;
}
/**
* @param string $alias
* @return array
*/
public function getAlias(string $alias = 'root'): array
{
if (!isset($this->_annotations[$alias])) {
return [];
}
return $this->_annotations[$alias];
}
/**
* @param string $target
* @return mixed
*/
public function getTarget(string $target): mixed
{
if (!isset($this->_targets[$target])) {
return [];
}
return $this->_targets[$target];
}
/**
* @param array $paths
* @param string $alias
* @return $this
* @throws ReflectionException
*/
private function scanDir(array $paths, string $alias): static
{
if (!isset($this->_annotations[$alias])) {
$this->_annotations[$alias] = [];
}
foreach ($paths as $path) {
if (is_file($path)) {
$this->_annotations[$alias][] = $this->getReflect($path);
} else {
$this->scanDir($path, $alias);
}
}
return $this;
}
/**
* @param $class
* @return array
* @throws ReflectionException
*/
private function getReflect($class): array
{
$reflect = Snowflake::getDi()->getReflect($class);
$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;
$annotations[] = $tmp;
}
return $annotations;
}
/**
* @param \ReflectionClass $reflect
*/
private function targets(\ReflectionClass $reflect)
{
$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);
}
}
/**
* @param ReflectionAttribute $attribute
* @return array|object
*/
private function instance(ReflectionAttribute $attribute): array|object
{
$instance = $attribute->newInstance();
if ($instance instanceof Middleware) {
$instance = [$instance, 'onHandler'];
}
if ($instance instanceof Interceptor) {
$instance = [$instance, 'onHandler'];
}
if ($instance instanceof Limits) {
$instance = [$instance, 'onHandler'];
}
if ($instance instanceof After) {
$instance = [$instance, 'onHandler'];
}
return $instance;
}
}
+20
View File
@@ -0,0 +1,20 @@
<?php
namespace Annotation;
use Closure;
interface IAnnotation
{
/**
* @param array|Closure $closure
* @return mixed
*/
public function setHandler(array|Closure $closure): mixed;
}
+33
View File
@@ -0,0 +1,33 @@
<?php
namespace Annotation;
use Closure;
#[\Attribute(\Attribute::TARGET_METHOD)] class Interceptor
{
/**
* Middleware constructor.
* @param string|array $handler
*/
public function __construct(
private string|array $handler
)
{
}
/**
* @return array|string
*/
public function getMiddleware(): array|string
{
return $this->handler;
}
}
+33
View File
@@ -0,0 +1,33 @@
<?php
namespace Annotation;
use Closure;
#[\Attribute(\Attribute::TARGET_METHOD)] class Limits
{
/**
* Middleware constructor.
* @param string|array $handler
*/
public function __construct(
private string|array $handler
)
{
}
/**
* @return array|string
*/
public function getMiddleware(): array|string
{
return $this->handler;
}
}
+33
View File
@@ -0,0 +1,33 @@
<?php
namespace Annotation;
use Closure;
#[\Attribute(\Attribute::TARGET_METHOD)] class Middleware
{
/**
* Middleware constructor.
* @param string|array $handler
*/
public function __construct(
private string|array $handler
)
{
}
/**
* @return array|string
*/
public function getMiddleware(): array|string
{
return $this->handler;
}
}
+42
View File
@@ -0,0 +1,42 @@
<?php
namespace Annotation;
use Closure;
use Snowflake\Exception\ComponentException;
use Snowflake\Snowflake;
#[\Attribute(\Attribute::TARGET_METHOD)] class Route implements IAnnotation
{
/**
* Route constructor.
* @param string $uri
* @param string $method
*/
public function __construct(
public string $uri,
public string $method
)
{
}
/**
* @param array|Closure $closure
* @return mixed
* @throws ComponentException
*/
public function setHandler(array|Closure $closure): mixed
{
$router = Snowflake::app()->getRouter();
// TODO: Implement setHandler() method.
return $router->addRoute($this->uri, $closure, $this->method);
}
}
+31
View File
@@ -0,0 +1,31 @@
<?php
namespace Annotation;
/**
* Class Socket
* @package Annotation
*/
#[\Attribute(\Attribute::TARGET_METHOD)] class Socket
{
const CLOSE = 'CLOSE';
const MESSAGE = 'MESSAGE';
const HANDSHAKE = 'HANDSHAKE';
/**
* Socket constructor.
* @param string $event
* @param string|null $uri
*/
public function __construct(
public string $event,
public ?string $uri
)
{
}
}
+3 -2
View File
@@ -9,7 +9,7 @@
],
"license": "MIT",
"require": {
"php": ">=7.4",
"php": "=7.4",
"swoole/ide-helper": "@dev",
"ext-json": "*",
"phpmailer/phpmailer": "^6.1",
@@ -40,7 +40,8 @@
"Console\\": "Console/",
"Database\\": "Database/",
"Gii\\": "Gii/",
"Kafka\\": "Kafka/"
"Kafka\\": "Kafka/",
"Annotation\\": "Annotation/"
},
"files": [
"error.php",