add plugin loader support

This commit is contained in:
crazywhalecc
2022-12-19 01:45:27 +08:00
parent 52a195aca2
commit cd2bb1b570
18 changed files with 373 additions and 96 deletions

View File

@@ -6,11 +6,9 @@ namespace ZM\Annotation;
abstract class AnnotationBase implements \IteratorAggregate
{
public string $method = '';
/** @var array|\Closure|string 方法名或闭包 */
public \Closure|string|array $method = '';
/**
* @var \Closure|string
*/
public $class = '';
public array $group = [];

View File

@@ -127,14 +127,18 @@ class AnnotationHandler
// 由于3.0有额外的插件模式支持,所以注解就不再提供独立的闭包函数调用支持了
// 提取要调用的目标类和方法名称
$class = $v->class;
$target_class = new $class();
$target_method = $v->method;
if ($class !== '') {
$target_class = new $class();
$callback = [$target_class, $target_method];
} else {
$callback = $target_method;
}
// 先执行规则失败就返回false
if ($rule_callback !== null && !$rule_callback($v)) {
$this->status = self::STATUS_RULE_FAILED;
return false;
}
$callback = [$target_class, $target_method];
try {
$this->return_val = middleware()->process($callback, ...$args);
} catch (InterruptException $e) {

View File

@@ -4,6 +4,8 @@ declare(strict_types=1);
namespace ZM\Annotation;
use ZM\Annotation\Interfaces\Level;
/**
* 注解全局存取位置
*/
@@ -36,4 +38,20 @@ class AnnotationMap
self::$_list = array_merge(self::$_list, $parser->generateAnnotationList());
self::$_map = $parser->getAnnotationMap();
}
/**
* 排序所有的注解
*/
public static function sortAnnotationList(): void
{
foreach (self::$_list as $class => $annotations) {
if (is_a($class, Level::class, true)) {
usort(self::$_list[$class], function ($a, $b) {
$left = $a->getLevel(); /** @phpstan-ignore-line */
$right = $b->getLevel(); /* @phpstan-ignore-line */
return $left > $right ? -1 : ($left == $right ? 0 : 1);
});
}
}
}
}

View File

@@ -10,7 +10,6 @@ use Koriym\Attributes\DualReader;
use ZM\Annotation\Http\Controller;
use ZM\Annotation\Http\Route;
use ZM\Annotation\Interfaces\ErgodicAnnotation;
use ZM\Annotation\Interfaces\Level;
use ZM\Annotation\Middleware\Middleware;
use ZM\Store\FileSystem;
use ZM\Utils\HttpUtil;
@@ -67,7 +66,7 @@ class AnnotationParser
* @param string $class_name 注解类名
* @param callable $callback 回调函数
*/
public function addSpecialParser(string $class_name, callable $callback)
public function addSpecialParser(string $class_name, callable $callback): void
{
$this->special_parsers[$class_name][] = $callback;
}
@@ -160,14 +159,11 @@ class AnnotationParser
}
// 预处理3调用自定义解析器
foreach (($this->special_parsers[get_class($vs)] ?? []) as $parser) {
$result = $parser($vs);
if ($result === true) {
continue 2;
}
if ($result === false) {
continue 3;
}
if (($a = $this->parseSpecial($vs)) === true) {
continue;
}
if ($a === false) {
continue 2;
}
}
@@ -191,14 +187,11 @@ class AnnotationParser
}
// 预处理3.3:调用自定义解析器
foreach (($this->special_parsers[get_class($method_anno)] ?? []) as $parser) {
$result = $parser($method_anno);
if ($result === true) {
continue 2;
}
if ($result === false) {
continue 3;
}
if (($a = $this->parseSpecial($method_anno, $methods_annotations)) === true) {
continue;
}
if ($a === false) {
continue 2;
}
// 如果上方没有解析或返回了 true则添加到注解解析列表中
@@ -240,12 +233,20 @@ class AnnotationParser
}
}
}
foreach ($o as $k => $v) {
$this->sortByLevel($o, $k);
}
return $o;
}
public function parseSpecial($annotation, $same_method_annotations = null): ?bool
{
foreach (($this->special_parsers[get_class($annotation)] ?? []) as $parser) {
$result = $parser($annotation, $same_method_annotations);
if (is_bool($result)) {
return $result;
}
}
return null;
}
/**
* 添加解析的路径
*
@@ -258,26 +259,6 @@ class AnnotationParser
$this->path_list[] = [$path, $indoor_name];
}
/**
* 排序注解列表
*
* @param array $events 需要排序的
* @param string $class_name 排序的类名
* @param string $prefix 前缀
* @internal 用于 level 排序
*/
public function sortByLevel(array &$events, string $class_name, string $prefix = '')
{
if (is_a($class_name, Level::class, true)) {
$class_name .= $prefix;
usort($events[$class_name], function ($a, $b) {
$left = $a->getLevel();
$right = $b->getLevel();
return $left > $right ? -1 : ($left == $right ? 0 : 1);
});
}
}
/**
* 获取解析器调用的时间(秒)
*/
@@ -297,14 +278,16 @@ class AnnotationParser
/**
* 添加注解路由
*/
private function addRouteAnnotation(Route $vss): void
private function addRouteAnnotation(Route $vss, ?array $same_method_annotations = null)
{
// 拿到所属方法的类上面有没有控制器的注解
$prefix = '';
foreach (($this->annotation_tree[$vss->class]['methods_annotations'][$vss->method] ?? []) as $annotation) {
if ($annotation instanceof Controller) {
$prefix = $annotation->prefix;
break;
if ($same_method_annotations !== null) {
foreach ($same_method_annotations as $annotation) {
if ($annotation instanceof Controller) {
$prefix = $annotation->prefix;
break;
}
}
}
$tail = trim($vss->route, '/');
@@ -314,5 +297,6 @@ class AnnotationParser
$route->setMethods($vss->request_method);
HttpUtil::getRouteCollection()->add(md5($route_name), $route);
return null;
}
}

View File

@@ -4,7 +4,6 @@ declare(strict_types=1);
namespace ZM\Annotation\OneBot;
use Attribute;
use Doctrine\Common\Annotations\Annotation\NamedArgumentConstructor;
use Doctrine\Common\Annotations\Annotation\Target;
use ZM\Annotation\AnnotationBase;
@@ -114,6 +113,12 @@ class BotCommand extends AnnotationBase implements Level
return $this;
}
public function withArgumentObject(CommandArgument $argument): BotCommand
{
$this->arguments[] = $argument;
return $this;
}
public function getLevel(): int
{
return $this->level;

View File

@@ -43,7 +43,7 @@ class CommandArgument extends AnnotationBase implements ErgodicAnnotation
* @param string $name 参数名称(可以是中文)
* @param string $description 参数描述(默认为空)
* @param bool $required 参数是否必需如果是必需为true默认为false
* @param string $prompt 当参数为必需时,返回给用户的提示输入的消息(默认为"请输入$name"
* @param string $prompt 当参数为必需且缺失时,返回给用户的提示输入的消息(默认为"请输入$name"
* @param string $default 当required为false时未匹配到参数将自动使用default值默认为空
* @param int $timeout prompt超时时间默认为60秒
* @throws InvalidArgumentException|ZMKnownException