mirror of
https://gitee.com/zoujingli/ThinkAdmin.git
synced 2026-06-08 04:48:10 +08:00
Replace header text "Payment Plugin for ThinkAdmin" with "ThinkAdmin Plugin for ThinkAdmin" across project files (configs, controllers, plugins, php-cs-fixer, etc.) to unify branding. Add a new composer script "rewrite-model" to regenerate models and run php-cs-fixer. Also apply a minor newline fix in .copilot-commit-message-instructions.md.
234 lines
6.7 KiB
PHP
234 lines
6.7 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
/**
|
||
* +----------------------------------------------------------------------
|
||
* | ThinkAdmin Plugin for ThinkAdmin
|
||
* +----------------------------------------------------------------------
|
||
* | 版权所有 2014~2026 ThinkAdmin [ thinkadmin.top ]
|
||
* +----------------------------------------------------------------------
|
||
* | 官方网站: https://thinkadmin.top
|
||
* +----------------------------------------------------------------------
|
||
* | 开源协议 ( https://mit-license.org )
|
||
* | 免责声明 ( https://thinkadmin.top/disclaimer )
|
||
* | 会员特权 ( https://thinkadmin.top/vip-introduce )
|
||
* +----------------------------------------------------------------------
|
||
* | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
|
||
* | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
|
||
* +----------------------------------------------------------------------
|
||
*/
|
||
|
||
namespace think\admin;
|
||
|
||
use think\admin\service\ModuleService;
|
||
use think\admin\service\NodeService;
|
||
use think\App;
|
||
use think\Service;
|
||
|
||
/**
|
||
* 插件注册服务
|
||
*
|
||
* @class Plugin
|
||
*
|
||
* @method string getAppCode() static 获取插件编号
|
||
* @method string getAppName() static 获取插件名称
|
||
* @method string getAppPath() static 获取插件路径
|
||
* @method string getAppSpace() static 获取插件空间名
|
||
* @method string getAppPackage() static 获取插件安装包
|
||
*/
|
||
abstract class Plugin extends Service
|
||
{
|
||
/**
|
||
* 必填,插件包名.
|
||
* @var string
|
||
*/
|
||
protected $package = '';
|
||
|
||
/**
|
||
* 必填,插件编码
|
||
* @var string
|
||
*/
|
||
protected $appCode = '';
|
||
|
||
/**
|
||
* 必填,插件名称.
|
||
* @var string
|
||
*/
|
||
protected $appName = '';
|
||
|
||
/**
|
||
* 可选,插件目录.
|
||
* @var string
|
||
*/
|
||
protected $appPath = '';
|
||
|
||
/**
|
||
* 可选,插件别名.
|
||
* @var string
|
||
*/
|
||
protected $appAlias = '';
|
||
|
||
/**
|
||
* 可选,命名空间.
|
||
* @var string
|
||
*/
|
||
protected $appSpace = '';
|
||
|
||
/**
|
||
* 可选,注册服务
|
||
* @var string
|
||
*/
|
||
protected $appService = '';
|
||
|
||
/**
|
||
* 插件配置.
|
||
* @var array
|
||
*/
|
||
private static $addons = [];
|
||
|
||
/**
|
||
* 自动注册插件.
|
||
*/
|
||
public function __construct(App $app)
|
||
{
|
||
parent::__construct($app);
|
||
|
||
// 获取基础服务类
|
||
$ref = new \ReflectionClass(static::class);
|
||
|
||
// 应用服务注册类
|
||
if (empty($this->appService)) {
|
||
$this->appService = static::class;
|
||
}
|
||
|
||
// 应用命名空间名
|
||
if (empty($this->appSpace)) {
|
||
$this->appSpace = $ref->getNamespaceName();
|
||
}
|
||
|
||
// 应用插件路径计算
|
||
if (empty($this->appPath) || !is_dir($this->appPath)) {
|
||
$this->appPath = dirname($ref->getFileName());
|
||
}
|
||
|
||
// 应用插件包名计算
|
||
if (empty($this->package) && ($path = $ref->getFileName())) {
|
||
for ($level = 1; $level <= 3; ++$level) {
|
||
if (is_file($file = dirname($path, $level) . '/composer.json')) {
|
||
$this->package = json_decode(file_get_contents($file), true)['name'] ?? '';
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 应用插件计算名称及别名
|
||
$attr = explode('\\', $ref->getNamespaceName());
|
||
if ($attr[0] === NodeService::space()) {
|
||
array_shift($attr);
|
||
}
|
||
|
||
$this->appCode = $this->appCode ?: join('-', $attr);
|
||
if ($this->appCode === $this->appAlias) {
|
||
$this->appAlias = '';
|
||
}
|
||
|
||
if (is_dir($this->appPath)) {
|
||
// 写入插件参数信息
|
||
self::$addons[$this->appCode] = [
|
||
'name' => $this->appName,
|
||
'path' => realpath($this->appPath) . DIRECTORY_SEPARATOR,
|
||
'alias' => $this->appAlias,
|
||
'space' => $this->appSpace ?: NodeService::space($this->appCode),
|
||
'package' => $this->package,
|
||
'service' => $this->appService,
|
||
];
|
||
// 插件别名动态设置
|
||
if (!empty($this->appAlias) && $this->appCode !== $this->appAlias) {
|
||
Library::$sapp->config->set([
|
||
'app_map' => array_merge(Library::$sapp->config->get('app.app_map', []), [
|
||
$this->appAlias => $this->appCode,
|
||
]),
|
||
], 'app');
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取对象内部属性.
|
||
*/
|
||
public function __get(string $name)
|
||
{
|
||
return $this->{$name} ?? '';
|
||
}
|
||
|
||
/**
|
||
* 静态调用方法兼容.
|
||
* @return null|array|string
|
||
* @throws Exception
|
||
*/
|
||
public static function __callStatic(string $method, array $arguments)
|
||
{
|
||
switch (strtolower($method)) {
|
||
case 'all':
|
||
return self::get(...$arguments);
|
||
case 'getappcode':
|
||
return app(static::class)->appCode;
|
||
case 'getappname':
|
||
return app(static::class)->appName;
|
||
case 'getapppath':
|
||
return app(static::class)->appPath;
|
||
case 'getappspace':
|
||
return app(static::class)->appSpace;
|
||
case 'getapppackage':
|
||
return app(static::class)->package;
|
||
default:
|
||
$class = basename(str_replace('\\', '/', static::class));
|
||
throw new Exception("method not exists: {$class}::{$method}()");
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 魔术方法调用兼容处理.
|
||
* @return null|array
|
||
* @throws Exception
|
||
*/
|
||
public function __call(string $method, array $arguments)
|
||
{
|
||
return self::__callStatic($method, $arguments);
|
||
}
|
||
|
||
/**
|
||
* 注册应用启动.
|
||
*/
|
||
public function boot(): void {}
|
||
|
||
/**
|
||
* 获取插件及安装信息.
|
||
* @param ?string $code 指定插件编号
|
||
* @param bool $append 关联安装数据
|
||
*/
|
||
public static function get(?string $code = null, bool $append = false): ?array
|
||
{
|
||
// 读取插件原始信息
|
||
$data = empty($code) ? self::$addons : (self::$addons[$code] ?? null);
|
||
if (empty($data) || empty($append)) {
|
||
return $data;
|
||
}
|
||
// 关联插件安装信息
|
||
$versions = ModuleService::getLibrarys();
|
||
return empty($code) ? array_map(static function ($item) use ($versions) {
|
||
$item['install'] = $versions[$item['package']] ?? [];
|
||
if (empty($item['name'])) {
|
||
$item['name'] = $item['install']['name'] ?? '';
|
||
}
|
||
return $item;
|
||
}, $data) : $data + ['install' => $versions[$data['package']] ?? []];
|
||
}
|
||
|
||
/**
|
||
* 定义插件菜单.
|
||
* @return array 一级或二级菜单
|
||
*/
|
||
abstract public static function menu(): array;
|
||
}
|