mirror of
https://github.com/zhamao-robot/zhamao-framework.git
synced 2026-07-20 23:25:35 +08:00
add plugin loader support
This commit is contained in:
@@ -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 = [];
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user