<?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;
}