2019-02-13 16:25:48 +08:00
|
|
|
|
<?php
|
|
|
|
|
// +----------------------------------------------------------------------
|
|
|
|
|
// | ShopXO 国内领先企业级B2C免费开源电商系统
|
|
|
|
|
// +----------------------------------------------------------------------
|
2021-03-16 10:34:52 +08:00
|
|
|
|
// | Copyright (c) 2011~2099 http://shopxo.net All rights reserved.
|
2019-02-13 16:25:48 +08:00
|
|
|
|
// +----------------------------------------------------------------------
|
2021-03-16 10:34:52 +08:00
|
|
|
|
// | Licensed ( https://opensource.org/licenses/mit-license.php )
|
2019-02-13 16:25:48 +08:00
|
|
|
|
// +----------------------------------------------------------------------
|
|
|
|
|
// | Author: Devil
|
|
|
|
|
// +----------------------------------------------------------------------
|
|
|
|
|
namespace app\service;
|
|
|
|
|
|
2021-07-18 23:42:10 +08:00
|
|
|
|
use think\facade\Db;
|
2022-04-21 22:08:53 +08:00
|
|
|
|
use app\service\SystemService;
|
2020-12-23 20:15:48 +08:00
|
|
|
|
use app\service\PluginsService;
|
2019-02-13 16:25:48 +08:00
|
|
|
|
use app\service\ResourcesService;
|
2021-07-24 22:25:00 +08:00
|
|
|
|
use app\service\SqlConsoleService;
|
2022-01-23 18:30:56 +08:00
|
|
|
|
use app\service\AdminPowerService;
|
|
|
|
|
use app\service\AdminService;
|
2023-08-27 16:59:15 +08:00
|
|
|
|
use app\service\StoreService;
|
2019-02-13 16:25:48 +08:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 应用管理服务层
|
|
|
|
|
* @author Devil
|
|
|
|
|
* @blog http://gong.gg/
|
|
|
|
|
* @version 0.0.1
|
|
|
|
|
* @datetime 2016-12-01T21:51:08+0800
|
|
|
|
|
*/
|
|
|
|
|
class PluginsAdminService
|
|
|
|
|
{
|
2019-05-13 00:38:18 +08:00
|
|
|
|
// 排除不能使用的名称
|
|
|
|
|
public static $plugins_exclude_verification = ['view', 'shopxo', 'www'];
|
|
|
|
|
|
2020-08-15 11:25:48 +08:00
|
|
|
|
// 排除的文件后缀
|
2021-01-06 19:50:37 +08:00
|
|
|
|
public static $exclude_ext = ['php'];
|
2020-08-15 11:25:48 +08:00
|
|
|
|
|
2021-01-05 14:48:01 +08:00
|
|
|
|
// 读取插件排序方式(自定义排序 -> 最早安装)
|
2021-01-06 19:50:37 +08:00
|
|
|
|
public static $plugins_order_by = 'sort asc,id asc';
|
2021-01-05 14:48:01 +08:00
|
|
|
|
|
2019-02-13 16:25:48 +08:00
|
|
|
|
/**
|
|
|
|
|
* 列表
|
|
|
|
|
* @author Devil
|
|
|
|
|
* @blog http://gong.gg/
|
|
|
|
|
* @version 1.0.0
|
|
|
|
|
* @date 2018-09-29
|
|
|
|
|
* @desc description
|
|
|
|
|
* @param [array] $params [输入参数]
|
|
|
|
|
*/
|
|
|
|
|
public static function PluginsList($params = [])
|
|
|
|
|
{
|
2019-06-24 18:45:36 +08:00
|
|
|
|
$data = [];
|
2021-01-05 14:48:01 +08:00
|
|
|
|
$db_data = [];
|
|
|
|
|
$dir_data = [];
|
2021-01-06 20:09:24 +08:00
|
|
|
|
$temp_data = [];
|
2019-06-24 18:45:36 +08:00
|
|
|
|
$plugins_dir = APP_PATH.'plugins'.DS;
|
|
|
|
|
if(is_dir($plugins_dir))
|
|
|
|
|
{
|
|
|
|
|
if($dh = opendir($plugins_dir))
|
|
|
|
|
{
|
2022-01-23 18:30:56 +08:00
|
|
|
|
// 是否需要校验权限
|
|
|
|
|
$power_plugins = [];
|
|
|
|
|
$is_power = (isset($params['is_power']) && $params['is_power'] == true);
|
|
|
|
|
if($is_power)
|
|
|
|
|
{
|
|
|
|
|
// 获取当前登录账户的插件权限
|
|
|
|
|
$admin = AdminService::LoginInfo();
|
|
|
|
|
if(!empty($admin))
|
|
|
|
|
{
|
2023-08-27 16:59:15 +08:00
|
|
|
|
if($admin['id'] != 1)
|
2022-01-23 18:30:56 +08:00
|
|
|
|
{
|
2023-08-27 16:59:15 +08:00
|
|
|
|
// 超级管理员id等于1则不处理权限
|
|
|
|
|
$is_power = false;
|
|
|
|
|
} else {
|
|
|
|
|
$res = MyCache(SystemService::CacheKey('shopxo.cache_admin_power_plugins_key').$admin['id']);
|
|
|
|
|
if(!empty($res))
|
|
|
|
|
{
|
|
|
|
|
$power_plugins = $res;
|
|
|
|
|
}
|
2022-01-23 18:30:56 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-05 14:48:01 +08:00
|
|
|
|
// 获取数据库已安装插件
|
2021-01-06 20:09:24 +08:00
|
|
|
|
$temp_data = Db::name('Plugins')->order(self::$plugins_order_by)->column('*', 'plugins');
|
2021-01-05 14:48:01 +08:00
|
|
|
|
|
|
|
|
|
// 获取目录所有插件
|
2019-06-24 18:45:36 +08:00
|
|
|
|
while(($temp_file = readdir($dh)) !== false)
|
|
|
|
|
{
|
|
|
|
|
if(!in_array($temp_file, ['.', '..', '/', 'view', 'index.html']) && substr($temp_file, 0, 1) != '.')
|
|
|
|
|
{
|
|
|
|
|
// 获取插件配置信息
|
|
|
|
|
$config = self::GetPluginsConfig($temp_file);
|
2021-07-21 15:15:46 +08:00
|
|
|
|
if(!empty($config) && !empty($config['base']))
|
2019-06-24 18:45:36 +08:00
|
|
|
|
{
|
|
|
|
|
// 获取数据库配置信息
|
2021-01-05 14:48:01 +08:00
|
|
|
|
$base = $config['base'];
|
2022-01-23 18:30:56 +08:00
|
|
|
|
|
|
|
|
|
// 是否需要判断权限
|
|
|
|
|
if($is_power == true)
|
|
|
|
|
{
|
|
|
|
|
if(empty($power_plugins) || !array_key_exists($base['plugins'], $power_plugins))
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-06-24 18:45:36 +08:00
|
|
|
|
|
|
|
|
|
// 数据组装
|
2022-01-23 18:30:56 +08:00
|
|
|
|
$db_config = array_key_exists($base['plugins'], $temp_data) ? $temp_data[$base['plugins']] : [];
|
2021-01-05 14:48:01 +08:00
|
|
|
|
$dir_data[$base['plugins']] = [
|
2023-05-26 19:44:20 +08:00
|
|
|
|
'id' => empty($db_config['id']) ? 0 : $db_config['id'],
|
|
|
|
|
'plugins' => $base['plugins'],
|
|
|
|
|
'plugins_category_id' => isset($db_config['plugins_category_id']) ? $db_config['plugins_category_id'] : 0,
|
2023-08-27 16:59:15 +08:00
|
|
|
|
'plugins_menu_control' => isset($db_config['plugins_menu_control']) ? $db_config['plugins_menu_control'] : '',
|
2023-05-26 19:44:20 +08:00
|
|
|
|
'is_enable' => isset($db_config['is_enable']) ? $db_config['is_enable'] : 0,
|
|
|
|
|
'is_install' => empty($db_config) ? 0 : 1,
|
|
|
|
|
'logo_old' => $base['logo'],
|
|
|
|
|
'logo' => ResourcesService::AttachmentPathViewHandle($base['logo']),
|
|
|
|
|
'is_home' => isset($base['is_home']) ? $base['is_home'] : false,
|
|
|
|
|
'name' => isset($base['name']) ? $base['name'] : '',
|
|
|
|
|
'author' => isset($base['author']) ? $base['author'] : '',
|
|
|
|
|
'author_url' => isset($base['author_url']) ? $base['author_url'] : '',
|
|
|
|
|
'version' => isset($base['version']) ? $base['version'] : '',
|
|
|
|
|
'desc' => isset($base['desc']) ? $base['desc'] : '',
|
|
|
|
|
'apply_version' => isset($base['apply_version']) ? $base['apply_version'] : [],
|
|
|
|
|
'apply_terminal' => isset($base['apply_terminal']) ? $base['apply_terminal'] : [],
|
|
|
|
|
'add_time_time' => isset($db_config['add_time']) ? date('Y-m-d H:i:s', $db_config['add_time']) : '',
|
|
|
|
|
'add_time_date' => isset($db_config['add_time']) ? date('Y-m-d', $db_config['add_time']) : '',
|
2019-06-24 18:45:36 +08:00
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
closedir($dh);
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-02-13 16:25:48 +08:00
|
|
|
|
|
2021-01-05 14:48:01 +08:00
|
|
|
|
// 存在插件和数据库插件数据则处理排序合并
|
2021-01-06 20:09:24 +08:00
|
|
|
|
if(!empty($dir_data) && !empty($temp_data))
|
2021-01-05 14:48:01 +08:00
|
|
|
|
{
|
2021-01-06 20:09:24 +08:00
|
|
|
|
foreach($temp_data as $v)
|
2021-01-05 14:48:01 +08:00
|
|
|
|
{
|
|
|
|
|
if(array_key_exists($v['plugins'], $dir_data))
|
|
|
|
|
{
|
2021-01-06 20:09:24 +08:00
|
|
|
|
$db_data[] = $dir_data[$v['plugins']];
|
2021-01-05 14:48:01 +08:00
|
|
|
|
unset($dir_data[$v['plugins']]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-06 20:09:24 +08:00
|
|
|
|
$data = [
|
|
|
|
|
'db_data' => $db_data,
|
|
|
|
|
'dir_data' => array_values($dir_data),
|
|
|
|
|
];
|
2023-01-19 17:44:03 +08:00
|
|
|
|
return DataReturn(MyLang('handle_success'), 0, $data);
|
2019-02-13 16:25:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2019-06-24 18:45:36 +08:00
|
|
|
|
* 应用安装
|
|
|
|
|
* @author Devil
|
2019-02-13 16:25:48 +08:00
|
|
|
|
* @blog http://gong.gg/
|
|
|
|
|
* @version 1.0.0
|
2019-06-24 18:45:36 +08:00
|
|
|
|
* @date 2018-09-17
|
2019-02-13 16:25:48 +08:00
|
|
|
|
* @desc description
|
2019-06-24 18:45:36 +08:00
|
|
|
|
* @param [array] $params [输入参数]
|
2019-02-13 16:25:48 +08:00
|
|
|
|
*/
|
2019-06-24 18:45:36 +08:00
|
|
|
|
public static function PluginsInstall($params = [])
|
2019-02-13 16:25:48 +08:00
|
|
|
|
{
|
2019-06-24 18:45:36 +08:00
|
|
|
|
// 参数
|
|
|
|
|
if(empty($params['id']))
|
|
|
|
|
{
|
2023-02-04 16:47:48 +08:00
|
|
|
|
return DataReturn(MyLang('params_error_tips'), -1);
|
2019-06-24 18:45:36 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 数据处理
|
2021-02-18 21:59:49 +08:00
|
|
|
|
$plugins = $params['id'];
|
|
|
|
|
$config = self::GetPluginsConfig($plugins);
|
2021-07-21 15:15:46 +08:00
|
|
|
|
if(!empty($config) && !empty($config['base']) && !empty($config['base']['name']))
|
2019-02-13 16:25:48 +08:00
|
|
|
|
{
|
2022-08-09 19:06:01 +08:00
|
|
|
|
// 插件前置事件
|
|
|
|
|
$ret = PluginsService::PluginsEventCall($plugins, 'BeginInstall', $params);
|
|
|
|
|
if(!empty($ret) && isset($ret['code']) && $ret['code'] != 0)
|
|
|
|
|
{
|
|
|
|
|
return $ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 添加处理
|
2021-02-18 21:59:49 +08:00
|
|
|
|
$cache = PluginsService::PluginsCacheData($plugins);
|
2019-06-24 18:45:36 +08:00
|
|
|
|
$data = [
|
2021-01-05 14:48:01 +08:00
|
|
|
|
'name' => $config['base']['name'],
|
2021-02-18 21:59:49 +08:00
|
|
|
|
'plugins' => $plugins,
|
2020-12-23 20:15:48 +08:00
|
|
|
|
'data' => empty($cache) ? '' : json_encode($cache),
|
2019-06-24 18:45:36 +08:00
|
|
|
|
'is_enable' => 0,
|
|
|
|
|
'add_time' => time(),
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
// 添加数据
|
|
|
|
|
if(Db::name('Plugins')->insertGetId($data) > 0)
|
2019-02-13 16:25:48 +08:00
|
|
|
|
{
|
2021-07-20 23:47:31 +08:00
|
|
|
|
// 附件同步到数据库
|
|
|
|
|
ResourcesService::AttachmentDiskFilesToDb('plugins_'.$plugins);
|
|
|
|
|
|
2021-02-18 21:59:49 +08:00
|
|
|
|
// 插件事件回调
|
|
|
|
|
PluginsService::PluginsEventCall($plugins, 'Install', $params);
|
|
|
|
|
|
2023-02-04 16:47:48 +08:00
|
|
|
|
return DataReturn(MyLang('install_success'), 0);
|
2019-06-24 18:45:36 +08:00
|
|
|
|
} else {
|
2023-02-04 16:47:48 +08:00
|
|
|
|
return DataReturn(MyLang('install_fail'), -100);
|
2019-02-13 16:25:48 +08:00
|
|
|
|
}
|
2019-06-24 18:45:36 +08:00
|
|
|
|
} else {
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('plugins_config_error_tips'), -10);
|
2019-02-13 16:25:48 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2019-06-24 18:45:36 +08:00
|
|
|
|
* 卸载应用
|
|
|
|
|
* @author Devil
|
2019-02-13 16:25:48 +08:00
|
|
|
|
* @blog http://gong.gg/
|
|
|
|
|
* @version 1.0.0
|
2019-06-24 18:45:36 +08:00
|
|
|
|
* @date 2018-09-17
|
2019-02-13 16:25:48 +08:00
|
|
|
|
* @desc description
|
2019-06-24 18:45:36 +08:00
|
|
|
|
* @param [array] $params [输入参数]
|
2019-02-13 16:25:48 +08:00
|
|
|
|
*/
|
2019-06-24 18:45:36 +08:00
|
|
|
|
public static function PluginsUninstall($params = [])
|
2019-02-13 16:25:48 +08:00
|
|
|
|
{
|
2019-06-24 18:45:36 +08:00
|
|
|
|
// 参数
|
|
|
|
|
if(empty($params['id']))
|
|
|
|
|
{
|
2023-02-04 16:47:48 +08:00
|
|
|
|
return DataReturn(MyLang('params_error_tips'), -1);
|
2019-06-24 18:45:36 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 开启事务
|
|
|
|
|
Db::startTrans();
|
|
|
|
|
|
|
|
|
|
// 开始卸载
|
2021-02-18 21:59:49 +08:00
|
|
|
|
$plugins = $params['id'];
|
|
|
|
|
if(DB::name('Plugins')->where(['plugins'=>$plugins])->delete())
|
2019-06-24 18:45:36 +08:00
|
|
|
|
{
|
|
|
|
|
// 钩子部署
|
|
|
|
|
$ret = self::PluginsHookDeployment();
|
|
|
|
|
if($ret['code'] == 0)
|
|
|
|
|
{
|
|
|
|
|
// 提交事务
|
|
|
|
|
Db::commit();
|
2021-02-18 21:59:49 +08:00
|
|
|
|
|
|
|
|
|
// 插件事件回调
|
|
|
|
|
PluginsService::PluginsEventCall($plugins, 'Uninstall', $params);
|
|
|
|
|
|
2023-02-04 16:47:48 +08:00
|
|
|
|
return DataReturn(MyLang('uninstall_success'), 0);
|
2019-06-24 18:45:36 +08:00
|
|
|
|
}
|
2019-07-16 00:09:54 +08:00
|
|
|
|
} else {
|
2023-02-04 16:47:48 +08:00
|
|
|
|
$ret = DataReturn(MyLang('uninstall_fail'), -100);
|
2019-06-24 18:45:36 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 事务回退
|
|
|
|
|
Db::rollback();
|
2019-07-16 00:09:54 +08:00
|
|
|
|
return $ret;
|
2019-02-13 16:25:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2019-06-24 18:45:36 +08:00
|
|
|
|
* 获取插件配置信息
|
2019-02-13 16:25:48 +08:00
|
|
|
|
* @author Devil
|
|
|
|
|
* @blog http://gong.gg/
|
|
|
|
|
* @version 1.0.0
|
2019-06-24 18:45:36 +08:00
|
|
|
|
* @date 2018-09-17
|
2019-02-13 16:25:48 +08:00
|
|
|
|
* @desc description
|
2019-06-24 18:45:36 +08:00
|
|
|
|
* @param [string] $plugins [插件名称]
|
2019-02-13 16:25:48 +08:00
|
|
|
|
*/
|
2021-04-20 18:38:23 +08:00
|
|
|
|
public static function GetPluginsConfig($plugins)
|
2019-02-13 16:25:48 +08:00
|
|
|
|
{
|
2019-06-24 18:45:36 +08:00
|
|
|
|
$config = [];
|
|
|
|
|
$file = APP_PATH.'plugins'.DS.$plugins.DS.'config.json';
|
|
|
|
|
if(file_exists($file))
|
|
|
|
|
{
|
|
|
|
|
$config = json_decode(file_get_contents($file), true);
|
|
|
|
|
}
|
2021-07-21 15:15:46 +08:00
|
|
|
|
return empty($config) ? [] : $config;
|
2019-02-13 16:25:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 状态更新
|
|
|
|
|
* @author Devil
|
|
|
|
|
* @blog http://gong.gg/
|
|
|
|
|
* @version 0.0.1
|
|
|
|
|
* @datetime 2016-12-06T21:31:53+0800
|
|
|
|
|
* @param [array] $params [输入参数]
|
|
|
|
|
*/
|
|
|
|
|
public static function PluginsStatusUpdate($params = [])
|
|
|
|
|
{
|
|
|
|
|
// 请求参数
|
|
|
|
|
$p = [
|
|
|
|
|
[
|
|
|
|
|
'checked_type' => 'empty',
|
|
|
|
|
'key_name' => 'id',
|
2023-02-04 16:47:48 +08:00
|
|
|
|
'error_msg' => MyLang('data_id_error_tips'),
|
2019-02-13 16:25:48 +08:00
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'checked_type' => 'in',
|
|
|
|
|
'key_name' => 'state',
|
|
|
|
|
'checked_data' => [0,1],
|
2023-02-04 16:47:48 +08:00
|
|
|
|
'error_msg' => MyLang('form_status_range_message'),
|
2019-02-13 16:25:48 +08:00
|
|
|
|
],
|
|
|
|
|
];
|
|
|
|
|
$ret = ParamsChecked($params, $p);
|
|
|
|
|
if($ret !== true)
|
|
|
|
|
{
|
|
|
|
|
return DataReturn($ret, -1);
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-13 23:10:06 +08:00
|
|
|
|
// 开启事务
|
|
|
|
|
Db::startTrans();
|
|
|
|
|
|
2019-02-13 16:25:48 +08:00
|
|
|
|
// 数据更新
|
2019-06-24 18:45:36 +08:00
|
|
|
|
if(Db::name('Plugins')->where(['plugins'=>$params['id']])->update(['is_enable'=>intval($params['state']), 'upd_time'=>time()]))
|
2019-02-13 16:25:48 +08:00
|
|
|
|
{
|
2019-02-13 18:15:06 +08:00
|
|
|
|
// 钩子部署
|
|
|
|
|
$ret = self::PluginsHookDeployment();
|
2019-02-13 23:10:06 +08:00
|
|
|
|
if($ret['code'] == 0)
|
2019-02-13 18:15:06 +08:00
|
|
|
|
{
|
2019-02-13 23:10:06 +08:00
|
|
|
|
// 提交事务
|
|
|
|
|
Db::commit();
|
2023-01-19 17:44:03 +08:00
|
|
|
|
return DataReturn(MyLang('operate_success'), 0);
|
2019-02-13 18:15:06 +08:00
|
|
|
|
}
|
2019-02-13 23:10:06 +08:00
|
|
|
|
} else {
|
2023-01-19 17:44:03 +08:00
|
|
|
|
$ret = DataReturn(MyLang('operate_fail'), -100);
|
2019-02-13 16:25:48 +08:00
|
|
|
|
}
|
2019-02-13 23:10:06 +08:00
|
|
|
|
|
|
|
|
|
// 事务回退
|
|
|
|
|
Db::rollback();
|
|
|
|
|
return $ret;
|
2019-02-13 16:25:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
2019-02-13 18:15:06 +08:00
|
|
|
|
/**
|
|
|
|
|
* 应用钩子部署
|
|
|
|
|
* @author Devil
|
|
|
|
|
* @blog http://gong.gg/
|
|
|
|
|
* @version 1.0.0
|
|
|
|
|
* @date 2019-02-13
|
|
|
|
|
* @desc description
|
|
|
|
|
*/
|
|
|
|
|
private static function PluginsHookDeployment()
|
|
|
|
|
{
|
|
|
|
|
// 钩子配置文件
|
2021-07-18 23:42:10 +08:00
|
|
|
|
$event_file = APP_PATH.'event.php';
|
|
|
|
|
if(file_exists($event_file))
|
2019-02-13 18:15:06 +08:00
|
|
|
|
{
|
2021-07-18 23:42:10 +08:00
|
|
|
|
if(!is_writable($event_file))
|
|
|
|
|
{
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('common_service.pluginsadmin.file_no_power_tips').'['.$event_file.']', -3);
|
2021-07-18 23:42:10 +08:00
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// 文件不存在则确认目录是否可写
|
|
|
|
|
if(!is_writable(APP_PATH))
|
|
|
|
|
{
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('common_service.pluginsadmin.dir_no_power_tips').'['.$event_file.']', -3);
|
2021-07-18 23:42:10 +08:00
|
|
|
|
}
|
2019-02-13 18:15:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 钩子容器
|
|
|
|
|
$result = [];
|
|
|
|
|
|
|
|
|
|
// 系统自带钩子处理
|
2021-07-18 23:42:10 +08:00
|
|
|
|
if(file_exists($event_file))
|
2019-02-13 18:15:06 +08:00
|
|
|
|
{
|
2021-07-18 23:42:10 +08:00
|
|
|
|
$tags = require $event_file;
|
2019-02-13 18:15:06 +08:00
|
|
|
|
if(!empty($tags) && is_array($tags))
|
|
|
|
|
{
|
|
|
|
|
$system_hook_list = [
|
2021-07-18 23:42:10 +08:00
|
|
|
|
'AppInit',
|
|
|
|
|
'HttpRun',
|
|
|
|
|
'HttpEnd',
|
|
|
|
|
'RouteLoaded',
|
|
|
|
|
'LogRecord'
|
2019-02-13 18:15:06 +08:00
|
|
|
|
];
|
|
|
|
|
foreach($system_hook_list as $system_hook)
|
|
|
|
|
{
|
|
|
|
|
if(isset($tags[$system_hook]))
|
|
|
|
|
{
|
|
|
|
|
$result[$system_hook] = $tags[$system_hook];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理应用钩子
|
2021-01-05 14:48:01 +08:00
|
|
|
|
$data = Db::name('Plugins')->where(['is_enable'=>1])->order(self::$plugins_order_by)->column('plugins');
|
2019-02-13 18:15:06 +08:00
|
|
|
|
if(!empty($data))
|
|
|
|
|
{
|
|
|
|
|
foreach($data as $plugins)
|
|
|
|
|
{
|
|
|
|
|
if(file_exists(APP_PATH.'plugins'.DS.$plugins.DS.'config.json'))
|
|
|
|
|
{
|
|
|
|
|
$config = json_decode(file_get_contents(APP_PATH.'plugins'.DS.$plugins.DS.'config.json'), true);
|
|
|
|
|
if(!empty($config['hook']) && is_array($config['hook']))
|
|
|
|
|
{
|
|
|
|
|
foreach($config['hook'] as $hook_key=>$hook_value)
|
|
|
|
|
{
|
|
|
|
|
if(isset($result[$hook_key]))
|
|
|
|
|
{
|
|
|
|
|
$result[$hook_key] = array_merge($result[$hook_key], $hook_value);
|
|
|
|
|
} else {
|
|
|
|
|
$result[$hook_key] = $hook_value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 部署钩子到文件
|
2021-07-18 23:42:10 +08:00
|
|
|
|
$ret = @file_put_contents($event_file, "<?php
|
2019-02-13 18:15:06 +08:00
|
|
|
|
// +----------------------------------------------------------------------
|
|
|
|
|
// | ShopXO 国内领先企业级B2C免费开源电商系统
|
|
|
|
|
// +----------------------------------------------------------------------
|
2021-03-16 10:34:52 +08:00
|
|
|
|
// | Copyright (c) 2011~2099 http://shopxo.net All rights reserved.
|
2019-02-13 18:15:06 +08:00
|
|
|
|
// +----------------------------------------------------------------------
|
2021-03-16 10:34:52 +08:00
|
|
|
|
// | Licensed ( https://opensource.org/licenses/mit-license.php )
|
2019-02-13 18:15:06 +08:00
|
|
|
|
// +----------------------------------------------------------------------
|
|
|
|
|
// | Author: Devil
|
|
|
|
|
// +----------------------------------------------------------------------
|
|
|
|
|
|
2021-07-18 23:42:10 +08:00
|
|
|
|
// 应用行为扩展定义文件\nreturn ".var_export(['listen'=>$result], true).";\n?>");
|
2019-02-13 18:15:06 +08:00
|
|
|
|
if($ret === false)
|
|
|
|
|
{
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('common_service.pluginsadmin.app_deployment_fail_tips'), -10);
|
2019-02-13 18:15:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-01-19 17:44:03 +08:00
|
|
|
|
return DataReturn(MyLang('handle_success'), 0);
|
2019-02-13 18:15:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
2019-02-13 16:25:48 +08:00
|
|
|
|
/**
|
|
|
|
|
* 删除
|
|
|
|
|
* @author Devil
|
|
|
|
|
* @blog http://gong.gg/
|
|
|
|
|
* @version 1.0.0
|
|
|
|
|
* @date 2018-12-18
|
|
|
|
|
* @desc description
|
|
|
|
|
* @param [array] $params [输入参数]
|
|
|
|
|
*/
|
|
|
|
|
public static function PluginsDelete($params = [])
|
|
|
|
|
{
|
|
|
|
|
// 请求参数
|
|
|
|
|
$p = [
|
|
|
|
|
[
|
|
|
|
|
'checked_type' => 'empty',
|
|
|
|
|
'key_name' => 'id',
|
2023-02-04 16:47:48 +08:00
|
|
|
|
'error_msg' => MyLang('data_id_error_tips'),
|
2019-02-13 16:25:48 +08:00
|
|
|
|
],
|
|
|
|
|
];
|
|
|
|
|
$ret = ParamsChecked($params, $p);
|
|
|
|
|
if($ret !== true)
|
|
|
|
|
{
|
|
|
|
|
return DataReturn($ret, -1);
|
|
|
|
|
}
|
2019-06-24 18:45:36 +08:00
|
|
|
|
|
|
|
|
|
// 应用是否存在
|
2021-02-18 21:59:49 +08:00
|
|
|
|
$plugins = $params['id'];
|
|
|
|
|
if(!file_exists(APP_PATH.'plugins'.DS.$plugins))
|
2019-06-24 18:45:36 +08:00
|
|
|
|
{
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('common_service.pluginsadmin.app_no_exist_tips'), -10);
|
2019-06-24 18:45:36 +08:00
|
|
|
|
}
|
2019-02-13 16:25:48 +08:00
|
|
|
|
|
|
|
|
|
// 获取应用标记
|
2021-02-18 21:59:49 +08:00
|
|
|
|
$data = Db::name('Plugins')->where(['plugins'=>$plugins])->find();
|
2019-06-24 18:45:36 +08:00
|
|
|
|
if(!empty($data['is_enable']))
|
2019-02-13 16:25:48 +08:00
|
|
|
|
{
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('common_service.pluginsadmin.please_uninstall_tips'), -10);
|
2019-02-13 16:25:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
2019-06-24 18:45:36 +08:00
|
|
|
|
// 钩子部署
|
|
|
|
|
$ret = self::PluginsHookDeployment();
|
|
|
|
|
if($ret['code'] == 0)
|
2019-02-13 16:25:48 +08:00
|
|
|
|
{
|
2019-06-24 18:45:36 +08:00
|
|
|
|
// 是否需要删除应用数据,sql运行
|
2021-02-18 21:59:49 +08:00
|
|
|
|
$is_delete_data = (isset($params['value']) && $params['value'] == 1);
|
2019-10-04 16:28:59 +08:00
|
|
|
|
|
2020-12-23 20:15:48 +08:00
|
|
|
|
// 删除数据
|
2021-02-18 21:59:49 +08:00
|
|
|
|
if($is_delete_data === true)
|
2019-02-14 11:33:41 +08:00
|
|
|
|
{
|
2020-12-23 20:15:48 +08:00
|
|
|
|
// 删除缓存
|
2021-02-18 21:59:49 +08:00
|
|
|
|
PluginsService::PluginsCacheDelete($plugins);
|
2020-12-23 20:15:48 +08:00
|
|
|
|
|
|
|
|
|
// 执行卸载sql
|
2021-02-18 21:59:49 +08:00
|
|
|
|
$uninstall_sql = APP_PATH.'plugins'.DS.$plugins.DS.'uninstall.sql';
|
2019-06-24 18:45:36 +08:00
|
|
|
|
if(file_exists($uninstall_sql))
|
2019-03-22 17:51:50 +08:00
|
|
|
|
{
|
2021-07-24 22:25:00 +08:00
|
|
|
|
SqlConsoleService::Implement(['sql'=>file_get_contents($uninstall_sql)]);
|
2019-03-22 17:51:50 +08:00
|
|
|
|
}
|
2019-06-24 18:45:36 +08:00
|
|
|
|
}
|
2019-12-12 10:14:57 +08:00
|
|
|
|
|
2022-02-24 17:35:35 +08:00
|
|
|
|
// 删除应用文件
|
|
|
|
|
self::PluginsResourcesDelete($plugins, $is_delete_data);
|
|
|
|
|
|
|
|
|
|
// 删除数据
|
|
|
|
|
if($is_delete_data === true)
|
|
|
|
|
{
|
|
|
|
|
// 删除数据库附件
|
|
|
|
|
ResourcesService::AttachmentPathTypeDelete('plugins_'.$plugins);
|
|
|
|
|
}
|
2019-12-12 10:14:57 +08:00
|
|
|
|
|
2021-02-18 21:59:49 +08:00
|
|
|
|
// 插件事件回调
|
|
|
|
|
PluginsService::PluginsEventCall($plugins, 'Delete', $params);
|
2020-12-23 20:15:48 +08:00
|
|
|
|
|
2023-01-19 17:44:03 +08:00
|
|
|
|
return DataReturn(MyLang('delete_success'), 0);
|
2019-02-13 16:25:48 +08:00
|
|
|
|
}
|
2019-02-14 11:33:41 +08:00
|
|
|
|
return $ret;
|
2019-02-13 16:25:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 应用资源删除
|
|
|
|
|
* @author Devil
|
|
|
|
|
* @blog http://gong.gg/
|
|
|
|
|
* @version 1.0.0
|
|
|
|
|
* @date 2019-02-13
|
|
|
|
|
* @desc description
|
2019-06-13 00:56:02 +08:00
|
|
|
|
* @param [string] $plugins [唯一标记]
|
2021-02-18 21:59:49 +08:00
|
|
|
|
* @param [boolean] $is_delete_data [是否删除应用数据]
|
2019-02-13 16:25:48 +08:00
|
|
|
|
*/
|
2021-02-18 21:59:49 +08:00
|
|
|
|
private static function PluginsResourcesDelete($plugins, $is_delete_data = false)
|
2019-02-13 16:25:48 +08:00
|
|
|
|
{
|
|
|
|
|
\base\FileUtil::UnlinkDir(APP_PATH.'plugins'.DS.$plugins);
|
|
|
|
|
\base\FileUtil::UnlinkDir(APP_PATH.'plugins'.DS.'view'.DS.$plugins);
|
|
|
|
|
\base\FileUtil::UnlinkDir(ROOT.'public'.DS.'static'.DS.'plugins'.DS.'css'.DS.$plugins);
|
|
|
|
|
\base\FileUtil::UnlinkDir(ROOT.'public'.DS.'static'.DS.'plugins'.DS.'js'.DS.$plugins);
|
|
|
|
|
\base\FileUtil::UnlinkDir(ROOT.'public'.DS.'static'.DS.'plugins'.DS.'images'.DS.$plugins);
|
2019-06-13 00:56:02 +08:00
|
|
|
|
|
|
|
|
|
// 是否需要删除应用数据
|
2021-02-18 21:59:49 +08:00
|
|
|
|
if($is_delete_data === true)
|
2019-06-13 00:56:02 +08:00
|
|
|
|
{
|
|
|
|
|
\base\FileUtil::UnlinkDir(ROOT.'public'.DS.'static'.DS.'upload'.DS.'images'.DS.'plugins_'.$plugins);
|
|
|
|
|
\base\FileUtil::UnlinkDir(ROOT.'public'.DS.'static'.DS.'upload'.DS.'video'.DS.'plugins_'.$plugins);
|
|
|
|
|
\base\FileUtil::UnlinkDir(ROOT.'public'.DS.'static'.DS.'upload'.DS.'file'.DS.'plugins_'.$plugins);
|
|
|
|
|
}
|
2019-02-13 16:25:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 保存
|
|
|
|
|
* @author Devil
|
|
|
|
|
* @blog http://gong.gg/
|
|
|
|
|
* @version 1.0.0
|
|
|
|
|
* @date 2018-12-18
|
|
|
|
|
* @desc description
|
|
|
|
|
* @param [array] $params [输入参数]
|
|
|
|
|
*/
|
|
|
|
|
public static function PluginsSave($params = [])
|
|
|
|
|
{
|
|
|
|
|
// 请求参数
|
|
|
|
|
$p = [
|
|
|
|
|
[
|
|
|
|
|
'checked_type' => 'empty',
|
|
|
|
|
'key_name' => 'plugins',
|
2023-02-09 19:04:35 +08:00
|
|
|
|
'error_msg' => MyLang('common_service.pluginsadmin.form_item_plugins_message'),
|
2019-02-13 16:25:48 +08:00
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'checked_type' => 'empty',
|
|
|
|
|
'key_name' => 'logo',
|
2023-02-09 19:04:35 +08:00
|
|
|
|
'error_msg' => MyLang('common_service.pluginsadmin.form_item_logo_message'),
|
2019-02-13 16:25:48 +08:00
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'checked_type' => 'empty',
|
|
|
|
|
'key_name' => 'name',
|
2023-02-09 19:04:35 +08:00
|
|
|
|
'error_msg' => MyLang('common_service.pluginsadmin.form_item_name_message'),
|
2019-02-13 16:25:48 +08:00
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'checked_type' => 'empty',
|
|
|
|
|
'key_name' => 'author',
|
2023-02-09 19:04:35 +08:00
|
|
|
|
'error_msg' => MyLang('common_service.pluginsadmin.form_item_author_message'),
|
2019-02-13 16:25:48 +08:00
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'checked_type' => 'empty',
|
|
|
|
|
'key_name' => 'author_url',
|
2023-02-09 19:04:35 +08:00
|
|
|
|
'error_msg' => MyLang('common_service.pluginsadmin.form_item_author_url_message'),
|
2019-02-13 16:25:48 +08:00
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'checked_type' => 'empty',
|
|
|
|
|
'key_name' => 'version',
|
2023-02-09 19:04:35 +08:00
|
|
|
|
'error_msg' => MyLang('common_service.pluginsadmin.form_item_version_message'),
|
2019-02-13 16:25:48 +08:00
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'checked_type' => 'empty',
|
|
|
|
|
'key_name' => 'desc',
|
2023-02-09 19:04:35 +08:00
|
|
|
|
'error_msg' => MyLang('common_service.pluginsadmin.form_item_desc_message'),
|
2019-02-13 16:25:48 +08:00
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'checked_type' => 'empty',
|
|
|
|
|
'key_name' => 'apply_terminal',
|
2023-02-09 19:04:35 +08:00
|
|
|
|
'error_msg' => MyLang('common_service.pluginsadmin.form_item_apply_terminal_message'),
|
2019-02-13 16:25:48 +08:00
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'checked_type' => 'empty',
|
|
|
|
|
'key_name' => 'apply_version',
|
2023-02-09 19:04:35 +08:00
|
|
|
|
'error_msg' => MyLang('common_service.pluginsadmin.form_item_apply_version_message'),
|
2019-02-13 16:25:48 +08:00
|
|
|
|
],
|
|
|
|
|
];
|
|
|
|
|
$ret = ParamsChecked($params, $p);
|
|
|
|
|
if($ret !== true)
|
|
|
|
|
{
|
|
|
|
|
return DataReturn($ret, -1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 权限校验
|
2019-02-13 18:15:06 +08:00
|
|
|
|
$ret = self::PowerCheck();
|
2019-02-13 16:25:48 +08:00
|
|
|
|
if($ret['code'] != 0)
|
|
|
|
|
{
|
|
|
|
|
return $ret;
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-13 18:15:06 +08:00
|
|
|
|
// 应用唯一标记
|
|
|
|
|
$plugins = trim($params['plugins']);
|
|
|
|
|
|
2019-06-24 18:45:36 +08:00
|
|
|
|
// 应用校验
|
|
|
|
|
$ret = self::PluginsVerification($plugins);
|
2019-02-13 16:25:48 +08:00
|
|
|
|
if($ret['code'] != 0)
|
|
|
|
|
{
|
|
|
|
|
return $ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 应用目录不存在则创建
|
|
|
|
|
$app_dir = APP_PATH.'plugins'.DS.$plugins;
|
2021-01-05 14:48:01 +08:00
|
|
|
|
if(!is_dir($app_dir) && \base\FileUtil::CreateDir($app_dir) !== true)
|
2019-02-13 16:25:48 +08:00
|
|
|
|
{
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('common_service.pluginsadmin.app_dir_create_fial_tips'), -10);
|
2019-02-13 16:25:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 生成配置文件
|
|
|
|
|
$ret = self::PluginsConfigCreated($params, $app_dir);
|
|
|
|
|
if($ret['code'] != 0)
|
|
|
|
|
{
|
|
|
|
|
return $ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 应用主文件生成
|
2019-02-14 23:06:04 +08:00
|
|
|
|
$ret = self::PluginsApplicationCreated($params, $app_dir);
|
|
|
|
|
if($ret['code'] != 0)
|
2019-02-13 16:25:48 +08:00
|
|
|
|
{
|
2019-02-14 23:06:04 +08:00
|
|
|
|
return $ret;
|
2019-02-13 16:25:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-01-19 17:44:03 +08:00
|
|
|
|
return DataReturn(MyLang('operate_success'), 0);
|
2019-02-13 16:25:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 应用文件生成
|
|
|
|
|
* @author Devil
|
|
|
|
|
* @blog http://gong.gg/
|
|
|
|
|
* @version 1.0.0
|
|
|
|
|
* @date 2018-12-18
|
|
|
|
|
* @desc description
|
|
|
|
|
* @param [array] $params [输入参数]
|
|
|
|
|
* @param [string] $app_dir [主目录地址]
|
|
|
|
|
*/
|
|
|
|
|
private static function PluginsApplicationCreated($params, $app_dir)
|
|
|
|
|
{
|
|
|
|
|
$plugins = trim($params['plugins']);
|
|
|
|
|
$admin=<<<php
|
|
|
|
|
<?php
|
2019-05-09 01:15:36 +08:00
|
|
|
|
namespace app\plugins\\$plugins\admin;
|
2019-02-26 22:45:47 +08:00
|
|
|
|
|
2021-07-19 09:48:40 +08:00
|
|
|
|
// {$params['name']} - 后台管理
|
|
|
|
|
class Admin
|
2019-02-13 16:25:48 +08:00
|
|
|
|
{
|
|
|
|
|
// 后台管理入口
|
|
|
|
|
public function index(\$params = [])
|
|
|
|
|
{
|
|
|
|
|
// 数组组装
|
2021-07-19 09:48:40 +08:00
|
|
|
|
MyViewAssign('data', ['hello', 'world!']);
|
|
|
|
|
MyViewAssign('msg', 'hello world! admin');
|
|
|
|
|
return MyView('../../../plugins/view/$plugins/admin/admin/index');
|
2019-02-13 16:25:48 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
?>
|
|
|
|
|
php;
|
|
|
|
|
|
|
|
|
|
$hook=<<<php
|
|
|
|
|
<?php
|
|
|
|
|
namespace app\plugins\\$plugins;
|
2019-02-26 22:45:47 +08:00
|
|
|
|
|
2021-07-19 09:48:40 +08:00
|
|
|
|
// {$params['name']} - 钩子入口
|
|
|
|
|
class Hook
|
2019-02-13 16:25:48 +08:00
|
|
|
|
{
|
|
|
|
|
// 应用响应入口
|
2021-07-19 09:48:40 +08:00
|
|
|
|
public function handle(\$params = [])
|
2019-02-13 16:25:48 +08:00
|
|
|
|
{
|
|
|
|
|
// 是否控制器钩子
|
2019-02-26 22:45:47 +08:00
|
|
|
|
// is_backend 当前为后端业务处理
|
2019-02-14 23:06:04 +08:00
|
|
|
|
// hook_name 钩子名称
|
2019-02-26 22:45:47 +08:00
|
|
|
|
if(isset(\$params['is_backend']) && \$params['is_backend'] === true && !empty(\$params['hook_name']))
|
2019-02-13 16:25:48 +08:00
|
|
|
|
{
|
2019-02-14 23:06:04 +08:00
|
|
|
|
// 参数一 描述
|
|
|
|
|
// 参数二 0 为处理成功, 负数为失败
|
|
|
|
|
// 参数三 返回数据
|
|
|
|
|
return DataReturn('返回描述', 0);
|
2019-02-13 16:25:48 +08:00
|
|
|
|
|
|
|
|
|
// 默认返回视图
|
|
|
|
|
} else {
|
|
|
|
|
return 'hello world!';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
?>
|
|
|
|
|
php;
|
|
|
|
|
|
|
|
|
|
$index=<<<php
|
|
|
|
|
<?php
|
2019-05-09 01:15:36 +08:00
|
|
|
|
namespace app\plugins\\$plugins\index;
|
2019-02-26 22:45:47 +08:00
|
|
|
|
|
2021-07-19 09:48:40 +08:00
|
|
|
|
// {$params['name']} - 前端独立页面入口
|
|
|
|
|
class Index
|
2019-02-13 16:25:48 +08:00
|
|
|
|
{
|
|
|
|
|
// 前端页面入口
|
|
|
|
|
public function index(\$params = [])
|
|
|
|
|
{
|
|
|
|
|
// 数组组装
|
2021-07-19 09:48:40 +08:00
|
|
|
|
MyViewAssign('data', ['hello', 'world!']);
|
|
|
|
|
MyViewAssign('msg', 'hello world! index');
|
|
|
|
|
return MyView('../../../plugins/view/$plugins/index/index/index');
|
2019-02-13 16:25:48 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
?>
|
|
|
|
|
php;
|
|
|
|
|
|
|
|
|
|
$admin_view=<<<php
|
|
|
|
|
{{include file="public/header" /}}
|
|
|
|
|
|
|
|
|
|
<!-- right content start -->
|
|
|
|
|
<div class="content-right">
|
|
|
|
|
<div class="content">
|
|
|
|
|
<h1>后台管理页面</h1>
|
|
|
|
|
{{:print_r(\$data)}}
|
|
|
|
|
<p class="msg">{{\$msg}}</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<!-- right content end -->
|
2023-08-27 16:59:15 +08:00
|
|
|
|
|
2019-02-13 16:25:48 +08:00
|
|
|
|
<!-- footer start -->
|
|
|
|
|
{{include file="public/footer" /}}
|
|
|
|
|
<!-- footer end -->
|
|
|
|
|
php;
|
|
|
|
|
|
|
|
|
|
$index_view=<<<php
|
|
|
|
|
{{include file="public/header" /}}
|
|
|
|
|
|
|
|
|
|
<!-- nav start -->
|
|
|
|
|
{{include file="public/nav" /}}
|
|
|
|
|
<!-- nav end -->
|
|
|
|
|
|
|
|
|
|
<!-- header top nav -->
|
|
|
|
|
{{include file="public/header_top_nav" /}}
|
|
|
|
|
|
|
|
|
|
<!-- search -->
|
|
|
|
|
{{include file="public/nav_search" /}}
|
|
|
|
|
|
|
|
|
|
<!-- header nav -->
|
|
|
|
|
{{include file="public/header_nav" /}}
|
|
|
|
|
|
|
|
|
|
<!-- goods category -->
|
|
|
|
|
{{include file="public/goods_category" /}}
|
|
|
|
|
|
|
|
|
|
<!-- content start -->
|
|
|
|
|
<div class="am-g my-content">
|
|
|
|
|
<div class="am-u-md-6 am-u-sm-centered">
|
|
|
|
|
<h1>前端页面</h1>
|
|
|
|
|
{{:print_r(\$data)}}
|
|
|
|
|
<p class="msg">{{\$msg}}</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<!-- content end -->
|
|
|
|
|
|
|
|
|
|
<!-- footer start -->
|
|
|
|
|
{{include file="public/footer" /}}
|
|
|
|
|
<!-- footer end -->
|
|
|
|
|
php;
|
|
|
|
|
|
|
|
|
|
$admin_css=<<<php
|
|
|
|
|
h1 {
|
|
|
|
|
font-size: 60px;
|
|
|
|
|
}
|
|
|
|
|
.msg {
|
|
|
|
|
font-size: 38px;
|
|
|
|
|
color: #F00;
|
|
|
|
|
}
|
|
|
|
|
php;
|
|
|
|
|
|
|
|
|
|
$index_css=<<<php
|
|
|
|
|
h1 {
|
|
|
|
|
font-size: 60px;
|
|
|
|
|
}
|
|
|
|
|
.msg {
|
|
|
|
|
font-size: 68px;
|
|
|
|
|
color: #4CAF50;
|
|
|
|
|
}
|
|
|
|
|
php;
|
2019-02-14 23:06:04 +08:00
|
|
|
|
// 静态文件目录
|
2019-02-13 16:25:48 +08:00
|
|
|
|
$app_static_css_dir = ROOT.'public'.DS.'static'.DS.'plugins'.DS.'css'.DS.trim($params['plugins']);
|
2021-01-05 14:48:01 +08:00
|
|
|
|
if(!is_dir($app_static_css_dir) && \base\FileUtil::CreateDir($app_static_css_dir) !== true)
|
2019-02-13 16:25:48 +08:00
|
|
|
|
{
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('common_service.pluginsadmin.app_static_dir_create_fail_tips').'[css]', -10);
|
2019-04-30 16:27:01 +08:00
|
|
|
|
} else {
|
|
|
|
|
// 后端css目录创建
|
2021-01-05 14:48:01 +08:00
|
|
|
|
if(!is_dir($app_static_css_dir.DS.'admin') && \base\FileUtil::CreateDir($app_static_css_dir.DS.'admin') !== true)
|
2019-04-30 16:27:01 +08:00
|
|
|
|
{
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('common_service.pluginsadmin.app_static_dir_create_fail_tips').'[css/admin]', -10);
|
2019-04-30 16:27:01 +08:00
|
|
|
|
}
|
2019-02-13 16:25:48 +08:00
|
|
|
|
}
|
2019-02-14 23:06:04 +08:00
|
|
|
|
|
2021-01-05 14:48:01 +08:00
|
|
|
|
// 后端admin目录创建
|
|
|
|
|
if(!is_dir($app_dir.DS.'admin') && \base\FileUtil::CreateDir($app_dir.DS.'admin') !== true)
|
2019-02-13 16:25:48 +08:00
|
|
|
|
{
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('common_service.pluginsadmin.app_admin_dir_create_fail_tips').'[admin]', -10);
|
2021-01-05 14:48:01 +08:00
|
|
|
|
}
|
2019-02-14 23:06:04 +08:00
|
|
|
|
|
2021-01-05 14:48:01 +08:00
|
|
|
|
// 创建文件
|
|
|
|
|
if(!file_exists($app_dir.DS.'admin'.DS.'Admin.php') && @file_put_contents($app_dir.DS.'admin'.DS.'Admin.php', $admin) === false)
|
|
|
|
|
{
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('common_service.pluginsadmin.app_file_create_fail_tips').'[Admin.php]', -11);
|
2021-01-05 14:48:01 +08:00
|
|
|
|
}
|
|
|
|
|
if(!file_exists($app_dir.DS.'Hook.php') && @file_put_contents($app_dir.DS.'Hook.php', $hook) === false)
|
|
|
|
|
{
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('common_service.pluginsadmin.app_file_create_fail_tips').'[Hook.php]', -11);
|
2021-01-05 14:48:01 +08:00
|
|
|
|
}
|
2019-02-14 23:06:04 +08:00
|
|
|
|
|
2021-01-05 14:48:01 +08:00
|
|
|
|
// 应用后台视图目录不存在则创建
|
|
|
|
|
$app_view_admin_dir = APP_PATH.'plugins'.DS.'view'.DS.trim($params['plugins']).DS.'admin'.DS.'admin';
|
|
|
|
|
if(!is_dir($app_view_admin_dir) && \base\FileUtil::CreateDir($app_view_admin_dir) !== true)
|
|
|
|
|
{
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('common_service.pluginsadmin.app_view_dir_create_fail_tips').'[admin]', -10);
|
2021-01-05 14:48:01 +08:00
|
|
|
|
}
|
|
|
|
|
if(!file_exists($app_view_admin_dir.DS.'index.html') && @file_put_contents($app_view_admin_dir.DS.'index.html', $admin_view) === false)
|
|
|
|
|
{
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('common_service.pluginsadmin.app_view_file_create_fail_tips').'[admin-view]', -11);
|
2019-02-13 16:25:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
2021-01-05 14:48:01 +08:00
|
|
|
|
// css创建
|
|
|
|
|
if(!file_exists($app_static_css_dir.DS.'admin'.DS.'admin.css') && @file_put_contents($app_static_css_dir.DS.'admin'.DS.'admin.css', $admin_css) === false)
|
|
|
|
|
{
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('common_service.pluginsadmin.app_static_file_create_fail_tips').'[admin-css]', -11);
|
2021-01-05 14:48:01 +08:00
|
|
|
|
}
|
2019-02-13 16:25:48 +08:00
|
|
|
|
|
|
|
|
|
// 是否有前端页面
|
|
|
|
|
if(isset($params['is_home']) && $params['is_home'] == 1)
|
|
|
|
|
{
|
2019-05-09 01:15:36 +08:00
|
|
|
|
// 前端index目录创建
|
2021-01-05 14:48:01 +08:00
|
|
|
|
if(!is_dir($app_dir.DS.'index') && \base\FileUtil::CreateDir($app_dir.DS.'index') !== true)
|
2019-05-09 01:15:36 +08:00
|
|
|
|
{
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('common_service.pluginsadmin.app_home_dir_create_fail_tips').'[index]', -10);
|
2019-05-09 01:15:36 +08:00
|
|
|
|
}
|
|
|
|
|
|
2019-02-13 16:25:48 +08:00
|
|
|
|
// 创建文件
|
2019-05-09 01:15:36 +08:00
|
|
|
|
if(!file_exists($app_dir.DS.'index'.DS.'Index.php') && @file_put_contents($app_dir.DS.'index'.DS.'Index.php', $index) === false)
|
2019-02-13 16:25:48 +08:00
|
|
|
|
{
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('common_service.pluginsadmin.app_file_create_fail_tips').'[index]', -11);
|
2019-02-13 16:25:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 应用前端视图目录不存在则创建
|
2019-05-09 01:15:36 +08:00
|
|
|
|
$app_view_index_dir = APP_PATH.'plugins'.DS.'view'.DS.trim($params['plugins']).DS.'index'.DS.'index';
|
2019-04-30 18:11:43 +08:00
|
|
|
|
if(!is_dir($app_view_index_dir) && \base\FileUtil::CreateDir($app_view_index_dir) !== true)
|
2019-02-13 16:25:48 +08:00
|
|
|
|
{
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('common_service.pluginsadmin.app_view_dir_create_fail_tips').'[index]', -10);
|
2019-02-13 16:25:48 +08:00
|
|
|
|
}
|
2019-04-30 18:11:43 +08:00
|
|
|
|
if(!file_exists($app_view_index_dir.DS.'index.html') && @file_put_contents($app_view_index_dir.DS.'index.html', $index_view) === false)
|
2019-02-13 16:25:48 +08:00
|
|
|
|
{
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('common_service.pluginsadmin.app_view_file_create_fail_tips').'[index-view]', -11);
|
2019-02-13 16:25:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
2019-04-30 16:27:01 +08:00
|
|
|
|
// 前端css目录创建
|
2019-04-30 18:11:43 +08:00
|
|
|
|
if(!is_dir($app_static_css_dir.DS.'index') && \base\FileUtil::CreateDir($app_static_css_dir.DS.'index') !== true)
|
2019-04-30 16:27:01 +08:00
|
|
|
|
{
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('common_service.pluginsadmin.app_static_dir_create_fail_tips').'[css/index]', -10);
|
2019-04-30 16:27:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
2019-02-13 16:25:48 +08:00
|
|
|
|
// css创建
|
2019-04-30 18:11:43 +08:00
|
|
|
|
if(!file_exists($app_static_css_dir.DS.'index'.DS.'index.css') && @file_put_contents($app_static_css_dir.DS.'index'.DS.'index.css', $index_css) === false)
|
2019-02-13 16:25:48 +08:00
|
|
|
|
{
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('common_service.pluginsadmin.app_static_file_create_fail_tips').'[index-css]', -11);
|
2019-02-13 16:25:48 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-19 17:44:03 +08:00
|
|
|
|
return DataReturn(MyLang('operate_success'), 0);
|
2019-02-13 16:25:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 应用配置文件生成
|
|
|
|
|
* @author Devil
|
|
|
|
|
* @blog http://gong.gg/
|
|
|
|
|
* @version 1.0.0
|
|
|
|
|
* @date 2018-12-18
|
|
|
|
|
* @desc description
|
|
|
|
|
* @param [array] $params [输入参数]
|
|
|
|
|
* @param [string] $app_dir [主目录地址]
|
|
|
|
|
*/
|
|
|
|
|
private static function PluginsConfigCreated($params, $app_dir)
|
|
|
|
|
{
|
2019-02-14 12:15:20 +08:00
|
|
|
|
// 模块名称
|
|
|
|
|
$plugins = trim($params['plugins']);
|
|
|
|
|
|
|
|
|
|
// 配置信息
|
|
|
|
|
$config = self::GetPluginsConfig($plugins);
|
2021-07-21 15:15:46 +08:00
|
|
|
|
$hook = (empty($config) || empty($config['hook'])) ? [] : $config['hook'];
|
2019-02-14 12:15:20 +08:00
|
|
|
|
|
|
|
|
|
// 配置信息组装
|
2019-02-13 16:25:48 +08:00
|
|
|
|
$data = [
|
|
|
|
|
// 基础信息
|
|
|
|
|
'base' => [
|
2019-02-14 12:15:20 +08:00
|
|
|
|
'plugins' => $plugins,
|
2019-02-13 16:25:48 +08:00
|
|
|
|
'name' => $params['name'],
|
2019-08-21 09:52:47 +08:00
|
|
|
|
'logo' => ResourcesService::AttachmentPathHandle($params['logo']),
|
2019-02-13 16:25:48 +08:00
|
|
|
|
'author' => $params['author'],
|
|
|
|
|
'author_url' => $params['author_url'],
|
|
|
|
|
'version' => $params['version'],
|
|
|
|
|
'desc' => $params['desc'],
|
|
|
|
|
'apply_terminal' => explode(',', $params['apply_terminal']),
|
|
|
|
|
'apply_version' => explode(',', $params['apply_version']),
|
|
|
|
|
'is_home' => (isset($params['is_home']) && $params['is_home'] == 1) ? true : false,
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
// 钩子配置
|
2019-02-14 12:15:20 +08:00
|
|
|
|
'hook' => (object) $hook,
|
2019-02-13 16:25:48 +08:00
|
|
|
|
];
|
|
|
|
|
|
2021-01-05 14:48:01 +08:00
|
|
|
|
// 文件是否存在、存在判断权限、则创建
|
2019-02-14 12:22:02 +08:00
|
|
|
|
$config_file = $app_dir.DS.'config.json';
|
2021-01-05 14:48:01 +08:00
|
|
|
|
if(file_exists($config_file))
|
2019-02-14 12:22:02 +08:00
|
|
|
|
{
|
2021-01-05 14:48:01 +08:00
|
|
|
|
// 文件存在是否有权限
|
|
|
|
|
if(!is_writable($config_file))
|
|
|
|
|
{
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('common_service.pluginsadmin.app_config_no_power_tips').'['.$config_file.']', -3);
|
2021-01-05 14:48:01 +08:00
|
|
|
|
}
|
2021-01-06 20:09:24 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 创建配置文件
|
|
|
|
|
if(@file_put_contents($config_file, JsonFormat($data)) === false)
|
|
|
|
|
{
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('common_service.pluginsadmin.app_config_create_tail_tips'), -10);
|
2019-02-13 16:25:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-01-19 17:44:03 +08:00
|
|
|
|
return DataReturn(MyLang('operate_success'), 0);
|
2019-02-13 16:25:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
2019-05-13 00:38:18 +08:00
|
|
|
|
/**
|
2023-02-09 19:04:35 +08:00
|
|
|
|
* 名称排除校验
|
2019-05-13 00:38:18 +08:00
|
|
|
|
* @author Devil
|
|
|
|
|
* @blog http://gong.gg/
|
|
|
|
|
* @version 1.0.0
|
|
|
|
|
* @datetime 2019-05-13T00:00:45+0800
|
2019-06-24 18:45:36 +08:00
|
|
|
|
* @param [string] $plugins [应用唯一标记]
|
2019-05-13 00:38:18 +08:00
|
|
|
|
*/
|
2019-06-24 18:45:36 +08:00
|
|
|
|
public static function PluginsVerification($plugins)
|
2019-05-13 00:38:18 +08:00
|
|
|
|
{
|
|
|
|
|
if(in_array($plugins, self::$plugins_exclude_verification))
|
|
|
|
|
{
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('common_service.pluginsadmin.app_name_exclude_tips').'['.$plugins.']', -1);
|
2019-05-13 00:38:18 +08:00
|
|
|
|
}
|
2023-02-04 16:47:48 +08:00
|
|
|
|
return DataReturn(MyLang('check_success'), 0);
|
2019-05-13 00:38:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
2019-02-13 16:25:48 +08:00
|
|
|
|
/**
|
2021-04-23 16:43:23 +08:00
|
|
|
|
* 应用是否存在
|
2019-02-13 16:25:48 +08:00
|
|
|
|
* @author Devil
|
|
|
|
|
* @blog http://gong.gg/
|
|
|
|
|
* @version 1.0.0
|
|
|
|
|
* @date 2018-12-18
|
|
|
|
|
* @desc description
|
|
|
|
|
* @param [string] $plugins [应用唯一标记]
|
|
|
|
|
*/
|
2019-06-24 18:45:36 +08:00
|
|
|
|
private static function PluginsExist($plugins)
|
2019-02-13 16:25:48 +08:00
|
|
|
|
{
|
2021-04-23 16:43:23 +08:00
|
|
|
|
return is_dir(APP_PATH.'plugins'.DS.$plugins);
|
2019-02-13 16:25:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 权限校验
|
|
|
|
|
* @author Devil
|
|
|
|
|
* @blog http://gong.gg/
|
|
|
|
|
* @version 1.0.0
|
|
|
|
|
* @datetime 2018-09-29T00:01:49+0800
|
|
|
|
|
*/
|
2019-02-13 18:15:06 +08:00
|
|
|
|
private static function PowerCheck()
|
2019-02-13 16:25:48 +08:00
|
|
|
|
{
|
|
|
|
|
// 应用目录
|
|
|
|
|
$app_dir = APP_PATH.'plugins';
|
|
|
|
|
if(!is_writable($app_dir))
|
|
|
|
|
{
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('common_service.pluginsadmin.app_dir_no_power_tips').'['.$app_dir.']', -3);
|
2019-02-13 16:25:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 应用视图目录
|
|
|
|
|
$app_view_dir = APP_PATH.'plugins'.DS.'view';
|
|
|
|
|
if(!is_writable($app_view_dir))
|
|
|
|
|
{
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('common_service.pluginsadmin.app_view_dir_no_power_tips').'['.$app_view_dir.']', -3);
|
2019-02-13 16:25:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 应用css目录
|
|
|
|
|
$app_static_css_dir = ROOT.'public'.DS.'static'.DS.'plugins'.DS.'css';
|
|
|
|
|
if(!is_writable($app_static_css_dir))
|
|
|
|
|
{
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('common_service.pluginsadmin.app_css_dir_no_power_tips').'['.$app_static_css_dir.']', -3);
|
2019-02-13 16:25:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 应用js目录
|
|
|
|
|
$app_static_js_dir = ROOT.'public'.DS.'static'.DS.'plugins'.DS.'js';
|
|
|
|
|
if(!is_writable($app_static_js_dir))
|
|
|
|
|
{
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('common_service.pluginsadmin.app_js_dir_no_power_tips').'['.$app_static_js_dir.']', -3);
|
2019-02-13 16:25:48 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 应用images目录
|
|
|
|
|
$app_static_images_dir = ROOT.'public'.DS.'static'.DS.'plugins'.DS.'images';
|
|
|
|
|
if(!is_writable($app_static_images_dir))
|
|
|
|
|
{
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('common_service.pluginsadmin.app_images_dir_no_power_tips').'['.$app_static_images_dir.']', -3);
|
2019-02-13 16:25:48 +08:00
|
|
|
|
}
|
2019-06-16 18:02:45 +08:00
|
|
|
|
|
|
|
|
|
// 应用upload目录
|
|
|
|
|
$app_upload_dir = ROOT.'public'.DS.'static'.DS.'upload';
|
|
|
|
|
if(!is_writable($app_upload_dir))
|
|
|
|
|
{
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('common_service.pluginsadmin.app_upload_dir_no_power_tips').'['.$app_upload_dir.']', -3);
|
2019-06-16 18:02:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn('success', 0);
|
2019-02-13 16:25:48 +08:00
|
|
|
|
}
|
2019-02-13 18:15:06 +08:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 应用上传
|
|
|
|
|
* @author Devil
|
|
|
|
|
* @blog http://gong.gg/
|
|
|
|
|
* @version 1.0.0
|
|
|
|
|
* @datetime 2018-12-19T00:53:45+0800
|
|
|
|
|
* @param [array] $params [输入参数]
|
|
|
|
|
*/
|
|
|
|
|
public static function PluginsUpload($params = [])
|
|
|
|
|
{
|
|
|
|
|
// 文件上传校验
|
|
|
|
|
$error = FileUploadError('file');
|
|
|
|
|
if($error !== true)
|
|
|
|
|
{
|
|
|
|
|
return DataReturn($error, -1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 文件格式化校验
|
2021-02-15 22:45:33 +08:00
|
|
|
|
$type = ResourcesService::ZipExtTypeList();
|
2019-02-13 18:15:06 +08:00
|
|
|
|
if(!in_array($_FILES['file']['type'], $type))
|
|
|
|
|
{
|
2023-02-06 18:30:08 +08:00
|
|
|
|
return DataReturn(MyLang('form_upload_zip_message'), -2);
|
2019-02-13 18:15:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
2021-02-23 12:16:31 +08:00
|
|
|
|
// 上传处理
|
|
|
|
|
return self::PluginsUploadHandle($_FILES['file']['tmp_name'], $params);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 应用上传处理
|
|
|
|
|
* @author Devil
|
|
|
|
|
* @blog http://gong.gg/
|
|
|
|
|
* @version 1.0.0
|
|
|
|
|
* @datetime 2018-12-19T00:53:45+0800
|
|
|
|
|
* @param [string] $package_file [软件包地址]
|
|
|
|
|
* @param [array] $params [输入参数]
|
|
|
|
|
*/
|
|
|
|
|
public static function PluginsUploadHandle($package_file, $params = [])
|
|
|
|
|
{
|
2019-02-13 18:15:06 +08:00
|
|
|
|
// 权限校验
|
|
|
|
|
$ret = self::PowerCheck();
|
|
|
|
|
if($ret['code'] != 0)
|
|
|
|
|
{
|
|
|
|
|
return $ret;
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-24 13:02:01 +08:00
|
|
|
|
// 包处理
|
|
|
|
|
$ret = self::PluginsPackageHandle($package_file, 0);
|
|
|
|
|
if($ret['code'] != 0)
|
|
|
|
|
{
|
|
|
|
|
return $ret;
|
|
|
|
|
}
|
|
|
|
|
$plugins = $ret['data'];
|
|
|
|
|
|
2022-01-23 18:30:56 +08:00
|
|
|
|
// 强制刷新用户权限缓存
|
2022-05-16 16:35:50 +08:00
|
|
|
|
AdminPowerService::PowerMenuInit(null, true);
|
2022-01-23 18:30:56 +08:00
|
|
|
|
|
2021-04-24 13:02:01 +08:00
|
|
|
|
// 附件同步到数据库
|
|
|
|
|
ResourcesService::AttachmentDiskFilesToDb('plugins_'.$plugins);
|
|
|
|
|
|
|
|
|
|
// sql运行
|
|
|
|
|
$install_sql = APP_PATH.'plugins'.DS.$plugins.DS.'install.sql';
|
|
|
|
|
if(!empty($plugins) && file_exists($install_sql))
|
|
|
|
|
{
|
2021-07-24 22:25:00 +08:00
|
|
|
|
SqlConsoleService::Implement(['sql'=>file_get_contents($install_sql)]);
|
2021-04-24 13:02:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 插件事件回调
|
|
|
|
|
PluginsService::PluginsEventCall($plugins, 'Upload', $params);
|
|
|
|
|
|
2023-02-04 16:47:48 +08:00
|
|
|
|
return DataReturn(MyLang('install_success'), 0);
|
2021-04-24 13:02:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 插件包处理
|
|
|
|
|
* @author Devil
|
|
|
|
|
* @blog http://gong.gg/
|
|
|
|
|
* @version 1.0.0
|
|
|
|
|
* @date 2021-04-24
|
|
|
|
|
* @desc description
|
|
|
|
|
* @param [string] $package_file [包地址]
|
|
|
|
|
* @param [int] $type [类型(0上传, 1更新)]
|
|
|
|
|
* @param [string] $plugins_old [原插件标识名称]
|
|
|
|
|
*/
|
|
|
|
|
public static function PluginsPackageHandle($package_file, $type = 0, $plugins_old = '')
|
|
|
|
|
{
|
2019-02-14 11:33:41 +08:00
|
|
|
|
// 资源目录
|
2021-04-23 16:43:23 +08:00
|
|
|
|
$dir_list = self::PluginsDirStructureMapping();
|
2019-02-14 11:33:41 +08:00
|
|
|
|
|
|
|
|
|
// 包名
|
2021-02-18 21:59:49 +08:00
|
|
|
|
$plugins = '';
|
2019-02-14 11:33:41 +08:00
|
|
|
|
|
2019-02-13 18:15:06 +08:00
|
|
|
|
// 开始解压文件
|
2021-08-11 17:30:06 +08:00
|
|
|
|
$zip = new \ZipArchive();
|
|
|
|
|
$resource = $zip->open($package_file);
|
|
|
|
|
if($resource != true)
|
2019-03-28 18:31:06 +08:00
|
|
|
|
{
|
2023-02-06 18:30:08 +08:00
|
|
|
|
return DataReturn(MyLang('form_open_zip_message').'['.$resource.']', -11);
|
2019-03-28 18:31:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
2021-08-11 17:30:06 +08:00
|
|
|
|
// 文件第一个目录为当前插件名称
|
|
|
|
|
$entry = $zip->statIndex(0);
|
|
|
|
|
$file = $entry['name'];
|
|
|
|
|
//根据第一个文件是目录,还是包含namespace payment,判断插件类型
|
|
|
|
|
if(str_ends_with($file, '/'))
|
2019-02-13 18:15:06 +08:00
|
|
|
|
{
|
2021-08-11 17:30:06 +08:00
|
|
|
|
//获取plugins
|
|
|
|
|
$plugins = substr($file, 0, strpos($file, '/'));
|
2019-02-13 18:15:06 +08:00
|
|
|
|
|
2021-08-11 17:30:06 +08:00
|
|
|
|
// 业务类型处理
|
|
|
|
|
switch($type)
|
|
|
|
|
{
|
|
|
|
|
// 上传安装
|
|
|
|
|
case 0 :
|
|
|
|
|
// 应用不存在则添加
|
|
|
|
|
$ret = self::PluginsVerification($plugins);
|
|
|
|
|
if($ret['code'] != 0)
|
2019-11-22 15:30:08 +08:00
|
|
|
|
{
|
2021-08-11 17:30:06 +08:00
|
|
|
|
return $ret;
|
2019-11-22 15:30:08 +08:00
|
|
|
|
}
|
|
|
|
|
|
2021-08-11 17:30:06 +08:00
|
|
|
|
// 应用是否存在
|
|
|
|
|
if(self::PluginsExist($plugins))
|
2019-06-24 18:45:36 +08:00
|
|
|
|
{
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('common_service.pluginsadmin.app_name_exist_tips').'['.$plugins.']', -1);
|
2021-08-11 17:30:06 +08:00
|
|
|
|
}
|
|
|
|
|
break;
|
2021-04-24 13:02:01 +08:00
|
|
|
|
|
2021-08-11 17:30:06 +08:00
|
|
|
|
// 更新
|
|
|
|
|
case 1 :
|
|
|
|
|
// 应用是否存在
|
|
|
|
|
if($plugins != $plugins_old)
|
|
|
|
|
{
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('common_service.pluginsadmin.app_name_appoint_error_tips').'['.$plugins.'<>'.$plugins_old.']', -1);
|
2021-08-11 17:30:06 +08:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// 应用名称为空、则校验是否为支付插件
|
|
|
|
|
$stream = $zip->getStream($file);
|
|
|
|
|
if($stream !== false)
|
|
|
|
|
{
|
|
|
|
|
$file_content = stream_get_contents($stream);
|
|
|
|
|
if($file_content !== false)
|
|
|
|
|
{
|
|
|
|
|
if(stripos($file_content, 'namespace payment') !== false)
|
|
|
|
|
{
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('common_service.pluginsadmin.plugins_package_error_tips'), -1);
|
2019-02-14 11:33:41 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2021-08-11 17:30:06 +08:00
|
|
|
|
fclose($stream);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 不是支付插件则提示插件包错误
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('common_service.pluginsadmin.plugins_package_empty_tips'), -30);
|
2021-08-11 17:30:06 +08:00
|
|
|
|
}
|
2019-02-14 11:33:41 +08:00
|
|
|
|
|
2021-08-11 17:30:06 +08:00
|
|
|
|
// 应用文件处理
|
|
|
|
|
$success = 0;
|
|
|
|
|
for($i=0; $i<$zip->numFiles; $i++)
|
|
|
|
|
{
|
|
|
|
|
// 资源文件
|
|
|
|
|
$file = $zip->getNameIndex($i);
|
|
|
|
|
|
|
|
|
|
// 排除临时文件和临时目录
|
|
|
|
|
if(strpos($file, '/.') === false && strpos($file, '__') === false)
|
|
|
|
|
{
|
|
|
|
|
// 文件包对应系统所在目录
|
|
|
|
|
$is_has_find = false;
|
|
|
|
|
foreach($dir_list as $dir_key=>$dir_value)
|
2019-02-13 18:15:06 +08:00
|
|
|
|
{
|
2021-08-11 17:30:06 +08:00
|
|
|
|
if(strpos($file, $dir_key) !== false)
|
2019-02-13 18:15:06 +08:00
|
|
|
|
{
|
2021-08-11 17:30:06 +08:00
|
|
|
|
// 仅控制器模块支持php文件
|
|
|
|
|
if($dir_key != '_controller_')
|
2019-02-14 11:33:41 +08:00
|
|
|
|
{
|
2021-08-11 17:30:06 +08:00
|
|
|
|
// 排除后缀文件
|
|
|
|
|
$pos = strripos($file, '.');
|
|
|
|
|
if($pos !== false)
|
2020-08-15 11:25:48 +08:00
|
|
|
|
{
|
2021-08-11 17:30:06 +08:00
|
|
|
|
$info = pathinfo($file);
|
2022-02-05 15:48:08 +08:00
|
|
|
|
if(isset($info['extension']) && in_array(strtolower($info['extension']), self::$exclude_ext))
|
2020-08-15 11:25:48 +08:00
|
|
|
|
{
|
2021-08-11 17:30:06 +08:00
|
|
|
|
continue;
|
2020-08-15 11:25:48 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2019-02-14 11:33:41 +08:00
|
|
|
|
}
|
2019-02-13 18:15:06 +08:00
|
|
|
|
|
2021-08-11 17:30:06 +08:00
|
|
|
|
// 匹配成功文件路径处理、跳出循环
|
|
|
|
|
$new_file = str_replace($plugins.'/'.$dir_key.'/', '', $dir_value.$file);
|
|
|
|
|
$is_has_find = true;
|
|
|
|
|
break;
|
2019-02-14 12:39:15 +08:00
|
|
|
|
}
|
2021-08-11 17:30:06 +08:00
|
|
|
|
}
|
2019-02-14 12:39:15 +08:00
|
|
|
|
|
2021-08-11 17:30:06 +08:00
|
|
|
|
// 没有匹配到则指定目录跳过
|
|
|
|
|
if($is_has_find == false)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 截取文件路径
|
|
|
|
|
$file_path = substr($new_file, 0, strrpos($new_file, '/'));
|
2019-06-14 11:11:15 +08:00
|
|
|
|
|
2021-08-11 17:30:06 +08:00
|
|
|
|
// 路径不存在则创建
|
|
|
|
|
\base\FileUtil::CreateDir($file_path);
|
2019-02-13 18:15:06 +08:00
|
|
|
|
|
2021-08-11 17:30:06 +08:00
|
|
|
|
// 如果不是目录则写入文件
|
|
|
|
|
if(!is_dir($new_file))
|
|
|
|
|
{
|
|
|
|
|
// 读取这个文件
|
|
|
|
|
$stream = $zip->getStream($file);
|
|
|
|
|
if($stream !== false)
|
2019-02-13 18:15:06 +08:00
|
|
|
|
{
|
2021-08-11 17:30:06 +08:00
|
|
|
|
$file_content = stream_get_contents($stream);
|
|
|
|
|
if($file_content !== false)
|
|
|
|
|
{
|
|
|
|
|
if(file_put_contents($new_file, $file_content))
|
|
|
|
|
{
|
|
|
|
|
$success++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
fclose($stream);
|
2019-02-13 18:15:06 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-08-11 17:30:06 +08:00
|
|
|
|
// 关闭zip
|
|
|
|
|
$zip->close();
|
2019-03-22 17:10:43 +08:00
|
|
|
|
|
2021-08-11 17:30:06 +08:00
|
|
|
|
// 未匹配成功一个文件则认为插件包无效
|
|
|
|
|
if($success <= 0)
|
|
|
|
|
{
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('common_service.pluginsadmin.plugins_package_invalid_tips'), -1);
|
2021-08-11 17:30:06 +08:00
|
|
|
|
}
|
2021-04-24 13:02:01 +08:00
|
|
|
|
return DataReturn('success', 0, $plugins);
|
2019-02-13 18:15:06 +08:00
|
|
|
|
}
|
2019-03-22 18:19:26 +08:00
|
|
|
|
|
2021-04-23 16:43:23 +08:00
|
|
|
|
/**
|
|
|
|
|
* 插件目录结构
|
|
|
|
|
* @author Devil
|
|
|
|
|
* @blog http://gong.gg/
|
|
|
|
|
* @version 1.0.0
|
|
|
|
|
* @date 2021-04-22
|
|
|
|
|
* @desc description
|
|
|
|
|
*/
|
|
|
|
|
public static function PluginsDirStructureMapping()
|
|
|
|
|
{
|
|
|
|
|
return [
|
|
|
|
|
'_controller_' => APP_PATH.'plugins'.DS,
|
|
|
|
|
'_view_' => APP_PATH.'plugins'.DS.'view'.DS,
|
|
|
|
|
'_css_' => ROOT.'public'.DS.'static'.DS.'plugins'.DS.'css'.DS,
|
|
|
|
|
'_js_' => ROOT.'public'.DS.'static'.DS.'plugins'.DS.'js'.DS,
|
|
|
|
|
'_images_' => ROOT.'public'.DS.'static'.DS.'plugins'.DS.'images'.DS,
|
|
|
|
|
'_uploadfile_' => ROOT.'public'.DS.'static'.DS.'upload'.DS.'file'.DS,
|
|
|
|
|
'_uploadimages_' => ROOT.'public'.DS.'static'.DS.'upload'.DS.'images'.DS,
|
|
|
|
|
'_uploadvideo_' => ROOT.'public'.DS.'static'.DS.'upload'.DS.'video'.DS,
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-22 18:19:26 +08:00
|
|
|
|
/**
|
|
|
|
|
* 应用打包
|
|
|
|
|
* @author Devil
|
|
|
|
|
* @blog http://gong.gg/
|
|
|
|
|
* @version 1.0.0
|
|
|
|
|
* @date 2019-03-22
|
|
|
|
|
* @desc description
|
2019-06-16 16:22:43 +08:00
|
|
|
|
* @param [array] $params [输入参数]
|
2019-03-22 18:19:26 +08:00
|
|
|
|
*/
|
|
|
|
|
public static function PluginsDownload($params = [])
|
|
|
|
|
{
|
|
|
|
|
// 请求参数
|
|
|
|
|
$p = [
|
|
|
|
|
[
|
|
|
|
|
'checked_type' => 'empty',
|
|
|
|
|
'key_name' => 'id',
|
2023-02-04 16:47:48 +08:00
|
|
|
|
'error_msg' => MyLang('data_id_error_tips'),
|
2019-03-22 18:19:26 +08:00
|
|
|
|
],
|
|
|
|
|
];
|
|
|
|
|
$ret = ParamsChecked($params, $p);
|
|
|
|
|
if($ret !== true)
|
|
|
|
|
{
|
|
|
|
|
return DataReturn($ret, -1);
|
|
|
|
|
}
|
2019-06-13 10:59:53 +08:00
|
|
|
|
|
2023-08-27 16:59:15 +08:00
|
|
|
|
// 生成下载包
|
|
|
|
|
$ret = self::PluginsDownloadHandle($params['id']);
|
|
|
|
|
if($ret['code'] != 0)
|
|
|
|
|
{
|
|
|
|
|
return $ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 开始下载
|
|
|
|
|
if(\base\FileUtil::DownloadFile($ret['data']['file'], $ret['data']['config']['base']['name'].'_v'.$ret['data']['config']['base']['version'].'.zip'))
|
|
|
|
|
{
|
|
|
|
|
// 删除文件
|
|
|
|
|
@unlink($ret['data']['file']);
|
|
|
|
|
|
|
|
|
|
// 插件事件回调
|
|
|
|
|
PluginsService::PluginsEventCall($ret['data']['plugins'], 'Download', $params);
|
|
|
|
|
} else {
|
|
|
|
|
return DataReturn(MyLang('download_fail'), -100);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 上传到应用商店
|
|
|
|
|
* @author Devil
|
|
|
|
|
* @blog http://gong.gg/
|
|
|
|
|
* @version 1.0.0
|
|
|
|
|
* @date 2023-08-17
|
|
|
|
|
* @desc description
|
|
|
|
|
* @param [array] $params [输入参数]
|
|
|
|
|
*/
|
|
|
|
|
public static function PluginsStoreUpload($params = [])
|
|
|
|
|
{
|
|
|
|
|
// 请求参数
|
|
|
|
|
$p = [
|
|
|
|
|
[
|
|
|
|
|
'checked_type' => 'empty',
|
|
|
|
|
'key_name' => 'plugins',
|
|
|
|
|
'error_msg' => MyLang('common_service.pluginsadmin.form_item_plugins_message'),
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'checked_type' => 'empty',
|
|
|
|
|
'key_name' => 'version_new',
|
|
|
|
|
'error_msg' => MyLang('common_service.pluginsadmin.form_item_version_message'),
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'checked_type' => 'empty',
|
|
|
|
|
'key_name' => 'describe',
|
|
|
|
|
'error_msg' => MyLang('common_service.pluginsadmin.form_item_desc_message'),
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'checked_type' => 'empty',
|
|
|
|
|
'key_name' => 'apply_version',
|
|
|
|
|
'error_msg' => MyLang('common_service.pluginsadmin.form_item_apply_version_message'),
|
|
|
|
|
],
|
|
|
|
|
];
|
|
|
|
|
$ret = ParamsChecked($params, $p);
|
|
|
|
|
if($ret !== true)
|
|
|
|
|
{
|
|
|
|
|
return DataReturn($ret, -1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 生成下载包
|
|
|
|
|
$package = self::PluginsDownloadHandle($params['plugins']);
|
|
|
|
|
if($package['code'] != 0)
|
|
|
|
|
{
|
|
|
|
|
return $package;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 帐号信息
|
|
|
|
|
$user = StoreService::AccountsData();
|
|
|
|
|
if(empty($user['accounts']) || empty($user['password']))
|
|
|
|
|
{
|
|
|
|
|
return DataReturn(MyLang('store_account_not_bind_tips'), -300);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 上传到远程
|
|
|
|
|
$params['file'] = new \CURLFile($package['data']['file']);
|
|
|
|
|
$ret = StoreService::RemoteStoreData($user['accounts'], $user['password'], MyConfig('shopxo.store_plugins_upload_url'), $params, 2);
|
|
|
|
|
// 是个与否都删除本地生成的zip包
|
|
|
|
|
@unlink($package['data']['file']);
|
|
|
|
|
// 返回数据
|
|
|
|
|
return $ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 应用下载打包处理
|
|
|
|
|
* @author Devil
|
|
|
|
|
* @blog http://gong.gg/
|
|
|
|
|
* @version 1.0.0
|
|
|
|
|
* @date 2023-08-17
|
|
|
|
|
* @desc description
|
|
|
|
|
* @param [string] $plugins [应用标识]
|
|
|
|
|
*/
|
|
|
|
|
public static function PluginsDownloadHandle($plugins)
|
|
|
|
|
{
|
2019-06-13 10:59:53 +08:00
|
|
|
|
// 是否开启开发者模式
|
2021-07-18 23:42:10 +08:00
|
|
|
|
if(MyConfig('shopxo.is_develop') !== true)
|
2019-06-13 10:59:53 +08:00
|
|
|
|
{
|
2023-02-06 18:30:08 +08:00
|
|
|
|
return DataReturn(MyLang('not_open_developer_mode_tips'), -1);
|
2019-06-13 10:59:53 +08:00
|
|
|
|
}
|
2019-10-14 21:33:20 +08:00
|
|
|
|
|
2019-03-22 18:19:26 +08:00
|
|
|
|
// 获取应用标记
|
2019-10-14 21:33:20 +08:00
|
|
|
|
// 防止路径回溯
|
2023-08-27 16:59:15 +08:00
|
|
|
|
$plugins = htmlentities(str_replace(array('.', '/', '\\', ':'), '', strip_tags($plugins)));
|
2019-10-14 21:33:20 +08:00
|
|
|
|
if(empty($plugins))
|
|
|
|
|
{
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('common_service.pluginsadmin.plugins_identification_error_tips'), -1);
|
2019-10-14 21:33:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 配置信息
|
|
|
|
|
$config = self::GetPluginsConfig($plugins);
|
2021-07-21 15:15:46 +08:00
|
|
|
|
if(empty($config))
|
2019-10-14 21:33:20 +08:00
|
|
|
|
{
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('plugins_config_error_tips'), -10);
|
2019-10-14 21:33:20 +08:00
|
|
|
|
}
|
2019-03-22 18:19:26 +08:00
|
|
|
|
|
2023-05-26 11:07:03 +08:00
|
|
|
|
// 安全判断
|
|
|
|
|
$ret = PluginsService::PluginsLegalCheck($plugins);
|
|
|
|
|
if($ret['code'] != 0)
|
|
|
|
|
{
|
|
|
|
|
return $ret;
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-25 10:57:00 +08:00
|
|
|
|
// 目录不存在则创建
|
2023-08-27 20:15:48 +08:00
|
|
|
|
$new_dir = ROOT.'runtime'.DS.'data'.DS.'plugins_package'.DS.$plugins;
|
2019-03-25 10:57:00 +08:00
|
|
|
|
\base\FileUtil::CreateDir($new_dir);
|
|
|
|
|
|
|
|
|
|
// 复制包目录 - 控制器
|
|
|
|
|
$old_dir = APP_PATH.'plugins'.DS.$plugins;
|
|
|
|
|
if(is_dir($old_dir))
|
|
|
|
|
{
|
|
|
|
|
if(\base\FileUtil::CopyDir($old_dir, $new_dir.DS.'_controller_'.DS.$plugins) != true)
|
|
|
|
|
{
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('project_copy_fail_tips').'['.MyLang('common_service.pluginsadmin.plugins_copy_control_fail_tips').']', -2);
|
2019-03-25 10:57:00 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 复制包目录 - 视图
|
|
|
|
|
$old_dir = APP_PATH.'plugins'.DS.'view'.DS.$plugins;
|
|
|
|
|
if(is_dir($old_dir))
|
|
|
|
|
{
|
|
|
|
|
if(\base\FileUtil::CopyDir($old_dir, $new_dir.DS.'_view_'.DS.$plugins) != true)
|
|
|
|
|
{
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('project_copy_fail_tips').'['.MyLang('common_service.pluginsadmin.plugins_copy_view_fail_tips').']', -2);
|
2019-03-25 10:57:00 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 复制包目录 - css
|
|
|
|
|
$old_dir = ROOT.'public'.DS.'static'.DS.'plugins'.DS.'css'.DS.$plugins;
|
|
|
|
|
if(is_dir($old_dir))
|
|
|
|
|
{
|
|
|
|
|
if(\base\FileUtil::CopyDir($old_dir, $new_dir.DS.'_css_'.DS.$plugins) != true)
|
|
|
|
|
{
|
2023-02-06 18:30:08 +08:00
|
|
|
|
return DataReturn(MyLang('project_copy_fail_tips').'[css]', -2);
|
2019-03-25 10:57:00 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 复制包目录 - js
|
|
|
|
|
$old_dir = ROOT.'public'.DS.'static'.DS.'plugins'.DS.'js'.DS.$plugins;
|
|
|
|
|
if(is_dir($old_dir))
|
|
|
|
|
{
|
|
|
|
|
if(\base\FileUtil::CopyDir($old_dir, $new_dir.DS.'_js_'.DS.$plugins) != true)
|
|
|
|
|
{
|
2023-02-06 18:30:08 +08:00
|
|
|
|
return DataReturn(MyLang('project_copy_fail_tips').'[js]', -2);
|
2019-03-25 10:57:00 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 复制包目录 - images
|
|
|
|
|
$old_dir = ROOT.'public'.DS.'static'.DS.'plugins'.DS.'images'.DS.$plugins;
|
|
|
|
|
if(is_dir($old_dir))
|
|
|
|
|
{
|
|
|
|
|
if(\base\FileUtil::CopyDir($old_dir, $new_dir.DS.'_images_'.DS.$plugins) != true)
|
|
|
|
|
{
|
2023-02-06 18:30:08 +08:00
|
|
|
|
return DataReturn(MyLang('project_copy_fail_tips').'[images]', -2);
|
2019-03-25 10:57:00 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 复制包目录 - uploadimages
|
|
|
|
|
$old_dir = ROOT.'public'.DS.'static'.DS.'upload'.DS.'images'.DS.'plugins_'.$plugins;
|
|
|
|
|
if(is_dir($old_dir))
|
|
|
|
|
{
|
|
|
|
|
if(\base\FileUtil::CopyDir($old_dir, $new_dir.DS.'_uploadimages_'.DS.'plugins_'.$plugins) != true)
|
|
|
|
|
{
|
2023-02-06 18:30:08 +08:00
|
|
|
|
return DataReturn(MyLang('project_copy_fail_tips').'[uploadimages]', -2);
|
2019-03-25 10:57:00 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 复制包目录 - uploadvideo
|
|
|
|
|
$old_dir = ROOT.'public'.DS.'static'.DS.'upload'.DS.'video'.DS.'plugins_'.$plugins;
|
|
|
|
|
if(is_dir($old_dir))
|
|
|
|
|
{
|
|
|
|
|
if(\base\FileUtil::CopyDir($old_dir, $new_dir.DS.'_uploadvideo_'.DS.'plugins_'.$plugins) != true)
|
|
|
|
|
{
|
2023-02-06 18:30:08 +08:00
|
|
|
|
return DataReturn(MyLang('project_copy_fail_tips').'[uploadvideo]', -2);
|
2019-03-25 10:57:00 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 复制包目录 - uploadfile
|
|
|
|
|
$old_dir = ROOT.'public'.DS.'static'.DS.'upload'.DS.'file'.DS.'plugins_'.$plugins;
|
|
|
|
|
if(is_dir($old_dir))
|
|
|
|
|
{
|
|
|
|
|
if(\base\FileUtil::CopyDir($old_dir, $new_dir.DS.'_uploadfile_'.DS.'plugins_'.$plugins) != true)
|
|
|
|
|
{
|
2023-02-06 18:30:08 +08:00
|
|
|
|
return DataReturn(MyLang('project_copy_fail_tips').'[uploadfile]', -2);
|
2019-03-25 10:57:00 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-18 14:15:42 +08:00
|
|
|
|
// 配置文件历史信息更新
|
|
|
|
|
$new_config_file = $new_dir.DS.'_controller_'.DS.$plugins.DS.'config.json';
|
|
|
|
|
if(!file_exists($new_config_file))
|
|
|
|
|
{
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('common_service.pluginsadmin.plugins_new_config_error_tips'), -10);
|
2021-02-18 14:15:42 +08:00
|
|
|
|
}
|
|
|
|
|
if(empty($config['history']))
|
|
|
|
|
{
|
|
|
|
|
$config['history'] = [];
|
|
|
|
|
}
|
|
|
|
|
$config['history'][] = [
|
|
|
|
|
'host' => __MY_HOST__,
|
|
|
|
|
'url' => __MY_URL__,
|
|
|
|
|
'ip' => __MY_ADDR__,
|
|
|
|
|
'time' => date('Y-m-d H:i:s'),
|
|
|
|
|
];
|
|
|
|
|
if(@file_put_contents($new_config_file, JsonFormat($config)) === false)
|
|
|
|
|
{
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('common_service.pluginsadmin.plugins_new_config_update_fail_tips'), -11);
|
2021-02-18 14:15:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
2019-03-25 10:57:00 +08:00
|
|
|
|
// 生成压缩包
|
|
|
|
|
$zip = new \base\ZipFolder();
|
|
|
|
|
if(!$zip->zip($new_dir.'.zip', $new_dir))
|
|
|
|
|
{
|
2023-02-06 18:30:08 +08:00
|
|
|
|
return DataReturn(MyLang('form_generate_zip_message'), -100);
|
2019-03-25 10:57:00 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 生成成功删除目录
|
|
|
|
|
\base\FileUtil::UnlinkDir($new_dir);
|
|
|
|
|
|
2023-08-27 16:59:15 +08:00
|
|
|
|
// 返回数据
|
|
|
|
|
return DataReturn('success', 0, [
|
|
|
|
|
'file' => $new_dir.'.zip',
|
|
|
|
|
'config' => $config,
|
|
|
|
|
'plugins' => $plugins,
|
|
|
|
|
]);
|
2019-03-22 18:19:26 +08:00
|
|
|
|
}
|
2021-01-05 14:48:01 +08:00
|
|
|
|
|
2021-04-23 16:43:23 +08:00
|
|
|
|
/**
|
|
|
|
|
* 插件更新
|
|
|
|
|
* @author Devil
|
|
|
|
|
* @blog http://gong.gg/
|
|
|
|
|
* @version 1.0.0
|
|
|
|
|
* @date 2021-04-22
|
|
|
|
|
* @desc description
|
|
|
|
|
* @param [string] $package_file [插件包文件]
|
|
|
|
|
* @param [array] $params [输入参数]
|
|
|
|
|
*/
|
|
|
|
|
public static function PluginsUpgradeHandle($package_file, $params = [])
|
|
|
|
|
{
|
|
|
|
|
// 权限校验
|
|
|
|
|
$ret = self::PowerCheck();
|
|
|
|
|
if($ret['code'] != 0)
|
|
|
|
|
{
|
|
|
|
|
return $ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 基础业务参数
|
|
|
|
|
if(empty($params['plugins_value']))
|
|
|
|
|
{
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('common_service.pluginsadmin.plugins_identification_empty_tips'), -1);
|
2021-04-23 16:43:23 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 应用是否存在
|
|
|
|
|
if(!self::PluginsExist($params['plugins_value']))
|
|
|
|
|
{
|
2023-02-09 19:04:35 +08:00
|
|
|
|
return DataReturn(MyLang('common_service.pluginsadmin.app_update_no_exist_tips', ['plugins'=>$params['plugins_value']]), -1);
|
2021-04-23 16:43:23 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-08-09 19:06:01 +08:00
|
|
|
|
// 插件前置事件
|
|
|
|
|
$ret = PluginsService::PluginsEventCall($params['plugins_value'], 'BeginUpgrade', $params);
|
|
|
|
|
if(!empty($ret) && isset($ret['code']) && $ret['code'] != 0)
|
|
|
|
|
{
|
|
|
|
|
return $ret;
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-24 13:02:01 +08:00
|
|
|
|
// 包处理
|
|
|
|
|
$ret = self::PluginsPackageHandle($package_file, 1, $params['plugins_value']);
|
|
|
|
|
if($ret['code'] != 0)
|
2021-04-23 16:43:23 +08:00
|
|
|
|
{
|
2021-04-24 13:02:01 +08:00
|
|
|
|
return $ret;
|
2021-04-23 16:43:23 +08:00
|
|
|
|
}
|
2021-04-24 13:02:01 +08:00
|
|
|
|
$plugins = $ret['data'];
|
2021-04-23 16:43:23 +08:00
|
|
|
|
|
|
|
|
|
// 更新sql
|
|
|
|
|
$sql_file = APP_PATH.'plugins'.DS.$plugins.DS.'update.sql';
|
|
|
|
|
if(!empty($plugins) && file_exists($sql_file))
|
|
|
|
|
{
|
2021-07-23 19:21:35 +08:00
|
|
|
|
$sql = file_get_contents($sql_file);
|
|
|
|
|
if(!empty($sql))
|
|
|
|
|
{
|
2021-07-24 22:25:00 +08:00
|
|
|
|
SqlConsoleService::Implement(['sql'=>$sql]);
|
2021-07-23 19:21:35 +08:00
|
|
|
|
}
|
2021-04-23 16:43:23 +08:00
|
|
|
|
}
|
|
|
|
|
|
2021-05-06 10:06:42 +08:00
|
|
|
|
// 钩子部署
|
|
|
|
|
$ret = self::PluginsHookDeployment();
|
|
|
|
|
if($ret['code'] != 0)
|
|
|
|
|
{
|
|
|
|
|
return $ret;
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-23 16:43:23 +08:00
|
|
|
|
// 插件事件回调
|
|
|
|
|
PluginsService::PluginsEventCall($plugins, 'Upgrade', $params);
|
|
|
|
|
|
2023-02-04 16:47:48 +08:00
|
|
|
|
return DataReturn(MyLang('update_success'));
|
2021-04-23 16:43:23 +08:00
|
|
|
|
}
|
|
|
|
|
|
2021-01-05 14:48:01 +08:00
|
|
|
|
/**
|
2023-05-26 19:44:20 +08:00
|
|
|
|
* 设置保存
|
2021-01-05 14:48:01 +08:00
|
|
|
|
* @author Devil
|
|
|
|
|
* @blog http://gong.gg/
|
|
|
|
|
* @version 1.0.0
|
|
|
|
|
* @date 2021-01-05
|
|
|
|
|
* @desc description
|
|
|
|
|
* @param [array] $params [输入参数]
|
|
|
|
|
*/
|
2023-05-26 19:44:20 +08:00
|
|
|
|
public static function SetupSave($params = [])
|
2021-01-05 14:48:01 +08:00
|
|
|
|
{
|
|
|
|
|
// 请求类型
|
|
|
|
|
$p = [
|
|
|
|
|
[
|
|
|
|
|
'checked_type' => 'empty',
|
|
|
|
|
'key_name' => 'data',
|
2023-05-26 19:44:20 +08:00
|
|
|
|
'error_msg' => MyLang('common_service.pluginsadmin.setup_save_data_empty_tips'),
|
2021-01-05 14:48:01 +08:00
|
|
|
|
]
|
|
|
|
|
];
|
|
|
|
|
$ret = ParamsChecked($params, $p);
|
|
|
|
|
if($ret !== true)
|
|
|
|
|
{
|
|
|
|
|
return DataReturn($ret, -1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 排序数据、非数组则当做json转换一次
|
|
|
|
|
$data = is_array($params['data']) ? $params['data'] : json_decode($params['data'], true);
|
|
|
|
|
if(!empty($data) && is_array($data))
|
|
|
|
|
{
|
|
|
|
|
// 启动事务
|
|
|
|
|
Db::startTrans();
|
|
|
|
|
|
|
|
|
|
// 捕获异常
|
|
|
|
|
try {
|
2023-05-26 19:44:20 +08:00
|
|
|
|
foreach($data as $v)
|
2021-01-05 14:48:01 +08:00
|
|
|
|
{
|
2023-05-26 19:44:20 +08:00
|
|
|
|
if(!empty($v['id']))
|
2021-01-05 14:48:01 +08:00
|
|
|
|
{
|
2023-05-26 19:44:20 +08:00
|
|
|
|
$upd_data = [
|
2023-08-27 16:59:15 +08:00
|
|
|
|
'sort' => empty($v['sort']) ? 0 : intval($v['sort']),
|
|
|
|
|
'plugins_category_id' => empty($v['category_id']) ? 0 : intval($v['category_id']),
|
|
|
|
|
'plugins_menu_control' => empty($v['menu_control']) ? '' : strtolower($v['menu_control']),
|
|
|
|
|
'upd_time' => time(),
|
2023-05-26 19:44:20 +08:00
|
|
|
|
];
|
|
|
|
|
if(Db::name('Plugins')->where(['id'=>intval($v['id'])])->update($upd_data) === false)
|
|
|
|
|
{
|
|
|
|
|
throw new \Exception(MyLang('operate_fail'));
|
|
|
|
|
}
|
2021-01-05 14:48:01 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 钩子部署
|
|
|
|
|
$ret = self::PluginsHookDeployment();
|
|
|
|
|
if($ret['code'] != 0)
|
|
|
|
|
{
|
|
|
|
|
throw new \Exception($ret['msg']);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 完成
|
|
|
|
|
Db::commit();
|
2023-01-19 17:44:03 +08:00
|
|
|
|
return DataReturn(MyLang('operate_success'), 0);
|
2021-01-05 14:48:01 +08:00
|
|
|
|
} catch(\Exception $e) {
|
|
|
|
|
Db::rollback();
|
|
|
|
|
return DataReturn($e->getMessage(), -1);
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-05-26 19:44:20 +08:00
|
|
|
|
return DataReturn(MyLang('common_service.pluginsadmin.setup_save_data_error_tips'), -1);
|
2021-01-05 14:48:01 +08:00
|
|
|
|
}
|
2019-02-13 16:25:48 +08:00
|
|
|
|
}
|
|
|
|
|
?>
|