From 4bf3226adf4ef93fa1d5934cdabb48277aa83f33 Mon Sep 17 00:00:00 2001 From: Jerry Date: Sat, 28 Jan 2023 11:29:44 +0800 Subject: [PATCH] add annotation group support --- src/ZM/Annotation/AnnotationParser.php | 17 +++++++++++++++-- src/ZM/Event/Listener/HttpEventListener.php | 2 -- src/ZM/Plugin/PluginManager.php | 21 ++++++++++++++++----- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/ZM/Annotation/AnnotationParser.php b/src/ZM/Annotation/AnnotationParser.php index b8c67648..8390c6d1 100644 --- a/src/ZM/Annotation/AnnotationParser.php +++ b/src/ZM/Annotation/AnnotationParser.php @@ -26,6 +26,8 @@ class AnnotationParser */ private array $class_list = []; + private array $class_bind_group_list = []; + /** * @var float 用于计算解析时间用的 */ @@ -174,6 +176,11 @@ class AnnotationParser continue 2; } $annotation_list[get_class($vs)][] = $vs; + + // 预处理4:加入组 + if (isset($this->class_bind_group_list[get_class($vs)])) { + $vs->group = array_merge($vs->group, $this->class_bind_group_list[get_class($vs)]); + } } // 预处理3:处理每个函数上面的特殊注解,就是需要操作一些东西的 @@ -249,11 +256,17 @@ class AnnotationParser * * @param string $path 注册解析注解的路径 * @param string $indoor_name 起始命名空间的名称 + * @param array $join_groups 此类命名空间解析出来的注解要加入的组 */ - public function addPsr4Path(string $path, string $indoor_name) + public function addPsr4Path(string $path, string $indoor_name, array $join_groups = []): void { logger()->debug('Add register path: ' . $path . ' => ' . $indoor_name); - $all_class = FileSystem::getClassesPsr4($path, $indoor_name); + $all_class = FileSystem::getClassesPsr4($path, $indoor_name, return_path_value: false); + if (!empty($join_groups)) { + foreach ($all_class as $v) { + $this->class_bind_group_list[$v] = $join_groups; + } + } $this->class_list = array_merge($this->class_list, $all_class); } diff --git a/src/ZM/Event/Listener/HttpEventListener.php b/src/ZM/Event/Listener/HttpEventListener.php index f01d9151..779c7e2d 100644 --- a/src/ZM/Event/Listener/HttpEventListener.php +++ b/src/ZM/Event/Listener/HttpEventListener.php @@ -30,7 +30,6 @@ class HttpEventListener { // 注册容器 ContainerRegistrant::registerHttpRequestServices($event); - // TODO: 这里有个bug,如果是用的Workerman+Fiber协程的话,有个前置协程挂起,这里获取到的Event是被挂起的Event对象,触发两次事件才能归正 // 跑一遍 BindEvent 绑定了 HttpRequestEvent 的注解 $handler = new AnnotationHandler(BindEvent::class); $handler->setRuleCallback(fn (BindEvent $anno) => is_a($anno->event_class, HttpRequestEvent::class, true)); @@ -49,7 +48,6 @@ class HttpEventListener $div = new Route($node['route']); $div->params = $params; $div->method = $node['method']; - // TODO:这里有个bug,逻辑上 request_method 应该是个数组,而不是字符串,但是这里 $node['method'] 是字符串,所以这里只能用字符串来判断 // $div->request_method = $node['request_method']; $div->class = $node['class']; $route_handler->handle($div, null, $params, $event->getRequest(), $event); diff --git a/src/ZM/Plugin/PluginManager.php b/src/ZM/Plugin/PluginManager.php index 24df5972..ae5d575c 100644 --- a/src/ZM/Plugin/PluginManager.php +++ b/src/ZM/Plugin/PluginManager.php @@ -114,19 +114,28 @@ class PluginManager */ public static function addPluginsFromComposer(): int { - $installed_file = SOURCE_ROOT_DIR . '/vendor/composer/installed.json'; - if (!file_exists($installed_file)) { + $try_list = [ + SOURCE_ROOT_DIR . '/vendor', + WORKING_DIR . '/vendor', + ]; + foreach ($try_list as $v) { + if (file_exists($v . '/composer/installed.json')) { + $vendor_dir = $v; + break; + } + } + if (!isset($vendor_dir)) { logger()->notice('找不到 Composer 的 installed.json 文件,跳过扫描 Composer 插件'); return 0; } - $json = json_decode(file_get_contents($installed_file), true); + $json = json_decode(file_get_contents($vendor_dir . '/composer/installed.json'), true); if (!is_array($json)) { logger()->notice('Composer 的 installed.json 文件解析失败,跳过扫描 Composer 插件'); return 0; } $cnt = 0; foreach ($json['packages'] as $item) { - $root_dir = SOURCE_ROOT_DIR . '/vendor/' . $item['name']; + $root_dir = $vendor_dir . '/' . $item['name']; $meta_file = zm_dir($root_dir . '/zmplugin.json'); if (!file_exists($meta_file)) { continue; @@ -249,7 +258,9 @@ class PluginManager } // 如果设置了 Autoload file,那么将会把 psr-4 的加载路径丢进 parser foreach ($meta->getAutoloadPsr4() as $namespace => $path) { - $parser->addPsr4Path($meta->getRootDir() . '/' . $path . '/', trim($namespace, '\\')); + $parser->addPsr4Path($meta->getRootDir() . '/' . $path . '/', trim($namespace, '\\'), [ + 'plugin:' . $name, + ]); } } }