Initial project files: BESCMS full source
This commit is contained in:
@@ -0,0 +1,303 @@
|
||||
<?php namespace Phpcmf\Model;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
// 程序插件管理
|
||||
class App extends \Phpcmf\Model {
|
||||
|
||||
public $cfg_cache;
|
||||
|
||||
// 是否是系统保留的app目录
|
||||
public function is_sys_dir($dir) {
|
||||
return in_array($dir, ['case', 'class', 'extends', 'site',
|
||||
'new', 'var', 'member', 'category', 'linkage', 'api', 'content',
|
||||
'module', 'form', 'all', 'admin', 'weixin', 'home', 'index', 'cms']);
|
||||
}
|
||||
|
||||
// 安装模板到站点
|
||||
public function install_tpl($dir, $cloud_id = 0) {
|
||||
|
||||
\Phpcmf\Service::M('Site')->set_theme($dir, SITE_ID);
|
||||
\Phpcmf\Service::M('Site')->set_template($dir, SITE_ID);
|
||||
|
||||
// 运行安装脚本
|
||||
if (is_file(WRITEPATH.'cloud/run-'.$cloud_id.'.php')) {
|
||||
require WRITEPATH.'cloud/run-'.$cloud_id.'.php';
|
||||
}
|
||||
|
||||
// 判断public
|
||||
if (defined('IS_VERSION') && IS_VERSION) {
|
||||
|
||||
} else {
|
||||
// 传统结构时复制目录到根目录去
|
||||
$path = ROOTPATH.'public/';
|
||||
if (is_dir($path)) {
|
||||
\Phpcmf\Service::L('file')->copy_dir($path, $path, ROOTPATH);
|
||||
dr_dir_delete($path, true);
|
||||
}
|
||||
}
|
||||
|
||||
\Phpcmf\Service::M('cache')->sync_cache('');
|
||||
}
|
||||
|
||||
// 开始安装app
|
||||
public function install($dir, $type = 0) {
|
||||
|
||||
if (!$dir) {
|
||||
return dr_return_data(0, dr_lang('应用参数不存在'));
|
||||
}
|
||||
|
||||
$path = dr_get_app_dir($dir);
|
||||
if (!is_file($path.'Config/App.php')) {
|
||||
return dr_return_data(0, dr_lang('应用配置文件不存在'));
|
||||
}
|
||||
|
||||
if ($dir == 'module' && \Phpcmf\Service::M()->is_table_exists('module')) {
|
||||
// 表示module表已经操作,防止误安装
|
||||
$rs = file_put_contents($path.'install.lock', 'fix');
|
||||
if (!$rs) {
|
||||
return dr_return_data(0, 'App/'.ucfirst($dir).'/'. dr_lang('目录无法写入'));
|
||||
}
|
||||
return dr_return_data(1, dr_lang('此程序已经安装'), [
|
||||
'url' => ''
|
||||
]);
|
||||
}
|
||||
|
||||
$config = require $path.'Config/App.php';
|
||||
|
||||
// 写入锁定文件
|
||||
$rt = file_put_contents($path.'install.test', SYS_TIME);
|
||||
if (!$rt) {
|
||||
return dr_return_data(0, 'App/'.ucfirst($dir).'/'. dr_lang('目录无法写入'));
|
||||
}
|
||||
|
||||
if (is_file($path.'install.lock')) {
|
||||
return dr_return_data(1, dr_lang('此程序已经安装'), [
|
||||
'url' => ''
|
||||
]);
|
||||
}
|
||||
|
||||
if (isset($config['ftype']) && $config['ftype'] == 'module') {
|
||||
// 如果是内容模块,就进入内容模块安装模式
|
||||
if (!IS_USE_MODULE) {
|
||||
return dr_return_data(0, dr_lang('没有安装<建站系统>插件'));
|
||||
}
|
||||
$config['share'] = $type ? 0 : 1;
|
||||
$rt = \Phpcmf\Service::M('module', 'cms')->install($dir, $config, 1);
|
||||
if (!$rt['code']) {
|
||||
return dr_return_data(0, $rt['msg']);
|
||||
}
|
||||
} else {
|
||||
// 安装前的判断
|
||||
if (is_file($path.'Config/Before.php')) {
|
||||
$rt = require $path.'Config/Before.php';
|
||||
if (!$rt['code']) {
|
||||
return dr_return_data(0, $rt['msg']);
|
||||
}
|
||||
}
|
||||
// 执行sql语句,主站的才执行
|
||||
if (SITE_ID == 1 && is_file($path.'Config/Install.sql')) {
|
||||
$rt = $this->query_all(file_get_contents($path.'/Config/Install.sql'));
|
||||
if ($rt) {
|
||||
return dr_return_data(0, $rt);
|
||||
}
|
||||
}
|
||||
// 执行各个站点sql语句
|
||||
if (is_file($path.'Config/Install_site.sql')) {
|
||||
$sql = file_get_contents($path.'Config/Install_site.sql');
|
||||
foreach ($this->site as $siteid) {
|
||||
$rt = $this->query_all(str_replace(['{dbprefix}', '{siteid}'], [$this->dbprefix($siteid.'_'), $siteid], $sql));
|
||||
if ($rt) {
|
||||
return dr_return_data(0, $rt);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 执行模块自己的安装程序
|
||||
if (is_file($path.'Config/Install.php')) {
|
||||
require $path.'Config/Install.php';
|
||||
}
|
||||
}
|
||||
|
||||
// 创建菜单
|
||||
$first_uri = \Phpcmf\Service::M('Menu')->add_app($dir);
|
||||
|
||||
// 写入锁定文件
|
||||
file_put_contents($path.'install.lock', SYS_TIME);
|
||||
file_put_contents(WRITEPATH.'install.lock', SYS_TIME);
|
||||
unlink($path.'install.test');
|
||||
|
||||
if (isset($config['uri']) && $config['uri']) {
|
||||
$url = dr_url($config['uri']);
|
||||
} elseif ($first_uri) {
|
||||
$url = dr_url($first_uri);
|
||||
} elseif (isset($config['ftype']) && $config['ftype'] == 'module') {
|
||||
$url = dr_url('module/module/index');
|
||||
} else {
|
||||
$url = dr_url('cloud/local');
|
||||
}
|
||||
|
||||
if (defined('IS_VERSION') && IS_VERSION) {
|
||||
// 存在public时,执行
|
||||
} elseif (is_dir(WEBPATH.'public/')) {
|
||||
//将public合并到根目录
|
||||
\Phpcmf\Service::L('file')->copy_dir(WEBPATH.'public/', WEBPATH.'public/', WEBPATH);
|
||||
dr_dir_delete(WEBPATH.'public/', true);
|
||||
}
|
||||
|
||||
return dr_return_data(1, dr_lang('安装成功'), [
|
||||
'url' => $url
|
||||
]);
|
||||
}
|
||||
|
||||
// 卸载
|
||||
public function uninstall($dir) {
|
||||
|
||||
$path = dr_get_app_dir($dir);
|
||||
if (!is_file($path.'Config/App.php')) {
|
||||
return dr_return_data(0, dr_lang('应用配置文件不存在'));
|
||||
}
|
||||
|
||||
$config = require $path.'Config/App.php';
|
||||
if (isset($config['ftype']) && $config['ftype'] == 'module') {
|
||||
// 如果是内容模块,就进入内容模块安装模式
|
||||
if (!IS_USE_MODULE) {
|
||||
return dr_return_data(0, dr_lang('没有安装<建站系统>插件'));
|
||||
}
|
||||
\Phpcmf\Service::M('module')->uninstall($dir, $config, 1);
|
||||
} else {
|
||||
// 删除菜单
|
||||
\Phpcmf\Service::M('Menu')->delete_app($dir);
|
||||
|
||||
// 执行sql语句
|
||||
if (is_file($path.'Config/Uninstall.sql')) {
|
||||
$rt = $this->query_all(file_get_contents($path.'Config/Uninstall.sql'));
|
||||
if ($rt) {
|
||||
return dr_return_data(0, $rt);
|
||||
}
|
||||
}
|
||||
|
||||
// 执行站点sql语句
|
||||
if (is_file($path.'Config/Uninstall_site.sql')) {
|
||||
$sql = file_get_contents($path.'Config/Uninstall_site.sql');
|
||||
foreach ($this->site as $siteid) {
|
||||
$rt = $this->query_all(str_replace(['{dbprefix}', '{siteid}'], [$this->dbprefix($siteid.'_'), $siteid], $sql));
|
||||
if ($rt) {
|
||||
return dr_return_data(0, $rt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 执行自己的卸载程序
|
||||
if (is_file($path.'Config/Uninstall.php')) {
|
||||
require $path.'Config/Uninstall.php';
|
||||
}
|
||||
}
|
||||
|
||||
@unlink($path.'install.lock');
|
||||
|
||||
if (is_file($path.'install.lock')) {
|
||||
return dr_return_data(0, dr_lang('目录%s权限写入', $path));
|
||||
}
|
||||
|
||||
return dr_return_data(1, dr_lang('卸载成功'));
|
||||
}
|
||||
|
||||
// 安装自定义table控制器表
|
||||
public function install_table($file) {
|
||||
|
||||
if (!is_file($file)) {
|
||||
$file = WEBPATH.$file;
|
||||
if (!is_file($file)) {
|
||||
return dr_return_data(0, dr_lang('配置文件不存在'));
|
||||
}
|
||||
}
|
||||
|
||||
$data = dr_string2array(file_get_contents($file));
|
||||
if (!$data) {
|
||||
return dr_return_data(0, dr_lang('配置文件格式错误'));
|
||||
} elseif (!$data['table']) {
|
||||
return dr_return_data(0, dr_lang('配置文件格式错误,缺少table值'));
|
||||
} elseif (!$data['table_sql']) {
|
||||
return dr_return_data(0, dr_lang('配置文件格式错误,缺少table_sql值'));
|
||||
}
|
||||
|
||||
$rt = $this->query_all(str_replace('{dbprefix}', $this->dbprefix(''), $data['table_sql']));
|
||||
if ($rt) {
|
||||
return dr_return_data(0, $rt);
|
||||
}
|
||||
|
||||
$rname = 'table-'.$data['table'];
|
||||
foreach ($data['field'] as $field) {
|
||||
if ($this->db->table('field')
|
||||
->where('fieldname', $field['fieldname'])
|
||||
->where('relatedid', 0)
|
||||
->where('relatedname', $rname)->countAllResults()) {
|
||||
continue;
|
||||
}
|
||||
$this->db->table('field')->insert(array(
|
||||
'name' => (string)($field['name'] ? $field['name'] : $field['textname']),
|
||||
'ismain' => 1,
|
||||
'setting' => dr_array2string($field['setting']),
|
||||
'issystem' => isset($field['issystem']) ? (int)$field['issystem'] : 1,
|
||||
'ismember' => isset($field['ismember']) ? (int)$field['ismember'] : 1,
|
||||
'disabled' => isset($field['disabled']) ? (int)$field['disabled'] : 0,
|
||||
'fieldname' => $field['fieldname'],
|
||||
'fieldtype' => $field['fieldtype'],
|
||||
'relatedid' => 0,
|
||||
'relatedname' => $rname,
|
||||
'displayorder' => (int)$field['displayorder'],
|
||||
));
|
||||
}
|
||||
|
||||
if ($data['config']) {
|
||||
\Phpcmf\Service::L('cache')->set_file('table-config-'.$data['table'], $data['config'], 'table');
|
||||
}
|
||||
|
||||
return dr_return_data(1, dr_lang('导入成功'));
|
||||
}
|
||||
|
||||
// 读取配置信息
|
||||
public function get_config($dir) {
|
||||
|
||||
if (!$dir) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (!isset($this->cfg_cache[$dir])) {
|
||||
$this->cfg_cache[$dir] = \Phpcmf\Service::L('cache')->get_file($dir, 'app');
|
||||
}
|
||||
|
||||
return $this->cfg_cache[$dir];
|
||||
}
|
||||
|
||||
// 存储配置缓存
|
||||
public function save_config($dir, $data) {
|
||||
|
||||
if (!$dir) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
\Phpcmf\Service::L('Cache')->set_file($dir, $data, 'app');
|
||||
}
|
||||
|
||||
// 判断是否是专业版
|
||||
public function is_pro($dir) {
|
||||
$vsn = \Phpcmf\Service::R(dr_get_app_dir($dir).'Config/Version.php');
|
||||
if ($vsn && $vsn['vip']) {
|
||||
return 'Pro';
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
// 购买专业版链接
|
||||
public function buy_url($dir) {
|
||||
$vsn = \Phpcmf\Service::R(dr_get_app_dir($dir).'Config/Version.php');
|
||||
if ($vsn && $vsn['id']) {
|
||||
return 'https://www.xunruicms.com/api/buy.php?id='.$vsn['id'];
|
||||
}
|
||||
return '';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,435 @@
|
||||
<?php namespace Phpcmf\Model;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
/**
|
||||
* 附件模型
|
||||
*/
|
||||
|
||||
class Attachment extends \Phpcmf\Model {
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
$this->siteid = SITE_ID;
|
||||
}
|
||||
|
||||
// 验证用户权限
|
||||
public function check($member, $siteid) {
|
||||
|
||||
if (IS_ADMIN) {
|
||||
// 后台不验证
|
||||
return dr_return_data(1);
|
||||
}
|
||||
|
||||
$this->member = $member;
|
||||
$this->siteid = $siteid;
|
||||
|
||||
$error = '';
|
||||
if ($member['is_admin']) {
|
||||
// 管理员不验证
|
||||
} elseif (IS_USE_MEMBER && !\Phpcmf\Service::L('member_auth', 'member')->member_auth('uploadfile', $this->member)) {
|
||||
$error = dr_lang('您的用户组不允许上传文件');
|
||||
} elseif (!IS_USE_MEMBER && (!defined('SYS_ATTACHMENT_GUEST') || !SYS_ATTACHMENT_GUEST)) {
|
||||
$error = dr_lang('游客不允许上传文件');
|
||||
}
|
||||
|
||||
// 挂钩点 验证格式
|
||||
$rt2 = \Phpcmf\Hooks::trigger_callback('check_upload_auth', $this->member, $error);
|
||||
if ($rt2 && isset($rt2['code'])) {
|
||||
$error = $rt2['code'] ? '' : $rt2['msg'];
|
||||
}
|
||||
|
||||
if ($error) {
|
||||
return dr_return_data(0, $error);
|
||||
}
|
||||
|
||||
return dr_return_data(1);
|
||||
}
|
||||
|
||||
// 附件归属
|
||||
public function handle($uid, $related, $data) {
|
||||
|
||||
if (!SYS_ATTACHMENT_DB) {
|
||||
return;
|
||||
}
|
||||
|
||||
$uid = intval($uid);
|
||||
$member = dr_member_info($uid);
|
||||
// 删除文件
|
||||
if ($data['del'] && $related && $related != 'rand') {
|
||||
$delete = $this->table('attachment')->where_in('id', $data['del'])->getAll();
|
||||
if ($delete) {
|
||||
foreach ($delete as $row) {
|
||||
if ($related == $row['related']) {
|
||||
$this->file_delete($member, $row['id']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 新增归档
|
||||
if ($data['add']) {
|
||||
foreach ($data['add'] as $id) {
|
||||
$id = is_numeric($id) ? intval($id) : 0;
|
||||
if (!$id) {
|
||||
continue;
|
||||
}
|
||||
$t = $this->table('attachment_unused')->get($id);
|
||||
if ($t) {
|
||||
// 更新主索引表
|
||||
$this->table('attachment')->update($id, array(
|
||||
'uid' => $t['uid'],
|
||||
'author' => '',
|
||||
'tableid' => 0,
|
||||
'related' => $related
|
||||
));
|
||||
$this->table('attachment_data')->insert(array(
|
||||
'id' => $t['id'],
|
||||
'uid' => $t['uid'],
|
||||
'remote' => $t['remote'],
|
||||
'author' => '',
|
||||
'related' => $related,
|
||||
'fileext' => $t['fileext'],
|
||||
'filesize' => $t['filesize'],
|
||||
'filename' => $t['filename'],
|
||||
'inputtime' => $t['inputtime'],
|
||||
'attachment' => $t['attachment'],
|
||||
'attachinfo' => $t['attachinfo'],
|
||||
));
|
||||
// 删除未使用附件
|
||||
$this->table('attachment_unused')->delete($id);
|
||||
} else {
|
||||
// 已使用的附件库
|
||||
$t = $this->table('attachment_data')->get($id);
|
||||
if ($t) {
|
||||
if (strpos($t['related'], 'ueditor') !== false) {
|
||||
// 编辑器字段归属
|
||||
$this->table('attachment')->update($id, array(
|
||||
'related' => $related
|
||||
));
|
||||
$this->table('attachment_data')->update($id, array(
|
||||
'related' => $related
|
||||
));
|
||||
} elseif ($t['related'] != $related) {
|
||||
// 表示多表复用
|
||||
$this->table('attachment')->update($id, array(
|
||||
'related' => 'rand'
|
||||
));
|
||||
$this->table('attachment_data')->update($id, array(
|
||||
'related' => 'rand'
|
||||
));
|
||||
} else {
|
||||
// 表示多表复用
|
||||
$this->table('attachment')->update($id, array(
|
||||
'related' => $related.'-rand'
|
||||
));
|
||||
$this->table('attachment_data')->update($id, array(
|
||||
'related' => $related.'-rand'
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 删除内容关联的文件
|
||||
public function cid_delete($member, $cid, $related) {
|
||||
|
||||
if (!$cid) {
|
||||
return;
|
||||
} elseif (!IS_ADMIN && !$member) {
|
||||
return;
|
||||
}
|
||||
|
||||
$indexs = $this->table('attachment')->where('related', $related.'-'.$cid)->getAll();
|
||||
if ($indexs) {
|
||||
foreach ($indexs as $i) {
|
||||
$this->file_delete($member, intval($i['id']));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 删除用户的全部关联的文件
|
||||
public function uid_delete($uid) {
|
||||
|
||||
if (!$uid ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$indexs = $this->table('attachment')->where('uid', $uid)->getAll();
|
||||
if ($indexs) {
|
||||
foreach ($indexs as $i) {
|
||||
$this->file_delete($uid, intval($i['id']));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 删除内容关联的文件
|
||||
public function id_delete($member, $ids, $related) {
|
||||
|
||||
if (!$member || !$ids) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($ids as $id) {
|
||||
$indexs = $this->table('attachment')->where('related', $related.'-'.$id)->getAll();
|
||||
if ($indexs) {
|
||||
foreach ($indexs as $i) {
|
||||
$this->file_delete($member, intval($i['id']));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// related删除
|
||||
public function related_delete($related, $id = 0) {
|
||||
|
||||
if ($id) {
|
||||
$indexs = $this->table('attachment')->where('related', $related.'-'.$id)->getAll();
|
||||
} else {
|
||||
$indexs = $this->table('attachment')->where('related LIKE "'.$related.'-%"')->getAll();
|
||||
}
|
||||
|
||||
if ($indexs) {
|
||||
foreach ($indexs as $index) {
|
||||
$this->_delete_file($index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 删除文件判断
|
||||
public function file_delete($member, $id) {
|
||||
|
||||
if (!$member) {
|
||||
return dr_return_data(0, dr_lang('必须登录之后才能删除文件'));
|
||||
} elseif (!$id) {
|
||||
return dr_return_data(0, dr_lang('文件id不存在'));
|
||||
} elseif (!isset($member['id'])) {
|
||||
return dr_return_data(0, dr_lang('必须登录之后才能删除文件'));
|
||||
}
|
||||
|
||||
if (is_numeric($member)) {
|
||||
$member = $this->table('member')->get($member);
|
||||
if (!$member) {
|
||||
return dr_return_data(0, dr_lang('必须登录之后才能删除文件'));
|
||||
}
|
||||
}
|
||||
|
||||
$index = $this->table('attachment')->get($id);
|
||||
if (!$index) {
|
||||
return dr_return_data(0, dr_lang('文件记录不存在'));
|
||||
}
|
||||
if (IS_ADMIN) {
|
||||
// 后台删除
|
||||
if (!\Phpcmf\Service::M('auth')->_is_admin_auth('attachments/del')) {
|
||||
return dr_return_data(0, dr_lang('无权限操作'));
|
||||
}
|
||||
} else {
|
||||
// 前端删除自己的
|
||||
if ($member['id'] != $index['uid']) {
|
||||
return dr_return_data(0, dr_lang('不能删除他人的文件'));
|
||||
}
|
||||
}
|
||||
|
||||
return $this->_delete_file($index);
|
||||
}
|
||||
|
||||
// 开始删除文件
|
||||
public function _delete_file($index) {
|
||||
|
||||
$table = $index['related'] ? 'attachment_data' : 'attachment_unused';
|
||||
|
||||
// 获取文件信息
|
||||
$info = $this->table($table)->get($index['id']);
|
||||
if (!$info) {
|
||||
$this->table('attachment')->delete($index['id']);
|
||||
return dr_return_data(0, dr_lang('文件数据不存在'));
|
||||
}
|
||||
|
||||
$rt = $this->table('attachment')->delete($index['id']);
|
||||
if (!$rt['code']) {
|
||||
return dr_return_data(0, $rt['msg']);
|
||||
}
|
||||
|
||||
// 删除记录
|
||||
$this->table($table)->delete($index['id']);
|
||||
|
||||
// 开始删除文件
|
||||
$storage = new \Phpcmf\Library\Storage(\Phpcmf\Service::C());
|
||||
$storage->delete($this->get_attach_info($info['remote']), $info['attachment']);
|
||||
|
||||
// 删除缓存
|
||||
$this->clear_data($index);
|
||||
|
||||
// 删除附件进行记录
|
||||
\Phpcmf\Service::L('input')->system_log('删除附件(#'.$index['id'].'-'.dr_now_url().')'.var_export($info, true));
|
||||
if (CI_DEBUG) {
|
||||
log_message('debug', '删除附件(#'.$index['id'].')'.dr_get_file_url($info));
|
||||
}
|
||||
|
||||
return dr_return_data(1, dr_lang('删除成功'));
|
||||
}
|
||||
|
||||
// 删除附件缓存
|
||||
public function clear_data($index) {
|
||||
|
||||
\Phpcmf\Service::L('cache')->del_file('attach-info-'.$index['id'], 'attach');
|
||||
|
||||
// 删除缩略图的缓存
|
||||
if (in_array($index['fileext'], ['png', 'jpeg', 'jpg', 'gif'])) {
|
||||
list($cache_path, $a, $b, $path) = dr_thumb_path($index['id']);
|
||||
dr_dir_delete($cache_path.'/'.$path.'/', true);
|
||||
}
|
||||
}
|
||||
|
||||
// 附件归档存储
|
||||
// $handle是否强制随机储存已使用
|
||||
public function save_data($data, $related = '', $handle = 0) {
|
||||
|
||||
if (!$this->member) {
|
||||
$this->member = [
|
||||
'id'=> 0,
|
||||
'username' => 'guest',
|
||||
];
|
||||
}
|
||||
|
||||
// 按uid散列分表
|
||||
$tid = (int)substr((string)$this->member['id'], -1, 1);
|
||||
$related = $related ? $related : (SYS_ATTACHMENT_DB ? '' : 'rand');
|
||||
$data['name'] = dr_safe_replace($data['name'], ["/", '\\', '..']);
|
||||
|
||||
// 入库索引表
|
||||
$rt = $this->table('attachment')->replace([
|
||||
'uid' => (int)$this->member['id'],
|
||||
'author' => '',
|
||||
'siteid' => $this->siteid,
|
||||
'related' => $related,
|
||||
'tableid' => $tid,
|
||||
'download' => 0,
|
||||
'filesize' => (int)$data['size'],
|
||||
'fileext' => $data['ext'],
|
||||
'filemd5' => $data['md5'] ? $data['md5'] : 0,
|
||||
]);
|
||||
if (!$rt['code']) {
|
||||
// 入库失败
|
||||
unlink($data['path']);
|
||||
return $rt;
|
||||
}
|
||||
$id = $rt['code'];
|
||||
if ($handle == 0 && (strpos($related, 'ueditor') === 0 ? 0 : SYS_ATTACHMENT_DB)) {
|
||||
// 归档存储
|
||||
$rt = $this->table('attachment_unused')->replace([
|
||||
'id' => $id,
|
||||
'uid' => (int)$this->member['id'],
|
||||
'author' => '',
|
||||
'siteid' => $this->siteid,
|
||||
'remote' => $data['remote'],
|
||||
'fileext' => $data['ext'],
|
||||
'filename' => $data['name'],
|
||||
'filesize' => (int)$data['size'],
|
||||
'inputtime' => SYS_TIME,
|
||||
'attachment' => $data['file'],
|
||||
'attachinfo' => dr_safe_url($_SERVER['HTTP_REFERER']),
|
||||
]);
|
||||
} else {
|
||||
// 随机存储
|
||||
$rt = $this->table('attachment_data')->replace([
|
||||
'id' => $id,
|
||||
'uid' => (int)$this->member['id'],
|
||||
'author' => '',
|
||||
'related' => $related,
|
||||
'filename' => $data['name'],
|
||||
'fileext' => $data['ext'],
|
||||
'filesize' => $data['size'],
|
||||
'remote' => $data['remote'],
|
||||
'attachinfo' => dr_array2string($data['info']),
|
||||
'attachment' => $data['file'],
|
||||
'inputtime' => SYS_TIME,
|
||||
]);
|
||||
}
|
||||
|
||||
// 入库失败 无主键id 返回msg为准
|
||||
if ($rt['msg']) {
|
||||
// 删除附件索引
|
||||
unlink($data['path']);
|
||||
$this->table('attachment')->delete($id);
|
||||
return dr_return_data(0, $rt['msg']);
|
||||
}
|
||||
|
||||
// 统计附件插件
|
||||
if (dr_is_app('mfile')) {
|
||||
\Phpcmf\Service::M('mfile', 'mfile')->update_member($this->member, $data['size']);
|
||||
}
|
||||
|
||||
return dr_return_data($id, 'ok');
|
||||
}
|
||||
|
||||
// 附件存储信息
|
||||
public function get_attach_info($id = 0, $image_reduce = 0) {
|
||||
|
||||
// 全局存储
|
||||
if ((!$id || $id == 'null') && SYS_ATTACHMENT_SAVE_ID) {
|
||||
$id = SYS_ATTACHMENT_SAVE_ID;
|
||||
}
|
||||
|
||||
$remote = \Phpcmf\Service::C()->get_cache('attachment');
|
||||
if (isset($remote[$id]) && $remote[$id]) {
|
||||
$rt = $remote[$id];
|
||||
$rt['image_reduce'] = $image_reduce;
|
||||
return $rt;
|
||||
}
|
||||
|
||||
return [
|
||||
'id' => 0,
|
||||
'url' => SYS_UPLOAD_URL,
|
||||
'type' => 0,
|
||||
'image_reduce' => $image_reduce,
|
||||
'value' => [
|
||||
'path' => SYS_UPLOAD_PATH
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
// 存储aid到内存中
|
||||
public function save_ueditor_aid($rid, $aid) {
|
||||
$name = 'ueditor_aid_'.$rid;
|
||||
$data = dr_string2array(\Phpcmf\Service::L('cache')->get_auth_data($name));
|
||||
if (!$data || !is_array($data)) {
|
||||
$data = [$aid];
|
||||
} else {
|
||||
$data[] = $aid;
|
||||
}
|
||||
\Phpcmf\Service::L('cache')->set_auth_data($name, $data);
|
||||
}
|
||||
|
||||
// 读取aid
|
||||
public function get_ueditor_aid($rid, $is_del = false) {
|
||||
$name = 'ueditor_aid_'.$rid;
|
||||
$data = \Phpcmf\Service::L('cache')->get_auth_data($name);
|
||||
$is_del && \Phpcmf\Service::L('cache')->del_auth_data($name);
|
||||
return $data;
|
||||
}
|
||||
|
||||
// 远程附件缓存
|
||||
public function cache($site = SITE_ID) {
|
||||
|
||||
$data = $this->table('attachment_remote')->getAll();
|
||||
$cache = [];
|
||||
if ($data) {
|
||||
foreach ($data as $t) {
|
||||
$t['url'] = trim($t['url'], '/').'/';
|
||||
$t['value'] = dr_string2array($t['value']);
|
||||
$t['value'] = $t['value'][intval($t['type'])];
|
||||
$cache[$t['id']] = $t;
|
||||
}
|
||||
}
|
||||
|
||||
\Phpcmf\Service::L('cache')->set_file('attachment', $cache);
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,427 @@
|
||||
<?php namespace Phpcmf\Model;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
|
||||
// 系统缓存
|
||||
class Cache extends \Phpcmf\Model {
|
||||
|
||||
protected $site_cache;
|
||||
protected $module_cache;
|
||||
protected $is_sync_cache;
|
||||
|
||||
// 清理缩略图
|
||||
public function update_thumb() {
|
||||
list($cache_path) = dr_thumb_path();
|
||||
if (strpos(WEBPATH, $cache_path) !== false || is_file($cache_path.'index.php')) {
|
||||
// 防止误删除
|
||||
\Phpcmf\Service::C()->_json(0, dr_lang('缩略图目录异常,请手动清理:%s', $cache_path));
|
||||
}
|
||||
dr_dir_delete($cache_path);
|
||||
dr_mkdirs($cache_path);
|
||||
\Phpcmf\Service::C()->_json(1, dr_lang('清理完成'), 1);
|
||||
}
|
||||
|
||||
|
||||
// 清理日志文件
|
||||
public function update_log() {
|
||||
|
||||
foreach ([
|
||||
WRITEPATH.'log/',
|
||||
WRITEPATH.'debugbar/',
|
||||
WRITEPATH.'debuglog/',
|
||||
WRITEPATH.'error/',
|
||||
WRITEPATH.'database/Sql/',
|
||||
] as $t) {
|
||||
if (is_dir($t)) {
|
||||
dr_dir_delete($t);
|
||||
dr_mkdirs($t);
|
||||
}
|
||||
}
|
||||
foreach ([
|
||||
WRITEPATH.'email_log.txt',
|
||||
WRITEPATH.'sms_log.txt',
|
||||
] as $t) {
|
||||
if (is_file($t)) {
|
||||
unlink($t);
|
||||
}
|
||||
}
|
||||
\Phpcmf\Service::C()->_json(1, dr_lang('清理完成'), 1);
|
||||
}
|
||||
|
||||
// 更新自定义路由
|
||||
public function update_rewrite_routes() {
|
||||
dr_dir_delete(WRITEPATH.'route/');
|
||||
\Phpcmf\Hooks::trigger('update_rewrite_routes');
|
||||
\Phpcmf\Service::C()->_json(1, dr_lang('执行完成,请更新其他地方的URL地址'), 1);
|
||||
}
|
||||
|
||||
// 更新附件缓存
|
||||
public function update_attachment() {
|
||||
|
||||
$page = intval($_GET['page']);
|
||||
if (!$page) {
|
||||
dr_dir_delete(WRITEPATH.'attach');
|
||||
dr_mkdirs(WRITEPATH.'attach');
|
||||
/*不清理缩略图文件是因为静态页面会导致缩略图404的悲剧
|
||||
list($cache_path) = dr_thumb_path();
|
||||
dr_dir_delete($cache_path);
|
||||
dr_mkdirs($cache_path);*/
|
||||
\Phpcmf\Service::C()->_json(1, dr_lang('正在检查附件'), 1);
|
||||
}
|
||||
|
||||
$total = $this->table('attachment')->counts();
|
||||
if (!$total) {
|
||||
\Phpcmf\Service::C()->_json(1, dr_lang('无可用附件更新'), 0);
|
||||
}
|
||||
|
||||
$psize = 300;
|
||||
$tpage = ceil($total/$psize);
|
||||
$result = $this->db->table('attachment')->orderBy('id ASC')->limit($psize, $psize * ($page - 1))->get()->getResultArray();
|
||||
if ($result) {
|
||||
foreach ($result as $t) {
|
||||
\Phpcmf\Service::C()->get_attachment($t['id']);
|
||||
}
|
||||
}
|
||||
|
||||
if ($page > $tpage) {
|
||||
\Phpcmf\Service::C()->_json(1, dr_lang('已更新%s个附件', $total), 0);
|
||||
}
|
||||
|
||||
\Phpcmf\Service::C()->_json(1, dr_lang('正在更新中(%s/%s)', $page, $tpage), $page + 1);
|
||||
}
|
||||
|
||||
// 同步更新缓存
|
||||
// \Phpcmf\Service::M('cache')->sync_cache(); $is_site 表示是否作为项目来更新缓存
|
||||
public function sync_cache($name = '', $namepspace = '', $is_site_param = 0) {
|
||||
|
||||
\Phpcmf\Hooks::trigger('update_cache');
|
||||
|
||||
if (!$this->is_sync_cache) {
|
||||
$this->site_cache = $this->table('site')->where('disabled', 0)->getAll();
|
||||
if (dr_is_use_module()) {
|
||||
$this->module_cache = $this->table('module')->order_by('displayorder ASC,id ASC')->getAll();
|
||||
\Phpcmf\Service::M('site', 'module')->cache(0, $this->site_cache, $this->module_cache);
|
||||
} else {
|
||||
\Phpcmf\Service::M('site')->cache(0, $this->site_cache);
|
||||
}
|
||||
}
|
||||
|
||||
if ($name) {
|
||||
if (!$is_site_param) {
|
||||
// 普通缓存执行
|
||||
\Phpcmf\Service::M($name, $namepspace)->cache();
|
||||
} else {
|
||||
// 传入项目参数
|
||||
\Phpcmf\Service::M($name, $namepspace)->cache(SITE_ID);
|
||||
}
|
||||
}
|
||||
|
||||
\Phpcmf\Service::M('table')->cache(SITE_ID, $this->module_cache);
|
||||
if ($this->module_cache) {
|
||||
\Phpcmf\Service::M('module')->cache(SITE_ID, $this->module_cache);
|
||||
}
|
||||
|
||||
\Phpcmf\Service::M('menu')->cache();
|
||||
|
||||
if (!$this->is_sync_cache) {
|
||||
$this->is_sync_cache = 1;
|
||||
}
|
||||
|
||||
$this->update_data_cache();
|
||||
}
|
||||
|
||||
// 更新数据结构
|
||||
public function update_db() {
|
||||
// 执行插件自己的更新程序
|
||||
$local = \Phpcmf\Service::Apps();
|
||||
foreach ($local as $dir => $path) {
|
||||
if (!is_file($path.'install.lock')) {
|
||||
continue;
|
||||
}
|
||||
if (is_file($path.'Config/Update.php')) {
|
||||
require $path.'Config/Update.php';
|
||||
}
|
||||
// 更新新增菜单
|
||||
\Phpcmf\Service::M('menu')->update_app($dir);
|
||||
}
|
||||
}
|
||||
|
||||
// 更新全部项目缓存
|
||||
public function update_site_cache() {
|
||||
|
||||
\Phpcmf\Hooks::trigger('update_cache');
|
||||
|
||||
if (dr_is_use_module()) {
|
||||
if (is_file(IS_USE_MODULE.'Models/Site.php')) {
|
||||
\Phpcmf\Service::M('site', 'module')->update_site_cache();
|
||||
} else {
|
||||
\Phpcmf\Service::C()->_json(0, dr_lang('请升级建站系统插件'));
|
||||
}
|
||||
} else {
|
||||
// 按项目更新的缓存
|
||||
$cache = [];
|
||||
if (is_file(MYPATH.'/Config/Cache.php')) {
|
||||
$_cache = require MYPATH.'/Config/Cache.php';
|
||||
$_cache && $cache = dr_array22array($cache, $_cache);
|
||||
}
|
||||
// 执行插件自己的缓存程序
|
||||
$local = \Phpcmf\Service::Apps();
|
||||
$app_cache = [];
|
||||
foreach ($local as $dir => $path) {
|
||||
if (!is_file($path.'install.lock')) {
|
||||
continue;
|
||||
}
|
||||
if (is_file($path.'Config/Cache.php')) {
|
||||
$_cache = require $path.'Config/Cache.php';
|
||||
$_cache && $app_cache[$dir] = $_cache;
|
||||
}
|
||||
// 更新新增菜单
|
||||
\Phpcmf\Service::M('menu')->update_app($dir);
|
||||
}
|
||||
//dr_dir_delete(WRITEPATH.'data');
|
||||
foreach (['auth', 'email', 'member', 'attachment', 'system', 'site'] as $m) {
|
||||
\Phpcmf\Service::M($m)->cache();
|
||||
}
|
||||
// 自定义缓存
|
||||
foreach ($cache as $m => $namespace) {
|
||||
\Phpcmf\Service::M($m, $namespace)->cache(1);
|
||||
}
|
||||
// 插件缓存
|
||||
$apps = [];
|
||||
if ($app_cache) {
|
||||
foreach ($app_cache as $namespace => $c) {
|
||||
\Phpcmf\Service::C()->init_file($namespace);
|
||||
foreach ($c as $i => $apt) {
|
||||
$class = is_numeric($i) ? $apt : $i;
|
||||
$apps[] = '['.$namespace.'-'.$class.']';
|
||||
\Phpcmf\Service::M($class, $namespace)->cache(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 记录日志
|
||||
CI_DEBUG && \Phpcmf\Service::L('input')->system_log('更新缓存:'.implode(' - ', $apps));
|
||||
\Phpcmf\Service::C()->_json(1, dr_lang('更新完成'));
|
||||
}
|
||||
}
|
||||
|
||||
// 更新当前项目缓存
|
||||
public function update_cache() {
|
||||
|
||||
\Phpcmf\Hooks::trigger('update_cache');
|
||||
|
||||
dr_dir_delete(WRITEPATH.'tree');
|
||||
|
||||
if (dr_is_use_module()) {
|
||||
if (is_file(IS_USE_MODULE.'Models/Site.php')) {
|
||||
\Phpcmf\Service::M('site', 'module')->update_cache();
|
||||
} else {
|
||||
\Phpcmf\Service::C()->_json(0, dr_lang('请升级建站系统插件'));
|
||||
}
|
||||
} else {
|
||||
// 全局缓存
|
||||
foreach (['auth', 'email', 'member', 'attachment', 'system', 'site'] as $m) {
|
||||
\Phpcmf\Service::M($m)->cache();
|
||||
}
|
||||
|
||||
// 按项目更新的缓存
|
||||
$cache = [];
|
||||
|
||||
if (is_file(MYPATH.'/Config/Cache.php')) {
|
||||
$_cache = require MYPATH.'/Config/Cache.php';
|
||||
$_cache && $cache = dr_array22array($cache, $_cache);
|
||||
}
|
||||
|
||||
// 执行插件自己的缓存程序
|
||||
$local = \Phpcmf\Service::Apps();
|
||||
$app_cache = [];
|
||||
foreach ($local as $dir => $path) {
|
||||
if (!is_file($path.'install.lock')) {
|
||||
continue;
|
||||
}
|
||||
if (is_file($path.'Config/Cache.php')) {
|
||||
$_cache = require $path.'Config/Cache.php';
|
||||
$_cache && $app_cache[$dir] = $_cache;
|
||||
}
|
||||
// 更新新增菜单
|
||||
\Phpcmf\Service::M('menu')->update_app($dir);
|
||||
}
|
||||
// 插件缓存
|
||||
$apps = [];
|
||||
if ($app_cache) {
|
||||
foreach ($app_cache as $namespace => $c) {
|
||||
\Phpcmf\Service::C()->init_file($namespace);
|
||||
foreach ($c as $i => $apt) {
|
||||
$class = is_numeric($i) ? $apt : $i;
|
||||
$apps[] = '['.$namespace.'-'.$class.']';
|
||||
\Phpcmf\Service::M($class, $namespace)->cache(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 记录日志
|
||||
CI_DEBUG && \Phpcmf\Service::L('input')->system_log('更新缓存:'.implode(' - ', $apps));
|
||||
|
||||
\Phpcmf\Service::M('table')->cache(1, []);
|
||||
\Phpcmf\Service::M('menu')->cache();
|
||||
}
|
||||
}
|
||||
|
||||
// 更新数据 $all表示是否强制更新缓存
|
||||
public function update_data_cache($all = false) {
|
||||
|
||||
if ($all or !SYS_CACHE_CLEAR) {
|
||||
|
||||
// 清空系统缓存
|
||||
\Phpcmf\Service::L('cache')->init()->clean();
|
||||
|
||||
// 清空文件缓存
|
||||
\Phpcmf\Service::L('cache')->init('file')->clean();
|
||||
|
||||
// 递归删除文件
|
||||
$path = [
|
||||
WRITEPATH.'file',
|
||||
WRITEPATH.'template',
|
||||
WRITEPATH.'debugbar',
|
||||
];
|
||||
// 默认文件内容
|
||||
$cache_index = '<IfModule authz_core_module>
|
||||
Require all denied
|
||||
</IfModule>
|
||||
<IfModule !authz_core_module>
|
||||
Deny from all
|
||||
</IfModule>
|
||||
';
|
||||
// 开始删除目录数据
|
||||
foreach ($path as $p) {
|
||||
dr_dir_delete($p);
|
||||
mkdir($p, 0777);
|
||||
file_put_contents($p.'/.htaccess', $cache_index);
|
||||
}
|
||||
}
|
||||
|
||||
// 删除缓存保留24小时内的文件
|
||||
$path = [
|
||||
WRITEPATH.'authcode',
|
||||
WRITEPATH.'debugbar',
|
||||
WRITEPATH.'session',
|
||||
WRITEPATH.'thread',
|
||||
WRITEPATH.'temp',
|
||||
];
|
||||
foreach ($path as $p) {
|
||||
if ($fp = opendir($p)) {
|
||||
while (FALSE !== ($file = readdir($fp))) {
|
||||
if ($file === '.' OR $file === '..'
|
||||
OR $file === 'index.html'
|
||||
OR $file === '.htaccess'
|
||||
OR $file[0] === '.'
|
||||
OR !is_file($p.'/'.$file)
|
||||
OR SYS_TIME - filemtime($p.'/'.$file) < 3600 * 24 // 保留24小时内的文件
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
unlink($p.'/'.$file);
|
||||
}
|
||||
file_put_contents($p.'/.htaccess', $cache_index);
|
||||
}
|
||||
}
|
||||
|
||||
// 删除首页静态文件
|
||||
if (isset(\Phpcmf\Service::C()->site_info[SITE_ID]['SITE_INDEX_HTML'])
|
||||
&& \Phpcmf\Service::C()->site_info[SITE_ID]['SITE_INDEX_HTML']) {
|
||||
unlink(\Phpcmf\Service::L('html')->get_webpath(SITE_ID, 'site', 'index.html'));
|
||||
unlink(\Phpcmf\Service::L('html')->get_webpath(SITE_ID, 'site', SITE_MOBILE_DIR.'/index.html'));
|
||||
}
|
||||
|
||||
@unlink(WRITEPATH.'config/run_lock.php');
|
||||
|
||||
// 重置Zend OPcache
|
||||
function_exists('opcache_reset') && opcache_reset();
|
||||
}
|
||||
|
||||
// 编辑器更新
|
||||
public function update_ueditor() {
|
||||
|
||||
$site = $this->table('site')->where('disabled', 0)->getAll();
|
||||
foreach ($site as $t) {
|
||||
$t['setting'] = dr_string2array($t['setting']);
|
||||
if ($t['id'] > 1 && $t['setting']['webpath']) {
|
||||
$path = rtrim($t['setting']['webpath'], '/').'/';
|
||||
} else {
|
||||
$path = WEBPATH;
|
||||
}
|
||||
// 复制百度编辑器到当前目录
|
||||
$this->cp_ueditor_file($path);
|
||||
// 复制百度编辑器到移动端项目
|
||||
$this->cp_ueditor_file($path.'mobile/');
|
||||
if ($t['setting']['client']) {
|
||||
foreach ($t['setting']['client'] as $c) {
|
||||
if ($c['name'] && $c['domain']) {
|
||||
// 复制百度编辑器到当前目录
|
||||
$this->cp_ueditor_file($path.$c['name'].'/');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 为后台域名移动编辑器目录
|
||||
if (dr_is_app('safe')) {
|
||||
$safe = \Phpcmf\Service::M('app')->get_config('safe');
|
||||
if ($safe) {
|
||||
foreach ($safe as $key => $path) {
|
||||
if (is_string($path) && is_numeric($key) && is_dir($path)) {
|
||||
$this->cp_ueditor_file($path.'/');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 复制编辑器
|
||||
public function cp_ueditor_file($path) {
|
||||
|
||||
$npath = $path.'api/ueditor/';
|
||||
if (!is_file($npath.'ueditor.config.js')) {
|
||||
return;
|
||||
}
|
||||
|
||||
dr_mkdirs($npath);
|
||||
|
||||
\Phpcmf\Service::L('file')->copy_dir(ROOTPATH.'api/ueditor/dialogs/', ROOTPATH.'api/ueditor/dialogs/', $npath.'dialogs/');
|
||||
\Phpcmf\Service::L('file')->copy_dir(ROOTPATH.'api/ueditor/third-party/', ROOTPATH.'api/ueditor/third-party/', $npath.'third-party/');
|
||||
}
|
||||
|
||||
public function update_search_index() {
|
||||
if (IS_USE_MODULE) {
|
||||
\Phpcmf\Service::M('site', 'module')->update_search_index();
|
||||
}
|
||||
}
|
||||
|
||||
// 重建子站配置文件
|
||||
public function update_site_config() {
|
||||
if (IS_USE_MODULE) {
|
||||
\Phpcmf\Service::M('site', 'module')->update_site_config();
|
||||
}
|
||||
}
|
||||
|
||||
// 生成目录式手机目录
|
||||
public function update_mobile_webpath($path, $dirname) {
|
||||
if (IS_USE_MODULE) {
|
||||
\Phpcmf\Service::M('site', 'module')->update_mobile_webpath($path, $dirname);
|
||||
}
|
||||
}
|
||||
|
||||
// 更新项目
|
||||
public function update_webpath($name, $path, $value, $root = TEMPPATH) {
|
||||
if (IS_USE_MODULE) {
|
||||
\Phpcmf\Service::M('site', 'module')->update_webpath($name, $path, $value, $root);
|
||||
}
|
||||
}
|
||||
|
||||
// 错误输出
|
||||
public function _error_msg($msg) {
|
||||
echo dr_array2string(dr_return_data(0, $msg));exit;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
<?php
|
||||
// 文件作废
|
||||
@@ -0,0 +1,2 @@
|
||||
<?php
|
||||
// 文件作废
|
||||
@@ -0,0 +1,140 @@
|
||||
<?php namespace Phpcmf\Model;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
class Cron extends \Phpcmf\Model {
|
||||
|
||||
// 入队任务
|
||||
public function add_cron($site, $type, $data) {
|
||||
|
||||
$rt = $this->table('cron')->insert([
|
||||
'site' => $site,
|
||||
'type' => $type,
|
||||
'value' => dr_array2string($data),
|
||||
'status' => 0,
|
||||
'error' => '',
|
||||
'updatetime' => 0,
|
||||
'inputtime' => SYS_TIME,
|
||||
]);
|
||||
|
||||
// 当服务器开启了自动任务,那么只入库不运行任务;未开启时直接执行
|
||||
if ($rt['code'] && !is_file(WRITEPATH.'config/run_lock.php')) {
|
||||
\Phpcmf\Service::L('thread')->cron(['action' => 'cron', 'id' => $rt['code'] ]);
|
||||
}
|
||||
|
||||
return $rt;
|
||||
}
|
||||
|
||||
// 存储renw
|
||||
public function save_cron($cron, $data) {
|
||||
|
||||
if ((!$data['value'] && !$data['error']) || $cron['status'] >= 9) {
|
||||
// 没有错 或者 超时 就删除记录
|
||||
$this->table('cron')->delete($cron['id']);
|
||||
return dr_return_data(1, 'ok');
|
||||
} else {
|
||||
$this->table('cron')->update($cron['id'], [
|
||||
'value' => dr_array2string($data['value']),
|
||||
'error' => dr_array2string($data['error']),
|
||||
'status' => $cron['status'] + 1,
|
||||
'updatetime' => SYS_TIME,
|
||||
]);
|
||||
return dr_return_data(0, $cron['id'].'#'.(is_array($data['error']) ? implode('、', $data['error']) : $data['error']), $cron);
|
||||
}
|
||||
}
|
||||
|
||||
// 执行本任务
|
||||
public function do_cron($cron) {
|
||||
|
||||
$value = dr_string2array($cron['value']);
|
||||
|
||||
switch ($cron['type']) {
|
||||
|
||||
case 'email':
|
||||
// 邮件发送
|
||||
list($error, $value) = \Phpcmf\Service::L('notice')->cron_email($value['config']['tomail'], $cron['site'], $value);
|
||||
|
||||
// 加入队列并执行
|
||||
return $this->save_cron($cron, [
|
||||
'error' => $error,
|
||||
'value' => $value,
|
||||
]);
|
||||
break;
|
||||
|
||||
case 'notice':
|
||||
// 通知消息
|
||||
list($error, $value) = \Phpcmf\Service::L('notice')->cron_notice($cron['site'], $value);
|
||||
|
||||
// 加入队列并执行
|
||||
return $this->save_cron($cron, [
|
||||
'error' => $error,
|
||||
'value' => $value,
|
||||
]);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
if (!$cron['type']) {
|
||||
log_message('debug', '任务查询('.$cron['id'].')类型type不存在');
|
||||
return dr_return_data(0, '任务查询('.$cron['id'].')类型type不存在');
|
||||
}
|
||||
|
||||
if (strpos($cron['type'], '::')) {
|
||||
list($app, $name) = explode('::', $cron['type']);
|
||||
if (dr_is_app($app)) {
|
||||
$file = dr_get_app_dir($app).'Cron/'.ucfirst($name).'.php';
|
||||
} else {
|
||||
log_message('debug', '任务查询('.$cron['id'].')类型【'.$cron['type'].'】插件不存在:'.$app);
|
||||
return dr_return_data(0, '任务查询('.$cron['id'].')类型【'.$cron['type'].'】插件不存在');
|
||||
}
|
||||
} else {
|
||||
$file = MYPATH.'Cron/'.ucfirst($cron['type']).'.php';
|
||||
}
|
||||
|
||||
if (is_file($file)) {
|
||||
$error = require $file;
|
||||
// 加入队列并执行
|
||||
return $this->save_cron($cron, [
|
||||
'error' => $error,
|
||||
'value' => $error ? $value : [],
|
||||
]);
|
||||
} else {
|
||||
log_message('debug', '任务查询('.$cron['id'].')类型【'.$cron['type'].'】程序文件不存在:'.$file);
|
||||
return dr_return_data(0, '任务查询('.$cron['id'].')类型【'.$cron['type'].'】程序文件不存在');
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 执行本任务
|
||||
public function do_cron_id($id) {
|
||||
$cron = $this->table('cron')->get($id);
|
||||
return $this->do_cron($cron);
|
||||
}
|
||||
|
||||
// 运行脚本
|
||||
public function run_cron($num = 20) {
|
||||
|
||||
$crons = $this->table('cron')->getAll($num ? $num : 20);
|
||||
if (!$crons) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
foreach ($crons as $cron) {
|
||||
if (isset($_GET['is_cdn'])) {
|
||||
$this->do_cron($cron);
|
||||
} else {
|
||||
\Phpcmf\Service::L('thread')->cron(['action' => 'cron', 'id' => $cron['id'] ]);
|
||||
}
|
||||
}
|
||||
|
||||
return dr_count($crons);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
<?php namespace Phpcmf\Model;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
class Email extends \Phpcmf\Model {
|
||||
|
||||
protected $site_name;
|
||||
|
||||
/**
|
||||
* 发件人名称
|
||||
*/
|
||||
public function site_name($siteid) {
|
||||
if (isset(\Phpcmf\Service::C()->site_info[$siteid]['SITE_NAME'])) {
|
||||
$this->site_name = \Phpcmf\Service::C()->site_info[$siteid]['SITE_NAME'];
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 邮件发送
|
||||
*/
|
||||
public function sendmail($tomail, $subject, $msg, $data = []) {
|
||||
|
||||
if (!$tomail) {
|
||||
return dr_return_data(0, dr_lang('第一个参数不能为空'));
|
||||
} elseif (!$subject) {
|
||||
return dr_return_data(0, dr_lang('第二个参数不能为空'));
|
||||
} elseif (!$msg) {
|
||||
return dr_return_data(0, dr_lang('第三个参数不能为空'));
|
||||
}
|
||||
|
||||
$cache = \Phpcmf\Service::L('cache')->get('email');
|
||||
if (!$cache) {
|
||||
return dr_return_data(0, dr_lang('无邮件smtp配置'));
|
||||
}
|
||||
|
||||
$content = $msg;
|
||||
if (strlen($msg) <= 30 && trim(strtolower(strrchr($msg, '.')), '.') == 'html') {
|
||||
$my = WEBPATH.'config/notice/email/'.$msg;
|
||||
$default = CONFIGPATH.'notice/email/'.$msg;
|
||||
$content = is_file($my) ? file_get_contents($my) : file_get_contents($default);
|
||||
if (!$content) {
|
||||
log_message('error', '邮件模板不存在:'.$msg);
|
||||
return dr_return_data(0, dr_lang('邮件模板[#%s]不存在', $msg));
|
||||
}
|
||||
ob_start();
|
||||
extract($data, EXTR_PREFIX_SAME, 'data');
|
||||
$file = \Phpcmf\Service::V()->code2php($content);
|
||||
require $file;
|
||||
$content = ob_get_clean();
|
||||
}
|
||||
|
||||
$dmail = \Phpcmf\Service::L('email');
|
||||
foreach ($cache as $data) {
|
||||
$dmail->set(array(
|
||||
'host' => trim($data['host']),
|
||||
'user' => trim($data['user']),
|
||||
'pass' => trim($data['pass']),
|
||||
'port' => $data['port'],
|
||||
'from' => $data['user'],
|
||||
));
|
||||
if ($dmail->send($tomail, $subject, $content, $this->site_name)) {
|
||||
return dr_return_data(1, 'ok');
|
||||
}
|
||||
}
|
||||
|
||||
return dr_return_data(0, '邮件发送失败:'.$dmail->error);
|
||||
}
|
||||
|
||||
// 缓存
|
||||
public function cache($site = SITE_ID) {
|
||||
|
||||
$data = $this->table('mail_smtp')->order_by('displayorder asc')->getAll();
|
||||
$cache = [];
|
||||
if ($data) {
|
||||
foreach ($data as $t) {
|
||||
$cache[$t['id']] = $t;
|
||||
}
|
||||
}
|
||||
|
||||
\Phpcmf\Service::L('cache')->set_file('email', $cache);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,985 @@
|
||||
<?php namespace Phpcmf\Model;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
// 字段操作表
|
||||
class Field extends \Phpcmf\Model {
|
||||
|
||||
public $data;
|
||||
public $func;
|
||||
public $relatedid;
|
||||
public $relatedname;
|
||||
|
||||
public $_table_field = [];
|
||||
|
||||
/**
|
||||
* 字段排序
|
||||
**/
|
||||
public function list_sort($field) {
|
||||
|
||||
if (!$field) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 当displayorder有值时,按displayorder小到大排序,否则按id小到大排序
|
||||
$dp = 0;
|
||||
foreach ($field as $i => $t) {
|
||||
$dp+= $t['displayorder'];
|
||||
}
|
||||
// 优化后的写法
|
||||
|
||||
|
||||
if (!$dp) {
|
||||
return $field;
|
||||
}
|
||||
|
||||
return dr_array_sort($field, 'displayorder', 'asc');;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过字段来查询表名称
|
||||
**/
|
||||
public function get_table_name($siteid, $field) {
|
||||
|
||||
$table = '';
|
||||
list($case_name, $a) = explode('-', $field['relatedname']);
|
||||
|
||||
if (function_exists('myfield_tablename_'.$case_name)) {
|
||||
$table = call_user_func_array('myfield_tablename_'.$case_name, [
|
||||
$field,
|
||||
$siteid,
|
||||
$this->relatedname,
|
||||
$this->relatedid
|
||||
]);
|
||||
} else {
|
||||
switch ($case_name) {
|
||||
|
||||
case 'form':
|
||||
// _网站表单 form-站点id, 表单id
|
||||
list($a, $siteid) = explode('-', $this->relatedname);
|
||||
$data = $this->table($siteid.'_form')->get($this->relatedid);
|
||||
if (!$data) {
|
||||
return;
|
||||
}
|
||||
$table = $field['ismain'] ? $siteid.'_form_'.$data['table'] : $siteid.'_form_'.$data['table'].'_data_{tableid}';
|
||||
break;
|
||||
|
||||
case 'tag':
|
||||
// _网站tag
|
||||
$table = $field['relatedid'].'_tag';
|
||||
break;
|
||||
|
||||
case 'linkage':
|
||||
// 联动菜单
|
||||
$table = 'linkage_data_'.$field['relatedid'];
|
||||
break;
|
||||
|
||||
case 'member':
|
||||
// _用户主表
|
||||
$table = 'member_data';
|
||||
break;
|
||||
|
||||
case 'navigator':
|
||||
// _导航链接
|
||||
$table = $field['relatedid'].'_navigator';
|
||||
break;
|
||||
|
||||
case 'order':
|
||||
// 订单插件
|
||||
$table = $field['relatedid'].'_order';
|
||||
break;
|
||||
|
||||
case 'page':
|
||||
// 网站单页
|
||||
$table = $field['relatedid'].'_order';
|
||||
break;
|
||||
|
||||
case 'table':
|
||||
// 任意表
|
||||
return $a;
|
||||
break;
|
||||
|
||||
case 'module':
|
||||
// 模块字段
|
||||
$data = \Phpcmf\Service::M()->table('module')->get($field['relatedid']);
|
||||
if ($data) {
|
||||
$table = $field['ismain'] ? '{siteid}_'.$data['dirname'] : '{siteid}_'.$data['dirname'].'_data_{tableid}';
|
||||
}
|
||||
break;
|
||||
|
||||
case 'mform':
|
||||
// 模块表单
|
||||
$data = \Phpcmf\Service::M()->table('module_form')->get($field['relatedid']);
|
||||
if (!$data) {
|
||||
$table = $field['ismain'] ? '{siteid}_'.$a.'_form_'.$data['table'] : '{siteid}_'.$a.'_form_'.$data['table'].'_data_{tableid}';
|
||||
}
|
||||
break;
|
||||
|
||||
case 'category':
|
||||
// 栏目自定义字段
|
||||
$table = $siteid.'_'.$a.'_category';
|
||||
break;
|
||||
|
||||
default:
|
||||
if (strpos($field['relatedname'], 'comment-module') !== false) {
|
||||
// 模块评论字段
|
||||
list($a, $b, $module) = explode('-', $field['relatedname']);
|
||||
$cache = \Phpcmf\Service::L('cache')->get('module-' . SITE_ID . '-' . $module);
|
||||
if (!$cache) {
|
||||
$table = $siteid . '_' . $cache['dirname'] . '_comment';
|
||||
}
|
||||
} elseif (strpos($field['relatedname'], 'comment-mform') !== false) {
|
||||
// 模块表单评论字段
|
||||
list($a, $b, $module, $fid) = explode('-', $field['relatedname']);
|
||||
$cache = \Phpcmf\Service::L('cache')->get('module-'.SITE_ID.'-'.$module);
|
||||
if (!$cache) {
|
||||
$table = $siteid.'_'.$cache['dirname'].'_form_'.$fid.'_comment';
|
||||
}
|
||||
} elseif (strpos($field['relatedname'], 'comment-form') !== false) {
|
||||
// 网站评论字段
|
||||
list($a, $b, $fid) = explode('-', $field['relatedname']);
|
||||
$cache = \Phpcmf\Service::L('cache')->get('form-'.$field['relatedid'], $fid);
|
||||
if (!$cache) {
|
||||
$table = $siteid.'_form_'.$cache['table'].'_comment';
|
||||
}
|
||||
} else {
|
||||
// 识别栏目模型字段
|
||||
list($module, $s) = explode('-', $field['relatedname']);
|
||||
$cache = \Phpcmf\Service::L('cache')->get('module-'.$s.'-'.$module);
|
||||
if ($cache) {
|
||||
$data = dr_cat_value($module, $field['relatedid']);
|
||||
if ($data) {
|
||||
if ($module == 'share') {
|
||||
if ($data['tid'] != 1) {
|
||||
} else {
|
||||
$table = dr_module_table_prefix($data['mid']).'_category_data';
|
||||
}
|
||||
} else {
|
||||
$table = dr_module_table_prefix($module).'_category_data';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return str_replace('{siteid}', $siteid, $table);
|
||||
}
|
||||
|
||||
/**
|
||||
* 全部字段
|
||||
**/
|
||||
public function get_all_field() {
|
||||
|
||||
if (!$this->relatedname) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$data = $this->db->table('field')
|
||||
->where('relatedid', $this->relatedid)
|
||||
->where('relatedname', $this->relatedname)
|
||||
->orderBy('disabled ASC,displayorder ASC,id ASC')
|
||||
->get()
|
||||
->getResultArray();
|
||||
if (!$data) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$rt = [];
|
||||
foreach ($data as $i => $t) {
|
||||
$t['spacer'] = '';
|
||||
$t['setting'] = dr_string2array($t['setting']);
|
||||
$rt[$t['id']] = $t;
|
||||
}
|
||||
|
||||
list($case_name, $a) = explode('-', $this->relatedname);
|
||||
if ($case_name == 'module') {
|
||||
// 模块字段时,加载栏目模型字段
|
||||
$module = \Phpcmf\Service::M()->table('module')->get($this->relatedid);
|
||||
if ($module) {
|
||||
$like = ['catmodule-'.$module['dirname']];
|
||||
if ($module['share']) {
|
||||
$like[] = 'catmodule-share';
|
||||
}
|
||||
$field = \Phpcmf\Service::M()->db->table('field')
|
||||
->where('ismain', 1)
|
||||
->where('disabled', 0)
|
||||
->whereIn('relatedname', $like)
|
||||
->orderBy('displayorder ASC, id ASC')->get()->getResultArray();
|
||||
if ($field) {
|
||||
foreach ($field as $t) {
|
||||
$t['spacer'] = '';
|
||||
$t['setting'] = dr_string2array($t['setting']);
|
||||
$rt[$t['id']] = $t;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $rt;
|
||||
}
|
||||
|
||||
/**
|
||||
* 储存任意表的自定义字段
|
||||
**/
|
||||
public function save_mytable_field($table, $fields, $siteid = 0) {
|
||||
|
||||
if (!$table || !$fields) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($fields as $field) {
|
||||
|
||||
if ($this->db->table('field')
|
||||
->where('fieldname', $field['fieldname'])
|
||||
->where('relatedid', $siteid)
|
||||
->where('relatedname', 'table-'.$table)->countAllResults()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->db->table('field')->insert(array(
|
||||
'name' => (string)($field['name'] ? $field['name'] : $field['textname']),
|
||||
'ismain' => (int)$field['ismain'],
|
||||
'setting' => dr_array2string($field['setting']),
|
||||
'issystem' => isset($field['issystem']) ? (int)$field['issystem'] : 1,
|
||||
'ismember' => isset($field['ismember']) ? (int)$field['ismember'] : 1,
|
||||
'disabled' => isset($field['disabled']) ? (int)$field['disabled'] : 0,
|
||||
'fieldname' => $field['fieldname'],
|
||||
'fieldtype' => $field['fieldtype'],
|
||||
'relatedid' => $siteid,
|
||||
'relatedname' => 'table-'.$table,
|
||||
'displayorder' => (int)$field['displayorder'],
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取任意表的自定义字段
|
||||
**/
|
||||
public function get_mytable_field($table, $siteid = 0) {
|
||||
|
||||
$name = 'my-table-'.$table;
|
||||
$value = \Phpcmf\Service::L('cache')->get_data($name);
|
||||
if (IS_ADMIN || !$value) {
|
||||
$field = $this->db->table('field')
|
||||
->where('disabled', 0)
|
||||
->where('relatedid', $siteid)
|
||||
->where('relatedname', 'table-'.$table)
|
||||
->orderBy('displayorder ASC,id ASC')
|
||||
->get()
|
||||
->getResultArray();
|
||||
if ($field) {
|
||||
foreach ($field as $t) {
|
||||
$t['setting'] = dr_string2array($t['setting']);
|
||||
$value[$t['fieldname']] = $t;
|
||||
}
|
||||
}
|
||||
\Phpcmf\Service::L('cache')->set_data($name, $value);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取网站信息的自定义字段
|
||||
**/
|
||||
public function get_mysite_field($siteid = SITE_ID) {
|
||||
|
||||
$name = 'my-site-'.$siteid;
|
||||
$value = \Phpcmf\Service::L('cache')->get_data($name);
|
||||
if (IS_ADMIN || !$value) {
|
||||
$field = $this->db->table('field')
|
||||
->where('disabled', 0)
|
||||
->where('relatedid', $siteid)
|
||||
->where('relatedname', 'site')
|
||||
->orderBy('displayorder ASC,id ASC')
|
||||
->get()
|
||||
->getResultArray();
|
||||
if ($field) {
|
||||
foreach ($field as $t) {
|
||||
$t['setting'] = dr_string2array($t['setting']);
|
||||
$value[$t['fieldname']] = $t;
|
||||
}
|
||||
}
|
||||
\Phpcmf\Service::L('cache')->set_data($name, $value);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除字段
|
||||
**/
|
||||
public function delete_field($ids) {
|
||||
|
||||
foreach ($ids as $id) {
|
||||
$id = intval($id);
|
||||
$data = $this->table('field')->get($id);
|
||||
if (!$data) {
|
||||
return dr_return_data(0, dr_lang('字段不存在(id:%s)', $id));
|
||||
} elseif ($data['issystem']) {
|
||||
return dr_return_data(0, dr_lang('系统字段不允许删除(id:%s)', $id));
|
||||
}
|
||||
$rt = $this->table('field')->delete($id);
|
||||
if (!$rt['code']) {
|
||||
return dr_return_data(0, $rt['msg']);
|
||||
}
|
||||
// 删除表中数据
|
||||
$field = \Phpcmf\Service::L('field')->get($data['fieldtype']);
|
||||
if ($field) {
|
||||
// 非系统字段才支持删除
|
||||
$sql = $field->drop_sql($data['fieldname']);
|
||||
// 需要分别更新各站点
|
||||
$sql && $this->update_table($sql, $data['ismain']);
|
||||
}
|
||||
}
|
||||
|
||||
return dr_return_data(1, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加字段
|
||||
*
|
||||
* @param array $data
|
||||
* @param object $field
|
||||
* @return void
|
||||
*/
|
||||
public function add($data, $field, $is_create = 1) {
|
||||
|
||||
// 验证字段上限
|
||||
/*
|
||||
if ($this->_check_table_name) {
|
||||
$max = 500;
|
||||
foreach ($this->_check_table_name as $t) {
|
||||
if (dr_count($this->db->getFieldNames($t)) > $max) {
|
||||
return dr_return_data(0, dr_lang('数据表[%s]字段个数已经达到上限(%s)', dr_count($this->db->getFieldNames($t)), $max));
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
if ($is_create) {
|
||||
// 先读取sql语句
|
||||
$sql = $field->create_sql($data['fieldname'], $data['setting']['option'], dr_safe_filename($data['name']));
|
||||
} else {
|
||||
$sql = '';
|
||||
}
|
||||
|
||||
// 当为编辑器类型时,关闭xss过滤
|
||||
//$data['fieldtype'] == 'Ueditor' && $data['setting']['validate']['xss'] = 1;
|
||||
|
||||
$data['ismain'] = (int)$data['ismain'];
|
||||
$data['setting'] = dr_array2string($data['setting']);
|
||||
$data['issystem'] = 0;
|
||||
$data['isedit'] = 0;
|
||||
$data['issearch'] = (int)$data['issearch'];
|
||||
$data['ismember'] = (int)$data['ismember'];
|
||||
$data['disabled'] = (int)$data['disabled'];
|
||||
$data['relatedid'] = (int)$this->relatedid;
|
||||
$data['relatedname'] = (string)$this->relatedname;
|
||||
$data['displayorder'] = (int)$data['displayorder'];
|
||||
|
||||
// 入库字段表
|
||||
$rt = $this->table('field')->insert($data);
|
||||
|
||||
// 执行数据库语句
|
||||
if ($rt['code'] && $sql) {
|
||||
$this->_table_field = [];
|
||||
$this->update_table($sql, $data['ismain']);
|
||||
// 验证字段是否上传成功
|
||||
$this->db->resetDataCache();// 清除缓存,影响字段存在的重复
|
||||
if ($this->_table_field && $yz = $field->test_sql($this->_table_field, $data['fieldname'])) {
|
||||
// 删除本字段
|
||||
$this->table('field')->delete($rt['code']);
|
||||
return dr_return_data(0, dr_lang('字段创建失败: %s', $yz));
|
||||
}
|
||||
}
|
||||
|
||||
return $rt;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改字段
|
||||
*
|
||||
* @param array $_data 旧数据
|
||||
* @param array $data 新数据
|
||||
* @param string $sql 执行该操作的sql语句
|
||||
* @return string
|
||||
*/
|
||||
public function edit($_data, $data, $sql) {
|
||||
|
||||
if (!$_data || !$data) {
|
||||
return dr_return_data(0, dr_lang('参数不完整'));
|
||||
}
|
||||
|
||||
// 如果字段类型、长度变化时,分别更新各站点
|
||||
($data['setting']['option']['fieldtype'] != $_data['setting']['option']['fieldtype']
|
||||
|| $data['setting']['option']['fieldlength'] != $_data['setting']['option']['fieldlength'])
|
||||
&& $this->update_table($sql, $_data['ismain']);
|
||||
|
||||
// 判断关联字段权限
|
||||
if (in_array($data['fieldtype'], ['Merge', 'Group'])) {
|
||||
$setting = dr_string2array($data['setting']);
|
||||
if ($setting['show_admin']) {
|
||||
if (preg_match_all('/\{(.+)\}/U', $setting['option']['value'], $value)) {
|
||||
foreach ($value[1] as $v) {
|
||||
$gl = $this->table('field')
|
||||
->where('fieldname', $v)
|
||||
->where('relatedid', $this->relatedid)
|
||||
->where('relatedname', $this->relatedname)
|
||||
->getRow();
|
||||
if (!$gl) {
|
||||
return dr_return_data(0, dr_lang('关联字段【%s】未定义', $v));
|
||||
}
|
||||
$gl_setting = dr_string2array($gl['setting']);
|
||||
if (!$gl_setting['show_admin']) {
|
||||
$gl_setting['show_admin'] = $setting['show_admin'];
|
||||
$this->table('field')->update($gl['id'], [
|
||||
'setting' => dr_array2string($gl_setting),
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 自定义属性不变
|
||||
if (isset($_data['setting']['diy'])) {
|
||||
$data['setting']['diy'] = $_data['setting']['diy'];
|
||||
}
|
||||
|
||||
$data['setting'] = dr_array2string($data['setting']);
|
||||
$data['issearch'] = (int)$data['issearch'];
|
||||
$data['ismember'] = (int)$data['ismember'];
|
||||
$data['disabled'] = (int)$data['disabled'];
|
||||
|
||||
// 更新字段表
|
||||
return $this->table('field')->update($_data['id'], $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断表字段否存在
|
||||
*/
|
||||
public function _field_exitsts($id, $name, $table, $siteid = 0) {
|
||||
|
||||
if (!$table) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $this->db->fieldExists($name, $table);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否是系统保留字段
|
||||
*/
|
||||
public function is_sys_field($name) {
|
||||
|
||||
if (!$name) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return in_array($name, [
|
||||
'id',
|
||||
'cat', 'category',
|
||||
'top', 'content_page',
|
||||
'pageid', 'params', 'page', 'pages',
|
||||
'parent', 'urlrule', 'member', 'module',
|
||||
'tags', 'tag', 'prev_page', 'app',
|
||||
'next_page', 'fstatus', 'old', 'mid', 'groupid', 'related', 'kws', 'more'
|
||||
]);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* 分别更新各站点的表结构
|
||||
*
|
||||
* @param string $sql 执行该操作的sql语句
|
||||
* @param intval $ismain 是否主表
|
||||
* @return void
|
||||
*/
|
||||
public function update_table($sql, $ismain) {
|
||||
|
||||
if (!$sql || !$this->func) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (method_exists($this, '_sql_'.$this->func)) {
|
||||
return call_user_func_array(array($this, '_sql_'.$this->func), array($sql, $ismain));
|
||||
} elseif (function_exists('myfield_sql_'.$this->func)) {
|
||||
$rt = call_user_func_array('myfield_sql_'.$this->func, array($sql, $ismain, $this->data));
|
||||
if ($rt) {
|
||||
$this->_table_field = dr_array2array($this->_table_field, $rt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断同表字段否存在
|
||||
*
|
||||
* @param string $name 字段名称
|
||||
* @param intval $int 字段id
|
||||
* @return int
|
||||
*/
|
||||
public function exitsts($name) {
|
||||
|
||||
if (!$name) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (method_exists($this, '_field_'.$this->func)) {
|
||||
return call_user_func_array(array($this, '_field_'.$this->func), array($name));
|
||||
} elseif (function_exists('myfield_field_'.$this->func)) {
|
||||
return call_user_func_array('myfield_field_'.$this->func, array($name, $this->data));
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
// 栏目模型字段
|
||||
protected function _sql_category_data($sql, $ismain) {
|
||||
$table = $this->dbprefix(dr_module_table_prefix($this->data['dirname']).'_category_data'); // 主表名称
|
||||
if (!$this->db->tableExists($table)) {
|
||||
return;
|
||||
}
|
||||
// 更新主表 格式: 站点id_名称
|
||||
$this->db->simpleQuery(str_replace('{tablename}', $table, $sql));
|
||||
$this->_table_field[] = $table;
|
||||
}
|
||||
// 字段是否存在
|
||||
protected function _field_category_data($name) {
|
||||
// 模块主表
|
||||
$table = $this->dbprefix(dr_module_table_prefix($this->data['dirname']));
|
||||
$rt = $this->_field_exitsts('id', $name, $table, SITE_ID);
|
||||
if ($rt) {
|
||||
return 1;
|
||||
}
|
||||
// 模块附表
|
||||
$rt = $this->_field_exitsts('id', $name, $table.'_data_0', SITE_ID);
|
||||
if ($rt) {
|
||||
return 1;
|
||||
}
|
||||
// 栏目表
|
||||
$rt = $this->_field_exitsts('id', $name, $table.'_category', SITE_ID);
|
||||
if ($rt) {
|
||||
return 1;
|
||||
}
|
||||
// 栏目模型主表
|
||||
$table = $this->dbprefix(dr_module_table_prefix($this->data['dirname']).'_category_data');
|
||||
$rt = $this->_field_exitsts('id', $name, $table, SITE_ID);
|
||||
if ($rt) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
// 评论自定义字段
|
||||
protected function _sql_comment($sql, $ismain) {
|
||||
// 更新站点模块
|
||||
foreach (\Phpcmf\Service::C()->site_info as $sid => $v) {
|
||||
$table = $this->dbprefix($sid.'_'.$this->data.'_comment');
|
||||
if (!$this->db->tableExists($table)) {
|
||||
return;
|
||||
}
|
||||
$this->db->simpleQuery(str_replace('{tablename}', $table, $sql));
|
||||
$this->_table_field[] = $table;
|
||||
}
|
||||
}
|
||||
// 字段是否存在
|
||||
protected function _field_comment($name) {
|
||||
// 主表
|
||||
$table = $this->dbprefix(dr_module_table_prefix($this->data).'_comment');
|
||||
$rt = $this->_field_exitsts('id', $name, $table, SITE_ID);
|
||||
if ($rt) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
// 栏目字段
|
||||
protected function _sql_category($sql, $ismain) {
|
||||
// 更新站点模块
|
||||
foreach (\Phpcmf\Service::C()->site_info as $sid => $v) {
|
||||
$table = $this->dbprefix($sid.'_'.$this->data.'_category');
|
||||
if (!$this->db->tableExists($table)) {
|
||||
return;
|
||||
}
|
||||
$this->db->simpleQuery(str_replace('{tablename}', $table, $sql));
|
||||
$this->_table_field[] = $table;
|
||||
}
|
||||
}
|
||||
// 字段是否存在
|
||||
protected function _field_category($name) {
|
||||
// 主表
|
||||
$table = $this->dbprefix(dr_module_table_prefix($this->data).'_category');
|
||||
$rt = $this->_field_exitsts('id', $name, $table, SITE_ID);
|
||||
if ($rt) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
// 会员字段
|
||||
protected function _sql_member($sql, $ismain) {
|
||||
$this->db->simpleQuery(str_replace('{tablename}', $this->dbprefix('member_data'), $sql));
|
||||
$this->_table_field[] = $this->dbprefix('member_data');
|
||||
}
|
||||
// 字段是否存在
|
||||
protected function _field_member($name) {
|
||||
// 保留
|
||||
if (in_array($name, ['role', 'uid', 'authid', 'adminid', 'tableid', 'group', 'groupid', 'levelid'])) {
|
||||
return 1;
|
||||
}
|
||||
// 主表
|
||||
$table = $this->dbprefix('member_data');
|
||||
$rt = $this->_field_exitsts('id', $name, $table, SITE_ID);
|
||||
if ($rt) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
// 网站表单字段
|
||||
protected function _sql_form($sql, $ismain) {
|
||||
$table = $this->dbprefix(SITE_ID.'_form_'.$this->data['table']); // 主表名称
|
||||
if (!$this->db->tableExists($table)) {
|
||||
return;
|
||||
}
|
||||
if ($ismain) {
|
||||
// 更新主表 格式: 站点id_名称
|
||||
$this->db->simpleQuery(str_replace('{tablename}', $table, $sql));
|
||||
$this->_table_field[] = $table;
|
||||
} else {
|
||||
for ($i = 0; $i < 200; $i ++) {
|
||||
if (!$this->db->tableExists($table.'_data_'.$i)) {
|
||||
break;
|
||||
}
|
||||
$this->db->simpleQuery(str_replace('{tablename}', $table.'_data_'.$i, $sql)); //执行更新语句
|
||||
$this->_table_field[] = $table.'_data_'.$i;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 字段是否存在
|
||||
protected function _field_form($name) {
|
||||
// 主表
|
||||
$table = $this->dbprefix(SITE_ID.'_form_'.$this->data['table']);
|
||||
$rt = $this->_field_exitsts('id', $name, $table, SITE_ID);
|
||||
if ($rt) {
|
||||
return 1;
|
||||
}
|
||||
// 附表
|
||||
$table.'_data_0';
|
||||
$rt = $this->_field_exitsts('id', $name, $table.'_data_0', SITE_ID);
|
||||
if ($rt) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
// 联动字段
|
||||
protected function _sql_linkage($sql, $ismain) {
|
||||
$table = $this->dbprefix('linkage_data_'.$this->relatedid);
|
||||
if (!$this->db->tableExists($table)) {
|
||||
return;
|
||||
}
|
||||
$this->db->simpleQuery(str_replace('{tablename}', $table, $sql));
|
||||
$this->_table_field[] = $table;
|
||||
}
|
||||
// 字段是否存在
|
||||
protected function _field_linkage($name) {
|
||||
// 主表
|
||||
$table = $this->dbprefix('linkage_data_'.$this->relatedid);
|
||||
$rt = $this->_field_exitsts('id', $name, $table, $this->relatedid);
|
||||
if ($rt) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
// Tag字段
|
||||
protected function _sql_tag($sql, $ismain) {
|
||||
$table = $this->dbprefix($this->relatedid.'_tag');
|
||||
if (!$this->db->tableExists($table)) {
|
||||
return;
|
||||
}
|
||||
$this->db->simpleQuery(str_replace('{tablename}', $table, $sql));
|
||||
$this->_table_field[] = $table;
|
||||
}
|
||||
// 字段是否存在
|
||||
protected function _field_tag($name) {
|
||||
// 主表
|
||||
$table = $this->dbprefix($this->relatedid.'_tag');
|
||||
$rt = $this->_field_exitsts('id', $name, $table, $this->relatedid);
|
||||
if ($rt) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------//--------------------------------------------------------------------
|
||||
|
||||
// navigator字段
|
||||
protected function _sql_navigator($sql, $ismain) {
|
||||
$table = $this->dbprefix($this->relatedid.'_navigator');
|
||||
if (!$this->db->tableExists($table)) {
|
||||
return;
|
||||
}
|
||||
$this->db->simpleQuery(str_replace('{tablename}', $table, $sql));
|
||||
$this->_table_field[] = $table;
|
||||
}
|
||||
// 字段是否存在
|
||||
protected function _field_navigator($name) {
|
||||
// 主表
|
||||
$table = $this->dbprefix($this->relatedid.'_navigator');
|
||||
$rt = $this->_field_exitsts('id', $name, $table, $this->relatedid);
|
||||
if ($rt) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
// 订单插件字段
|
||||
protected function _sql_order($sql, $ismain) {
|
||||
$table = $this->dbprefix($this->relatedid.'_order');
|
||||
if (!$this->db->tableExists($table)) {
|
||||
return;
|
||||
}
|
||||
$this->db->simpleQuery(str_replace('{tablename}', $table, $sql));
|
||||
$this->_table_field[] = $table;
|
||||
}
|
||||
// 字段是否存在
|
||||
protected function _field_order($name) {
|
||||
// 主表
|
||||
$table = $this->dbprefix($this->relatedid.'_order');
|
||||
$rt = $this->_field_exitsts('id', $name, $table, $this->relatedid);
|
||||
if ($rt) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
// 单页字段
|
||||
protected function _sql_page($sql, $ismain) {
|
||||
$table = $this->dbprefix($this->relatedid.'_page');
|
||||
if (!$this->db->tableExists($table)) {
|
||||
return;
|
||||
}
|
||||
$this->db->simpleQuery(str_replace('{tablename}', $table, $sql));
|
||||
$this->_table_field[] = $table;
|
||||
}
|
||||
// 字段是否存在
|
||||
protected function _field_page($name) {
|
||||
// 主表
|
||||
$table = $this->dbprefix($this->relatedid.'_page');
|
||||
$rt = $this->_field_exitsts('id', $name, $table, $this->relatedid);
|
||||
if ($rt) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
// 模块字段
|
||||
protected function _sql_module($sql, $ismain) {
|
||||
// 更新站点模块
|
||||
foreach (\Phpcmf\Service::C()->site_info as $sid => $v) {
|
||||
$table = $this->dbprefix($sid.'_'.$this->data['dirname']); // 主表名称
|
||||
if (!$this->db->tableExists($table)) {
|
||||
continue;
|
||||
}
|
||||
if ($ismain) {
|
||||
// 更新主表 格式: 站点id_名称
|
||||
$this->db->simpleQuery(str_replace('{tablename}', $table, $sql));
|
||||
$this->_table_field[] = $table;
|
||||
} else {
|
||||
// 更新副表 格式: 名称_站点id_data_副表id
|
||||
for ($i = 0; $i < 200; $i ++) {
|
||||
if (!$this->db->tableExists($table.'_data_'.$i)) {
|
||||
break;
|
||||
}
|
||||
$this->db->simpleQuery(str_replace('{tablename}', $table.'_data_'.$i, $sql)); //执行更新语句
|
||||
$this->_table_field[] = $table.'_data_'.$i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 字段是否存在
|
||||
protected function _field_module($name) {
|
||||
// 保留字段
|
||||
if (in_array($name, [
|
||||
'cat', 'category', 'name',
|
||||
'top', 'content_page',
|
||||
'pageid', 'params', 'page', 'pages',
|
||||
'parent', 'urlrule', 'member',
|
||||
'tags', 'tag', 'prev_page',
|
||||
'next_page', 'fstatus', 'old', 'mid', 'groupid', 'related', 'kws', 'more'
|
||||
])) {
|
||||
return 1;
|
||||
}
|
||||
// 主表
|
||||
$table = $this->dbprefix(dr_module_table_prefix($this->data['dirname']));
|
||||
$rt = $this->_field_exitsts('id', $name, $table, SITE_ID);
|
||||
if ($rt) {
|
||||
return 1;
|
||||
}
|
||||
// 附表
|
||||
$rt = $this->_field_exitsts('id', $name, $table.'_data_0', SITE_ID);
|
||||
if ($rt) {
|
||||
return 1;
|
||||
}
|
||||
// 栏目表
|
||||
$rt = $this->_field_exitsts('id', $name, $table.'_category', SITE_ID);
|
||||
if ($rt) {
|
||||
return 1;
|
||||
}
|
||||
// 栏目模型表
|
||||
$rt = $this->_field_exitsts('id', $name, $table.'_category_data', SITE_ID);
|
||||
if ($rt) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
// 模块表单字段
|
||||
protected function _sql_mform($sql, $ismain) {
|
||||
|
||||
// 更新站点模块
|
||||
foreach (\Phpcmf\Service::C()->site_info as $sid => $v) {
|
||||
$table = $this->dbprefix($sid.'_'.$this->data['module'].'_form_'.$this->data['table']); // 主表名称
|
||||
if (!$this->db->tableExists($table)) {
|
||||
continue;
|
||||
}
|
||||
if ($ismain) {
|
||||
// 更新主表 格式: 站点id_名称
|
||||
$this->db->simpleQuery(str_replace('{tablename}', $table, $sql));
|
||||
$this->_table_field[] = $table;
|
||||
} else {
|
||||
// 更新副表 格式: 名称_站点id_data_副表id
|
||||
for ($i = 0; $i < 200; $i ++) {
|
||||
if (!$this->db->tableExists($table.'_data_'.$i)) {
|
||||
break;
|
||||
}
|
||||
$this->db->simpleQuery(str_replace('{tablename}', $table.'_data_'.$i, $sql)); //执行更新语句
|
||||
$this->_table_field[] = $table.'_data_'.$i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// 字段是否存在
|
||||
protected function _field_mform($name) {
|
||||
// 主表
|
||||
$table = $this->dbprefix(dr_module_table_prefix($this->data['module']).'_form_'.$this->data['table']);
|
||||
$rt = $this->_field_exitsts('id', $name, $table, $this->data['module'] == 'space' ? 0 : SITE_ID);
|
||||
if ($rt) {
|
||||
return 1;
|
||||
}
|
||||
// 附表
|
||||
$rt = $this->_field_exitsts('id', $name, $table.'_data_0', $this->data['module'] == 'space' ? 0 : SITE_ID);
|
||||
if ($rt) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
// 任意表
|
||||
protected function _sql_table($sql, $ismain) {
|
||||
$table = $this->dbprefix($this->data);
|
||||
if (!$this->db->tableExists($table)) {
|
||||
return;
|
||||
}
|
||||
$this->db->simpleQuery(str_replace('{tablename}', $table, $sql));
|
||||
$this->_table_field[] = $table;
|
||||
}
|
||||
// 字段是否存在
|
||||
protected function _field_table($name) {
|
||||
// 主表
|
||||
$table = $this->dbprefix($this->data);
|
||||
if (!$this->db->tableExists($table)) {
|
||||
return;
|
||||
}
|
||||
$rt = $this->_field_exitsts('id', $name, $table, $this->relatedid);
|
||||
if ($rt) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
// 网站信息表
|
||||
protected function _sql_site($sql, $ismain) {
|
||||
return '';
|
||||
}
|
||||
// 网站信息表
|
||||
protected function _field_site($name) {
|
||||
// 保留字段
|
||||
if (in_array($name, ['logo'])) {
|
||||
return 1;
|
||||
}
|
||||
if ($this->table('field')
|
||||
->where('fieldname', $name)
|
||||
->where('relatedid', $this->relatedid)
|
||||
->where('relatedname', $this->relatedname)->counts()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php namespace Phpcmf\Model;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
// 用户组模型类
|
||||
|
||||
class Group extends \Phpcmf\Model {
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,475 @@
|
||||
<?php namespace Phpcmf\Model;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
// 模型类
|
||||
|
||||
class Linkage extends \Phpcmf\Model {
|
||||
|
||||
protected $top;
|
||||
protected $pids;
|
||||
protected $cache;
|
||||
protected $categorys;
|
||||
protected $child_pids;
|
||||
|
||||
// 创建菜单
|
||||
public function create($data) {
|
||||
|
||||
if ($this->table('linkage')->is_exists(0, 'code', $data['code'])) {
|
||||
return dr_return_data(0, dr_lang('别名已经存在'));
|
||||
}
|
||||
|
||||
$rt = $this->table('linkage')->insert([
|
||||
'name' => $data['name'],
|
||||
'code' => strtolower($data['code']),
|
||||
'type' => (int)$data['type'],
|
||||
]);
|
||||
if (!$rt['code']) {
|
||||
return $rt;
|
||||
}
|
||||
|
||||
// 返回id
|
||||
$id = intval($rt['code']);
|
||||
|
||||
// 创建数据表
|
||||
$table = $this->dbprefix('linkage_data_'.$id);
|
||||
\Phpcmf\Service::M('table')->drop_table($table);
|
||||
$rt = \Phpcmf\Service::M('table')->create_table(
|
||||
$table,
|
||||
[
|
||||
'id' => 'mediumint(8) unsigned NOT NULL AUTO_INCREMENT',
|
||||
'site' => 'smallint(5) unsigned NOT NULL',
|
||||
'pid' => "mediumint(8) unsigned NOT NULL DEFAULT '0' COMMENT '上级id'",
|
||||
'pids' => "varchar(255) DEFAULT NULL COMMENT '所有上级id'",
|
||||
'name' => "varchar(255) NOT NULL COMMENT '菜单名称'",
|
||||
'cname' => "varchar(255) NOT NULL COMMENT '菜单别名'",
|
||||
'child' => "tinyint(1) unsigned DEFAULT '0' COMMENT '是否有下级'",
|
||||
'hidden' => "tinyint(1) unsigned DEFAULT '0' COMMENT '前端隐藏'",
|
||||
'childids' => "text DEFAULT NULL COMMENT '下级所有id'",
|
||||
'displayorder' => "int(10) DEFAULT '0'",
|
||||
],
|
||||
[
|
||||
'PRIMARY KEY (`id`)',
|
||||
'KEY `cname` (`cname`)',
|
||||
'KEY `hidden` (`hidden`)',
|
||||
'KEY `list` (`site`,`displayorder`)',
|
||||
],
|
||||
'联动菜单'.dr_safe_replace($data['name']).'数据表'
|
||||
);
|
||||
if (!$rt['code']) {
|
||||
// 创建失败删除数据
|
||||
$this->table('linkage')->delete($id);
|
||||
return $rt;
|
||||
}
|
||||
|
||||
return dr_return_data($id);
|
||||
}
|
||||
|
||||
// 批量删除
|
||||
public function delete_all($ids, $where = '') {
|
||||
|
||||
foreach ($ids as $id) {
|
||||
$row = $this->table('linkage')->get(intval($id));
|
||||
if (!$row) {
|
||||
return dr_return_data(0, dr_lang('数据不存在(id:%s)', $id));
|
||||
}
|
||||
$rt = $this->table('linkage')->delete($id);
|
||||
if (!$rt['code']) {
|
||||
return dr_return_data(0, $rt['msg']);
|
||||
}
|
||||
// 删除表数据
|
||||
$table = $this->dbprefix('linkage_data_'.$id);
|
||||
\Phpcmf\Service::M('table')->drop_table($table);
|
||||
}
|
||||
|
||||
return dr_return_data(1, '');
|
||||
}
|
||||
|
||||
// 批量删除
|
||||
public function delete_list_all($key, $ids) {
|
||||
|
||||
foreach ($ids as $id) {
|
||||
$row = $this->table('linkage_data_'.$key)->get(intval($id));
|
||||
if (!$row) {
|
||||
return dr_return_data(0, dr_lang('数据不存在(id:%s)', $id));
|
||||
}
|
||||
if ($row['child']) {
|
||||
$rt = $this->table('linkage_data_'.$key)->deleteAll(explode(',', $row['childids']));
|
||||
}
|
||||
$rt = $this->table('linkage_data_'.$key)->delete($id);
|
||||
if (!$rt['code']) {
|
||||
return dr_return_data(0, $rt['msg']);
|
||||
}
|
||||
}
|
||||
|
||||
return dr_return_data(1, '');
|
||||
}
|
||||
|
||||
// 批量移动分类
|
||||
public function edit_pid_all($key, $pid, $ids) {
|
||||
|
||||
foreach ($ids as $id) {
|
||||
$row = $this->table('linkage_data_'.$key)->get(intval($id));
|
||||
if (!$row) {
|
||||
return dr_return_data(0, dr_lang('数据不存在(id:%s)', $id));
|
||||
}
|
||||
|
||||
$rt = $this->table('linkage_data_'.$key)->update($id, ['pid' => $pid]);
|
||||
if (!$rt['code']) {
|
||||
return dr_return_data(0, $rt['msg']);
|
||||
}
|
||||
}
|
||||
|
||||
$this->repair([
|
||||
'id' => $key,
|
||||
'type' => 0
|
||||
]);
|
||||
|
||||
return dr_return_data(1, '');
|
||||
}
|
||||
|
||||
// 添加子内容
|
||||
public function add_list($key, $data) {
|
||||
|
||||
$pid = intval($data['pid']);
|
||||
|
||||
if ($data['all']) {
|
||||
// 批量
|
||||
$c = 0;
|
||||
$py = \Phpcmf\Service::L('pinyin'); // 拼音转换类
|
||||
$names = explode(PHP_EOL, trim($data['all']));
|
||||
foreach ($names as $t) {
|
||||
$t = trim($t);
|
||||
if (!$t) {
|
||||
continue;
|
||||
}
|
||||
$cname = $py->result($t);
|
||||
if (is_numeric($cname)) {
|
||||
$cname = 'a'.$cname;
|
||||
} elseif (!preg_match('/^[a-z]+[a-z0-9\_]+$/i', $cname)) {
|
||||
$cname = dr_safe_filename($cname);
|
||||
}
|
||||
$cf = $this->db->table('linkage_data_'.$key)->where('cname', $cname)->countAllResults();
|
||||
$rt = $this->table('linkage_data_'.$key)->insert(array(
|
||||
'pid' => $pid,
|
||||
'pids' => '',
|
||||
'name' => $t,
|
||||
'site' => SITE_ID,
|
||||
'child' => 0,
|
||||
'cname' => $cname,
|
||||
'hidden' => 0,
|
||||
'childids' => '',
|
||||
'displayorder' => 0
|
||||
));
|
||||
if (!$rt['code']) {
|
||||
return $rt;
|
||||
}
|
||||
if ($cf) {
|
||||
// 重复验证
|
||||
$this->table('linkage_data_'.$key)->update($rt['code'], [
|
||||
'cname' => $cname.$rt['code']
|
||||
]);
|
||||
}
|
||||
$c++;
|
||||
}
|
||||
// 更新pid
|
||||
$pid && $this->table('linkage_data_'.$key)->update($pid, ['child' => 1]);
|
||||
return dr_return_data(1, dr_lang('批量添加%s个', $c));
|
||||
} else {
|
||||
// 单个
|
||||
$data['name'] = trim($data['name']);
|
||||
if (!$data['name']) {
|
||||
return dr_return_data(0, dr_lang('名称不能为空'));
|
||||
} elseif (!$data['cname']) {
|
||||
return dr_return_data(0, dr_lang('别名不能为空'));
|
||||
}
|
||||
if (is_numeric($data['cname'])) {
|
||||
$data['cname'] = 'a'.$data['cname'];
|
||||
} elseif (!preg_match('/^[a-z]+[a-z0-9\_]+$/i', $data['cname'])) {
|
||||
$data['cname'] = dr_safe_filename($data['cname']);
|
||||
}
|
||||
if ($this->db->table('linkage_data_'.$key)->where('cname', $data['cname'])->countAllResults()) {
|
||||
return dr_return_data(0, dr_lang('别名已经存在'));
|
||||
}
|
||||
$rt = $this->table('linkage_data_'.$key)->insert(array(
|
||||
'pid' => $pid,
|
||||
'pids' => '',
|
||||
'name' => $data['name'],
|
||||
'site' => SITE_ID,
|
||||
'child' => 0,
|
||||
'cname' => $data['cname'],
|
||||
'hidden' => 0,
|
||||
'childids' => '',
|
||||
'displayorder' => 0
|
||||
));
|
||||
if (!$rt['code']) {
|
||||
return $rt;
|
||||
}
|
||||
// 更新pid
|
||||
$pid && $this->table('linkage_data_'.$key)->update($pid, ['child' => 1]);
|
||||
return dr_return_data(1, dr_lang('操作成功'));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 全部子菜单数据
|
||||
*
|
||||
* @param array $link
|
||||
* @param intval $pid
|
||||
* @return array
|
||||
*/
|
||||
public function getList($link, $pid = 'NULL') {
|
||||
|
||||
$key = (int)$link['id'];
|
||||
|
||||
if ($pid === 'NULL') {
|
||||
$name = 'linkage-cahce-list-'.$key.'-'.$pid;
|
||||
$data = \Phpcmf\Service::L('cache')->get_data($name);
|
||||
if ($data) {
|
||||
return $data;
|
||||
}
|
||||
$db = $this->db->table('linkage_data_'.$key);
|
||||
// 站点查询
|
||||
//$link['type'] == 1 && $db->where('site', SITE_ID);
|
||||
// 获取菜单数据
|
||||
$menu = $db->orderBy('displayorder ASC,id ASC')->get()->getResultArray();
|
||||
if (!$menu) {
|
||||
return [];
|
||||
}
|
||||
// 格式返回数据
|
||||
$data = [];
|
||||
foreach ($menu as $t) {
|
||||
$data[$t['id']] = $t;
|
||||
}
|
||||
\Phpcmf\Service::L('cache')->set_data($name, $data);
|
||||
} else {
|
||||
$db = $this->db->table('linkage_data_'.$key);
|
||||
// 站点查询
|
||||
$link['type'] == 1 && $db->where('site', SITE_ID);
|
||||
$menu = $db->where('pid', (int)$pid)->orderBy('displayorder ASC,id ASC')->get()->getResultArray();
|
||||
if (!$menu) {
|
||||
return [];
|
||||
}
|
||||
// 格式返回数据
|
||||
$data = [];
|
||||
foreach ($menu as $t) {
|
||||
$data[$t['id']] = $t;
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取父栏目ID列表
|
||||
*
|
||||
* @param integer $catid 栏目ID
|
||||
* @param array $pids 父目录ID
|
||||
* @param integer $n 查找的层次
|
||||
* @return string
|
||||
*/
|
||||
protected function get_pids($catid, $pids = '', $n = 1) {
|
||||
|
||||
if ($n > 100 || !$this->categorys || !isset($this->categorys[$catid])) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$pid = $this->categorys[$catid]['pid'];
|
||||
$pids = $pids ? $pid.','.$pids : $pid;
|
||||
$pid && $pids = $this->get_pids($pid, $pids, ++$n);
|
||||
|
||||
return $pids;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取子栏目ID列表
|
||||
*
|
||||
* @param $catid
|
||||
* @return string
|
||||
*/
|
||||
protected function get_childids($catid, $n = 1) {
|
||||
|
||||
$childids = $catid;
|
||||
|
||||
if ($n > 100 || !is_array($this->categorys)
|
||||
|| !isset($this->categorys[$catid])) {
|
||||
return $childids;
|
||||
}
|
||||
|
||||
if ($this->pids[$catid]) {
|
||||
foreach ($this->pids[$catid] as $id) {
|
||||
$cat = $this->categorys[$id];
|
||||
// 避免造成死循环
|
||||
$cat['pid']
|
||||
&& $id != $catid
|
||||
&& $cat['pid'] == $catid
|
||||
&& $this->categorys[$catid]['pid'] != $id
|
||||
&& $childids.= ','.$this->get_childids($id, ++$n);
|
||||
}
|
||||
}
|
||||
|
||||
return $childids;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修复菜单数据
|
||||
*/
|
||||
public function repair($link, $siteid = SITE_ID) {
|
||||
|
||||
if (!$link) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->categorys = $categorys = [];
|
||||
|
||||
// 站点独立 // 共享共享
|
||||
$table = 'linkage_data_'.$link['id'];
|
||||
$_data = $link['type']
|
||||
? $this->db->table($table)->where('site', $siteid)->orderBy('displayorder ASC,id ASC')->get()->getResultArray()
|
||||
: $this->db->table($table)->orderBy('displayorder ASC,id ASC')->get()->getResultArray();
|
||||
if (!$_data) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 全部栏目数据
|
||||
foreach ($_data as $t) {
|
||||
$this->pids[$t['pid']][] = $t['id']; // 归类
|
||||
$categorys[$t['id']] = $this->categorys[$t['id']] = $t;
|
||||
}
|
||||
|
||||
$this->child_pids = [0];
|
||||
foreach ($this->categorys as $catid => $cat) {
|
||||
$this->categorys[$catid]['pids'] = $this->get_pids($catid);
|
||||
$this->categorys[$catid]['childids'] = $this->get_childids($catid);
|
||||
$this->categorys[$catid]['child'] = is_numeric($this->categorys[$catid]['childids']) ? 0 : 1;
|
||||
if ($this->categorys[$catid]['child']) {
|
||||
$this->child_pids[] = $catid;
|
||||
}
|
||||
// 当库中与实际不符合才更新数据表
|
||||
if ($categorys[$catid]['pids'] != $this->categorys[$catid]['pids']
|
||||
|| $categorys[$catid]['childids'] != $this->categorys[$catid]['childids']
|
||||
|| $categorys[$catid]['child'] != $this->categorys[$catid]['child']) {
|
||||
$this->table($table)->update($cat['id'], [
|
||||
'pids' => $this->categorys[$catid]['pids'],
|
||||
'child' => $this->categorys[$catid]['child'],
|
||||
'childids' => $this->categorys[$catid]['childids']
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->categorys;
|
||||
}
|
||||
|
||||
public function get_child_row($pid) {
|
||||
$newArr = [];
|
||||
foreach ($this->categorys as $cat) {
|
||||
if ($cat['hidden']) {
|
||||
continue;
|
||||
}
|
||||
$item = [
|
||||
'value' => $cat['id'],
|
||||
'label' => $cat['name'],
|
||||
'children' => [],
|
||||
];
|
||||
if ($pid == $cat['pid']) {
|
||||
$item['children'] = $this->get_child_row($cat['id']);
|
||||
$newArr[] = $item;
|
||||
}
|
||||
|
||||
}
|
||||
return $newArr;
|
||||
}
|
||||
|
||||
public function get_child_pids() {
|
||||
return $this->child_pids;
|
||||
}
|
||||
|
||||
// 自定义字段
|
||||
public function get_fields($id) {
|
||||
|
||||
$rt = [];
|
||||
$field = $this->db->table('field')
|
||||
->where('disabled', 0)
|
||||
->where('relatedname', 'linkage')
|
||||
->where('relatedid', intval($id))
|
||||
->orderBy('displayorder ASC,id ASC')
|
||||
->get()->getResultArray();
|
||||
if ($field) {
|
||||
foreach ($field as $fv) {
|
||||
$fv['setting'] = dr_string2array($fv['setting']);
|
||||
$rt[$fv['fieldname']] = $fv;
|
||||
}
|
||||
}
|
||||
|
||||
return $rt;
|
||||
}
|
||||
|
||||
// 缓存
|
||||
public function cache($siteid = SITE_ID) {
|
||||
|
||||
}
|
||||
|
||||
public function get_json($link, $links) {
|
||||
|
||||
$json = [];
|
||||
if ($links) {
|
||||
$this->categorys = $links;
|
||||
$json = $this->get_child_row(0);
|
||||
}
|
||||
|
||||
$data_path = 'linkage/'.SITE_ID.'_'.$link['code'].'/';
|
||||
\Phpcmf\Service::L('cache')->set_file('json', $json, $data_path);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 分组缓存菜单数据
|
||||
*/
|
||||
public function cache_list($link, $pid, $field) {
|
||||
|
||||
$path = WRITEPATH.'linkage/';
|
||||
dr_mkdirs($path);
|
||||
|
||||
$data_path = 'linkage/'.SITE_ID.'_'.$link['code'].'/';
|
||||
dr_mkdirs(WRITEPATH.$data_path);
|
||||
|
||||
// 格式返回数据
|
||||
$lv = $data = [];
|
||||
$cid = \Phpcmf\Service::L('cache')->get_file('id', $data_path, false);
|
||||
!$cid && $cid = [];
|
||||
|
||||
// 执行程序
|
||||
$key = (int)$link['id'];
|
||||
$db = $this->db->table('linkage_data_'.$key);
|
||||
$link['type'] == 1 && $db->where('site', SITE_ID); // 站点查询
|
||||
$menu = $db->where('pid', (int)$pid)->orderBy('displayorder ASC,id ASC')->get()->getResultArray();
|
||||
if ($menu) {
|
||||
foreach ($menu as $t) {
|
||||
if ($t['hidden']) {
|
||||
continue;
|
||||
}
|
||||
$lv[] = substr_count($t['pids'], ',');
|
||||
$t['ii'] = $t['iid'] = $t['id'];
|
||||
$t['id'] = $t['cname'];
|
||||
$cid[$t['ii']] = $t['id'];
|
||||
$data[$t['cname']] = \Phpcmf\Service::L('Field')->app('')->format_value($field, $t);
|
||||
\Phpcmf\Service::L('cache')->set_file('data-'.$t['cname'], $data[$t['cname']], $data_path);
|
||||
}
|
||||
}
|
||||
|
||||
\Phpcmf\Service::L('cache')->set_file('list-'.$pid, $data, $data_path);
|
||||
|
||||
\Phpcmf\Service::L('cache')->set_file('id', $cid, $data_path);
|
||||
\Phpcmf\Service::L('cache')->set_file('key', $key, $data_path);
|
||||
|
||||
$level_data = (int)\Phpcmf\Service::L('cache')->get_file('level', $data_path, false);
|
||||
\Phpcmf\Service::L('cache')->set_file('level', max($lv ? max($lv) : 0, $level_data), $data_path);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,47 @@
|
||||
<?php namespace Phpcmf\Model;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
|
||||
// 用户权限处理
|
||||
class Member_auth extends \Phpcmf\Model {
|
||||
|
||||
// 获取用户权限值
|
||||
public function member_auth($name, $member = []) {
|
||||
return IS_USE_MEMBER ? \Phpcmf\Service::L('member_auth', 'member')->member_auth($name, $member) : 1;
|
||||
}
|
||||
|
||||
// 获取应用插件权限值
|
||||
public function app_auth($dir, $name, $member = []) {
|
||||
return IS_USE_MEMBER ? \Phpcmf\Service::L('member_auth', 'member')->app_auth($dir, $name, $member) : 0;
|
||||
}
|
||||
|
||||
// 获取站点权限值
|
||||
public function home_auth($name, $member = []) {
|
||||
return IS_USE_MEMBER ? \Phpcmf\Service::L('member_auth', 'member')->home_auth($name, $member) : 0;
|
||||
}
|
||||
|
||||
// 获取模块权限值
|
||||
public function module_auth($mid, $name, $member = []) {
|
||||
return IS_USE_MEMBER ? \Phpcmf\Service::L('member_auth', 'member')->module_auth($mid, $name, $member) : 0;
|
||||
}
|
||||
|
||||
// 获取模块的栏目权限值
|
||||
public function category_auth($module, $catid, $name, $member = []) {
|
||||
return IS_USE_MEMBER ? \Phpcmf\Service::L('member_auth', 'member')->category_auth($module, $catid, $name, $member) : 1;
|
||||
}
|
||||
|
||||
// 获取模块表单权限值
|
||||
public function mform_auth($mid, $fid, $name, $member = []) {
|
||||
return IS_USE_MEMBER ? \Phpcmf\Service::L('member_auth', 'member')->mform_auth($mid, $fid, $name, $member) : 1;
|
||||
}
|
||||
|
||||
// 获取网站表单权限值
|
||||
public function form_auth($fid, $name, $member = []) {
|
||||
return IS_USE_MEMBER ? \Phpcmf\Service::L('member_auth', 'member')->form_auth($fid, $name, $member) : 1;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,899 @@
|
||||
<?php namespace Phpcmf\Model;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
// 菜单控制模型
|
||||
|
||||
class Menu extends \Phpcmf\Model {
|
||||
|
||||
protected $ids;
|
||||
|
||||
// 新增后台菜单
|
||||
public function _add($table, $pid, $data, $mark = '', $is_return = false) {
|
||||
|
||||
if (!$data['name']) {
|
||||
return $is_return ? 0 : dr_return_data(0, dr_lang('名称不能为空'));
|
||||
}
|
||||
|
||||
!$mark && ($mark = $data['mark'] ? $data['mark'] : '');
|
||||
$data['name'] = dr_lang($data['name']);
|
||||
|
||||
if ($table == 'admin') {
|
||||
// 重复判断
|
||||
if ($data['uri'] && $this->table('admin_menu')->where('uri', $data['uri'])->counts()) {
|
||||
// 链接菜单判断重复
|
||||
return $is_return ? 0 : dr_return_data(0, dr_lang('系统路径已经存在'), ['field' => 'uri']);
|
||||
} elseif ($mark && $r = $this->table('admin_menu')->where('mark', $mark)->getRow()) {
|
||||
return $is_return ? $r['id'] : dr_return_data(0, dr_lang('标识字符已经存在'), ['field' => 'uri']);
|
||||
}
|
||||
$this->db->table('admin_menu')->replace([
|
||||
'pid' => $pid,
|
||||
'name' => $data['name'],
|
||||
'uri' => $data['uri'] ? $data['uri'] : '',
|
||||
'url' => $data['url'] ? $data['url'] : '',
|
||||
'mark' => $mark ? $mark : (string)$data['mark'],
|
||||
'site' => $data['site'] ? (string)$data['site'] : '',
|
||||
'icon' => $data['icon'] ? $data['icon'] : '',
|
||||
'hidden' => (int)$data['hidden'],
|
||||
'displayorder' => (int)$data['displayorder'],
|
||||
]);
|
||||
} elseif ($table == 'admin_min') {
|
||||
// 重复判断
|
||||
if ($data['uri'] && $this->table('admin_min_menu')->where('uri', $data['uri'])->counts()) {
|
||||
// 链接菜单判断重复
|
||||
return $is_return ? 0 : dr_return_data(0, dr_lang('系统路径已经存在'), ['field' => 'uri']);
|
||||
} elseif ($data['uri'] && !$this->table('admin_menu')->where('uri', $data['uri'])->counts()) {
|
||||
// 判断完整菜单表
|
||||
return $is_return ? 0 : dr_return_data(0, dr_lang('系统路径没有存在于完整菜单中'), ['field' => 'uri']);
|
||||
} elseif ($mark && $r = $this->table('admin_min_menu')->where('mark', $mark)->counts()) {
|
||||
return $is_return ? $r['id'] : dr_return_data(0, dr_lang('标识字符已经存在'), ['field' => 'uri']);
|
||||
}
|
||||
$this->db->table('admin_min_menu')->replace([
|
||||
'pid' => $pid,
|
||||
'name' => $data['name'],
|
||||
'uri' => $data['uri'] ? $data['uri'] : '',
|
||||
'url' => $data['url'] ? $data['url'] : '',
|
||||
'mark' => $mark ? $mark : (string)$data['mark'],
|
||||
'site' => $data['site'] ? (string)$data['site'] : '',
|
||||
'icon' => $data['icon'] ? $data['icon'] : '',
|
||||
'hidden' => (int)$data['hidden'],
|
||||
'displayorder' => (int)$data['displayorder'],
|
||||
]);
|
||||
} elseif ($this->is_table_exists('member_menu')) {
|
||||
// 重复 判断
|
||||
if ($data['uri'] && $this->table('member_menu')->where('uri', $data['uri'])->counts()) {
|
||||
// 链接菜单判断重复
|
||||
return $is_return ? 0 : dr_return_data(0, dr_lang('系统路径已经存在'), ['field' => 'uri']);
|
||||
} elseif ($mark && $r = $this->table('member_menu')->where('mark', $mark)->counts()) {
|
||||
return $is_return ? $r['id'] : dr_return_data(0, dr_lang('标识字符已经存在'), ['field' => 'uri']);
|
||||
}
|
||||
$group = [];
|
||||
if ($data['group']) {
|
||||
foreach ($data['group'] as $i) {
|
||||
$group[$i] = $i;
|
||||
}
|
||||
}
|
||||
$this->db->table('member_menu')->replace([
|
||||
'pid' => $pid,
|
||||
'name' => $data['name'],
|
||||
'uri' => $data['uri'] ? $data['uri'] : '',
|
||||
'url' => $data['url'] ? $data['url'] : '',
|
||||
'mark' => $mark,
|
||||
'icon' => $data['icon'] ? $data['icon'] : '',
|
||||
'group' => dr_array2string($group),
|
||||
'site' => $data['site'] ? (string)$data['site'] : '',
|
||||
'client' => $data['client'] ? (string)$data['client'] : '',
|
||||
'hidden' => (int)$data['hidden'],
|
||||
'displayorder' => (int)$data['displayorder'],
|
||||
]);
|
||||
}
|
||||
|
||||
return $is_return ? $this->db->insertID() : dr_return_data($this->db->insertID(), 'ok');
|
||||
}
|
||||
|
||||
// 修改菜单
|
||||
public function _edit($table, $id, $data) {
|
||||
|
||||
if ($table == 'admin') {
|
||||
$this->db->table('admin_menu')->where('id', (int)$id)->update($data);
|
||||
} elseif ($table == 'admin_min') {
|
||||
$this->db->table('admin_min_menu')->where('id', (int)$id)->update($data);
|
||||
} elseif ($this->is_table_exists('member_menu')) {
|
||||
$this->db->table('member_menu')->where('id', (int)$id)->update($data);
|
||||
}
|
||||
|
||||
return $id;
|
||||
}
|
||||
|
||||
// 后台菜单合并
|
||||
protected function _admin_add_menu($menu, $new) {
|
||||
|
||||
foreach ($new as $mk1 => $top) {
|
||||
// 合并顶级菜单
|
||||
if ($mk1 && isset($menu[$mk1])) {
|
||||
// 它存在分组菜单时才合并
|
||||
if (!isset($menu[$mk1]['name']) && $top['name']) {
|
||||
$menu[$mk1]['name'] = $top['name'];
|
||||
}
|
||||
if (!isset($menu[$mk1]['icon']) && $top['icon']) {
|
||||
$menu[$mk1]['icon'] = $top['icon'];
|
||||
}
|
||||
if ($top['left']) {
|
||||
foreach ($top['left'] as $mk2 => $left) {
|
||||
if ($mk2 && isset($menu[$mk1]['left'][$mk2])) {
|
||||
if (!isset($menu[$mk1]['left'][$mk2]['name']) && $left['name']) {
|
||||
$menu[$mk1]['left'][$mk2]['name'] = $left['name'];
|
||||
}
|
||||
if (!isset($menu[$mk1]['left'][$mk2]['icon']) && $left['icon']) {
|
||||
$menu[$mk1]['left'][$mk2]['icon'] = $left['icon'];
|
||||
}
|
||||
foreach ($left['link'] as $link) {
|
||||
$menu[$mk1]['left'][$mk2]['link'][] = $link;
|
||||
}
|
||||
} elseif ($mk2) {
|
||||
$menu[$mk1]['left'][$mk2] = $left;
|
||||
} else {
|
||||
$menu[$mk1]['left'][] = $left;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$menu[$mk1] = $top;
|
||||
}
|
||||
}
|
||||
|
||||
return $menu;
|
||||
}
|
||||
|
||||
// 用户菜单合并
|
||||
protected function _member_add_menu($menu, $new) {
|
||||
|
||||
foreach ($new as $mk1 => $top) {
|
||||
// 合并顶级菜单
|
||||
if ($mk1 && isset($menu[$mk1])) {
|
||||
if (!isset($menu[$mk1]['name']) && $top['name']) {
|
||||
$menu[$mk1]['name'] = $top['name'];
|
||||
}
|
||||
if (!isset($menu[$mk1]['icon']) && $top['icon']) {
|
||||
$menu[$mk1]['icon'] = $top['icon'];
|
||||
}
|
||||
// 它存在下级菜单时才合并
|
||||
if ($top['link']) {
|
||||
foreach ($top['link'] as $left) {
|
||||
$menu[$mk1]['link'][] = $left;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$menu[$mk1] = $top;
|
||||
}
|
||||
}
|
||||
|
||||
return $menu;
|
||||
}
|
||||
|
||||
// 更具mark获取id
|
||||
protected function _get_id_for_mark($table, $mark) {
|
||||
|
||||
if (!$mark) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$data = $this->db->table($table.'_menu')->where('mark', $mark)->get()->getRowArray();
|
||||
|
||||
return (int)$data['id'];
|
||||
}
|
||||
|
||||
// 安装app时的操作
|
||||
public function add_app($dir) {
|
||||
|
||||
$path = dr_get_app_dir($dir);
|
||||
if (!is_file($path.'Config/Menu.php')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$menu = require $path.'Config/Menu.php';
|
||||
if (!$menu) {
|
||||
return;
|
||||
}
|
||||
|
||||
$afirst = '';
|
||||
if ($menu['admin']) {
|
||||
// 后台菜单
|
||||
foreach ($menu['admin'] as $mark => $top) {
|
||||
// 插入顶级菜单
|
||||
$mark = strlen($mark) > 2 ? $mark : '';
|
||||
$top_id = $top['name'] ? $this->_add('admin', 0, $top, $mark, true) : 0;
|
||||
!$top_id && $top_id = $this->_get_id_for_mark('admin', $mark);
|
||||
// 插入分组菜单
|
||||
if ($top_id && $top['left'] && is_array($top['left'])) {
|
||||
foreach ($top['left'] as $mark2 => $left) {
|
||||
$mark2 = strlen($mark2) > 2 ? $mark2 : '';
|
||||
$left_id = $left['name'] ? $this->_add('admin', $top_id, $left, $mark2, true) : 0;
|
||||
!$left_id && $left_id = $this->_get_id_for_mark('admin', $mark2);
|
||||
// 插入链接菜单
|
||||
if ($left_id && $left['link'] && is_array($left['link'])) {
|
||||
foreach ($left['link'] as $key => $link) {
|
||||
if (!$afirst && $link['uri']) {
|
||||
$afirst = $link['uri']; // 第一个菜单
|
||||
}
|
||||
if ($this->counts('admin_menu', 'pid='.$left_id.' and `uri`=\''.$link['uri'].'\'')) {
|
||||
continue;
|
||||
}
|
||||
$id = $this->_add('admin', $left_id, $link, $link['mark'], 1);
|
||||
if (!$link['mark']) {
|
||||
$this->_edit('admin', $id, [
|
||||
'mark' => 'app-'.$dir.'-'.$id,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($menu['member'] && $this->is_table_exists('member_menu')) {
|
||||
// 用户菜单
|
||||
foreach ($menu['member'] as $mark => $top) {
|
||||
// 插入顶级菜单
|
||||
$mark = strlen($mark) > 2 ? $mark : '';
|
||||
$top_id = $top['name'] ? $this->_add('member', 0, $top, $mark, true) : 0;
|
||||
!$top_id && $top_id = $this->_get_id_for_mark('member', $mark);
|
||||
// 插入链接菜单
|
||||
if ($top_id && $top['link'] && is_array($top['link'])) {
|
||||
foreach ($top['link'] as $mark2 => $link) {
|
||||
if ($this->counts('member_menu', 'pid='.$top_id.' and `uri`=\''.$link['uri'].'\'')) {
|
||||
continue;
|
||||
}
|
||||
$id = $this->_add('member', $top_id, $link, $link['mark'], 1);
|
||||
if (!$link['mark']) {
|
||||
$this->_edit('member', $id, [
|
||||
'mark' => 'app-'.$dir.'-'.$id,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if ($menu['admin_min']) {
|
||||
foreach ($menu['admin_min'] as $mark => $top) {
|
||||
$mark = strlen($mark) > 2 ? $mark : '';
|
||||
$top_id = $top['name'] ? $this->_add('admin_min', 0, $top, $mark, true) : 0;
|
||||
!$top_id && $top_id = $this->_get_id_for_mark('admin_min', $mark);
|
||||
// 插入链接菜单
|
||||
if ($top_id && $top['link'] && is_array($top['link'])) {
|
||||
foreach ($top['link'] as $mark2 => $link) {
|
||||
if ($this->counts('admin_min_menu', 'pid='.$top_id.' and `uri`=\''.$link['uri'].'\'')) {
|
||||
continue;
|
||||
}
|
||||
$id = $this->_add('admin_min', $top_id, $link, $link['mark'], 1);
|
||||
if (!$link['mark']) {
|
||||
$this->_edit('admin_min_menu', $id, [
|
||||
'mark' => 'app-'.$dir.'-'.$id,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $afirst;
|
||||
}
|
||||
|
||||
// 更新app时的操作
|
||||
public function update_app($dir) {
|
||||
|
||||
$path = dr_get_app_dir($dir);
|
||||
if (!is_file($path.'Config/Menu.php')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$menu = require $path.'Config/Menu.php';
|
||||
if (!$menu) {
|
||||
return;
|
||||
}
|
||||
|
||||
$afirst = '';
|
||||
if ($menu['admin']) {
|
||||
// 后台菜单
|
||||
foreach ($menu['admin'] as $mark => $top) {
|
||||
// 插入顶级菜单
|
||||
$mark = strlen($mark) > 2 ? $mark : '';
|
||||
if (!$mark) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$is_top = $this->table('admin_menu')->where('mark', $mark)->getRow();
|
||||
$top_id = $is_top ? $is_top['id'] : $this->_add('admin', 0, $top, $mark, true);
|
||||
|
||||
|
||||
// 插入分组菜单
|
||||
if ($top_id && $top['left'] && is_array($top['left'])) {
|
||||
foreach ($top['left'] as $mark2 => $left) {
|
||||
$mark2 = strlen($mark2) > 2 ? $mark2 : '';
|
||||
if (!$mark2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$is_left = $this->table('admin_menu')->where('mark', $mark2)->getRow();
|
||||
$left_id = $is_left ? $is_left['id'] : $this->_add('admin', $top_id, $left, $mark2, true);
|
||||
|
||||
// 插入链接菜单
|
||||
if ($left_id && $left['link'] && is_array($left['link'])) {
|
||||
foreach ($left['link'] as $key => $link) {
|
||||
if (!$afirst && $link['uri']) {
|
||||
$afirst = $link['uri']; // 第一个菜单
|
||||
}
|
||||
if ($this->counts('admin_menu', 'pid='.$left_id.' and `uri`=\''.$link['uri'].'\'')) {
|
||||
continue;
|
||||
}
|
||||
$id = $this->_add('admin', $left_id, $link, $link['mark'], 1);
|
||||
if (!$link['mark']) {
|
||||
$this->_edit('admin', $id, [
|
||||
'mark' => 'app-'.$dir.'-'.$id,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($menu['member'] && $this->is_table_exists('member_menu')) {
|
||||
// 用户菜单
|
||||
foreach ($menu['member'] as $mark => $top) {
|
||||
// 插入顶级菜单
|
||||
$mark = strlen($mark) > 2 ? $mark : '';
|
||||
if (!$mark) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$is_top = $this->table('member_menu')->where('mark', $mark)->getRow();
|
||||
$top_id = $is_top ? $is_top['id'] : $this->_add('member', 0, $top, $mark, true);
|
||||
|
||||
// 插入链接菜单
|
||||
if ($top_id && $top['link'] && is_array($top['link'])) {
|
||||
foreach ($top['link'] as $mark2 => $link) {
|
||||
if ($this->counts('member_menu', 'pid='.$top_id.' and `uri`=\''.$link['uri'].'\'')) {
|
||||
continue;
|
||||
}
|
||||
$id = $this->_add('member', $top_id, $link, $link['mark'], 1);
|
||||
if (!$link['mark']) {
|
||||
$this->_edit('member_menu', $id, [
|
||||
'mark' => 'app-'.$dir.'-'.$id,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($menu['admin_min']) {
|
||||
// 简化菜单
|
||||
foreach ($menu['admin_min'] as $mark => $top) {
|
||||
// 插入顶级菜单
|
||||
$mark = strlen($mark) > 2 ? $mark : '';
|
||||
if (!$mark) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$is_top = $this->table('admin_min_menu')->where('mark', $mark)->getRow();
|
||||
$top_id = $is_top ? $is_top['id'] : $this->_add('admin_min', 0, $top, $mark, true);
|
||||
|
||||
// 插入链接菜单
|
||||
if ($top_id && $top['link'] && is_array($top['link'])) {
|
||||
foreach ($top['link'] as $mark2 => $link) {
|
||||
if ($this->counts('admin_min_menu', 'pid='.$top_id.' and `uri`=\''.$link['uri'].'\'')) {
|
||||
continue;
|
||||
}
|
||||
$id = $this->_add('admin_min', $top_id, $link, $link['mark'], 1);
|
||||
if (!$link['mark']) {
|
||||
$this->_edit('admin_min_menu', $id, [
|
||||
'mark' => 'app-'.$dir.'-'.$id,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 卸载app时的操作
|
||||
public function delete_app($dir) {
|
||||
|
||||
$path = dr_get_app_dir($dir);
|
||||
if (!is_file($path.'Config/Menu.php')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$menu = require $path.'Config/Menu.php';
|
||||
if (!$menu) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($menu['admin']) {
|
||||
// 后台菜单
|
||||
foreach ($menu['admin'] as $mark => $top) {
|
||||
// 插入顶级菜单
|
||||
$mark = strlen($mark) > 2 ? $mark : '';
|
||||
$top_id = $this->_get_id_for_mark('admin', $mark);
|
||||
// 插入分组菜单
|
||||
if ($top_id && $top['left']) {
|
||||
foreach ($top['left'] as $mark2 => $left) {
|
||||
$mark2 = strlen($mark2) > 2 ? $mark2 : '';
|
||||
$left_id = $this->_get_id_for_mark('admin', $mark2);
|
||||
// 插入链接菜单
|
||||
if ($left_id) {
|
||||
foreach ($left['link'] as $link) {
|
||||
$this->db->table('admin_menu')->where('pid='.$left_id.' and `uri`=\''.$link['uri'].'\'')->delete();
|
||||
}
|
||||
// 判断当前分组菜单是否为空
|
||||
if (!$this->db->table('admin_menu')->where('pid='.$left_id)->countAllResults()) {
|
||||
$this->db->table('admin_menu')->where('id='.$left_id)->delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 判断当前顶级菜单是否为空
|
||||
if ($top_id && !$this->db->table('admin_menu')->where('pid='.$top_id)->countAllResults()) {
|
||||
$this->db->table('admin_menu')->where('id='.$top_id)->delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($menu['member'] && $this->is_table_exists('member_menu')) {
|
||||
// 用户菜单
|
||||
foreach ($menu['member'] as $mark => $top) {
|
||||
// 插入顶级菜单
|
||||
$mark = strlen($mark) > 2 ? $mark : '';
|
||||
$top_id = $this->_get_id_for_mark('member', $mark);
|
||||
// 插入链接菜单
|
||||
if ($top_id && $top['link']) {
|
||||
foreach ($top['link'] as $link) {
|
||||
$this->db->table('member_menu')->where('pid='.$top_id.' and `uri`=\''.$link['uri'].'\'')->delete();
|
||||
}
|
||||
//
|
||||
}
|
||||
// 判断当前顶级菜单是否为空
|
||||
if ($top_id && !$this->db->table('member_menu')->where('pid='.$top_id)->countAllResults()) {
|
||||
$this->db->table('member_menu')->where('id='.$top_id)->delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($menu['admin_min']) {
|
||||
// 简化菜单
|
||||
foreach ($menu['admin_min'] as $mark => $top) {
|
||||
// 插入顶级菜单
|
||||
$mark = strlen($mark) > 2 ? $mark : '';
|
||||
$top_id = $this->_get_id_for_mark('admin_min', $mark);
|
||||
// 插入链接菜单
|
||||
if ($top_id && $top['link']) {
|
||||
foreach ($top['link'] as $link) {
|
||||
$this->db->table('admin_min_menu')->where('pid='.$top_id.' and `uri`=\''.$link['uri'].'\'')->delete();
|
||||
}
|
||||
//
|
||||
}
|
||||
// 判断当前顶级菜单是否为空
|
||||
if ($top_id && !$this->db->table('admin_min_menu')->where('pid='.$top_id)->countAllResults()) {
|
||||
$this->db->table('admin_min_menu')->where('id='.$top_id)->delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$this->db->table('admin_menu')->where('mark', 'app-'.$dir)->delete();
|
||||
$this->db->table('admin_min_menu')->where('mark', 'app-'.$dir)->delete();
|
||||
|
||||
$this->db->table('admin_menu')->like('mark', 'app-'.$dir.'%')->delete();
|
||||
$this->db->table('admin_min_menu')->like('mark', 'app-'.$dir.'%')->delete();
|
||||
|
||||
if ($this->is_table_exists('member_menu')) {
|
||||
$this->db->table('member_menu')->where('mark', 'app-'.$dir)->delete();
|
||||
$this->db->table('member_menu')->like('mark', 'app-'.$dir.'%')->delete();
|
||||
}
|
||||
}
|
||||
|
||||
// 查询老库值
|
||||
private function _get_old_value($rp, $t) {
|
||||
$key = ((string)$t['name'].(string)$t['mark'].(string)$t['uri'].(string)$t['url']);
|
||||
if (isset($rp[$key]) && $rp[$key]) {
|
||||
return $rp[$key];
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
// 初始化菜单
|
||||
public function init($table = '') {
|
||||
|
||||
// 程序自定义菜单
|
||||
if (is_file(MYPATH.'Config/Menu.php')) {
|
||||
$menu = require MYPATH.'Config/Menu.php';
|
||||
}
|
||||
|
||||
if (!$menu) {
|
||||
$menu = require CMSPATH.'Config/Menu.php';
|
||||
}
|
||||
|
||||
// 子程序菜单
|
||||
$local = \Phpcmf\Service::Apps();
|
||||
foreach ($local as $dir => $path) {
|
||||
if (is_file($path.'Config/Menu.php')) {
|
||||
if (is_file($path.'Config/App.php')) {
|
||||
$cfg = require $path.'Config/App.php';
|
||||
if ($cfg['type'] == 'app' && !is_file($path.'install.lock')) {
|
||||
// 表示应用插件
|
||||
continue;
|
||||
} elseif ($cfg['type'] == 'module' && IS_USE_MODULE
|
||||
&& !$this->counts('module', '`dirname`=\''.strtolower($dir).'\'')) {
|
||||
// 表示模块
|
||||
continue;
|
||||
}
|
||||
$_menu = require $path.'Config/Menu.php';
|
||||
if ($_menu) {
|
||||
$_menu['admin'] && $menu['admin'] = $this->_admin_add_menu($menu['admin'], $_menu['admin']);
|
||||
$_menu['member'] && $menu['member'] = $this->_member_add_menu($menu['member'], $_menu['member']);
|
||||
$_menu['admin_min'] && $menu['admin_min'] = $this->_member_add_menu($menu['admin_min'], $_menu['admin_min']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($table == 'admin' || !$table) {
|
||||
// 清空表
|
||||
$rp = [];
|
||||
$old = $this->table('admin_menu')->where('site<>\'\'')->getAll();
|
||||
if ($old) {
|
||||
foreach ($old as $t) {
|
||||
$key = ($t['name'].$t['mark'].$t['uri'].$t['url']);
|
||||
$rp[$key] = $t['site'];
|
||||
}
|
||||
}
|
||||
$this->db->table('admin_menu')->truncate();
|
||||
$this->db->table('admin_menu')->emptyTable();
|
||||
foreach ($menu['admin'] as $mark => $top) {
|
||||
// 插入顶级菜单
|
||||
$top['mark'] = $mark = strlen($mark) > 2 ? $mark : $top['mark'];
|
||||
$top['site'] = $this->_get_old_value($rp, $top);
|
||||
$top_id = $this->_add('admin', 0, $top, $mark, true);
|
||||
// 插入分组菜单
|
||||
if ($top_id) {
|
||||
foreach ($top['left'] as $mark2 => $left) {
|
||||
$left['mark'] = $mark2 = strlen($mark2) > 2 ? $mark2 : $left['mark'];
|
||||
$left['site'] = $this->_get_old_value($rp, $left);
|
||||
$left_id = $this->_add('admin', $top_id, $left, $mark2, true);
|
||||
// 插入链接菜单
|
||||
if ($left_id) {
|
||||
foreach ($left['link'] as $mark3 => $link) {
|
||||
$link['mark'] = $mark3 = strlen($mark3) > 2 ? $mark3 : $link['mark'];
|
||||
$link['site'] = $this->_get_old_value($rp, $link);
|
||||
$this->_add('admin', $left_id, $link, $mark3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} elseif ($table == 'admin_min') {
|
||||
// 清空表
|
||||
$this->db->table('admin_min_menu')->truncate();
|
||||
$this->db->table('admin_min_menu')->emptyTable();
|
||||
foreach ($menu['admin_min'] as $mark => $top) {
|
||||
$mark = strlen($mark) > 2 ? $mark : '';
|
||||
$top_id = $this->_add('admin_min', 0, $top, $mark, true);
|
||||
// 插入链接菜单
|
||||
if ($top_id) {
|
||||
foreach ($top['link'] as $mark2 => $link) {
|
||||
if (is_numeric($mark2)) {
|
||||
$mark2 = $top_id.'-'.$mark2;
|
||||
}
|
||||
$this->_add('admin_min', $top_id, $link, $mark2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} elseif ($this->is_table_exists('member_menu') && $table == 'member') {
|
||||
// 清空表
|
||||
$site = $group = $client = [];
|
||||
$old = $this->table('member_menu')->where('`site`<>\'\' or `group`<>\'\' or `client`<>\'\'')->getAll();
|
||||
if ($old) {
|
||||
foreach ($old as $t) {
|
||||
$key = ($t['name'].$t['mark'].$t['uri'].$t['url']);
|
||||
$site[$key] = ($t['site']);
|
||||
$group[$key] = dr_string2array($t['group']);
|
||||
$client[$key] = ($t['client']);
|
||||
}
|
||||
}
|
||||
$this->db->table('member_menu')->truncate();
|
||||
$this->db->table('member_menu')->emptyTable();
|
||||
foreach ($menu['member'] as $mark => $top) {
|
||||
// 插入顶级菜单
|
||||
$top['mark'] = $mark = strlen($mark) > 2 ? $mark : $top['mark'];
|
||||
$top['site'] = $this->_get_old_value($site, $top);
|
||||
$top['group'] = $this->_get_old_value($group, $top);
|
||||
$top['client'] = $this->_get_old_value($client, $top);
|
||||
$top_id = $this->_add('member', 0, $top, $mark, true);
|
||||
// 插入链接菜单
|
||||
if ($top_id) {
|
||||
foreach ($top['link'] as $mark2 => $link) {
|
||||
if (is_numeric($mark2)) {
|
||||
$mark2 = $top_id.'-'.$mark2;
|
||||
}
|
||||
$link['site'] = $this->_get_old_value($site, $link);
|
||||
$link['group'] = $this->_get_old_value($group, $link);
|
||||
$link['client'] = $this->_get_old_value($client, $link);
|
||||
$this->_add('member', $top_id, $link, $mark2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#\Phpcmf\Service::M('Form')->cache(); // 更新表单菜单
|
||||
|
||||
}
|
||||
|
||||
// 获取单个
|
||||
public function getRowData($table, $id) {
|
||||
|
||||
return $this->db->table($table.'_menu')->where('id', $id)->get()->getRowArray();
|
||||
}
|
||||
|
||||
// 获取菜单
|
||||
public function gets($table, $where = '') {
|
||||
|
||||
$menu = [];
|
||||
$db = $this->db->table($table.'_menu');
|
||||
$where && $db->where($where);
|
||||
$db->orderBy('displayorder ASC,id ASC');
|
||||
$data = $db->get()->getResultArray();
|
||||
|
||||
if ($data) {
|
||||
|
||||
$top = $left = [];
|
||||
// 第一级
|
||||
foreach ($data as $i => $t) {
|
||||
if ($t['pid'] == 0) {
|
||||
$top[] = $t['id'];
|
||||
$data[$i]['level'] = 1;
|
||||
}
|
||||
}
|
||||
// 第二级
|
||||
foreach ($data as $i => $t) {
|
||||
if (dr_in_array($t['pid'], $top)) {
|
||||
$left[$t['id']] = $t['pid'];
|
||||
$data[$i]['level'] = 2;
|
||||
}
|
||||
}
|
||||
// 第三级
|
||||
foreach ($data as $i => $t) {
|
||||
if (isset($left[$t['pid']])) {
|
||||
$data[$i]['mark'] = $t['uri'] ? $t['uri'] : $t['url'];
|
||||
$data[$i]['tid'] = $left[$t['pid']];
|
||||
$data[$i]['level'] = 3;
|
||||
}
|
||||
/*
|
||||
if (strpos($t['uri'], 'cloud/') === 0 && substr_count($t['uri'], '/') == 1) {
|
||||
unset($data[$i]);
|
||||
}*/
|
||||
}
|
||||
|
||||
$menu = \Phpcmf\Service::L('tree')->get($data);
|
||||
}
|
||||
|
||||
return $menu;
|
||||
}
|
||||
|
||||
// 获取顶级菜单
|
||||
public function get_top($table) {
|
||||
|
||||
$menu = [];
|
||||
$data = $this->db->table($table.'_menu')->where('pid', 0)->orderBy('displayorder ASC,id ASC')->get()->getResultArray();
|
||||
|
||||
if ($data) {
|
||||
foreach ($data as $t) {
|
||||
$menu[$t['id']] = $t;
|
||||
}
|
||||
}
|
||||
|
||||
return $menu;
|
||||
}
|
||||
|
||||
// 操作菜单
|
||||
public function _uesd($table, $id) {
|
||||
|
||||
return $this->table($table.'_menu')->used($id, 'hidden');
|
||||
}
|
||||
|
||||
public function _save($table, $id, $name, $value) {
|
||||
|
||||
return $this->table($table.'_menu')->save($id, $name, $value);
|
||||
}
|
||||
|
||||
public function _update($table, $id, $data) {
|
||||
|
||||
return $this->table($table.'_menu')->update($id, $data);
|
||||
}
|
||||
|
||||
public function _delete($table, $ids) {
|
||||
|
||||
if ($ids) {
|
||||
$this->ids = array();
|
||||
foreach ($ids as $id) {
|
||||
$this->_get_id($table, (int)$id);
|
||||
}
|
||||
$this->ids && $this->db->table($table.'_menu')->whereIn('id', $this->ids)->delete();
|
||||
}
|
||||
}
|
||||
|
||||
// 获取自己id和子id
|
||||
protected function _get_id($table, $id) {
|
||||
|
||||
if (!$id) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
$this->ids[$id] = $id;
|
||||
|
||||
$data = $this->db->table($table.'_menu')->where('pid', $id)->get()->getResultArray();
|
||||
if (!$data) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
foreach ($data as $t) {
|
||||
$this->ids[$t['id']] = $t['id'];
|
||||
$this->_get_id($table, (int)$t['id']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 父级菜单选择
|
||||
*
|
||||
* @param intval $level 级别
|
||||
* @param intval $id 选中项id
|
||||
* @param intval $name select部分
|
||||
* @return string
|
||||
*/
|
||||
public function parent_select($table, $level, $id = NULL, $name = NULL) {
|
||||
|
||||
$select = $name ? $name : '<select class="form-control bs-select" data-live-search="true" name="data[pid]">';
|
||||
|
||||
switch ($level) {
|
||||
case 1: // 顶级菜单
|
||||
$select.= '<option value="0">'.dr_lang('顶级菜单').'</option>';
|
||||
break;
|
||||
case 2: // 分组菜单
|
||||
$topdata = $this->db->table($table.'_menu')->select('id,name')->where('pid=0')->get()->getResultArray();
|
||||
foreach ($topdata as $t) {
|
||||
$select.= '<option value="'.$t['id'].'"'.($id == $t['id'] ? ' selected' : '').'>'.$t['name'].'</option>';
|
||||
}
|
||||
break;
|
||||
case 3: // 链接菜单
|
||||
$topdata = $this->db->table($table.'_menu')->select('id,name')->where('pid=0')->get()->getResultArray();
|
||||
foreach ($topdata as $t) {
|
||||
$select.= '<optgroup label="'.$t['name'].'">';
|
||||
$linkdata = $this->db->table($table.'_menu')->select('id,name')->where('pid='.$t['id'])->get()->getResultArray();
|
||||
foreach ($linkdata as $c) {
|
||||
$select.= '<option value="'.$c['id'].'"'.($id == $c['id'] ? ' selected' : '').'>'.$c['name'].'</option>';
|
||||
}
|
||||
$select.= '</optgroup>';
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
$select.= '</select>';
|
||||
$select.= \Phpcmf\Service::L('Field')->get('select')->get_select_search_code();
|
||||
|
||||
return $select;
|
||||
}
|
||||
|
||||
// 缓存
|
||||
public function cache($site = SITE_ID) {
|
||||
|
||||
$menu = [
|
||||
'admin' => [],
|
||||
'member' => [],
|
||||
'admin-uri' => [],
|
||||
'admin-min' => [],
|
||||
];
|
||||
|
||||
// admin 菜单
|
||||
$data = $this->db->table('admin_menu')->where('hidden', 0)->orderBy('displayorder ASC,id ASC')->get()->getResultArray();
|
||||
if ($data) {
|
||||
$list = [];
|
||||
foreach ($data as $t) {
|
||||
if ($t['pid'] == 0) {
|
||||
$t['site'] = dr_string2array($t['site']);
|
||||
$list[$t['id']] = $t;
|
||||
foreach ($data as $m) {
|
||||
if ($m['pid'] == $t['id']) {
|
||||
$m['site'] = dr_string2array($m['site']);
|
||||
$list[$t['id']]['left'][$m['id']] = $m;
|
||||
foreach ($data as $n) {
|
||||
if ($n['pid'] == $m['id']) {
|
||||
$n['tid'] = $t['id'];
|
||||
$n['uri'] = str_replace('admin/', '', $n['uri']);
|
||||
$n['site'] = dr_string2array($n['site']);
|
||||
$n['pid'] == $m['id'] && $list[$t['id']]['left'][$m['id']]['link'][$n['id']] = $n;
|
||||
$menu['admin-uri'][$n['uri']] = $n;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$menu['admin'] = $list;
|
||||
}
|
||||
// member 菜单
|
||||
if ($this->is_table_exists('member_menu')) {
|
||||
$data = $this->db->table('member_menu')->where('hidden', 0)->orderBy('displayorder ASC,id ASC')->get()->getResultArray();
|
||||
if ($data) {
|
||||
$list = [
|
||||
'url' => [],
|
||||
'uri' => [],
|
||||
];
|
||||
foreach ($data as $t) {
|
||||
if ($t['pid'] == 0) {
|
||||
$t['site'] = dr_string2array($t['site']);
|
||||
$t['group'] = dr_string2array($t['group']);
|
||||
$t['client'] = dr_string2array($t['client']);
|
||||
$list['url'][$t['id']] = $t;
|
||||
foreach ($data as $n) {
|
||||
$n['site'] = dr_string2array($n['site']);
|
||||
$n['group'] = dr_string2array($n['group']);
|
||||
$n['client'] = dr_string2array($n['client']);
|
||||
if ($n['pid'] == $t['id']) {
|
||||
$list['url'][$t['id']]['link'][$n['id']] = $n;
|
||||
$n['uri'] && $list['uri'][$n['uri']] = [
|
||||
'id' => $n['id'],
|
||||
'pid' => $t['id'],
|
||||
'icon' => $n['icon'],
|
||||
'picon' => $t['icon'],
|
||||
'name' => $n['name'],
|
||||
'pname' => $t['name'],
|
||||
];
|
||||
}
|
||||
}
|
||||
if (!$list['url'][$t['id']]['link']) {
|
||||
unset($list['url'][$t['id']]);
|
||||
}
|
||||
}
|
||||
}
|
||||
$menu['member'] = $list;
|
||||
}
|
||||
}
|
||||
|
||||
// admin-min 菜单
|
||||
$data = $this->db->table('admin_min_menu')->where('hidden', 0)->orderBy('displayorder ASC,id ASC')->get()->getResultArray();
|
||||
if ($data) {
|
||||
$list = [];
|
||||
foreach ($data as $t) {
|
||||
if ($t['pid'] == 0) {
|
||||
$list[$t['id']] = $t;
|
||||
foreach ($data as $n) {
|
||||
$n['site'] = dr_string2array($n['site']);
|
||||
if ($n['pid'] == $t['id']) {
|
||||
$list[$t['id']]['link'][$n['id']] = $n;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$menu['admin-min'] = $list;
|
||||
}
|
||||
|
||||
\Phpcmf\Service::L('cache')->set_file('menu-admin', $menu['admin']);
|
||||
\Phpcmf\Service::L('cache')->set_file('menu-admin-uri', $menu['admin-uri']);
|
||||
\Phpcmf\Service::L('cache')->set_file('menu-member', $menu['member']);
|
||||
\Phpcmf\Service::L('cache')->set_file('menu-admin-min', $menu['admin-min']);
|
||||
|
||||
return $menu;
|
||||
}
|
||||
|
||||
public function update_module($mdir, $config, $form) {
|
||||
\Phpcmf\Service::M('menu', 'cms')->update_module($mdir, $config, $form);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
<?php
|
||||
// 文件作废
|
||||
@@ -0,0 +1,250 @@
|
||||
<?php namespace Phpcmf\Model;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
class Site extends \Phpcmf\Model {
|
||||
|
||||
// 设置风格
|
||||
public function set_theme($name, $siteid) {
|
||||
|
||||
$site = $this->table('site')->get($siteid);
|
||||
if (!$site) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$site['setting'] = dr_string2array($site['setting']);
|
||||
$site['setting']['config']['SITE_THEME'] = $name;
|
||||
|
||||
$this->table('site')->update($siteid, [
|
||||
'setting' => dr_array2string($site['setting']),
|
||||
]);
|
||||
}
|
||||
|
||||
// 设置模板
|
||||
public function set_template($name, $siteid) {
|
||||
|
||||
$site = $this->table('site')->get($siteid);
|
||||
if (!$site) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$site['setting'] = dr_string2array($site['setting']);
|
||||
$site['setting']['config']['SITE_TEMPLATE'] = $name;
|
||||
|
||||
$this->table('site')->update($siteid, [
|
||||
'setting' => dr_array2string($site['setting']),
|
||||
]);
|
||||
}
|
||||
|
||||
// 获取项目配置
|
||||
public function config($siteid, $name = '', $data = []) {
|
||||
|
||||
!$siteid && $siteid = SITE_ID;
|
||||
$site = $this->table('site')->get($siteid);
|
||||
if (!$site) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$site['setting'] = dr_string2array($site['setting']);
|
||||
$site['setting']['config']['SITE_NAME'] = $site['name'];
|
||||
$site['setting']['config']['SITE_DOMAIN'] = strtolower((string)$site['domain']);
|
||||
|
||||
if ($name && $data) {
|
||||
// 更新数据
|
||||
if ($data['SITE_NAME']) {
|
||||
$site['name'] = $data['SITE_NAME'];
|
||||
}
|
||||
if ($data['SITE_DOMAIN']) {
|
||||
$site['domain'] = $data['SITE_DOMAIN'];
|
||||
}
|
||||
$site['setting'][$name] = $data;
|
||||
$this->table('site')->update($siteid, [
|
||||
'name' => $site['name'],
|
||||
'domain' => strtolower((string)$site['domain']),
|
||||
'setting' => dr_array2string($site['setting']),
|
||||
]);
|
||||
}
|
||||
|
||||
return $site['setting'];
|
||||
}
|
||||
|
||||
// 存储项目配置
|
||||
public function save_config($siteid, $name, $data) {
|
||||
|
||||
!$siteid && $siteid = SITE_ID;
|
||||
$site = $this->table('site')->get($siteid);
|
||||
if (!$site) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$site['setting'] = dr_string2array($site['setting']);
|
||||
$site['setting']['config']['SITE_NAME'] = $site['name'];
|
||||
$site['setting']['config']['SITE_DOMAIN'] = strtolower((string)$site['domain']);
|
||||
|
||||
// 更新数据
|
||||
if ($data['SITE_NAME']) {
|
||||
$site['name'] = $data['SITE_NAME'];
|
||||
}
|
||||
if ($data['SITE_DOMAIN']) {
|
||||
$site['domain'] = $data['SITE_DOMAIN'];
|
||||
}
|
||||
$site['setting'][$name] = $data;
|
||||
$this->table('site')->update($siteid, [
|
||||
'name' => $site['name'],
|
||||
'domain' => strtolower((string)$site['domain']),
|
||||
'setting' => dr_array2string($site['setting']),
|
||||
]);
|
||||
|
||||
return $site['setting'];
|
||||
}
|
||||
|
||||
// 设置项目单个配置
|
||||
public function config_value($siteid, $group, $value) {
|
||||
|
||||
!$siteid && $siteid = SITE_ID;
|
||||
$site = $this->table('site')->get($siteid);
|
||||
if (!$site || !$value) {
|
||||
return;
|
||||
}
|
||||
|
||||
$site['setting'] = dr_string2array($site['setting']);
|
||||
|
||||
foreach ($value as $n => $v) {
|
||||
$site['setting'][$group][$n] = $v;
|
||||
}
|
||||
|
||||
$this->table('site')->update($siteid, [
|
||||
'setting' => dr_array2string($site['setting']),
|
||||
]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// 新增
|
||||
public function create($data) {
|
||||
|
||||
if (IS_USE_MODULE) {
|
||||
return \Phpcmf\Service::M('site', 'module')->create($data);
|
||||
}
|
||||
|
||||
$save = [
|
||||
'name' => $data['name'],
|
||||
'domain' => (string)$data['domain'],
|
||||
'setting' => dr_array2string([
|
||||
'webpath' => $data['webpath'],
|
||||
]),
|
||||
'disabled' => 0,
|
||||
'displayorder' => 0,
|
||||
];
|
||||
if (defined('IS_INSTALL')) {
|
||||
$save['id'] = 1;
|
||||
}
|
||||
$this->db->table('site')->replace($save);
|
||||
|
||||
$siteid = $this->db->insertID();
|
||||
|
||||
if ($siteid == 1) {
|
||||
return $siteid; // 安装不执行后面操作
|
||||
}
|
||||
|
||||
return $siteid;
|
||||
}
|
||||
|
||||
// 变更主域名
|
||||
public function edit_domain($value) {
|
||||
|
||||
if (IS_USE_MODULE) {
|
||||
return \Phpcmf\Service::M('site', 'module')->edit_domain($value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 设置域名
|
||||
public function domain($value = []) {
|
||||
|
||||
if (IS_USE_MODULE) {
|
||||
return \Phpcmf\Service::M('site', 'module')->domain($value);
|
||||
}
|
||||
|
||||
return [[], []];
|
||||
}
|
||||
|
||||
// 站点缓存缓存
|
||||
public function cache($siteid = null, $data = null, $module = null) {
|
||||
|
||||
if (IS_USE_MODULE) {
|
||||
return \Phpcmf\Service::M('site', 'module')->cache($siteid, $data, $module);
|
||||
}
|
||||
|
||||
$sso_domain = $client_domain = $webpath = $app_domain = $site_domain = $config = $cache = [];
|
||||
|
||||
if (!$data) {
|
||||
$data = $this->table('site')->where('disabled', 0)->order_by('displayorder ASC,id ASC')->getAll();
|
||||
}
|
||||
|
||||
if ($data) {
|
||||
foreach ($data as $t) {
|
||||
if ($t['id'] > 1) {
|
||||
break;
|
||||
}
|
||||
$t['domain'] = DOMAIN_NAME;
|
||||
$t['setting'] = dr_string2array($t['setting']);
|
||||
|
||||
$config[$t['id']] = [
|
||||
'SITE_NAME' => $t['name'],
|
||||
'SITE_DOMAIN' => $t['domain'],
|
||||
'SITE_LOGO' => $t['setting']['config']['logo'] ? dr_get_file($t['setting']['config']['logo']) : ROOT_THEME_PATH.'assets/logo-web.png',
|
||||
'SITE_MOBILE' => '',
|
||||
'SITE_MOBILE_DIR' => '',
|
||||
'SITE_AUTO' => 0,
|
||||
'SITE_IS_MOBILE_HTML' => 0,
|
||||
'SITE_MOBILE_NOT_PAD' => 0,
|
||||
'SITE_CLOSE' => 0,
|
||||
'SITE_THEME' => 'default',
|
||||
'SITE_TEMPLATE' => 'default',
|
||||
'SITE_REWRITE' => 0,
|
||||
'SITE_SEOJOIN' => '_',
|
||||
'SITE_LANGUAGE' => $t['setting']['config']['SITE_LANGUAGE'],
|
||||
'SITE_TIMEZONE' => $t['setting']['config']['SITE_TIMEZONE'],
|
||||
'SITE_TIME_FORMAT' => $t['setting']['config']['SITE_TIME_FORMAT'],
|
||||
'SITE_INDEX_HTML' => 0,
|
||||
'SITE_THUMB_WATERMARK' => (int)$t['setting']['watermark']['thumb'],
|
||||
];
|
||||
unset($t['setting']['mobile']['auto'],
|
||||
$t['setting']['mobile']['domain'],
|
||||
$t['setting']['seo']['SITE_REWRITE'],
|
||||
$t['setting']['seo']['SITE_SEOJOIN'],
|
||||
$t['setting']['config']['SITE_THEME'],
|
||||
$t['setting']['config']['SITE_TEMPLATE'],
|
||||
$t['setting']['config']['SITE_LANGUAGE'],
|
||||
$t['setting']['config']['SITE_TIME_FORMAT'],
|
||||
$t['setting']['config']['SITE_NAME'],
|
||||
$t['setting']['config']['SITE_TIMEZONE'],
|
||||
$t['setting']['config']['SITE_DOMAIN'],
|
||||
$t['setting']['config']['SITE_CLOSE']
|
||||
);
|
||||
// 本站的全部域名归属
|
||||
$sso_domain[] = $t['domain'];
|
||||
$site_domain[$t['domain']] = $t['id'];
|
||||
// 项目路径
|
||||
$webpath[$t['id']] = [
|
||||
'site' => ROOTPATH,
|
||||
];
|
||||
$cache[$t['id']] = $t['setting'];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
\Phpcmf\Service::L('Cache')->set_file('site', $cache);
|
||||
\Phpcmf\Service::L('Config')->file(WRITEPATH.'config/site.php', '项目配置文件', 32)->to_require($config);
|
||||
\Phpcmf\Service::L('Config')->file(WRITEPATH.'config/domain_sso.php', '同步域名配置文件', 32)->to_require_one($sso_domain);
|
||||
\Phpcmf\Service::L('Config')->file(WRITEPATH.'config/domain_app.php', '项目域名配置文件', 32)->to_require_one($app_domain);
|
||||
\Phpcmf\Service::L('Config')->file(WRITEPATH.'config/domain_site.php', '项目域名配置文件', 32)->to_require_one($site_domain);
|
||||
\Phpcmf\Service::L('Config')->file(WRITEPATH.'config/domain_client.php', '客户端域名配置文件', 32)->to_require_one($client_domain);
|
||||
\Phpcmf\Service::L('Config')->file(WRITEPATH.'config/webpath.php', '入口文件目录配置文件', 32)->to_require($webpath);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
<?php namespace Phpcmf\Model;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
|
||||
// 同步删除
|
||||
class Sync extends \Phpcmf\Model {
|
||||
|
||||
protected $sync = [
|
||||
'delete_member' => [],
|
||||
'delete_content' => [],
|
||||
];
|
||||
|
||||
public function __construct(...$params) {
|
||||
parent::__construct(...$params);
|
||||
|
||||
$local = \Phpcmf\Service::Apps();
|
||||
foreach ($local as $dir => $path) {
|
||||
if (is_file($path.'Config/Sync.php')) {
|
||||
$sync = require $path.'Config/Sync.php';
|
||||
foreach ($sync as $tid => $t) {
|
||||
if ($t) {
|
||||
if (!$this->sync[$tid][$dir]) {
|
||||
$this->sync[$tid][$dir] = $t;
|
||||
} else {
|
||||
$this->sync[$tid][$dir] = dr_array2array($this->sync[$tid][$dir], $t);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除用户时的联动
|
||||
*/
|
||||
public function delete_member($id) {
|
||||
|
||||
if (!$id) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$this->sync['delete_member']) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($this->sync['delete_member'] as $dir => $list) {
|
||||
foreach ($list as $model => $method) {
|
||||
\Phpcmf\Service::M($model, $dir)->$method($id);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除模块内容时的联动
|
||||
*/
|
||||
public function delete_content($id, $siteid, $dirname) {
|
||||
|
||||
if (!$id) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$this->sync['delete_content']) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($this->sync['delete_content'] as $dir => $list) {
|
||||
foreach ($list as $model => $method) {
|
||||
\Phpcmf\Service::M($model, $dir)->$method($id, $siteid, $dirname);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
<?php namespace Phpcmf\Model;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
|
||||
// 系统模型 - 后台
|
||||
class System extends \Phpcmf\Model {
|
||||
|
||||
public $config = [
|
||||
|
||||
'SYS_DEBUG' => '调试器开关',
|
||||
'SYS_ADMIN_CODE' => '后台登录验证码开关',
|
||||
'SYS_ADMIN_LOG' => '后台操作日志开关',
|
||||
'SYS_AUTO_FORM' => '自动存储表单数据',
|
||||
'SYS_ADMIN_PAGESIZE' => '后台数据分页显示数量',
|
||||
'SYS_TABLE_ISFOOTER' => '批量操作按钮位置设定',
|
||||
'SYS_CRON_AUTH' => '自动任务权限IP地址',
|
||||
'SYS_SMS_IMG_CODE' => '发送短信验证码双重图形验证开关',
|
||||
'SYS_GO_404' => '404页面跳转开关',
|
||||
'SYS_301' => '内容地址唯一模式',
|
||||
'SYS_FONT_SIZE' => '字号设置',
|
||||
|
||||
'SYS_URL_ONLY' => '地址匹配规则',
|
||||
'SYS_URL_REL' => '地址相对模式',
|
||||
|
||||
'SYS_KEY' => '安全密匙',
|
||||
'SYS_CSRF' => '开启跨站验证',
|
||||
'SYS_CSRF_TIME' => '跨站验证有效期',
|
||||
'SYS_HTTPS' => 'https模式',
|
||||
'SYS_NOT_ADMIN_CACHE' => '禁用后台tab切换效果',
|
||||
'SYS_ADMIN_MODE' => '禁用后台登录进行模式选择',
|
||||
'SYS_ADMIN_LOGINS' => '登录失败N次后,系统将锁定登录',
|
||||
'SYS_ADMIN_LOGIN_TIME' => '登录失败锁定后在x分钟内禁止登录',
|
||||
'SYS_ADMIN_LOGIN_AES' => '登录密码加密处理',
|
||||
'SYS_ADMIN_OAUTH' => '后台启用快捷登录',
|
||||
'SYS_ADMIN_SMS_LOGIN' => '后台启用短信登录',
|
||||
'SYS_ADMIN_SMS_CHECK' => '后台启用短信二次验证登录',
|
||||
|
||||
'SYS_ATTACHMENT_DB' => '附件归属开启模式',
|
||||
'SYS_ATTACHMENT_GUEST' => '游客是否附件上传',
|
||||
'SYS_ATTACHMENT_PAGESIZE' => '浏览附件分页数',
|
||||
'SYS_ATTACHMENT_CF' => '重复上传控制',
|
||||
'SYS_ATTACHMENT_REL' => '相对于当前站点的域名',
|
||||
'SYS_ATTACHMENT_SAFE' => '附件上传安全模式',
|
||||
'SYS_ATTACHMENT_DOWN_REMOTE' => '下载远程附件重命名方式',
|
||||
'SYS_ATTACHMENT_DOWN_SIZE' => '下载附件重命名条件',
|
||||
'SYS_ATTACHMENT_PATH' => '附件上传路径',
|
||||
'SYS_ATTACHMENT_SAVE_TYPE' => '附件存储方式',
|
||||
'SYS_ATTACHMENT_SAVE_DIR' => '附件存储目录',
|
||||
'SYS_ATTACHMENT_SAVE_ID' => '附件存储全局策略',
|
||||
'SYS_ATTACHMENT_URL' => '附件访问地址',
|
||||
'SYS_AVATAR_PATH' => '头像上传路径',
|
||||
'SYS_AVATAR_URL' => '头像访问地址',
|
||||
'SYS_API_TOKEN' => 'API请求密钥',
|
||||
'SYS_API_CODE' => 'API请求时验证码开关',
|
||||
'SYS_API_REL' => 'API请求时的URL方式',
|
||||
'SYS_THEME_ROOT_PATH' => '资源路径引用方式',
|
||||
'SYS_NOT_UPDATE' => '禁止自动检测版本',
|
||||
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* 保存配置文件
|
||||
*/
|
||||
public function save_config($system, $data) {
|
||||
|
||||
foreach ($this->config as $name => $s) {
|
||||
if (isset($data[$name])) {
|
||||
$value = $data[$name];
|
||||
if ($name == 'SYS_ADMIN_PAGESIZE') {
|
||||
$value = max(1, $value);
|
||||
} elseif ($name == 'SYS_NOT_ADMIN_CACHE') {
|
||||
if (!\Phpcmf\Service::LIC('vip')) {
|
||||
$value = 1;
|
||||
}
|
||||
}
|
||||
$system[$name] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
\Phpcmf\Service::L('config')->file(WRITEPATH.'config/system.php', '系统配置文件', 32)->to_require_one(
|
||||
$this->config,
|
||||
$system
|
||||
);
|
||||
}
|
||||
|
||||
// 读取配置信息
|
||||
public function get_setting($name) {
|
||||
$data = $this->table('admin_setting')->where('name', $name)->getRow();
|
||||
return $data ? dr_string2array($data['value']) : [];
|
||||
}
|
||||
|
||||
// 存储配置信息
|
||||
public function save_setting($name, $value) {
|
||||
$this->table('admin_setting')->replace([
|
||||
'name' => $name,
|
||||
'value' => dr_array2string($value),
|
||||
]);
|
||||
}
|
||||
|
||||
// 更新缓存
|
||||
public function cache() {
|
||||
|
||||
$rt = [];
|
||||
$data = $this->table('admin_setting')->getAll();
|
||||
if ($data) {
|
||||
foreach ($data as $t) {
|
||||
$rt[$t['name']] = dr_string2array($t['value']);
|
||||
}
|
||||
}
|
||||
|
||||
\Phpcmf\Service::L('cache')->set_file('admin_setting', $rt);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,986 @@
|
||||
<?php namespace Phpcmf\Model;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
|
||||
// 数据表(DDL 优先驱动;未实现时按 MySQL 源方言兼容,经 formatCreateSql 转换)
|
||||
class Table extends \Phpcmf\Model {
|
||||
|
||||
/**
|
||||
* MySQL 源方言标识符加反引号(供 formatCreateSql 转换)
|
||||
*
|
||||
* @param string $id
|
||||
* @return string
|
||||
*/
|
||||
protected function _mysql_qi($id) {
|
||||
return '`'.str_replace('`', '``', $this->unquote_id((string) $id)).'`';
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行 MySQL 源 DDL(_query_batch → dr_format_create_sql)
|
||||
*
|
||||
* @param string $sql
|
||||
* @return bool
|
||||
*/
|
||||
protected function _ddl_exec_mysql($sql) {
|
||||
|
||||
$sql = trim((string) $sql);
|
||||
if ($sql === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
$rt = $this->_query_batch($sql);
|
||||
if (!empty($rt['code'])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
log_message('error', 'DDL compat: '.($rt['msg'] ?? $sql));
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改字段(优先驱动 editField)
|
||||
*
|
||||
* @param string $table
|
||||
* @param string $name
|
||||
* @param string $type
|
||||
* @param string $info
|
||||
* @param string $note
|
||||
* @return mixed
|
||||
*/
|
||||
public function edit_field($table, $name, $type, $info, $note) {
|
||||
|
||||
if (method_exists($this->db, 'editField')) {
|
||||
return $this->db->editField($table, $name, $type, $info, $note);
|
||||
}
|
||||
|
||||
return $this->_edit_field_compat($table, $name, $type, $info, $note);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $table
|
||||
* @param string $name
|
||||
* @param string $type
|
||||
* @param string $info
|
||||
* @param string $note
|
||||
* @return bool
|
||||
*/
|
||||
protected function _edit_field_compat($table, $name, $type, $info, $note) {
|
||||
|
||||
$table = $this->unquote_id((string) $table);
|
||||
$name = $this->unquote_id((string) $name);
|
||||
if ($table === '' || $name === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
$qi = $this->_mysql_qi($name);
|
||||
$sql = 'ALTER TABLE '.$this->_mysql_qi($table).' CHANGE '.$qi.' '.$qi
|
||||
.' '.$type.' '.$info;
|
||||
$note = (string) $note;
|
||||
if ($note !== '') {
|
||||
$sql .= " COMMENT '".str_replace("'", "''", $note)."'";
|
||||
}
|
||||
|
||||
return $this->_ddl_exec_mysql($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加字段(优先驱动 addField)
|
||||
*
|
||||
* @param string $table
|
||||
* @param string $name
|
||||
* @param string $type
|
||||
* @param string $info
|
||||
* @param string $note
|
||||
* @return mixed
|
||||
*/
|
||||
public function add_field($table, $name, $type, $info, $note) {
|
||||
|
||||
if (method_exists($this->db, 'addField')) {
|
||||
return $this->db->addField($table, $name, $type, $info, $note);
|
||||
}
|
||||
|
||||
return $this->_add_field_compat($table, $name, $type, $info, $note);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $table
|
||||
* @param string $name
|
||||
* @param string $type
|
||||
* @param string $info
|
||||
* @param string $note
|
||||
* @return bool
|
||||
*/
|
||||
protected function _add_field_compat($table, $name, $type, $info, $note) {
|
||||
|
||||
$table = $this->unquote_id((string) $table);
|
||||
$name = $this->unquote_id((string) $name);
|
||||
if ($table === '' || $name === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
$sql = 'ALTER TABLE '.$this->_mysql_qi($table).' ADD '.$this->_mysql_qi($name)
|
||||
.' '.$type.' '.$info;
|
||||
$note = (string) $note;
|
||||
if ($note !== '') {
|
||||
$sql .= " COMMENT '".str_replace("'", "''", $note)."'";
|
||||
}
|
||||
|
||||
return $this->_ddl_exec_mysql($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除字段(优先驱动 dropField)
|
||||
*
|
||||
* @param string $table
|
||||
* @param string $name
|
||||
* @return mixed
|
||||
*/
|
||||
public function drop_field($table, $name) {
|
||||
|
||||
if (method_exists($this->db, 'dropField')) {
|
||||
return $this->db->dropField($table, $name);
|
||||
}
|
||||
|
||||
return $this->_drop_field_compat($table, $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $table
|
||||
* @param string $name
|
||||
* @return bool
|
||||
*/
|
||||
protected function _drop_field_compat($table, $name) {
|
||||
|
||||
$table = $this->unquote_id((string) $table);
|
||||
$name = $this->unquote_id((string) $name);
|
||||
if ($table === '' || $name === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->_ddl_exec_mysql(
|
||||
'ALTER TABLE '.$this->_mysql_qi($table).' DROP '.$this->_mysql_qi($name)
|
||||
);
|
||||
}
|
||||
|
||||
// 根据配置创建字段(字段类 create_sql 经驱动 sqlAddField 生成)
|
||||
public function create_field($table, $config) {
|
||||
|
||||
if (!$config || !$table) {
|
||||
return;
|
||||
}
|
||||
|
||||
$tablename = $this->dbprefix($table);
|
||||
foreach ($config as $field) {
|
||||
|
||||
if ($this->db->fieldExists($field['fieldname'], $tablename)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$obj = \Phpcmf\Service::L('field')->get($field['fieldtype']);
|
||||
if (!$obj) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$sql = $obj->create_sql($field['fieldname'], $field['setting']['option'], dr_safe_filename($field['name']));
|
||||
if (!$sql) {
|
||||
continue;
|
||||
}
|
||||
// create_sql 为 MySQL 源(含 {tablename}),走兼容执行
|
||||
$sql = str_replace('{tablename}', $this->unquote_id($tablename), $sql);
|
||||
$this->_ddl_exec_mysql($sql);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建表(优先驱动 createTable;未实现时拼 MySQL 源 SQL 经 formatCreateSql 兼容执行)
|
||||
*
|
||||
* @param string $table 表名(可含前缀)
|
||||
* @param array $fields ['字段名'=>'类型属性'] 或 [0=>'完整列定义']
|
||||
* @param array $indexs ['PRIMARY KEY (`id`)', 'KEY `name` (`name`)', ...]
|
||||
* @param string $note 表注释
|
||||
* @return array
|
||||
*/
|
||||
public function create_table($table, $fields, $indexs, $note) {
|
||||
|
||||
try {
|
||||
if (method_exists($this->db, 'createTable')) {
|
||||
$rt = $this->db->createTable($table, $fields, $indexs, $note);
|
||||
if ($rt === false) {
|
||||
$error = $this->db->error();
|
||||
return dr_return_data(0, $error['message'] ?? 'createTable failed');
|
||||
}
|
||||
return dr_return_data(1);
|
||||
}
|
||||
return $this->_create_table_compat($table, $fields, $indexs, $note);
|
||||
} catch (\Throwable $e) {
|
||||
log_message('error', 'createTable: '.$e->getMessage());
|
||||
return dr_return_data(0, $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 驱动未实现 createTable 时的兼容建表
|
||||
*
|
||||
* @param string $table
|
||||
* @param array $fields
|
||||
* @param array $indexs
|
||||
* @param string $note
|
||||
* @return array
|
||||
*/
|
||||
protected function _create_table_compat($table, $fields, $indexs, $note) {
|
||||
|
||||
$table = $this->unquote_id((string) $table);
|
||||
if ($table === '' || !is_array($fields) || !$fields) {
|
||||
return dr_return_data(0, 'createTable 参数无效');
|
||||
}
|
||||
|
||||
$lines = [];
|
||||
foreach ($fields as $name => $def) {
|
||||
if (is_int($name)) {
|
||||
$lines[] = (string) $def;
|
||||
} else {
|
||||
$lines[] = $this->_mysql_qi($name).' '.(string) $def;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_array($indexs)) {
|
||||
foreach ($indexs as $idx) {
|
||||
$idx = trim((string) $idx);
|
||||
if ($idx !== '') {
|
||||
$lines[] = $idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$lines) {
|
||||
return dr_return_data(0, 'createTable 无字段定义');
|
||||
}
|
||||
|
||||
$sql = 'CREATE TABLE IF NOT EXISTS '.$this->_mysql_qi($table).' (
|
||||
'.implode(",\n", $lines).'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT=\''
|
||||
.str_replace("'", "''", (string) $note).'\'';
|
||||
|
||||
$rt = $this->_query_batch($sql);
|
||||
if (empty($rt['code'])) {
|
||||
return dr_return_data(0, $rt['msg'] ?? 'createTable compat failed');
|
||||
}
|
||||
|
||||
return dr_return_data(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除表(优先驱动 dropTable;未实现时走兼容 SQL)
|
||||
*
|
||||
* @param string $table
|
||||
* @param bool $ifExists
|
||||
* @return array
|
||||
*/
|
||||
public function drop_table($table, $ifExists = true) {
|
||||
|
||||
try {
|
||||
if (method_exists($this->db, 'dropTable')) {
|
||||
$rt = $this->db->dropTable($table, $ifExists);
|
||||
} else {
|
||||
$rt = $this->_drop_table_compat($table, $ifExists);
|
||||
}
|
||||
if ($rt === false) {
|
||||
$error = $this->db->error();
|
||||
return dr_return_data(0, $error['message'] ?? 'dropTable failed');
|
||||
}
|
||||
return dr_return_data(1);
|
||||
} catch (\Throwable $e) {
|
||||
log_message('error', 'dropTable: '.$e->getMessage());
|
||||
return dr_return_data(0, $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 驱动未实现 dropTable 时的兼容删除
|
||||
*
|
||||
* @param string $table
|
||||
* @param bool $ifExists
|
||||
* @return bool
|
||||
*/
|
||||
protected function _drop_table_compat($table, $ifExists = true) {
|
||||
|
||||
$table = $this->unquote_id((string) $table);
|
||||
if ($table === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($ifExists && method_exists($this->db, 'tableExists') && !$this->db->tableExists($table)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$sql = ($ifExists ? 'DROP TABLE IF EXISTS ' : 'DROP TABLE ').$this->_mysql_qi($table);
|
||||
if ($this->_ddl_exec_mysql($sql)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// IF EXISTS 不被支持时退化
|
||||
if ($ifExists) {
|
||||
return $this->_ddl_exec_mysql('DROP TABLE '.$this->_mysql_qi($table));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 按 Schema 安装表结构与种子数据(Config/Install.php)
|
||||
*
|
||||
* @param array $schema ['tables'=>[name=>['fields','indexes','comment','drop']], 'seeds'=>[['table','data']]]
|
||||
* @return array
|
||||
*/
|
||||
public function install_schema(array $schema) {
|
||||
|
||||
$tables = isset($schema['tables']) && is_array($schema['tables']) ? $schema['tables'] : [];
|
||||
$seeds = isset($schema['seeds']) && is_array($schema['seeds']) ? $schema['seeds'] : [];
|
||||
|
||||
foreach ($tables as $name => $def) {
|
||||
if (!$name || !is_array($def) || empty($def['fields'])) {
|
||||
continue;
|
||||
}
|
||||
$table = $this->dbprefix($name);
|
||||
if (!empty($def['drop'])) {
|
||||
$rt = $this->drop_table($table, true);
|
||||
if (!$rt['code']) {
|
||||
return $rt;
|
||||
}
|
||||
}
|
||||
$rt = $this->create_table(
|
||||
$table,
|
||||
$def['fields'],
|
||||
isset($def['indexes']) ? $def['indexes'] : [],
|
||||
isset($def['comment']) ? $def['comment'] : ''
|
||||
);
|
||||
if (!$rt['code']) {
|
||||
return dr_return_data(0, dr_lang('创建表失败(%s):%s', $table, $rt['msg']));
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($seeds as $seed) {
|
||||
if (empty($seed['table']) || empty($seed['data']) || !is_array($seed['data'])) {
|
||||
continue;
|
||||
}
|
||||
$rt = \Phpcmf\Service::M()->table($seed['table'])->replace($seed['data']);
|
||||
if (is_array($rt) && isset($rt['code']) && !$rt['code']) {
|
||||
return dr_return_data(0, dr_lang('写入初始数据失败(%s):%s', $seed['table'], $rt['msg']));
|
||||
}
|
||||
}
|
||||
|
||||
return dr_return_data(1, '', ['tables' => dr_count($tables), 'seeds' => dr_count($seeds)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取建表 SQL(优先驱动 createTableSql)
|
||||
*
|
||||
* @param string $table
|
||||
* @return array [createSql, fieldFragments, table]
|
||||
*/
|
||||
public function create_table_sql($table) {
|
||||
|
||||
if (method_exists($this->db, 'createTableSql')) {
|
||||
$create = $this->db->createTableSql($table);
|
||||
} else {
|
||||
$create = $this->_create_table_sql_compat($table);
|
||||
}
|
||||
|
||||
if (!$create) {
|
||||
return ['', [], $table];
|
||||
}
|
||||
|
||||
$char = '`';
|
||||
if (isset($this->db->escapeChar) && is_string($this->db->escapeChar) && $this->db->escapeChar !== '') {
|
||||
$char = $this->db->escapeChar;
|
||||
}
|
||||
$quote = preg_quote($char, '/');
|
||||
|
||||
$arr = explode(PHP_EOL, $create);
|
||||
$sql = [];
|
||||
foreach ($arr as $t) {
|
||||
if (preg_match('/'.$quote.'(.+)'.$quote.'/U', $t, $mt)
|
||||
&& strpos($t, ' KEY ') === false
|
||||
&& strpos($t, $char.$this->dbprefix()) === false
|
||||
) {
|
||||
$sql[$mt[1]] = trim($t, ',');
|
||||
}
|
||||
}
|
||||
|
||||
return [$create, $sql, $table];
|
||||
}
|
||||
|
||||
/**
|
||||
* 驱动未实现 createTableSql:先试 SHOW CREATE TABLE,再按字段元数据拼装
|
||||
*
|
||||
* @param string $table
|
||||
* @return string
|
||||
*/
|
||||
protected function _create_table_sql_compat($table) {
|
||||
|
||||
$table = $this->unquote_id((string) $table);
|
||||
if ($table === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
try {
|
||||
$query = $this->db->query('SHOW CREATE TABLE '.$this->_mysql_qi($table));
|
||||
$row = $query ? $query->getRowArray() : null;
|
||||
if ($row) {
|
||||
foreach ($row as $k => $v) {
|
||||
if (stripos((string) $k, 'create') !== false && $v) {
|
||||
return str_replace('CREATE TABLE', 'CREATE TABLE IF NOT EXISTS', (string) $v);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
// 非 MySQL 忽略
|
||||
}
|
||||
|
||||
if (!method_exists($this->db, 'getFieldData')) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$fds = $this->db->getFieldData($table);
|
||||
if (!$fds) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$lines = [];
|
||||
$pk = [];
|
||||
foreach ($fds as $f) {
|
||||
$name = isset($f->name) ? $f->name : '';
|
||||
if ($name === '') {
|
||||
continue;
|
||||
}
|
||||
$type = isset($f->type) ? $f->type : 'TEXT';
|
||||
if (!empty($f->max_length) && !preg_match('/\(/', $type)
|
||||
&& !preg_match('/(TEXT|BLOB|DATE|TIME|INT|FLOAT|DOUBLE|REAL|BOOL)/i', $type)
|
||||
) {
|
||||
$type .= '('.$f->max_length.')';
|
||||
}
|
||||
$null = (isset($f->nullable) ? $f->nullable : true) ? 'NULL' : 'NOT NULL';
|
||||
$def = '';
|
||||
if (isset($f->default) && $f->default !== null) {
|
||||
$def = " DEFAULT '".str_replace("'", "''", (string) $f->default)."'";
|
||||
}
|
||||
$extra = '';
|
||||
if (!empty($f->primary_key)) {
|
||||
$pk[] = $this->_mysql_qi($name);
|
||||
}
|
||||
if (!empty($f->auto_increment)) {
|
||||
$extra = ' AUTO_INCREMENT';
|
||||
}
|
||||
$lines[] = $this->_mysql_qi($name).' '.$type.' '.$null.$def.$extra;
|
||||
}
|
||||
if ($pk) {
|
||||
$lines[] = 'PRIMARY KEY ('.implode(',', $pk).')';
|
||||
}
|
||||
|
||||
return 'CREATE TABLE IF NOT EXISTS '.$this->_mysql_qi($table).' (
|
||||
'.implode(",\n", $lines).'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci';
|
||||
}
|
||||
|
||||
/**
|
||||
* 从表结构导出规范化 Schema(fields / indexes / comment)
|
||||
* 供 Dever 导出 Config/Content.php、Form.php 等使用
|
||||
*/
|
||||
public function create_table_schema($table) {
|
||||
|
||||
list($create) = $this->create_table_sql($table);
|
||||
if (!$create) {
|
||||
return [
|
||||
'comment' => '',
|
||||
'fields' => [],
|
||||
'indexes' => [],
|
||||
];
|
||||
}
|
||||
|
||||
$comment = '';
|
||||
if (preg_match("/COMMENT='([^']*)'/", $create, $cm)) {
|
||||
$comment = $cm[1];
|
||||
} elseif (preg_match('/COMMENT="([^"]*)"/', $create, $cm)) {
|
||||
$comment = $cm[1];
|
||||
}
|
||||
|
||||
$inner = $create;
|
||||
if (preg_match('/\((.*)\)\s*ENGINE/is', $create, $m)) {
|
||||
$inner = $m[1];
|
||||
}
|
||||
|
||||
$fields = [];
|
||||
$indexes = [];
|
||||
$parts = preg_split("/,\s*\n/", trim($inner));
|
||||
if (dr_count($parts) < 2) {
|
||||
$parts = [];
|
||||
$buf = '';
|
||||
$depth = 0;
|
||||
$len = strlen($inner);
|
||||
for ($i = 0; $i < $len; $i++) {
|
||||
$ch = $inner[$i];
|
||||
if ($ch === '(') {
|
||||
$depth++;
|
||||
$buf .= $ch;
|
||||
} elseif ($ch === ')') {
|
||||
$depth = max(0, $depth - 1);
|
||||
$buf .= $ch;
|
||||
} elseif ($ch === ',' && $depth === 0) {
|
||||
$parts[] = trim($buf);
|
||||
$buf = '';
|
||||
} else {
|
||||
$buf .= $ch;
|
||||
}
|
||||
}
|
||||
if (trim($buf) !== '') {
|
||||
$parts[] = trim($buf);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($parts as $line) {
|
||||
$line = trim($line);
|
||||
$line = rtrim($line, ',');
|
||||
if ($line === '') {
|
||||
continue;
|
||||
}
|
||||
if (preg_match('/^(PRIMARY KEY|UNIQUE KEY|KEY|FULLTEXT KEY)\s/i', $line)) {
|
||||
$indexes[] = $line;
|
||||
continue;
|
||||
}
|
||||
if (preg_match('/^`([^`]+)`\s+(.+)$/s', $line, $fm)) {
|
||||
$fields[$fm[1]] = trim($fm[2]);
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'comment' => $comment,
|
||||
'fields' => $fields,
|
||||
'indexes' => $indexes,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 表完整字段信息(优先驱动 showFullColunms)
|
||||
*
|
||||
* @param string $table
|
||||
* @return array
|
||||
*/
|
||||
public function show_full_colunms($table) {
|
||||
|
||||
if (method_exists($this->db, 'showFullColunms')) {
|
||||
return $this->db->showFullColunms($table);
|
||||
}
|
||||
|
||||
return $this->_show_full_colunms_compat($table);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $table
|
||||
* @return array
|
||||
*/
|
||||
protected function _show_full_colunms_compat($table) {
|
||||
|
||||
$table = $this->unquote_id((string) $table);
|
||||
if ($table === '') {
|
||||
return [];
|
||||
}
|
||||
|
||||
try {
|
||||
$query = $this->db->query('SHOW FULL COLUMNS FROM '.$this->_mysql_qi($table));
|
||||
if ($query) {
|
||||
$rows = $query->getResultArray();
|
||||
if ($rows) {
|
||||
return $rows;
|
||||
}
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
// 非 MySQL
|
||||
}
|
||||
|
||||
if (!method_exists($this->db, 'getFieldData')) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$out = [];
|
||||
foreach ($this->db->getFieldData($table) as $f) {
|
||||
$out[] = [
|
||||
'Field' => isset($f->name) ? $f->name : '',
|
||||
'Type' => isset($f->type) ? $f->type : '',
|
||||
'Collation' => null,
|
||||
'Null' => (isset($f->nullable) && !$f->nullable) ? 'NO' : 'YES',
|
||||
'Key' => !empty($f->primary_key) ? 'PRI' : '',
|
||||
'Default' => isset($f->default) ? $f->default : null,
|
||||
'Extra' => !empty($f->auto_increment) ? 'auto_increment' : '',
|
||||
'Privileges' => '',
|
||||
'Comment' => '',
|
||||
];
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* 全部表状态(优先驱动 showTableStatus)
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function show_table_status() {
|
||||
|
||||
if (method_exists($this->db, 'showTableStatus')) {
|
||||
return $this->db->showTableStatus();
|
||||
}
|
||||
|
||||
return $this->_show_table_status_compat();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function _show_table_status_compat() {
|
||||
|
||||
try {
|
||||
$query = $this->db->query('SHOW TABLE STATUS');
|
||||
if ($query) {
|
||||
$rows = $query->getResultArray();
|
||||
if ($rows) {
|
||||
return $rows;
|
||||
}
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
// 非 MySQL
|
||||
}
|
||||
|
||||
$out = [];
|
||||
if (method_exists($this->db, 'listTables')) {
|
||||
foreach ($this->db->listTables() as $name) {
|
||||
$out[] = [
|
||||
'Name' => $name,
|
||||
'Engine' => '',
|
||||
'Version' => '',
|
||||
'Row_format' => '',
|
||||
'Rows' => 0,
|
||||
'Avg_row_length' => 0,
|
||||
'Data_length' => 0,
|
||||
'Max_data_length' => 0,
|
||||
'Index_length' => 0,
|
||||
'Data_free' => 0,
|
||||
'Auto_increment' => null,
|
||||
'Create_time' => null,
|
||||
'Update_time' => null,
|
||||
'Check_time' => null,
|
||||
'Collation' => '',
|
||||
'Checksum' => null,
|
||||
'Create_options' => '',
|
||||
'Comment' => '',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修复表(优先驱动;兼容执行 MySQL REPAIR TABLE,失败则视为跳过成功)
|
||||
*
|
||||
* @param string $table
|
||||
* @return mixed
|
||||
*/
|
||||
public function repair_table($table) {
|
||||
|
||||
if (method_exists($this->db, 'repairTable')) {
|
||||
return $this->db->repairTable($table);
|
||||
}
|
||||
|
||||
return $this->_maintenance_table_compat('REPAIR TABLE', $table);
|
||||
}
|
||||
|
||||
/**
|
||||
* 优化表
|
||||
*
|
||||
* @param string $table
|
||||
* @return mixed
|
||||
*/
|
||||
public function optimize_table($table) {
|
||||
|
||||
if (method_exists($this->db, 'optimizeTable')) {
|
||||
return $this->db->optimizeTable($table);
|
||||
}
|
||||
|
||||
return $this->_maintenance_table_compat('OPTIMIZE TABLE', $table);
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新表
|
||||
*
|
||||
* @param string $table
|
||||
* @return mixed
|
||||
*/
|
||||
public function flush_table($table) {
|
||||
|
||||
if (method_exists($this->db, 'flushTable')) {
|
||||
return $this->db->flushTable($table);
|
||||
}
|
||||
|
||||
return $this->_maintenance_table_compat('FLUSH TABLE', $table);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查表
|
||||
*
|
||||
* @param string $table
|
||||
* @return array
|
||||
*/
|
||||
public function check_table($table) {
|
||||
|
||||
if (method_exists($this->db, 'checkTable')) {
|
||||
return $this->db->checkTable($table);
|
||||
}
|
||||
|
||||
$table = $this->unquote_id((string) $table);
|
||||
if ($table === '') {
|
||||
return [];
|
||||
}
|
||||
|
||||
try {
|
||||
$query = $this->db->query('CHECK TABLE '.$this->_mysql_qi($table));
|
||||
$row = $query ? $query->getRowArray() : null;
|
||||
if ($row) {
|
||||
return $row;
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
// 非 MySQL:返回通过状态,避免后台报错
|
||||
}
|
||||
|
||||
return ['Msg_text' => 'OK', 'Msg_type' => 'status'];
|
||||
}
|
||||
|
||||
/**
|
||||
* MySQL 维护类语句兼容(不支持的库跳过并返回 true)
|
||||
*
|
||||
* @param string $verb REPAIR TABLE / OPTIMIZE TABLE / FLUSH TABLE
|
||||
* @param string $table
|
||||
* @return bool
|
||||
*/
|
||||
protected function _maintenance_table_compat($verb, $table) {
|
||||
|
||||
$table = $this->unquote_id((string) $table);
|
||||
if ($table === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
$rt = $this->db->query($verb.' '.$this->_mysql_qi($table));
|
||||
if ($rt !== false) {
|
||||
return $rt;
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改表默认字符集(优先驱动 setTableCharset)
|
||||
*
|
||||
* @param string $table
|
||||
* @param string $charset
|
||||
* @param string $collate
|
||||
* @return mixed
|
||||
*/
|
||||
public function set_table_charset($table, $charset = 'utf8mb4', $collate = 'utf8mb4_unicode_ci') {
|
||||
|
||||
if (method_exists($this->db, 'setTableCharset')) {
|
||||
return $this->db->setTableCharset($table, $charset, $collate);
|
||||
}
|
||||
|
||||
return $this->_set_table_charset_compat($table, $charset, $collate);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $table
|
||||
* @param string $charset
|
||||
* @param string $collate
|
||||
* @return bool
|
||||
*/
|
||||
protected function _set_table_charset_compat($table, $charset = 'utf8mb4', $collate = 'utf8mb4_unicode_ci') {
|
||||
|
||||
$table = $this->unquote_id((string) $table);
|
||||
if ($table === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
$charset = preg_replace('/[^a-z0-9_]/i', '', (string) $charset);
|
||||
$collate = preg_replace('/[^a-z0-9_]/i', '', (string) $collate);
|
||||
$sql = 'ALTER TABLE '.$this->_mysql_qi($table).' DEFAULT CHARSET='.$charset.' COLLATE '.$collate;
|
||||
|
||||
if ($this->_ddl_exec_mysql($sql)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 不支持字符集的库视为跳过
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建索引(优先驱动;否则 MySQL CREATE INDEX 经 formatCreateSql)
|
||||
*
|
||||
* @param string $table
|
||||
* @param string $name
|
||||
* @param string|array $columns
|
||||
* @return mixed
|
||||
*/
|
||||
public function add_index($table, $name, $columns) {
|
||||
|
||||
$table = $this->unquote_id((string) $table);
|
||||
$name = $this->unquote_id((string) $name);
|
||||
if ($table === '' || $name === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_array($columns)) {
|
||||
$cols = [];
|
||||
foreach ($columns as $c) {
|
||||
$cols[] = $this->_mysql_qi($c);
|
||||
}
|
||||
$colsql = implode(', ', $cols);
|
||||
} else {
|
||||
$colsql = (string) $columns;
|
||||
if (!$this->has_id_quotes($colsql)) {
|
||||
$parts = array_map('trim', explode(',', $colsql));
|
||||
$tmp = [];
|
||||
foreach ($parts as $p) {
|
||||
$p !== '' && $tmp[] = $this->_mysql_qi($p);
|
||||
}
|
||||
$colsql = implode(', ', $tmp);
|
||||
}
|
||||
}
|
||||
|
||||
if (method_exists($this->db, 'addIndex')) {
|
||||
return $this->db->addIndex($table, $name, $columns);
|
||||
}
|
||||
|
||||
return $this->_ddl_exec_mysql(
|
||||
'CREATE INDEX '.$this->_mysql_qi($name).' ON '.$this->_mysql_qi($table).'('.$colsql.')'
|
||||
);
|
||||
}
|
||||
|
||||
// 表结构缓存
|
||||
public function cache($siteid = SITE_ID, $module = null) {
|
||||
|
||||
$cache = [];
|
||||
$paytable = []; // 付款表名 支持模块和表单 后期淘汰
|
||||
// 生成模块表结构
|
||||
if (dr_is_use_module()) {
|
||||
$obj = \Phpcmf\Service::M('module', 'cms');
|
||||
if (method_exists($obj, 'paytable')) {
|
||||
list($cache, $paytable) = $obj->paytable($cache, $paytable, $module, $siteid);
|
||||
}
|
||||
}
|
||||
|
||||
// 网站表单
|
||||
if (dr_is_app('form') && $this->is_table_exists($siteid.'_form')) {
|
||||
$obj = \Phpcmf\Service::M('form', 'form');
|
||||
if (method_exists($obj, 'paytable')) {
|
||||
list($cache, $paytable) = $obj->paytable($cache, $paytable, $siteid);
|
||||
}
|
||||
}
|
||||
|
||||
// 会员表
|
||||
$table = $this->dbprefix('member');
|
||||
$cache[$table] = $this->db->getFieldNames($table);
|
||||
|
||||
// 会员附表
|
||||
$table = $this->dbprefix('member_data');
|
||||
$cache[$table] = $this->db->getFieldNames($table);
|
||||
|
||||
// 缓存表结构
|
||||
\Phpcmf\Service::L('cache')->set_file('table-'.$siteid, $cache);
|
||||
|
||||
// 缓存的字段类型
|
||||
//$type = ['Select', 'Checkbox', 'Radio', 'Pay', 'Pays', 'File', 'Files', 'Image', 'Images', 'Ftable'];
|
||||
$cache = [];
|
||||
$field = $this->db->table('field')->where('disabled', 0)->orderBy('id ASC')->get()->getResultArray();
|
||||
if ($field) {
|
||||
foreach ($field as $f) {
|
||||
$f['setting'] = dr_string2array($f['setting']);
|
||||
$cache[$f['id']] = $f;
|
||||
}
|
||||
}
|
||||
\Phpcmf\Service::L('cache')->set_file('table-field', $cache);
|
||||
|
||||
// 缓存付款表
|
||||
\Phpcmf\Service::L('cache')->set_file('table-pay-'.$siteid, $paytable);
|
||||
/*
|
||||
* $paytable字段主键为 自定义字段rname-rid
|
||||
* */
|
||||
}
|
||||
|
||||
// 获取字段结构
|
||||
public function get_field($table) {
|
||||
return $this->db->getFieldNames($this->dbprefix($table));
|
||||
}
|
||||
|
||||
// 获取缓存的字段结构
|
||||
public function get_cache_field($table) {
|
||||
|
||||
$tableinfo = \Phpcmf\Service::L('cache')->get('table-'.SITE_ID);
|
||||
if (!$tableinfo) {
|
||||
// 没有表结构缓存时返回空
|
||||
return [];
|
||||
}
|
||||
|
||||
return isset($tableinfo[$this->dbprefix($table)]) ? $tableinfo[$this->dbprefix($table)] : [];
|
||||
}
|
||||
|
||||
// 执行批量sql
|
||||
public function _query($sql, $replace = []) {
|
||||
return $this->_query_batch($sql, $replace);
|
||||
}
|
||||
|
||||
// 网站表单--------------------------------------------------------------------
|
||||
|
||||
// 创建
|
||||
public function create_form($data) {
|
||||
if (dr_is_app('form')) {
|
||||
\Phpcmf\Service::M('form', 'form')->create_form($data);
|
||||
}
|
||||
}
|
||||
|
||||
// 删除表单
|
||||
public function delete_form($data) {
|
||||
if (dr_is_app('form')) {
|
||||
\Phpcmf\Service::M('form', 'form')->delete_form_table($data);
|
||||
}
|
||||
}
|
||||
|
||||
// 模块表单--------------------------------------------------------------------
|
||||
|
||||
// 创建
|
||||
public function create_module_form($data) {
|
||||
if (dr_is_app('mform')) {
|
||||
\Phpcmf\Service::M('mform', 'mform')->create_module_form($data);
|
||||
}
|
||||
}
|
||||
|
||||
// 删除模块表单
|
||||
public function delete_module_form($data) {
|
||||
if (dr_is_app('mform')) {
|
||||
\Phpcmf\Service::M('mform', 'mform')->delete_module_form($data);
|
||||
}
|
||||
}
|
||||
|
||||
// 项目--------------------------------------------------------------------
|
||||
|
||||
// 创建项目
|
||||
public function create_site($siteid) {
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user