Initial project files: BESCMS full source

This commit is contained in:
bes
2026-08-13 23:37:46 +08:00
parent fa6cddb540
commit 2e26f85723
2166 changed files with 396625 additions and 0 deletions
+303
View File
@@ -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 '';
}
}
+435
View File
@@ -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
+427
View File
@@ -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;
}
}
+2
View File
@@ -0,0 +1,2 @@
<?php
// 文件作废
+2
View File
@@ -0,0 +1,2 @@
<?php
// 文件作废
+140
View File
@@ -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);
}
}
+87
View File
@@ -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);
}
}
+985
View File
@@ -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;
}
//--------------------------------------------------------------------
}
+14
View File
@@ -0,0 +1,14 @@
<?php namespace Phpcmf\Model;
/**
* https://www.besyun.com
* BESCMS
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
**/
// 用户组模型类
class Group extends \Phpcmf\Model {
}
+475
View File
@@ -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
+47
View File
@@ -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;
}
}
+899
View File
@@ -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);
}
}
+2
View File
@@ -0,0 +1,2 @@
<?php
// 文件作废
+250
View File
@@ -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);
}
}
+80
View File
@@ -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);
}
}
}
}
+120
View File
@@ -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);
}
}
+986
View File
@@ -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';
}
/**
* 从表结构导出规范化 Schemafields / 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) {
}
}