<?php
<364666827@qq.com>,开发者QQ群:50304283
namespace app\system\model;
use think\Model;
use Env;
use hisi\Dir;
use think\facade\Build;
class SystemModule extends Model
{
protected $createTime = 'ctime';
protected $updateTime = 'mtime';
protected $autoWriteTimestamp = true;
/**
* 获取模块配置信息
* @param string $name 配置名
* @param bool $update 是否更新缓存
* @author 橘子俊 <364666827@qq.com>
* @return mixed
*/
public static function getConfig($name = '', $update = false)
{
$result = cache('module_config');
if (!$result || $update == true) {
$rows = self::where('status', 2)->column('name,config', 'name');
$result = [];
foreach ($rows as $k => $r) {
if (empty($r)) {
continue;
}
$config = json_decode($r, 1);
if (!is_array($config)) {
continue;
}
foreach ($config as $rr) {
switch ($rr['type']) {
case 'array':
case 'checkbox':
$result['module_'.$k][$rr['name']] = parse_attr($rr['value']);
break;
default:
$result['module_'.$k][$rr['name']] = $rr['value'];
break;
}
}
}
cache('module_config', $result);
}
return $name != '' ? $result[$name] : $result;
}
/**
* 将已安装模块添加到路由配置文件
* @param bool $update 是否更新缓存
* @author 橘子俊 <364666827@qq.com>
* @return array
*/
public static function moduleRoute($update = false)
{
$result = cache('module_route');
if (!$result || $update == true) {
$map = [];
$map['status'] = 2;
$map['name'] = ['neq', 'admin'];
$result = self::where($map)->column('name');
if (!$result) {
$result = ['route'];
} else {
foreach ($result as &$v) {
$v = $v.'Route';
}
}
array_push($result, 'route');
cache('module_route', $result);
}
return $result;
}
/**
* 获取所有已安装模块(下拉列)
* @param string $select 选中的值
* @author 橘子俊 <364666827@qq.com>
* @return string
*/
public static function getOption($select = '', $field='name,title')
{
$rows = self::column($field);
$str = '';
foreach ($rows as $k => $v) {
if ($k == 1) continue;
}
if ($select == $k) {
$str .= '<option value="'.$k.'" selected>['.$k.']'.$v.'</option>';
} else {
$str .= '<option value="'.$k.'">['.$k.']'.$v.'</option>';
}
}
return $str;
}
/**
* 设计并生成标准模块结构
* @author 橘子俊 <364666827@qq.com>
* @return bool
*/
public function design($data = [])
{
$app_path = Env::get('app_path');
if (empty($data)) {
$data = input('post.');
}
$icon = 'static/'.$data['name'].'/'.$data['name'].'.png';
$data['icon'] = ROOT_DIR.$icon;
$mod_path = $app_path.$data['name'] . '/';
if (is_dir($mod_path) || self::where('name', $data['name'])->find() || in_array($data['name'], config('hs_system.modules')) !== false) {
$this->error = '模块已存在!';
return false;
}
if (!is_writable(Env::get('root_path').'application')) {
$this->error = '[application]目录不可写!';
return false;
}
if (!is_writable(Env::get('root_path').'public/theme')) {
$this->error = '[theme]目录不可写!';
return false;
}
if (!is_writable(Env::get('root_path').'public/static')) {
$this->error = '[static]目录不可写!';
return false;
}
$build = [];
if ($data['file']) {
$build[$data['name']]['__file__'] = explode(',', $data['file']);
}
$build[$data['name']]['__dir__'] = parse_attr($data['dir']);
$build[$data['name']]['model'] = ['example'];
$build[$data['name']]['view'] = ['index/index'];
Build::run($build);
if (!is_dir($mod_path)) {
$this->error = '模块目录生成失败[application/'.$data['name'].']!';
return false;
}
Dir::delDir(Env::get('config_path').$data['name']);
$dir_list = [
'public/theme/'.$data['name'].'/default/static/css',
'public/theme/'.$data['name'].'/default/static/js',
'public/theme/'.$data['name'].'/default/static/image',
'public/theme/'.$data['name'].'/default/index',
'public/static/'.$data['name'].'/css',
'public/static/'.$data['name'].'/js',
'public/static/'.$data['name'].'/image',
];
self::mkDir($dir_list);
self::mkThemeConfig('theme/'.$data['name'].'/default/', $data);
self::mkSql($mod_path, $data);
self::mkMenu($mod_path, $data);
self::mkInfo($mod_path, $data);
self::mkControl($mod_path, $data);
$sql = [];
$sql['name'] = $data['name'];
$sql['identifier'] = $data['identifier'];
$sql['title'] = $data['title'];
$sql['intro'] = $data['intro'];
$sql['author'] = $data['author'];
$sql['icon'] = $data['icon'];
$sql['version'] = $data['version'];
$sql['url'] = $data['url'];
$sql['config'] = '';
$sql['status'] = 0;
self::create($sql);
copy(Env::get('root_path').'public/static/system/image/app.png', Env::get('root_path').'public/'.$icon);
copy($app_path.'system/view/block/layout.html', $mod_path.'view/layout.html');
return true;
}
/**
* 生成目录
* @param array $list 目录列表
* @author 橘子俊 <364666827@qq.com>
*/
public static function mkDir($list)
{
$root_path = Env::get('root_path');
foreach ($list as $dir) {
if (!is_dir($root_path . $dir)) {
mkdir($root_path . $dir, 0755, true);
}
}
}
/**
* 生成模块控制器
* @author 橘子俊 <364666827@qq.com>
*/
public static function mkControl($path = '', $data = [])
{
unlink($path.'controller/Index.php');
rmdir($path.'controller');
if (is_dir($path.'admin')) {
$admin_contro = "<?php\nnamespace app\\".$data["name"]."\\admin;\nuse app\system\admin\Admin;\n\nclass Index extends Admin\n{\n protected ".'$hisiModel'." = '' @unlink($path . 'view/index/index.html');
file_put_contents($path . 'admin/Index.php', $admin_contro);
file_put_contents($path . 'view/index/index.html', "我是后台模板[".$path."view/index/index.html]\n{include file=\"system@block/layui\" /}");
}
if (is_dir($path.'home')) {
$home_contro = "<?php\nnamespace app\\".$data["name"]."\\home;\nuse app\common\controller\Common;\n\nclass Index extends Common\n{\n public function index()\n {\n return ".'$this->fetch()'.";\n }\n}";
file_put_contents($path . 'home/Index.php', $home_contro);
file_put_contents(Env::get('root_path').'public/theme/'.$data['name'].'/default/index/index.html', '我是前台模板[/theme/'.$data['name'].'/default/index/index.html]');
}
}
/**
* 生成SQL文件
* @author 橘子俊 <364666827@qq.com>
*/
public static function mkSql($path = '')
{
if (!is_dir($path . 'sql')) {
mkdir($path . 'sql', 0755, true);
}
file_put_contents($path . 'sql/install.sql', "");
file_put_contents($path . 'sql/uninstall.sql', "");
}
public static function mkMenu($path = '', $data = [])
{
$menus = <<<INFO
<?php
<364666827@qq.com>,开发者QQ群:50304283
return [
[
'pid' => 0,
'title' => '{$data['title']}',
'icon' => 'aicon ai-shezhi',
'module' => '{$data['name']}',
'url' => '{$data['name']}',
'param' => '',
'target' => '_self',
'sort' => 100,
],
];
INFO;
file_put_contents($path . 'menu.php', $menus);
}
/**
* 生成模块信息文件
* @author 橘子俊 <364666827@qq.com>
*/
public static function mkInfo($path = '', $data = [])
{
$config = <<<INFO
<?php
<364666827@qq.com>,开发者QQ群:50304283
return [
'framework' => 'thinkphp5.1',
'name' => '{$data['name']}',
'title' => '{$data['title']}',
'identifier' => '{$data['identifier']}',
'theme' => 'default',
'icon' => '{$data['icon']}',
'intro' => '{$data['intro']}',
'author' => '{$data['author']}',
'author_url' => '{$data['url']}',
'version' => '{$data['version']}',
'module_depend' => [],
'plugin_depend' => [],
'tables' => [
],
'db_prefix' => 'db_',
'hooks' => [
],
'config' => [],
];
INFO;
file_put_contents($path . 'info.php', $config);
}
public static function mkThemeConfig($path, $data = [])
{
$str = '<?xml version="1.0" encoding="ISO-8859-1"?>
<root>
<item id="title"><![CDATA[默认模板]]></item>
<item id="version"><![CDATA[v1.0.0]]></item>
<item id="time"><![CDATA['.date('Y-m-d H:i').']]></item>
<item id="author"><![CDATA[HisiPHP]]></item>
<item id="copyright"><![CDATA[HisiPHP]]></item>
<item id="identifier" title="默认模板必须留空,非默认模板必须填写对应的应用标识"><![CDATA[]]></item>
<item id="depend" title="请填写当前对应的模块标识"><![CDATA['.$data['identifier'].']]></item>
</root>';
file_put_contents($path.'config.xml', $str);
}
}