plugin_path = base_path('plugin'); $this->project_path = dirname(base_path()); // 项目根目录(前端和后端的父级) $this->server_path = base_path(); // 后端根目录 } /** * 获取前端基础目录 * 前端代码统一在 frontend 目录下 * * @return string 前端基础目录 */ public function getFrontendPath(): string { return $this->project_path . DIRECTORY_SEPARATOR . 'frontend'; } /** * 获取前端指定项目目录 * * @param string $frontendType 前端类型(admin/web/uni-app) * @return string 前端项目目录 */ public function getFrontendProjectPath(string $frontendType): string { return $this->getFrontendPath() . DIRECTORY_SEPARATOR . $frontendType; } /** * 获取插件配置(兼容 ConfigTrait) * * @param string $code 插件编码 * @return array|null */ protected function getPluginConfig(string $code): ?array { $configFile = $this->plugin_path . DIRECTORY_SEPARATOR . $code . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'info.php'; if (is_file($configFile)) { return include $configFile; } return null; } /** * 执行插件 Install 类方法 * * 统一调用插件的 install/uninstall/update 方法 * CLI 和在线模式都通过此方法调用 * * @param string $code 插件编码 * @param string $action 方法名 (install/uninstall/update) * @param string|null $version 版本(对于 install 是目标版本,对于 update 是新版本) * @param string|null $oldVersion 旧版本(仅 update 时使用) * @param bool $silent 是否静默执行失败(true: 失败不抛出异常, false: 失败抛出异常) * @return bool 是否成功执行 * @throws \Exception 当 silent=false 且执行失败时抛出异常 */ protected function executePluginMethod(string $code, string $action, ?string $version = null, ?string $oldVersion = null, bool $silent = false): bool { $className = "plugin\\" . $code . "\\Install"; if (!class_exists($className)) { // 插件未提供 Install 类,静默跳过 return true; } try { $pluginConfig = $this->getPluginConfig($code); $version = $pluginConfig['version'] ?? ($version ?? '1.0.0'); // 实例化插件 Install 类 $installInstance = new $className(); switch ($action) { case 'install': if (method_exists($installInstance, 'install')) { $installInstance->install($version); } break; case 'uninstall': if (method_exists($installInstance, 'uninstall')) { $installInstance->uninstall($version); } break; case 'update': if (method_exists($installInstance, 'update')) { $installInstance->update($oldVersion ?? '1.0.0', $version); } break; default: return false; } return true; } catch (\Exception $e) { // 插件方法执行失败,记录日志 $logLevel = $silent ? 'warning' : 'error'; \support\Log::$logLevel('插件方法执行失败', [ 'plugin' => $code, 'action' => $action, 'version' => $version, 'old_version' => $oldVersion, 'exception' => $e->getMessage(), 'file' => $e->getFile(), 'line' => $e->getLine(), ]); // 静默模式不抛出异常,非静默模式抛出异常 if (!$silent) { throw $e; } return false; } } /** * 调用插件 Install 类的方法(兼容 CLI 模式) * * 此方法专门用于 CLI 命令直接调用插件方法 * 与在线模式的区别:CLI 模式不需要 SSE 返回,直接执行 * * @param string $code 插件编码 * @param string $action 方法名 (install/uninstall/update) * @param string|null $version 版本 * @param string|null $oldVersion 旧版本(仅 update 时使用) * @return bool 是否成功 * @throws \Exception */ public function callPluginInstallMethod(string $code, string $action, ?string $version = null, ?string $oldVersion = null): bool { return $this->executePluginMethod($code, $action, $version, $oldVersion, false); } }