4
0
Fork 0
dcat-admin/src/Extend/ServiceProvider.php

608 lines
12 KiB
PHP

<?php
namespace Dcat\Admin\Extend;
use Dcat\Admin\Admin;
use Dcat\Admin\Exception\RuntimeException;
use Dcat\Admin\Support\ComposerProperty;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\URL;
use Illuminate\Support\ServiceProvider as LaravelServiceProvider;
use Symfony\Component\Console\Output\NullOutput;
abstract class ServiceProvider extends LaravelServiceProvider
{
use CanImportMenu;
const TYPE_THEME = 'theme';
/**
* @var ComposerProperty
*/
public $composerProperty;
/**
* @var string
*/
protected $name;
/**
* @var string
*/
protected $packageName;
/**
* @var string
*/
protected $type;
/**
* @var string
*/
protected $path;
/**
* @var array
*/
protected $js = [];
/**
* @var array
*/
protected $css = [];
/**
* @var \Symfony\Component\Console\Output\OutputInterface
*/
public $output;
/**
* @var array
*/
protected $config;
/**
* @var array
*/
protected $middleware = [];
/**
* @var array
*/
protected $exceptRoutes = [];
public function __construct($app)
{
parent::__construct($app);
$this->output = new NullOutput();
}
/**
* {@inheritdoc}
*/
final public function boot()
{
$this->autoRegister();
if ($this->disabled()) {
return;
}
$this->init();
}
/**
* 初始化操作.
*
* @return void
*/
public function init()
{
if ($views = $this->getViewPath()) {
$this->loadViewsFrom($views, $this->getName());
}
if ($lang = $this->getLangPath()) {
$this->loadTranslationsFrom($lang, $this->getName());
}
if ($routes = $this->getRoutes()) {
$this->registerRoutes($routes);
}
if ($this->middleware()) {
$this->addMiddleware();
}
if ($this->exceptRoutes) {
$this->addExceptRoutes();
}
$this->aliasAssets();
}
/**
* 自动注册扩展.
*/
protected function autoRegister()
{
if ($this->getName()) {
return;
}
Admin::extension()->addExtension($this);
}
/**
* 获取扩展名称.
*
* @return string|void
*/
public function getName()
{
return $this->name ?: ($this->name = str_replace('/', '.', $this->getPackageName()));
}
/**
* 获取扩展别名.
*
* @return string
*/
public function getAlias()
{
if (! $this->composerProperty) {
return;
}
return $this->composerProperty->alias;
}
/**
* 获取包名.
*
* @return string|void
*/
public function getPackageName()
{
if (! $this->packageName) {
if (! $this->composerProperty) {
return;
}
$this->packageName = $this->composerProperty->name;
}
return $this->packageName;
}
/**
* 获取插件类型.
*
* @return string
*/
public function getType()
{
return $this->type;
}
/**
* 获取当前已安装版本.
*
* @return string
*/
public function getVersion()
{
return Admin::extension()->versionManager()->getCurrentVersion($this);
}
/**
* 获取当前最新版本.
*
* @return string
*/
public function getLatestVersion()
{
return Admin::extension()->versionManager()->getFileVersions($this);
}
/**
* 获取当前本地最新版本.
*
* @return string
*/
public function getLocalLatestVersion()
{
return last(
array_keys(Admin::extension()->versionManager()->getFileVersions($this))
);
}
/**
* 获取扩展包路径.
*
* @param string $path
* @return string
*
* @throws \ReflectionException
*/
public function path(?string $path = null)
{
if (! $this->path) {
$this->path = realpath(dirname((new \ReflectionClass(static::class))->getFileName()).'/..');
if (! is_dir($this->path)) {
throw new RuntimeException("The {$this->path} is not a directory.");
}
}
$path = ltrim($path, '/');
return $path ? $this->path.'/'.$path : $this->path;
}
/**
* 获取logo路径.
*
* @return string
*
* @throws \ReflectionException
*/
public function getLogoPath()
{
return $this->path('logo.png');
}
/**
* @return string
*/
public function getLogoBase64()
{
try {
$logo = $this->getLogoPath();
if (is_file($logo) && $file = fopen($logo, 'rb', 0)) {
$content = fread($file, filesize($logo));
fclose($file);
$base64 = chunk_split(base64_encode($content));
return 'data:image/png;base64,'.$base64;
}
} catch (\ReflectionException $e) {
}
}
/**
* 判断扩展是否启用.
*
* @return bool
*/
public function enabled()
{
return Admin::extension()->enabled($this->getName());
}
/**
* 判断扩展是否禁用.
*
* @return bool
*/
public function disabled()
{
return ! $this->enabled();
}
/**
* 获取或保存配置.
*
* @param string $key
* @param null $default
* @return mixed
*/
public function config($key = null, $default = null)
{
if ($this->config === null) {
$this->initConfig();
}
if (is_array($key)) {
$this->saveConfig($key);
return;
}
if ($key === null) {
return $this->config;
}
return Arr::get($this->config, $key, $default);
}
/**
* 保存配置.
*
* @param array $config
*/
public function saveConfig(array $config)
{
$this->config = array_merge($this->config, $config);
Admin::setting()->save([$this->getConfigKey() => $this->serializeConfig($this->config)]);
}
/**
* 初始化配置.
*/
protected function initConfig()
{
$this->config = Admin::setting()->get($this->getConfigKey());
$this->config = $this->config ? $this->unserializeConfig($this->config) : [];
}
/**
* 更新扩展.
*
* @param string $currentVersion
* @param string $stopOnVersion
*
* @throws \Exception
*/
public function update($currentVersion, $stopOnVersion)
{
$this->refreshMenu();
}
/**
* 卸载扩展.
*/
public function uninstall()
{
$this->flushMenu();
}
/**
* 发布静态资源.
*/
public function publishable()
{
if ($assets = $this->getAssetPath()) {
$this->publishes([
$assets => $this->getPublishsPath(),
], $this->getName());
}
}
/**
* 获取资源发布路径.
*
* @return string
*/
protected function getPublishsPath()
{
return public_path(
Admin::asset()->getRealPath('@extension/'.str_replace('.', '/', $this->getName()))
);
}
/**
* 注册路由.
*
* @param $callback
*/
public function registerRoutes($callback)
{
$this->loadRoutesFrom($callback);
// Admin::app()->routes(function ($router) use ($callback) {
// $router->group([
// 'prefix' => config('admin.route.prefix'),
// 'middleware' => config('admin.route.middleware'),
// ], $callback);
// });
}
/**
* 获取中间件.
*
* @return array
*/
protected function middleware()
{
return $this->middleware;
}
/**
* 注册中间件.
*/
protected function addMiddleware()
{
$adminMiddleware = (array) config('admin.route.middleware');
$middleware = $this->middleware();
$before = $middleware['before'] ?? [];
$middle = $middleware['middle'] ?? [];
$after = $middleware['after'] ?? [];
$this->mixMiddleware($middle);
config([
'admin.route.middleware' => array_merge((array) $before, $adminMiddleware, (array) $after),
]);
}
protected function mixMiddleware(array $middle)
{
Admin::mixMiddlewareGroup($middle);
}
/**
* 配置需要跳过权限认证和登录认证的路由.
*/
protected function addExceptRoutes()
{
if (! empty($this->exceptRoutes['permission'])) {
Admin::context()->merge('permission.except', (array) $this->exceptRoutes['permission']);
}
if (! empty($this->exceptRoutes['auth'])) {
Admin::context()->merge('auth.except', (array) $this->exceptRoutes['auth']);
}
}
/**
* 获取静态资源路径.
*
* @return string
*/
final public function getAssetPath()
{
return $this->path('resources/assets');
}
/**
* 获取视图路径.
*
* @return string
*/
final public function getViewPath()
{
return $this->path('resources/views');
}
/**
* 获取语言包路径.
*
* @return string
*/
final public function getLangPath()
{
return $this->path('resources/lang');
}
/**
* 获取路由地址.
*
* @return string
*
* @throws \ReflectionException
*/
final public function getRoutes()
{
$path = $this->path('src/Http/routes.php');
return is_file($path) ? $path : null;
}
/**
* @param ComposerProperty $composerProperty
* @return $this
*/
public function withComposerProperty(ComposerProperty $composerProperty)
{
$this->composerProperty = $composerProperty;
return $this;
}
/**
* 获取或保存配置.
*
* @param string $key
* @param string $value
* @return mixed
*/
public static function setting($key = null, $value = null)
{
$extension = static::instance();
if ($extension && $extension instanceof ServiceProvider) {
return $extension->config($key, $value);
}
}
/**
* 翻译.
*
* @param string $key
* @param array $replace
* @param null $locale
* @return array|string|null
*/
public static function trans($key, $replace = [], $locale = null)
{
return trans(static::instance()->getName().'::'.$key, $replace, $locale);
}
/**
* 获取自身实例.
*
* @return $this
*/
public static function instance()
{
return app(static::class);
}
/**
* 注册别名.
*/
protected function aliasAssets()
{
$asset = Admin::asset();
// 注册静态资源路径别名
$asset->alias($this->getName().'.path', '@extension/'.$this->getPackageName());
if ($this->js || $this->css) {
$asset->alias($this->getName(), [
'js' => $this->formatAssetFiles($this->js),
'css' => $this->formatAssetFiles($this->css),
]);
}
}
/**
* @param string|array $files
* @return mixed
*/
protected function formatAssetFiles($files)
{
if (is_array($files)) {
return array_map([$this, 'formatAssetFiles'], $files);
}
if (URL::isValidUrl($files)) {
return $files;
}
return '@'.$this->getName().'.path/'.trim($files, '/');
}
/**
* 配置key.
*
* @return mixed
*/
protected function getConfigKey()
{
return str_replace('.', ':', $this->getName());
}
/**
* @param $config
* @return false|string
*/
protected function serializeConfig($config)
{
return json_encode($config);
}
/**
* @param $config
* @return array
*/
protected function unserializeConfig($config)
{
return json_decode($config, true);
}
}