1129 lines
35 KiB
PHP
Executable File
1129 lines
35 KiB
PHP
Executable File
<?php
|
||
// +----------------------------------------------------------------------
|
||
// | ShopXO 国内领先企业级B2C免费开源电商系统
|
||
// +----------------------------------------------------------------------
|
||
// | Copyright (c) 2011~2019 http://shopxo.net All rights reserved.
|
||
// +----------------------------------------------------------------------
|
||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||
// +----------------------------------------------------------------------
|
||
// | Author: Devil
|
||
// +----------------------------------------------------------------------
|
||
namespace app\service;
|
||
|
||
use think\Db;
|
||
use app\service\ResourcesService;
|
||
use app\service\SqlconsoleService;
|
||
|
||
/**
|
||
* 应用管理服务层
|
||
* @author Devil
|
||
* @blog http://gong.gg/
|
||
* @version 0.0.1
|
||
* @datetime 2016-12-01T21:51:08+0800
|
||
*/
|
||
class PluginsAdminService
|
||
{
|
||
/**
|
||
* 列表
|
||
* @author Devil
|
||
* @blog http://gong.gg/
|
||
* @version 1.0.0
|
||
* @date 2018-09-29
|
||
* @desc description
|
||
* @param [array] $params [输入参数]
|
||
*/
|
||
public static function PluginsList($params = [])
|
||
{
|
||
$where = empty($params['where']) ? [] : $params['where'];
|
||
$m = isset($params['m']) ? intval($params['m']) : 0;
|
||
$n = isset($params['n']) ? intval($params['n']) : 10;
|
||
$order_by = empty($params['order_by']) ? 'id desc' : $params['order_by'];
|
||
|
||
// 获取数据列表
|
||
$data = Db::name('Plugins')->where($where)->limit($m, $n)->order($order_by)->select();
|
||
|
||
return DataReturn('处理成功', 0, self::PluginsDataHandle($data));
|
||
}
|
||
|
||
/**
|
||
* 数据处理
|
||
* @author Devil
|
||
* @blog http://gong.gg/
|
||
* @version 1.0.0
|
||
* @date 2018-09-29
|
||
* @desc description
|
||
* @param [array] $data [数据]
|
||
*/
|
||
private static function PluginsDataHandle($data)
|
||
{
|
||
$result = [];
|
||
if(!empty($data))
|
||
{
|
||
foreach($data as $v)
|
||
{
|
||
$config = self::GetPluginsConfig($v['plugins']);
|
||
if($config !== false)
|
||
{
|
||
$base = $config['base'];
|
||
$result[] = [
|
||
'id' => $v['id'],
|
||
'plugins' => $v['plugins'],
|
||
'is_enable' => $v['is_enable'],
|
||
'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' => date('Y-m-d H:i:s', $v['add_time']),
|
||
'add_time_date' => date('Y-m-d', $v['add_time']),
|
||
];
|
||
}
|
||
}
|
||
}
|
||
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* 总数
|
||
* @author Devil
|
||
* @blog http://gong.gg/
|
||
* @version 1.0.0
|
||
* @date 2018-09-29
|
||
* @desc description
|
||
* @param [array] $where [条件]
|
||
*/
|
||
public static function PluginsTotal($where = [])
|
||
{
|
||
return (int) Db::name('Plugins')->where($where)->count();
|
||
}
|
||
|
||
/**
|
||
* 列表条件
|
||
* @author Devil
|
||
* @blog http://gong.gg/
|
||
* @version 1.0.0
|
||
* @date 2018-09-29
|
||
* @desc description
|
||
* @param [array] $params [输入参数]
|
||
*/
|
||
public static function PluginsListWhere($params = [])
|
||
{
|
||
$where = [];
|
||
return $where;
|
||
}
|
||
|
||
/**
|
||
* 状态更新
|
||
* @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',
|
||
'error_msg' => '操作id有误',
|
||
],
|
||
[
|
||
'checked_type' => 'in',
|
||
'key_name' => 'state',
|
||
'checked_data' => [0,1],
|
||
'error_msg' => '状态有误',
|
||
],
|
||
];
|
||
$ret = ParamsChecked($params, $p);
|
||
if($ret !== true)
|
||
{
|
||
return DataReturn($ret, -1);
|
||
}
|
||
|
||
// 开启事务
|
||
Db::startTrans();
|
||
|
||
// 数据更新
|
||
if(Db::name('Plugins')->where(['id'=>$params['id']])->update(['is_enable'=>intval($params['state']), 'upd_time'=>time()]))
|
||
{
|
||
// 钩子部署
|
||
$ret = self::PluginsHookDeployment();
|
||
if($ret['code'] == 0)
|
||
{
|
||
// 提交事务
|
||
Db::commit();
|
||
return DataReturn('操作成功');
|
||
}
|
||
} else {
|
||
$ret = DataReturn('操作失败', -100);
|
||
}
|
||
|
||
// 事务回退
|
||
Db::rollback();
|
||
return $ret;
|
||
}
|
||
|
||
/**
|
||
* 应用钩子部署
|
||
* @author Devil
|
||
* @blog http://gong.gg/
|
||
* @version 1.0.0
|
||
* @date 2019-02-13
|
||
* @desc description
|
||
*/
|
||
private static function PluginsHookDeployment()
|
||
{
|
||
// 钩子配置文件
|
||
$tags_file = APP_PATH.'tags.php';
|
||
if(!is_writable($tags_file))
|
||
{
|
||
return DataReturn('钩子配置文件没有操作权限'.'['.$tags_file.']', -3);
|
||
}
|
||
|
||
// 钩子容器
|
||
$result = [];
|
||
|
||
// 系统自带钩子处理
|
||
if(file_exists($tags_file))
|
||
{
|
||
$tags = require $tags_file;
|
||
if(!empty($tags) && is_array($tags))
|
||
{
|
||
$system_hook_list = [
|
||
'app_init',
|
||
'app_dispatch',
|
||
'app_begin',
|
||
'module_init',
|
||
'action_begin',
|
||
'view_filter',
|
||
'app_end',
|
||
'log_write',
|
||
'log_level',
|
||
'response_send',
|
||
'response_end'
|
||
];
|
||
foreach($system_hook_list as $system_hook)
|
||
{
|
||
if(isset($tags[$system_hook]))
|
||
{
|
||
$result[$system_hook] = $tags[$system_hook];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 处理应用钩子
|
||
$data = Db::name('Plugins')->where(['is_enable'=>1])->column('plugins');
|
||
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;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 部署钩子到文件
|
||
$ret = @file_put_contents($tags_file, "<?php
|
||
// +----------------------------------------------------------------------
|
||
// | ShopXO 国内领先企业级B2C免费开源电商系统
|
||
// +----------------------------------------------------------------------
|
||
// | Copyright (c) 2011~2019 http://shopxo.net All rights reserved.
|
||
// +----------------------------------------------------------------------
|
||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||
// +----------------------------------------------------------------------
|
||
// | Author: Devil
|
||
// +----------------------------------------------------------------------
|
||
|
||
// 应用行为扩展定义文件\nreturn ".var_export($result, true).";\n?>");
|
||
if($ret === false)
|
||
{
|
||
return DataReturn('应用钩子部署失败', -10);
|
||
}
|
||
|
||
return DataReturn('处理成功', 0);
|
||
}
|
||
|
||
/**
|
||
* 删除
|
||
* @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',
|
||
'error_msg' => '操作id有误',
|
||
],
|
||
];
|
||
$ret = ParamsChecked($params, $p);
|
||
if($ret !== true)
|
||
{
|
||
return DataReturn($ret, -1);
|
||
}
|
||
|
||
// 获取应用标记
|
||
$where = ['id'=>intval($params['id'])];
|
||
$plugins = Db::name('Plugins')->where($where)->value('plugins');
|
||
if(empty($plugins))
|
||
{
|
||
return DataReturn('应用不存在', -10);
|
||
}
|
||
|
||
// 开启事务
|
||
Db::startTrans();
|
||
|
||
// 删除操作
|
||
if(Db::name('Plugins')->where($where)->delete())
|
||
{
|
||
// 钩子部署
|
||
$ret = self::PluginsHookDeployment();
|
||
if($ret['code'] == 0)
|
||
{
|
||
// sql运行
|
||
$uninstall_sql = APP_PATH.'plugins'.DS.$plugins.DS.'uninstall.sql';
|
||
if(file_exists($uninstall_sql))
|
||
{
|
||
SqlconsoleService::Implement(['sql'=>file_get_contents($uninstall_sql)]);
|
||
}
|
||
|
||
// 删除应用文件
|
||
self::PluginsResourcesDelete($plugins);
|
||
|
||
// 提交事务
|
||
Db::commit();
|
||
return DataReturn('删除成功');
|
||
}
|
||
} else {
|
||
$ret = DataReturn('删除失败或资源不存在', -100);
|
||
}
|
||
|
||
// 事务回退
|
||
Db::rollback();
|
||
return $ret;
|
||
}
|
||
|
||
/**
|
||
* 应用资源删除
|
||
* @author Devil
|
||
* @blog http://gong.gg/
|
||
* @version 1.0.0
|
||
* @date 2019-02-13
|
||
* @desc description
|
||
* @param [string] $plugins [唯一标记]
|
||
*/
|
||
private static function PluginsResourcesDelete($plugins)
|
||
{
|
||
\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);
|
||
\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);
|
||
}
|
||
|
||
/**
|
||
* 获取应用配置信息
|
||
* @author Devil
|
||
* @blog http://gong.gg/
|
||
* @version 1.0.0
|
||
* @date 2018-09-17
|
||
* @desc description
|
||
* @param [string] $plugins [应用名称]
|
||
*/
|
||
private static function GetPluginsConfig($plugins)
|
||
{
|
||
$config_file = APP_PATH.'plugins'.DS.$plugins.DS.'config.json';
|
||
if(file_exists($config_file))
|
||
{
|
||
return json_decode(file_get_contents($config_file), true);
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* 保存
|
||
* @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',
|
||
'error_msg' => '应用唯一标记不能为空',
|
||
],
|
||
[
|
||
'checked_type' => 'empty',
|
||
'key_name' => 'logo',
|
||
'error_msg' => '请上传LOGO',
|
||
],
|
||
[
|
||
'checked_type' => 'empty',
|
||
'key_name' => 'name',
|
||
'error_msg' => '应用名称不能为空',
|
||
],
|
||
[
|
||
'checked_type' => 'empty',
|
||
'key_name' => 'author',
|
||
'error_msg' => '作者不能为空',
|
||
],
|
||
[
|
||
'checked_type' => 'empty',
|
||
'key_name' => 'author_url',
|
||
'error_msg' => '作者主页不能为空',
|
||
],
|
||
[
|
||
'checked_type' => 'empty',
|
||
'key_name' => 'version',
|
||
'error_msg' => '版本号不能为空',
|
||
],
|
||
[
|
||
'checked_type' => 'empty',
|
||
'key_name' => 'desc',
|
||
'error_msg' => '描述不能为空',
|
||
],
|
||
[
|
||
'checked_type' => 'empty',
|
||
'key_name' => 'apply_terminal',
|
||
'error_msg' => '请至少选择一个适用终端',
|
||
],
|
||
[
|
||
'checked_type' => 'empty',
|
||
'key_name' => 'apply_version',
|
||
'error_msg' => '请至少选择一个适用系统版本',
|
||
],
|
||
];
|
||
$ret = ParamsChecked($params, $p);
|