Initial project files: BESCMS full source
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
/**
|
||||
* 后台的自定义分页标签样式
|
||||
*/
|
||||
|
||||
if (dr_is_mobile()) {
|
||||
return array(
|
||||
|
||||
// 自定义“统计”链接
|
||||
'total_link' => '共%s条', // 你希望在分页中显示“统计”链接的名字。如果你不希望显示,可以把它的值设为 FALSE
|
||||
'total_tag_open' => '<li><a>', // “统计”链接的打开标签
|
||||
'total_tag_close' => '</a></li>', // “统计”链接的关闭标签
|
||||
|
||||
// 自定义“下一页”链接
|
||||
'next_link' => '下页', // 你希望在分页中显示“下一页”链接的名字。如果你不希望显示,可以把它的值设为 FALSE
|
||||
'next_tag_open' => '<li>', // “下一页”链接的打开标签
|
||||
'next_tag_close' => '</li>', // “下一页”链接的关闭标签
|
||||
|
||||
// 自定义“上一页”链接
|
||||
'prev_link' => '上页', // 你希望在分页中显示“上一页”链接的名字。如果你不希望显示,可以把它的值设为 FALSE
|
||||
'prev_tag_open' => '<li>', // “上一页”链接的打开标签
|
||||
'prev_tag_close' => '</li>', // “上一页”链接的关闭标签
|
||||
|
||||
// 自定义“当前页”链接
|
||||
'cur_tag_open' => '<li class="active"><a>', // “当前页”链接的打开标签
|
||||
'cur_tag_close' => '</a></li>', // “当前页”链接的关闭标签
|
||||
|
||||
// 自定义“数字”链接
|
||||
'num_tag_open' => '<li>', // “数字”链接的打开标签
|
||||
'num_tag_close' => '</li>', // “数字”链接的关闭标签
|
||||
|
||||
// 自定义“最后一页”链接
|
||||
'last_link' => FALSE, // 你希望在分页的右边显示“最后一页”链接的名字。如果你不希望显示,可以把它的值设为 FALSE
|
||||
'last_tag_open' => '<li>', // “最后一页”链接的打开标签
|
||||
'last_tag_close' => '</li>', // “最后一页”链接的关闭标签
|
||||
|
||||
// 自定义“第一页”链接
|
||||
'first_link' => FALSE, // 你希望在分页的左边显示“第一页”链接的名字。如果你不希望显示,可以把它的值设为 FALSE
|
||||
'first_tag_open' => '<li>', // “第一页”链接的打开标签
|
||||
'first_tag_close' => '</li>', // “第一页”链接的关闭标签
|
||||
|
||||
// 是否显示数字链接
|
||||
'display_pages' => FALSE,
|
||||
|
||||
// 显示的分页数字个数
|
||||
'num_links' => 2,
|
||||
|
||||
// 区域标签
|
||||
'full_tag_open' => '<ul class="pagination">',
|
||||
|
||||
// 区域标签
|
||||
'full_tag_close' => '</ul>',
|
||||
|
||||
|
||||
);
|
||||
} else {
|
||||
return array(
|
||||
|
||||
// 自定义“统计”链接
|
||||
'total_link' => '共%s条', // 你希望在分页中显示“统计”链接的名字。如果你不希望显示,可以把它的值设为 FALSE
|
||||
'total_tag_open' => '<li><a>', // “统计”链接的打开标签
|
||||
'total_tag_close' => '</a></li>', // “统计”链接的关闭标签
|
||||
|
||||
// 自定义“下一页”链接
|
||||
'next_link' => '', // 你希望在分页中显示“下一页”链接的名字。如果你不希望显示,可以把它的值设为 FALSE
|
||||
'next_tag_open' => '', // “下一页”链接的打开标签
|
||||
'next_tag_close' => '', // “下一页”链接的关闭标签
|
||||
|
||||
// 自定义“上一页”链接
|
||||
'prev_link' => '', // 你希望在分页中显示“上一页”链接的名字。如果你不希望显示,可以把它的值设为 FALSE
|
||||
'prev_tag_open' => '', // “上一页”链接的打开标签
|
||||
'prev_tag_close' => '', // “上一页”链接的关闭标签
|
||||
|
||||
// 自定义“当前页”链接
|
||||
'cur_tag_open' => '<li class="active"><a>', // “当前页”链接的打开标签
|
||||
'cur_tag_close' => '</a></li>', // “当前页”链接的关闭标签
|
||||
|
||||
// 自定义“数字”链接
|
||||
'num_tag_open' => '<li>', // “数字”链接的打开标签
|
||||
'num_tag_close' => '</li>', // “数字”链接的关闭标签
|
||||
|
||||
// 自定义“最后一页”链接
|
||||
'last_link' => '最后一页', // 你希望在分页的右边显示“最后一页”链接的名字。如果你不希望显示,可以把它的值设为 FALSE
|
||||
'last_tag_open' => '<li>', // “最后一页”链接的打开标签
|
||||
'last_tag_close' => '</li>', // “最后一页”链接的关闭标签
|
||||
|
||||
// 自定义“第一页”链接
|
||||
'first_link' => '第一页', // 你希望在分页的左边显示“第一页”链接的名字。如果你不希望显示,可以把它的值设为 FALSE
|
||||
'first_tag_open' => '<li>', // “第一页”链接的打开标签
|
||||
'first_tag_close' => '</li>', // “第一页”链接的关闭标签
|
||||
|
||||
// 是否显示数字链接
|
||||
'display_pages' => TRUE,
|
||||
|
||||
// 显示的分页数字个数
|
||||
'num_links' => 2,
|
||||
|
||||
// 区域标签
|
||||
'full_tag_open' => '<ul class="pagination">',
|
||||
|
||||
// 区域标签
|
||||
'full_tag_close' => '</ul>',
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,477 @@
|
||||
<?php
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 系统安装 Schema(规范化 DDL:Table::install_schema → 驱动 createTable)
|
||||
* 由 Control\Install / Init 显式 require 后交给安装门面执行,勿依赖副作用。
|
||||
*/
|
||||
|
||||
return [
|
||||
'tables' => [
|
||||
'cron' => [
|
||||
'comment' => '任务管理',
|
||||
'drop' => true,
|
||||
'fields' => [
|
||||
'id' => 'int(10) NOT NULL AUTO_INCREMENT',
|
||||
'site' => 'int(10) NOT NULL COMMENT \'项目id\'',
|
||||
'type' => 'varchar(100) NOT NULL COMMENT \'类型\'',
|
||||
'value' => 'text NOT NULL COMMENT \'参数值\'',
|
||||
'status' => 'tinyint(1) unsigned NOT NULL COMMENT \'状态\'',
|
||||
'error' => 'text DEFAULT NULL COMMENT \'错误信息\'',
|
||||
'updatetime' => 'int(10) unsigned NOT NULL COMMENT \'执行时间\'',
|
||||
'inputtime' => 'int(10) unsigned NOT NULL COMMENT \'写入时间\'',
|
||||
],
|
||||
'indexes' => [
|
||||
'PRIMARY KEY (`id`)',
|
||||
'KEY `site` (`site`)',
|
||||
'KEY `type` (`type`)',
|
||||
'KEY `status` (`status`)',
|
||||
'KEY `updatetime` (`updatetime`)',
|
||||
'KEY `inputtime` (`inputtime`)',
|
||||
],
|
||||
],
|
||||
'admin' => [
|
||||
'comment' => '管理员表',
|
||||
'drop' => true,
|
||||
'fields' => [
|
||||
'id' => 'smallint(5) unsigned NOT NULL AUTO_INCREMENT',
|
||||
'uid' => 'int(10) unsigned NOT NULL COMMENT \'管理员uid\'',
|
||||
'setting' => 'mediumtext DEFAULT NULL COMMENT \'相关配置\'',
|
||||
'usermenu' => 'text COMMENT \'自定义面板菜单,序列化数组格式\'',
|
||||
'history' => 'text COMMENT \'历史菜单,序列化数组格式\'',
|
||||
],
|
||||
'indexes' => [
|
||||
'PRIMARY KEY (`id`)',
|
||||
'UNIQUE KEY `uid` (`uid`)',
|
||||
],
|
||||
],
|
||||
'admin_notice' => [
|
||||
'comment' => '后台提醒表',
|
||||
'drop' => true,
|
||||
'fields' => [
|
||||
'id' => 'int(10) NOT NULL AUTO_INCREMENT COMMENT \'id\'',
|
||||
'site' => 'int(5) NOT NULL COMMENT \'项目id\'',
|
||||
'type' => 'varchar(20) NOT NULL COMMENT \'提醒类型:系统、内容、会员、应用\'',
|
||||
'msg' => 'text NOT NULL COMMENT \'提醒内容说明\'',
|
||||
'uri' => 'varchar(100) NOT NULL COMMENT \'对应的URI\'',
|
||||
'to_rid' => 'varchar(100) NOT NULL COMMENT \'指定角色组\'',
|
||||
'to_uid' => 'varchar(100) NOT NULL COMMENT \'指定管理员\'',
|
||||
'status' => 'tinyint(1) NOT NULL COMMENT \'未处理0,1已查看,2处理中,3处理完成\'',
|
||||
'uid' => 'int(10) NOT NULL COMMENT \'申请人\'',
|
||||
'username' => 'varchar(100) NOT NULL COMMENT \'申请人\'',
|
||||
'op_uid' => 'int(10) NOT NULL COMMENT \'处理人\'',
|
||||
'op_username' => 'varchar(100) NOT NULL COMMENT \'处理人\'',
|
||||
'updatetime' => 'int(10) NOT NULL COMMENT \'处理时间\'',
|
||||
'inputtime' => 'int(10) NOT NULL COMMENT \'提醒时间\'',
|
||||
],
|
||||
'indexes' => [
|
||||
'PRIMARY KEY (`id`)',
|
||||
'KEY `uri` (`uri`)',
|
||||
'KEY `site` (`site`)',
|
||||
'KEY `status` (`status`)',
|
||||
'KEY `uid` (`uid`)',
|
||||
'KEY `op_uid` (`op_uid`)',
|
||||
'KEY `to_uid` (`to_uid`)',
|
||||
'KEY `to_rid` (`to_rid`)',
|
||||
'KEY `updatetime` (`updatetime`)',
|
||||
'KEY `inputtime` (`inputtime`)',
|
||||
],
|
||||
],
|
||||
'admin_login' => [
|
||||
'comment' => '登录日志记录',
|
||||
'drop' => true,
|
||||
'fields' => [
|
||||
'id' => 'int(10) unsigned NOT NULL AUTO_INCREMENT',
|
||||
'uid' => 'mediumint(8) unsigned DEFAULT NULL COMMENT \'会员uid\'',
|
||||
'loginip' => 'varchar(50) NOT NULL COMMENT \'登录Ip\'',
|
||||
'logintime' => 'int(10) unsigned NOT NULL COMMENT \'登录时间\'',
|
||||
'useragent' => 'varchar(255) NOT NULL COMMENT \'客户端信息\'',
|
||||
],
|
||||
'indexes' => [
|
||||
'PRIMARY KEY (`id`)',
|
||||
'KEY `uid` (`uid`)',
|
||||
'KEY `loginip` (`loginip`)',
|
||||
'KEY `logintime` (`logintime`)',
|
||||
],
|
||||
],
|
||||
'admin_menu' => [
|
||||
'comment' => '后台菜单表',
|
||||
'drop' => true,
|
||||
'fields' => [
|
||||
'id' => 'smallint(5) unsigned NOT NULL AUTO_INCREMENT',
|
||||
'pid' => 'smallint(5) unsigned NOT NULL COMMENT \'上级菜单id\'',
|
||||
'name' => 'text NOT NULL COMMENT \'菜单语言名称\'',
|
||||
'site' => 'text NOT NULL COMMENT \'项目归属\'',
|
||||
'uri' => 'varchar(255) DEFAULT NULL COMMENT \'uri字符串\'',
|
||||
'url' => 'varchar(255) DEFAULT NULL COMMENT \'外链地址\'',
|
||||
'mark' => 'varchar(255) DEFAULT NULL COMMENT \'菜单标识\'',
|
||||
'hidden' => 'tinyint(1) unsigned DEFAULT NULL COMMENT \'是否隐藏\'',
|
||||
'icon' => 'varchar(255) DEFAULT NULL COMMENT \'图标标示\'',
|
||||
'displayorder' => 'int(5) DEFAULT NULL COMMENT \'排序值\'',
|
||||
],
|
||||
'indexes' => [
|
||||
'PRIMARY KEY (`id`)',
|
||||
'KEY `list` (`pid`)',
|
||||
'KEY `displayorder` (`displayorder`)',
|
||||
'KEY `mark` (`mark`)',
|
||||
'KEY `hidden` (`hidden`)',
|
||||
'KEY `uri` (`uri`)',
|
||||
],
|
||||
],
|
||||
'admin_min_menu' => [
|
||||
'comment' => '后台简化菜单表',
|
||||
'drop' => true,
|
||||
'fields' => [
|
||||
'id' => 'smallint(5) unsigned NOT NULL AUTO_INCREMENT',
|
||||
'pid' => 'smallint(5) unsigned NOT NULL COMMENT \'上级菜单id\'',
|
||||
'name' => 'text NOT NULL COMMENT \'菜单语言名称\'',
|
||||
'site' => 'text NOT NULL COMMENT \'项目归属\'',
|
||||
'uri' => 'varchar(255) DEFAULT NULL COMMENT \'uri字符串\'',
|
||||
'url' => 'varchar(255) DEFAULT NULL COMMENT \'外链地址\'',
|
||||
'mark' => 'varchar(255) DEFAULT NULL COMMENT \'菜单标识\'',
|
||||
'hidden' => 'tinyint(1) unsigned DEFAULT NULL COMMENT \'是否隐藏\'',
|
||||
'icon' => 'varchar(255) DEFAULT NULL COMMENT \'图标标示\'',
|
||||
'displayorder' => 'int(5) DEFAULT NULL COMMENT \'排序值\'',
|
||||
],
|
||||
'indexes' => [
|
||||
'PRIMARY KEY (`id`)',
|
||||
'KEY `list` (`pid`)',
|
||||
'KEY `displayorder` (`displayorder`)',
|
||||
'KEY `mark` (`mark`)',
|
||||
'KEY `hidden` (`hidden`)',
|
||||
'KEY `uri` (`uri`)',
|
||||
],
|
||||
],
|
||||
'admin_role' => [
|
||||
'comment' => '后台角色权限表',
|
||||
'drop' => true,
|
||||
'fields' => [
|
||||
'id' => 'smallint(5) NOT NULL AUTO_INCREMENT',
|
||||
'site' => 'text NOT NULL COMMENT \'允许管理的项目,序列化数组格式\'',
|
||||
'name' => 'text NOT NULL COMMENT \'角色组语言名称\'',
|
||||
'system' => 'mediumtext NOT NULL COMMENT \'系统权限\'',
|
||||
'module' => 'mediumtext NOT NULL COMMENT \'模块权限\'',
|
||||
'application' => 'mediumtext NOT NULL COMMENT \'应用权限\'',
|
||||
],
|
||||
'indexes' => [
|
||||
'PRIMARY KEY (`id`)',
|
||||
],
|
||||
],
|
||||
'admin_role_index' => [
|
||||
'comment' => '后台角色组分配表',
|
||||
'drop' => true,
|
||||
'fields' => [
|
||||
'id' => 'smallint(5) NOT NULL AUTO_INCREMENT',
|
||||
'uid' => 'mediumint(8) unsigned DEFAULT NULL COMMENT \'会员uid\'',
|
||||
'roleid' => 'mediumint(8) unsigned DEFAULT NULL COMMENT \'角色组id\'',
|
||||
],
|
||||
'indexes' => [
|
||||
'PRIMARY KEY (`id`)',
|
||||
'KEY (`uid`)',
|
||||
'KEY (`roleid`)',
|
||||
],
|
||||
],
|
||||
'admin_setting' => [
|
||||
'comment' => '系统属性参数表',
|
||||
'drop' => true,
|
||||
'fields' => [
|
||||
'name' => 'varchar(50) NOT NULL',
|
||||
'value' => 'mediumtext NOT NULL',
|
||||
],
|
||||
'indexes' => [
|
||||
'PRIMARY KEY (`name`)',
|
||||
],
|
||||
],
|
||||
'mail_smtp' => [
|
||||
'comment' => '邮件账户表',
|
||||
'drop' => true,
|
||||
'fields' => [
|
||||
'id' => 'smallint(5) unsigned NOT NULL AUTO_INCREMENT',
|
||||
'host' => 'varchar(255) NOT NULL',
|
||||
'user' => 'varchar(255) NOT NULL',
|
||||
'pass' => 'varchar(255) NOT NULL',
|
||||
'port' => 'mediumint(8) unsigned NOT NULL',
|
||||
'displayorder' => 'smallint(5) DEFAULT NULL',
|
||||
],
|
||||
'indexes' => [
|
||||
'PRIMARY KEY (`id`)',
|
||||
'KEY (`displayorder`)',
|
||||
],
|
||||
],
|
||||
'attachment' => [
|
||||
'comment' => '附件表',
|
||||
'drop' => true,
|
||||
'fields' => [
|
||||
'id' => 'mediumint(8) unsigned NOT NULL AUTO_INCREMENT',
|
||||
'uid' => 'mediumint(8) unsigned NOT NULL COMMENT \'会员id\'',
|
||||
'author' => 'varchar(50) NOT NULL COMMENT \'会员\'',
|
||||
'siteid' => 'mediumint(5) unsigned NOT NULL COMMENT \'项目id\'',
|
||||
'related' => 'varchar(50) NOT NULL COMMENT \'相关表标识\'',
|
||||
'tableid' => 'tinyint(1) unsigned NOT NULL DEFAULT \'0\' COMMENT \'附件副表id\'',
|
||||
'download' => 'mediumint(8) NOT NULL DEFAULT \'0\' COMMENT \'无用保留\'',
|
||||
'filesize' => 'int(10) unsigned NOT NULL COMMENT \'文件大小\'',
|
||||
'fileext' => 'varchar(20) NOT NULL COMMENT \'文件扩展名\'',
|
||||
'filemd5' => 'varchar(50) NOT NULL COMMENT \'文件md5值\'',
|
||||
],
|
||||
'indexes' => [
|
||||
'PRIMARY KEY (`id`)',
|
||||
'KEY `uid` (`uid`)',
|
||||
'KEY `author` (`author`)',
|
||||
'KEY `relatedtid` (`related`)',
|
||||
'KEY `fileext` (`fileext`)',
|
||||
'KEY `filemd5` (`filemd5`)',
|
||||
'KEY `siteid` (`siteid`)',
|
||||
],
|
||||
],
|
||||
'attachment_remote' => [
|
||||
'comment' => '附件储存策略表',
|
||||
'drop' => true,
|
||||
'fields' => [
|
||||
'id' => 'tinyint(2) unsigned NOT NULL AUTO_INCREMENT',
|
||||
'type' => 'tinyint(2) NOT NULL COMMENT \'类型\'',
|
||||
'name' => 'varchar(50) NOT NULL COMMENT \'名称\'',
|
||||
'url' => 'varchar(255) NOT NULL COMMENT \'访问地址\'',
|
||||
'value' => 'text NOT NULL COMMENT \'参数值\'',
|
||||
],
|
||||
'indexes' => [
|
||||
'PRIMARY KEY (`id`)',
|
||||
],
|
||||
],
|
||||
'attachment_data' => [
|
||||
'comment' => '附件已归档表',
|
||||
'drop' => true,
|
||||
'fields' => [
|
||||
'id' => 'mediumint(8) unsigned NOT NULL COMMENT \'附件id\'',
|
||||
'uid' => 'mediumint(8) unsigned NOT NULL DEFAULT \'0\' COMMENT \'会员id\'',
|
||||
'author' => 'varchar(50) NOT NULL COMMENT \'会员\'',
|
||||
'related' => 'varchar(50) NOT NULL COMMENT \'相关表标识\'',
|
||||
'filename' => 'varchar(255) NOT NULL DEFAULT \'\' COMMENT \'原文件名\'',
|
||||
'fileext' => 'varchar(20) NOT NULL COMMENT \'文件扩展名\'',
|
||||
'filesize' => 'int(10) unsigned NOT NULL DEFAULT \'0\' COMMENT \'文件大小\'',
|
||||
'attachment' => 'varchar(255) NOT NULL DEFAULT \'\' COMMENT \'服务器路径\'',
|
||||
'remote' => 'tinyint(2) unsigned NOT NULL DEFAULT \'0\' COMMENT \'附件策略id\'',
|
||||
'attachinfo' => 'text NOT NULL COMMENT \'附件信息\'',
|
||||
'inputtime' => 'int(10) unsigned NOT NULL COMMENT \'入库时间\'',
|
||||
],
|
||||
'indexes' => [
|
||||
'PRIMARY KEY (`id`)',
|
||||
'KEY `inputtime` (`inputtime`)',
|
||||
'KEY `fileext` (`fileext`)',
|
||||
'KEY `remote` (`remote`)',
|
||||
'KEY `author` (`author`)',
|
||||
'KEY `uid` (`uid`)',
|
||||
],
|
||||
],
|
||||
'attachment_unused' => [
|
||||
'comment' => '未使用的附件表',
|
||||
'drop' => true,
|
||||
'fields' => [
|
||||
'id' => 'mediumint(8) unsigned NOT NULL COMMENT \'附件id\'',
|
||||
'uid' => 'mediumint(8) unsigned NOT NULL DEFAULT \'0\' COMMENT \'会员id\'',
|
||||
'author' => 'varchar(50) NOT NULL COMMENT \'会员\'',
|
||||
'siteid' => 'mediumint(5) unsigned NOT NULL COMMENT \'项目id\'',
|
||||
'filename' => 'varchar(255) NOT NULL DEFAULT \'\' COMMENT \'原文件名\'',
|
||||
'fileext' => 'varchar(20) NOT NULL COMMENT \'文件扩展名\'',
|
||||
'filesize' => 'int(10) unsigned NOT NULL DEFAULT \'0\' COMMENT \'文件大小\'',
|
||||
'attachment' => 'varchar(255) NOT NULL DEFAULT \'\' COMMENT \'服务器路径\'',
|
||||
'remote' => 'tinyint(2) unsigned NOT NULL DEFAULT \'0\' COMMENT \'附件策略id\'',
|
||||
'attachinfo' => 'text NOT NULL COMMENT \'附件信息\'',
|
||||
'inputtime' => 'int(10) unsigned NOT NULL COMMENT \'入库时间\'',
|
||||
],
|
||||
'indexes' => [
|
||||
'PRIMARY KEY (`id`)',
|
||||
'KEY `uid` (`uid`)',
|
||||
'KEY `inputtime` (`inputtime`)',
|
||||
'KEY `fileext` (`fileext`)',
|
||||
'KEY `remote` (`remote`)',
|
||||
'KEY `author` (`author`)',
|
||||
],
|
||||
],
|
||||
'field' => [
|
||||
'comment' => '字段表',
|
||||
'drop' => true,
|
||||
'fields' => [
|
||||
'id' => 'smallint(5) unsigned NOT NULL AUTO_INCREMENT',
|
||||
'name' => 'text NOT NULL COMMENT \'字段别名语言\'',
|
||||
'fieldname' => 'varchar(50) NOT NULL COMMENT \'字段名称\'',
|
||||
'fieldtype' => 'varchar(50) NOT NULL COMMENT \'字段类型\'',
|
||||
'relatedid' => 'smallint(5) unsigned NOT NULL COMMENT \'相关id\'',
|
||||
'relatedname' => 'varchar(50) NOT NULL COMMENT \'相关表\'',
|
||||
'isedit' => 'tinyint(1) unsigned NOT NULL DEFAULT \'1\' COMMENT \'是否可修改\'',
|
||||
'ismain' => 'tinyint(1) unsigned NOT NULL COMMENT \'是否主表\'',
|
||||
'issystem' => 'tinyint(1) unsigned NOT NULL COMMENT \'是否系统表\'',
|
||||
'ismember' => 'tinyint(1) unsigned NOT NULL COMMENT \'是否会员可见\'',
|
||||
'issearch' => 'tinyint(1) unsigned NOT NULL DEFAULT \'1\' COMMENT \'是否可搜索\'',
|
||||
'disabled' => 'tinyint(1) unsigned NOT NULL COMMENT \'禁用?\'',
|
||||
'setting' => 'mediumtext NOT NULL COMMENT \'配置信息\'',
|
||||
'displayorder' => 'int(5) NOT NULL COMMENT \'排序\'',
|
||||
],
|
||||
'indexes' => [
|
||||
'PRIMARY KEY (`id`)',
|
||||
'KEY `list` (`relatedid`,`disabled`,`issystem`)',
|
||||
],
|
||||
],
|
||||
'linkage' => [
|
||||
'comment' => '联动菜单表',
|
||||
'drop' => true,
|
||||
'fields' => [
|
||||
'id' => 'smallint(5) unsigned NOT NULL AUTO_INCREMENT',
|
||||
'name' => 'varchar(255) NOT NULL COMMENT \'菜单名称\'',
|
||||
'type' => 'tinyint(1) unsigned NOT NULL',
|
||||
'code' => 'char(20) NOT NULL',
|
||||
],
|
||||
'indexes' => [
|
||||
'PRIMARY KEY (`id`)',
|
||||
'UNIQUE KEY `code` (`code`)',
|
||||
'KEY `module` (`id`)',
|
||||
],
|
||||
],
|
||||
'linkage_data_1' => [
|
||||
'comment' => '联动菜单数据表',
|
||||
'drop' => true,
|
||||
'fields' => [
|
||||
'id' => 'mediumint(8) unsigned NOT NULL AUTO_INCREMENT',
|
||||
'site' => 'mediumint(5) unsigned NOT NULL COMMENT \'项目id\'',
|
||||
'pid' => 'mediumint(8) unsigned NOT NULL DEFAULT \'0\' COMMENT \'上级id\'',
|
||||
'pids' => 'varchar(255) DEFAULT NULL COMMENT \'所有上级id\'',
|
||||
'name' => 'varchar(30) NOT NULL COMMENT \'栏目名称\'',
|
||||
'cname' => 'varchar(30) NOT NULL COMMENT \'别名\'',
|
||||
'child' => 'tinyint(1) unsigned DEFAULT \'0\' COMMENT \'是否有下级\'',
|
||||
'hidden' => 'tinyint(1) unsigned DEFAULT \'0\' COMMENT \'前端隐藏\'',
|
||||
'childids' => 'text DEFAULT NULL COMMENT \'下级所有id\'',
|
||||
'displayorder' => 'mediumint(8) DEFAULT \'0\'',
|
||||
],
|
||||
'indexes' => [
|
||||
'PRIMARY KEY (`id`)',
|
||||
'KEY `cname` (`cname`)',
|
||||
'KEY `hidden` (`hidden`)',
|
||||
'KEY `list` (`site`,`displayorder`)',
|
||||
],
|
||||
],
|
||||
'site' => [
|
||||
'comment' => '项目表',
|
||||
'drop' => true,
|
||||
'fields' => [
|
||||
'id' => 'smallint(5) unsigned NOT NULL AUTO_INCREMENT',
|
||||
'name' => 'varchar(255) NOT NULL COMMENT \'项目名称\'',
|
||||
'domain' => 'varchar(50) NOT NULL COMMENT \'项目域名\'',
|
||||
'setting' => 'mediumtext NOT NULL COMMENT \'项目配置\'',
|
||||
'disabled' => 'tinyint(1) NOT NULL DEFAULT \'0\' COMMENT \'禁用\'',
|
||||
'displayorder' => 'smallint(5) DEFAULT \'0\' COMMENT \'排序\'',
|
||||
],
|
||||
'indexes' => [
|
||||
'PRIMARY KEY (`id`)',
|
||||
'KEY `disabled` (`disabled`)',
|
||||
'KEY `displayorder` (`displayorder`)',
|
||||
],
|
||||
],
|
||||
'member' => [
|
||||
'comment' => '会员表',
|
||||
'drop' => true,
|
||||
'fields' => [
|
||||
'id' => 'int(10) unsigned NOT NULL AUTO_INCREMENT',
|
||||
'email' => 'varchar(50) NOT NULL DEFAULT \'\' COMMENT \'邮箱地址\'',
|
||||
'phone' => 'varchar(20) NOT NULL COMMENT \'手机号码\'',
|
||||
'username' => 'varchar(50) NOT NULL DEFAULT \'\' COMMENT \'用户名\'',
|
||||
'password' => 'varchar(50) NOT NULL DEFAULT \'\' COMMENT \'加密密码\'',
|
||||
'login_attr' => 'varchar(100) NOT NULL DEFAULT \'\' COMMENT \'登录附加验证字符\'',
|
||||
'salt' => 'varchar(50) NOT NULL COMMENT \'随机加密码\'',
|
||||
'name' => 'varchar(50) NOT NULL COMMENT \'姓名\'',
|
||||
'money' => 'decimal(10,2) unsigned NOT NULL COMMENT \'RMB\'',
|
||||
'freeze' => 'decimal(10,2) unsigned NOT NULL COMMENT \'冻结RMB\'',
|
||||
'spend' => 'decimal(10,2) unsigned NOT NULL COMMENT \'消费RMB总额\'',
|
||||
'score' => 'int(10) unsigned NOT NULL COMMENT \'积分\'',
|
||||
'experience' => 'int(10) unsigned NOT NULL COMMENT \'经验值\'',
|
||||
'regip' => 'varchar(200) NOT NULL COMMENT \'注册ip\'',
|
||||
'regtime' => 'int(10) unsigned NOT NULL COMMENT \'注册时间\'',
|
||||
'randcode' => 'mediumint(6) unsigned NOT NULL COMMENT \'随机验证码\'',
|
||||
],
|
||||
'indexes' => [
|
||||
'PRIMARY KEY (`id`)',
|
||||
'KEY `username` (`username`)',
|
||||
'KEY `email` (`email`)',
|
||||
'KEY `phone` (`phone`)',
|
||||
],
|
||||
],
|
||||
'member_data' => [
|
||||
'comment' => '会员表',
|
||||
'drop' => true,
|
||||
'fields' => [
|
||||
'id' => 'int(10) unsigned NOT NULL AUTO_INCREMENT',
|
||||
'is_admin' => 'tinyint(1) unsigned DEFAULT 0 COMMENT \'是否是管理员\'',
|
||||
'is_lock' => 'tinyint(1) unsigned DEFAULT 0 COMMENT \'账号锁定标识\'',
|
||||
'is_verify' => 'tinyint(1) unsigned DEFAULT 0 COMMENT \'审核标识\'',
|
||||
'is_mobile' => 'tinyint(1) unsigned DEFAULT 0 COMMENT \'手机认证标识\'',
|
||||
'is_email' => 'tinyint(1) unsigned DEFAULT 0 COMMENT \'邮箱认证标识\'',
|
||||
'is_avatar' => 'tinyint(1) unsigned DEFAULT 0 COMMENT \'头像上传标识\'',
|
||||
'is_complete' => 'tinyint(1) unsigned DEFAULT 0 COMMENT \'完善资料标识\'',
|
||||
],
|
||||
'indexes' => [
|
||||
'PRIMARY KEY (`id`)',
|
||||
],
|
||||
],
|
||||
],
|
||||
'seeds' => [
|
||||
[
|
||||
'table' => 'admin_role',
|
||||
'data' => [
|
||||
'id' => 1,
|
||||
'site' => '',
|
||||
'name' => '超级管理员',
|
||||
'system' => '',
|
||||
'module' => '',
|
||||
'application' => '',
|
||||
],
|
||||
],
|
||||
[
|
||||
'table' => 'admin_role',
|
||||
'data' => [
|
||||
'id' => 2,
|
||||
'site' => '',
|
||||
'name' => '编辑员',
|
||||
'system' => '',
|
||||
'module' => '',
|
||||
'application' => '',
|
||||
],
|
||||
],
|
||||
[
|
||||
'table' => 'linkage',
|
||||
'data' => [
|
||||
'id' => 1,
|
||||
'name' => '中国地区',
|
||||
'type' => 0,
|
||||
'code' => 'address',
|
||||
],
|
||||
],
|
||||
[
|
||||
'table' => 'linkage_data_1',
|
||||
'data' => [
|
||||
'id' => 1,
|
||||
'site' => 1,
|
||||
'pid' => 0,
|
||||
'pids' => 0,
|
||||
'name' => '北京',
|
||||
'cname' => 'bj',
|
||||
'child' => 0,
|
||||
'hidden' => 0,
|
||||
'childids' => 1,
|
||||
'displayorder' => 0,
|
||||
],
|
||||
],
|
||||
[
|
||||
'table' => 'linkage_data_1',
|
||||
'data' => [
|
||||
'id' => 2,
|
||||
'site' => 1,
|
||||
'pid' => 0,
|
||||
'pids' => 0,
|
||||
'name' => '成都',
|
||||
'cname' => 'cd',
|
||||
'child' => 0,
|
||||
'hidden' => 0,
|
||||
'childids' => 2,
|
||||
'displayorder' => 0,
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
@@ -0,0 +1,284 @@
|
||||
<?php
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
/**
|
||||
* 菜单配置
|
||||
*/
|
||||
|
||||
|
||||
return [
|
||||
|
||||
'admin' => [
|
||||
|
||||
'home' => [
|
||||
'name' => '首页',
|
||||
'icon' => 'fa fa-home',
|
||||
'displayorder' => '-2',
|
||||
'left' => [
|
||||
'home-my' => [
|
||||
'name' => '我的面板',
|
||||
'icon' => 'fa fa-home',
|
||||
'link' => [
|
||||
[
|
||||
'name' => '后台首页',
|
||||
'icon' => 'fa fa-home',
|
||||
'uri' => 'home/main',
|
||||
],
|
||||
[
|
||||
'name' => '资料修改',
|
||||
'icon' => 'fa fa-user',
|
||||
'uri' => 'api/my',
|
||||
],
|
||||
[
|
||||
'name' => '系统更新',
|
||||
'icon' => 'fa fa-refresh',
|
||||
'uri' => 'cache/index',
|
||||
],
|
||||
[
|
||||
'name' => '应用市场',
|
||||
'icon' => 'fa fa-puzzle-piece',
|
||||
'uri' => 'api/app',
|
||||
],
|
||||
]
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
'system' => [
|
||||
'name' => '系统',
|
||||
'icon' => 'fa fa-globe',
|
||||
'displayorder' => '-2',
|
||||
'left' => [
|
||||
'system-wh' => [
|
||||
'name' => '系统维护',
|
||||
'icon' => 'fa fa-cog',
|
||||
'link' => [
|
||||
[
|
||||
'name' => '系统参数',
|
||||
'icon' => 'fa fa-cog',
|
||||
'uri' => 'system/index',
|
||||
],
|
||||
[
|
||||
'name' => '系统缓存',
|
||||
'icon' => 'fa fa-clock-o',
|
||||
'uri' => 'system_cache/index',
|
||||
],
|
||||
[
|
||||
'name' => '附件设置',
|
||||
'icon' => 'fa fa-folder',
|
||||
'uri' => 'attachment/index',
|
||||
],
|
||||
[
|
||||
'name' => '存储策略',
|
||||
'icon' => 'fa fa-cloud',
|
||||
'uri' => 'attachment/remote_index',
|
||||
],
|
||||
[
|
||||
'name' => '短信设置',
|
||||
'icon' => 'fa fa-envelope',
|
||||
'uri' => 'sms/index',
|
||||
],
|
||||
[
|
||||
'name' => '邮件设置',
|
||||
'icon' => 'fa fa-envelope-open',
|
||||
'uri' => 'email/index',
|
||||
],
|
||||
[
|
||||
'name' => '系统提醒',
|
||||
'icon' => 'fa fa-bell',
|
||||
'uri' => 'notice/index',
|
||||
],
|
||||
[
|
||||
'name' => '系统体检',
|
||||
'icon' => 'fa fa-wrench',
|
||||
'uri' => 'check/index',
|
||||
],
|
||||
]
|
||||
],
|
||||
'auth-admin' => [
|
||||
'name' => '后台权限',
|
||||
'icon' => 'fa fa-user-circle',
|
||||
'link' => [
|
||||
[
|
||||
'name' => '后台菜单',
|
||||
'icon' => 'fa fa-list-alt',
|
||||
'uri' => 'menu/index',
|
||||
],
|
||||
[
|
||||
'name' => '简化菜单',
|
||||
'icon' => 'fa fa-list',
|
||||
'uri' => 'min_menu/index',
|
||||
],
|
||||
[
|
||||
'name' => '角色权限',
|
||||
'icon' => 'fa fa-users',
|
||||
'uri' => 'role/index',
|
||||
],
|
||||
[
|
||||
'name' => '角色账号',
|
||||
'icon' => 'fa fa-user',
|
||||
'uri' => 'root/index',
|
||||
],
|
||||
]
|
||||
],
|
||||
'system-log' => [
|
||||
'name' => '日志管理',
|
||||
'icon' => 'fa fa-calendar',
|
||||
'link' => [
|
||||
[
|
||||
'name' => '系统日志',
|
||||
'icon' => 'fa fa-shield',
|
||||
'uri' => 'error/index',
|
||||
],
|
||||
[
|
||||
'name' => '操作记录',
|
||||
'icon' => 'fa fa-calendar',
|
||||
'uri' => 'system_log/index',
|
||||
],
|
||||
[
|
||||
'name' => '密码错误',
|
||||
'icon' => 'fa fa-unlock-alt',
|
||||
'uri' => 'password_log/index',
|
||||
],
|
||||
[
|
||||
'name' => '短信错误',
|
||||
'icon' => 'fa fa-envelope',
|
||||
'uri' => 'sms_log/index',
|
||||
],
|
||||
[
|
||||
'name' => '邮件错误',
|
||||
'icon' => 'fa fa-envelope-open',
|
||||
'uri' => 'email_log/index',
|
||||
],
|
||||
[
|
||||
'name' => '慢查询日志',
|
||||
'icon' => 'fa fa-database',
|
||||
'uri' => 'sql_log/index',
|
||||
],
|
||||
]
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
|
||||
'app' => [
|
||||
'name' => '应用',
|
||||
'icon' => 'fa fa-puzzle-piece',
|
||||
'left' => [
|
||||
'app-plugin' => [
|
||||
'name' => '应用插件',
|
||||
'icon' => 'fa fa-puzzle-piece',
|
||||
'link' => [
|
||||
[
|
||||
'name' => '应用管理',
|
||||
'icon' => 'fa fa-folder',
|
||||
'uri' => 'cloud/local',
|
||||
],
|
||||
[
|
||||
'name' => '联动菜单',
|
||||
'icon' => 'fa fa-columns',
|
||||
'uri' => 'linkage/index',
|
||||
],
|
||||
[
|
||||
'name' => '任务队列',
|
||||
'icon' => 'fa fa-indent',
|
||||
'uri' => 'cron/index',
|
||||
],
|
||||
[
|
||||
'name' => '附件管理',
|
||||
'icon' => 'fa fa-folder',
|
||||
'uri' => 'attachments/index',
|
||||
],
|
||||
]
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
'cloud' => [
|
||||
'name' => '服务',
|
||||
'icon' => 'fa fa-cloud',
|
||||
'displayorder' => 99,
|
||||
'left' => [
|
||||
'cloud-dayrui' => [
|
||||
'name' => '项目服务',
|
||||
'icon' => 'fa fa-cloud',
|
||||
'link' => [
|
||||
[
|
||||
'name' => '我的项目',
|
||||
'icon' => 'fa fa-cog',
|
||||
'uri' => 'cloud/index',
|
||||
],
|
||||
[
|
||||
'name' => '服务工单',
|
||||
'icon' => 'fa fa-user-md',
|
||||
'uri' => 'cloud/service',
|
||||
],
|
||||
[
|
||||
'name' => '应用商城',
|
||||
'icon' => 'fa fa-puzzle-piece',
|
||||
'uri' => 'cloud/app',
|
||||
],
|
||||
[
|
||||
'name' => '模板商城',
|
||||
'icon' => 'fa fa-html5',
|
||||
'uri' => 'cloud/template',
|
||||
],
|
||||
[
|
||||
'name' => '版本升级',
|
||||
'icon' => 'fa fa-refresh',
|
||||
'uri' => 'cloud/update',
|
||||
],
|
||||
]
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
|
||||
'admin_min' => [
|
||||
|
||||
'home' => [
|
||||
'name' => '我的面板',
|
||||
'icon' => 'fa fa-home',
|
||||
'link' => [
|
||||
[
|
||||
'name' => '后台首页',
|
||||
'icon' => 'fa fa-home',
|
||||
'uri' => 'home/main',
|
||||
],
|
||||
[
|
||||
'name' => '资料修改',
|
||||
'icon' => 'fa fa-user',
|
||||
'uri' => 'api/my',
|
||||
],
|
||||
]
|
||||
],
|
||||
|
||||
|
||||
|
||||
'app-plugin' => [
|
||||
'name' => '应用插件',
|
||||
'icon' => 'fa fa-puzzle-piece',
|
||||
'link' => [
|
||||
[
|
||||
'name' => '联动菜单',
|
||||
'icon' => 'fa fa-columns',
|
||||
'uri' => 'linkage/index',
|
||||
],
|
||||
[
|
||||
'name' => '附件管理',
|
||||
'icon' => 'fa fa-folder',
|
||||
'uri' => 'attachments/index',
|
||||
],
|
||||
]
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
|
||||
];
|
||||
@@ -0,0 +1,4 @@
|
||||
<?php
|
||||
|
||||
// CI路由识别定向文件 兼容老版本
|
||||
require FRAMEPATH.'Config/Routes.php';
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,289 @@
|
||||
<?php namespace Phpcmf\Control\Admin;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
class Attachment extends \Phpcmf\Common {
|
||||
|
||||
public $type;
|
||||
public $path;
|
||||
public $load_file;
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
$this->type = [
|
||||
0 => [
|
||||
'name' => dr_lang('本地磁盘'),
|
||||
],
|
||||
];
|
||||
$this->path = FCPATH.'ThirdParty/Storage/';
|
||||
$local = dr_dir_map($this->path, 1);
|
||||
$this->load_file = [];
|
||||
foreach ($local as $dir) {
|
||||
if (is_file($this->path.$dir.'/App.php')) {
|
||||
$cfg = require $this->path.$dir.'/App.php';
|
||||
if ($cfg['id']) {
|
||||
$this->load_file[] = $this->path.$dir.'/Config.html';
|
||||
$this->type[$cfg['id']] = $cfg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function index() {
|
||||
|
||||
$data = is_file(WRITEPATH.'config/system.php') ? require WRITEPATH.'config/system.php' : [];
|
||||
|
||||
if (IS_AJAX_POST) {
|
||||
$post = \Phpcmf\Service::L('input')->post('data');
|
||||
$image = \Phpcmf\Service::L('input')->post('image');
|
||||
$save = [
|
||||
'SYS_ATTACHMENT_SAFE' => (int)$post['SYS_ATTACHMENT_SAFE'],
|
||||
'SYS_ATTACHMENT_GUEST' => (int)$post['SYS_ATTACHMENT_GUEST'],
|
||||
'SYS_ATTACHMENT_CF' => (int)$post['SYS_ATTACHMENT_CF'],
|
||||
'SYS_ATTACHMENT_REL' => (int)$post['SYS_ATTACHMENT_REL'],
|
||||
'SYS_ATTACHMENT_DB' => (int)$post['SYS_ATTACHMENT_DB'],
|
||||
'SYS_ATTACHMENT_PAGESIZE' => (int)$post['SYS_ATTACHMENT_PAGESIZE'],
|
||||
'SYS_ATTACHMENT_URL' => $post['SYS_ATTACHMENT_URL'],
|
||||
'SYS_ATTACHMENT_PATH' => addslashes($post['SYS_ATTACHMENT_PATH']),
|
||||
'SYS_ATTACHMENT_SAVE_TYPE' => intval($post['SYS_ATTACHMENT_SAVE_TYPE']),
|
||||
'SYS_ATTACHMENT_DOWN_REMOTE' => intval($post['SYS_ATTACHMENT_DOWN_REMOTE']),
|
||||
'SYS_ATTACHMENT_DOWN_SIZE' => intval($post['SYS_ATTACHMENT_DOWN_SIZE']),
|
||||
'SYS_ATTACHMENT_SAVE_DIR' => addslashes($post['SYS_ATTACHMENT_SAVE_DIR']),
|
||||
'SYS_ATTACHMENT_SAVE_ID' => intval($post['SYS_ATTACHMENT_SAVE_ID']),
|
||||
'SYS_AVATAR_URL' => $image['avatar_url'],
|
||||
'SYS_AVATAR_PATH' => addslashes($image['avatar_path']),
|
||||
];
|
||||
if ($image['cache_path']) {
|
||||
if ($save['SYS_ATTACHMENT_PATH'] && $image['cache_path'] == $save['SYS_ATTACHMENT_PATH']) {
|
||||
$this->_json(0, dr_lang('附件上传目录不能与缩略图存储目录相同'));
|
||||
} elseif ($save['SYS_AVATAR_PATH'] && $image['cache_path'] == $save['SYS_AVATAR_PATH']) {
|
||||
$this->_json(0, dr_lang('头像存储目录不能与缩略图存储目录相同'));
|
||||
}
|
||||
}
|
||||
$save['cache_path'] = $image['cache_path'];
|
||||
foreach (['SYS_ATTACHMENT_PATH' => '附件上传', 'SYS_AVATAR_PATH' => '头像上传', 'cache_path' => '缩略图上传'] as $key => $name) {
|
||||
if (isset($save[$key]) && $save[$key] &&
|
||||
(strpos($save[$key], 'config') !== false || strpos($save[$key], CONFIGPATH) !== false)) {
|
||||
$this->_json(0, dr_lang('%s目录不能包含config目录', $name));
|
||||
}
|
||||
}
|
||||
unset($save['cache_path']);
|
||||
\Phpcmf\Service::M('System')->save_config($data, $save);
|
||||
unset($image['avatar_url'], $image['avatar_path']);
|
||||
|
||||
|
||||
// 图片参数
|
||||
|
||||
\Phpcmf\Service::M('Site')->config(
|
||||
SITE_ID,
|
||||
'watermark',
|
||||
\Phpcmf\Service::L('input')->post('watermark')
|
||||
);
|
||||
|
||||
$image = \Phpcmf\Service::L('input')->post('image');
|
||||
unset($image['avatar_url'], $image['avatar_path']);
|
||||
\Phpcmf\Service::M('site')->config(SITE_ID, 'image', $image);
|
||||
|
||||
|
||||
\Phpcmf\Service::L('input')->system_log('设置附件参数');
|
||||
// 自动更新缓存
|
||||
\Phpcmf\Service::M('cache')->sync_cache('');
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
|
||||
$page = intval(\Phpcmf\Service::L('input')->get('page'));
|
||||
|
||||
$site = \Phpcmf\Service::M('Site')->config(SITE_ID);
|
||||
|
||||
$locate = [
|
||||
|
||||
'left-top' => '左上',
|
||||
'center-top' => '中上',
|
||||
'right-top' => '右上',
|
||||
|
||||
'left-middle' => '左中',
|
||||
'center-middle' => '正中',
|
||||
'right-middle' => '右中',
|
||||
|
||||
'left-bottom' => '左下',
|
||||
'center-bottom' => '中下',
|
||||
'right-bottom' => '右下',
|
||||
|
||||
];
|
||||
|
||||
$image = $site['image'];
|
||||
$image['avatar_url'] = defined('SYS_AVATAR_URL') ? SYS_AVATAR_URL : '';
|
||||
$image['avatar_path'] = defined('SYS_AVATAR_PATH') ? SYS_AVATAR_PATH : '';
|
||||
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'page' => $page,
|
||||
'data' => $data,
|
||||
'form' => dr_form_hidden(['page' => $page]),
|
||||
'menu' => \Phpcmf\Service::M('auth')->_admin_menu(
|
||||
[
|
||||
'附件设置' => [\Phpcmf\Service::L('Router')->class.'/index', 'fa fa-folder'],
|
||||
'存储策略' => [\Phpcmf\Service::L('Router')->class.'/remote_index', 'fa fa-cloud'],
|
||||
'help' => [359],
|
||||
]
|
||||
),
|
||||
|
||||
'image' => $image,
|
||||
'locate' => $locate,
|
||||
'waterfile' => dr_file_map(WRITEPATH.'watermark/', 1),
|
||||
'watermark' => $site['watermark'],
|
||||
|
||||
'remote' => \Phpcmf\Service::C()->get_cache('attachment'),
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('attachment_index.html');
|
||||
}
|
||||
|
||||
public function remote_index() {
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'list' => \Phpcmf\Service::M()->table('attachment_remote')->getAll(),
|
||||
'menu' => \Phpcmf\Service::M('auth')->_admin_menu(
|
||||
[
|
||||
'附件设置' => [\Phpcmf\Service::L('Router')->class.'/index', 'fa fa-folder'],
|
||||
'存储策略' => [\Phpcmf\Service::L('Router')->class.'/remote_index', 'fa fa-cloud'],
|
||||
'添加' => [\Phpcmf\Service::L('Router')->class.'/add', 'fa fa-plus'],
|
||||
'help' => [88],
|
||||
]
|
||||
),
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('attachment_remote.html');
|
||||
}
|
||||
|
||||
public function add() {
|
||||
|
||||
if (IS_AJAX_POST) {
|
||||
$data = \Phpcmf\Service::L('input')->post('data', true);
|
||||
$rt = \Phpcmf\Service::M()->table('attachment_remote')->insert([
|
||||
'type' => intval($data['type']),
|
||||
'name' => (string)$data['name'],
|
||||
'url' => trim((string)$data['url']),
|
||||
'value' => dr_array2string($data['value']),
|
||||
]);
|
||||
if (!$rt['code']) {
|
||||
$this->_json(0, $rt['msg']);
|
||||
}
|
||||
// 自动更新缓存
|
||||
\Phpcmf\Service::M('cache')->sync_cache('attachment');
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'form' => dr_form_hidden(),
|
||||
'menu' => \Phpcmf\Service::M('auth')->_admin_menu(
|
||||
[
|
||||
'附件设置' => [\Phpcmf\Service::L('Router')->class.'/index', 'fa fa-folder'],
|
||||
'存储策略' => [\Phpcmf\Service::L('Router')->class.'/remote_index', 'fa fa-cloud'],
|
||||
'添加' => [\Phpcmf\Service::L('Router')->class.'/add', 'fa fa-plus'],
|
||||
'help' => [88],
|
||||
]
|
||||
),
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('attachment_add.html');
|
||||
}
|
||||
|
||||
public function edit() {
|
||||
|
||||
$id = intval($_GET['id']);
|
||||
|
||||
if (IS_AJAX_POST) {
|
||||
$data = \Phpcmf\Service::L('input')->post('data', true);
|
||||
$rt = \Phpcmf\Service::M()->table('attachment_remote')->update($id,
|
||||
[
|
||||
'type' => intval($data['type']),
|
||||
'name' => (string)$data['name'],
|
||||
'url' => trim((string)$data['url']),
|
||||
'value' => dr_array2string($data['value']),
|
||||
]
|
||||
);
|
||||
if (!$rt['code']) {
|
||||
$this->_json(0, $rt['msg']);
|
||||
}
|
||||
// 自动更新缓存
|
||||
\Phpcmf\Service::M('cache')->sync_cache('attachment');
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
|
||||
$data = \Phpcmf\Service::M()->table('attachment_remote')->get($id);
|
||||
$data['value'] = dr_string2array($data['value']);
|
||||
$data['value'] = $data['value'][intval($data['type'])];
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'data' => $data,
|
||||
'form' => dr_form_hidden(),
|
||||
'menu' => \Phpcmf\Service::M('auth')->_admin_menu(
|
||||
[
|
||||
'附件设置' => [\Phpcmf\Service::L('Router')->class.'/index', 'fa fa-folder'],
|
||||
'存储策略' => [\Phpcmf\Service::L('Router')->class.'/remote_index', 'fa fa-cloud'],
|
||||
'添加' => [\Phpcmf\Service::L('Router')->class.'/add', 'fa fa-plus'],
|
||||
'修改' => ['hide:'.\Phpcmf\Service::L('Router')->class.'/edit', 'fa fa-edit'],
|
||||
'help' => [88],
|
||||
]
|
||||
),
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('attachment_add.html');
|
||||
}
|
||||
|
||||
public function del() {
|
||||
|
||||
$ids = \Phpcmf\Service::L('input')->get_post_ids();
|
||||
if (!$ids) {
|
||||
$this->_json(0, dr_lang('你还没有选择呢'));
|
||||
}
|
||||
|
||||
\Phpcmf\Service::M()->table('attachment_remote')->deleteAll($ids);
|
||||
\Phpcmf\Service::L('input')->system_log('批量删除远程附件策略: '. implode(',', $ids));
|
||||
|
||||
// 自动更新缓存
|
||||
\Phpcmf\Service::M('cache')->sync_cache('attachment');
|
||||
|
||||
$this->_json(1, dr_lang('操作成功'), ['ids' => $ids]);
|
||||
}
|
||||
|
||||
// 上传字体文件或图片
|
||||
public function upload_index() {
|
||||
|
||||
$at = dr_safe_filename($_GET['at']);
|
||||
if ($at == 'font') {
|
||||
$rt = \Phpcmf\Service::L('upload')->upload_file([
|
||||
'save_name' => 'null',
|
||||
'save_path' => WRITEPATH.'watermark/',
|
||||
'form_name' => 'file_data',
|
||||
'file_exts' => ['ttf'],
|
||||
'file_size' => 50 * 1024 * 1024,
|
||||
'attachment' => [
|
||||
'value' => [
|
||||
'path' => 'null'
|
||||
]
|
||||
],
|
||||
]);
|
||||
} else {
|
||||
$rt = \Phpcmf\Service::L('upload')->upload_file([
|
||||
'save_name' => 'null',
|
||||
'save_path' => WRITEPATH.'watermark/',
|
||||
'form_name' => 'file_data',
|
||||
'file_exts' => ['png', 'jpg', 'jpeg'],
|
||||
'file_size' => 10 * 1024 * 1024,
|
||||
'attachment' => [
|
||||
'value' => [
|
||||
'path' => 'null'
|
||||
]
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
if (!$rt['code']) {
|
||||
exit(dr_array2string($rt));
|
||||
}
|
||||
|
||||
$this->_json(1, dr_lang('上传成功'));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,782 @@
|
||||
<?php namespace Phpcmf\Control\Admin;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
// 附件
|
||||
class Attachments extends \Phpcmf\Table {
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'menu' => \Phpcmf\Service::M('auth')->_admin_menu(
|
||||
[
|
||||
'附件管理' => [\Phpcmf\Service::L('Router')->class.'/index', 'fa fa-folder'],
|
||||
'已归档的附件' => [\Phpcmf\Service::L('Router')->class.'/db_index', 'fa fa-folder'],
|
||||
'未归档的附件' => [\Phpcmf\Service::L('Router')->class.'/unused_index', 'fa fa-folder-o'],
|
||||
'变更储存策略' => ['add:'.\Phpcmf\Service::L('Router')->class.'/remote_edit', 'fa fa-edit', '500px', '400px'],
|
||||
'help' => [356],
|
||||
]
|
||||
)
|
||||
]);
|
||||
}
|
||||
|
||||
// 附件目录(资源管理器)
|
||||
public function index() {
|
||||
|
||||
$rel = $this->_dir_rel_path(\Phpcmf\Service::L('input')->get('path'));
|
||||
$listing = $this->_dir_listing($rel);
|
||||
if ($listing === null) {
|
||||
$rel = '';
|
||||
$listing = $this->_dir_listing($rel);
|
||||
}
|
||||
|
||||
$p = [
|
||||
'size' => 9999,
|
||||
'exts' => '*',
|
||||
'count' => 20,
|
||||
'attachment' => 0,
|
||||
'image_reduce' => 0,
|
||||
'chunk' => 10 * 1024 * 1024,
|
||||
];
|
||||
$upload = [
|
||||
'url' => dr_web_prefix(SELF.'?c='.\Phpcmf\Service::L('Router')->class.'&m=dir_upload')
|
||||
.'&siteid='.SITE_ID,
|
||||
'param' => $p,
|
||||
];
|
||||
|
||||
$uriprefix = trim(APP_DIR.'/'.\Phpcmf\Service::L('Router')->class, '/');
|
||||
$parent_rel = '';
|
||||
if ($listing['rel'] !== '') {
|
||||
$norm = str_replace('\\', '/', $listing['rel']);
|
||||
$d = dirname($norm);
|
||||
$parent_rel = ($d === '.' || $d === '') ? '' : str_replace('\\', '/', $d);
|
||||
}
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'dir' => IS_DEV ? SYS_UPLOAD_PATH : dr_safe_replace_path(SYS_UPLOAD_PATH),
|
||||
'url' => SYS_UPLOAD_URL,
|
||||
'rel' => $listing['rel'],
|
||||
'parent_rel' => $parent_rel,
|
||||
'dirs' => $listing['dirs'],
|
||||
'files' => $listing['files'],
|
||||
'breadcrumb' => $this->_dir_breadcrumb($listing['rel']),
|
||||
'upload' => $upload,
|
||||
'uriprefix' => $uriprefix,
|
||||
'dir_delete_url' => dr_url($uriprefix.'/dir_delete'),
|
||||
'dir_mkdir_url' => dr_url($uriprefix.'/dir_mkdir'),
|
||||
'dir_replace_url' => dr_url($uriprefix.'/dir_replace'),
|
||||
'dir_folder_size_url' => dr_url($uriprefix.'/dir_folder_size'),
|
||||
'dir_js' => [
|
||||
'confirm_del' => addslashes(dr_lang('你确定要删除它们吗?')),
|
||||
'mkdir_title' => addslashes(dr_lang('新建文件夹')),
|
||||
'name_empty' => addslashes(dr_lang('名称不能为空')),
|
||||
'upload_fail' => addslashes(dr_lang('上传失败')),
|
||||
],
|
||||
'meta_title' => dr_lang('附件目录'),
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('attachment_dir.html');
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX:递归统计文件夹及子目录文件总大小
|
||||
*/
|
||||
public function dir_folder_size() {
|
||||
|
||||
if (function_exists('set_time_limit')) {
|
||||
@set_time_limit(300);
|
||||
}
|
||||
|
||||
$rel = $this->_dir_rel_path(\Phpcmf\Service::L('input')->get('path'));
|
||||
if ($rel === '') {
|
||||
$this->_json(0, dr_lang('参数错误'));
|
||||
}
|
||||
|
||||
list($ok, $abs, $r) = $this->_dir_safe($rel);
|
||||
if (!$ok || !is_dir($abs)) {
|
||||
$this->_json(0, dr_lang('目录不存在'));
|
||||
}
|
||||
|
||||
$root = rtrim(str_replace(['/', '\\'], DIRECTORY_SEPARATOR, SYS_UPLOAD_PATH), DIRECTORY_SEPARATOR);
|
||||
$rootReal = realpath($root);
|
||||
if ($rootReal === false) {
|
||||
$this->_json(0, dr_lang('目录无效或不存在'));
|
||||
}
|
||||
|
||||
$bytes = $this->_dir_tree_size($abs, $rootReal);
|
||||
$this->_json(1, 'ok', [
|
||||
'size' => $bytes,
|
||||
'size_text' => dr_format_file_size($bytes),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归统计目录下所有文件字节(不跟随符号链接)
|
||||
*/
|
||||
protected function _dir_tree_size($absDir, $rootReal) {
|
||||
|
||||
$total = 0;
|
||||
if (!is_dir($absDir)) {
|
||||
return 0;
|
||||
}
|
||||
$absDir = rtrim($absDir, DIRECTORY_SEPARATOR);
|
||||
if (is_link($absDir)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ($fp = @opendir($absDir)) {
|
||||
while (($name = readdir($fp)) !== false) {
|
||||
if ($name === '.' || $name === '..') {
|
||||
continue;
|
||||
}
|
||||
$sub = $absDir.DIRECTORY_SEPARATOR.$name;
|
||||
if (is_link($sub)) {
|
||||
continue;
|
||||
}
|
||||
if (is_file($sub)) {
|
||||
$sz = @filesize($sub);
|
||||
if ($sz !== false) {
|
||||
$total += $sz;
|
||||
}
|
||||
} elseif (is_dir($sub)) {
|
||||
$rp = realpath($sub);
|
||||
if ($rp !== false && $this->_dir_under_root($rootReal, $rp)) {
|
||||
$total += $this->_dir_tree_size($rp, $rootReal);
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir($fp);
|
||||
}
|
||||
|
||||
return $total;
|
||||
}
|
||||
|
||||
/**
|
||||
* 附件目录内上传(写入当前文件夹,并走附件归档)
|
||||
*/
|
||||
public function dir_upload() {
|
||||
|
||||
if (!IS_POST) {
|
||||
$this->_json(0, dr_lang('请求错误'));
|
||||
}
|
||||
|
||||
$rel = $this->_dir_rel_path(\Phpcmf\Service::L('input')->post('path'));
|
||||
list($ok, $abs, $r) = $this->_dir_safe($rel);
|
||||
if (!$ok || !is_dir($abs)) {
|
||||
$this->_json(0, dr_lang('目录无效或不存在'));
|
||||
}
|
||||
|
||||
$cfg = [
|
||||
'form_name' => 'file_data',
|
||||
'file_exts' => ['*'],
|
||||
'file_size' => 9999 * 1024 * 1024,
|
||||
'attachment' => \Phpcmf\Service::M('Attachment')->get_attach_info(0),
|
||||
'watermark' => 0,
|
||||
'save_name' => 'null',
|
||||
];
|
||||
if ($r !== '') {
|
||||
$cfg['path'] = $r;
|
||||
}
|
||||
|
||||
$rt = \Phpcmf\Service::L('upload')->upload_file($cfg);
|
||||
if (!$rt['code']) {
|
||||
exit(dr_array2string($rt));
|
||||
}
|
||||
|
||||
$data = [];
|
||||
if (defined('SYS_ATTACHMENT_CF') && SYS_ATTACHMENT_CF && $rt['data']['md5']) {
|
||||
$att = \Phpcmf\Service::M()->table('attachment')
|
||||
->where('uid', $this->uid)
|
||||
->where('filemd5', $rt['data']['md5'])
|
||||
->where('fileext', $rt['data']['ext'])
|
||||
->where('filesize', $rt['data']['size'])
|
||||
->getRow();
|
||||
if ($att) {
|
||||
$storage = new \Phpcmf\Library\Storage($this);
|
||||
$storage->delete(\Phpcmf\Service::M('Attachment')->get_attach_info(0), $rt['data']['file']);
|
||||
$rt['data'] = $this->get_attachment($att['id']);
|
||||
if ($rt['data']) {
|
||||
$rt['data']['name'] = $rt['data']['filename'];
|
||||
}
|
||||
$data = dr_return_data($att['id'], 'ok');
|
||||
}
|
||||
}
|
||||
if (!$data) {
|
||||
$data = \Phpcmf\Service::M('Attachment')->save_data($rt['data']);
|
||||
if (!$data['code']) {
|
||||
exit(dr_array2string($data));
|
||||
}
|
||||
}
|
||||
|
||||
exit(dr_array2string(['code' => 1, 'msg' => dr_lang('上传成功'), 'id' => $data['code'], 'info' => $rt['data']]));
|
||||
}
|
||||
|
||||
/**
|
||||
* 覆盖重传指定文件(扩展名须一致)
|
||||
*/
|
||||
public function dir_replace() {
|
||||
|
||||
if (!IS_POST) {
|
||||
$this->_json(0, dr_lang('请求错误'));
|
||||
}
|
||||
|
||||
$file = isset($_FILES['file_data']) ? $_FILES['file_data'] : null;
|
||||
$maxBytes = 9999 * 1024 * 1024;
|
||||
if ($file && !empty($file['size']) && $file['size'] > $maxBytes) {
|
||||
$this->_json(0, dr_lang('文件大小超出网站限制'));
|
||||
}
|
||||
|
||||
$rel = $this->_dir_rel_path(\Phpcmf\Service::L('input')->post('replace'));
|
||||
if ($rel === '') {
|
||||
$this->_json(0, dr_lang('参数错误'));
|
||||
}
|
||||
|
||||
list($ok, $abs, $r) = $this->_dir_safe($rel);
|
||||
if (!$ok || !is_file($abs)) {
|
||||
$this->_json(0, dr_lang('文件不存在'));
|
||||
}
|
||||
|
||||
$name = basename(str_replace('\\', '/', $abs));
|
||||
$oldExt = strpos($name, '.') !== false ? strtolower(trim(strrchr($name, '.'), '.')) : '';
|
||||
|
||||
$cfg = [
|
||||
'form_name' => 'file_data',
|
||||
'file_exts' => $oldExt !== '' ? [$oldExt] : ['*'],
|
||||
'file_name' => $abs,
|
||||
];
|
||||
|
||||
$rt = \Phpcmf\Service::L('upload')->update_file($cfg);
|
||||
if (!$rt['code']) {
|
||||
exit(dr_array2string($rt));
|
||||
}
|
||||
|
||||
exit(dr_array2string(['code' => 1, 'msg' => dr_lang('上传成功')]));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除所选文件或空目录
|
||||
*/
|
||||
public function dir_delete() {
|
||||
|
||||
if (!IS_POST) {
|
||||
$this->_json(0, dr_lang('请求错误'));
|
||||
}
|
||||
|
||||
$paths = \Phpcmf\Service::L('input')->post('paths');
|
||||
if (!$paths || !is_array($paths)) {
|
||||
$this->_json(0, dr_lang('你还没有选择呢'));
|
||||
}
|
||||
|
||||
foreach ($paths as $p) {
|
||||
$rel = $this->_dir_rel_path($p);
|
||||
if ($rel === '') {
|
||||
$this->_json(0, dr_lang('禁止删除附件根目录'));
|
||||
}
|
||||
list($ok, $abs, $r) = $this->_dir_safe($rel);
|
||||
if (!$ok) {
|
||||
continue;
|
||||
}
|
||||
if (is_file($abs)) {
|
||||
if (!@unlink($abs)) {
|
||||
$this->_json(0, dr_lang('文件删除失败'));
|
||||
}
|
||||
} elseif (is_dir($abs)) {
|
||||
$items = @scandir($abs);
|
||||
$left = $items ? array_diff($items, ['.', '..']) : [];
|
||||
if ($left) {
|
||||
$this->_json(0, dr_lang('目录非空,无法删除'));
|
||||
}
|
||||
if (!@rmdir($abs)) {
|
||||
$this->_json(0, dr_lang('目录删除失败'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 在当前目录下新建文件夹
|
||||
*/
|
||||
public function dir_mkdir() {
|
||||
|
||||
if (!IS_POST) {
|
||||
$this->_json(0, dr_lang('请求错误'));
|
||||
}
|
||||
|
||||
$rel = $this->_dir_rel_path(\Phpcmf\Service::L('input')->post('path'));
|
||||
$name = trim((string) \Phpcmf\Service::L('input')->post('name'));
|
||||
$name = dr_safe_filename($name);
|
||||
if ($name === '' || strpos($name, '.') === 0) {
|
||||
$this->_json(0, dr_lang('名称不规范'));
|
||||
}
|
||||
|
||||
list($ok, $parentAbs, $r) = $this->_dir_safe($rel);
|
||||
if (!$ok || !is_dir($parentAbs)) {
|
||||
$this->_json(0, dr_lang('当前目录无效'));
|
||||
}
|
||||
|
||||
$newAbs = rtrim($parentAbs, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.$name;
|
||||
if (file_exists($newAbs)) {
|
||||
$this->_json(0, dr_lang('已存在同名文件或目录'));
|
||||
}
|
||||
if (!dr_mkdirs($newAbs)) {
|
||||
$this->_json(0, dr_lang('目录创建失败'));
|
||||
}
|
||||
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 规范化相对路径(相对 SYS_UPLOAD_PATH)
|
||||
* 按段解析,禁止路径跳出上传根(..),避免简单替换字符串被绕过
|
||||
*/
|
||||
protected function _dir_rel_path($raw) {
|
||||
|
||||
$raw = (string) $raw;
|
||||
if ($raw === '' || strpos($raw, "\0") !== false) {
|
||||
return '';
|
||||
}
|
||||
$raw = str_replace('\\', '/', $raw);
|
||||
$raw = str_replace(["\r", "\n", '<', '>', '{', '}'], '', $raw);
|
||||
$raw = trim($raw, '/');
|
||||
if ($raw === '') {
|
||||
return '';
|
||||
}
|
||||
$parts = explode('/', $raw);
|
||||
$out = [];
|
||||
foreach ($parts as $p) {
|
||||
if ($p === '' || $p === '.') {
|
||||
continue;
|
||||
}
|
||||
if ($p === '..') {
|
||||
if (empty($out)) {
|
||||
return '';
|
||||
}
|
||||
array_pop($out);
|
||||
continue;
|
||||
}
|
||||
$p = trim($p);
|
||||
if ($p === '' || $p === '.' || $p === '..') {
|
||||
continue;
|
||||
}
|
||||
$out[] = $p;
|
||||
}
|
||||
|
||||
return implode('/', $out);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否位于上传根目录之下
|
||||
*/
|
||||
protected function _dir_under_root($rootReal, $candidate) {
|
||||
|
||||
$root = strtolower(str_replace('\\', '/', rtrim($rootReal, '/\\')));
|
||||
$path = strtolower(str_replace('\\', '/', $candidate));
|
||||
|
||||
return $path === $root || strpos($path, $root.'/') === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析安全绝对路径
|
||||
*/
|
||||
protected function _dir_safe($rel) {
|
||||
|
||||
$rel = $this->_dir_rel_path($rel);
|
||||
$root = rtrim(str_replace(['/', '\\'], DIRECTORY_SEPARATOR, SYS_UPLOAD_PATH), DIRECTORY_SEPARATOR);
|
||||
if (!is_dir($root)) {
|
||||
return [false, '', ''];
|
||||
}
|
||||
$rootReal = realpath($root);
|
||||
if ($rootReal === false) {
|
||||
return [false, '', ''];
|
||||
}
|
||||
if ($rel === '') {
|
||||
return [true, $rootReal.DIRECTORY_SEPARATOR, ''];
|
||||
}
|
||||
$sub = str_replace('/', DIRECTORY_SEPARATOR, $rel);
|
||||
$full = $rootReal.DIRECTORY_SEPARATOR.$sub;
|
||||
if (is_file($full) || is_dir($full)) {
|
||||
$rp = realpath($full);
|
||||
if ($rp !== false && $this->_dir_under_root($rootReal, $rp)) {
|
||||
return [true, $rp, $rel];
|
||||
}
|
||||
|
||||
return [false, '', ''];
|
||||
}
|
||||
|
||||
return [false, '', ''];
|
||||
}
|
||||
|
||||
/**
|
||||
* 列出目录内容
|
||||
*/
|
||||
protected function _dir_listing($rel) {
|
||||
|
||||
list($ok, $abs, $r) = $this->_dir_safe($rel);
|
||||
if (!$ok || !is_dir($abs)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$dirs = [];
|
||||
$files = [];
|
||||
if ($fp = @opendir($abs)) {
|
||||
while (($name = readdir($fp)) !== false) {
|
||||
if ($name === '.' || $name === '..' || $name === '.DS_Store') {
|
||||
continue;
|
||||
}
|
||||
if (strtolower(substr($name, -4)) === '.php') {
|
||||
continue;
|
||||
}
|
||||
$full = $abs.DIRECTORY_SEPARATOR.$name;
|
||||
$childRel = $r === '' ? $name : $r.'/'.$name;
|
||||
if (is_dir($full)) {
|
||||
$dirs[] = [
|
||||
'name' => $name,
|
||||
'path' => $childRel,
|
||||
'path_esc' => htmlspecialchars($childRel, ENT_QUOTES, 'UTF-8'),
|
||||
'mtime' => filemtime($full),
|
||||
];
|
||||
} elseif (is_file($full)) {
|
||||
$ext = strtolower(trim(strrchr($name, '.'), '.'));
|
||||
$files[] = [
|
||||
'name' => $name,
|
||||
'path' => $childRel,
|
||||
'path_esc' => htmlspecialchars($childRel, ENT_QUOTES, 'UTF-8'),
|
||||
'size' => filesize($full),
|
||||
'mtime' => filemtime($full),
|
||||
'ext' => $ext,
|
||||
'url' => SYS_UPLOAD_URL.str_replace('\\', '/', $childRel),
|
||||
'is_image' => dr_is_image($ext),
|
||||
'is_mp4' => $ext === 'mp4',
|
||||
];
|
||||
}
|
||||
}
|
||||
closedir($fp);
|
||||
}
|
||||
|
||||
usort($dirs, function ($a, $b) {
|
||||
return strcasecmp($a['name'], $b['name']);
|
||||
});
|
||||
usort($files, function ($a, $b) {
|
||||
return strcasecmp($a['name'], $b['name']);
|
||||
});
|
||||
|
||||
return [
|
||||
'rel' => $r,
|
||||
'dirs' => $dirs,
|
||||
'files' => $files,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 面包屑
|
||||
*/
|
||||
protected function _dir_breadcrumb($rel) {
|
||||
|
||||
$crumbs = [['name' => dr_lang('附件根目录'), 'path' => '']];
|
||||
if ($rel === '') {
|
||||
return $crumbs;
|
||||
}
|
||||
$parts = explode('/', $rel);
|
||||
$acc = '';
|
||||
foreach ($parts as $p) {
|
||||
if ($p === '') {
|
||||
continue;
|
||||
}
|
||||
$acc = $acc === '' ? $p : $acc.'/'.$p;
|
||||
$crumbs[] = ['name' => $p, 'path' => $acc];
|
||||
}
|
||||
|
||||
return $crumbs;
|
||||
}
|
||||
|
||||
// 已归档管理
|
||||
public function db_index() {
|
||||
|
||||
$field = [
|
||||
'uid' => [
|
||||
'ismain' => 1,
|
||||
'fieldtype' => 'Text',
|
||||
'fieldname' => 'uid',
|
||||
'name' => '账号',
|
||||
],
|
||||
'related' => [
|
||||
'ismain' => 1,
|
||||
'fieldtype' => 'Text',
|
||||
'fieldname' => 'related',
|
||||
'name' => dr_lang('附件归属'),
|
||||
],
|
||||
'fileext' => [
|
||||
'ismain' => 1,
|
||||
'fieldtype' => 'Text',
|
||||
'fieldname' => 'fileext',
|
||||
'name' => dr_lang('扩展名'),
|
||||
],
|
||||
'filename' => [
|
||||
'ismain' => 1,
|
||||
'fieldtype' => 'Text',
|
||||
'fieldname' => 'filename',
|
||||
'name' => dr_lang('附件名称'),
|
||||
],
|
||||
'attachment' => [
|
||||
'ismain' => 1,
|
||||
'fieldtype' => 'Text',
|
||||
'fieldname' => 'attachment',
|
||||
'name' => dr_lang('附件路径'),
|
||||
],
|
||||
];
|
||||
|
||||
$remote = (int)$_GET['remote'];
|
||||
$where_list = 'id in (select id from '.\Phpcmf\Service::M()->dbprefix('attachment').' where siteid='.SITE_ID.')';
|
||||
$remote && $where_list.= ' and `remote`='.$remote;
|
||||
|
||||
$this->_init([
|
||||
'table' => 'attachment_data',
|
||||
'field' => $field,
|
||||
'order_by' => 'id desc',
|
||||
'where_list' => $where_list,
|
||||
'date_field' => 'inputtime',
|
||||
]);
|
||||
|
||||
$this->_List();
|
||||
|
||||
// 快捷上传字段参数
|
||||
$p = [
|
||||
'size' => 9999,
|
||||
'exts' => '*',
|
||||
'count' => 20,
|
||||
'attachment' => $remote,
|
||||
'image_reduce' => 0,
|
||||
'chunk' => 10 * 1024 * 1024,
|
||||
];
|
||||
$upload = [
|
||||
'url' => dr_web_prefix(SELF.'?c=api&token='.dr_get_csrf_token())
|
||||
.'&siteid='.SITE_ID.'&m=upload&p='.dr_authcode($p, 'ENCODE'),
|
||||
'param' => $p,
|
||||
'back' => dr_now_url(),
|
||||
];
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'field' => $field,
|
||||
'table' => 'data',
|
||||
'remote' => \Phpcmf\Service::M()->table('attachment_remote')->getAll(0, 'id'),
|
||||
'upload' => $upload,
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('attachment_admin.html');
|
||||
}
|
||||
|
||||
// 未归档的附件
|
||||
public function unused_index() {
|
||||
|
||||
$field = [
|
||||
'author' => [
|
||||
'ismain' => 1,
|
||||
'fieldtype' => 'Text',
|
||||
'fieldname' => 'author',
|
||||
'name' => dr_lang('账号'),
|
||||
],
|
||||
'fileext' => [
|
||||
'ismain' => 1,
|
||||
'fieldtype' => 'Text',
|
||||
'fieldname' => 'fileext',
|
||||
'name' => dr_lang('扩展名'),
|
||||
],
|
||||
'uid' => [
|
||||
'ismain' => 1,
|
||||
'fieldtype' => 'Text',
|
||||
'fieldname' => 'uid',
|
||||
'name' => 'uid',
|
||||
],
|
||||
];
|
||||
|
||||
$remote = (int)$_GET['remote'];
|
||||
$where_list = 'siteid='.SITE_ID;
|
||||
$remote && $where_list.= ' and `remote`='.$remote;
|
||||
|
||||
$this->_init([
|
||||
'table' => 'attachment_unused',
|
||||
'field' => $field,
|
||||
'order_by' => 'id desc',
|
||||
'where_list' => $where_list,
|
||||
'date_field' => 'inputtime',
|
||||
]);
|
||||
|
||||
$this->_List();
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'field' => $field,
|
||||
'table' => 'unused',
|
||||
'remote' => \Phpcmf\Service::M()->table('attachment_remote')->getAll(0, 'id'),
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('attachment_admin.html');
|
||||
}
|
||||
|
||||
public function remote_edit() {
|
||||
|
||||
if (IS_POST) {
|
||||
$post = \Phpcmf\Service::L('input')->post('data');
|
||||
if ($post['o'] == $post['n']) {
|
||||
$this->_json(0, dr_lang('储存策略不能相同'));
|
||||
}
|
||||
|
||||
\Phpcmf\Service::M()->table('attachment_unused')->where('remote', intval($post['o']))->update(0, [
|
||||
'remote' => intval($post['n'])
|
||||
]);
|
||||
|
||||
\Phpcmf\Service::M()->table('attachment_data')->where('remote', intval($post['o']))->update(0, [
|
||||
'remote' => intval($post['n'])
|
||||
]);
|
||||
|
||||
dr_dir_delete(WRITEPATH.'attach');
|
||||
dr_mkdirs(WRITEPATH.'attach');
|
||||
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'form' => dr_form_hidden(),
|
||||
'remote' => \Phpcmf\Service::M()->table('attachment_remote')->getAll(0, 'id'),
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('attachment_remote_edit.html');
|
||||
}
|
||||
|
||||
public function del() {
|
||||
|
||||
$ids = \Phpcmf\Service::L('input')->get_post_ids();
|
||||
if (!$ids) {
|
||||
$this->_json(0, dr_lang('你还没有选择呢'));
|
||||
}
|
||||
|
||||
$table = \Phpcmf\Service::L('input')->post('table');
|
||||
$table != 'data' && $table = 'unused';
|
||||
|
||||
$data = \Phpcmf\Service::M()->db->table('attachment_'.$table)->whereIn('id', $ids)->get()->getResultArray();
|
||||
if (!$data) {
|
||||
$this->_json(0, dr_lang('所选附件不存在'));
|
||||
}
|
||||
|
||||
foreach ($data as $t) {
|
||||
$rt = \Phpcmf\Service::M('attachment')->_delete_file($t);
|
||||
if (!$rt['code']) {
|
||||
return dr_return_data(0, $rt['msg']);
|
||||
}
|
||||
}
|
||||
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
|
||||
// 强制归档
|
||||
public function edit() {
|
||||
|
||||
$ids = \Phpcmf\Service::L('input')->get_post_ids();
|
||||
if (!$ids) {
|
||||
$this->_json(0, dr_lang('你还没有选择呢'));
|
||||
}
|
||||
|
||||
$data = \Phpcmf\Service::M()->db->table('attachment_unused')->whereIn('id', $ids)->get()->getResultArray();
|
||||
if (!$data) {
|
||||
$this->_json(0, dr_lang('所选附件不存在'));
|
||||
}
|
||||
|
||||
$related = 'Save';
|
||||
foreach ($data as $t) {
|
||||
// 更新主索引表
|
||||
\Phpcmf\Service::M()->table('attachment')->update($t['id'], array(
|
||||
'related' => $related
|
||||
));
|
||||
\Phpcmf\Service::M()->table('attachment_data')->insert(array(
|
||||
'id' => $t['id'],
|
||||
'uid' => $t['uid'],
|
||||
'remote' => $t['remote'],
|
||||
'author' => $t['author'],
|
||||
'related' => $related,
|
||||
'fileext' => $t['fileext'],
|
||||
'filesize' => $t['filesize'],
|
||||
'filename' => $t['filename'],
|
||||
'inputtime' => $t['inputtime'],
|
||||
'attachment' => $t['attachment'],
|
||||
'attachinfo' => '',
|
||||
));
|
||||
// 删除未归档附件
|
||||
\Phpcmf\Service::M()->table('attachment_unused')->delete($t['id']);
|
||||
}
|
||||
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
|
||||
// 变更储存策略
|
||||
public function type_edit() {
|
||||
|
||||
$ids = \Phpcmf\Service::L('input')->get_post_ids();
|
||||
if (!$ids) {
|
||||
$this->_json(0, dr_lang('你还没有选择呢'));
|
||||
}
|
||||
|
||||
$rid = intval(\Phpcmf\Service::L('input')->post('remote'));
|
||||
if ($rid < 0) {
|
||||
$this->_json(0, dr_lang('你还没有选择储存策略'));
|
||||
}
|
||||
|
||||
$table = \Phpcmf\Service::L('input')->post('table');
|
||||
$table != 'data' && $table = 'unused';
|
||||
|
||||
\Phpcmf\Service::M()->table('attachment_'.$table)->where_in('id', $ids)->update(0, [
|
||||
'remote' => $rid
|
||||
]);
|
||||
|
||||
dr_dir_delete(WRITEPATH.'attach');
|
||||
dr_mkdirs(WRITEPATH.'attach');
|
||||
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
|
||||
// 重新上传附件
|
||||
public function file_edit() {
|
||||
|
||||
$id = \Phpcmf\Service::L('input')->get('id');
|
||||
if (!$id) {
|
||||
$this->_json(0, dr_lang('你还没有选择呢'));
|
||||
}
|
||||
|
||||
$data = $this->get_attachment($id, true);
|
||||
if (!$data) {
|
||||
$this->_json(0, dr_lang('附件信息不存在'));
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'data' => $data,
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('attachment_upload.html');
|
||||
}
|
||||
|
||||
// 重新上传附件
|
||||
public function upload_edit() {
|
||||
|
||||
$id = \Phpcmf\Service::L('input')->get('id');
|
||||
if (!$id) {
|
||||
$this->_json(0, dr_lang('你还没有选择呢'));
|
||||
}
|
||||
|
||||
$data = $this->get_attachment($id, true);
|
||||
if (!$data) {
|
||||
$this->_json(0, dr_lang('附件信息不存在'));
|
||||
}
|
||||
|
||||
$rt = \Phpcmf\Service::L('upload')->upload_file([
|
||||
'save_name' => str_replace('.'.$data['fileext'], '', basename($data['attachment'])),
|
||||
'path' => dirname($data['attachment']),
|
||||
'form_name' => 'file_data',
|
||||
'file_exts' => [$data['fileext']],
|
||||
'file_size' => 1000 * 1024 * 1024,
|
||||
'attachment' => \Phpcmf\Service::M('Attachment')->get_attach_info($data['remote']),
|
||||
]);
|
||||
if (!$rt['code']) {
|
||||
exit(dr_array2string($rt));
|
||||
}
|
||||
\Phpcmf\Service::M()->table('attachment_data')->update($id, ['filesize' => $rt['data']['size']]);
|
||||
\Phpcmf\Service::M()->table('attachment_unused')->update($id, ['filesize' => $rt['data']['size']]);
|
||||
$this->_json(1, dr_lang('上传成功'), $rt['data']);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,631 @@
|
||||
<?php namespace Phpcmf\Control\Admin;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
// 缓存更新
|
||||
class Cache extends \Phpcmf\Common {
|
||||
|
||||
public function index() {
|
||||
|
||||
$list = [
|
||||
['系统配置缓存', 'update_cache'],
|
||||
['表或表字段异常时,更新数据结构', 'update_db'],
|
||||
['附件地址未更新时,更新附件缓存', 'update_attachment'],
|
||||
['清理自定义路由缓存', 'update_rewrite_routes'],
|
||||
['手动清理缩略图文件(如果生成过静态页面,请慎用)', 'update_thumb'],
|
||||
['清理全部系统日志、操作日志、邮件日志、短信日志、慢查询日志等', 'update_log'],
|
||||
];
|
||||
|
||||
if (dr_is_app('ueditor') && is_file(CMSPATH.'Field/Ueditor.php')) {
|
||||
$list[] = ['生成百度编辑器到其他域名', 'update_ueditor'];
|
||||
}
|
||||
|
||||
if (is_file(APPSPATH.'Module/install.lock') && is_file(APPSPATH.'Module/Config/Content.php')) {
|
||||
if (is_dir(APPSPATH.'Cms')) {
|
||||
// 已存在 Cms 目录,直接删除旧的 Module 目录
|
||||
dr_dir_delete(APPSPATH.'Module', true);
|
||||
if (is_dir(APPSPATH.'Module')) {
|
||||
$this->_admin_msg(0, dr_lang('请手动删除目录[%s]', APPSPATH.'Module'));
|
||||
} else {
|
||||
$this->_admin_msg(1, dr_lang('CMS迁移成功,请更新系统缓存'), dr_now_url());
|
||||
}
|
||||
} else {
|
||||
// 重命名目录 Module -> Cms,判断是否重命名失败
|
||||
@rename(APPSPATH.'Module', APPSPATH.'Cms');
|
||||
if (is_dir(APPSPATH.'Module')) {
|
||||
$this->_admin_msg(0, dr_lang('请手动将目录[%s]重命名为[%s]', APPSPATH.'Module', APPSPATH.'Cms'));
|
||||
} else {
|
||||
$this->_admin_msg(1, dr_lang('CMS迁移成功,请更新系统缓存'), dr_now_url());
|
||||
}
|
||||
}
|
||||
} elseif (is_file(APPSPATH.'Cms/install.lock') && is_file(APPSPATH.'Cms/Models/Module.php')) {
|
||||
if (is_file(APPSPATH.'Module/Config/Content.php')) {
|
||||
// 已存在 Cms 目录,直接删除旧的 Module 目录
|
||||
dr_dir_delete(APPSPATH.'Module', true);
|
||||
if (is_dir(APPSPATH.'Module')) {
|
||||
$this->_admin_msg(0, dr_lang('请手动将目录[%s]删除', APPSPATH.'Module'));
|
||||
}
|
||||
}
|
||||
$need = false;
|
||||
foreach ([APPSPATH.'Cms/Models/', APPSPATH.'Cms/Libraries/'] as $path) {
|
||||
if (!is_dir($path)) {
|
||||
continue;
|
||||
}
|
||||
$files = dr_file_map($path);
|
||||
if (!$files) {
|
||||
continue;
|
||||
}
|
||||
foreach ($files as $file) {
|
||||
if (substr($file, -4) !== '.php' || !is_file($path.$file)) {
|
||||
continue;
|
||||
}
|
||||
$code = file_get_contents($path.$file);
|
||||
if ($code && (strpos($code, 'Phpcmf\\Model\\Module') !== false || strpos($code, 'Phpcmf\\Library\\Module') !== false)) {
|
||||
$need = true;
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($need) {
|
||||
$error = [];
|
||||
$replace = [
|
||||
'Phpcmf\\Model\\Module' => 'Phpcmf\\Model\\Cms',
|
||||
'Phpcmf\\Library\\Module' => 'Phpcmf\\Library\\Cms',
|
||||
];
|
||||
foreach ([APPSPATH.'Cms/Models/', APPSPATH.'Cms/Libraries/'] as $path) {
|
||||
if (!is_dir($path)) {
|
||||
continue;
|
||||
}
|
||||
$files = dr_file_map($path);
|
||||
if (!$files) {
|
||||
continue;
|
||||
}
|
||||
foreach ($files as $file) {
|
||||
if (substr($file, -4) !== '.php') {
|
||||
continue;
|
||||
}
|
||||
$filepath = $path.$file;
|
||||
if (!is_file($filepath)) {
|
||||
continue;
|
||||
}
|
||||
$code = file_get_contents($filepath);
|
||||
if (!$code) {
|
||||
continue;
|
||||
}
|
||||
$new = str_replace(array_keys($replace), array_values($replace), $code);
|
||||
if ($new === $code) {
|
||||
continue;
|
||||
}
|
||||
if (@file_put_contents($filepath, $new) === false) {
|
||||
$error[] = $filepath;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($error) {
|
||||
$this->_admin_msg(0, dr_lang('文件无法写入'), '', implode('<br>', $error));
|
||||
} else {
|
||||
$this->_admin_msg(1, dr_lang('CMS命名空间迁移成功,请更新系统缓存'), dr_now_url());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$sync = [];
|
||||
$local = \Phpcmf\Service::Apps();
|
||||
foreach ($local as $dir => $path) {
|
||||
if (is_file($path.'Config/Cache.html')) {
|
||||
$sync[] = $path.'Config/Cache.html';
|
||||
}
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'sync' => $sync,
|
||||
'list' => $list,
|
||||
'menu' => \Phpcmf\Service::M('auth')->_admin_menu(
|
||||
[
|
||||
'系统更新' => ['cache/index', 'fa fa-refresh'],
|
||||
'系统体检' => ['check/index', 'fa fa-wrench'],
|
||||
'help' => [378],
|
||||
]
|
||||
),
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('cache.html');
|
||||
}
|
||||
|
||||
public function update_index() {
|
||||
|
||||
$page = intval($_GET['page']);
|
||||
$next = dr_url('cache/update_index');
|
||||
if (!$page) {
|
||||
file_put_contents(WRITEPATH.'install.lock', SYS_TIME);
|
||||
if (is_file(WRITEPATH.'update.lock')) {
|
||||
@unlink(WRITEPATH.'update.lock');
|
||||
if (is_file(WRITEPATH.'update.lock')) {
|
||||
$this->_html_msg(0, dr_lang('%s目录请给可写入权限', IS_DEV ? WRITEPATH : 'cache'));
|
||||
}
|
||||
}
|
||||
$this->_html_msg(1, dr_lang('正在更新升级程序'), $next.'&page=1');
|
||||
}
|
||||
|
||||
switch ($page) {
|
||||
|
||||
case 1:
|
||||
|
||||
$dir = [
|
||||
WRITEPATH.'cloud/',
|
||||
WRITEPATH.'watermark/',
|
||||
];
|
||||
foreach ($dir as $path) {
|
||||
if (!is_dir($path)) {
|
||||
dr_mkdirs($path);
|
||||
}
|
||||
if (!dr_check_put_path($path)) {
|
||||
$this->_html_msg(0, dr_lang('目录创建失败'), '', $path);
|
||||
}
|
||||
}
|
||||
|
||||
// 移动水印目录
|
||||
if (is_dir(WEBPATH.'config/watermark/')) {
|
||||
\Phpcmf\Service::L('file')->copy_dir(WEBPATH.'config/watermark/', WEBPATH.'config/watermark/', WRITEPATH.'watermark/');
|
||||
}
|
||||
|
||||
// 判断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);
|
||||
}
|
||||
if (is_dir($path)) {
|
||||
$this->_html_msg(0, dr_lang('目录移动失败'), '', '请手动将['.$path.']下面的文件移动到网站根目录中['.ROOTPATH.'],再删除public目录');
|
||||
}
|
||||
}
|
||||
|
||||
// 移动头像目录
|
||||
$path = ROOTPATH.'api/member/';
|
||||
if (is_dir($path)) {
|
||||
\Phpcmf\Service::L('file')->copy_dir($path, $path, SYS_UPLOAD_PATH.'member/');
|
||||
dr_dir_delete($path, true);
|
||||
}
|
||||
|
||||
$this->_html_msg(1, dr_lang('正在升级文件目录结构'), $next.'&page='.($page+1));
|
||||
break;
|
||||
|
||||
case 2:
|
||||
|
||||
// 判断模块表
|
||||
if (!IS_USE_MODULE
|
||||
&& \Phpcmf\Service::M()->is_table_exists('module')
|
||||
&& is_file(dr_get_app_dir('module').'/Config/App.php')
|
||||
) {
|
||||
// 表示模块表已经操作,手动安装模块
|
||||
$rs = file_put_contents(dr_get_app_dir('module').'/install.lock', 'fix');
|
||||
if (!$rs) {
|
||||
$this->_html_msg(0, dr_lang('目录无法写入'), '', dr_get_app_dir('module'));
|
||||
}
|
||||
}
|
||||
|
||||
$local = dr_dir_map(APPSPATH, 1); // 搜索本地模块
|
||||
foreach ($local as $dir) {
|
||||
if (is_file(APPSPATH.$dir.'/Config/App.php')) {
|
||||
$file = APPSPATH.$dir.'/Controllers/Search.php';
|
||||
if (is_file($file)) {
|
||||
// 替换搜索控制器
|
||||
$code = file_get_contents($file);
|
||||
if ($code && strpos($code, '\Phpcmf\Home\Search') !== false) {
|
||||
file_put_contents($file, str_replace(
|
||||
['\Phpcmf\Home\Search', '_Module_Search'],
|
||||
['\Phpcmf\Home\Module', '_Search'],
|
||||
$code
|
||||
));
|
||||
}
|
||||
}
|
||||
$file = APPSPATH.$dir.'/Controllers/Recycle.php';
|
||||
if (is_file($file)) {
|
||||
// 替换搜索控制器
|
||||
$code = file_get_contents($file);
|
||||
if ($code && strpos($code, '_Admin_Recycle_Edit') === false) {
|
||||
file_put_contents($file, str_replace(
|
||||
'public function index() {',
|
||||
' public function edit() {
|
||||
$this->_Admin_Recycle_Edit();
|
||||
}
|
||||
public function index() {
|
||||
',
|
||||
$code
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 升级插件兼容测试
|
||||
$error = [];
|
||||
$table_app = [
|
||||
'module' => 'module',
|
||||
SITE_ID.'_form' => 'form',
|
||||
'module_form' => 'mform',
|
||||
'member_notice' => 'notice',
|
||||
'member_scorelog' => 'scorelog',
|
||||
'member_paylog' => 'pay',
|
||||
'member_explog' => 'explog',
|
||||
];
|
||||
$app_name = [
|
||||
'module' => '建站系统',
|
||||
'form' => '表单系统',
|
||||
'mform' => '模块内容表单',
|
||||
'notice' => '提醒消息',
|
||||
'pay' => '支付系统',
|
||||
'scorelog' => '积分系统',
|
||||
'explog' => '经验值系统',
|
||||
'member' => '用户系统',
|
||||
];
|
||||
foreach ($table_app as $table => $name) {
|
||||
if (\Phpcmf\Service::M()->is_table_exists($table) && \Phpcmf\Service::M()->table($table)->counts()) {
|
||||
$cpath = dr_get_app_dir($name);
|
||||
if (is_dir($cpath)) {
|
||||
file_put_contents($cpath.'/install.lock', 1);
|
||||
} else {
|
||||
$error[] = $app_name[$name];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 用户系统
|
||||
if (\Phpcmf\Service::M()->is_table_exists('member_menu') && !dr_is_app('member')) {
|
||||
$error[] = $app_name['member'];
|
||||
}
|
||||
|
||||
if ($error) {
|
||||
$this->_html_msg(0, '需要手动安装这些应用插件:'.implode('、', $error).'
|
||||
<br><br><a href="http://help.xunruicms.com/1104.html" target="_blank">查看解决方案</a><br><br>将以上问题处理之后继续更新此脚本', 0);
|
||||
}
|
||||
|
||||
$this->_html_msg(1, dr_lang('正在升级程序兼容性'), $next.'&page='.($page+1));
|
||||
break;
|
||||
|
||||
case 3:
|
||||
|
||||
$prefix = \Phpcmf\Service::M()->prefix;
|
||||
$db = \Phpcmf\Service::M()->db;
|
||||
$T = \Phpcmf\Service::M('table');
|
||||
|
||||
// 增加长度
|
||||
$T->edit_field($prefix.'member', 'salt', 'VARCHAR(50)', 'NOT NULL', '随机加密码');
|
||||
|
||||
$table = $prefix.'cron';
|
||||
if (!$db->fieldExists('site', $table)) {
|
||||
$T->add_field($table, 'site', 'INT(10)', 'NOT NULL', '站点');
|
||||
}
|
||||
|
||||
$table = $prefix.'site';
|
||||
if (!$db->fieldExists('displayorder', $table)) {
|
||||
$T->add_field($table, 'displayorder', 'INT(10)', 'DEFAULT NULL', '排序');
|
||||
}
|
||||
|
||||
$table = $prefix.'member_data';
|
||||
if (!$db->fieldExists('is_email', $table)) {
|
||||
$T->add_field($table, 'is_email', 'tinyint(1)', 'DEFAULT NULL', '邮箱认证');
|
||||
}
|
||||
|
||||
$table = $prefix.'member_paylog';
|
||||
if ($db->tableExists($table)) {
|
||||
if (!$db->fieldExists('site', $table)) {
|
||||
$T->add_field($table, 'site', 'INT(10)', 'NOT NULL', '站点');
|
||||
}
|
||||
if ($db->fieldExists('username', $table)) {
|
||||
$T->drop_field($table, 'username');
|
||||
}
|
||||
if ($db->fieldExists('tousername', $table)) {
|
||||
$T->drop_field($table, 'tousername');
|
||||
}
|
||||
}
|
||||
|
||||
$T->edit_field($prefix.'admin_notice', 'to_rid', 'varchar(100)', 'NOT NULL', '指定角色组');
|
||||
$T->edit_field($prefix.'admin_notice', 'to_uid', 'varchar(100)', 'NOT NULL', '指定管理员');
|
||||
|
||||
$table = $prefix.'member_group_verify';
|
||||
if ($db->tableExists($table) && !$db->fieldExists('price', $table)) {
|
||||
$T->add_field($table, 'price', 'decimal(10,2)', 'DEFAULT NULL', '已费用');
|
||||
}
|
||||
|
||||
$table = $prefix.'member_scorelog';
|
||||
if ($db->tableExists($table) && !$db->fieldExists('username', $table)) {
|
||||
$T->add_field($table, 'username', 'VARCHAR(100)', 'DEFAULT NULL', '');
|
||||
}
|
||||
|
||||
$table = $prefix.'member_notice';
|
||||
if ($db->tableExists($table) && !$db->fieldExists('mark', $table)) {
|
||||
$T->add_field($table, 'mark', 'VARCHAR(100)', 'DEFAULT NULL', '');
|
||||
$T->edit_field($prefix.'member_notice', 'type', 'tinyint(2)', 'unsigned NOT NULL', '类型');
|
||||
}
|
||||
|
||||
$table = $prefix.'member_explog';
|
||||
if ($db->tableExists($table) && !$db->fieldExists('username', $table)) {
|
||||
$T->add_field($table, 'username', 'VARCHAR(100)', 'DEFAULT NULL', '');
|
||||
}
|
||||
|
||||
$table = $prefix.'member_oauth';
|
||||
if ($db->tableExists($table) && !$db->fieldExists('unionid', $table)) {
|
||||
$T->add_field($table, 'unionid', 'VARCHAR(100)', 'DEFAULT NULL', '');
|
||||
}
|
||||
|
||||
$table = $prefix.'member';
|
||||
if (!$db->fieldExists('login_attr', $table)) {
|
||||
$T->add_field($table, 'login_attr', 'VARCHAR(100)', 'DEFAULT NULL', '');
|
||||
}
|
||||
|
||||
$table = $prefix.'member_menu';
|
||||
if ($db->tableExists($table) && !$db->fieldExists('site', $table)) {
|
||||
$T->add_field($table, 'site', 'TEXT', 'DEFAULT NULL', '');
|
||||
}
|
||||
|
||||
$table = $prefix.'member_menu';
|
||||
if ($db->tableExists($table) && !$db->fieldExists('client', $table)) {
|
||||
$T->add_field($table, 'client', 'TEXT', 'DEFAULT NULL', '');
|
||||
}
|
||||
|
||||
$table = $prefix.'member_level';
|
||||
if (!$db->tableExists($table)) {
|
||||
$T->create_table($table, [
|
||||
'id' => 'smallint(5) unsigned NOT NULL AUTO_INCREMENT',
|
||||
'gid' => 'smallint(5) unsigned NOT NULL COMMENT \'用户id\'',
|
||||
'name' => 'varchar(255) NOT NULL COMMENT \'名称\'',
|
||||
'stars' => 'int(10) NOT NULL COMMENT \'图标\'',
|
||||
'value' => 'int(10) unsigned NOT NULL COMMENT \'升级值要求\'',
|
||||
'note' => 'text NOT NULL COMMENT \'备注\'',
|
||||
'apply' => 'tinyint(1) unsigned NOT NULL COMMENT \'是否允许升级\'',
|
||||
'setting' => 'text NOT NULL COMMENT \'等级配置\'',
|
||||
'displayorder' => 'smallint(5) NOT NULL COMMENT \'排序\'',
|
||||
], [
|
||||
'PRIMARY KEY (`id`)',
|
||||
'KEY `value` (`value`)',
|
||||
'KEY `apply` (`apply`)',
|
||||
'KEY `gid` (`gid`)',
|
||||
'KEY `displayorder` (`displayorder`)',
|
||||
], '用户组级别表');
|
||||
} else {
|
||||
$T->edit_field($table, 'stars', 'int(10)', 'unsigned NOT NULL', '图标');
|
||||
if (!$db->fieldExists('setting', $table)) {
|
||||
$T->add_field($table, 'setting', 'TEXT', 'DEFAULT NULL', '');
|
||||
}
|
||||
if (!$db->fieldExists('displayorder', $table)) {
|
||||
$T->add_field($table, 'displayorder', 'INT(10)', 'DEFAULT NULL', '排序');
|
||||
}
|
||||
}
|
||||
|
||||
$table = $prefix.'admin_menu';
|
||||
if (!$db->fieldExists('site', $table)) {
|
||||
$T->add_field($table, 'site', 'TEXT', 'DEFAULT NULL', '');
|
||||
}
|
||||
|
||||
$table = $prefix.'admin';
|
||||
if (!$db->fieldExists('history', $table)) {
|
||||
$T->add_field($table, 'history', 'TEXT', 'DEFAULT NULL', '');
|
||||
}
|
||||
|
||||
$table = $prefix.'admin_setting';
|
||||
if (!$db->tableExists($table)) {
|
||||
$T->create_table($table, [
|
||||
'name' => 'varchar(50) NOT NULL',
|
||||
'value' => 'mediumtext NOT NULL',
|
||||
], [
|
||||
'PRIMARY KEY (`name`)',
|
||||
], '系统属性参数表');
|
||||
}
|
||||
|
||||
if (IS_USE_MEMBER) {
|
||||
$table = $prefix.'member_setting';
|
||||
if (!$db->tableExists($table)) {
|
||||
$T->create_table($table, [
|
||||
'name' => 'varchar(50) NOT NULL',
|
||||
'value' => 'mediumtext NOT NULL',
|
||||
], [
|
||||
'PRIMARY KEY (`name`)',
|
||||
], '用户属性参数表');
|
||||
} else {
|
||||
if ($db->fieldExists('id', $table)) {
|
||||
// 处理id字段
|
||||
$data = $db->table('member_setting')->get()->getResultArray();
|
||||
$T->drop_table($table);
|
||||
$T->create_table($table, [
|
||||
'name' => 'varchar(50) NOT NULL',
|
||||
'value' => 'mediumtext NOT NULL',
|
||||
], [
|
||||
'PRIMARY KEY (`name`)',
|
||||
], '用户属性参数表');
|
||||
if ($data) {
|
||||
foreach ($data as $t) {
|
||||
\Phpcmf\Service::M()->table('member_setting')->replace([
|
||||
'name' => $t['name'],
|
||||
'value' => $t['value'],
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!$db->table('member_setting')->where('name', 'auth2')->get()->getRowArray()) {
|
||||
// 权限数据
|
||||
\Phpcmf\Service::M()->table('member_setting')->replace([
|
||||
'name' => 'auth2',
|
||||
'value' => '{"1":{"public":{"home":{"show":"0","is_category":"0"},"form_public":[],"share_category_public":{"show":"1","add":"1","edit":"1","code":"1","verify":"1","exp":"","score":"","money":"","day_post":"","total_post":""},"category_public":[],"mform_public":"","form":null,"share_category":null,"category":null,"mform":null}}}',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$table = $prefix.'admin_min_menu';
|
||||
if (!$db->tableExists($table)) {
|
||||
$T->create_table($table, [
|
||||
'id' => 'smallint(5) unsigned NOT NULL AUTO_INCREMENT',
|
||||
'pid' => "smallint(5) unsigned NOT NULL COMMENT '上级菜单id'",
|
||||
'name' => "text NOT NULL COMMENT '菜单语言名称'",
|
||||
'site' => "text NOT NULL COMMENT '站点归属'",
|
||||
'uri' => "varchar(255) DEFAULT NULL COMMENT 'uri字符串'",
|
||||
'url' => "varchar(255) DEFAULT NULL COMMENT '外链地址'",
|
||||
'mark' => "varchar(255) DEFAULT NULL COMMENT '菜单标识'",
|
||||
'hidden' => "tinyint(1) unsigned DEFAULT NULL COMMENT '是否隐藏'",
|
||||
'icon' => "varchar(255) DEFAULT NULL COMMENT '图标标示'",
|
||||
'displayorder' => "int(5) DEFAULT NULL COMMENT '排序值'",
|
||||
], [
|
||||
'PRIMARY KEY (`id`)',
|
||||
'KEY `list` (`pid`)',
|
||||
'KEY `displayorder` (`displayorder`)',
|
||||
'KEY `mark` (`mark`)',
|
||||
'KEY `hidden` (`hidden`)',
|
||||
'KEY `uri` (`uri`)',
|
||||
], '后台简化菜单表');
|
||||
}
|
||||
|
||||
// 模块
|
||||
$is_module = $db->tableExists('module');
|
||||
if ($is_module) {
|
||||
$module = \Phpcmf\Service::M()->table('module')->order_by('displayorder ASC,id ASC')->getAll();
|
||||
// 栏目模型字段修正
|
||||
$db->table('field')->where('relatedname', 'share-'.SITE_ID)->update(['relatedname' => 'catmodule-share']);
|
||||
if ($module) {
|
||||
foreach ($module as $m) {
|
||||
if (!\Phpcmf\Service::M()->table('field')->where('relatedname', 'module')
|
||||
->where('relatedid', $m['id'])->where('fieldname', 'author')->counts()) {
|
||||
$db->table('field')->insert(array(
|
||||
'name' => '笔名',
|
||||
'fieldname' => 'author',
|
||||
'fieldtype' => 'Text',
|
||||
'relatedid' => $m['id'],
|
||||
'relatedname' => 'module',
|
||||
'isedit' => 1,
|
||||
'ismain' => 1,
|
||||
'ismember' => 1,
|
||||
'issystem' => 1,
|
||||
'issearch' => 1,
|
||||
'disabled' => 0,
|
||||
'setting' => dr_array2string(array(
|
||||
'is_right' => 1,
|
||||
'option' => array(
|
||||
'width' => 200, // 表单宽度
|
||||
'fieldtype' => 'VARCHAR', // 字段类型
|
||||
'fieldlength' => '255', // 字段长度
|
||||
'value' => '{name}'
|
||||
),
|
||||
'validate' => array(
|
||||
'xss' => 1, // xss过滤
|
||||
)
|
||||
)),
|
||||
'displayorder' => 0,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 站点
|
||||
foreach ($this->site as $siteid) {
|
||||
// 升级资料库
|
||||
$table = $prefix.$siteid.'_block';
|
||||
if ($db->tableExists($table)) {
|
||||
// 创建code字段 代码
|
||||
if (!$db->fieldExists('code', $table)) {
|
||||
$T->add_field($table, 'code', 'VARCHAR(100)', 'NOT NULL', '');
|
||||
}
|
||||
}
|
||||
// 升级栏目表
|
||||
|
||||
if ($is_module) {
|
||||
$table = $prefix . $siteid . '_share_category';
|
||||
if ($db->tableExists($table)) {
|
||||
// 创建字段 代码
|
||||
if (!$db->fieldExists('disabled', $table)) {
|
||||
$T->add_field($table, 'disabled', 'tinyint(1)', "DEFAULT '0'", '');
|
||||
$db->table($table)->update(['disabled' => 0]);
|
||||
}
|
||||
$db->table($table)->where('disabled', null)->update(['disabled' => 0]);
|
||||
if (!$db->fieldExists('ismain', $table)) {
|
||||
$T->add_field($table, 'ismain', 'tinyint(1)', "DEFAULT '0'", '');
|
||||
$db->table($table)->update(['ismain' => 1]);
|
||||
}
|
||||
}
|
||||
if ($module) {
|
||||
foreach ($module as $m) {
|
||||
if (!$db->tableExists($prefix . $siteid . '_' . $m['dirname'])) {
|
||||
continue;
|
||||
}
|
||||
// 增加长度
|
||||
$table = $prefix . $siteid . '_' . $m['dirname'];
|
||||
if ($db->fieldExists('inputip', $table)) {
|
||||
$T->edit_field($table, 'inputip', 'VARCHAR(100)', 'NOT NULL', '客户端ip信息');
|
||||
}
|
||||
$table = $prefix . $siteid . '_' . $m['dirname'] . '_recycle';
|
||||
if ($db->tableExists($table)) {
|
||||
// 创建字段 删除理由
|
||||
if (!$db->fieldExists('result', $table)) {
|
||||
$T->add_field($table, 'result', 'Text', 'NOT NULL', '');
|
||||
}
|
||||
}
|
||||
$table = $prefix . $siteid . '_' . $m['dirname'] . '_support';
|
||||
if ($db->tableExists($table)) {
|
||||
// 创建字段 游客点赞
|
||||
if (!$db->fieldExists('agent', $table)) {
|
||||
$T->add_field($table, 'agent', 'VARCHAR(200)', 'DEFAULT NULL', '');
|
||||
}
|
||||
}
|
||||
$table = $prefix . $siteid . '_' . $m['dirname'] . '_oppose';
|
||||
if ($db->tableExists($table)) {
|
||||
// 创建字段 游客点赞
|
||||
if (!$db->fieldExists('agent', $table)) {
|
||||
$T->add_field($table, 'agent', 'VARCHAR(200)', 'DEFAULT NULL', '');
|
||||
}
|
||||
}
|
||||
$table = $prefix . $siteid . '_' . $m['dirname'] . '_verify';
|
||||
if (!$db->fieldExists('vid', $table)) {
|
||||
$T->add_field($table, 'vid', 'INT(10)', 'DEFAULT NULL', '');
|
||||
}
|
||||
if (!$db->fieldExists('islock', $table)) {
|
||||
$T->add_field($table, 'islock', 'tinyint(1)', 'DEFAULT NULL', '');
|
||||
}
|
||||
// 点击时间
|
||||
$table = $prefix . $siteid . '_' . $m['dirname'] . '_hits';
|
||||
foreach (['day_time', 'week_time', 'month_time', 'year_time'] as $a) {
|
||||
if (!$db->fieldExists($a, $table)) {
|
||||
$T->add_field($table, $a, 'INT(10)', 'DEFAULT NULL', '');
|
||||
}
|
||||
}
|
||||
$table = $prefix . $siteid . '_' . $m['dirname'] . '_category';
|
||||
if ($db->tableExists($table)) {
|
||||
if (!$db->fieldExists('disabled', $table)) {
|
||||
$T->add_field($table, 'disabled', 'tinyint(1)', "DEFAULT '0'", '');
|
||||
$db->table($table)->update(['disabled' => 0]);
|
||||
}
|
||||
$db->table($table)->where('disabled', null)->update(['disabled' => 0]);
|
||||
if (!$db->fieldExists('ismain', $table)) {
|
||||
$T->add_field($table, 'ismain', 'tinyint(1)', "DEFAULT '0'", '');
|
||||
$db->table($table)->update(['ismain' => 1]);
|
||||
}
|
||||
}
|
||||
// 栏目模型字段修正
|
||||
$db->table('field')->where('relatedname', $m['dirname'] . '-' . $siteid)->update(['relatedname' => 'catmodule-' . $m['dirname']]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$this->_html_msg(1, dr_lang('正在升级数据表结构'), $next.'&page='.($page+1));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
\Phpcmf\Service::M('cache')->update_db();
|
||||
\Phpcmf\Service::M('cache')->update_cache();
|
||||
\Phpcmf\Service::M('cache')->update_data_cache();
|
||||
$this->_html_msg(1, dr_lang('更新完成'));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php namespace Phpcmf\Control\Admin;
|
||||
|
||||
|
||||
class Category extends \Phpcmf\Admin\Category
|
||||
{
|
||||
|
||||
public function index() {
|
||||
$this->_Admin_List();
|
||||
}
|
||||
|
||||
public function all_add() {
|
||||
$this->_Admin_All_Add();
|
||||
}
|
||||
|
||||
public function add() {
|
||||
$this->_Admin_Add();
|
||||
}
|
||||
|
||||
public function edit() {
|
||||
$this->_Admin_Edit();
|
||||
}
|
||||
|
||||
public function url_edit() {
|
||||
$this->_Admin_Url_Edit();
|
||||
}
|
||||
|
||||
public function move_edit() {
|
||||
$this->_Admin_Move_Edit();
|
||||
}
|
||||
|
||||
public function show_edit() {
|
||||
$this->_Admin_Show_Edit();
|
||||
}
|
||||
|
||||
public function displayorder_edit() {
|
||||
$this->_Admin_Order();
|
||||
}
|
||||
|
||||
public function html_edit() {
|
||||
$this->_Admin_Html_Edit();
|
||||
}
|
||||
|
||||
public function htmlall_edit() {
|
||||
$this->_Admin_Html_All_Edit();
|
||||
}
|
||||
|
||||
public function phpall_edit() {
|
||||
$this->_Admin_Php_All_Edit();
|
||||
}
|
||||
|
||||
public function del() {
|
||||
$this->_Admin_Del();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,563 @@
|
||||
<?php namespace Phpcmf\Control\Admin;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
class Check extends \Phpcmf\Common
|
||||
{
|
||||
|
||||
private $_list = [
|
||||
|
||||
'01' => '文件上传检测',
|
||||
'02' => 'PHP环境检测',
|
||||
'03' => '目录权限检测',
|
||||
'15' => '服务器环境检测',
|
||||
'04' => '后台入口名称检测',
|
||||
'05' => '数据库权限检测',
|
||||
'06' => '模板完整性检测',
|
||||
//'07' => '数据库表结构检测',
|
||||
//'08' => '程序兼容性检测',
|
||||
'09' => '项目安全性检测',
|
||||
'10' => '数据负载优化检测',
|
||||
'12' => 'HTTPS检测',
|
||||
'13' => '应用插件兼容性检测',
|
||||
'16' => '自动任务配置检测',
|
||||
|
||||
];
|
||||
|
||||
public function index() {
|
||||
|
||||
if (IS_USE_MODULE) {
|
||||
$this->_list['14'] = '移动端检测';
|
||||
$this->_list['11'] = '移动端检测';
|
||||
}
|
||||
|
||||
if (is_file(WRITEPATH.'install.info')) {
|
||||
unlink(WRITEPATH.'install.info');
|
||||
unlink(WRITEPATH.'install.error');
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'menu' => \Phpcmf\Service::M('auth')->_admin_menu(
|
||||
[
|
||||
'系统体检' => [\Phpcmf\Service::L('Router')->class.'/index', 'fa fa-wrench'],
|
||||
'系统更新' => ['cache/index', 'fa fa-refresh'],
|
||||
'PHP环境' => [\Phpcmf\Service::L('Router')->class.'/php_index', 'fa fa-code'],
|
||||
'SERVER变量' => [\Phpcmf\Service::L('Router')->class.'/server_index', 'fa fa-cog'],
|
||||
]
|
||||
),
|
||||
'list' => $this->_list,
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('check_index.html');
|
||||
}
|
||||
|
||||
public function do_index() {
|
||||
|
||||
$id = $_GET['id'];
|
||||
|
||||
switch ($id) {
|
||||
|
||||
case '01':
|
||||
|
||||
$post = intval(ini_get("post_max_size"));
|
||||
$file = intval(ini_get("upload_max_filesize"));
|
||||
|
||||
if ($file > $post) {
|
||||
$this->_json(0,dr_lang('系统配置不合理,post_max_size值(%s)必须大于upload_max_filesize值(%s)', $post, $file));
|
||||
} elseif ($file < 10) {
|
||||
$this->_json(1,dr_lang('系统环境只允许上传%sMB文件,可以设置upload_max_filesize值提升上传大小', $file));
|
||||
} elseif ($post < 10) {
|
||||
$this->_json(1,dr_lang('系统环境要求每次发布内容不能超过%sMB(含文件),可以设置post_max_size值提升发布大小', $post));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case '02':
|
||||
|
||||
$rt = [];
|
||||
if (!function_exists('mb_substr')) {
|
||||
$rt[] = dr_lang('PHP不支持mbstring扩展,必须开启');
|
||||
}
|
||||
if (!function_exists('imagettftext')) {
|
||||
$rt[] = dr_lang('PHP扩展库:GD库未安装或GD库版本太低,可能无法正常显示验证码和图片缩略图');
|
||||
}
|
||||
if (!function_exists('curl_init')) {
|
||||
$rt[] = dr_lang('PHP不支持CURL扩展,必须开启');
|
||||
}
|
||||
if (!function_exists('mb_convert_encoding')) {
|
||||
$rt[] = dr_lang('PHP的mb函数不支持,无法使用百度关键词接口');
|
||||
}
|
||||
if (!function_exists('imagecreatetruecolor')) {
|
||||
$rt[] = dr_lang('PHP的GD库版本太低,无法支持验证码图片');
|
||||
}
|
||||
if (!function_exists('ini_get')) {
|
||||
$rt[] = dr_lang('系统函数ini_get未启用,将无法获取到系统环境参数');
|
||||
}
|
||||
if (!function_exists('gzopen')) {
|
||||
$rt[] = dr_lang('zlib扩展未启用,您将无法进行在线升级、无法下载应用插件等');
|
||||
}
|
||||
if (!function_exists('gzinflate')) {
|
||||
$rt[] = dr_lang('函数gzinflate未启用,您将无法进行在线升级、无法下载应用插件等');
|
||||
}
|
||||
if (!function_exists('fsockopen')) {
|
||||
$rt[] = dr_lang('PHP不支持fsockopen,可能充值接口无法使用、手机短信无法发送、电子邮件无法发送、一键登录无法登录等');
|
||||
}
|
||||
if (!function_exists('openssl_open')) {
|
||||
$rt[] = dr_lang('PHP不支持openssl,可能充值接口无法使用、手机短信无法发送、电子邮件无法发送、一键登录无法登录等');
|
||||
}
|
||||
if (!ini_get('allow_url_fopen')) {
|
||||
$rt[] = dr_lang('allow_url_fopen未启用,远程图片无法保存、网络图片无法上传、可能充值接口无法使用、手机短信无法发送、电子邮件无法发送、一键登录无法登录等');
|
||||
}
|
||||
if (!class_exists('ZipArchive')) {
|
||||
$rt[] = dr_lang('php_zip扩展未开启,无法使用应用市场功能');
|
||||
}
|
||||
$url = 'https://www.xunruicms.com/';
|
||||
if ($this->cmf_license['cloud']) {
|
||||
$url = $this->cmf_license['cloud'];
|
||||
}
|
||||
if (!fopen($url, "rb")) {
|
||||
$rt[] = dr_lang('fopen无法获取远程数据,无法使用在线下载插件和在线升级');
|
||||
}
|
||||
|
||||
if ($rt) {
|
||||
$this->halt(implode('<br>', $rt), 0);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case '03':
|
||||
|
||||
list($thumb_path) = dr_thumb_path();
|
||||
list($avatar_path) = dr_avatar_path();
|
||||
|
||||
$rt = [];
|
||||
$dir = [
|
||||
WRITEPATH => '无法生成系统缓存文件',
|
||||
$avatar_path => '无法上传头像',
|
||||
WRITEPATH.'cloud/' => '无法下载应用插件',
|
||||
WRITEPATH.'data/' => '无法生成系统配置文件,会导致系统配置无效',
|
||||
WRITEPATH.'file/' => '无法生成系统缓存文件,会导致系统无法运行',
|
||||
$thumb_path => '无法生成缩略图缓存文件',
|
||||
SYS_UPLOAD_PATH => '无法上传附件',
|
||||
APPSPATH => '无法创建模块、创建表单、下载应用插件',
|
||||
TPLPATH => '无法创建模块模板和应用插件模板',
|
||||
];
|
||||
|
||||
foreach ($dir as $path => $note) {
|
||||
if (!is_dir($path)) {
|
||||
dr_mkdirs($path);
|
||||
}
|
||||
if (!dr_check_put_path($path)) {
|
||||
$rt[] = dr_lang($note).'【'.(IS_DEV ? $path : dr_safe_replace_path($path)).'】';
|
||||
}
|
||||
}
|
||||
|
||||
if ($rt) {
|
||||
$this->halt(implode('<br>', $rt), 0);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case '04':
|
||||
if (SELF == 'admin.php') {
|
||||
$this->halt(dr_lang('为了系统安全,请修改根目录admin.php的文件名'), 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case '05':
|
||||
|
||||
$field = \Phpcmf\Service::M('table')->show_full_colunms(\Phpcmf\Service::M()->dbprefix('admin'));
|
||||
if (!$field) {
|
||||
$this->halt(dr_lang('无法获取到数据表字段结构,请检查数据库账号是否具备读取表结构的权限'), 0);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case '06':
|
||||
|
||||
// 语言文件兼容处理
|
||||
if (is_dir(CONFIGPATH.'language/') && !is_dir(CONFIGPATH.'language/')) {
|
||||
\Phpcmf\Service::L('file')->copy_dir(CONFIGPATH.'language/', CONFIGPATH.'language/', ROOTPATH.'api/language/');
|
||||
}
|
||||
|
||||
$rt = [];
|
||||
|
||||
// 语言文件
|
||||
$lang = dr_catcher_data(LANG_PATH.'lang.js', 5, false);
|
||||
if ($lang && strlen($lang) < 10) {
|
||||
$rt[] = dr_lang('语言JS文件异常:%s', LANG_PATH.'lang.js');
|
||||
} elseif ($lang && strpos($lang, 'finecms_datepicker_lang') === false) {
|
||||
$rt[] = dr_lang('语言JS文件异常:%s', LANG_PATH.'lang.js');
|
||||
}
|
||||
|
||||
// 模板文件
|
||||
if (!is_file(TPLPATH.'pc/'.SITE_TEMPLATE.'/home/index.html')) {
|
||||
$rt[] = dr_lang('前端模板【电脑版】不存在:%s', 'TPLPATH/pc/'.SITE_TEMPLATE.'/home/index.html');
|
||||
}
|
||||
if (IS_USE_MEMBER) {
|
||||
if (!is_file(TPLPATH.'pc/'.SITE_TEMPLATE.'/member/index.html')) {
|
||||
$rt[] = dr_lang('用户中心模板【电脑版】不存在:%s', 'TPLPATH/pc/'.SITE_TEMPLATE.'/member/index.html');
|
||||
} elseif (!is_file(TPLPATH.'pc/'.SITE_TEMPLATE.'/member/msg.html')) {
|
||||
$rt[] = dr_lang('用户中心模板【电脑版】不存在:%s', 'TPLPATH/pc/'.SITE_TEMPLATE.'/member/msg.html');
|
||||
}
|
||||
}
|
||||
// 必备模板检测
|
||||
foreach (['msg.html', '404.html'] as $tt) {
|
||||
if (!is_file(TPLPATH.'pc/'.SITE_TEMPLATE.'/home/'.$tt)) {
|
||||
$rt[] = dr_lang('前端模板【电脑版】不存在:%s', 'TPLPATH/pc/'.SITE_TEMPLATE.'/home/'.$tt);
|
||||
}
|
||||
}
|
||||
|
||||
if ($rt) {
|
||||
$this->halt(implode('<br>', $rt), 0);
|
||||
}
|
||||
|
||||
// 移动端模板检测
|
||||
if (!is_file(TPLPATH.'mobile/'.SITE_TEMPLATE.'/home/index.html')) {
|
||||
$this->halt(dr_lang('前端模板【手机版】不存在:%s', 'TPLPATH/mobile/'.SITE_TEMPLATE.'/home/index.html'), 1);
|
||||
}
|
||||
|
||||
if (IS_USE_MEMBER) {
|
||||
if (!is_file(TPLPATH.'mobile/'.SITE_TEMPLATE.'/member/index.html')) {
|
||||
$this->halt(dr_lang('用户中心模板【手机版】不存在:%s', 'TPLPATH/mobile/'.SITE_TEMPLATE.'/member/index.html'), 1);
|
||||
} elseif (!is_file(TPLPATH.'mobile/'.SITE_TEMPLATE.'/member/msg.html')) {
|
||||
$this->halt(dr_lang('用户中心模板【手机版】不存在:%s', 'TPLPATH/mobile/'.SITE_TEMPLATE.'/member/msg.html'), 1);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case '07':
|
||||
|
||||
|
||||
break;
|
||||
|
||||
case '08':
|
||||
// 程序兼容性
|
||||
|
||||
break;
|
||||
|
||||
case '09':
|
||||
$rt = [];
|
||||
// 搜索根目录
|
||||
$local = dr_file_map(WEBPATH, 1); // 搜索根目录
|
||||
foreach ($local as $file) {
|
||||
if (in_array(strtolower(substr(strrchr($file, '.'), 1)), ['zip', 'rar', 'sql'])) {
|
||||
$rt[] = dr_lang('文件不安全【%s】请及时清理', '/'.$file.'');
|
||||
}
|
||||
$str = file_get_contents(WEBPATH.$file, 0, null, 0, 9286630);
|
||||
if ($str && strlen($str) >= 9286630) {
|
||||
$rt[] = dr_lang('存在大文件文件【%s】请及时清理', '/'.$file.'');
|
||||
}
|
||||
}
|
||||
|
||||
if (is_file(WEBPATH.'cache/api.php')) {
|
||||
$code = dr_catcher_data(SITE_URL.'cache/api.php/test', 5, false);
|
||||
if (strpos($code, 'phpcmf') !== false) {
|
||||
$rt[] = '<a href="javascript:dr_help(1005);">'.dr_lang('目录[cache]需要设置禁止访问');
|
||||
}
|
||||
}
|
||||
|
||||
$code = file_get_contents(WEBPATH.'index.php');
|
||||
if ($code && substr_count($code, '<?php') > 1) {
|
||||
$rt[] = dr_lang('首页入口文件index.php疑似被篡改');
|
||||
}
|
||||
|
||||
if (function_exists('ini_get')) {
|
||||
$pfile = ini_get('auto_prepend_file');
|
||||
if ($pfile) {
|
||||
$rt[] = '<font color="#ff7f50">'.dr_lang('php.ini中auto_prepend_file参数疑似可疑代码:%s', dr_strcut($pfile, 20));
|
||||
}
|
||||
$afile = ini_get('auto_append_file');
|
||||
if ($afile) {
|
||||
$rt[] = '<font color="#ff7f50">'.dr_lang('php.ini中auto_append_file参数疑似可疑代码:%s', dr_strcut($afile, 20));
|
||||
}
|
||||
}
|
||||
|
||||
if (!dr_is_app('safe')) {
|
||||
$rt[] = '<font color="green">'.dr_lang('安装「系统安全加固」插件可以大大提高安全等级');
|
||||
}
|
||||
|
||||
if ($rt) {
|
||||
$this->halt(implode('<br>', $rt), 0);
|
||||
}
|
||||
|
||||
$this->_json(1,dr_lang('完成'));
|
||||
break;
|
||||
|
||||
case '10':
|
||||
// 数据负载
|
||||
$rt = [];
|
||||
// 任务队列
|
||||
$cron = \Phpcmf\Service::M()->table('cron')->counts();
|
||||
if ($cron > 10) {
|
||||
$rt[] = '<font color="red">'.dr_lang('【任务队列】含有大量未执行的任务,会影响加载速度,建议删除不需要的任务').'</font>';
|
||||
}
|
||||
// 模块数据检测
|
||||
if (IS_USE_MODULE) {
|
||||
$module = \Phpcmf\Service::M()->table('module')->getAll();
|
||||
if ($module) {
|
||||
foreach ($module as $m) {
|
||||
$site = dr_string2array($m['site']);
|
||||
$mform = \Phpcmf\Service::M()->is_table_exists('module_form') ? \Phpcmf\Service::M()->table('module_form')->where('module', $m['dirname'])->getAll() : [];
|
||||
foreach ($this->site_info as $siteid => $s) {
|
||||
if (isset($site[$siteid]) && $site[$siteid]) {
|
||||
$r = $this->_check_table_counts($siteid . '_' . $m['dirname'], $m['dirname'] . dr_lang('模块主表'));
|
||||
$r && $rt[] = $r;
|
||||
if ($mform) {
|
||||
foreach ($mform as $mm) {
|
||||
$r = $this->_check_table_counts(
|
||||
$siteid . '_' . $m['dirname'] . '_form_' . $mm['table'],
|
||||
$m['dirname'] . dr_lang('模块') . $mm['name'] . dr_lang('表')
|
||||
);
|
||||
$r && $rt[] = $r;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($rt) {
|
||||
$this->halt(implode('<br>', $rt), 0);
|
||||
}
|
||||
|
||||
$this->_json(1,dr_lang('正常'));
|
||||
break;
|
||||
|
||||
case '11':
|
||||
|
||||
// 域名检测
|
||||
if (!function_exists('stream_context_create')) {
|
||||
$this->halt(dr_lang('函数没有被启用:%s', 'stream_context_create'), 0);
|
||||
}
|
||||
|
||||
$error = $tips = [];
|
||||
list($a, $data) = \Phpcmf\Service::M('Site')->domain();
|
||||
if ($data) {
|
||||
foreach ($data as $name => $domain) {
|
||||
$url = '';
|
||||
$cname = '';
|
||||
if ($name == 'mobile_domain') {
|
||||
if ($domain) {
|
||||
$url = dr_http_prefix($domain) . '/api.php';
|
||||
} else {
|
||||
$tips[] = dr_lang('当前站点没有绑定手机域名,可能无法使用移动端界面');
|
||||
}
|
||||
$cname = '移动端';
|
||||
} elseif (strpos($name, 'module_') === 0) {
|
||||
// 模块
|
||||
if ($domain) {
|
||||
$url = dr_http_prefix($domain) . '/api.php';
|
||||
}
|
||||
$cname = '模块';
|
||||
} elseif (strpos($name, 'client_') === 0) {
|
||||
// 终端
|
||||
if ($domain) {
|
||||
$url = dr_http_prefix($domain) . '/api.php';
|
||||
}
|
||||
$cname = '终端';
|
||||
}
|
||||
|
||||
if ($url && $cname) {
|
||||
$code = dr_catcher_data($url, 5, false);
|
||||
if ($code != 'phpcmf ok') {
|
||||
$error[] = dr_lang('[%s]域名绑定异常,无法访问:%s,可以尝试手动访问此地址,如果提示phpcmf ok就表示成功', dr_lang($cname), $url);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 验证附件域名
|
||||
list($a, $b) = dr_thumb_path();
|
||||
list($c, $d) = dr_avatar_path();
|
||||
$domain = [
|
||||
['name' => dr_lang('附件域名'), 'path' => SYS_UPLOAD_PATH, 'url' => SYS_UPLOAD_URL],
|
||||
['name' => dr_lang('缩略图域名'), 'path' => $a, 'url' => $b],
|
||||
['name' => dr_lang('头像域名'), 'path' => $c, 'url' => $d],
|
||||
];
|
||||
foreach ($domain as $t) {
|
||||
if (!file_put_contents($t['path'].'api.html', 'phpcmf ok')) {
|
||||
$this->_json(0, (IS_DEV ? $t['path'] : dr_safe_replace_path($t['path'])).' '.dr_lang('无法写入文件'));
|
||||
}
|
||||
$code = dr_catcher_data($t['url'].'api.html', 5, false);
|
||||
if ($code != 'phpcmf ok') {
|
||||
$error[] = dr_lang('[%s]异常,无法访问:%s,可以尝试手动访问此地址,如果提示phpcmf ok就表示成功', $t['name'], $t['url'].'api.html');
|
||||
}
|
||||
}
|
||||
|
||||
// 重复验证
|
||||
if (is_file(WRITEPATH.'config/domain_sso.php')) {
|
||||
$domains = require WRITEPATH.'config/domain_sso.php';
|
||||
if ($domains) {
|
||||
// 获取去掉重复数据的数组
|
||||
$unique_arr = array_unique ( $domains );
|
||||
// 获取重复数据的数组
|
||||
$repeat_arr = array_diff_assoc ( $domains, $unique_arr );
|
||||
if ($repeat_arr) {
|
||||
foreach ($repeat_arr as $t) {
|
||||
$error[] = dr_lang('域名【%s】被多处重复配置,可能会影响到此域名的作用域或访问异常', $t);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ($error) {
|
||||
$this->_json(0, implode('<br>', $error));
|
||||
} elseif ($tips) {
|
||||
$this->_json(1, implode('<br>', $tips));
|
||||
} else {
|
||||
$this->_json(1, dr_lang(dr_lang('完成')));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case '12':
|
||||
// https
|
||||
if (SYS_HTTPS) {
|
||||
if (strpos(FC_NOW_URL, 'https://') !== false) {
|
||||
$this->_json(1,dr_lang('正常'));
|
||||
} else {
|
||||
$this->_json(0,'<a href="javascript:dr_help(751);">'.dr_lang('服务器无法识别HTTPS证书,查看解决方案').'</a>');
|
||||
}
|
||||
} else {
|
||||
$this->_json(0,'<a href="javascript:dr_help(668);">'.dr_lang('系统没有开启HTTPS服务,查看解决方案').'</a>');
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case '13':
|
||||
// 应用插件
|
||||
$func = [];
|
||||
$local = \Phpcmf\Service::Apps();
|
||||
$custom = file_get_contents(CONFIGPATH.'custom.php');
|
||||
foreach ($local as $dir => $path) {
|
||||
if (is_file($path.'Config/App.php')) {
|
||||
// 变量重定义
|
||||
if (is_file($path.'Config/Init.php')) {
|
||||
$code = file_get_contents($path.'Config/Init.php');
|
||||
if (preg_match_all("/\s+function (.+)\(/", $code, $arr)) {
|
||||
foreach ($arr[1] as $a) {
|
||||
$name = trim($a);
|
||||
if (strpos($name, "'") !== false) {
|
||||
continue;
|
||||
}
|
||||
if (isset($func[$name]) && $func[$name]) {
|
||||
$this->_json(0,dr_lang('应用[%s]中的函数[%s]存在于%s之中,不能被重复定义', $dir, $name, $func[$name]));
|
||||
}
|
||||
$func[$name] = $dir;
|
||||
if (function_exists($name)) {
|
||||
if (preg_match("/\s+function ".$name."\(/", $custom)) {
|
||||
// 存在于自定义函数库中
|
||||
} else {
|
||||
$this->_json(0, dr_lang('应用[%s]中的函数[%s]是系统函数,不能定义', $dir, $name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_file(ROOTPATH.'static/assets/js/my.js') && is_dir(ROOTPATH.'static/assets/js/')) {
|
||||
@file_put_contents(ROOTPATH.'static/assets/js/my.js', '');
|
||||
}
|
||||
|
||||
$this->_json(1, dr_lang(dr_lang('完成')));
|
||||
|
||||
break;
|
||||
|
||||
case '14':
|
||||
// 移动端检测
|
||||
|
||||
$error = [];
|
||||
|
||||
// 开起自动识别,又开启了首页静态
|
||||
if ($this->site_info[SITE_ID]['SITE_AUTO'] && $this->site_info[SITE_ID]['SITE_INDEX_HTML']) {
|
||||
$error[] = '<a href="javascript:dr_help(664);">'.dr_lang('当前站点已经开启[首页静态]模式,将无法实现移动端自动跳转功能,查看解决方案').'</a>';
|
||||
}
|
||||
|
||||
$config = $this->get_cache('site', SITE_ID, 'mobile');
|
||||
if (!$this->site_info[SITE_ID]['SITE_IS_MOBILE'] && $config && $config['tohtml']) {
|
||||
$error[] = '<a href="javascript:dr_help(506);">'.dr_lang('当前站点没有绑定移动端域名,将无法实现移动端静态页面功能,查看解决方案').'</a>';
|
||||
}
|
||||
|
||||
if ($error) {
|
||||
$this->_json(0, implode('<br>', $error));
|
||||
}
|
||||
|
||||
// 单独域名判断
|
||||
if (!$this->site_info[SITE_ID]['SITE_IS_MOBILE']) {
|
||||
$this->_json(1,dr_lang('当前项目没有绑定移动端域名'));
|
||||
}
|
||||
|
||||
$this->_json(1, dr_lang(dr_lang('完成')));
|
||||
break;
|
||||
|
||||
case '15':
|
||||
// 服务器环境
|
||||
if (is_file(ROOTPATH.'test.php')) {
|
||||
$error[] = dr_lang('根目录检测文件test.php,当项目正式上线后需要删除,以免影响网站安全');
|
||||
}
|
||||
if (IS_DEV) {
|
||||
$error[] = dr_lang('根目录index.php中的开发者模式已开启,当项目正式上线后需要关闭,以免影响网站安全');
|
||||
}
|
||||
|
||||
if ($error) {
|
||||
$this->_json(0, implode('<br>', $error));
|
||||
}
|
||||
|
||||
$this->_json(1, dr_lang(dr_lang('完成')));
|
||||
break;
|
||||
|
||||
case '16':
|
||||
// 自动任务检测
|
||||
if (is_file(WRITEPATH.'config/run_time.php')) {
|
||||
$time = file_get_contents(WRITEPATH.'config/run_time.php');
|
||||
$this->_json(1, dr_lang('最近执行时间:%s', $time));
|
||||
}
|
||||
|
||||
$this->_json(0, '<a href="javascript:dr_help(353);">'.dr_lang('没有配置自动任务功能,无法自动清理缓存和更新缓存,查看解决方案').'</a>');
|
||||
break;
|
||||
|
||||
case '99':
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
$this->_json(1, dr_lang(dr_lang('完成')));
|
||||
}
|
||||
|
||||
public function php_index() {
|
||||
phpinfo();
|
||||
}
|
||||
|
||||
public function server_index() {
|
||||
echo '<pre style="background: #f1f5f8;padding: 10px">';
|
||||
print_r($_SERVER);
|
||||
}
|
||||
|
||||
private function halt($msg, $code) {
|
||||
$this->_json($code, $msg);
|
||||
}
|
||||
|
||||
private function _check_table_counts($table, $name) {
|
||||
|
||||
$ptable = \Phpcmf\Service::M()->dbprefix($table);
|
||||
if (!\Phpcmf\Service::M()->db->tableExists($ptable)) {
|
||||
return dr_lang('数据表【%s】不存在,请创建', $name.'/'.$ptable);
|
||||
}
|
||||
|
||||
$counts = \Phpcmf\Service::M()->table($table)->counts();
|
||||
if ($counts > 1000000) {
|
||||
return '<font color="green">'.dr_lang('数据表【%s】数据量超过100万,会影响加载速度,建议对其进行数据优化', $name.'/'.$ptable).'</font>';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,153 @@
|
||||
<?php namespace Phpcmf\Control\Admin;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
// 任务队列
|
||||
class Cron extends \Phpcmf\Table
|
||||
{
|
||||
|
||||
private $type;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'menu' => \Phpcmf\Service::M('auth')->_admin_menu(
|
||||
[
|
||||
'任务管理' => [\Phpcmf\Service::L('Router')->class.'/index', 'fa fa-indent'],
|
||||
'任务设置' => ['add:'.\Phpcmf\Service::L('Router')->class.'/edit', 'fa fa-cog'],
|
||||
'help' => [353],
|
||||
]
|
||||
)
|
||||
]);
|
||||
// 表单显示名称
|
||||
$this->name = dr_lang('任务队列');
|
||||
$this->is_data = 0;
|
||||
// 初始化数据表
|
||||
$this->_init([
|
||||
'table' => 'cron',
|
||||
'field' => [
|
||||
'type' => [
|
||||
'ismain' => 1,
|
||||
'fieldtype' => 'Text',
|
||||
'fieldname' => 'type',
|
||||
],
|
||||
],
|
||||
'date_field' => 'inputtime',
|
||||
'order_by' => 'id desc,status asc',
|
||||
]);
|
||||
// 任务类别
|
||||
$this->type = [
|
||||
'email' => dr_lang('邮件发送'),
|
||||
'notice' => dr_lang('消息通知'),
|
||||
];
|
||||
}
|
||||
|
||||
// 任务管理
|
||||
public function index() {
|
||||
|
||||
list($tpl, $data) = $this->_List();
|
||||
if ($data['list']) {
|
||||
foreach ($data['list'] as $i => $t) {
|
||||
$data['list'][$i]['value'] = ('<pre>'.str_replace([PHP_EOL, "'", '"'], ["<br>", "", ""], var_export(dr_string2array($t['value']), true)).'</pre>');
|
||||
$t['error'] && $data['list'][$i]['error'] = ('<pre>'.str_replace([PHP_EOL, "'", '"'], ["<br>", "", ""], var_export(dr_string2array($t['error']), true)).'</pre>');
|
||||
}
|
||||
}
|
||||
|
||||
$run_time = '';
|
||||
if (is_file(WRITEPATH.'config/run_time.php')) {
|
||||
$run_time = file_get_contents(WRITEPATH.'config/run_time.php');
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'type' => $this->type,
|
||||
'list' => $data['list'],
|
||||
'run_time' => $run_time,
|
||||
]);
|
||||
\Phpcmf\Service::V()->display($tpl);
|
||||
}
|
||||
|
||||
public function edit() {
|
||||
|
||||
if (is_file(WRITEPATH.'config/system.php')) {
|
||||
$data = require WRITEPATH.'config/system.php';
|
||||
} else {
|
||||
$data = [];
|
||||
}
|
||||
|
||||
if (IS_POST) {
|
||||
$post = \Phpcmf\Service::L('input')->post('data', true);
|
||||
\Phpcmf\Service::M('System')->save_config($data, [
|
||||
'SYS_CRON_AUTH' => dr_safe_replace($post['SYS_CRON_AUTH'] ?? ''),
|
||||
]);
|
||||
\Phpcmf\Service::L('input')->system_log('设置自动任务权限');
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'data' => $data,
|
||||
'form' => dr_form_hidden(),
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('cron_edit.html');
|
||||
}
|
||||
|
||||
public function show() {
|
||||
|
||||
list($tpl, $data) = $this->_Show(\Phpcmf\Service::L('input')->get('id'));
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'show_error' => var_export(dr_string2array($data['error']), true),
|
||||
'show_value' => var_export(dr_string2array($data['value']), true),
|
||||
]);
|
||||
\Phpcmf\Service::V()->display($tpl);exit;
|
||||
}
|
||||
|
||||
// 后台删除任务
|
||||
public function del() {
|
||||
$this->_Del(
|
||||
\Phpcmf\Service::L('input')->get_post_ids(),
|
||||
null,
|
||||
null,
|
||||
\Phpcmf\Service::M()->dbprefix($this->init['table'])
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// 执行任务
|
||||
public function post_add() {
|
||||
|
||||
$ids = \Phpcmf\Service::L('input')->get_post_ids();
|
||||
if ($ids) {
|
||||
foreach ($ids as $id) {
|
||||
\Phpcmf\Service::M('cron')->do_cron_id($id);
|
||||
//\Phpcmf\Service::L('thread')->cron(['action' => 'cron', 'id' => $id ], 1);
|
||||
}
|
||||
$this->_json(1, dr_lang('任务已提交,等待执行结果'));
|
||||
} else {
|
||||
$this->_json(0, dr_lang('所选数据不存在'));
|
||||
}
|
||||
}
|
||||
|
||||
// 单个执行任务
|
||||
public function do_add() {
|
||||
|
||||
$id = (int)\Phpcmf\Service::L('input')->get('id');
|
||||
if (!$id) {
|
||||
$this->_json(0, dr_lang('所选数据不存在'));
|
||||
}
|
||||
|
||||
$rt = \Phpcmf\Service::M('cron')->do_cron_id($id);
|
||||
if (!$rt['code']) {
|
||||
$this->_json(0, $rt['msg']);
|
||||
}
|
||||
|
||||
$this->_json(1, dr_lang('任务执行完成'));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php namespace Phpcmf\Control\Admin;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
class Debug extends \Phpcmf\Common
|
||||
{
|
||||
|
||||
public function index() {
|
||||
|
||||
$this->_echo_msg(IS_DEV ? 1 : 0, '开发者模式:'.(IS_DEV ? '已开启' : '未开启'));
|
||||
$this->_echo_msg(1, '客户端字符串:'.$_SERVER['HTTP_USER_AGENT']);
|
||||
$this->_echo_msg(1, 'PHP版本:'.PHP_VERSION.'');
|
||||
$db = \Phpcmf\Service::M()->db;
|
||||
$driver = isset($db->DBDriver) ? $db->DBDriver : 'unknown';
|
||||
$this->_echo_msg(1, '数据库驱动:'.$driver);
|
||||
$this->_echo_msg(1, '数据库版本:'.$db->getVersion());
|
||||
|
||||
$this->_echo_msg(1, '内核版本:'.FRAME_NAME.' - '.FRAME_VERSION);
|
||||
$this->_echo_msg(1, 'CMS版本:'.$this->cmf_version['version'].' - '.dr_date($this->cmf_version['downtime'], 'Y-m-d H:i:s'));
|
||||
$local = \Phpcmf\Service::Apps();
|
||||
foreach ($local as $dir => $path) {
|
||||
if (is_file($path.'Config/App.php')) {
|
||||
$key = strtolower($dir);
|
||||
$cfg = require $path.'Config/App.php';
|
||||
if (is_file($path.'Config/Version.php')) {
|
||||
$vsn = require $path.'Config/Version.php';
|
||||
$this->_echo_msg(1, $cfg['name'].' - 版本:'.$vsn['version'].' - '.dr_date($vsn['downtime'], 'Y-m-d H:i:s'));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function _echo_msg($code, $msg) {
|
||||
echo '<div style="border-bottom: 1px dashed #9699a2; padding: 5px;">';
|
||||
if (!$code) {
|
||||
echo '<b style="color:red;text-decoration:none;">'.$msg.'</b>';
|
||||
} else {
|
||||
echo '<font color=green>'.$msg.'</font>';
|
||||
}
|
||||
echo '</div>';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
<?php namespace Phpcmf\Control\Admin;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
class Email extends \Phpcmf\Common
|
||||
{
|
||||
private $form; // 表单验证配置
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
\Phpcmf\Service::V()->assign('menu', \Phpcmf\Service::M('auth')->_admin_menu(
|
||||
[
|
||||
'邮件服务器' => ['email/index', 'fa fa-envelope'],
|
||||
'添加' => ['add:email/add', 'fa fa-plus', '600px'],
|
||||
'help' => [361],
|
||||
]
|
||||
));
|
||||
// 表单验证配置
|
||||
$this->form = [
|
||||
'host' => [
|
||||
'name' => '服务器',
|
||||
'rule' => [
|
||||
'empty' => dr_lang('服务器不能为空')
|
||||
],
|
||||
'filter' => [],
|
||||
'length' => '200'
|
||||
],
|
||||
'port' => [
|
||||
'name' => '端口号',
|
||||
'filter' => ['intval'],
|
||||
'length' => '30'
|
||||
],
|
||||
'user' => [
|
||||
'name' => '邮箱账号',
|
||||
'filter' => [],
|
||||
'rule' => [
|
||||
'empty' => dr_lang('邮箱账号不能为空')
|
||||
],
|
||||
'length' => '200'
|
||||
],
|
||||
'pass' => [
|
||||
'name' => '邮箱密码',
|
||||
'filter' => [],
|
||||
'length' => '200'
|
||||
],
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
public function index() {
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'list' => \Phpcmf\Service::M()->table('mail_smtp')->order_by('displayorder asc')->getAll(),
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('email_index.html');
|
||||
}
|
||||
|
||||
public function add() {
|
||||
|
||||
if (IS_AJAX_POST) {
|
||||
$data = \Phpcmf\Service::L('input')->post('data');
|
||||
if (\Phpcmf\Service::L('input')->post('type')) {
|
||||
$data['host'] = 'mail';
|
||||
}
|
||||
$this->_validation($data);
|
||||
\Phpcmf\Service::L('input')->system_log('添加SMTP服务器: '.$data['name']);
|
||||
$data['displayorder'] = intval($data['displayorder']);
|
||||
\Phpcmf\Service::M()->table('mail_smtp')->insert($data);
|
||||
// 自动更新缓存
|
||||
\Phpcmf\Service::M('cache')->sync_cache('email');
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'form' => dr_form_hidden()
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('email_add.html');
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
public function edit() {
|
||||
|
||||
$id = intval(\Phpcmf\Service::L('input')->get('id'));
|
||||
$data = \Phpcmf\Service::M()->table('mail_smtp')->get($id);
|
||||
if (!$data) {
|
||||
$this->_json(0, dr_lang('数据#%s不存在', $id));
|
||||
}
|
||||
|
||||
if (IS_AJAX_POST) {
|
||||
$data = \Phpcmf\Service::L('input')->post('data');
|
||||
$this->_validation($data);
|
||||
if ($data['pass'] == '******') {
|
||||
unset($data['pass']);
|
||||
}
|
||||
\Phpcmf\Service::M()->table('mail_smtp')->update($id, $data);
|
||||
\Phpcmf\Service::L('input')->system_log('修改邮件服务器: '.$data['name']);
|
||||
|
||||
\Phpcmf\Service::M('cache')->sync_cache('email'); // 自动更新缓存
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
|
||||
$data['pass'] = '******';
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'data' => $data,
|
||||
'form' => dr_form_hidden(),
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('email_add.html');
|
||||
exit;
|
||||
}
|
||||
|
||||
// 保存数据
|
||||
public function save_edit() {
|
||||
|
||||
$i = intval(\Phpcmf\Service::L('input')->get('id'));
|
||||
\Phpcmf\Service::M()->table('mail_smtp')->save(
|
||||
$i,
|
||||
dr_safe_replace(\Phpcmf\Service::L('input')->get('name')),
|
||||
dr_safe_replace(\Phpcmf\Service::L('input')->get('value'))
|
||||
);
|
||||
|
||||
\Phpcmf\Service::L('input')->system_log('修改邮件服务器排序值: '. $i);
|
||||
\Phpcmf\Service::M('cache')->sync_cache('email'); // 自动更新缓存
|
||||
|
||||
$this->_json(1, dr_lang('更改成功'));
|
||||
}
|
||||
|
||||
public function del() {
|
||||
|
||||
$ids = \Phpcmf\Service::L('input')->get_post_ids();
|
||||
if (!$ids) {
|
||||
$this->_json(0, dr_lang('你还没有选择呢'));
|
||||
}
|
||||
|
||||
\Phpcmf\Service::M()->table('mail_smtp')->deleteAll($ids);
|
||||
\Phpcmf\Service::M('cache')->sync_cache('email'); // 自动更新缓存
|
||||
\Phpcmf\Service::L('input')->system_log('批量删除邮件服务器: '. implode(',', $ids));
|
||||
|
||||
$this->_json(1, dr_lang('操作成功'), ['ids' => $ids]);
|
||||
}
|
||||
|
||||
|
||||
// 验证数据
|
||||
private function _validation($data) {
|
||||
list($data, $return) = \Phpcmf\Service::L('Form')->validation($data, $this->form);
|
||||
if ($return) {
|
||||
$this->_json(0, $return['error'], ['field' => $return['name']]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php namespace Phpcmf\Control\Admin;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
class Email_log extends \Phpcmf\Common
|
||||
{
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
\Phpcmf\Service::V()->assign('menu', \Phpcmf\Service::M('auth')->_admin_menu(
|
||||
[
|
||||
'错误日志' => ['email_log/index', 'fa fa-calendar'],
|
||||
]
|
||||
));
|
||||
}
|
||||
|
||||
public function index() {
|
||||
|
||||
$data = $list = [];
|
||||
$file = WRITEPATH.'email_log.txt';
|
||||
if (is_file(WRITEPATH.'email_log.txt')) {
|
||||
$data = explode(PHP_EOL, str_replace(array(chr(13), chr(10)), PHP_EOL, file_get_contents($file)));
|
||||
$data = $data ? array_reverse($data) : [];
|
||||
$page = max(1, (int)\Phpcmf\Service::L('input')->get('page'));
|
||||
$limit = ($page - 1) * SYS_ADMIN_PAGESIZE;
|
||||
$i = $j = 0;
|
||||
foreach ($data as $v) {
|
||||
if ($v && $i >= $limit && $j < SYS_ADMIN_PAGESIZE) {
|
||||
$list[] = $v;
|
||||
$j ++;
|
||||
}
|
||||
$i ++;
|
||||
}
|
||||
}
|
||||
|
||||
$total = $data ? max(0, count($data) - 1) : 0;
|
||||
|
||||
\Phpcmf\Service::V()->assign(array(
|
||||
'list' => $list,
|
||||
'total' => $total,
|
||||
'mypages' => \Phpcmf\Service::L('input')->page(\Phpcmf\Service::L('Router')->url('email_log/index'), $total, 'admin')
|
||||
));
|
||||
\Phpcmf\Service::V()->display('email_log.html');
|
||||
}
|
||||
|
||||
public function del() {
|
||||
|
||||
@unlink(WRITEPATH.'email_log.txt');
|
||||
|
||||
exit($this->_json(1, dr_lang('操作成功')));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
<?php namespace Phpcmf\Control\Admin;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
class Error extends \Phpcmf\Common {
|
||||
|
||||
public function index() {
|
||||
|
||||
$time = (int)strtotime(\Phpcmf\Service::L('input')->get('time'));
|
||||
!$time && $time = SYS_TIME;
|
||||
|
||||
$list = [];
|
||||
$total = 0;
|
||||
$file = WRITEPATH.'error/log-'.date('Y-m-d', $time).'.php';
|
||||
if (is_file($file)) {
|
||||
if (filesize($file) > 1024*1024*2) {
|
||||
$list[] = [
|
||||
'time' => date('Y-m-d', $time),
|
||||
'type' => '<span class="label label-warning"> '.dr_lang('提醒').' </span>',
|
||||
'message' => '此日志文件大于2MB,请使用Ftp等工具查看此文件:'.$file,
|
||||
];
|
||||
} else {
|
||||
$c = file_get_contents($file);
|
||||
$data = explode(PHP_EOL, trim(str_replace('<?php defined(\'BASEPATH\') OR exit(\'No direct script access allowed\'); ?>'.PHP_EOL.PHP_EOL, '', str_replace(array(chr(13), chr(10)), PHP_EOL, $c)), PHP_EOL));
|
||||
$data && $data = array_reverse($data);
|
||||
|
||||
$page = max(1, (int)\Phpcmf\Service::L('input')->get('page'));
|
||||
//$total = max(0, count($data));
|
||||
$total = max(0, substr_count($c, '- '.date('Y-m-d', $time).' '));
|
||||
$limit = ($page - 1) * SYS_ADMIN_PAGESIZE;
|
||||
|
||||
$i = $j = 0;
|
||||
|
||||
foreach ($data as $t) {
|
||||
if ($t && $i >= $limit && $j < SYS_ADMIN_PAGESIZE) {
|
||||
$v = explode(' --> ', $t);
|
||||
$time2 = $v ? explode(' - ', $v[0]) : [ 0 => '', 1 => '' ];
|
||||
if ($time2[1]) {
|
||||
$value = [
|
||||
'time' => $time2[1] ? $time2[1] : '',
|
||||
'type' => '',
|
||||
];
|
||||
if ($time2[0] == 'DEBUG') {
|
||||
$value['type'] = '<span class="label label-success"> '.dr_lang('调试').' </span>';
|
||||
} elseif ($time2[0] == 'INFO') {
|
||||
$value['type'] = '<span class="label label-default"> '.dr_lang('信息').' </span>';
|
||||
} elseif ($time2[0] == 'WARNING') {
|
||||
$value['type'] = '<span class="label label-warning"> '.dr_lang('提醒').' </span>';
|
||||
} else {
|
||||
$value['type'] = '<span class="label label-danger"> '.dr_lang('错误').' </span>';
|
||||
}
|
||||
if (strpos((string)$v[1], '{br}')) {
|
||||
// phpcmf模式
|
||||
$vv = explode('{br}', $v[1]);
|
||||
$value['message'] = $vv[0];
|
||||
unset($vv[0]);
|
||||
$value['json'] = str_replace("'", '\\\'', $vv[1]);
|
||||
unset($vv[1]);
|
||||
$value['info'] = '错误:'.$value['message'].'<br>';
|
||||
foreach ($vv as $p) {
|
||||
$value['info'].= $p.'<br>';
|
||||
}
|
||||
$value['info'] = str_replace("'", '\\\'', $value['info']);
|
||||
} else {
|
||||
// ci4模式
|
||||
$value['message'] = str_replace([PHP_EOL, chr(13), chr(10)], ' ', htmlentities((string)$v[1]));
|
||||
if (preg_match('/'.$value['time'].' \-\->(.*)\{main\}/sU', $c, $mt)) {
|
||||
$value['info'] = str_replace("'", '\\\'', str_replace([PHP_EOL, chr(13), chr(10)], '<br>', $mt[1]));
|
||||
}
|
||||
}
|
||||
$value['message'] = str_replace("'", '\\\'', $value['message']);
|
||||
$list[] = $value;
|
||||
$j ++;
|
||||
}
|
||||
}
|
||||
$i ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$time = date('Y-m-d', $time);
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'menu' => \Phpcmf\Service::M('auth')->_admin_menu(
|
||||
[
|
||||
'系统日志' => ['error/index', 'fa fa-shield'],
|
||||
]
|
||||
),
|
||||
'list' => $list,
|
||||
'time' => $time,
|
||||
'total' => $total,
|
||||
'mypages' => \Phpcmf\Service::L('input')->page(\Phpcmf\Service::L('Router')->url(\Phpcmf\Service::L('Router')->class.'/index', ['time' => $time]), $total, 'admin')
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('error_log.html');
|
||||
}
|
||||
|
||||
public function log_show() {
|
||||
|
||||
$time = dr_safe_filename($_GET['time']);
|
||||
!$time && $time = date('Y-m-d');
|
||||
$file = WRITEPATH.'error/log-'.$time.'.php';
|
||||
if (!$file) {
|
||||
exit('文件不存在:'.$file);
|
||||
}
|
||||
if (filesize($file) > 1024*1024*2) {
|
||||
exit('此日志文件大于2MB,请使用Ftp等工具查看此文件:'.$file);
|
||||
}
|
||||
$code = file_get_contents($file);
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'file' => $file,
|
||||
'code' => $code,
|
||||
'menu' => [],
|
||||
]);
|
||||
|
||||
\Phpcmf\Service::V()->display('error_file.html');exit;
|
||||
}
|
||||
|
||||
public function del() {
|
||||
|
||||
$time = dr_safe_filename($_GET['time']);
|
||||
!$time && $time = date('Y-m-d');
|
||||
$file = WRITEPATH.'error/log-'.$time.'.php';
|
||||
unlink($file);
|
||||
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,905 @@
|
||||
<?php namespace Phpcmf\Control\Admin;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
class Field extends \Phpcmf\Common {
|
||||
|
||||
public $name;
|
||||
public $data;
|
||||
|
||||
public $ftype;
|
||||
|
||||
public $backurl; // 返回链接
|
||||
public $cachename; // 缓存名称
|
||||
|
||||
public $namespace;
|
||||
public $relatedid;
|
||||
public $relatedname;
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
|
||||
$this->name = dr_lang('字段管理');
|
||||
$this->namespace = ''; // 设置应用目录
|
||||
|
||||
// 字段来源相关表
|
||||
\Phpcmf\Service::M('Field')->relatedid = $this->relatedid = (int)\Phpcmf\Service::L('input')->get('rid');
|
||||
\Phpcmf\Service::M('Field')->relatedname = $this->relatedname = \Phpcmf\Service::L('input')->get('rname');
|
||||
|
||||
list($ismain, $issearch, $iscategory) = $this->_set_init();
|
||||
|
||||
// 可用字段类别
|
||||
$this->ftype = \Phpcmf\Service::L('Field')->app($this->namespace)->type(\Phpcmf\Service::M('Field')->func);
|
||||
|
||||
// 判断类别权限
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'menu' => \Phpcmf\Service::M('auth')->_admin_menu(
|
||||
[
|
||||
'返回' => ['url:'.$this->backurl, 'fa fa-reply'],
|
||||
$this->name => ['url:'.dr_url('field/index', ['rname'=>$this->relatedname, 'rid'=>$this->relatedid]), 'fa fa-code', 'field/index'],
|
||||
'添加' => ['url:'.dr_url('field/add', ['rname'=>$this->relatedname, 'rid'=>$this->relatedid]), 'fa fa-plus', 'field/add'],
|
||||
'导入' => ['add:field/import_add{rname='.$this->relatedname.'&rid='.$this->relatedid.'}', 'fa fa-sign-in', '60%', '70%'],
|
||||
'修改' => ['hide:field/edit', 'fa fa-edit'],
|
||||
]
|
||||
),
|
||||
'rid' => $this->relatedid,
|
||||
'rname' => $this->relatedname,
|
||||
'ftype' => $this->ftype,
|
||||
'ismain' => $ismain,
|
||||
'issearch' => $issearch,
|
||||
'namespace' => $this->namespace,
|
||||
'iscategory' => $iscategory,
|
||||
]);
|
||||
}
|
||||
|
||||
public function index() {
|
||||
|
||||
$field = \Phpcmf\Service::M('Field')->get_all_field();
|
||||
if ($field) {
|
||||
$field = dr_array_sort($field, 'displayorder', 'asc');
|
||||
$group = [];
|
||||
$mygroup = [];
|
||||
// 分组和合并字段筛选
|
||||
foreach ($field as $t) {
|
||||
if ($t['fieldtype'] == 'Group' || $t['fieldtype'] == 'Merge') {
|
||||
if (preg_match_all('/\{(.+)\}/U', $t['setting']['option']['value'], $value)) {
|
||||
foreach ($value[1] as $v) {
|
||||
$group[$t['fieldtype']][$v] = $t['fieldname'];
|
||||
}
|
||||
}
|
||||
$mygroup[$t['fieldtype']][$t['fieldname']] = $t;
|
||||
}
|
||||
}
|
||||
|
||||
$data = [];
|
||||
$group_data = [];
|
||||
|
||||
$ftype = [];
|
||||
foreach ($this->ftype as $t) {
|
||||
$ftype[$t['id']] = strpos($t['id'], $t['name']) !== false ? $t['id'] : $t['name'].' '.$t['id'];
|
||||
}
|
||||
|
||||
// 主字段
|
||||
foreach ($field as $t) {
|
||||
|
||||
// 验证字段对象的有效性
|
||||
$obj = \Phpcmf\Service::L('Field')->get($t['fieldtype']);
|
||||
if ($obj) {
|
||||
if ($obj->use_xss) {
|
||||
// 强制开启xss
|
||||
$t['setting']['validate']['xss'] = 1;
|
||||
} elseif ($obj->close_xss) {
|
||||
// 强制关闭xss
|
||||
$t['setting']['validate']['xss'] = 0;
|
||||
}
|
||||
}
|
||||
$t['ftype'] = isset($ftype[$t['fieldtype']]) ? $ftype[$t['fieldtype']] : $t['fieldtype'];
|
||||
// 重复了 删除记录
|
||||
if (isset($data[$t['fieldname']]) && $data[$t['fieldname']]) {
|
||||
\Phpcmf\Service::M()->table('field')->delete($t['id']);
|
||||
}
|
||||
if (isset($group['Merge'][$t['fieldname']])) {
|
||||
$group_data['Merge'][$t['fieldname']] = $t;
|
||||
} elseif (isset($group['Group'][$t['fieldname']])) {
|
||||
// 属于分组字段
|
||||
$group_data['Group'][$t['fieldname']] = $t;
|
||||
} elseif ($t['fieldtype'] == 'Group') {
|
||||
$data[$t['fieldname']] = '';
|
||||
} elseif ($t['fieldtype'] == 'Merge') {
|
||||
$data[$t['fieldname']] = '';
|
||||
} else {
|
||||
$data[$t['fieldname']] = $t;
|
||||
}
|
||||
}
|
||||
|
||||
if ($mygroup['Merge']) {
|
||||
foreach ($mygroup['Merge'] as $m) {
|
||||
$list = [];
|
||||
foreach ($group['Merge'] as $fieldname => $t) {
|
||||
$m['fieldname'] == $t && $list[] = $group_data['Merge'][$fieldname];
|
||||
}
|
||||
$list && $data[$m['fieldname']] = $list;
|
||||
}
|
||||
}
|
||||
if ($mygroup['Group']) {
|
||||
foreach ($mygroup['Group'] as $m) {
|
||||
$list = [];
|
||||
foreach ($group['Group'] as $fieldname => $t) {
|
||||
$m['fieldname'] == $t && $list[] = $group_data['Group'][$fieldname];
|
||||
}
|
||||
$list && $data[$m['fieldname']] = $list;
|
||||
}
|
||||
}
|
||||
|
||||
$list = [];
|
||||
foreach ($data as $fname => $t) {
|
||||
if (isset($t['id'])) {
|
||||
$list[$t['fieldname']] = $t;
|
||||
} elseif ($mygroup['Group'][$fname]) {
|
||||
$mygroup['Group'][$fname]['spacer'] = $group['Merge'][$fname] ? '<span class="tree-icon">└</span>' : '';
|
||||
$list[$fname] = $mygroup['Group'][$fname];
|
||||
foreach ($t as $f) {
|
||||
$f['spacer'] = $group['Merge'][$fname] ? '<span class="tree-icon">└</span><span class="tree-icon">└</span>' : '<span class="tree-icon">└</span>';
|
||||
$f['id'] && $list[$f['fieldname']] = $f;
|
||||
}
|
||||
} elseif ($mygroup['Merge'][$fname]) {
|
||||
$list[] = $mygroup['Merge'][$fname];
|
||||
foreach ($t as $f) {
|
||||
$f['spacer'] = '<span class="tree-icon">└</span>';
|
||||
if ($f['id']) {
|
||||
$list[$f['fieldname']] = $f;
|
||||
if ($mygroup['Group'][$f['fieldname']] && $data[$f['fieldname']]) {
|
||||
foreach ($data[$f['fieldname']] as $ff) {
|
||||
$ff['spacer'] = '<span class="tree-icon">└</span><span class="tree-icon">└</span>';
|
||||
$ff['id'] && $list[$ff['fieldname']] = $ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
//print_r($data);
|
||||
} else {
|
||||
$list = [];
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->assign(array(
|
||||
'list' => $list,
|
||||
'role' => \Phpcmf\Service::C()->get_cache('auth'),
|
||||
));
|
||||
\Phpcmf\Service::V()->display('field_index.html');
|
||||
}
|
||||
|
||||
public function add() {
|
||||
|
||||
$id = 0;
|
||||
$page = max((int)\Phpcmf\Service::L('input')->post('page'), 0);
|
||||
|
||||
// 初始化部分值
|
||||
$data = [
|
||||
'ismember' => 1,
|
||||
'ismain' => 1,
|
||||
'fieldtype' => '',
|
||||
'setting' => [
|
||||
'option' => [],
|
||||
'validate' => [
|
||||
'xss' => 1,
|
||||
'required' => 0,
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
// 提交表单
|
||||
if (IS_AJAX_POST) {
|
||||
$data = \Phpcmf\Service::L('input')->post('data', false);
|
||||
$field = \Phpcmf\Service::L('field')->get($data['fieldtype']);
|
||||
if (!$field) {
|
||||
$this->_json(0, dr_lang('字段类别(%s)文件不存在', $data['fieldtype']));
|
||||
} elseif (empty($data['name'])) {
|
||||
$this->_json(0, dr_lang('字段显示名称不能为空'));
|
||||
} elseif (empty($data['fieldname'])) {
|
||||
$this->_json(0, dr_lang('字段名称不能为空'));
|
||||
} elseif (!preg_match('/^[a-z]+[a-z0-9\_]+$/i', $data['fieldname'])) {
|
||||
$this->_json(0, dr_lang('字段(%s)名称不规范', $data['fieldname']));
|
||||
} elseif (strlen($data['fieldname']) > 30) {
|
||||
$this->_json(0, dr_lang('字段(%s)名称太长', $data['fieldname']));
|
||||
} else {
|
||||
if (\Phpcmf\Service::M('Field')->exitsts($data['fieldname'])) {
|
||||
if (\Phpcmf\Service::M('Field')->table('field')
|
||||
->where('relatedid', (int)$this->relatedid)
|
||||
->where('relatedname', (string)$this->relatedname)
|
||||
->where('fieldname', (string)$data['fieldname'])
|
||||
->counts()) {
|
||||
$this->_json(0, dr_lang('字段(%s)已经存在', $data['fieldname']));
|
||||
} elseif (\Phpcmf\Service::M('Field')->is_sys_field($data['fieldname'])) {
|
||||
$this->_json(0, dr_lang('字段(%s)是系统保留字段,禁止创建', $data['fieldname']));
|
||||
} else {
|
||||
// 已经存在的字段是否创建
|
||||
if (!isset($_GET['is_op_add'])) {
|
||||
$this->_json(-1, dr_lang('字段(%s)是已经存在于表中,请更换名字,否则可能会影响程序的运行', $data['fieldname']));
|
||||
}
|
||||
}
|
||||
$is_create = 0;
|
||||
} else {
|
||||
$is_create = 1;
|
||||
}
|
||||
$rt = $field->edit_config($data);
|
||||
if (!$rt['code']) {
|
||||
$this->_json(0, $rt['msg']);
|
||||
}
|
||||
$rt = \Phpcmf\Service::M('Field')->add($data, $field, $is_create);
|
||||
if (!$rt['code']) {
|
||||
$this->_json(0, dr_lang($rt['msg']));
|
||||
}
|
||||
$this->_cache(); // 自动更新缓存
|
||||
\Phpcmf\Service::L('input')->system_log('添加'.$this->name.'【'.$data['fieldname'].'】'.$data['name']); // 记录日志
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'id' => $id,
|
||||
'page' => $page,
|
||||
'data' => $data,
|
||||
'form' => dr_form_hidden(['page' => $page]),
|
||||
'role' => \Phpcmf\Service::C()->get_cache('auth'),
|
||||
'cat_show' => 0,
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('field_add.html');
|
||||
}
|
||||
|
||||
public function edit() {
|
||||
|
||||
$id = intval(\Phpcmf\Service::L('input')->get('id'));
|
||||
$page = max((int)\Phpcmf\Service::L('input')->get('page'), 0);
|
||||
$data = \Phpcmf\Service::M()->table('field')->get($id);
|
||||
if (!$data) {
|
||||
$this->_json(0, dr_lang('数据#%s不存在', $id));
|
||||
}
|
||||
|
||||
$data['setting'] = dr_string2array($data['setting']);
|
||||
|
||||
// 加载系统编辑器
|
||||
if ($data['fieldtype'] == 'Ueditor' && !is_file(CMSPATH.'Field/Ueditor.php')) {
|
||||
$data['fieldtype'] = 'Editor';
|
||||
}
|
||||
|
||||
// 验证字段对象的有效性
|
||||
$obj = \Phpcmf\Service::L('Field')->get($data['fieldtype']);
|
||||
if ($obj) {
|
||||
if ($obj->use_xss) {
|
||||
// 强制开启xss
|
||||
$data['setting']['validate']['xss'] = 1;
|
||||
} elseif ($obj->close_xss) {
|
||||
// 强制关闭xss
|
||||
$data['setting']['validate']['xss'] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_AJAX_POST) {
|
||||
$post = \Phpcmf\Service::L('input')->post('data', false);
|
||||
$field = \Phpcmf\Service::L('field')->get($post['fieldtype']);
|
||||
if (!$field) {
|
||||
$this->_json(0, dr_lang('字段类别(%s)文件不存在', $post['fieldtype']));
|
||||
}
|
||||
$rt = $field->edit_config($post);
|
||||
if (!$rt['code']) {
|
||||
$this->_json(0, $rt['msg']);
|
||||
}
|
||||
$rt = \Phpcmf\Service::M('Field')->edit(
|
||||
$data,
|
||||
$post,
|
||||
$field->alter_sql($data['fieldname'], $post['setting']['option'], $data['name'])
|
||||
);
|
||||
if (!$rt['code']) {
|
||||
$this->_json(0, dr_lang($rt['msg']));
|
||||
}
|
||||
$this->_cache(); // 自动更新缓存
|
||||
\Phpcmf\Service::L('input')->system_log('修改'.$this->name.'【'.$data['fieldname'].'】'.$data['name']); // 记录日志
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'id' => $id,
|
||||
'data' => $data,
|
||||
'page' => $page,
|
||||
'form' => dr_form_hidden(['page' => $page]),
|
||||
'role' => \Phpcmf\Service::C()->get_cache('auth'),
|
||||
'is_edit' => $obj->is_edit,
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('field_add.html');
|
||||
}
|
||||
|
||||
public function type_edit() {
|
||||
|
||||
$my = dr_safe_filename(\Phpcmf\Service::L('input')->get('my'));
|
||||
$to = dr_safe_filename(\Phpcmf\Service::L('input')->get('to'));
|
||||
|
||||
$int = ['Cat', 'Date', 'Linkage', 'Touchspin', 'Uid'];
|
||||
$text = ['Catids', 'Files', 'Ftable', 'Image', 'Property', 'Redirect', 'Textarea', 'Editor'];
|
||||
$json = ['Checkbox', 'Linkage', 'Members', 'Related', 'Selects'];
|
||||
$char = ['Color', 'File', 'Text', 'Textbtn', 'Time', 'Select', 'Radio'];
|
||||
|
||||
if (in_array($my, $int)) {
|
||||
if (in_array($to, $int)) {
|
||||
$this->_json(1, dr_lang('同一类型'));
|
||||
}
|
||||
$this->_json(0, dr_lang('当前字段存储的数据是%s,变更后建议手动去数据库将其字段数据类型改成合适的类型,确定继续变更吗?', 'INT'));
|
||||
} elseif (in_array($my, $text)) {
|
||||
if (in_array($to, $text)) {
|
||||
$this->_json(1, dr_lang('同一类型'));
|
||||
} elseif (stripos($to, 'editor') !== false) {
|
||||
$this->_json(1, dr_lang('同一类型'));
|
||||
}
|
||||
$this->_json(0, dr_lang('当前字段存储的数据是%s,变更后建议手动去数据库将其字段数据类型改成合适的类型,确定继续变更吗?', 'TEXT'));
|
||||
} elseif (in_array($my, $json)) {
|
||||
if (in_array($to, $json)) {
|
||||
$this->_json(1, dr_lang('同一类型'));
|
||||
}
|
||||
$this->_json(0, dr_lang('当前字段存储的数据是%s,变更后建议手动去数据库将其字段数据类型改成合适的类型,确定继续变更吗?', 'JSON'));
|
||||
} elseif (in_array($my, $char)) {
|
||||
if (in_array($to, $char)) {
|
||||
$this->_json(1, dr_lang('同一类型'));
|
||||
}
|
||||
$this->_json(0, dr_lang('当前字段存储的数据是%s,变更后建议手动去数据库将其字段数据类型改成合适的类型,确定继续变更吗?', 'CHAR'));
|
||||
} elseif (stripos($my, 'editor') !== false && stripos($to, 'editor') !== false) {
|
||||
$this->_json(1, dr_lang('同一类型'));
|
||||
} else {
|
||||
$this->_json(0, dr_lang('变更字段类别可能会影响已有的数据,你确定吗?'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用操作
|
||||
*/
|
||||
public function option() {
|
||||
|
||||
$id = (int)\Phpcmf\Service::L('input')->get('id');
|
||||
$data = \Phpcmf\Service::M()->table('field')->get($id);
|
||||
if (!$data) {
|
||||
$this->_json(0, dr_lang('字段不存在'));
|
||||
}
|
||||
|
||||
switch (\Phpcmf\Service::L('input')->get('op')) {
|
||||
case 'disabled':
|
||||
$value = $data['disabled'] == 1 ? 0 : 1;
|
||||
\Phpcmf\Service::M()->table('field')->save($id, 'disabled', $value);
|
||||
$this->_cache(); // 自动更新缓存
|
||||
\Phpcmf\Service::L('input')->system_log(($value ? '禁用' : '启用').$this->name.'【'.$data['fieldname'].'】'); // 记录日志
|
||||
$this->_json(1, dr_lang(($value ? '禁用' : '启用').'成功'), ['value' => $value]);
|
||||
break;
|
||||
case 'xss':
|
||||
// 验证字段对象的有效性
|
||||
$obj = \Phpcmf\Service::L('Field')->get($data['fieldtype']);
|
||||
if ($obj) {
|
||||
if ($obj->use_xss) {
|
||||
// 强制开启xss
|
||||
$this->_json(0, dr_lang('该字段已经强制启用了XSS过滤'));
|
||||
} elseif ($obj->close_xss) {
|
||||
// 强制关闭xss
|
||||
$this->_json(0, dr_lang('该字段已经强制关闭了XSS过滤'));
|
||||
}
|
||||
}
|
||||
$data['setting'] = dr_string2array($data['setting']);
|
||||
$data['setting']['validate']['xss'] = $value = $data['setting']['validate']['xss'] ? 0 : 1;
|
||||
\Phpcmf\Service::M()->table('field')->save($id, 'setting', dr_array2string($data['setting']));
|
||||
$this->_cache(); // 自动更新缓存
|
||||
\Phpcmf\Service::L('input')->system_log($this->name.'【'.$data['fieldname'].'】'.($value ? '开启XSS' : '关闭XSS')); // 记录日志
|
||||
$this->_json(1, dr_lang('操作成功'), ['value' => $value]);
|
||||
break;
|
||||
case 'member':
|
||||
$value = $data['ismember'] ? 0 : 1;
|
||||
\Phpcmf\Service::M()->table('field')->save($id, 'ismember', $value);
|
||||
$this->_cache(); // 自动更新缓存
|
||||
\Phpcmf\Service::L('input')->system_log($this->name.'【'.$data['fieldname'].'】'.($value ? '前端显示' : '前端隐藏')); // 记录日志
|
||||
$this->_json(1, dr_lang('操作成功'), ['value' => $value]);
|
||||
break;
|
||||
case 'save':
|
||||
\Phpcmf\Service::M()->table('field')->save($id, 'displayorder', dr_safe_replace(\Phpcmf\Service::L('input')->get('value')));
|
||||
$this->_cache(); // 自动更新缓存
|
||||
\Phpcmf\Service::L('input')->system_log('修改排序值: '. $this->name.'【'.$data['fieldname'].'】');
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
break;
|
||||
}
|
||||
|
||||
$this->_json(0, dr_lang('未知操作'));
|
||||
}
|
||||
|
||||
// 删除字段
|
||||
public function del() {
|
||||
|
||||
$ids = \Phpcmf\Service::L('input')->get_post_ids();
|
||||
if (!$ids) {
|
||||
$this->_json(0, dr_lang('你还没有选择呢'));
|
||||
}
|
||||
|
||||
$rt = \Phpcmf\Service::M('Field')->delete_field($ids);
|
||||
if (!$rt['code']) {
|
||||
$this->_json(0, $rt['msg']);
|
||||
}
|
||||
|
||||
$this->_cache(); // 自动更新缓存
|
||||
\Phpcmf\Service::L('input')->system_log('删除字段'. $this->name.' '. implode(',', $ids));
|
||||
|
||||
$this->_json(1, dr_lang('操作成功'), ['ids' => $ids]);
|
||||
}
|
||||
|
||||
// 导出
|
||||
public function export() {
|
||||
|
||||
$id = intval(\Phpcmf\Service::L('input')->get('id'));
|
||||
$data = \Phpcmf\Service::M()->table('field')->get($id);
|
||||
if (!$data) {
|
||||
$this->_admin_msg(0, dr_lang('字段(%s)不存在', $id));
|
||||
}
|
||||
|
||||
unset($data['id']);
|
||||
unset($data['relatedid']);
|
||||
unset($data['relatedname']);
|
||||
|
||||
$data['setting'] = dr_string2array($data['setting']);
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'data' => dr_array2string($data),
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('api_export_code.html');exit;
|
||||
}
|
||||
|
||||
// 导出
|
||||
public function export_all() {
|
||||
|
||||
$ids = \Phpcmf\Service::L('input')->get('ids');
|
||||
if (!$ids) {
|
||||
$this->_json(0, dr_lang('你还没有选择呢'));
|
||||
}
|
||||
|
||||
$rt = '';
|
||||
foreach ($ids as $id) {
|
||||
|
||||
$id = intval($id);
|
||||
$data = \Phpcmf\Service::M()->table('field')->get($id);
|
||||
if (!$data) {
|
||||
$this->_admin_msg(0, dr_lang('字段(%s)不存在', $id));
|
||||
}
|
||||
|
||||
unset($data['id']);
|
||||
unset($data['relatedid']);
|
||||
unset($data['relatedname']);
|
||||
|
||||
$data['setting'] = dr_string2array($data['setting']);
|
||||
|
||||
$rt.= dr_array2string($data).PHP_EOL;
|
||||
}
|
||||
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'data' => $rt,
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('api_export_code.html');exit;
|
||||
}
|
||||
|
||||
// 导入
|
||||
public function import_add() {
|
||||
|
||||
if (IS_AJAX_POST) {
|
||||
$code = \Phpcmf\Service::L('input')->post('code');
|
||||
$arr = explode(PHP_EOL, $code);
|
||||
if (!$arr) {
|
||||
$this->_json(0, dr_lang('代码不能为空'));
|
||||
}
|
||||
$save = [];
|
||||
foreach ($arr as $t) {
|
||||
if ($t) {
|
||||
$data = dr_string2array($t);
|
||||
if (!$data) {
|
||||
$this->_json(0, dr_lang('代码解析失败'));
|
||||
}
|
||||
$field = \Phpcmf\Service::L('field')->get($data['fieldtype']);
|
||||
if (!$field) {
|
||||
$this->_json(0, dr_lang('字段类别(%s)文件不存在', $data['fieldtype']));
|
||||
} elseif (empty($data['name'])) {
|
||||
$this->_json(0, dr_lang('字段显示名称不能为空'));
|
||||
}
|
||||
if (empty($data['fieldname'])) {
|
||||
$data['fieldname'] = $data['name'];
|
||||
}
|
||||
if (!preg_match('/^[a-z]+[a-z0-9\_]+$/i', $data['fieldname'])) {
|
||||
$this->_json(0, dr_lang('字段(%s)名称不规范', $data['fieldname']));
|
||||
} elseif (strlen($data['fieldname']) > 30) {
|
||||
$this->_json(0, dr_lang('字段(%s)名称太长', $data['fieldname']));
|
||||
} elseif (\Phpcmf\Service::M('Field')->exitsts($data['fieldname'])) {
|
||||
$this->_json(0, dr_lang('字段(%s)已经存在', $data['fieldname']));
|
||||
} else {
|
||||
$save[] = $data;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!$save) {
|
||||
$this->_json(0, dr_lang('没有可用的导入字段'));
|
||||
}
|
||||
// 入库操作
|
||||
foreach ($save as $data) {
|
||||
$field = \Phpcmf\Service::L('field')->get($data['fieldtype']);
|
||||
if (isset($data['id'])) {
|
||||
unset($data['id']);
|
||||
}
|
||||
$data['setting'] = dr_string2array($data['setting']);
|
||||
$rt = \Phpcmf\Service::M('Field')->add($data, $field);
|
||||
if (!$rt['code']) {
|
||||
$this->_json(0, dr_lang($rt['msg']));
|
||||
}
|
||||
}
|
||||
|
||||
$this->_cache(); // 自动更新缓存
|
||||
\Phpcmf\Service::L('input')->system_log('导入字段:'.$this->name); // 记录日志
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'data' => '',
|
||||
'form' => dr_form_hidden(),
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('api_export_code.html');
|
||||
exit;
|
||||
}
|
||||
|
||||
// 联动更新缓存
|
||||
private function _cache() {
|
||||
|
||||
list($case_name, $a) = explode('-', $this->relatedname);
|
||||
|
||||
if (function_exists('myfield_cache_'.$case_name)) {
|
||||
call_user_func('myfield_cache_'.$case_name);
|
||||
} else {
|
||||
|
||||
switch ($case_name) {
|
||||
|
||||
case 'form':
|
||||
// _网站表单 form-站点id, 表单id
|
||||
\Phpcmf\Service::M('cache')->sync_cache('form', 'form', 1); // 自动更新缓存
|
||||
break;
|
||||
|
||||
case 'tag':
|
||||
// _网站tag
|
||||
\Phpcmf\Service::M('cache')->sync_cache('tag', 'tag', 1); // 自动更新缓存
|
||||
break;
|
||||
|
||||
case 'linkage':
|
||||
// 联动菜单
|
||||
\Phpcmf\Service::M('cache')->sync_cache('linkage', '', 1); // 自动更新缓存
|
||||
break;
|
||||
|
||||
case 'member':
|
||||
// _用户主表
|
||||
\Phpcmf\Service::M('cache')->sync_cache('member'); // 自动更新缓存
|
||||
break;
|
||||
|
||||
case 'navigator':
|
||||
// _导航链接
|
||||
\Phpcmf\Service::M('cache')->sync_cache('navigator', 'navigator', 1); // 自动更新缓存
|
||||
break;
|
||||
|
||||
case 'order':
|
||||
// 订单插件
|
||||
break;
|
||||
|
||||
case 'page':
|
||||
// 网站单页
|
||||
\Phpcmf\Service::M('cache')->sync_cache('page', 'page', 1); // 自动更新缓存
|
||||
break;
|
||||
|
||||
case 'table':
|
||||
// 任意表
|
||||
break;
|
||||
|
||||
case 'module':
|
||||
// 模块字段
|
||||
\Phpcmf\Service::M('cache')->sync_cache(''); // 自动更新缓存
|
||||
break;
|
||||
|
||||
case 'mform':
|
||||
// 模块表单
|
||||
\Phpcmf\Service::M('cache')->sync_cache(''); // 自动更新缓存
|
||||
break;
|
||||
|
||||
case 'category':
|
||||
// 栏目自定义字段
|
||||
\Phpcmf\Service::M('cache')->sync_cache(''); // 自动更新缓存
|
||||
break;
|
||||
|
||||
case 'site':
|
||||
// 网站信息
|
||||
\Phpcmf\Service::L('cache')->del_data('my-site-'.SITE_ID);
|
||||
break;
|
||||
|
||||
default:
|
||||
\Phpcmf\Service::M('cache')->sync_cache(''); // 自动更新缓存
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 初始化设置
|
||||
private function _set_init() {
|
||||
|
||||
$local = \Phpcmf\Service::Apps(true);
|
||||
if ($local) {
|
||||
foreach ($local as $dir => $path) {
|
||||
if (is_file($path.'Config/Myfield.php')) {
|
||||
require $path.'Config/Myfield.php';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$ismain = $issearch = $iscategory = 0;
|
||||
|
||||
list($case_name, $a) = explode('-', $this->relatedname);
|
||||
|
||||
if (function_exists('myfield_init_'.$case_name)) {
|
||||
$rt = call_user_func_array('myfield_init_'.$case_name, [
|
||||
$this->relatedname,
|
||||
$this->relatedid
|
||||
]);
|
||||
if (!$rt['code']) {
|
||||
$this->_admin_msg(0, $rt['msg']);
|
||||
}
|
||||
$this->data = $rt['data']['data'];
|
||||
$this->name = $rt['data']['name'];
|
||||
$this->backurl = $rt['data']['backurl'];
|
||||
if (isset($rt['data']['ismain']) && $rt['data']['ismain']) {
|
||||
$ismain = 1;
|
||||
}
|
||||
\Phpcmf\Service::M('Field')->func = $case_name; // 重要标识: 函数和识别码
|
||||
\Phpcmf\Service::M('Field')->data = $this->data;
|
||||
} else {
|
||||
|
||||
switch ($case_name) {
|
||||
|
||||
case 'form':
|
||||
// _网站表单 form-站点id, 表单id
|
||||
list($a, $siteid) = explode('-', $this->relatedname);
|
||||
$this->data = \Phpcmf\Service::M()->init(['db' => $siteid, 'table' => $siteid.'_form'])->get($this->relatedid);
|
||||
if (!$this->data) {
|
||||
$this->_admin_msg(0, dr_lang('表单【%s】不存在', $this->relatedid));
|
||||
}
|
||||
$this->name = dr_lang('表单【%s】字段', $this->data['name']);
|
||||
$this->backurl = ''; // 返回uri地址
|
||||
\Phpcmf\Service::M('Field')->func = 'form'; // 重要标识: 函数和识别码
|
||||
\Phpcmf\Service::M('Field')->data = $this->data;
|
||||
break;
|
||||
|
||||
case 'site':
|
||||
// 网站信息
|
||||
$ismain = 1;
|
||||
$this->name = dr_lang('自定义字段');
|
||||
$this->backurl = \Phpcmf\Service::L('Router')->url('cms/site_param/index'); // 返回uri地址
|
||||
\Phpcmf\Service::M('Field')->func = 'site'; // 重要标识: 函数和识别码
|
||||
break;
|
||||
|
||||
case 'tag':
|
||||
// _网站tag
|
||||
$ismain = 1;
|
||||
$this->name = dr_lang('自定义字段');
|
||||
$this->backurl = \Phpcmf\Service::L('Router')->url('tag/home/index'); // 返回uri地址
|
||||
\Phpcmf\Service::M('Field')->func = 'tag'; // 重要标识: 函数和识别码
|
||||
break;
|
||||
|
||||
case 'linkage':
|
||||
// 联动菜单
|
||||
$ismain = 1;
|
||||
$this->name = dr_lang('联动菜单字段');
|
||||
$this->backurl = ''; // 返回uri地址
|
||||
\Phpcmf\Service::M('Field')->func = 'linkage'; // 重要标识: 函数和识别码
|
||||
break;
|
||||
|
||||
case 'member':
|
||||
// _用户主表
|
||||
$ismain = 1;
|
||||
$this->name = dr_lang('自定义字段');
|
||||
$this->backurl = \Phpcmf\Service::L('Router')->url('member/field/index'); // 返回uri地址
|
||||
\Phpcmf\Service::M('Field')->func = 'member'; // 重要标识: 函数和识别码
|
||||
break;
|
||||
|
||||
case 'navigator':
|
||||
// _导航链接
|
||||
$ismain = 1;
|
||||
$this->name = dr_lang('自定义字段');
|
||||
$this->backurl = \Phpcmf\Service::L('Router')->url('navigator/home/index'); // 返回uri地址
|
||||
\Phpcmf\Service::M('Field')->func = 'navigator'; // 重要标识: 函数和识别码
|
||||
break;
|
||||
|
||||
case 'order':
|
||||
// 订单插件
|
||||
$ismain = 1;
|
||||
$this->name = dr_lang('自定义字段');
|
||||
$this->backurl = \Phpcmf\Service::L('Router')->url('order/field/index'); // 返回uri地址
|
||||
\Phpcmf\Service::M('Field')->func = 'order'; // 重要标识: 函数和识别码
|
||||
break;
|
||||
|
||||
case 'page':
|
||||
// 网站单页
|
||||
$ismain = 1;
|
||||
$this->name = dr_lang('自定义字段');
|
||||
$this->backurl = \Phpcmf\Service::L('Router')->url('page/home/index'); // 返回uri地址
|
||||
\Phpcmf\Service::M('Field')->func = 'page'; // 重要标识: 函数和识别码
|
||||
break;
|
||||
|
||||
case 'table':
|
||||
// 任意表
|
||||
$ismain = 1;
|
||||
$this->name = '【'.\Phpcmf\Service::M()->dbprefix($a).'】';
|
||||
\Phpcmf\Service::M('Field')->data = $a;
|
||||
\Phpcmf\Service::M('Field')->func = 'table'; // 重要标识: 函数和识别码
|
||||
break;
|
||||
|
||||
case 'module':
|
||||
// 模块字段
|
||||
$this->data = \Phpcmf\Service::M()->table('module')->get($this->relatedid);
|
||||
if (!$this->data) {
|
||||
$this->_admin_msg(0, dr_lang('模块【%s】不存在', $this->relatedid));
|
||||
}
|
||||
$this->backurl = ''; // 返回uri地址
|
||||
$this->name = dr_lang('模块【%s】字段', $this->data['dirname']);
|
||||
\Phpcmf\Service::M('Field')->func = 'module'; // 重要标识: 函数和识别码
|
||||
\Phpcmf\Service::M('Field')->data = $this->data;
|
||||
$this->namespace = $this->data['dirname'];
|
||||
break;
|
||||
|
||||
case 'mform':
|
||||
// 模块表单
|
||||
$this->data = \Phpcmf\Service::M()->table('module_form')->get($this->relatedid);
|
||||
if (!$this->data) {
|
||||
$this->_admin_msg(0, dr_lang('模块【%s】不存在', $this->relatedid));
|
||||
}
|
||||
$this->backurl = ''; // 返回uri地址
|
||||
$this->name = dr_lang('模块【%s】的表单【%s】字段', $a, $this->data['name']);
|
||||
\Phpcmf\Service::M('Field')->func = 'mform'; // 重要标识: 函数和识别码
|
||||
\Phpcmf\Service::M('Field')->data = $this->data;
|
||||
$this->namespace = $this->data['module'];
|
||||
break;
|
||||
|
||||
case 'category':
|
||||
// 栏目自定义字段
|
||||
$ismain = 1;
|
||||
$this->name = dr_lang('栏目自定义字段');
|
||||
$this->backurl = ''; // 返回uri地址
|
||||
\Phpcmf\Service::M('Field')->func = 'category'; // 重要标识: 函数和识别码
|
||||
\Phpcmf\Service::M('Field')->data = $a;
|
||||
$this->module = \Phpcmf\Service::L('cache')->get('module-'.SITE_ID.'-'.$a);
|
||||
if (!$this->module) {
|
||||
$this->_admin_msg(0, dr_lang('模块【%s】缓存不存在', $a));
|
||||
}
|
||||
break;
|
||||
|
||||
case 'catmodule':
|
||||
// 识别栏目模型字段
|
||||
$ismain = 1;
|
||||
$issearch = 1;
|
||||
$iscategory = 1;
|
||||
$module = $a;
|
||||
$cache = \Phpcmf\Service::L('cache')->get('module-'.SITE_ID.'-'.$module);
|
||||
if (!$cache) {
|
||||
$this->_admin_msg(0, dr_lang('模块【%s】缓存不存在', $module));
|
||||
}
|
||||
if ($this->relatedid) {
|
||||
$this->data = dr_cat_value($cache['mid'], $this->relatedid);
|
||||
if (!$this->data) {
|
||||
$this->_admin_msg(0, dr_lang('模块【%s】栏目【%s】缓存不存在', $module, $this->relatedid));
|
||||
}
|
||||
if ($module == 'share') {
|
||||
$this->data['tid'] != 1 && $this->_admin_msg(0, dr_lang('模块栏目才支持创建'));
|
||||
$this->data['dirname'] = $this->data['mid'];
|
||||
$this->backurl = \Phpcmf\Service::L('Router')->url('category/index'); // 返回uri地址
|
||||
$this->name = dr_lang('模块【%s】栏目【#%s】模型字段', $this->data['mid'], $this->relatedid);
|
||||
} else {
|
||||
$this->data['dirname'] = $module;
|
||||
$this->backurl = \Phpcmf\Service::L('Router')->url($module.'/category/index'); // 返回uri地址
|
||||
$this->name = dr_lang('模块【%s】栏目【#%s】模型字段', $module, $this->relatedid);
|
||||
}
|
||||
} else {
|
||||
$this->data = [
|
||||
'dirname' => $module,
|
||||
];
|
||||
$this->name = dr_lang('模块【%s】栏目公共模型字段', $module);
|
||||
$this->backurl = \Phpcmf\Service::L('Router')->url('module/module_category/field_index', ['dir' => $module]); // 返回uri地址
|
||||
}
|
||||
|
||||
$this->module = $cache;
|
||||
|
||||
\Phpcmf\Service::M('Field')->func = 'category_data'; // 重要标识: 函数和识别码
|
||||
\Phpcmf\Service::M('Field')->data = $this->data;
|
||||
$this->namespace = $module;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (strpos($this->relatedname, 'comment-module') !== false) {
|
||||
// 模块评论字段
|
||||
if (!dr_is_app('comment')) {
|
||||
$this->_admin_msg(0, dr_lang('系统没有安装评论插件'));
|
||||
}
|
||||
$ismain = 1;
|
||||
list($a, $b, $module) = explode('-', $this->relatedname);
|
||||
$cache = \Phpcmf\Service::L('cache')->get('module-' . SITE_ID . '-' . $module);
|
||||
if (!$cache) {
|
||||
$this->_admin_msg(0, dr_lang('模块【%s】缓存不存在', $module));
|
||||
}
|
||||
$this->name = '模块【' . $cache['name'] . '】评论字段';
|
||||
$this->data = $cache['dirname'];
|
||||
$this->backurl = ''; // 返回uri地址
|
||||
\Phpcmf\Service::M('Field')->func = 'comment'; // 重要标识: 函数和识别码
|
||||
\Phpcmf\Service::M('Field')->data = $cache['dirname'];
|
||||
$this->namespace = $cache['dirname'];
|
||||
} elseif (strpos($this->relatedname, 'comment-mform') !== false) {
|
||||
// 模块评论字段
|
||||
if (!dr_is_app('comment')) {
|
||||
$this->_admin_msg(0, dr_lang('系统没有安装评论插件'));exit;
|
||||
}
|
||||
$ismain = 1;
|
||||
list($a, $b, $module, $fid) = explode('-', $this->relatedname);
|
||||
$cache = \Phpcmf\Service::L('cache')->get('module-'.SITE_ID.'-'.$module);
|
||||
if (!$cache) {
|
||||
$this->_admin_msg(0, dr_lang('模块【%s】缓存不存在', $module));
|
||||
} elseif (!$cache['form'][$fid]) {
|
||||
$this->_admin_msg(0, dr_lang('模块【%s】表单【%s】缓存不存在', $module, $fid));
|
||||
}
|
||||
$this->name = '模块【'.$cache['name'].'】表单【'.$cache['form'][$fid]['name'].'】评论字段';
|
||||
$this->data = $cache['dirname'].'_form_'.$cache['form'][$fid]['table'];
|
||||
$this->backurl = ''; // 返回uri地址
|
||||
\Phpcmf\Service::M('Field')->func = 'comment'; // 重要标识: 函数和识别码
|
||||
\Phpcmf\Service::M('Field')->data = $this->data;
|
||||
$this->namespace = $cache['dirname'];
|
||||
} elseif (strpos($this->relatedname, 'comment-form') !== false) {
|
||||
// 表单评论字段
|
||||
if (!dr_is_app('comment')) {
|
||||
$this->_admin_msg(0, dr_lang('系统没有安装评论插件'));exit;
|
||||
}
|
||||
$ismain = 1;
|
||||
list($a, $b, $fid) = explode('-', $this->relatedname);
|
||||
$cache = \Phpcmf\Service::L('cache')->get('form-'.$this->relatedid, $fid);
|
||||
if (!$cache) {
|
||||
$this->_admin_msg(0, dr_lang('表单【%s】缓存不存在', $fid));
|
||||
}
|
||||
$this->name = '表单【'.$cache['name'].'】评论字段';
|
||||
$this->data = 'form_'.$cache['table'];
|
||||
$this->backurl = ''; // 返回uri地址
|
||||
\Phpcmf\Service::M('Field')->func = 'comment'; // 重要标识: 函数和识别码
|
||||
\Phpcmf\Service::M('Field')->data = $this->data;
|
||||
} elseif (function_exists('myfield_info_'.$case_name)) {
|
||||
// 其他自定义
|
||||
$rt = call_user_func_array('myfield_info_'.$case_name, array(
|
||||
$this->relatedname,
|
||||
$this->relatedid
|
||||
));
|
||||
if (is_array($rt)) {
|
||||
list(
|
||||
$ismain,
|
||||
$this->name,
|
||||
$this->data,
|
||||
\Phpcmf\Service::M('Field')->func,
|
||||
$this->backurl
|
||||
) = $rt;
|
||||
\Phpcmf\Service::M('Field')->data = $this->data;
|
||||
} else {
|
||||
$this->_admin_msg(0, $rt);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->assign('fmid', \Phpcmf\Service::M('Field')->func);
|
||||
|
||||
if (!$this->name) {
|
||||
$this->_admin_msg(0, dr_lang('字段来源未定义'));
|
||||
}
|
||||
|
||||
return [$ismain, $issearch, $iscategory];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,492 @@
|
||||
<?php namespace Phpcmf\Control\Admin;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
class Home extends \Phpcmf\Common
|
||||
{
|
||||
|
||||
public function home() {
|
||||
$this->index();
|
||||
}
|
||||
|
||||
public function main() {
|
||||
|
||||
if (is_file(WRITEPATH.'update.txt')) {
|
||||
unlink(WRITEPATH.'update.txt');
|
||||
dr_redirect(dr_url('cache/index'));
|
||||
} elseif (is_file(WRITEPATH.'check.txt')) {
|
||||
unlink(WRITEPATH.'check.txt');
|
||||
dr_redirect(dr_url('check/index'));
|
||||
}
|
||||
|
||||
$local = \Phpcmf\Service::Apps(1);
|
||||
if ($local) {
|
||||
foreach ($local as $dir => $path) {
|
||||
if (is_file(dr_get_app_dir($dir).'Config/Panel.php')) {
|
||||
\Phpcmf\Service::V()->admin(dr_get_app_dir($dir).'Views/');
|
||||
require dr_get_app_dir($dir).'Config/Panel.php';
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$table_data = [];
|
||||
if (is_file(WRITEPATH.'config/main.php')) {
|
||||
$table_data = require WRITEPATH.'config/main.php';
|
||||
}
|
||||
|
||||
// 验证权限
|
||||
if ($table_data && !dr_in_array(1, $this->admin['roleid'])) {
|
||||
// 不是超管用户
|
||||
$auth = \Phpcmf\Service::M('system')->get_setting('index_main');
|
||||
if ($auth) {
|
||||
foreach ($table_data as $name => $t) {
|
||||
$key = md5($name);
|
||||
if (isset($auth[$key]) && !dr_array_intersect($this->admin['roleid'], (array)$auth[$key])) {
|
||||
unset($table_data[$name]); // 无权限移除
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$menu = [
|
||||
'控制台' => ['home/main', 'fa fa-home'],
|
||||
'自定义控制台' => ['home/edit', 'fa fa-edit'],
|
||||
//'后台功能地图' => ['js:dr_sitemap', 'fa fa-sitemap'],
|
||||
'访问项目首页' => ['blank:api/gohome', 'fa fa-send'],
|
||||
];
|
||||
if (!dr_in_array(1, $this->admin['roleid'])) {
|
||||
unset($menu['自定义控制台']);
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'menu' => \Phpcmf\Service::M('auth')->_admin_menu($menu),
|
||||
'admin' => $this->admin,
|
||||
'domain' => dr_get_domain_name(ROOT_URL),
|
||||
'license' => $this->cmf_license,
|
||||
'table_data' => $table_data,
|
||||
'cmf_update' => $this->cmf_version['updatetime'],
|
||||
'cmf_version' => $this->cmf_version['version'],
|
||||
]);
|
||||
\Phpcmf\Service::V()->display($table_data ? 'index_main.html' : 'main.html');
|
||||
}
|
||||
|
||||
public function init_edit() {
|
||||
|
||||
$file = WRITEPATH.'config/main.php';
|
||||
\Phpcmf\Service::L('Config')->file($file, '后台自定义面板', 32)->to_require([]);
|
||||
|
||||
$this->_json(1, dr_lang('自定义面板恢复成功'));
|
||||
}
|
||||
|
||||
//后台自定义面板
|
||||
public function edit() {
|
||||
|
||||
if (!dr_in_array(1, $this->admin['roleid'])) {
|
||||
$this->_admin_msg(0, dr_lang('无权限操作'));
|
||||
}
|
||||
|
||||
$file = WRITEPATH.'config/main.php';
|
||||
|
||||
if (IS_POST) {
|
||||
$data = \Phpcmf\Service::L('input')->post('tables');
|
||||
\Phpcmf\Service::L('Config')->file($file, '后台自定义面板', 32)->to_require($data);
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
exit;
|
||||
}
|
||||
|
||||
if (is_file($file)) {
|
||||
$data = require $file;
|
||||
} else {
|
||||
$data = [];
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'menu' => \Phpcmf\Service::M('auth')->_admin_menu(
|
||||
[
|
||||
'控制台' => ['home/main', 'fa fa-home'],
|
||||
'自定义控制台' => ['home/edit', 'fa fa-edit'],
|
||||
'help' => [718],
|
||||
]
|
||||
),
|
||||
'tables' => $this->_main_table(),
|
||||
'table_data' => $data,
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('index_edit.html');
|
||||
}
|
||||
|
||||
//后台自定义面板 权限划分
|
||||
public function auth_edit() {
|
||||
|
||||
$name = \Phpcmf\Service::L('input')->get('name');
|
||||
$data = \Phpcmf\Service::M('system')->get_setting('index_main');
|
||||
|
||||
if (IS_POST) {
|
||||
$post = \Phpcmf\Service::L('input')->post('data');
|
||||
if (!$post) {
|
||||
$post = [];
|
||||
}
|
||||
$post[] = 1;
|
||||
$data[$name] = array_unique($post);
|
||||
\Phpcmf\Service::M('system')->save_setting('index_main', $data);
|
||||
\Phpcmf\Service::M('system')->cache();
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'data' => $data[$name],
|
||||
'form' => dr_form_hidden(),
|
||||
'role' => \Phpcmf\Service::C()->get_cache('auth'),
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('index_auth_edit.html');
|
||||
}
|
||||
|
||||
public function index() {
|
||||
|
||||
// 账号是否强制了简化模式
|
||||
if (!IS_API_HTTP) {
|
||||
if (\Phpcmf\Service::M('auth')->is_admin_min_mode()) {
|
||||
$this->min();exit;
|
||||
} elseif ($this->admin['setting']['admin_min']) {
|
||||
// 自己切换的
|
||||
$this->min();exit;
|
||||
}
|
||||
}
|
||||
|
||||
$menu = \Phpcmf\Service::L('cache')->get('menu-admin');
|
||||
if (!$menu) {
|
||||
$m = \Phpcmf\Service::M('menu')->cache();
|
||||
$menu = $m['admin'];
|
||||
}
|
||||
|
||||
$first = 0;
|
||||
$mstring = $string = '';
|
||||
$menu_top = $my_menu = [];
|
||||
if ($this->admin['adminid'] > 1) {
|
||||
foreach ($menu as $t) {
|
||||
dr_in_array($t['mark'], $this->admin['system']['mark']) && $my_menu[$t['id']] = $t;
|
||||
}
|
||||
} else {
|
||||
$my_menu = $menu;
|
||||
}
|
||||
|
||||
// 挂钩点
|
||||
$rt = \Phpcmf\Hooks::trigger_callback('admin_menu', $menu, $my_menu);
|
||||
if ($rt && isset($rt['code']) && $rt['code']) {
|
||||
$my_menu = $rt['msg'];
|
||||
}
|
||||
|
||||
// 默认的首页内容
|
||||
$main_url = dr_url('home/main');
|
||||
$main_name = dr_lang('后台首页');
|
||||
$main_link = '';
|
||||
$main_menu = [];
|
||||
if (isset($_GET['go']) && $_GET['go']) {
|
||||
$go = urldecode((string)\Phpcmf\Service::L('input')->get('go'));
|
||||
$url = parse_url($go);
|
||||
if (isset($url['query']) && $url['query']) {
|
||||
parse_str($url['query'], $p);
|
||||
$uri = trim($p['s'].'/'.$p['c'].'/'.$p['m'], '/');
|
||||
$main_menu = \Phpcmf\Service::L('cache')->get('menu-admin-uri', $uri);
|
||||
if ($main_menu) {
|
||||
$first = $main_menu['tid'];
|
||||
$main_url = dr_url($uri);
|
||||
$main_name = dr_lang($main_menu['name'] ? $main_menu['name'] : '默认首页');
|
||||
$main_link = 'Mlink('.$main_menu['tid'].', '.$main_menu['pid'].', '.$main_menu['id'].', \'\');';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($my_menu) {
|
||||
// 加载全部插件的
|
||||
$local = \Phpcmf\Service::Apps();
|
||||
foreach ($local as $dir => $path) {
|
||||
// 判断插件目录
|
||||
if (is_file($path.'install.lock') && is_file($path.'Models/Auth.php') && is_file($path.'Config/App.php')) {
|
||||
$cfg = require $path.'Config/App.php';
|
||||
if ($cfg['type'] == 'app' && !$cfg['ftype']) {
|
||||
$obj = \Phpcmf\Service::M('auth', $dir);
|
||||
if (method_exists($obj, 'get_admin_menu_data')) {
|
||||
$my_menu = $obj->get_admin_menu_data($my_menu);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 权限判断并筛选
|
||||
foreach ($my_menu as $tid => $top) {
|
||||
if (!$top['left']) {
|
||||
unset($my_menu[$tid]);
|
||||
continue; // 没有分组菜单就不要
|
||||
} elseif (SITE_ID > 1 && !dr_in_array(SITE_ID, $top['site'])) {
|
||||
unset($my_menu[$tid]);
|
||||
continue; // 没有划分本站点就不显示
|
||||
} elseif ($top['mark'] && strpos($top['mark'], 'app-') === 0) {
|
||||
// 判断应用模块权限
|
||||
list($a, $mm) = explode('-', $top['mark']);
|
||||
if ($mm) {
|
||||
$mp = dr_get_app_dir($mm);
|
||||
if (is_file($mp.'Config/App.php')) {
|
||||
$config = require $mp.'Config/App.php';
|
||||
// 如果是内容模块
|
||||
if ((isset($config['ftype']) && $config['ftype'] == 'module') || $config['type'] == 'module') {
|
||||
if (!$this->get_cache('module-'.SITE_ID.'-content', $mm)) {
|
||||
unset($top[$tid]);
|
||||
unset($my_menu[$tid]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$left_string = '';
|
||||
!$first && $first = $tid;
|
||||
foreach ($top['left'] as $if => $left) {
|
||||
if (!$left['link']) {
|
||||
unset($top['left'][$if]);
|
||||
unset($my_menu[$tid]['left'][$if]);
|
||||
continue; // 没有链接菜单就不要
|
||||
} elseif (SITE_ID > 1 && !dr_in_array(SITE_ID, $left['site'])) {
|
||||
unset($top['left'][$if]);
|
||||
unset($my_menu[$tid]['left'][$if]);
|
||||
continue; // 没有划分本站点就不显示
|
||||
}
|
||||
// 链接菜单开始
|
||||
$link_string = '';
|
||||
foreach ($left['link'] as $i => $link) {
|
||||
if (SITE_ID > 1 && !dr_in_array(SITE_ID, $link['site'])) {
|
||||
unset($left['link'][$i]);
|
||||
unset($my_menu[$tid]['left'][$if]['link'][$i]);
|
||||
continue; // 没有划分本站点就不显示
|
||||
} elseif ($link['uri'] && !\Phpcmf\Service::M('auth')->_is_admin_auth($link['uri'], 1)) {
|
||||
// 判断权限
|
||||
unset($left['link'][$i]);
|
||||
unset($my_menu[$tid]['left'][$if]['link'][$i]);
|
||||
continue;
|
||||
} elseif ($link['mark'] && $left['mark'] == 'content-module') {
|
||||
// 内容模块权限判断
|
||||
list($ac, $name, $cname) = explode('-', $link['mark']);
|
||||
if ($ac == 'module' && !$this->get_cache('module-'.SITE_ID.'-content', $name)) {
|
||||
unset($left['link'][$i]);
|
||||
unset($my_menu[$tid]['left'][$if]['link'][$i]);
|
||||
continue;
|
||||
}
|
||||
// 网站表单权限判断
|
||||
if ($ac == 'app' && $name == 'form' && !$this->get_cache('form-'.SITE_ID, $cname)) {
|
||||
unset($left['link'][$i]);
|
||||
unset($my_menu[$tid]['left'][$if]['link'][$i]);
|
||||
continue;
|
||||
}
|
||||
} elseif (SITE_ID > 1 && $link['uri'] && $link['uri'] == 'cloud/local') {
|
||||
// 多站点不显示应用
|
||||
unset($left['link'][$i]);
|
||||
unset($my_menu[$tid]['left'][$if]['link'][$i]);
|
||||
continue;
|
||||
} elseif ($link['mark'] && $left['mark'] == 'content-verify') {
|
||||
// 内容模块审核部分权限判断
|
||||
list($ac, $ab, $name, $cc, $dd) = explode('-', $link['mark']);
|
||||
if ($ac.'-'.$ab == 'verify-module' && !$this->get_cache('module-'.SITE_ID.'-content', $name)) {
|
||||
unset($left['link'][$i]);
|
||||
unset($my_menu[$tid]['left'][$if]['link'][$i]);
|
||||
continue;
|
||||
}
|
||||
} elseif (IS_OEM_CMS && $link['uri'] == 'cloud/bf') {
|
||||
// oem版排除对比菜单
|
||||
unset($left['link'][$i]);
|
||||
unset($my_menu[$tid]['left'][$if]['link'][$i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
$left['link'][$i]['url'] = $link['url'] ? $link['url'] : \Phpcmf\Service::L('Router')->url($link['uri']);
|
||||
$left['link'][$i]['icon'] = $link['icon'] ? $link['icon'] : 'fa fa-th-large';
|
||||
|
||||
if (!$main_menu) {
|
||||
$main_menu = $link;
|
||||
}
|
||||
$link_string = 'true';
|
||||
}
|
||||
if (!$link_string) {
|
||||
unset($top['left'][$if]);
|
||||
unset($my_menu[$tid]['left'][$if]);
|
||||
continue; // 没有链接菜单就不要
|
||||
}
|
||||
$left_string = 'true';
|
||||
$top['left'][$if] = $left;
|
||||
}
|
||||
if (!$left_string) {
|
||||
$first == $tid && $first = 0;
|
||||
unset($my_menu[$tid]);
|
||||
continue; // 没有分组菜单就不要
|
||||
}
|
||||
$my_menu[$tid] = $top;
|
||||
unset($top['left']);
|
||||
$menu_top[$tid] = $top;
|
||||
}
|
||||
}
|
||||
if (!$menu_top && SITE_ID > 1) {
|
||||
$this->_admin_msg(0, dr_lang('没有给当前站点分配管理菜单权限'));
|
||||
}
|
||||
|
||||
if (IS_API_HTTP) {
|
||||
$vue_menu = [];
|
||||
foreach ($my_menu as $i => $top) {
|
||||
$vue_menu[$i] = [
|
||||
'heading' => $top['name'],
|
||||
'route' => $top['mark'],
|
||||
'fontIcon' => $top['icon'],
|
||||
'pages' => [],
|
||||
];
|
||||
foreach ($top['left'] as $f => $left) {
|
||||
$vue_menu[$i]['pages'][$f] = [
|
||||
'sectionTitle' => $left['name'],
|
||||
'route' => $left['mark'],
|
||||
'fontIcon' => $left['icon'],
|
||||
'sub' => [],
|
||||
];
|
||||
foreach ($left['link'] as $l => $link) {
|
||||
$vue_menu[$i]['pages'][$f]['sub'][] = [
|
||||
'heading' => $link['name'],
|
||||
'route' => '/'.$link['uri'],
|
||||
'fontIcon' => $link['icon'],
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->_json(1, 'ok', ['menu' => $vue_menu]);
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'top' => $menu_top,
|
||||
'first' => $first,
|
||||
'my_menu' => $my_menu,
|
||||
'is_index' => 1,
|
||||
'main_url' => $main_url,
|
||||
'main_link' => $main_link,
|
||||
'main_menu' => $main_menu,
|
||||
'main_name' => $main_name,
|
||||
'is_search_help' => IS_OEM_CMS ? 0 : CI_DEBUG,
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('index.html');exit;
|
||||
}
|
||||
|
||||
// 简化模式界面
|
||||
public function min() {
|
||||
|
||||
$menu = \Phpcmf\Service::L('cache')->get('menu-admin-min');
|
||||
if (!$menu) {
|
||||
$m = \Phpcmf\Service::M('menu')->cache();
|
||||
$menu = $m['admin-min'];
|
||||
}
|
||||
|
||||
$admin_menu = \Phpcmf\Service::L('cache')->get('menu-admin-uri');
|
||||
|
||||
$my_menu = $menu;
|
||||
|
||||
// 默认的首页内容
|
||||
$main_url = dr_url('home/main');
|
||||
$main_link = '';
|
||||
$main_menu = [];
|
||||
if (isset($_GET['go']) && $_GET['go']) {
|
||||
$go = urldecode((string)\Phpcmf\Service::L('input')->get('go'));
|
||||
$url = parse_url($go);
|
||||
if (isset($url['query']) && $url['query']) {
|
||||
parse_str($url['query'], $p);
|
||||
$uri = trim($p['s'].'/'.$p['c'].'/'.$p['m'], '/');
|
||||
$main_menu = \Phpcmf\Service::L('cache')->get('menu-admin-uri', $uri);
|
||||
if ($main_menu) {
|
||||
$first = $main_menu['tid'];
|
||||
$main_url = dr_url($uri);
|
||||
$main_link = 'Mlink('.$main_menu['tid'].', '.$main_menu['pid'].', '.$main_menu['id'].', \'\');';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($my_menu) {
|
||||
// 加载全部插件的
|
||||
$local = \Phpcmf\Service::Apps();
|
||||
foreach ($local as $dir => $path) {
|
||||
// 判断插件目录
|
||||
if (is_file($path.'install.lock') && is_file($path.'Models/Auth.php') && is_file($path.'Config/App.php')) {
|
||||
$cfg = require $path.'Config/App.php';
|
||||
if ($cfg['type'] == 'app' && !$cfg['ftype']) {
|
||||
$obj = \Phpcmf\Service::M('auth', $dir);
|
||||
if (method_exists($obj, 'get_admin_menu_data')) {
|
||||
$my_menu = $obj->get_admin_menu_data($my_menu);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 权限判断并筛选
|
||||
foreach ($my_menu as $tid => $left) {
|
||||
if (!$left['link']) {
|
||||
continue; // 没有分组菜单就不要
|
||||
}
|
||||
// 链接菜单开始
|
||||
$link_string = '';
|
||||
foreach ($left['link'] as $i => $link) {
|
||||
if ($link['uri'] && !$this->_is_admin_auth($link['uri'])) {
|
||||
// 判断权限
|
||||
unset($left['link'][$i]);
|
||||
continue;
|
||||
} elseif ($link['mark'] && $left['mark'] == 'content-module') {
|
||||
// 内容模块权限判断
|
||||
list($ac, $name) = explode('-', $link['mark']);
|
||||
if ($ac == 'module' && !$this->get_cache('module-'.SITE_ID.'-content', $name)) {
|
||||
unset($left['link'][$i]);
|
||||
continue;
|
||||
}
|
||||
// 网站表单权限判断
|
||||
list($ac, $name, $cname) = explode('-', $link['mark']);
|
||||
if ($ac == 'app' && $name == 'form' && !$this->get_cache('form-'.SITE_ID, $cname)) {
|
||||
unset($left['link'][$i]);
|
||||
continue;
|
||||
}
|
||||
} elseif (SITE_ID > 1 && $link['uri'] && $admin_menu[$link['uri']] && !dr_in_array(SITE_ID, $admin_menu[$link['uri']]['site'])) {
|
||||
// 没有划分本站点就不显示
|
||||
unset($left['link'][$i]);
|
||||
continue;
|
||||
} elseif (SITE_ID > 1 && $link['uri'] && $link['uri'] == 'cloud/local') {
|
||||
// 多站点不显示应用
|
||||
unset($left['link'][$i]);
|
||||
continue;
|
||||
} elseif ($link['mark'] && $left['mark'] == 'content-form') {
|
||||
// 网站表单权限判断
|
||||
} elseif ($link['mark'] && $left['mark'] == 'content-verify') {
|
||||
// 内容模块审核部分权限判断
|
||||
list($ac, $ab, $name, $cc) = explode('-', $link['mark']);
|
||||
if ($ac.'-'.$ab == 'verify-module' && !$this->get_cache('module-'.SITE_ID.'-content', $name)) {
|
||||
unset($left['link'][$i]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$left['link'][$i]['url'] = $link['url'] ? $link['url'] :\Phpcmf\Service::L('Router')->url($link['uri']);
|
||||
$left['link'][$i]['icon'] = $link['icon'] ? $link['icon'] : 'fa fa-th-large';
|
||||
$link_string.= 'true';
|
||||
if (!$main_menu) {
|
||||
$first = $tid;
|
||||
$main_menu = $link;
|
||||
}
|
||||
}
|
||||
if (!$link_string) {
|
||||
unset($my_menu[$tid]);
|
||||
continue; // 没有链接菜单就不要
|
||||
}
|
||||
$my_menu[$tid] = $left;
|
||||
}
|
||||
}
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'first' => $first,
|
||||
'is_min' => 1,
|
||||
'is_mode' => \Phpcmf\Service::M('auth')->is_admin_min_mode(),
|
||||
'my_menu' => $my_menu,
|
||||
'is_index' => 1,
|
||||
'main_url' => $main_url,
|
||||
'main_link' => $main_link,
|
||||
'main_menu' => $main_menu,
|
||||
'is_search_help' => IS_OEM_CMS ? 0 : CI_DEBUG,
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('index_min.html');exit;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,685 @@
|
||||
<?php namespace Phpcmf\Control\Admin;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
// 联动菜单
|
||||
class Linkage extends \Phpcmf\Common {
|
||||
|
||||
public function index() {
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'list' => \Phpcmf\Service::M('Linkage')->table('linkage')->getAll(),
|
||||
'menu' => \Phpcmf\Service::M('auth')->_admin_menu(
|
||||
[
|
||||
'联动菜单' => ['linkage/index', 'fa fa-columns'],
|
||||
'创建菜单' => ['add:linkage/add', 'fa fa-plus'],
|
||||
'修改' => ['hide:linkage/edit', 'fa fa-edit'],
|
||||
'数据管理' => ['hide:linkage/list_index', 'fa fa-table'],
|
||||
'help' => [354],
|
||||
]
|
||||
),
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('linkage_index.html');
|
||||
}
|
||||
|
||||
public function add() {
|
||||
|
||||
if (IS_AJAX_POST) {
|
||||
$data = \Phpcmf\Service::L('input')->post('data');
|
||||
$this->_validation(0, $data);
|
||||
\Phpcmf\Service::L('input')->system_log('创建联动菜单('.$data['name'].')');
|
||||
$rt = \Phpcmf\Service::M('Linkage')->create($data);
|
||||
if (!$rt['code']) {
|
||||
$this->_json(0, $rt['msg']);
|
||||
}
|
||||
\Phpcmf\Service::M('cache')->sync_cache('linkage', '', 1); // 自动更新缓存
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'form' => dr_form_hidden()
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('linkage_add.html');
|
||||
exit;
|
||||
}
|
||||
|
||||
public function edit() {
|
||||
|
||||
$id = intval(\Phpcmf\Service::L('input')->get('id'));
|
||||
$data = \Phpcmf\Service::M('Linkage')->table('linkage')->get($id);
|
||||
if (!$data) {
|
||||
$this->_admin_msg(0, dr_lang('联动菜单(%s)不存在', $id));
|
||||
}
|
||||
|
||||
if (IS_AJAX_POST) {
|
||||
$data = \Phpcmf\Service::L('input')->post('data');
|
||||
$data['code'] = strtolower($data['code']);
|
||||
$this->_validation($id, $data);
|
||||
$rt = \Phpcmf\Service::M('Linkage')->table('linkage')->update($id, $data);
|
||||
if (!$rt['code']) {
|
||||
$this->_json(0, $rt['msg']);
|
||||
}
|
||||
\Phpcmf\Service::L('input')->system_log('修改联动菜单('.$data['name'].')');
|
||||
\Phpcmf\Service::M('cache')->sync_cache('linkage', '', 1); // 自动更新缓存
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'data' => $data,
|
||||
'form' => dr_form_hidden()
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('linkage_add.html');exit;
|
||||
}
|
||||
|
||||
public function export_down() {
|
||||
|
||||
$key = (int)\Phpcmf\Service::L('input')->get('key');
|
||||
$file = WRITEPATH.'temp/linkage-export-file-'.$this->uid.'-'.$key.'.json';
|
||||
|
||||
if (!is_file($file)) {
|
||||
$this->_html_msg(0, dr_lang('导出文件不存在'));
|
||||
}
|
||||
|
||||
set_time_limit(0);
|
||||
$handle = fopen($file,"rb");
|
||||
if (FALSE === $handle) {
|
||||
$this->_html_msg(0, dr_lang('文件已经损坏'));
|
||||
}
|
||||
|
||||
$filesize = filesize($file);
|
||||
$link = \Phpcmf\Service::M()->table('linkage')->get($key);
|
||||
header('Content-Type: application/octet-stream');
|
||||
header("Accept-Ranges:bytes");
|
||||
header("Accept-Length:".$filesize);
|
||||
header("Content-Disposition: attachment; filename=".urlencode($link['name'].'.json'));
|
||||
|
||||
while (!feof($handle)) {
|
||||
$contents = fread($handle, 4096);
|
||||
echo $contents;
|
||||
ob_flush(); //把数据从PHP的缓冲中释放出来
|
||||
flush(); //把被释放出来的数据发送到浏览器
|
||||
}
|
||||
|
||||
fclose($handle);
|
||||
exit;
|
||||
}
|
||||
|
||||
public function export() {
|
||||
|
||||
$key = (int)\Phpcmf\Service::L('input')->get('key');
|
||||
$page = (int)\Phpcmf\Service::L('input')->get('page');
|
||||
$file = WRITEPATH.'temp/linkage-export-file-'.$this->uid.'-'.$key.'.json';
|
||||
|
||||
if (!$page) {
|
||||
$nums = \Phpcmf\Service::M()->table('linkage_data_'.$key)->counts();
|
||||
if (!$nums) {
|
||||
$this->_json(0, dr_lang('数据为空,无法导出'));
|
||||
}
|
||||
|
||||
$this->_html_msg(1, dr_lang('正在准备导出数据'), dr_url('linkage/export', ['key'=>$key, 'page' => 1]));
|
||||
} elseif ($page == 2) {
|
||||
$nums = \Phpcmf\Service::M()->table('linkage_data_'.$key)->counts();
|
||||
$this->_html_msg(1, dr_lang('导出完毕,共计%s条数据', $nums), dr_url('linkage/export_down', ['key'=>$key]), dr_lang('请关闭本窗口'));
|
||||
}
|
||||
|
||||
$data = \Phpcmf\Service::M()->db->table('linkage_data_'.$key)->orderBy('id DESC')->get()->getResultArray();
|
||||
|
||||
$rt = file_put_contents($file, dr_array2string($data));
|
||||
if (!$rt) {
|
||||
$this->_html_msg(0, '文件写入失败');
|
||||
}
|
||||
|
||||
$this->_html_msg(1, dr_lang('正在整理数据...'), dr_url('linkage/export', ['key'=>$key, 'page' => 2]));
|
||||
|
||||
}
|
||||
|
||||
public function import_add() {
|
||||
|
||||
$key = (int)\Phpcmf\Service::L('input')->get('key');
|
||||
$page = (int)\Phpcmf\Service::L('input')->get('page');
|
||||
$file = WRITEPATH.'temp/linkage-import-file-'.$this->uid.'-'.$key.'.json';
|
||||
$table = 'linkage_data_'.$key;
|
||||
|
||||
if (!$page) {
|
||||
if (!is_file($file)) {
|
||||
$this->_html_msg(0, dr_lang('导入文件不存在'));
|
||||
}
|
||||
\Phpcmf\Service::M()->table($table)->clear_all();
|
||||
$this->_html_msg(1, dr_lang('正在准备导入数据'), dr_url('linkage/import_add', ['key'=>$key, 'page' => 1]));
|
||||
}
|
||||
|
||||
if (!is_file($file)) {
|
||||
$nums = \Phpcmf\Service::M()->table('linkage_data_'.$key)->counts();
|
||||
\Phpcmf\Service::M('cache')->sync_cache('linkage', '', 1); // 自动更新缓存
|
||||
$this->_html_msg(1, dr_lang('导入完毕,共计%s条数据', $nums), '', dr_lang('请关闭本窗口'));
|
||||
}
|
||||
|
||||
// 开始导入
|
||||
$data = dr_string2array(file_get_contents($file));
|
||||
if (!is_array($data)) {
|
||||
$this->_html_msg(0, dr_lang('导入信息验证失败'));
|
||||
}
|
||||
foreach ($data as $t) {
|
||||
if (is_numeric($t['cname'])) {
|
||||
$t['cname'] = 'a'.$t['cname'];
|
||||
} elseif (!preg_match('/^[a-z]+[a-z0-9\_]+$/i', $t['cname'])) {
|
||||
$t['cname'] = dr_safe_filename($t['cname']);
|
||||
}
|
||||
$rt = \Phpcmf\Service::M('Linkage')->table($table)->insert($t);
|
||||
if ($rt['code']) {
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
|
||||
unlink($file);
|
||||
|
||||
$this->_html_msg(1, dr_lang('正在导入数据...'), dr_url('linkage/import_add', ['key'=>$key, 'page' => 2]));
|
||||
|
||||
}
|
||||
|
||||
public function import() {
|
||||
|
||||
$key = (int)\Phpcmf\Service::L('input')->get('key');
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'add_url' => dr_url('linkage/import_add', ['key' => $key]),
|
||||
'upload_url' => dr_url('linkage/import_upload', ['key' => $key]),
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('linkage_import.html');
|
||||
exit;
|
||||
}
|
||||
|
||||
// 上传处理
|
||||
function import_upload() {
|
||||
|
||||
$key = (int)\Phpcmf\Service::L('input')->get('key');
|
||||
$file = WRITEPATH.'temp/linkage-import-file-'.$this->uid.'-'.$key.'.json';
|
||||
$rt = \Phpcmf\Service::L('upload')->upload_file([
|
||||
'save_file' => $file, // 上传的固定文件路径
|
||||
'form_name' => 'file_data', // 固定格式
|
||||
'file_exts' => ['json'], // 上传的扩展名
|
||||
'file_size' => 2 * 1024 * 1024, // 上传的大小限制
|
||||
'attachment' => \Phpcmf\Service::M('Attachment')->get_attach_info('null'), // 固定文件时必须这样写
|
||||
]);
|
||||
if (!$rt['code']) {
|
||||
// 失败了
|
||||
exit(dr_array2string($rt));
|
||||
}
|
||||
// 验证json格式内容
|
||||
$data = dr_string2array(file_get_contents($file));
|
||||
if (!is_array($data)) {
|
||||
unlink($file);
|
||||
$this->_json(0, dr_lang('导入信息验证失败'));
|
||||
}
|
||||
// 上传成功了
|
||||
exit(dr_array2string($rt));
|
||||
}
|
||||
|
||||
public function del() {
|
||||
|
||||
$ids = \Phpcmf\Service::L('input')->get_post_ids();
|
||||
if (!$ids) {
|
||||
$this->_json(0, dr_lang('你还没有选择呢'));
|
||||
}
|
||||
|
||||
$rt = \Phpcmf\Service::M('Linkage')->delete_all($ids);
|
||||
if (!$rt['code']) {
|
||||
$this->_json(0, $rt['msg']);
|
||||
}
|
||||
|
||||
\Phpcmf\Service::M('cache')->sync_cache('linkage', '', 1); // 自动更新缓存
|
||||
\Phpcmf\Service::L('input')->system_log('批量联动菜单: '. implode(',', $ids));
|
||||
|
||||
$this->_json(1, dr_lang('操作成功'), ['ids' => $ids]);
|
||||
}
|
||||
|
||||
// 验证数据
|
||||
private function _validation($id, $data) {
|
||||
// 表单验证配置
|
||||
$config = [
|
||||
'name' => [
|
||||
'name' => '名称',
|
||||
'rule' => [
|
||||
'empty' => dr_lang('名称不能为空')
|
||||
],
|
||||
'filter' => [],
|
||||
'length' => '200'
|
||||
],
|
||||
'code' => [
|
||||
'name' => '别名',
|
||||
'rule' => [
|
||||
'empty' => dr_lang('别名不能为空'),
|
||||
'table' => dr_lang('别名格式不正确'),
|
||||
],
|
||||
'filter' => [],
|
||||
'length' => '200'
|
||||
],
|
||||
];
|
||||
list($data, $return) = \Phpcmf\Service::L('Form')->validation($data, $config);
|
||||
if ($return) {
|
||||
$this->_json(0, $return['error'], ['field' => $return['name']]);
|
||||
} elseif (\Phpcmf\Service::M('Linkage')->table('linkage')->is_exists($id, 'code', $data['code'])) {
|
||||
$this->_json(0, dr_lang('别名已经存在'), ['field' => 'code']);
|
||||
}
|
||||
}
|
||||
|
||||
public function displayorder_edit() {
|
||||
|
||||
// 查询数据
|
||||
$id = (int)\Phpcmf\Service::L('input')->get('id');
|
||||
$key = (int)\Phpcmf\Service::L('input')->get('key');
|
||||
$row = \Phpcmf\Service::M('Linkage')->table('linkage_data_'.$key)->get($id);
|
||||
if (!$row) {
|
||||
$this->_json(0, dr_lang('数据#%s不存在', $id));
|
||||
}
|
||||
|
||||
$value = (int)\Phpcmf\Service::L('input')->get('value');
|
||||
$rt = \Phpcmf\Service::M('Linkage')->table('linkage_data_'.$key)->save($id, 'displayorder', $value);
|
||||
if (!$rt['code']) {
|
||||
$this->_json(0, $rt['msg']);
|
||||
}
|
||||
|
||||
\Phpcmf\Service::M('cache')->sync_cache('linkage', '', 1); // 自动更新缓存
|
||||
\Phpcmf\Service::L('input')->system_log('修改联动菜单值('.$row['name'].')的排序值为'.$value);
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
|
||||
// 禁用或者启用
|
||||
public function hidden_edit() {
|
||||
|
||||
$id = (int)\Phpcmf\Service::L('input')->get('id');
|
||||
$key = (int)\Phpcmf\Service::L('input')->get('key');
|
||||
$row = \Phpcmf\Service::M('Linkage')->table('linkage_data_'.$key)->get($id);
|
||||
if (!$row) {
|
||||
$this->_json(0, dr_lang('数据#%s不存在', $id));
|
||||
}
|
||||
|
||||
$i = intval(\Phpcmf\Service::L('input')->get('id'));
|
||||
$v = $row['hidden'] ? 0 : 1;
|
||||
\Phpcmf\Service::M('Linkage')->table('linkage_data_'.$key)->update($id, ['hidden' => $v]);
|
||||
|
||||
\Phpcmf\Service::M('cache')->sync_cache('linkage', '', 1); // 自动更新缓存
|
||||
\Phpcmf\Service::L('input')->system_log('修改联动菜单状态: '. $i);
|
||||
$this->_json(1, dr_lang($v ? '此菜单已被禁用' : '此菜单已被启用'), ['value' => $v]);
|
||||
}
|
||||
|
||||
public function list_del() {
|
||||
|
||||
$ids = \Phpcmf\Service::L('input')->get_post_ids();
|
||||
$key = (int)\Phpcmf\Service::L('input')->get('key');
|
||||
if (!$ids) {
|
||||
$this->_json(0, dr_lang('你还没有选择呢'));
|
||||
}
|
||||
|
||||
$rt = \Phpcmf\Service::M('Linkage')->delete_list_all($key, $ids);
|
||||
if (!$rt['code']) {
|
||||
$this->_json(0, $rt['msg']);
|
||||
}
|
||||
|
||||
\Phpcmf\Service::M('cache')->sync_cache('linkage', '', 1); // 自动更新缓存
|
||||
\Phpcmf\Service::L('input')->system_log('批量删除联动菜单: '. implode(',', $ids));
|
||||
|
||||
$this->_json(1, dr_lang('操作成功'), ['ids' => $ids]);
|
||||
}
|
||||
|
||||
public function close_edit() {
|
||||
|
||||
$ids = \Phpcmf\Service::L('input')->get_post_ids();
|
||||
$key = (int)\Phpcmf\Service::L('input')->get('key');
|
||||
if (!$ids) {
|
||||
$this->_json(0, dr_lang('你还没有选择呢'));
|
||||
}
|
||||
|
||||
\Phpcmf\Service::M()->table('linkage_data_'.$key)->where_in('id', $ids)->update(null, [
|
||||
'hidden' => 1,
|
||||
]);
|
||||
|
||||
\Phpcmf\Service::M('cache')->sync_cache('linkage', '', 1); // 自动更新缓存
|
||||
\Phpcmf\Service::L('input')->system_log('批量禁用联动菜单: '. implode(',', $ids));
|
||||
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
|
||||
public function open_edit() {
|
||||
|
||||
$ids = \Phpcmf\Service::L('input')->get_post_ids();
|
||||
$key = (int)\Phpcmf\Service::L('input')->get('key');
|
||||
if (!$ids) {
|
||||
$this->_json(0, dr_lang('你还没有选择呢'));
|
||||
}
|
||||
|
||||
\Phpcmf\Service::M()->table('linkage_data_'.$key)->where_in('id', $ids)->update(null, [
|
||||
'hidden' => 0,
|
||||
]);
|
||||
|
||||
\Phpcmf\Service::M('cache')->sync_cache('linkage', '', 1); // 自动更新缓存
|
||||
\Phpcmf\Service::L('input')->system_log('批量启用联动菜单: '. implode(',', $ids));
|
||||
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
|
||||
// 变更分类
|
||||
public function pid_edit() {
|
||||
|
||||
$ids = \Phpcmf\Service::L('input')->get_post_ids();
|
||||
$key = (int)\Phpcmf\Service::L('input')->get('key');
|
||||
$pid = (int)\Phpcmf\Service::L('input')->post('pid');
|
||||
if (!$ids) {
|
||||
$this->_json(0, dr_lang('你还没有选择呢'));
|
||||
}
|
||||
|
||||
$rt = \Phpcmf\Service::M('Linkage')->edit_pid_all($key, $pid, $ids);
|
||||
if (!$rt['code']) {
|
||||
$this->_json(0, $rt['msg']);
|
||||
}
|
||||
|
||||
\Phpcmf\Service::M('cache')->sync_cache('linkage', '', 1); // 自动更新缓存
|
||||
\Phpcmf\Service::L('input')->system_log('批量更改联动菜单分类: '. implode(',', $ids));
|
||||
|
||||
$this->_json(1, dr_lang('操作成功'), ['ids' => $ids]);
|
||||
}
|
||||
|
||||
// 数据列表
|
||||
public function list_index() {
|
||||
|
||||
$key = (int)\Phpcmf\Service::L('input')->get('key');
|
||||
$pid = (int)\Phpcmf\Service::L('input')->get('pid');
|
||||
|
||||
$link = \Phpcmf\Service::M('Linkage')->table('linkage')->get($key);
|
||||
if (!$link) {
|
||||
$this->_admin_msg(0, dr_lang('联动菜单不存在'));
|
||||
}
|
||||
|
||||
$select = dr_fieldform('{"name":"pid","fieldname":"pid","ismain":"1","fieldtype":"Linkage","setting":{"option":{"linkage":"'.$link['code'].'","file":"","ck_child":"0","value":"","css":""},"validate":{"required":"0","pattern":"","errortips":"","check":"","filter":"","formattr":"","tips":""}},"ismember":"1"}', 0, 1, 1);
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'key' => $key,
|
||||
'pid' => $pid,
|
||||
'list' => \Phpcmf\Service::M('Linkage')->getList($link, $pid),
|
||||
'menu' => \Phpcmf\Service::M('auth')->_admin_menu(
|
||||
[
|
||||
'联动菜单' => ['linkage/index', 'fa fa-columns'],
|
||||
'数据管理' => ['hide:linkage/list_index', 'fa fa-table'],
|
||||
'修改' => ['hide:linkage/list_edit', 'fa fa-edit'],
|
||||
'添加' => ['linkage/list_add{key='.$key.'&pid='.$pid.'}', 'fa fa-plus'],
|
||||
'help' => [354],
|
||||
]
|
||||
),
|
||||
'select' => str_replace('data[pid]', 'pid', $select),
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('linkage_list_index.html');
|
||||
}
|
||||
|
||||
// 快速添加数据
|
||||
public function listk_add() {
|
||||
|
||||
$pid = (int)\Phpcmf\Service::L('input')->get('pid');
|
||||
$key = (int)\Phpcmf\Service::L('input')->get('key');
|
||||
$link = \Phpcmf\Service::M('Linkage')->table('linkage')->get($key);
|
||||
if (!$link) {
|
||||
$this->_admin_msg(0, dr_lang('联动菜单不存在'));
|
||||
}
|
||||
|
||||
if (IS_AJAX_POST) {
|
||||
$data = \Phpcmf\Service::L('input')->post('data', true);
|
||||
$rt = \Phpcmf\Service::M('Linkage')->add_list($key, $data);
|
||||
if (!$rt['code']) {
|
||||
$this->_json(0, $rt['msg']);
|
||||
}
|
||||
\Phpcmf\Service::M('cache')->sync_cache('linkage', '', 1); // 自动更新缓存
|
||||
\Phpcmf\Service::L('input')->system_log('创建联动菜单('.$data['name'].')');
|
||||
$this->_json(1, $rt['msg']);
|
||||
}
|
||||
|
||||
$select = '';
|
||||
if ($pid) {
|
||||
$top = \Phpcmf\Service::M('Linkage')->table('linkage_data_'.$key)->get($pid);
|
||||
if ($top) {
|
||||
$select = '<input type="hidden" name="data[pid]" value="'.$pid.'">';
|
||||
$select.= '<p class="form-control-static"> '.$top['name'].' </p>';
|
||||
}
|
||||
}
|
||||
if (!$select) {
|
||||
$select = '<input type="hidden" name="data[pid]" value="0">';
|
||||
$select.= '<p class="form-control-static"> '.dr_lang('顶级').' </p>';
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'form' => dr_form_hidden(),
|
||||
'select' => $select
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('linkage_list_add.html');
|
||||
exit;
|
||||
}
|
||||
|
||||
// 添加数据
|
||||
public function list_add() {
|
||||
|
||||
$pid = (int)\Phpcmf\Service::L('input')->get('pid');
|
||||
$key = (int)\Phpcmf\Service::L('input')->get('key');
|
||||
$link = \Phpcmf\Service::M('Linkage')->table('linkage')->get($key);
|
||||
if (!$link) {
|
||||
$this->_admin_msg(0, dr_lang('联动菜单不存在'));
|
||||
}
|
||||
|
||||
$field = \Phpcmf\Service::M('Linkage')->get_fields($key);
|
||||
|
||||
if (IS_AJAX_POST) {
|
||||
$post = \Phpcmf\Service::L('input')->post('data');
|
||||
$post['name'] = trim($post['name']);
|
||||
if (!$post['name']) {
|
||||
$this->_json(0, dr_lang('名称不能为空'));
|
||||
} elseif (!$post['cname']) {
|
||||
$this->_json(0, dr_lang('别名不能为空'));
|
||||
} elseif (is_numeric($post['cname'])) {
|
||||
$this->_json(0, dr_lang('别名不能是数字'));
|
||||
} elseif (!preg_match('/^[a-z]+[a-z0-9\_]+$/i', $post['cname'])) {
|
||||
$this->_json(0, dr_lang('别名名称不规范'));
|
||||
} elseif (\Phpcmf\Service::M()->db->table('linkage_data_'.$key)->where('cname', $post['cname'])->countAllResults()) {
|
||||
$this->_json(0, dr_lang('别名已经存在'));
|
||||
}
|
||||
$update = [
|
||||
'pid' => $post['pid'],
|
||||
'name' => $post['name'],
|
||||
'cname' => $post['cname'],
|
||||
];
|
||||
if ($field) {
|
||||
list($save, $return, $attach) = \Phpcmf\Service::L('form')->validation($post, null, $field, []);
|
||||
// 输出错误
|
||||
if ($return) {
|
||||
$this->_json(0, $return['error'], ['field' => $return['name']]);
|
||||
}
|
||||
$update = dr_array22array($update, $save[1]);
|
||||
}
|
||||
$update['site'] = SITE_ID;
|
||||
$rt = \Phpcmf\Service::M('Linkage')->table('linkage_data_'.$key)->insert($update);
|
||||
if (!$rt['code']) {
|
||||
$this->_json(0, $rt['msg']);
|
||||
}
|
||||
// 附件归档
|
||||
SYS_ATTACHMENT_DB && $attach && \Phpcmf\Service::M('Attachment')->handle(
|
||||
$this->member['id'],
|
||||
\Phpcmf\Service::M()->dbprefix('linkage_data_'.$key),
|
||||
$attach
|
||||
);
|
||||
\Phpcmf\Service::M('cache')->sync_cache('linkage', '', 1); // 自动更新缓存
|
||||
\Phpcmf\Service::L('input')->system_log('创建联动菜单('.$post['name'].')');
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
|
||||
$select = '';
|
||||
if ($pid) {
|
||||
$top = \Phpcmf\Service::M('Linkage')->table('linkage_data_'.$key)->get($pid);
|
||||
if ($top) {
|
||||
$select = '<input type="hidden" name="data[pid]" value="'.$pid.'">';
|
||||
$select.= '<p class="form-control-static"> '.$top['name'].' </p>';
|
||||
}
|
||||
}
|
||||
if (!$select) {
|
||||
$select = '<input type="hidden" name="data[pid]" value="0">';
|
||||
$select.= '<p class="form-control-static"> '.dr_lang('顶级').' </p>';
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'form' => dr_form_hidden(),
|
||||
'menu' => \Phpcmf\Service::M('auth')->_admin_menu(
|
||||
[
|
||||
'联动菜单' => ['linkage/index', 'fa fa-columns'],
|
||||
'数据管理' => ['linkage/list_index{key='.$key.'}', 'fa fa-table'],
|
||||
'修改' => ['hide:linkage/list_edit', 'fa fa-edit'],
|
||||
'添加' => ['linkage/list_add{key='.$key.'&pid='.$pid.'}', 'fa fa-plus'],
|
||||
'help' => [354],
|
||||
]
|
||||
),
|
||||
'select' => $select,
|
||||
'myfield' => \Phpcmf\Service::L('field')->toform($this->uid, $field, []),
|
||||
'reply_url' => dr_url('linkage/list_index', ['key'=> $key, 'pid' => $pid]),
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('linkage_list_edit.html');
|
||||
}
|
||||
|
||||
// 修改数据
|
||||
public function list_edit() {
|
||||
|
||||
$id = (int)\Phpcmf\Service::L('input')->get('id');
|
||||
$key = (int)\Phpcmf\Service::L('input')->get('key');
|
||||
|
||||
$link = \Phpcmf\Service::M('Linkage')->table('linkage')->get($key);
|
||||
if (!$link) {
|
||||
$this->_admin_msg(0, dr_lang('联动菜单不存在'));
|
||||
}
|
||||
|
||||
$data = \Phpcmf\Service::M('Linkage')->table('linkage_data_'.$key)->get($id);
|
||||
if (!$data) {
|
||||
$this->_admin_msg(0, dr_lang('联动菜单数据#%s不存在', $id));
|
||||
}
|
||||
|
||||
$field = \Phpcmf\Service::M('Linkage')->get_fields($key);
|
||||
|
||||
if (IS_AJAX_POST) {
|
||||
$post = \Phpcmf\Service::L('input')->post('data');
|
||||
$post['name'] = trim($post['name']);
|
||||
if (!$post['name']) {
|
||||
$this->_json(0, dr_lang('名称不能为空'));
|
||||
} elseif (!$post['cname']) {
|
||||
$this->_json(0, dr_lang('别名不能为空'));
|
||||
} elseif (is_numeric($post['cname'])) {
|
||||
$this->_json(0, dr_lang('别名不能是数字'));
|
||||
} elseif (!preg_match('/^[a-z]+[a-z0-9\_]+$/i', $post['cname'])) {
|
||||
$this->_json(0, dr_lang('别名名称不规范'));
|
||||
} else if (\Phpcmf\Service::M()->db->table('linkage_data_'.$key)->where('id<>', $id)->where('cname', $post['cname'])->countAllResults()) {
|
||||
$this->_json(0, dr_lang('别名已经存在'));
|
||||
}
|
||||
$update = [
|
||||
'pid' => $post['pid'],
|
||||
'name' => $post['name'],
|
||||
'cname' => $post['cname'],
|
||||
];
|
||||
if ($field) {
|
||||
list($save, $return, $attach) = \Phpcmf\Service::L('form')->validation($post, null, $field, $data);
|
||||
// 输出错误
|
||||
if ($return) {
|
||||
$this->_json(0, $return['error'], ['field' => $return['name']]);
|
||||
}
|
||||
$update = dr_array22array($update, $save[1]);
|
||||
}
|
||||
$rt = \Phpcmf\Service::M('Linkage')->table('linkage_data_'.$key)->update($id, $update);
|
||||
if (!$rt['code']) {
|
||||
$this->_json(0, $rt['msg']);
|
||||
}
|
||||
// 附件归档
|
||||
SYS_ATTACHMENT_DB && $attach && \Phpcmf\Service::M('Attachment')->handle(
|
||||
$this->member['id'],
|
||||
\Phpcmf\Service::M()->dbprefix('linkage_data_'.$key),
|
||||
$attach
|
||||
);
|
||||
\Phpcmf\Service::M('cache')->sync_cache('linkage', '', 1); // 自动更新缓存
|
||||
\Phpcmf\Service::L('input')->system_log('修改联动菜单('.$post['name'].')');
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
|
||||
$select = '';
|
||||
if ($data['pid']) {
|
||||
$top = \Phpcmf\Service::M('Linkage')->table('linkage_data_'.$key)->get($data['pid']);
|
||||
if ($top) {
|
||||
$select = '<input type="hidden" name="data[pid]" value="'.$data['pid'].'">';
|
||||
$select.= '<p class="form-control-static"> '.$top['name'].' </p>';
|
||||
}
|
||||
}
|
||||
if (!$select) {
|
||||
$select = '<input type="hidden" name="data[pid]" value="0">';
|
||||
$select.= '<p class="form-control-static"> '.dr_lang('顶级').' </p>';
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'form' => dr_form_hidden(),
|
||||
'data' => $data,
|
||||
'menu' => \Phpcmf\Service::M('auth')->_admin_menu(
|
||||
[
|
||||
'联动菜单' => ['linkage/index', 'fa fa-columns'],
|
||||
'数据管理' => ['linkage/list_index{key='.$key.'}', 'fa fa-table'],
|
||||
'修改' => ['hide:linkage/list_edit', 'fa fa-edit'],
|
||||
'添加' => ['linkage/list_add{key='.$key.'&pid='.$data['pid'].'}', 'fa fa-plus'],
|
||||
'help' => [354],
|
||||
]
|
||||
),
|
||||
'select' => $select,
|
||||
'myfield' => \Phpcmf\Service::L('field')->toform($this->uid, $field, $data),
|
||||
'reply_url' => dr_url('linkage/list_index', ['key'=> $key, 'pid' => $data['pid']]),
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('linkage_list_edit.html');
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
// 一键生成
|
||||
public function cache_index() {
|
||||
|
||||
$key = (int)\Phpcmf\Service::L('input')->get('key');
|
||||
$link = \Phpcmf\Service::M('Linkage')->table('linkage')->get($key);
|
||||
if (!$link) {
|
||||
$this->_html_msg(0, dr_lang('联动菜单不存在'));
|
||||
}
|
||||
|
||||
$page = (int)\Phpcmf\Service::L('input')->get('page');
|
||||
$psize = 10; // 每页处理的数量
|
||||
$total = (int)\Phpcmf\Service::L('input')->get('total');
|
||||
|
||||
if (!$page) {
|
||||
$path = WRITEPATH.'linkage/'.SITE_ID.'_'.$link['code'].'/';
|
||||
dr_dir_delete($path);
|
||||
$links = \Phpcmf\Service::M('Linkage')->repair($link, SITE_ID); // 修复菜单
|
||||
$pids = \Phpcmf\Service::M('Linkage')->get_child_pids();
|
||||
$total = dr_count($pids);
|
||||
if (!$total) {
|
||||
$this->_html_msg(0, dr_lang('无可用数据'));
|
||||
}
|
||||
// 存储执行
|
||||
\Phpcmf\Service::L('cache')->set_auth_data('linkage-all-'.$key, $links, SITE_ID);
|
||||
\Phpcmf\Service::L('cache')->set_auth_data('linkage-cache-'.$key, array_chunk($pids, $psize), SITE_ID);
|
||||
$this->_html_msg(1, dr_lang('正在执行中...'), dr_url('linkage/cache_index', ['key' => $key]).'&total='.$total.'&page='.($page+1));
|
||||
}
|
||||
|
||||
$tpage = ceil($total / $psize); // 总页数
|
||||
$pids = \Phpcmf\Service::L('cache')->get_auth_data('linkage-cache-'.$key, SITE_ID);
|
||||
if (!$pids) {
|
||||
$this->_html_msg(0, dr_lang('临时数据读取失败'));
|
||||
} elseif (!isset($pids[$page-1]) || $page > $tpage) {
|
||||
// 生成级联关系
|
||||
$links = \Phpcmf\Service::L('cache')->get_auth_data('linkage-all-'.$key, SITE_ID);
|
||||
\Phpcmf\Service::M('Linkage')->get_json($link, $links);
|
||||
$this->_html_msg(1, dr_lang('更新完成'));
|
||||
}
|
||||
|
||||
$field = \Phpcmf\Service::M('Linkage')->get_fields($key);
|
||||
foreach ($pids[$page-1] as $pid) {
|
||||
\Phpcmf\Service::M('linkage')->cache_list($link, $pid, $field);
|
||||
}
|
||||
|
||||
$this->_html_msg( 1, dr_lang('正在执行中【%s】...', "$tpage/$page"),
|
||||
dr_url('linkage/cache_index', ['key' => $key, 'total' => $total, 'page' => $page + 1])
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,250 @@
|
||||
<?php namespace Phpcmf\Control\Admin;
|
||||
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
class Login extends \Phpcmf\Common
|
||||
{
|
||||
|
||||
public function index() {
|
||||
|
||||
$url = '';
|
||||
if (isset($_GET['go']) && $_GET['go']) {
|
||||
$url = pathinfo(urldecode((string)\Phpcmf\Service::L('input')->get('go')));
|
||||
$url = $url['basename'] && $url['basename'] != SELF ? $url['basename'] : '';
|
||||
}
|
||||
|
||||
// 避免安装时的卡顿超时
|
||||
if (is_file(WRITEPATH.'install.test')) {
|
||||
set_time_limit(0);
|
||||
// 创建后台默认菜单
|
||||
\Phpcmf\Service::M('Menu')->init('admin');
|
||||
\Phpcmf\Service::M('Menu')->init('admin_min');
|
||||
// 完成之后更新缓存
|
||||
\Phpcmf\Service::M('cache')->update_cache();
|
||||
unlink(WRITEPATH.'install.test');
|
||||
}
|
||||
|
||||
|
||||
if (IS_AJAX_POST) {
|
||||
$sn = $is_login = 0;
|
||||
// 回调钩子
|
||||
$data = \Phpcmf\Service::L('input')->post('data');
|
||||
\Phpcmf\Hooks::trigger('admin_login_before', $data);
|
||||
$rs = \Phpcmf\Hooks::trigger_callback('admin_login_post', $data);
|
||||
if ($rs && isset($rs['code']) && $rs['msg']) {
|
||||
// 返回登陆类型
|
||||
if (!$rs['code']) {
|
||||
// 登陆失败
|
||||
$this->_json(0, $rs['msg']);
|
||||
} else {
|
||||
// 登陆成功
|
||||
$is_login = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$is_login) {
|
||||
// 账号登录
|
||||
if (defined('SYS_ADMIN_LOGINS') && SYS_ADMIN_LOGINS) {
|
||||
$sn = (int)$this->session()->get('fclogin_error_sn');
|
||||
$time = (int)$this->session()->get('fclogin_error_time');
|
||||
if (defined('SYS_ADMIN_LOGIN_TIME') && SYS_ADMIN_LOGIN_TIME && $time && SYS_TIME - $time > (SYS_ADMIN_LOGIN_TIME * 60)) {
|
||||
// 超过时间了
|
||||
\Phpcmf\Service::C()->session()->set('fclogin_error_sn', 0);
|
||||
\Phpcmf\Service::C()->session()->set('fclogin_error_time', 0);
|
||||
}
|
||||
}
|
||||
if (SYS_ADMIN_CODE && !\Phpcmf\Service::L('form')->check_captcha('code')) {
|
||||
$this->_json(0, dr_lang('验证码不正确'));
|
||||
} elseif (!IS_DEV && defined('SYS_ADMIN_LOGINS') && SYS_ADMIN_LOGINS && $sn && $sn > SYS_ADMIN_LOGINS) {
|
||||
$msg = dr_lang('失败次数已达到%s次,已被禁止登录', SYS_ADMIN_LOGINS);
|
||||
$msg2 = dr_lang('后台登录密码错误的次数已达到%s次', SYS_ADMIN_LOGINS);
|
||||
$user = \Phpcmf\Service::M()->table('member')->where('username', $data['username'])->getRow();
|
||||
if ($user) {
|
||||
\Phpcmf\Service::M()->table('member_data')->update($user['id'], ['is_lock' => 1]);
|
||||
$user['email'] && \Phpcmf\Service::M('member')->sendmail($user['email'], $msg2, 'admin_password_error.html', $data);
|
||||
}
|
||||
\Phpcmf\Service::L('input')->system_log($msg2, 1, [], $data['username']);
|
||||
$this->_json(0, $msg);
|
||||
} elseif (empty($data['username']) || empty($data['password'])) {
|
||||
$this->_json(0, dr_lang('账号或密码必须填写'));
|
||||
} else {
|
||||
if (defined('SYS_ADMIN_LOGIN_AES') && SYS_ADMIN_LOGIN_AES && !isset($_POST['is_aes'])) {
|
||||
$this->_json(0, IS_DEV ? '登陆模板不支持AES加密传输,请在cache/config/system.php中配置SYS_ADMIN_LOGIN_AES=0' : dr_lang('当前登录模板不支持AES加密传输'));
|
||||
}
|
||||
$data['username'] = dr_safe_username($data['username']);
|
||||
$login = \Phpcmf\Service::M('auth')->login(
|
||||
$data['username'],
|
||||
$data['password'],
|
||||
!IS_DEV && defined('SYS_ADMIN_SMS_CHECK') && SYS_ADMIN_SMS_CHECK
|
||||
);
|
||||
if (isset($this->admin) && is_array($this->admin)) {
|
||||
$this->admin['uid'] = 0;
|
||||
$this->admin['username'] = $data['username'];
|
||||
}
|
||||
if ($login['code']) {
|
||||
// 登录成功
|
||||
if ($login['code'] == "sms") {
|
||||
$this->_json(9, dr_lang('向%s的手机发送验证码:',
|
||||
substr($login['msg'], 0, 3).'****'.substr($login['msg'],-4)),
|
||||
dr_authcode($login['msg'], 'ENCODE')
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// 登录失败
|
||||
if ($login['data'] == 3) {
|
||||
// 密码错误时记录日志
|
||||
\Phpcmf\Service::L('input')->password_log($data);
|
||||
// 记录错误计次
|
||||
if (defined('SYS_ADMIN_LOGINS') && SYS_ADMIN_LOGINS) {
|
||||
\Phpcmf\Service::C()->session()->set('fclogin_error_sn', $sn + 1);
|
||||
\Phpcmf\Service::C()->session()->set('fclogin_error_time', SYS_TIME);
|
||||
}
|
||||
} else {
|
||||
// 写入日志
|
||||
\Phpcmf\Service::L('input')->system_log($login['msg'], 1, [], dr_safe_replace($data['username']));
|
||||
}
|
||||
$this->_json(0, $login['msg']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
\Phpcmf\Service::L('input')->system_log('登录后台成功', 1, [], $data['username']);
|
||||
if ($sn) {
|
||||
// 解除禁止登陆
|
||||
\Phpcmf\Service::C()->session()->set('fclogin_error_sn', 0);
|
||||
\Phpcmf\Service::C()->session()->set('fclogin_error_time', 0);
|
||||
}
|
||||
if (IS_API_HTTP) {
|
||||
return $this->_json(1, 'ok', $login['data'], true);
|
||||
}
|
||||
if (!$url) {
|
||||
$url = SELF.'?time='.SYS_TIME;
|
||||
if (isset($data['mode']) && $data['mode']) {
|
||||
// 模式选择
|
||||
$admin = \Phpcmf\Service::M()->table('admin')->where('uid', $login['code'])->getRow();
|
||||
$setting = (array)dr_string2array($admin['setting']);
|
||||
if ($data['mode'] == 2) {
|
||||
// 简化
|
||||
$setting['admin_min'] = 1;
|
||||
file_put_contents(WRITEPATH.'config/admin.mode', 1);
|
||||
} else {
|
||||
// 完整
|
||||
if (\Phpcmf\Service::M('auth')->is_admin_min_mode()) {
|
||||
$this->_json(0, dr_lang('此账号无法使用完整模式'));
|
||||
}
|
||||
$setting['admin_min'] = 0;
|
||||
@unlink(WRITEPATH.'config/admin.mode');
|
||||
}
|
||||
\Phpcmf\Service::M()->table('admin')->update($login['code'], [
|
||||
'setting' => dr_array2string($setting)
|
||||
]);
|
||||
}
|
||||
}
|
||||
$url = dr_redirect_safe_check(\Phpcmf\Service::L('input')->xss_clean($url, true));
|
||||
// 写入日志
|
||||
$this->admin = $login['data'];
|
||||
return $this->_json(1, 'ok', ['sync' => [], 'url' => $url], true);
|
||||
}
|
||||
|
||||
// 检测登录了就跳转首页
|
||||
if ($this->member) {
|
||||
$uid = (int)$this->session()->get('uid');
|
||||
if ($uid == $this->member['uid']) {
|
||||
$rt = \Phpcmf\Service::M('auth')->member($this->member, 1);
|
||||
if (!$rt['code']) {
|
||||
$this->_admin_msg(0, $rt['msg']);
|
||||
} else {
|
||||
dr_redirect(SELF);exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$license = \Phpcmf\Service::R(MYPATH.'Config/License.php');
|
||||
|
||||
$name = dr_oauth_list();
|
||||
if (dr_is_app('weixin')) {
|
||||
$name['wechat'] = [];
|
||||
}
|
||||
|
||||
$oauth = [];
|
||||
if ($name) {
|
||||
$ourl = ADMIN_URL.SELF.'?c=api&m=oauth&is_admin_call=1&name=';
|
||||
foreach ($name as $value => $t) {
|
||||
if (!isset($this->member_cache['oauth'][$value]['id'])
|
||||
|| !$this->member_cache['oauth'][$value]['id']) {
|
||||
continue;
|
||||
}
|
||||
if (in_array($value, ['weixin', 'wechat'])) {
|
||||
if (dr_is_weixin_app()) {
|
||||
dr_is_app('weixin') && $oauth['wechat'] = [
|
||||
'title' => '微信公众号登录',
|
||||
'name' => 'wechat',
|
||||
'url' => OAUTH_URL.'index.php?s=weixin&c=member&m=login_url&back='.urlencode($ourl.'wechat'),
|
||||
];
|
||||
} else {
|
||||
$oauth[$value] = [
|
||||
'title' => ($value == 'weixin' ? '微信扫码' : '微信公众号').'登录',
|
||||
'name' => $value,
|
||||
'url' => OAUTH_URL.'index.php?s=api&c=oauth&m=index&name='.$value.'&type=login&back='.urlencode($ourl.$value),
|
||||
];
|
||||
}
|
||||
} else {
|
||||
$oauth[$value] = [
|
||||
'title' => $t['name'].'登录',
|
||||
'name' => $value,
|
||||
'url' => OAUTH_URL.'index.php?s=api&c=oauth&m=index&name='.$value.'&type=login&back='.urlencode($ourl.$value),
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$mode = is_file(WRITEPATH.'config/admin.mode') ? 2 : 1;
|
||||
|
||||
$mytpl = '';
|
||||
$rs = \Phpcmf\Hooks::trigger_callback('admin_login_html', $data);
|
||||
if ($rs && isset($rs['code']) && $rs['code']) {
|
||||
$mytpl = $rs['msg'];
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'mode' => $mode,
|
||||
'form' => dr_form_hidden(),
|
||||
'oauth' => $oauth,
|
||||
'mytpl' => $mytpl,
|
||||
'license' => $license,
|
||||
'crypto_iv' => substr(md5(SYS_KEY), 10, 16),
|
||||
'crypto_key' => substr(md5(SYS_KEY), 0, 16),
|
||||
'sms_url' => WEB_DIR.SELF.'?c=login&m=sms',
|
||||
'login_url' => WEB_DIR.SELF.'?c=login&go='.urlencode($url).'&'.($is_sms ? 'is_sms=1' : ''),
|
||||
'rlogin_url' => WEB_DIR.SELF.'?c=login&go='.urlencode($url),
|
||||
]);
|
||||
if (isset($_GET['is_cloud']) && $_GET['is_cloud']) {
|
||||
\Phpcmf\Service::V()->display('cloud_login_admin.html');exit;
|
||||
} else {
|
||||
\Phpcmf\Service::V()->display('login.html');exit;
|
||||
}
|
||||
}
|
||||
|
||||
// 子站客户端自动登录
|
||||
public function fclient() {
|
||||
|
||||
$file = ROOTPATH.'api/fclient/login.php';
|
||||
if (!is_file($file)) {
|
||||
$this->_admin_msg(0, '子站客户端程序'.(IS_DEV ? $file : '').'未安装');
|
||||
}
|
||||
|
||||
require $file;
|
||||
}
|
||||
|
||||
public function out() {
|
||||
$this->session()->remove('uid');
|
||||
$this->session()->remove('admin');
|
||||
$this->session()->remove('siteid');
|
||||
return $this->_json(1, dr_lang('您已经安全退出系统了'), 0, true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,281 @@
|
||||
<?php namespace Phpcmf\Control\Admin;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
class Menu extends \Phpcmf\Common
|
||||
{
|
||||
private $form; // 表单验证配置
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
\Phpcmf\Service::V()->assign('menu', \Phpcmf\Service::M('auth')->_admin_menu(
|
||||
[
|
||||
'后台菜单' => ['menu/index', 'fa fa-list-alt'],
|
||||
'初始化菜单' => ['ajax:menu/init', 'fa fa-refresh'],
|
||||
'help' => [927],
|
||||
]
|
||||
));
|
||||
// 表单验证配置
|
||||
$this->form = [
|
||||
'name' => [
|
||||
'name' => '菜单名称',
|
||||
'rule' => [
|
||||
'empty' => dr_lang('菜单名称不能为空')
|
||||
],
|
||||
'filter' => [],
|
||||
'length' => '200'
|
||||
],
|
||||
'icon' => [
|
||||
'name' => '菜单图标',
|
||||
'rule' => [
|
||||
'empty' => dr_lang('菜单图标不能为空')
|
||||
],
|
||||
'filter' => [],
|
||||
'length' => '100'
|
||||
],
|
||||
'uri' => [
|
||||
'name' => '系统路径',
|
||||
'rule' => [
|
||||
'empty' => dr_lang('系统路径不能为空')
|
||||
],
|
||||
'filter' => [],
|
||||
'length' => '200'
|
||||
],
|
||||
'url' => [
|
||||
'name' => '实际地址',
|
||||
'rule' => [
|
||||
'empty' => dr_lang('实际地址不能为空')
|
||||
],
|
||||
'filter' => [
|
||||
'url'
|
||||
],
|
||||
'length' => '200'
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function index() {
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'data' => \Phpcmf\Service::M('menu')->gets('admin'),
|
||||
'color' => ['blue', 'red', 'green', 'dark', 'yellow'],
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('menu_index.html');
|
||||
}
|
||||
|
||||
public function add() {
|
||||
|
||||
$pid = intval(\Phpcmf\Service::L('input')->get('pid'));
|
||||
$top = \Phpcmf\Service::M('menu')->get_top('admin');
|
||||
$type = $pid ? (isset($top[$pid]) ? 2 : 3) : 1;
|
||||
|
||||
if (IS_AJAX_POST) {
|
||||
$data = \Phpcmf\Service::L('input')->post('data');
|
||||
$data = $this->_validation($type, $data);
|
||||
if ($data['uri'] && \Phpcmf\Service::M()->table('admin_menu')->where('uri', $data['uri'])->counts()) {
|
||||
// 链接菜单判断重复
|
||||
$this->_json(0, dr_lang('系统路径已经存在'), ['field' => 'uri']);
|
||||
}
|
||||
$rt = \Phpcmf\Service::M('menu')->_add('admin', $pid, $data);
|
||||
if ($rt['code']) {
|
||||
\Phpcmf\Service::M('cache')->sync_cache(''); // 自动更新缓存
|
||||
\Phpcmf\Service::L('input')->system_log('添加后台菜单: '.$data['name']);
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
} else {
|
||||
$this->_json(0, $rt['msg']);
|
||||
}
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'type' => $type,
|
||||
'form' => dr_form_hidden()
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('menu_add.html');
|
||||
exit;
|
||||
}
|
||||
|
||||
public function site_add() {
|
||||
|
||||
$ids = \Phpcmf\Service::L('input')->get_post_ids();
|
||||
if (!$ids) {
|
||||
$this->_json(0, dr_lang('你还没有选择呢'));
|
||||
}
|
||||
|
||||
$data = \Phpcmf\Service::M()->db->table('admin_menu')->whereIN('id', $ids)->get()->getResultArray();
|
||||
if (!$data) {
|
||||
$this->_json(0, dr_lang('无可用菜单'));
|
||||
}
|
||||
|
||||
$sids = \Phpcmf\Service::L('input')->post('siteid');
|
||||
if (!$sids) {
|
||||
foreach ($data as $t) {
|
||||
\Phpcmf\Service::M()->db->table('admin_menu')->where('id', $t['id'])->update([
|
||||
'site' => ''
|
||||
]);
|
||||
}
|
||||
$this->_json(1, dr_lang('取消成功'));
|
||||
}
|
||||
|
||||
foreach ($data as $t) {
|
||||
$value = dr_string2array($t['site']);
|
||||
foreach ($sids as $sid) {
|
||||
$value[$sid] = $sid;
|
||||
}
|
||||
\Phpcmf\Service::M()->db->table('admin_menu')->where('id', $t['id'])->update([
|
||||
'site' => dr_array2string($value)
|
||||
]);
|
||||
}
|
||||
|
||||
\Phpcmf\Service::M('cache')->sync_cache(''); // 自动更新缓存
|
||||
$this->_json(1, dr_lang('划分成功'));
|
||||
}
|
||||
|
||||
public function site_del() {
|
||||
|
||||
$id = (int)\Phpcmf\Service::L('input')->get('id');
|
||||
$data = \Phpcmf\Service::M('menu')->getRowData('admin', $id);
|
||||
if (!$data) {
|
||||
$this->_json(0, dr_lang('菜单不存在'));
|
||||
}
|
||||
|
||||
$sid = (int)\Phpcmf\Service::L('input')->get('sid');
|
||||
if (!$sid) {
|
||||
$this->_json(0, dr_lang('站点id不存在'));
|
||||
}
|
||||
|
||||
$value = dr_string2array($data['site']);
|
||||
unset($value[$sid]);
|
||||
|
||||
\Phpcmf\Service::M()->db->table('admin_menu')->where('id', $id)->update([
|
||||
'site' => dr_array2string($value)
|
||||
]);
|
||||
|
||||
\Phpcmf\Service::M('cache')->sync_cache(''); // 自动更新缓存
|
||||
$this->_json(1, dr_lang('删除成功'));
|
||||
}
|
||||
|
||||
public function edit() {
|
||||
|
||||
$id = intval(\Phpcmf\Service::L('input')->get('id'));
|
||||
$data = \Phpcmf\Service::M('menu')->getRowData('admin', $id);
|
||||
if (!$data) {
|
||||
$this->_json(0, dr_lang('数据#%s不存在', $id));
|
||||
}
|
||||
|
||||
$pid = intval($data['pid']);
|
||||
$top = \Phpcmf\Service::M('menu')->get_top('admin');
|
||||
$type = $pid ? (isset($top[$pid]) ? 2 : 3) : 1;
|
||||
|
||||
if (IS_AJAX_POST) {
|
||||
$data = \Phpcmf\Service::L('input')->post('data');
|
||||
$data = $this->_validation($type, $data);
|
||||
if ($data['uri'] && \Phpcmf\Service::M()->table('admin_menu')->where('id<>'.$id)->where('uri', $data['uri'])->counts()) {
|
||||
// 链接菜单判断重复
|
||||
$this->_json(0, dr_lang('系统路径已经存在'), ['field' => 'uri']);
|
||||
}
|
||||
\Phpcmf\Service::M('menu')->_update('admin', $id, $data);
|
||||
\Phpcmf\Service::M('cache')->sync_cache(''); // 自动更新缓存
|
||||
\Phpcmf\Service::L('input')->system_log('修改后台菜单: '.$data['name']);
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'type' => $type,
|
||||
'data' => $data,
|
||||
'form' => dr_form_hidden(),
|
||||
'select' => \Phpcmf\Service::M('Menu')->parent_select('admin', $type, $pid)
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('menu_add.html');
|
||||
exit;
|
||||
}
|
||||
|
||||
public function del() {
|
||||
|
||||
$ids = \Phpcmf\Service::L('input')->get_post_ids();
|
||||
if (!$ids) {
|
||||
$this->_json(0, dr_lang('你还没有选择呢'));
|
||||
}
|
||||
|
||||
\Phpcmf\Service::M('menu')->_delete('admin', $ids);
|
||||
\Phpcmf\Service::M('cache')->sync_cache(''); // 自动更新缓存
|
||||
\Phpcmf\Service::L('input')->system_log('批量删除后台菜单: '. implode(',', $ids));
|
||||
$this->_json(1, dr_lang('操作成功'), ['ids' => $ids]);
|
||||
}
|
||||
|
||||
// 初始化
|
||||
public function init() {
|
||||
|
||||
\Phpcmf\Service::M('menu')->init('admin');
|
||||
|
||||
\Phpcmf\Service::L('input')->system_log('初始化后台菜单');
|
||||
\Phpcmf\Service::M('cache')->update_cache(); // 自动更新缓存
|
||||
|
||||
$this->_json(1, dr_lang('初始化菜单成功,请按F5刷新整个页面'));
|
||||
}
|
||||
|
||||
// 隐藏或者启用
|
||||
public function use_edit() {
|
||||
|
||||
$i = intval(\Phpcmf\Service::L('input')->get('id'));
|
||||
$v = \Phpcmf\Service::M('menu')->_uesd('admin', $i);
|
||||
if ($v == -1) {
|
||||
$this->_json(0, dr_lang('数据#%s不存在', $i), ['value' => $v]);
|
||||
}
|
||||
\Phpcmf\Service::M('cache')->sync_cache(''); // 自动更新缓存
|
||||
\Phpcmf\Service::L('input')->system_log('修改后台菜单状态: '. $i);
|
||||
$this->_json(1, dr_lang($v ? '此菜单已被隐藏' : '此菜单已被启用'), ['value' => $v]);
|
||||
|
||||
}
|
||||
|
||||
// 保存数据
|
||||
public function save_edit() {
|
||||
|
||||
$i = intval(\Phpcmf\Service::L('input')->get('id'));
|
||||
\Phpcmf\Service::M('menu')->_save(
|
||||
'admin',
|
||||
$i,
|
||||
dr_safe_replace(\Phpcmf\Service::L('input')->get('name')),
|
||||
dr_safe_replace(\Phpcmf\Service::L('input')->get('value'))
|
||||
);
|
||||
|
||||
\Phpcmf\Service::M('cache')->sync_cache(''); // 自动更新缓存
|
||||
\Phpcmf\Service::L('input')->system_log('修改后台菜单信息: '. $i);
|
||||
$this->_json(1, dr_lang('更改成功'));
|
||||
}
|
||||
|
||||
|
||||
// 验证数据
|
||||
private function _validation($type, $data) {
|
||||
|
||||
if ($type != 3) {
|
||||
// 非链接菜单时不录入url和uri
|
||||
unset($this->form['url'], $this->form['uri']);
|
||||
} else {
|
||||
// url和uri 只验证一个
|
||||
if ($data['url']) {
|
||||
unset($this->form['uri']);
|
||||
}
|
||||
if ($data['uri']) {
|
||||
unset($this->form['url']);
|
||||
}
|
||||
}
|
||||
|
||||
//$type是菜单级别 1 2 3
|
||||
if (in_array($type, [2, 1]) && !$data['mark']) {
|
||||
$this->_json(0, dr_lang('标识字符不能为空'), ['field' => 'mark']);
|
||||
}
|
||||
|
||||
list($data, $return) = \Phpcmf\Service::L('form')->validation($data, $this->form);
|
||||
|
||||
if ($return) {
|
||||
$this->_json(0, $return['error'], ['field' => $return['name']]);
|
||||
}
|
||||
|
||||
$data['uri'] = strtolower((string)$data['uri']);
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,296 @@
|
||||
<?php namespace Phpcmf\Control\Admin;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
class Min_menu extends \Phpcmf\Common {
|
||||
|
||||
private $form; // 表单验证配置
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
\Phpcmf\Service::V()->assign('menu', \Phpcmf\Service::M('auth')->_admin_menu(
|
||||
[
|
||||
'简化菜单' => ['min_menu/index', 'fa fa-list-alt'],
|
||||
'初始化菜单' => ['ajax:min_menu/init', 'fa fa-refresh'],
|
||||
'help' => [961],
|
||||
]
|
||||
));
|
||||
// 表单验证配置
|
||||
$this->form = [
|
||||
'name' => [
|
||||
'name' => '菜单名称',
|
||||
'rule' => [
|
||||
'empty' => dr_lang('菜单名称不能为空')
|
||||
],
|
||||
'filter' => [],
|
||||
'length' => '200'
|
||||
],
|
||||
'icon' => [
|
||||
'name' => '菜单图标',
|
||||
'rule' => [
|
||||
'empty' => dr_lang('菜单图标不能为空')
|
||||
],
|
||||
'filter' => [],
|
||||
'length' => '100'
|
||||
],
|
||||
'uri' => [
|
||||
'name' => '系统路径',
|
||||
'rule' => [
|
||||
'empty' => dr_lang('系统路径不能为空')
|
||||
],
|
||||
'filter' => [],
|
||||
'length' => '200'
|
||||
],
|
||||
'url' => [
|
||||
'name' => '实际地址',
|
||||
'rule' => [
|
||||
'empty' => dr_lang('实际地址不能为空')
|
||||
],
|
||||
'filter' => [
|
||||
'url'
|
||||
],
|
||||
'length' => '200'
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function index() {
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'data' => \Phpcmf\Service::M('Menu')->gets('admin_min'),
|
||||
'color' => ['blue', 'red', 'green', 'dark', 'yellow'],
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('min_menu_list.html');
|
||||
}
|
||||
|
||||
public function add() {
|
||||
|
||||
$pid = intval(\Phpcmf\Service::L('input')->get('pid'));
|
||||
$top = \Phpcmf\Service::M('Menu')->get_top('admin_min');
|
||||
|
||||
if (IS_AJAX_POST) {
|
||||
$data = \Phpcmf\Service::L('input')->post('data');
|
||||
if ($pid) {
|
||||
if (!$data['id']) {
|
||||
$this->_json(0, dr_lang('没有选择菜单'));
|
||||
}
|
||||
$menu = \Phpcmf\Service::M('Menu')->getRowData('admin', $data['id']);
|
||||
if (!$menu) {
|
||||
$this->_json(0, dr_lang('所选菜单不存在'));
|
||||
}
|
||||
$data = [
|
||||
'pid' => $pid,
|
||||
'name' => $menu['name'],
|
||||
'mark' => $menu['mark'],
|
||||
'icon' => $menu['icon'],
|
||||
'uri' => $menu['uri'],
|
||||
'url' => $menu['url'],
|
||||
'displayorder' => $data['displayorder'],
|
||||
];
|
||||
}
|
||||
$data = $this->_validation($data);
|
||||
\Phpcmf\Service::L('input')->system_log('添加简化菜单: '.$data['name']);
|
||||
$rt = \Phpcmf\Service::M('Menu')->_add('admin_min', $pid, $data);
|
||||
if ($rt['code']) {
|
||||
\Phpcmf\Service::M('cache')->sync_cache(''); // 自动更新缓存
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
} else {
|
||||
$this->_json(0, $rt['msg']);
|
||||
}
|
||||
}
|
||||
|
||||
$select = '<select class="form-control" name="data[id]">';
|
||||
$select.= '<option value="0"> -- </option>';
|
||||
$topdata = \Phpcmf\Service::M()->table('admin_menu')->where('pid=0')->order_by('displayorder ASC,id ASC')->getAll();
|
||||
foreach ($topdata as $t) {
|
||||
$leftdata = \Phpcmf\Service::M()->table('admin_menu')->where('pid='.$t['id'])->order_by('displayorder ASC,id ASC')->getAll();
|
||||
$is_left = '';
|
||||
foreach ($leftdata as $c) {
|
||||
$linkdata = \Phpcmf\Service::M()->table('admin_menu')->where('pid='.$c['id'])->order_by('displayorder ASC,id ASC')->getAll();
|
||||
$is_link = '';
|
||||
if ($linkdata) {
|
||||
foreach ($linkdata as $k) {
|
||||
if ($k['uri'] && !$this->_is_admin_auth($k['uri'])) {
|
||||
continue;
|
||||
}
|
||||
$is_link.= '<option value="'.$k['id'].'"> └ '.$k['name'].'</option>';
|
||||
}
|
||||
}
|
||||
if ($is_link) {
|
||||
$is_left.= '<optgroup label=" └ '.$c['name'].'">';
|
||||
$is_left.= $is_link;
|
||||
$is_left.= '</optgroup>';
|
||||
}
|
||||
}
|
||||
if ($is_left) {
|
||||
$select.= '<optgroup label="'.$t['name'].'">';
|
||||
$select.= $is_left;
|
||||
$select.= '</optgroup>';
|
||||
}
|
||||
}
|
||||
$select.= '</select>';
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'top' => $top,
|
||||
'type' => $pid,
|
||||
'form' => dr_form_hidden(),
|
||||
'select' => $select
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('min_menu_add.html');
|
||||
exit;
|
||||
}
|
||||
|
||||
public function edit() {
|
||||
|
||||
$id = intval(\Phpcmf\Service::L('input')->get('id'));
|
||||
$data = \Phpcmf\Service::M('Menu')->getRowData('admin_min', $id);
|
||||
if (!$data) {
|
||||
$this->_json(0, dr_lang('数据#%s不存在', $id));
|
||||
}
|
||||
|
||||
$top = \Phpcmf\Service::M('Menu')->get_top('admin_min');
|
||||
|
||||
if (IS_AJAX_POST) {
|
||||
$data = \Phpcmf\Service::L('input')->post('data');
|
||||
$data = $this->_validation($data);
|
||||
if ($data['uri']
|
||||
&& \Phpcmf\Service::M()->table('admin_min_menu')->where('id<>'.$id)->where('uri', $data['uri'])->counts()) {
|
||||
// 链接菜单判断重复
|
||||
$this->_json(0, dr_lang('系统路径已经存在'), ['field' => 'uri']);
|
||||
}
|
||||
\Phpcmf\Service::M('Menu')->_update('admin_min', $id, $data);
|
||||
\Phpcmf\Service::L('input')->system_log('修改简化菜单: '.$data['name']);
|
||||
|
||||
\Phpcmf\Service::M('cache')->sync_cache(''); // 自动更新缓存
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
|
||||
if ($data['pid']) {
|
||||
$select = '<select class="form-control" name="data[pid]">';
|
||||
$topdata = \Phpcmf\Service::M()->table('admin_min_menu')->where('pid=0')->order_by('displayorder ASC,id ASC')->getAll();
|
||||
foreach ($topdata as $t) {
|
||||
$select.= '<option value="'.$t['id'].'" '.($data['pid'] == $t['id'] ? 'selected' : '').'>'.$t['name'].'</option>';
|
||||
}
|
||||
$select.= '</select>';
|
||||
} else {
|
||||
$select = '<input type="hidden" value="0" name="data[pid]" /><div class="form-control-static"><label>'.dr_lang('顶级').'</label></div>';
|
||||
}
|
||||
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'top' => $top,
|
||||
'type' => $data['pid'],
|
||||
'data' => $data,
|
||||
'form' => dr_form_hidden(),
|
||||
'select' => $select
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('min_menu_edit.html');
|
||||
exit;
|
||||
}
|
||||
|
||||
public function del() {
|
||||
|
||||
$ids = \Phpcmf\Service::L('input')->get_post_ids();
|
||||
if (!$ids) {
|
||||
$this->_json(0, dr_lang('你还没有选择呢'));
|
||||
}
|
||||
|
||||
\Phpcmf\Service::M('Menu')->_delete('admin_min', $ids);
|
||||
\Phpcmf\Service::M('cache')->sync_cache(''); // 自动更新缓存
|
||||
\Phpcmf\Service::L('input')->system_log('批量删除简化菜单: '. implode(',', $ids));
|
||||
$this->_json(1, dr_lang('操作成功'), ['ids' => $ids]);
|
||||
}
|
||||
|
||||
|
||||
// 初始化
|
||||
public function init() {
|
||||
|
||||
\Phpcmf\Service::M('Menu')->init('admin_min');
|
||||
\Phpcmf\Service::L('input')->system_log('初始化简化菜单');
|
||||
\Phpcmf\Service::M('cache')->update_cache(); // 自动更新缓存
|
||||
$this->_json(1, dr_lang('初始化菜单成功,请按F5刷新整个页面'));
|
||||
}
|
||||
|
||||
// 隐藏或者启用
|
||||
public function use_edit() {
|
||||
|
||||
$i = intval(\Phpcmf\Service::L('input')->get('id'));
|
||||
$v = \Phpcmf\Service::M('Menu')->_uesd('admin_min', $i);
|
||||
if ($v == -1) {
|
||||
$this->_json(0, dr_lang('数据#%s不存在', $i), ['value' => $v]);
|
||||
}
|
||||
\Phpcmf\Service::L('input')->system_log('修改简化菜单状态: '. $i);
|
||||
\Phpcmf\Service::M('cache')->sync_cache(''); // 自动更新缓存
|
||||
$this->_json(1, dr_lang($v ? '此菜单已被隐藏' : '此菜单已被启用'), ['value' => $v]);
|
||||
|
||||
}
|
||||
|
||||
// 保存数据
|
||||
public function save_edit() {
|
||||
|
||||
$i = intval(\Phpcmf\Service::L('input')->get('id'));
|
||||
\Phpcmf\Service::M('Menu')->_save(
|
||||
'admin_min',
|
||||
$i,
|
||||
dr_safe_replace(\Phpcmf\Service::L('input')->get('name')),
|
||||
dr_safe_replace(\Phpcmf\Service::L('input')->get('value'))
|
||||
);
|
||||
|
||||
\Phpcmf\Service::M('cache')->sync_cache(''); // 自动更新缓存
|
||||
\Phpcmf\Service::L('input')->system_log('修改简化菜单信息: '. $i);
|
||||
|
||||
$this->_json(1, dr_lang('更改成功'));
|
||||
}
|
||||
|
||||
|
||||
// 验证数据
|
||||
private function _validation($data) {
|
||||
|
||||
if (!$data['pid']) {
|
||||
// 非链接菜单时不录入url和uri
|
||||
unset($this->form['url'], $this->form['uri']);
|
||||
} else {
|
||||
// url和uri 只验证一个
|
||||
if ($data['url']) {
|
||||
unset($this->form['uri']);
|
||||
}
|
||||
if ($data['uri']) {
|
||||
unset($this->form['url']);
|
||||
}
|
||||
}
|
||||
|
||||
// 顶级验证mark
|
||||
if (!$data['pid']) {
|
||||
if (!$data['mark']) {
|
||||
$this->_json(0, dr_lang('标识字符不能为空'), ['field' => 'mark']);
|
||||
}
|
||||
/*
|
||||
elseif (!\Phpcmf\Service::M()->table('admin_menu')->where('mark', $data['mark'])->counts()) {
|
||||
$this->_json(0, dr_lang('标识字符没有存在于完整菜单中'), ['field' => 'mark']);
|
||||
}*/
|
||||
}
|
||||
|
||||
if ($data['uri'] && !\Phpcmf\Service::M()->table('admin_menu')->where('uri', $data['uri'])->counts()) {
|
||||
// 验证是否操作员完整菜单中
|
||||
$this->_json(0, dr_lang('系统路径没有存在于完整菜单中'), ['field' => 'uri']);
|
||||
}
|
||||
|
||||
if ($data['mark']) {
|
||||
list($a, $b) = explode('-', $data['mark']);
|
||||
if ($a == 'module' && !is_dir(dr_get_app_dir($b))) {
|
||||
$this->_json(0, dr_lang('模块[%s]不存在', $b), ['field' => 'mark']);
|
||||
}
|
||||
}
|
||||
|
||||
list($data, $return) = \Phpcmf\Service::L('form')->validation($data, $this->form);
|
||||
if ($return) {
|
||||
$this->_json(0, $return['error'], ['field' => $return['name']]);
|
||||
}
|
||||
|
||||
$data['uri'] = strtolower((string)$data['uri']);
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
<?php namespace Phpcmf\Control\Admin;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
class Notice extends \Phpcmf\Common
|
||||
{
|
||||
|
||||
private $field;
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
$this->field = [
|
||||
'msg' => [
|
||||
'name' => dr_lang('内容'),
|
||||
'ismain' => 1,
|
||||
'fieldname' => 'msg',
|
||||
'fieldtype' => 'Text',
|
||||
],
|
||||
'username' => [
|
||||
'name' => dr_lang('申请人'),
|
||||
'ismain' => 1,
|
||||
'fieldname' => 'username',
|
||||
'fieldtype' => 'Text',
|
||||
],
|
||||
'op_username' => [
|
||||
'name' => dr_lang('处理人'),
|
||||
'ismain' => 1,
|
||||
'fieldname' => 'op_username',
|
||||
'fieldtype' => 'Text',
|
||||
]
|
||||
];
|
||||
$menu = [
|
||||
'处理记录' => [\Phpcmf\Service::L('Router')->class.'/index', 'fa fa-bell-slash'],
|
||||
'待处理' => [\Phpcmf\Service::L('Router')->class.'/my_index', 'fa fa-bell-o'],
|
||||
];
|
||||
if (dr_in_array(1, $this->admin['roleid'])) {
|
||||
$menu['全部'] = [\Phpcmf\Service::L('Router')->class.'/all_index', 'fa fa-bell'];
|
||||
}
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'menu' => \Phpcmf\Service::M('auth')->_admin_menu($menu),
|
||||
'field' => $this->field,
|
||||
]);
|
||||
}
|
||||
|
||||
// 处理记录
|
||||
public function index() {
|
||||
|
||||
list($list, $total, $param) = \Phpcmf\Service::M()->init([
|
||||
'table' => 'admin_notice',
|
||||
'where_list' => 'op_uid='. $this->uid . ' and (site=0 or site='.SITE_ID.')',
|
||||
'field' => $this->field,
|
||||
'date_field' => 'inputtime',
|
||||
'order' => 'inputtime desc'
|
||||
])->limit_page();
|
||||
|
||||
if ($param['keyword']) {
|
||||
$param['keyword'] = htmlspecialchars($param['keyword']);
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'list' => $list,
|
||||
'total' => $total,
|
||||
'param' => $param,
|
||||
'mypages' => \Phpcmf\Service::L('input')->page(\Phpcmf\Service::L('Router')->url(\Phpcmf\Service::L('Router')->class.'/'.\Phpcmf\Service::L('Router')->method), $total, 'admin')
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('notice_index.html');
|
||||
}
|
||||
|
||||
// 待处理
|
||||
public function my_index() {
|
||||
|
||||
if (\Phpcmf\Service::M('auth')->is_post_user()) {
|
||||
$where = '`to_uid`='.$this->uid.' and `status`<>3 and (site=0 or site='.SITE_ID.')';
|
||||
} else {
|
||||
$where = '((`to_uid`='.$this->uid.') '.($this->admin['roleid'] ? ' or (`to_rid` IN ('.implode(',', $this->admin['roleid']).'))' : '').' or (`to_uid`=0 and `to_rid`=0)) and `status`<>3 and (site=0 or site='.SITE_ID.')';
|
||||
}
|
||||
|
||||
list($list, $total, $param) = \Phpcmf\Service::M()->init([
|
||||
'table' => 'admin_notice',
|
||||
'where_list' => $where,
|
||||
'field' => $this->field,
|
||||
'date_field' => 'inputtime',
|
||||
'order' => 'inputtime desc'
|
||||
])->limit_page();
|
||||
|
||||
if ($param['keyword']) {
|
||||
$param['keyword'] = htmlspecialchars($param['keyword']);
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'list' => $list,
|
||||
'total' => $total,
|
||||
'param' => $param,
|
||||
'mypages' => \Phpcmf\Service::L('input')->page(\Phpcmf\Service::L('Router')->url(\Phpcmf\Service::L('Router')->class.'/'.\Phpcmf\Service::L('Router')->method), $total, 'admin')
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('notice_index.html');
|
||||
}
|
||||
|
||||
// 全部
|
||||
public function all_index() {
|
||||
|
||||
if (!dr_in_array(1, $this->admin['roleid'])) {
|
||||
$this->_admin_msg(0, dr_lang('需要超级管理员账号操作'));
|
||||
}
|
||||
|
||||
list($list, $total, $param) = \Phpcmf\Service::M()->init([
|
||||
'table' => 'admin_notice',
|
||||
'field' => $this->field,
|
||||
'date_field' => 'inputtime',
|
||||
'where_list' => '(site=0 or site='.SITE_ID.')',
|
||||
'order' => 'inputtime desc'
|
||||
])->limit_page();
|
||||
|
||||
if ($param['keyword']) {
|
||||
$param['keyword'] = htmlspecialchars($param['keyword']);
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'list' => $list,
|
||||
'total' => $total,
|
||||
'param' => $param,
|
||||
'mypages' => \Phpcmf\Service::L('input')->page(\Phpcmf\Service::L('Router')->url(\Phpcmf\Service::L('Router')->class.'/'.\Phpcmf\Service::L('Router')->method, $param), $total, 'admin')
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('notice_index.html');
|
||||
}
|
||||
|
||||
public function del() {
|
||||
|
||||
$ids = \Phpcmf\Service::L('input')->get_post_ids();
|
||||
if (!$ids) {
|
||||
$this->_json(0, dr_lang('所选数据不存在'));
|
||||
}
|
||||
|
||||
\Phpcmf\Service::M()->db->table('admin_notice')->whereIn('id', $ids)->delete();
|
||||
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php namespace Phpcmf\Control\Admin;
|
||||
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
class Password_log extends \Phpcmf\Common
|
||||
{
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
\Phpcmf\Service::V()->assign('menu', \Phpcmf\Service::M('auth')->_admin_menu(
|
||||
[
|
||||
'密码错误记录' => [\Phpcmf\Service::L('Router')->class.'/index', 'fa fa-unlock-alt'],
|
||||
]
|
||||
));
|
||||
}
|
||||
|
||||
public function index() {
|
||||
|
||||
$file = WRITEPATH.'password_log.php';
|
||||
$data = $list = [];
|
||||
if (filesize($file) > 1024*1024*2) {
|
||||
$list[] = [
|
||||
'time' => SYS_TIME,
|
||||
'username' => '账号',
|
||||
'message' => '此日志文件大于2MB,请使用Ftp等工具查看此文件:'.$file,
|
||||
];
|
||||
} else {
|
||||
$code = file_get_contents($file);
|
||||
if ($code) {
|
||||
$data = explode(PHP_EOL, str_replace(array(chr(13), chr(10)), PHP_EOL, $code));
|
||||
if ($data) {
|
||||
unset($data[0]);
|
||||
$data = array_reverse($data);
|
||||
}
|
||||
$page = max(1, (int)\Phpcmf\Service::L('input')->get('page'));
|
||||
$limit = ($page - 1) * SYS_ADMIN_PAGESIZE;
|
||||
$i = $j = 0;
|
||||
foreach ($data as $v) {
|
||||
$val = dr_string2array($v);
|
||||
if ($val && $i >= $limit && $j < SYS_ADMIN_PAGESIZE) {
|
||||
$list[] = $val;
|
||||
$j ++;
|
||||
}
|
||||
$i ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$total = max(0, dr_count($data) - 1);
|
||||
|
||||
\Phpcmf\Service::V()->assign(array(
|
||||
|
||||
'list' => $list,
|
||||
'total' => $total,
|
||||
'mypages' => \Phpcmf\Service::L('input')->page(dr_url(\Phpcmf\Service::L('Router')->class.'/index'), $total, 'admin')
|
||||
));
|
||||
\Phpcmf\Service::V()->display('password_log.html');
|
||||
}
|
||||
|
||||
|
||||
public function del() {
|
||||
|
||||
unlink(WRITEPATH.'password_log.php');
|
||||
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,290 @@
|
||||
<?php namespace Phpcmf\Control\Admin;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
class Role extends \Phpcmf\Common {
|
||||
|
||||
private $form; // 表单验证配置
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
// 不是超级管理员
|
||||
if (!dr_in_array(1, $this->admin['roleid'])) {
|
||||
$this->_admin_msg(0, dr_lang('需要超级管理员账号操作'));
|
||||
}
|
||||
\Phpcmf\Service::V()->assign('menu', \Phpcmf\Service::M('auth')->_admin_menu(
|
||||
[
|
||||
'角色权限' => ['role/index', 'fa fa-users'],
|
||||
'添加' => ['add:role/add', 'fa fa-plus', '500px', '400px'],
|
||||
'权限划分' => ['hide:role/auth_edit', 'fa fa-user-md'],
|
||||
'help' => ['824'],
|
||||
]
|
||||
));
|
||||
// 表单验证配置
|
||||
$this->form = [
|
||||
'name' => [
|
||||
'name' => '角色名称',
|
||||
'rule' => [
|
||||
'empty' => dr_lang('角色名称不能为空')
|
||||
],
|
||||
'filter' => [],
|
||||
'length' => '200'
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function index() {
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'data' => \Phpcmf\Service::M('auth')->get_role_all(),
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('role_index.html');
|
||||
}
|
||||
|
||||
public function add() {
|
||||
|
||||
if (IS_AJAX_POST) {
|
||||
$data = \Phpcmf\Service::L('input')->post('data');
|
||||
$this->_validation($data);
|
||||
\Phpcmf\Service::L('input')->system_log('添加角色组('.$data['name'].')');
|
||||
if (\Phpcmf\Service::M('auth')->add_role($data)) {
|
||||
\Phpcmf\Service::M('cache')->sync_cache('auth');
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
} else {
|
||||
$this->_json(0, dr_lang('操作失败'));
|
||||
}
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'form' => dr_form_hidden()
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('role_add.html');
|
||||
exit;
|
||||
}
|
||||
|
||||
public function edit() {
|
||||
|
||||
$id = intval(\Phpcmf\Service::L('input')->get('id'));
|
||||
$data = \Phpcmf\Service::M('auth')->get_role($id);
|
||||
if (!$data) {
|
||||
$this->_json(0, dr_lang('数据#%s不存在', $id));
|
||||
}
|
||||
|
||||
if (IS_AJAX_POST) {
|
||||
$temp = $post = \Phpcmf\Service::L('input')->post('data');
|
||||
$this->_validation($post);
|
||||
$post['application'] = $data['application'];
|
||||
$post['application']['tid'] = $temp['application']['tid'];
|
||||
$post['application']['mode'] = $temp['application']['mode'];
|
||||
$post['application']['verify'] = $temp['application']['verify'];
|
||||
\Phpcmf\Service::M('auth')->update_role($id, $post);
|
||||
\Phpcmf\Service::M('cache')->sync_cache('auth');
|
||||
\Phpcmf\Service::L('input')->system_log('修改角色组('.$post['name'].')');
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'id' => $id,
|
||||
'data' => $data,
|
||||
'form' => dr_form_hidden(),
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('role_add.html');
|
||||
exit;
|
||||
}
|
||||
|
||||
// 复制动作
|
||||
public function copy_edit() {
|
||||
|
||||
$id = intval(\Phpcmf\Service::L('input')->get('id'));
|
||||
$data = \Phpcmf\Service::M('auth')->get_role($id);
|
||||
if (!$data) {
|
||||
$this->_json(0, dr_lang('数据#%s不存在', $id));
|
||||
}
|
||||
|
||||
if (IS_AJAX_POST) {
|
||||
|
||||
$post = \Phpcmf\Service::L('input')->post('data');
|
||||
if (!$post['ids']) {
|
||||
$this->_json(0, dr_lang('没有选择目标角色组'));
|
||||
} elseif (!$post['option']) {
|
||||
$this->_json(0, dr_lang('没有选择复制项目'));
|
||||
}
|
||||
|
||||
$save = [];
|
||||
if (dr_in_array(1, $post['option'])) {
|
||||
$save['site'] = dr_array2string($data['site']);
|
||||
}
|
||||
|
||||
if (dr_in_array(2, $post['option'])) {
|
||||
$save['system'] = dr_array2string($data['system']);
|
||||
$save['module'] = dr_array2string($data['module']);
|
||||
}
|
||||
|
||||
if (!$save) {
|
||||
$this->_json(0, dr_lang('没有选择复制项目'));
|
||||
}
|
||||
|
||||
foreach ($post['ids'] as $rid) {
|
||||
\Phpcmf\Service::M('auth')->table('admin_role')->update($rid, $save);
|
||||
}
|
||||
|
||||
\Phpcmf\Service::M('cache')->sync_cache('auth');
|
||||
\Phpcmf\Service::L('input')->system_log('修改角色组('.$data['name'].')到'.implode('、', $post['ids']));
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'id' => $id,
|
||||
'role' => \Phpcmf\Service::M('auth')->get_role_all()
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('role_copy.html');
|
||||
exit;
|
||||
}
|
||||
|
||||
// 角色组权限,超级管理员有权限
|
||||
public function auth_edit() {
|
||||
|
||||
$id = intval(\Phpcmf\Service::L('input')->get('id'));
|
||||
$data = \Phpcmf\Service::M('auth')->get_role($id);
|
||||
if (!$data) {
|
||||
$this->_admin_msg(0, dr_lang('角色组(%s)不存在', $id));
|
||||
}
|
||||
|
||||
if (IS_AJAX_POST) {
|
||||
$post = \Phpcmf\Service::L('input')->post('data');
|
||||
$module = \Phpcmf\Service::L('input')->post('module');
|
||||
\Phpcmf\Service::M('auth')->table('admin_role')->update($id, [
|
||||
'system' => dr_array2string($post),
|
||||
'module' => dr_array2string($module),
|
||||
]);
|
||||
\Phpcmf\Service::M('cache')->sync_cache('auth');
|
||||
\Phpcmf\Service::L('input')->system_log('设置角色组('.$data['name'].')权限');
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
//print_r($data);
|
||||
#print_r($this->_M('Menu')->gets('admin'));
|
||||
|
||||
$page = intval(\Phpcmf\Service::L('input')->get('page'));
|
||||
$module_auth = IS_USE_MODULE ? \Phpcmf\Service::M('module', 'cms')->module_auth() : [];
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'data' => $data,
|
||||
'page' => $page,
|
||||
'form' => dr_form_hidden(['page' => $page]),
|
||||
'menu_data' => \Phpcmf\Service::M('Menu')->gets('admin', 'mark<>\'cloud\''),
|
||||
'module_auth' => $module_auth,
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('role_auth.html');
|
||||
}
|
||||
|
||||
public function site_edit() {
|
||||
|
||||
$id = intval(\Phpcmf\Service::L('input')->get('id'));
|
||||
$data = \Phpcmf\Service::M('auth')->get_role($id);
|
||||
if (!$data) {
|
||||
$this->_admin_msg(0, dr_lang('角色组(%s)不存在', $id));
|
||||
}
|
||||
|
||||
if (IS_AJAX_POST) {
|
||||
$post = \Phpcmf\Service::L('input')->post('data');
|
||||
\Phpcmf\Service::M('auth')->table('admin_role')->update($id, ['site' => dr_array2string($post)]);
|
||||
\Phpcmf\Service::M('cache')->sync_cache('auth');
|
||||
\Phpcmf\Service::L('input')->system_log('设置角色组('.$data['name'].')站点权限');
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'data' => $data,
|
||||
'form' => dr_form_hidden(),
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('role_site.html');exit;
|
||||
}
|
||||
|
||||
public function verify_edit() {
|
||||
|
||||
$id = intval(\Phpcmf\Service::L('input')->get('id'));
|
||||
$data = \Phpcmf\Service::M('auth')->get_role($id);
|
||||
if (!$data) {
|
||||
$this->_admin_msg(0, dr_lang('角色组(%s)不存在', $id));
|
||||
} elseif (!IS_USE_MEMBER) {
|
||||
$this->_admin_msg(0, dr_lang('需要安装用户系统插件,才能使用本功能'));
|
||||
}
|
||||
|
||||
$verify = \Phpcmf\Service::M()->table('admin_verify')->getAll(30);
|
||||
|
||||
if (IS_AJAX_POST) {
|
||||
$post = \Phpcmf\Service::L('input')->post('data');
|
||||
foreach ($verify as $v) {
|
||||
$rs = dr_string2array($v['verify']);
|
||||
if ($rs) {
|
||||
foreach ($rs['role'] as $i => $t) {
|
||||
if (isset($post[$v['id']]) && dr_in_array($i, $post[$v['id']])) {
|
||||
// 表示选择的
|
||||
if (!isset($rs['role'][$i])) {
|
||||
$rs['role'][$i] = []; // 不存在时重新定义
|
||||
} elseif (!is_array($rs['role'][$i]) && $rs['role'][$i]) {
|
||||
if ($id == $rs['role'][$i]) {
|
||||
$rs['role'][$i] = []; // 值相同时
|
||||
} else {
|
||||
$rs['role'][$i] = [
|
||||
(int)$rs['role'][$i]
|
||||
]; // 老版本的单值
|
||||
}
|
||||
}
|
||||
$rs['role'][$i][] = $id;
|
||||
} else {
|
||||
// 表示没选中
|
||||
foreach ($t as $k => $kt) {
|
||||
if ($id == $kt) {
|
||||
unset($rs['role'][$i][$k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
\Phpcmf\Service::M()->table('admin_verify')->update($v['id'], [
|
||||
'verify' => dr_array2string($rs)
|
||||
]);
|
||||
}
|
||||
|
||||
\Phpcmf\Service::M('cache')->sync_cache('');
|
||||
\Phpcmf\Service::L('input')->system_log('设置角色组('.$data['name'].')审核权限');
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'rid' => $id,
|
||||
'form' => dr_form_hidden(),
|
||||
'verify' => $verify,
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('role_verify.html');exit;
|
||||
}
|
||||
|
||||
public function del() {
|
||||
|
||||
$ids = \Phpcmf\Service::L('input')->get_post_ids();
|
||||
if (!$ids) {
|
||||
$this->_json(0, dr_lang('你还没有选择呢'));
|
||||
} elseif (dr_in_array(1, $ids)) {
|
||||
$this->_json(0, dr_lang('超级管理员角色组不能删除'));
|
||||
}
|
||||
|
||||
\Phpcmf\Service::M('auth')->delete_role($ids);
|
||||
\Phpcmf\Service::M('cache')->sync_cache('auth');
|
||||
\Phpcmf\Service::L('input')->system_log('批量删除角色组: '. @implode(',', $ids));
|
||||
|
||||
$this->_json(1, dr_lang('操作成功'), ['ids' => $ids]);
|
||||
}
|
||||
|
||||
// 验证数据
|
||||
private function _validation($data) {
|
||||
list($data, $return) = \Phpcmf\Service::L('Form')->validation($data, $this->form);
|
||||
if ($return) {
|
||||
$this->_json(0, $return['error'], ['field' => $return['name']]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,345 @@
|
||||
<?php namespace Phpcmf\Control\Admin;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
// 管理员
|
||||
class Root extends \Phpcmf\Table
|
||||
{
|
||||
public $role;
|
||||
private $myrole;
|
||||
private $mywhere;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
if (!dr_in_array(1, $this->admin['roleid'])) {
|
||||
// 不是超级管理员
|
||||
if (dr_is_app('cqx')) {
|
||||
$this->myrole = \Phpcmf\Service::M('content', 'cqx')->myrole();
|
||||
} else {
|
||||
$this->myrole = $this->admin['roleid'];
|
||||
}
|
||||
$this->role = \Phpcmf\Service::M('auth')->get_role_all($this->myrole);
|
||||
$this->mywhere = '`uid` IN (select uid from `'.\Phpcmf\Service::M()->dbprefix('admin_role_index').'` where roleid in ('.implode(',', $this->myrole).'))';
|
||||
} else {
|
||||
$this->role = \Phpcmf\Service::M('auth')->get_role_all();
|
||||
$this->myrole = [];
|
||||
}
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'menu' => \Phpcmf\Service::M('auth')->_admin_menu(
|
||||
[
|
||||
'管理员' => [\Phpcmf\Service::L('Router')->class.'/index', 'fa fa-user'],
|
||||
'添加' => [\Phpcmf\Service::L('Router')->class.'/add', 'fa fa-plus'],
|
||||
'修改' => ['hide:'.\Phpcmf\Service::L('Router')->class.'/edit', 'fa fa-edit'],
|
||||
'登录记录' => ['hide:root/login_index', 'fa fa-calendar'],
|
||||
'help' => [813],
|
||||
]
|
||||
),
|
||||
]);
|
||||
$this->name = dr_lang('管理员');
|
||||
}
|
||||
|
||||
public function index() {
|
||||
|
||||
$p = [
|
||||
'rid' => intval($_GET['rid']),
|
||||
'keyword' => dr_safe_replace($_GET['keyword']),
|
||||
];
|
||||
$where = [];
|
||||
if ($p['keyword']) {
|
||||
$where[] = '`username` LIKE "%'.$p['keyword'].'%"';
|
||||
}
|
||||
if ($this->myrole) {
|
||||
$where[] = $this->mywhere;
|
||||
}
|
||||
if ($p['rid']) {
|
||||
$where[] = '`uid` IN (select uid from `'.\Phpcmf\Service::M()->dbprefix('admin_role_index').'` where roleid='.$p['rid'].')';
|
||||
}
|
||||
|
||||
$this->_init([
|
||||
'table' => 'admin',
|
||||
'join_list' => ['member', 'member.id=admin.uid', 'left'],
|
||||
'order_by' => 'uid desc',
|
||||
'where_list' => implode(' AND ', $where),
|
||||
]);
|
||||
list($a, $data) = $this->_List($p);
|
||||
if ($data['list']) {
|
||||
foreach ($data['list'] as $i => $t) {
|
||||
$role = \Phpcmf\Service::M()->db->table('admin_role_index')->where('uid', $t['uid'])->get()->getResultArray();
|
||||
if ($role) {
|
||||
foreach ($role as $r) {
|
||||
$data['list'][$i]['role'][$r['roleid']] = $this->role[$r['roleid']]['name'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
\Phpcmf\Service::V()->assign('p', $p);
|
||||
\Phpcmf\Service::V()->assign('list', $data['list']);
|
||||
\Phpcmf\Service::V()->display('root_index.html');
|
||||
}
|
||||
|
||||
// 登录记录
|
||||
public function login_index() {
|
||||
|
||||
$uid = (int)\Phpcmf\Service::L('input')->get('id');
|
||||
$where = 'uid='.$uid;
|
||||
if ($this->myrole) {
|
||||
$where.= ' and '.$this->mywhere;
|
||||
}
|
||||
$this->_init([
|
||||
'table' => 'admin_login',
|
||||
'order_by' => 'logintime desc',
|
||||
'where_list' => $where,
|
||||
]);
|
||||
list($a, $data) = $this->_List(['uid' => $uid]);
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'list' => $data['list'],
|
||||
'user' => dr_member_info($uid),
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('root_login.html');
|
||||
|
||||
}
|
||||
|
||||
public function ck_index() {
|
||||
$name = dr_safe_replace($_GET['name']);
|
||||
$data = \Phpcmf\Service::M()->db->table('member')->where('username', $name)->get()->getRowArray();
|
||||
$this->_json($data ? 0 : 1, 'ok');
|
||||
}
|
||||
|
||||
public function status_edit() {
|
||||
$uid = intval($_GET['id']);
|
||||
$data = \Phpcmf\Service::M()->db->table('member_data')->where('id', $uid)->get()->getRowArray();
|
||||
if ($data['is_lock']) {
|
||||
\Phpcmf\Service::M()->db->table('member_data')->where('id', $uid)->update(['is_lock' => 0]);
|
||||
$this->_json(1, dr_lang('解除登录锁定'));
|
||||
} else {
|
||||
if ($this->uid == $uid) {
|
||||
$this->_json(0, dr_lang('无法对自己设置状态'));
|
||||
} elseif (1 == $uid) {
|
||||
$this->_json(0, dr_lang('不能设置超管账号'));
|
||||
}
|
||||
\Phpcmf\Service::M()->db->table('member_data')->where('id', $uid)->update(['is_lock' => 1]);
|
||||
$this->_json(1, dr_lang('登录已锁定,将无法登陆账号'));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function add() {
|
||||
|
||||
if (IS_AJAX_POST) {
|
||||
$post = \Phpcmf\Service::L('input')->post('data');
|
||||
$name = dr_safe_replace($post['username']);
|
||||
if (!$name) {
|
||||
$this->_json(0, dr_lang('账号不能为空'), ['field' => 'username']);
|
||||
} elseif (!$post['role']) {
|
||||
$this->_json(0, dr_lang('至少要选择一个角色组'), ['field' => 'role']);
|
||||
}
|
||||
if ($this->myrole) {
|
||||
foreach ($post['role'] as $t) {
|
||||
if (!in_array($t, $this->myrole)) {
|
||||
$this->_json(0, dr_lang('存在无权限操作的角色组'), ['field' => 'role']);
|
||||
}
|
||||
}
|
||||
}
|
||||
$data = \Phpcmf\Service::M()->db->table('member')->where('username', $name)->get()->getRowArray();
|
||||
if (!$data) {
|
||||
// 注册账号
|
||||
$rt = \Phpcmf\Service::L('form')->check_username($name);
|
||||
if (!$rt['code']) {
|
||||
$this->_json(0, $rt['msg'], ['field' => 'username']);
|
||||
}
|
||||
if (!\Phpcmf\Service::L('Form')->check_email($post['email'])) {
|
||||
$this->_json(0, dr_lang('邮箱格式不正确'), ['field' => 'email']);
|
||||
} elseif (!\Phpcmf\Service::L('Form')->check_phone($post['phone'])) {
|
||||
$this->_json(0, dr_lang('手机号码格式不正确'), ['field' => 'phone']);
|
||||
} elseif (empty($post['password'])) {
|
||||
$this->_json(0, dr_lang('密码必须填写'), ['field' => 'password']);
|
||||
} elseif ($post['name'] && $this->member_cache['config']['unique_name']
|
||||
&& \Phpcmf\Service::M()->db->table('member')->where('name', $post['name'])->countAllResults()) {
|
||||
$this->_json(0, dr_lang('%s已经注册', MEMBER_CNAME), ['field' => 'name']);
|
||||
}
|
||||
$rt = \Phpcmf\Service::L('Form')->check_password($post['password'], $name);
|
||||
if (!$rt['code']) {
|
||||
$this->_json(0, $rt['msg'], ['field' => 'password']);
|
||||
}
|
||||
$rt = \Phpcmf\Service::M('member')->register(0, [
|
||||
'username' => $post['username'],
|
||||
'phone' => $post['phone'],
|
||||
'email' => $post['email'],
|
||||
'name' => $post['name'],
|
||||
'password' => dr_safe_password($post['password']),
|
||||
]);
|
||||
if (!$rt['code']) {
|
||||
// 注册失败
|
||||
$this->_json(0, $rt['msg'], ['field' => $rt['data']['field']]);
|
||||
}
|
||||
$data = $rt['data'];
|
||||
}
|
||||
if (\Phpcmf\Service::M()->table('admin')->where('uid', $data['id'])->counts()) {
|
||||
$this->_json(0, dr_lang('此账号已经是管理员'));
|
||||
}
|
||||
$rt = \Phpcmf\Service::M()->table('admin')->insert([
|
||||
'uid' => $data['id'],
|
||||
'setting' => '',
|
||||
'usermenu' => '',
|
||||
]);
|
||||
if (!$rt['code']) {
|
||||
$this->_json(0, $rt['msg']);
|
||||
}
|
||||
if (dr_in_array(1, $post['role'])) {
|
||||
// 超管模式
|
||||
\Phpcmf\Service::M()->table('admin_role_index')->insert([
|
||||
'uid' => $data['id'],
|
||||
'roleid' => 1,
|
||||
]);
|
||||
} else {
|
||||
foreach ($post['role'] as $t) {
|
||||
\Phpcmf\Service::M()->table('admin_role_index')->insert([
|
||||
'uid' => $data['id'],
|
||||
'roleid' => $t,
|
||||
]);
|
||||
}
|
||||
}
|
||||
\Phpcmf\Service::M()->table('member_data')->update($data['id'], ['is_admin' => 1]);
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'post_url' =>\Phpcmf\Service::L('Router')->url('root/add'),
|
||||
'reply_url' =>\Phpcmf\Service::L('Router')->url('root/index'),
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('root_add.html');
|
||||
}
|
||||
|
||||
public function edit() {
|
||||
|
||||
$id = intval(\Phpcmf\Service::L('input')->get('id'));
|
||||
$data = \Phpcmf\Service::M()->db->table('admin')->where('uid', $id)->get()->getRowArray();
|
||||
if (!$data) {
|
||||
$this->_admin_msg(0, dr_lang('账号不存在'));
|
||||
}
|
||||
|
||||
$member = \Phpcmf\Service::M()->db->table('member')->where('id', $data['uid'])->get()->getRowArray();
|
||||
if (!$member) {
|
||||
$this->_admin_msg(0, dr_lang('账号不存在'));
|
||||
}
|
||||
|
||||
if (IS_AJAX_POST) {
|
||||
$post = \Phpcmf\Service::L('input')->post('data');
|
||||
if (!$post['role']) {
|
||||
$this->_json(0, dr_lang('至少要选择一个角色组'), ['field' => 'role']);
|
||||
} elseif (!\Phpcmf\Service::L('Form')->check_email($post['email'])) {
|
||||
$this->_json(0, dr_lang('邮箱格式不正确'), ['field' => 'email']);
|
||||
} elseif (!\Phpcmf\Service::L('Form')->check_phone($post['phone'])) {
|
||||
$this->_json(0, dr_lang('手机号码格式不正确'), ['field' => 'phone']);
|
||||
} elseif (\Phpcmf\Service::M()->db->table('member')->where('id<>'. $member['id'])->where('email', $post['email'])->countAllResults()) {
|
||||
$this->_json(0, dr_lang('邮箱%s已经注册', $post['email']), ['field' => 'email']);
|
||||
} elseif (\Phpcmf\Service::M()->db->table('member')->where('id<>'. $member['id'])->where('phone', $post['phone'])->countAllResults()) {
|
||||
$this->_json(0, dr_lang('手机号码%s已经注册', $post['phone']), ['field' => 'phone']);
|
||||
} elseif ($post['name'] && $this->member_cache['config']['unique_name']
|
||||
&& \Phpcmf\Service::M()->db->table('member')->where('id<>'. $member['id'])->where('name', $post['name'])->countAllResults()) {
|
||||
$this->_json(0, dr_lang('%s已经注册', MEMBER_CNAME), ['field' => 'name']);
|
||||
} elseif ($this->myrole) {
|
||||
foreach ($post['role'] as $t) {
|
||||
if (!in_array($t, $this->myrole)) {
|
||||
$this->_json(0, dr_lang('存在无权限操作的角色组'), ['field' => 'role']);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($post['username'] != $member['username']) {
|
||||
// 改账号时
|
||||
$rs = \Phpcmf\Service::L('Form')->check_username($post['username']);
|
||||
if (!$rs['code']) {
|
||||
$this->_json(0, $rs['msg'], ['field' => 'username']);
|
||||
} elseif (\Phpcmf\Service::M()->db->table('member')->where('username', $post['username'])->countAllResults()) {
|
||||
$this->_json(0, dr_lang('账号%s已经注册', $post['username']), ['field' => 'username']);
|
||||
}
|
||||
\Phpcmf\Service::M()->table('member')->update($member['id'], [
|
||||
'username' => $post['username'],
|
||||
'phone' => $post['phone'],
|
||||
'email' => $post['email'],
|
||||
'name' => $post['name'],
|
||||
]);
|
||||
\Phpcmf\Service::M('member')->clear_cache($member['id'], $member['username']);
|
||||
} else {
|
||||
\Phpcmf\Service::M()->table('member')->update($member['id'], [
|
||||
'phone' => $post['phone'],
|
||||
'email' => $post['email'],
|
||||
'name' => $post['name'],
|
||||
]);
|
||||
}
|
||||
|
||||
if ($post['password']) {
|
||||
$rt = \Phpcmf\Service::L('Form')->check_password($post['password'], $post['username']);
|
||||
if (!$rt['code']) {
|
||||
$this->_json(0, $rt['msg'], ['field' => 'password']);
|
||||
}
|
||||
\Phpcmf\Service::M('member')->edit_password($member, $post['password']);
|
||||
}
|
||||
if ($id > 1) {
|
||||
\Phpcmf\Service::M()->db->table('admin_role_index')->where('uid', $member['id'])->delete();
|
||||
foreach ($post['role'] as $t) {
|
||||
\Phpcmf\Service::M()->table('admin_role_index')->replace([
|
||||
'uid' => $member['id'],
|
||||
'roleid' => $t,
|
||||
]);
|
||||
}
|
||||
}
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
|
||||
$data = $data + $member;
|
||||
$role = \Phpcmf\Service::M()->db->table('admin_role_index')->where('uid', $data['uid'])->get()->getResultArray();
|
||||
if ($role) {
|
||||
foreach ($role as $r) {
|
||||
$data['role'][$r['roleid']] = $this->role[$r['roleid']]['name'];
|
||||
}
|
||||
}
|
||||
|
||||
// 不是超级管理员,排除超管账号
|
||||
if (!dr_in_array(1, $this->admin['roleid'])) {
|
||||
unset($this->role[1]);
|
||||
if (isset($data['role'][1])) {
|
||||
$this->_admin_msg(0, dr_lang('无权限编辑'));
|
||||
}
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'edit' => 1,
|
||||
'data' => $data,
|
||||
'post_url' =>\Phpcmf\Service::L('Router')->url('root/add'),
|
||||
'reply_url' =>\Phpcmf\Service::L('Router')->url('root/index'),
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('root_add.html');
|
||||
}
|
||||
|
||||
// 后台删除url内容
|
||||
public function del() {
|
||||
|
||||
$ids = \Phpcmf\Service::L('input')->get_post_ids();
|
||||
if (dr_in_array(1, $ids)) {
|
||||
$this->_json(0, dr_lang('创始人账号不能删除'));
|
||||
} elseif (dr_in_array($this->uid, $ids)) {
|
||||
$this->_json(0, dr_lang('不能删除自己'));
|
||||
}
|
||||
|
||||
// 批量操作
|
||||
foreach ($ids as $u) {
|
||||
// 不是超级管理员,排除超管账号
|
||||
if ($this->myrole && !\Phpcmf\Service::M()->table('admin_role_index')->where('uid', $u)->where($this->mywhere)->counts()) {
|
||||
$this->_json(0, dr_lang('存在无权限操作的角色组'), ['field' => 'role']);
|
||||
}
|
||||
\Phpcmf\Service::M()->db->table('admin')->where('uid', $u)->delete();
|
||||
\Phpcmf\Service::M()->db->table('admin_login')->where('uid', $u)->delete();
|
||||
\Phpcmf\Service::M()->db->table('admin_role_index')->where('uid', $u)->delete();
|
||||
\Phpcmf\Service::M()->table('member_data')->update($u, ['is_admin' => 0]);
|
||||
}
|
||||
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
<?php namespace Phpcmf\Control\Admin;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
class Sms extends \Phpcmf\Common
|
||||
{
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
\Phpcmf\Service::V()->assign('menu', \Phpcmf\Service::M('auth')->_admin_menu(
|
||||
[
|
||||
'短信设置' => [\Phpcmf\Service::L('Router')->class.'/index', 'fa fa-envelope'],
|
||||
'发送短信' => [\Phpcmf\Service::L('Router')->class.'/add', 'fa fa-send'],
|
||||
'help' => ['393'],
|
||||
]
|
||||
));
|
||||
}
|
||||
|
||||
public function index() {
|
||||
|
||||
$file = WRITEPATH.'config/sms.php';
|
||||
$cfile = WRITEPATH.'config/cache.php';
|
||||
$cache = is_file($cfile) ? require $cfile : [];
|
||||
|
||||
if (IS_AJAX_POST) {
|
||||
|
||||
$data = \Phpcmf\Service::L('input')->post('data');
|
||||
|
||||
$cache['SYS_CACHE_SMS'] = (int)\Phpcmf\Service::L('input')->post('SYS_CACHE_SMS');
|
||||
if (!\Phpcmf\Service::L('Config')->file($cfile, '缓存配置文件')->to_require_one($cache)) {
|
||||
$this->_json(0, dr_lang('配置文件写入失败'));
|
||||
}
|
||||
|
||||
if (!\Phpcmf\Service::L('Config')->file($file, '短信配置文件')->to_require_one($data)) {
|
||||
$this->_json(0, dr_lang('配置文件写入失败'));
|
||||
}
|
||||
|
||||
\Phpcmf\Service::L('input')->system_log('配置短信接口'); // 记录日志
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->assign(array(
|
||||
'data' => is_file($file) ? require $file : [],
|
||||
'cache' => $cache,
|
||||
));
|
||||
\Phpcmf\Service::V()->display('sms_index.html');
|
||||
}
|
||||
|
||||
public function add() {
|
||||
|
||||
$file = WRITEPATH.'config/sms.php';
|
||||
if (!is_file($file)) {
|
||||
$this->_admin_msg(0, dr_lang('没有配置短信参数,不能使用发送功能'));
|
||||
}
|
||||
|
||||
if (IS_AJAX_POST) {
|
||||
|
||||
$data = \Phpcmf\Service::L('input')->post('data');
|
||||
if ($data['content'] && strlen($data['content']) < 10) {
|
||||
$this->_json(0, dr_lang('短信内容太短了'));
|
||||
} elseif (!$data['mobiles']) {
|
||||
$this->_json(0, dr_lang('手机号码不能为空'));
|
||||
}
|
||||
|
||||
$ok = 0;
|
||||
$mobile = explode(',', trim(str_replace(',,', ',', str_replace(array(PHP_EOL, chr(13), chr(10)), ',', $data['mobiles'])), ','));
|
||||
foreach ($mobile as $m) {
|
||||
$rt = \Phpcmf\Service::M('member')->sendsms_text($m, $data['content']);
|
||||
if ($rt['code']) {
|
||||
$ok ++;
|
||||
}
|
||||
}
|
||||
|
||||
\Phpcmf\Service::L('input')->system_log('发送系统短信'); // 记录日志
|
||||
|
||||
$this->_json(1, dr_lang('发送成功%s个手机', $ok));
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->display('sms_add.html');
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php namespace Phpcmf\Control\Admin;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
class Sms_log extends \Phpcmf\Common
|
||||
{
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
\Phpcmf\Service::V()->assign('menu', \Phpcmf\Service::M('auth')->_admin_menu(
|
||||
[
|
||||
'短信记录' => [\Phpcmf\Service::L('Router')->class.'/index', 'fa fa-envelope'],
|
||||
]
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
public function index() {
|
||||
|
||||
$data = $list = [];
|
||||
$file = file_get_contents(WRITEPATH.'sms_log.txt');
|
||||
if ($file) {
|
||||
$data = explode(PHP_EOL, str_replace(array(chr(13), chr(10)), PHP_EOL, $file));
|
||||
$data = $data ? array_reverse($data) : [];
|
||||
$page = max(1, (int)\Phpcmf\Service::L('input')->get('page'));
|
||||
$limit = ($page - 1) * SYS_ADMIN_PAGESIZE;
|
||||
$i = $j = 0;
|
||||
foreach ($data as $v) {
|
||||
if ($i >= $limit && $j < SYS_ADMIN_PAGESIZE) {
|
||||
$list[] = $v;
|
||||
$j ++;
|
||||
}
|
||||
$i ++;
|
||||
}
|
||||
}
|
||||
|
||||
$total = max(0, dr_count($data) - 1);
|
||||
|
||||
\Phpcmf\Service::V()->assign(array(
|
||||
'list' => $list,
|
||||
'total' => $total,
|
||||
'mypages' => \Phpcmf\Service::L('input')->page(\Phpcmf\Service::L('Router')->url('sms_log/index'), $total, 'admin')
|
||||
));
|
||||
\Phpcmf\Service::V()->display('sms_log.html');
|
||||
}
|
||||
|
||||
public function del() {
|
||||
|
||||
unlink(WRITEPATH.'sms_log.txt');
|
||||
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
<?php namespace Phpcmf\Control\Admin;
|
||||
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
class Sql_log extends \Phpcmf\Common
|
||||
{
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
\Phpcmf\Service::V()->assign('menu', \Phpcmf\Service::M('auth')->_admin_menu(
|
||||
[
|
||||
'前端慢查询记录' => [\Phpcmf\Service::L('Router')->class.'/index', 'fa fa-database'],
|
||||
]
|
||||
));
|
||||
}
|
||||
|
||||
public function index() {
|
||||
|
||||
$dir = dr_file_map(WRITEPATH.'database/Sql/');
|
||||
$time = (int)\Phpcmf\Service::L('input')->get('time');
|
||||
if (!$time) {
|
||||
$time = 'sql';
|
||||
}
|
||||
|
||||
$data = $list = [];
|
||||
$file = WRITEPATH.'database/Sql/'.$time.'.txt';
|
||||
if (filesize($file) > 1024*1024*2) {
|
||||
$list[] = [
|
||||
$time,
|
||||
'',
|
||||
'10',
|
||||
'message' => '此日志文件大于2MB,请使用Ftp等工具查看此文件:'.$file,
|
||||
];
|
||||
} else {
|
||||
$code = file_get_contents($file);
|
||||
if ($code) {
|
||||
$data = explode(PHP_EOL, str_replace(array(chr(13), chr(10)), PHP_EOL, $code));
|
||||
$data = $data ? array_reverse($data) : [];
|
||||
$page = max(1, (int)\Phpcmf\Service::L('input')->get('page'));
|
||||
$limit = ($page - 1) * SYS_ADMIN_PAGESIZE;
|
||||
$i = $j = 0;
|
||||
foreach ($data as $v) {
|
||||
$val = dr_string2array($v);
|
||||
if ($val && $i >= $limit && $j < SYS_ADMIN_PAGESIZE) {
|
||||
$list[] = $val;
|
||||
$j ++;
|
||||
}
|
||||
$i ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$total = max(0, dr_count($data) - 1);
|
||||
|
||||
\Phpcmf\Service::V()->assign(array(
|
||||
'time' => $time,
|
||||
'mdir' => $dir,
|
||||
'list' => $list,
|
||||
'total' => $total,
|
||||
'used' => is_file(WRITEPATH.'database/sql.lock'),
|
||||
'mypages' => \Phpcmf\Service::L('input')->page(dr_url(\Phpcmf\Service::L('Router')->class.'/index', ['time' => $time]), $total, 'admin')
|
||||
));
|
||||
\Phpcmf\Service::V()->display('sql_log.html');
|
||||
}
|
||||
|
||||
public function add() {
|
||||
|
||||
$file = WRITEPATH.'database/sql.lock';
|
||||
if (is_file($file)) {
|
||||
unlink($file);
|
||||
} else {
|
||||
$size = file_put_contents($file, 'ok');
|
||||
if (!$size) {
|
||||
dr_mkdirs(dirname($file));
|
||||
$this->_json(0, dr_lang('Cache目录权限不可写入'));
|
||||
}
|
||||
}
|
||||
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
|
||||
public function del() {
|
||||
|
||||
dr_dir_delete(WRITEPATH.'database/Sql/');
|
||||
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
<?php namespace Phpcmf\Control\Admin;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
class System extends \Phpcmf\Common
|
||||
{
|
||||
public function index() {
|
||||
|
||||
if (is_file(WRITEPATH.'config/system.php')) {
|
||||
$data = require WRITEPATH.'config/system.php'; // 加载网站系统配置文件
|
||||
} else {
|
||||
$data = [];
|
||||
}
|
||||
|
||||
$logo = [
|
||||
'logo' => [
|
||||
'ismain' => 1,
|
||||
'fieldtype' => 'File',
|
||||
'fieldname' => 'logo',
|
||||
'setting' => ['option' => ['ext' => 'jpg,gif,png,jpeg,webp,svg', 'size' => 10, 'input' => 1]]
|
||||
]
|
||||
];
|
||||
|
||||
$site = \Phpcmf\Service::M('Site')->config(SITE_ID);
|
||||
|
||||
if (IS_AJAX_POST) {
|
||||
$post = \Phpcmf\Service::L('input')->post('data', true);
|
||||
$save = [
|
||||
'SYS_DEBUG' => (int)$post['SYS_DEBUG'],
|
||||
'SYS_AUTO_FORM' => (int)$post['SYS_AUTO_FORM'],
|
||||
'SYS_CRON_AUTH' => dr_safe_replace($post['SYS_CRON_AUTH']),
|
||||
'SYS_SMS_IMG_CODE' => intval($post['SYS_SMS_IMG_CODE']),
|
||||
'SYS_GO_404' => intval($post['SYS_GO_404']),
|
||||
'SYS_301' => intval($post['SYS_301']),
|
||||
'SYS_THEME_ROOT_PATH' => intval($post['SYS_THEME_ROOT_PATH']),
|
||||
'SYS_TABLE_ISFOOTER' => intval($post['SYS_TABLE_ISFOOTER']),
|
||||
|
||||
'SYS_URL_ONLY' => (int)$post['SYS_URL_ONLY'],
|
||||
'SYS_URL_REL' => (int)$post['SYS_URL_REL'],
|
||||
'SYS_NOT_UPDATE' => (int)$post['SYS_NOT_UPDATE'],
|
||||
'SYS_NOT_ADMIN_CACHE' => (int)$post['SYS_NOT_ADMIN_CACHE'],
|
||||
|
||||
'SYS_ADMIN_MODE' => intval($post['SYS_ADMIN_MODE']),
|
||||
'SYS_ADMIN_LOG' => intval($post['SYS_ADMIN_LOG']),
|
||||
'SYS_ADMIN_CODE' => intval($post['SYS_ADMIN_CODE']),
|
||||
'SYS_ADMIN_LOGINS' => intval($post['SYS_ADMIN_LOGINS']),
|
||||
'SYS_LOGIN_AES' => intval($post['SYS_LOGIN_AES']),
|
||||
'SYS_ADMIN_LOGIN_TIME' => intval($post['SYS_ADMIN_LOGIN_TIME']),
|
||||
'SYS_ADMIN_PAGESIZE' => intval($post['SYS_ADMIN_PAGESIZE']),
|
||||
'SYS_ADMIN_OAUTH' => intval($post['SYS_ADMIN_OAUTH']),
|
||||
'SYS_ADMIN_SMS_LOGIN' => intval($post['SYS_ADMIN_SMS_LOGIN']),
|
||||
'SYS_ADMIN_SMS_CHECK' => intval($post['SYS_ADMIN_SMS_CHECK']),
|
||||
|
||||
'SYS_KEY' => dr_safe_filename($post['SYS_KEY'] == '************' ? $data['SYS_KEY'] : $post['SYS_KEY']),
|
||||
'SYS_HTTPS' => (int)$post['SYS_HTTPS'],
|
||||
'SYS_CSRF' => (int)$post['SYS_CSRF'],
|
||||
'SYS_CSRF_TIME' => (int)$post['SYS_CSRF_TIME'],
|
||||
'SYS_API_CODE' => (int)$post['SYS_API_CODE'],
|
||||
'SYS_API_REL' => (int)$post['SYS_API_REL'],
|
||||
'SYS_API_TOKEN' => (string)$post['SYS_API_TOKEN'],
|
||||
];
|
||||
if ($save['SYS_HTTPS'] && $data['SYS_HTTPS'] != $save['SYS_HTTPS']
|
||||
&& !\Phpcmf\Service::L('input')->post('https_test')) {
|
||||
// 表示开启https时需要点击测试按钮
|
||||
$this->_json(0, dr_lang('开启HTTPS时需要点击旁边的测试按钮'), ['field' => 'https']);
|
||||
}
|
||||
foreach ($data as $name => $value) {
|
||||
strpos($name, 'SYS_CACHE') === 0 && $save[$name] = intval($post[$name]);
|
||||
}
|
||||
\Phpcmf\Service::M('System')->save_config($data, $save);
|
||||
|
||||
// 项目信息储存
|
||||
$site_post = \Phpcmf\Service::L('input')->post('site');
|
||||
foreach ([
|
||||
'SITE_NAME',
|
||||
'SITE_LANGUAGE',
|
||||
'SITE_TIMEZONE',
|
||||
'SITE_TIME_FORMAT',
|
||||
'logo'
|
||||
] as $name) {
|
||||
$site['config'][$name] = $site_post[$name];
|
||||
}
|
||||
|
||||
$rt = \Phpcmf\Service::M('Site')->config(SITE_ID, 'config', $site['config']);
|
||||
if (!is_array($rt)) {
|
||||
$this->_json(0, dr_lang('项目信息(#%s)不存在', SITE_ID));
|
||||
}
|
||||
|
||||
\Phpcmf\Service::L('input')->system_log('设置系统配置参数');
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
|
||||
$page = (int)\Phpcmf\Service::L('input')->get('page');
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'data' => $data,
|
||||
'site' => $site['config'],
|
||||
'page' => $page,
|
||||
'form' => dr_form_hidden(['page' => $page]),
|
||||
'lang' => dr_dir_map(ROOTPATH.'api/language/', 1),
|
||||
'menu' => \Phpcmf\Service::M('auth')->_admin_menu(
|
||||
[
|
||||
'系统参数' => ['system/index', 'fa fa-cog'],
|
||||
'help' => [503],
|
||||
]
|
||||
),
|
||||
'config' => \Phpcmf\Service::M('System')->config,
|
||||
'logofield' => dr_fieldform($logo['logo'], $site['config']['logo']),
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('system_index.html');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php namespace Phpcmf\Control\Admin;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
class System_cache extends \Phpcmf\Common
|
||||
{
|
||||
|
||||
public function index() {
|
||||
|
||||
$file = WRITEPATH.'config/cache.php';
|
||||
|
||||
if (IS_AJAX_POST) {
|
||||
|
||||
$config = \Phpcmf\Service::L('input')->post('data');
|
||||
$config['SYS_CACHE_LIST'] = $config['SYS_CACHE_SEARCH'] = $config['SYS_CACHE_SHOW']; // 统一视为缓存时间
|
||||
if (!\Phpcmf\Service::L('Config')->file($file, '缓存配置文件')->to_require_one($config)) {
|
||||
$this->_json(0, dr_lang('配置文件写入失败'));
|
||||
}
|
||||
|
||||
\Phpcmf\Service::L('input')->system_log('配置缓存参数'); // 记录日志
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
|
||||
$data = is_file($file) ? require $file : [];
|
||||
if (!isset($data['SYS_CACHE_CRON']) or empty($data['SYS_CACHE_CRON'])) {
|
||||
$data['SYS_CACHE_CRON'] = 3;
|
||||
}
|
||||
$page = intval(\Phpcmf\Service::L('input')->get('page'));
|
||||
|
||||
$run_time = '';
|
||||
if (is_file(WRITEPATH.'config/run_time.php')) {
|
||||
$run_time = file_get_contents(WRITEPATH.'config/run_time.php');
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'page' => $page,
|
||||
'form' => dr_form_hidden(['page' => $page]),
|
||||
'data' => $data,
|
||||
'menu' => \Phpcmf\Service::M('auth')->_admin_menu(
|
||||
[
|
||||
'缓存设置' => [\Phpcmf\Service::L('Router')->class.'/index', 'fa fa-clock-o'],
|
||||
'help' => [504],
|
||||
]
|
||||
),
|
||||
'cache_var' => [
|
||||
'SHOW' => '缓存时间',
|
||||
//'ATTACH' => '网站附件',
|
||||
//'LIST' => '查询缓存',
|
||||
//'SEARCH' => '搜索缓存',
|
||||
],
|
||||
'run_time' => $run_time,
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('system_cache.html');
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php namespace Phpcmf\Control\Admin;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
class System_log extends \Phpcmf\Common {
|
||||
|
||||
public function index() {
|
||||
|
||||
$time = (int)strtotime(\Phpcmf\Service::L('input')->get('time'));
|
||||
!$time && $time = SYS_TIME;
|
||||
|
||||
$file = WRITEPATH.'log/'.date('Ym', $time).'/'.date('d', $time).'.php';
|
||||
|
||||
$list = [];
|
||||
$data = explode(PHP_EOL, str_replace(array(chr(13), chr(10)), PHP_EOL, file_get_contents($file)));
|
||||
$data = array_reverse($data);
|
||||
|
||||
$page = max(1, (int)\Phpcmf\Service::L('input')->get('page'));
|
||||
$total = max(0, dr_count($data) - 1);
|
||||
$limit = ($page - 1) * SYS_ADMIN_PAGESIZE;
|
||||
|
||||
$i = $j = 0;
|
||||
$key = 1;
|
||||
$time = date('Y-m-d', $time);
|
||||
foreach ($data as $v) {
|
||||
if ($v && $i >= $limit && $j < SYS_ADMIN_PAGESIZE) {
|
||||
$v = dr_string2array($v);
|
||||
if ($v) {
|
||||
\Phpcmf\Service::L('cache')->set_data('system_log_'.USER_HTTP_CODE.$time.'_'.$key, $v, 3600);
|
||||
$list[$key] = $v;
|
||||
$j ++;
|
||||
$key ++;
|
||||
}
|
||||
}
|
||||
$i ++;
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->assign(array(
|
||||
'list' => $list,
|
||||
'time' => $time,
|
||||
'menu' => \Phpcmf\Service::M('auth')->_admin_menu(
|
||||
[
|
||||
'操作日志' => [\Phpcmf\Service::L('Router')->class.'/index', 'fa fa-calendar'],
|
||||
]
|
||||
),
|
||||
'total' => $total,
|
||||
'mypages' => \Phpcmf\Service::L('input')->page(\Phpcmf\Service::L('Router')->url('system_log/index', ['time' => $time]), $total, 'admin')
|
||||
));
|
||||
\Phpcmf\Service::V()->display('system_log.html');
|
||||
}
|
||||
|
||||
public function show_index() {
|
||||
|
||||
$key = intval($_GET['id']);
|
||||
$time = dr_safe_filename($_GET['time']);
|
||||
!$time && $time = date('Y-m-d');
|
||||
|
||||
$cache = \Phpcmf\Service::L('cache')->get_data('system_log_'.USER_HTTP_CODE.$time.'_'.$key);
|
||||
if (!$cache) {
|
||||
$this->_json(0, dr_lang('查看超时,请重新进入'));
|
||||
}
|
||||
|
||||
$cache['msg'] = $cache['action'];
|
||||
if ($cache['param']) {
|
||||
$cache['msg'].= '<br><hr><pre>'.(var_export($cache['param'], true)).'</pre>';
|
||||
}
|
||||
$cache['msg'].= '<br><hr>'.htmlspecialchars((string)$cache['url']);
|
||||
$cache['msg'] = str_replace([PHP_EOL, chr(13), chr(10)], '<br>', $cache['msg']);
|
||||
|
||||
echo '<link href="'.THEME_PATH.'assets/global/css/admin.min.css" rel="stylesheet" type="text/css" />
|
||||
<div style="padding: 20px">';
|
||||
echo $cache['msg'];
|
||||
exit('</div>');
|
||||
}
|
||||
|
||||
public function del() {
|
||||
|
||||
$time = dr_safe_filename($_GET['time']);
|
||||
!$time && $time = date('Y-m-d');
|
||||
|
||||
$time = strtotime($time);
|
||||
$file = WRITEPATH.'log/'.date('Ym', $time).'/'.date('d', $time).'.php';
|
||||
unlink($file);
|
||||
|
||||
$this->_json(1, dr_lang('操作成功'));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,527 @@
|
||||
<?php namespace Phpcmf\Control\Api;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
// 通用接口处理
|
||||
class Api extends \Phpcmf\Common {
|
||||
|
||||
/**
|
||||
* ip地址
|
||||
*/
|
||||
public function ip_address() {
|
||||
|
||||
$value = dr_safe_replace(\Phpcmf\Service::L('input')->get('value'));
|
||||
if (!$value) {
|
||||
exit(dr_lang('IP地址为空'));
|
||||
}
|
||||
|
||||
list($value, $port) = explode('-', $value);
|
||||
$address = \Phpcmf\Service::L('ip')->address($value);
|
||||
echo ('<a href="https://www.baidu.com/s?wd='.$value.'&action=xunruicms" target="_blank">'.dr_lang('IP归属地:%s', $address).'</a>');
|
||||
if ($port) {
|
||||
echo '
|
||||
<br>'.dr_lang('源端口号:%s', (int)$port);
|
||||
}
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存浏览器定位坐标
|
||||
*/
|
||||
public function map_position() {
|
||||
|
||||
$value = dr_safe_replace(\Phpcmf\Service::L('input')->get('value'));
|
||||
$cookie = \Phpcmf\Service::L('input')->get_cookie('map_position');
|
||||
if ($cookie != $value) {
|
||||
\Phpcmf\Service::L('input')->set_cookie('map_position', $value, 10000);
|
||||
exit('ok');
|
||||
}
|
||||
|
||||
exit('none');
|
||||
}
|
||||
|
||||
/**
|
||||
* 二维码显示
|
||||
*/
|
||||
public function qrcode() {
|
||||
|
||||
$value = urldecode(\Phpcmf\Service::L('input')->get('text'));
|
||||
$thumb = urldecode(\Phpcmf\Service::L('input')->get('thumb'));
|
||||
$matrixPointSize = (int)\Phpcmf\Service::L('input')->get('size');
|
||||
$errorCorrectionLevel = dr_safe_replace(\Phpcmf\Service::L('input')->get('level'));
|
||||
|
||||
//生成二维码图片
|
||||
require_once CMSPATH.'Library/Phpqrcode.php';
|
||||
$file = WRITEPATH.'file/qrcode-'.md5($value.$thumb.$matrixPointSize.$errorCorrectionLevel).'-qrcode.png';
|
||||
if (!IS_DEV && is_file($file)) {
|
||||
$QR = imagecreatefrompng($file);
|
||||
} else {
|
||||
\QRcode::png($value, $file, $errorCorrectionLevel, $matrixPointSize, 3);
|
||||
if (!is_file($file)) {
|
||||
exit('二维码生成失败');
|
||||
}
|
||||
$QR = imagecreatefromstring(file_get_contents($file));
|
||||
if ($thumb) {
|
||||
if (stripos($thumb, 'phar://') !== false) {
|
||||
exit('图片地址不规范');
|
||||
} elseif (filter_var($thumb, FILTER_VALIDATE_URL) !== false || file_exists($thumb)) {
|
||||
$img = getimagesize($thumb);
|
||||
if (!$img) {
|
||||
exit('此图片不是一张可用的图片');
|
||||
}
|
||||
$code = dr_catcher_data($thumb);
|
||||
if (!$code) {
|
||||
exit('图片参数不规范');
|
||||
}
|
||||
$logo = imagecreatefromstring($code);
|
||||
$QR_width = imagesx($QR);//二维码图片宽度
|
||||
$logo_width = imagesx($logo);//logo图片宽度
|
||||
$logo_height = imagesy($logo);//logo图片高度
|
||||
$logo_qr_width = $QR_width / 4;
|
||||
$scale = $logo_width/$logo_qr_width;
|
||||
$logo_qr_height = $logo_height/$scale;
|
||||
$from_width = ($QR_width - $logo_qr_width) / 2;
|
||||
//重新组合图片并调整大小
|
||||
imagecopyresampled($QR, $logo, (int)$from_width, (int)$from_width, 0, 0, (int)$logo_qr_width, (int)$logo_qr_height, (int)$logo_width, (int)$logo_height);
|
||||
imagepng($QR, $file);
|
||||
} else {
|
||||
exit('图片地址不规范');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 输出图片
|
||||
ob_start();
|
||||
ob_clean();
|
||||
header("Content-type: image/png");
|
||||
$QR && imagepng($QR);
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* 搜索
|
||||
*/
|
||||
public function search() {
|
||||
if (function_exists('dr_module_api_search')) {
|
||||
dr_module_api_search();
|
||||
} else {
|
||||
exit('需要升级最新版的【内容建站系统】插件');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查关键字
|
||||
*/
|
||||
public function checktitle() {
|
||||
if (function_exists('dr_module_checktitle')) {
|
||||
dr_module_checktitle();
|
||||
} else {
|
||||
exit('需要升级最新版的【内容建站系统】插件');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 提取关键字
|
||||
*/
|
||||
public function getkeywords() {
|
||||
exit(dr_get_keywords(dr_safe_replace(\Phpcmf\Service::L('input')->get('title'))));
|
||||
}
|
||||
|
||||
/**
|
||||
* 存储临时表单内容
|
||||
*/
|
||||
public function save_form_data() {
|
||||
|
||||
if (IS_POST && $this->member && $this->member['is_admin']) {
|
||||
$rt = \Phpcmf\Service::L('cache')->init('file')->save(
|
||||
md5(\Phpcmf\Service::L('input')->get('name')),
|
||||
\Phpcmf\Service::L('input')->post('data'),
|
||||
7200
|
||||
);
|
||||
var_dump($rt);
|
||||
}
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除临时表单内容
|
||||
*/
|
||||
public function delete_form_data() {
|
||||
\Phpcmf\Service::L('cache')->init('file')->delete(md5(\Phpcmf\Service::L('input')->get('name', true)));
|
||||
$this->_json(1, dr_lang('清除成功'));
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证码
|
||||
*/
|
||||
public function captcha() {
|
||||
|
||||
$code = \Phpcmf\Service::L('captcha')->create(
|
||||
max(0, intval($_GET['width'])), max(0, intval($_GET['height']))
|
||||
);
|
||||
|
||||
\Phpcmf\Service::L('cache')->set_auth_data('web-captcha-'.USER_HTTP_CODE, $code, SITE_ID);
|
||||
IS_DEV && log_message('debug', '图片验证码生成('.USER_HTTP_CODE.')验证码:'.$code);
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* 汉字转换拼音
|
||||
*/
|
||||
public function pinyin() {
|
||||
|
||||
$name = dr_safe_replace(\Phpcmf\Service::L('input')->get('name'));
|
||||
if (!$name) {
|
||||
exit('');
|
||||
}
|
||||
|
||||
$py = \Phpcmf\Service::L('pinyin')->result($name);
|
||||
if (strlen($py) > 12) {
|
||||
$sx = \Phpcmf\Service::L('pinyin')->result($name, 0);
|
||||
if ($sx) {
|
||||
exit($sx);
|
||||
}
|
||||
}
|
||||
|
||||
exit($py);
|
||||
}
|
||||
|
||||
/**
|
||||
* 联动菜单调用
|
||||
*/
|
||||
public function linkage() {
|
||||
|
||||
$code = dr_safe_replace(\Phpcmf\Service::L('input')->get('code'));
|
||||
$linkage = dr_linkage_json($code);
|
||||
if (!$linkage) {
|
||||
if (CI_DEBUG) {
|
||||
$linkage = [
|
||||
[
|
||||
'value' => 0,
|
||||
'label' => '请在联动菜单管理,找到【'.$code.'】,点击一键生成按钮',
|
||||
'children' => [],
|
||||
]
|
||||
];
|
||||
} else {
|
||||
$linkage = [];
|
||||
}
|
||||
}
|
||||
|
||||
echo 'var linkage_'.$code.' ='.json_encode($linkage, JSON_UNESCAPED_UNICODE).';';exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* 联动菜单Api
|
||||
*/
|
||||
public function linkage_json() {
|
||||
|
||||
$code = dr_safe_replace(\Phpcmf\Service::L('input')->get('code'));
|
||||
if (!$code) {
|
||||
$this->_json(0, dr_lang('联动菜单code参数没有值'));
|
||||
}
|
||||
|
||||
$linkage = dr_linkage_json($code);
|
||||
if (!$linkage) {
|
||||
$this->_json(0, dr_lang('没有联动菜单数据'));
|
||||
}
|
||||
|
||||
$this->_json(1, $code, $linkage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 经典样式的联动菜单调用
|
||||
*/
|
||||
public function linkage_data() {
|
||||
|
||||
$code = dr_safe_replace(\Phpcmf\Service::L('input')->get('code'));
|
||||
if (!$code) {
|
||||
$this->_json(0, dr_lang('联动菜单code参数没有值'));
|
||||
}
|
||||
|
||||
$pid = (int)\Phpcmf\Service::L('input')->get('pid');
|
||||
$linkage = dr_linkage_list($code, $pid);
|
||||
|
||||
$json = [];
|
||||
foreach ($linkage as $v) {
|
||||
if ($v['pid'] == $pid) {
|
||||
$json[] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$json) {
|
||||
$this->_json(0, dr_lang('没有联动菜单数据'));
|
||||
}
|
||||
|
||||
$this->_json(1, $code, $json);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 经典样式的联动菜单调用
|
||||
*/
|
||||
public function linkage_ld() {
|
||||
|
||||
$pid = (int)\Phpcmf\Service::L('input')->get('parent_id');
|
||||
$code = dr_safe_replace(\Phpcmf\Service::L('input')->get('code'));
|
||||
$linkage = dr_linkage_list($code, $pid);
|
||||
|
||||
$json = [];
|
||||
$html = '';
|
||||
foreach ($linkage as $v) {
|
||||
if ($v['pid'] == $pid) {
|
||||
$json[] = [
|
||||
'region_id' => $v['ii'],
|
||||
'region_code' => $v['id'],
|
||||
'region_name' => $v['name']
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
echo json_encode([
|
||||
'data' => $json,
|
||||
'html' => $html,
|
||||
], JSON_UNESCAPED_UNICODE);exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax调用字段属性表单
|
||||
*/
|
||||
public function field() {
|
||||
\Phpcmf\Service::L('api')->field();
|
||||
}
|
||||
|
||||
/**
|
||||
* 动态调用模板
|
||||
*/
|
||||
public function template() {
|
||||
|
||||
$app = dr_safe_filename(\Phpcmf\Service::L('input')->get('app'));
|
||||
$file = dr_safe_filename(\Phpcmf\Service::L('input')->get('name'));
|
||||
$module = dr_safe_filename(\Phpcmf\Service::L('input')->get('module'));
|
||||
|
||||
$data = [
|
||||
'app' => $app,
|
||||
'file' => $file,
|
||||
'module' => $module,
|
||||
];
|
||||
|
||||
if (!$file) {
|
||||
$html = 'name不能为空';
|
||||
} else {
|
||||
if ($module) {
|
||||
$this->_module_init($module);
|
||||
\Phpcmf\Service::V()->module($module);
|
||||
} elseif ($app) {
|
||||
\Phpcmf\Service::V()->module($app);
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->assign(\Phpcmf\Service::L('input')->get('', true));
|
||||
ob_start();
|
||||
\Phpcmf\Service::V()->display($file);
|
||||
$html = ob_get_contents();
|
||||
ob_clean();
|
||||
|
||||
$data['call_value'] = \Phpcmf\Service::V()->call_value;
|
||||
}
|
||||
|
||||
$this->_json(1, $html, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 内容关联字段数据读取
|
||||
*/
|
||||
public function related() {
|
||||
$this->_json(0, dr_lang('需要安装最新版的【建站系统】插件'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 会员关联字段数据读取
|
||||
*/
|
||||
public function members() {
|
||||
$this->_json(0, dr_lang('需要安装最新版的【用户系统】插件'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 退出前台账号
|
||||
*/
|
||||
public function loginout() {
|
||||
|
||||
// 注销授权登陆的会员
|
||||
if ($this->session()->get('member_auth_uid')) {
|
||||
\Phpcmf\Service::C()->session()->delete('member_auth_uid');
|
||||
$this->_json(0, dr_lang('当前状态无法退出账号'));
|
||||
}
|
||||
|
||||
$this->_json(1, dr_lang('您的账号已退出系统'), [
|
||||
'url' => isset($_SERVER['HTTP_REFERER']) ? dr_safe_url($_SERVER['HTTP_REFERER']) : SITE_URL,
|
||||
'sso' => \Phpcmf\Service::M('member')->logout(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 电脑和手机网站切换处理接口
|
||||
*/
|
||||
public function client() {
|
||||
$this->_json(0, dr_lang('此功能已废弃'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送验证码
|
||||
*/
|
||||
public function send_code() {
|
||||
|
||||
$phone = dr_safe_replace(\Phpcmf\Service::L('input')->get('id'));
|
||||
if (!$phone) {
|
||||
$this->_json(0, dr_lang('手机号码未填写'), ['field' => 'phone']);
|
||||
} elseif (!\Phpcmf\Service::L('Form')->check_phone($phone)) {
|
||||
$this->_json(0, dr_lang('手机号码格式不正确'), ['field' => 'phone']);
|
||||
}
|
||||
|
||||
// 挂钩点 短信验证之前
|
||||
\Phpcmf\Hooks::trigger('send_phone_before', $phone);
|
||||
|
||||
if (!defined('SYS_SMS_IMG_CODE') || SYS_SMS_IMG_CODE == 0) {
|
||||
$code = dr_safe_replace(\Phpcmf\Service::L('input')->get('code'));
|
||||
if (!$code) {
|
||||
$this->_json(0, dr_lang('图片验证码未填写'), ['field' => 'code']);
|
||||
} elseif (!\Phpcmf\Service::L('Form')->check_captcha_value($code)) {
|
||||
$this->_json(0, dr_lang('图片验证码不正确'), ['field' => 'code']);
|
||||
}
|
||||
}
|
||||
|
||||
// 验证操作间隔
|
||||
if (\Phpcmf\Service::L('Form')->get_mobile_code($phone)) {
|
||||
$this->_json(1, dr_lang('已经发送稍后再试'));
|
||||
}
|
||||
|
||||
$code = \Phpcmf\Service::L('Form')->get_rand_value();
|
||||
$rt = \Phpcmf\Service::M('member')->sendsms_code($phone, $code);
|
||||
if (!$rt['code']) {
|
||||
$this->_json(0, IS_DEV ? $rt['msg'] : dr_lang('发送失败'));
|
||||
}
|
||||
|
||||
\Phpcmf\Service::L('Form')->set_mobile_code($phone, $code);
|
||||
|
||||
$this->_json(1, dr_lang('验证码发送成功'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 关联字段数据读取
|
||||
*/
|
||||
public function join() {
|
||||
|
||||
$user = (string)$_SERVER['HTTP_USER_AGENT'];
|
||||
if (stripos($user, 'spider') !== false or strpos($user, 'bot') !== false) {
|
||||
$this->goto_404_page('蜘蛛禁止抓取');
|
||||
}
|
||||
|
||||
// 强制将模板设置为后台
|
||||
\Phpcmf\Service::V()->admin();
|
||||
|
||||
// 登陆判断
|
||||
//if (!$this->uid) {
|
||||
// $this->_json(0, dr_lang('会话超时,请重新登录'));
|
||||
//}
|
||||
|
||||
// 参数判断
|
||||
$fid = intval(\Phpcmf\Service::L('input')->get('fid'));
|
||||
if (!$fid) {
|
||||
$this->_json(0, dr_lang('fid参数不存在'));
|
||||
}
|
||||
|
||||
$field = \Phpcmf\Service::M()->table('field')->get($fid);
|
||||
if (!$field) {
|
||||
$this->_json(0, dr_lang('字段(%s)不存在', $fid));
|
||||
}
|
||||
$field['setting'] = dr_string2array($field['setting']);
|
||||
|
||||
$pagesize = $field['setting']['option']['pagesize'];
|
||||
if (!$pagesize) {
|
||||
$pagesize = 10;
|
||||
}
|
||||
|
||||
// 模块缓存判断
|
||||
$table = $field['setting']['option']['table'];
|
||||
if (!$table) {
|
||||
$this->_json(0, dr_lang('未设置关联表'));
|
||||
}
|
||||
|
||||
|
||||
|
||||
$param = $data = \Phpcmf\Service::L('input')->get('', true);
|
||||
|
||||
$name = $field['fieldname'];
|
||||
|
||||
|
||||
if (IS_POST) {
|
||||
$ids = \Phpcmf\Service::L('input')->get_post_ids();
|
||||
if (!$ids) {
|
||||
$this->_json(0, dr_lang('没有选择项'));
|
||||
}
|
||||
$id = [];
|
||||
foreach ($ids as $i) {
|
||||
$id[] = (int)$i;
|
||||
}
|
||||
$builder = \Phpcmf\Service::M()->db->table($table);
|
||||
$builder->whereIn('id', $id);
|
||||
$mylist = $builder->orderBy('id DESC')->get()->getResultArray();
|
||||
if (!$mylist) {
|
||||
$this->_json(0, dr_lang('没有相关数据'));
|
||||
}
|
||||
|
||||
$ids = [];
|
||||
foreach ($mylist as $t) {
|
||||
$ids[] = $t['id'];
|
||||
}
|
||||
|
||||
$file = \Phpcmf\Service::V()->code2php(
|
||||
file_get_contents(is_file(MYPATH.'View/api_join_field_'.$field['fieldname'].'.html') ? MYPATH.'View/api_join_field_'.$field['fieldname'].'.html' : COREPATH.'View/api_join_field.html')
|
||||
);
|
||||
ob_start();
|
||||
require $file;
|
||||
$code = ob_get_clean();
|
||||
$html = explode('<!--list-->', $code);
|
||||
|
||||
$this->_json(1, dr_lang('操作成功'), ['ids' => $ids, 'html' => $html[1]]);
|
||||
}
|
||||
|
||||
$where = [];
|
||||
if ($data['search']) {
|
||||
|
||||
$data['keyword'] = dr_safe_replace(urldecode($data['keyword']));
|
||||
if ($data['keyword']) {
|
||||
$where[] = 'id LIKE "%'.$data['keyword'].'%"';
|
||||
foreach ($field['setting']['option']['field'] as $t) {
|
||||
if ($t['field']) {
|
||||
$where[] = $t['field'].' LIKE "%'.$data['keyword'].'%"';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$rules = $data;
|
||||
$rules['page'] = '{page}';
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'table' => $table,
|
||||
'param' => $data,
|
||||
'field' => $field,
|
||||
'where' => $where ? urlencode('('.implode(' OR ', $where).')') : '',
|
||||
'search' => dr_form_search_hidden(['search' => 1, 'is_iframe' => 1, 'fid' => $fid]),
|
||||
'urlrule' => '/index.php?s=api&c=api&m=join&'.http_build_query($rules),
|
||||
'pagesize' => $pagesize,
|
||||
]);
|
||||
if (is_file(MYPATH.'View/api_join_'.$field['fieldname'].'.html')) {
|
||||
\Phpcmf\Service::V()->display('api_join_'.$field['fieldname'].'.html');
|
||||
} else {
|
||||
\Phpcmf\Service::V()->display('api_join.html');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php namespace Phpcmf\Control\Api;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
$file = dr_get_app_dir('pay').'Controllers/Buy.php';
|
||||
if (is_file($file)) {
|
||||
require_once $file;
|
||||
} else {
|
||||
\dr_exit_msg(0, '没有安装「支付系统」插件');
|
||||
}
|
||||
|
||||
// 交易下单
|
||||
class Buy extends \Phpcmf\Controllers\Buy {
|
||||
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,121 @@
|
||||
<?php namespace Phpcmf\Control\Api;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
// 文件操作
|
||||
class File extends \Phpcmf\Common
|
||||
{
|
||||
|
||||
// 验证权限脚本
|
||||
public function _check_upload_auth($editor = 0) {
|
||||
return \Phpcmf\Service::L('api')->check_upload_auth($editor);
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
*/
|
||||
public function upload() {
|
||||
\Phpcmf\Service::L('api')->upload();
|
||||
}
|
||||
|
||||
/**
|
||||
* 输入一个附件
|
||||
*/
|
||||
public function input_file_url() {
|
||||
\Phpcmf\Service::L('api')->input_file_url();
|
||||
}
|
||||
|
||||
/**
|
||||
* 浏览文件
|
||||
*/
|
||||
public function input_file_list() {
|
||||
\Phpcmf\Service::L('api')->input_file_list();
|
||||
}
|
||||
|
||||
/**
|
||||
* 浏览文件
|
||||
*/
|
||||
public function file_list() {
|
||||
\Phpcmf\Service::L('api')->file_list();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除文件
|
||||
*/
|
||||
public function file_delete() {
|
||||
|
||||
$rt = \Phpcmf\Service::M('Attachment')->file_delete(
|
||||
$this->member,
|
||||
(int)\Phpcmf\Service::L('input')->get('id')
|
||||
);
|
||||
|
||||
$this->_json($rt['code'], $rt['msg']);
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载文件
|
||||
*/
|
||||
public function down() {
|
||||
\Phpcmf\Service::L('api')->down();
|
||||
}
|
||||
|
||||
/**
|
||||
* 百度编辑器处理接口
|
||||
*/
|
||||
public function ueditor() {
|
||||
require ROOTPATH.'api/ueditor/php/controller.php';exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* base64图片上传
|
||||
*/
|
||||
public function upload_base64_image() {
|
||||
\Phpcmf\Service::L('api')->upload_base64_image();
|
||||
}
|
||||
|
||||
/**
|
||||
* 图片编辑
|
||||
*/
|
||||
public function image_edit() {
|
||||
\Phpcmf\Service::L('api')->image_edit();
|
||||
}
|
||||
|
||||
/**
|
||||
* 附件改名
|
||||
*/
|
||||
public function name_edit() {
|
||||
\Phpcmf\Service::L('api')->name_edit();
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载远程图片
|
||||
*/
|
||||
public function down_img_list() {
|
||||
\Phpcmf\Service::L('api')->down_img_list();
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载远程图片
|
||||
*/
|
||||
public function down_img_url() {
|
||||
\Phpcmf\Service::L('api')->down_img_url();
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载远程图片
|
||||
*/
|
||||
public function down_img() {
|
||||
\Phpcmf\Service::L('api')->down_img();
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑器视频外链解析
|
||||
*/
|
||||
public function video() {
|
||||
\Phpcmf\Service::L('api')->video_link();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php namespace Phpcmf\Control\Api;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
// 接口处理
|
||||
class Home extends \Phpcmf\Common
|
||||
{
|
||||
|
||||
public function index() {
|
||||
|
||||
if (IS_API === 'pay') {
|
||||
// 支付接口部分
|
||||
$info = pathinfo($_SERVER['PHP_SELF']);
|
||||
$name = basename($info['dirname']);
|
||||
$path = trim($info['dirname'], '/');
|
||||
$file = str_replace('_url.php', '_api.php', $info['basename']);
|
||||
$apifile = WEBPATH . $path . '/' . $file;
|
||||
if (!is_file($apifile)) {
|
||||
if (IS_DEV) {
|
||||
exit('支付接口文件('.$apifile.')不存在');
|
||||
}
|
||||
exit('支付接口文件不存在');
|
||||
}
|
||||
// 接口配置参数
|
||||
$config = $this->member_cache['payapi'][$name];
|
||||
require $apifile;
|
||||
} elseif (IS_API === 'cron') {
|
||||
// 任务脚本
|
||||
$cron = new \Phpcmf\Control\Api\Run($this);
|
||||
$cron->index();
|
||||
} elseif (is_file(IS_API)) {
|
||||
// 自定义任意目录的api
|
||||
require IS_API;
|
||||
} else {
|
||||
$myfile = MYPATH.'Api/'.ucfirst(IS_API).'.php';
|
||||
if (!is_file($myfile)) {
|
||||
if (IS_DEV) {
|
||||
exit('Api接口文件('.$myfile.')不存在');
|
||||
}
|
||||
exit('api file is error');
|
||||
}
|
||||
require $myfile;
|
||||
exit;
|
||||
}
|
||||
exit;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
<?php namespace Phpcmf\Control\Api;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本代码基于MIT开源协议,协议规定此处版权信息不可去除
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
// 模块ajax操作接口
|
||||
class Module extends \Phpcmf\Common {
|
||||
|
||||
private $siteid;
|
||||
private $dirname;
|
||||
private $tablename;
|
||||
public $content_model;
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
// 初始化模块
|
||||
$this->siteid = (int)\Phpcmf\Service::L('input')->get('siteid');
|
||||
!$this->siteid && $this->siteid = SITE_ID;
|
||||
$this->dirname = dr_safe_filename(\Phpcmf\Service::L('input')->get('app'));
|
||||
if ($this->dirname == 'MOD_DIR') {
|
||||
$this->_msg(0, dr_lang('app参数存在问题'));
|
||||
} elseif (!$this->dirname || !dr_is_app_dir(($this->dirname))) {
|
||||
$this->_msg(0, dr_lang('模块目录[%s]不存在', $this->dirname));
|
||||
exit;
|
||||
}
|
||||
$this->tablename = $this->siteid.'_'.$this->dirname;
|
||||
$this->content_model = \Phpcmf\Service::M('Content', $this->dirname);
|
||||
$this->_module_init($this->dirname, $this->siteid);
|
||||
$user = (string)$_SERVER['HTTP_USER_AGENT'];
|
||||
if (strpos($user, 'spider') !== false or strpos($user, 'bot') !== false) {
|
||||
$this->goto_404_page('蜘蛛禁止抓取');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function index() {
|
||||
exit('module api');
|
||||
}
|
||||
|
||||
/**
|
||||
* 阅读数统计
|
||||
*/
|
||||
public function hits() {
|
||||
|
||||
$id = (int)\Phpcmf\Service::L('input')->get('id');
|
||||
if (!$id) {
|
||||
$this->_jsonp(0, dr_lang('阅读统计: id参数不完整'));
|
||||
}
|
||||
|
||||
$rt = $this->content_model->update_hits($id, (int)\Phpcmf\Service::L('input')->get('qx'));
|
||||
|
||||
if (isset($_GET['format']) && $_GET['format'] == 'json') {
|
||||
$this->_json($rt['code'], $rt['msg'], $rt['data']);
|
||||
} else {
|
||||
$this->_jsonp($rt['code'], $rt['msg'], $rt['data']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 收藏模块内容
|
||||
*/
|
||||
public function favorite() {
|
||||
|
||||
if (!dr_is_app('favorite')) {
|
||||
$this->_json(0, dr_lang('应用[模块内容收藏]未安装'));
|
||||
}
|
||||
|
||||
$rt = \Phpcmf\Service::M('op', 'favorite')->run($this->tablename, $this->dirname);
|
||||
|
||||
$this->_json($rt['code'], $rt['msg'], $rt['data']);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否收藏模块内容
|
||||
*/
|
||||
public function is_favorite() {
|
||||
|
||||
if (!dr_is_app('favorite')) {
|
||||
$this->_json(0, dr_lang('应用[模块内容收藏]未安装'));
|
||||
}
|
||||
|
||||
$rt = \Phpcmf\Service::M('op', 'favorite')->is_favorite($this->tablename, $this->dirname);
|
||||
|
||||
$this->_json($rt['code'], $rt['msg'], $rt['data']);
|
||||
}
|
||||
|
||||
/**
|
||||
* 模块内容支持与反对
|
||||
*/
|
||||
public function digg() {
|
||||
|
||||
if (!dr_is_app('zan')) {
|
||||
$this->_json(0, dr_lang('应用[模块内容点赞]未安装'));
|
||||
}
|
||||
|
||||
$rt = \Phpcmf\Service::M('op', 'zan')->run($this->tablename, $this->dirname);
|
||||
|
||||
$this->_json($rt['code'], $rt['msg'], $rt['data']);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php namespace Phpcmf\Control\Api;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
// 快捷登录接口
|
||||
class Oauth extends \Phpcmf\Common
|
||||
{
|
||||
|
||||
/**
|
||||
* 快捷登录
|
||||
*/
|
||||
public function index() {
|
||||
|
||||
$name = dr_safe_filename(\Phpcmf\Service::L('input')->get('name'));
|
||||
$type = dr_safe_replace(\Phpcmf\Service::L('input')->get('type'));
|
||||
$back = dr_safe_replace(\Phpcmf\Service::L('input')->get('back'));
|
||||
$action = dr_safe_replace(\Phpcmf\Service::L('input')->get('action'));
|
||||
|
||||
// 非授权登录时必须验证登录状态
|
||||
if ($type != 'login' && !$this->uid) {
|
||||
$this->_msg(0, dr_lang('你还没有登录'));
|
||||
} elseif (!$name) {
|
||||
$this->_msg(0, dr_lang('未知接入商'));
|
||||
}
|
||||
|
||||
// 请求参数
|
||||
$appid = $this->member_cache['oauth'][$name]['id'];
|
||||
$appkey = $this->member_cache['oauth'][$name]['value'];
|
||||
$callback_url = OAUTH_URL.'index.php?s=api&c=oauth&m=index&action=callback&name='.$name.'&type='.$type;
|
||||
if ($back) {
|
||||
$callback_url.= '&back='.urlencode(dr_redirect_safe_check($back));
|
||||
}
|
||||
|
||||
$file = FCPATH.'ThirdParty/OAuth/'.ucfirst($name).'/Run.php';
|
||||
if (is_file($file)) {
|
||||
require $file;
|
||||
} else {
|
||||
$this->_msg(0, IS_DEV ? dr_lang('没有找到接入商(%s)执行程序', $file) : dr_lang('没有找到接入商的执行程序'));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php namespace Phpcmf\Control\Api;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
$file = dr_get_app_dir('pay').'Controllers/Home.php';
|
||||
if (is_file($file)) {
|
||||
require_once $file;
|
||||
} else {
|
||||
\dr_exit_msg(0, '没有安装「支付系统」插件');
|
||||
}
|
||||
|
||||
// 付款
|
||||
class Pay extends \Phpcmf\Controllers\Home
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php namespace Phpcmf\Control\Api;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
// 系统默认伪静态处理
|
||||
class Rewrite extends \Phpcmf\Common
|
||||
{
|
||||
|
||||
// test
|
||||
public function test() {
|
||||
$this->_jsonp(1, '服务器支持伪静态功能,可以自定义URL规则和解析规则了');
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转地址
|
||||
*/
|
||||
public function url() {
|
||||
|
||||
$url = urldecode(\Phpcmf\Service::L('input')->get('url'));
|
||||
$arr = [ 0 => [], 1 => []];
|
||||
for ($i = 1 ; $i < 10; $i ++) {
|
||||
$arr[0][] = urldecode(\Phpcmf\Service::L('input')->get('p'.$i));
|
||||
$arr[1][] = '$'.$i;
|
||||
}
|
||||
dr_redirect(dr_url_prefix(str_replace($arr[1], $arr[0], $url)), 'location', '301');
|
||||
}
|
||||
|
||||
public function license() {
|
||||
|
||||
$license = \Phpcmf\Service::R(MYPATH.'Config/License.php');
|
||||
if (isset($license['oem']) && $license['oem']) {
|
||||
echo $license['name'].' '.$license['cms'].'('.$license['type'].') V'.$this->cmf_version['version'] . ' <span style="display: none">'.$license['license'].'</span>';exit;
|
||||
}
|
||||
|
||||
echo 'XunRuiCMS V'.$this->cmf_version['version'].'<hr>';
|
||||
|
||||
if (is_file(WEBPATH.'LICENSE')) {
|
||||
$file = WEBPATH.'LICENSE';
|
||||
} elseif (is_file(ROOTPATH.'LICENSE')) {
|
||||
$file = ROOTPATH.'LICENSE';
|
||||
} elseif (is_file(dirname(WEBPATH).'/LICENSE')) {
|
||||
$file = dirname(WEBPATH).'/LICENSE';
|
||||
} else {
|
||||
exit('<font color="red">LICENSE许可证文件不存在,请遵守迅睿MIT开源协议</font>');
|
||||
}
|
||||
|
||||
echo nl2br((string)file_get_contents($file));
|
||||
exit;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,243 @@
|
||||
<?php namespace Phpcmf\Control\Api;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
/**
|
||||
* 运行任务接口
|
||||
*/
|
||||
|
||||
class Run extends \Phpcmf\Common
|
||||
{
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
*/
|
||||
public function __construct($object = NULL)
|
||||
{
|
||||
parent::__construct();
|
||||
if ($object) {
|
||||
foreach ($object as $var => $value) {
|
||||
$this->$var = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function index() {
|
||||
|
||||
// 验证运行权限
|
||||
if (!IS_DEV) {
|
||||
if (defined('SYS_CRON_AUTH') && SYS_CRON_AUTH) {
|
||||
if (is_cli()) {
|
||||
// cli模式
|
||||
} else {
|
||||
// url模式
|
||||
if (SYS_CRON_AUTH == 'cli') {
|
||||
exit('限制CLI模式执行任务');
|
||||
}
|
||||
$ip = \Phpcmf\Service::L('input')->ip_address();
|
||||
if (!$ip) {
|
||||
if (CI_DEBUG) {
|
||||
log_message('error', '任务执行失败:无法获取执行客户端的IP地址');
|
||||
}
|
||||
exit('无权限执行任务');
|
||||
return;
|
||||
}
|
||||
if (SYS_CRON_AUTH != $ip) {
|
||||
if (CI_DEBUG) {
|
||||
log_message('error', '任务执行失败:后台设置的服务端ip('.SYS_CRON_AUTH.')与客户端ip('.$ip.')不一致');
|
||||
}
|
||||
exit('限制固定IP执行任务');
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
$run_time = 0;// 上次执行的时间
|
||||
if (is_file(WRITEPATH.'config/cron_run_time.php')) {
|
||||
$run_time = file_get_contents(WRITEPATH.'config/cron_run_time.php');
|
||||
if ($run_time && SYS_TIME - $run_time < 100) {
|
||||
exit('未到任务执行时间');
|
||||
}
|
||||
} else {
|
||||
file_put_contents(WRITEPATH.'config/cron_run_time.php', SYS_TIME);
|
||||
}
|
||||
$fp = fopen ( WRITEPATH.'config/cron_run_time.php' , "r" );
|
||||
//加锁
|
||||
if ( flock ( $fp ,LOCK_EX | LOCK_NB)) {
|
||||
// 写入新的时间
|
||||
file_put_contents(WRITEPATH.'config/cron_run_time.php', SYS_TIME);
|
||||
} else {
|
||||
fclose( $fp );
|
||||
exit('任务正在执行中');
|
||||
}
|
||||
|
||||
if (isset($_GET['is_ajax'])) {
|
||||
// 后台脚本自动任务时
|
||||
|
||||
} else {
|
||||
// 服务器自动任务时
|
||||
// 自动任务锁定
|
||||
if (!is_file(WRITEPATH.'config/run_lock.php')) {
|
||||
file_put_contents(WRITEPATH.'config/run_lock.php', 'true');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$fp = false;
|
||||
}
|
||||
|
||||
// 批量执行站点动作
|
||||
foreach ($this->site_info as $siteid => $site) {
|
||||
// 删除网站首页
|
||||
if ($site['SITE_INDEX_HTML']) {
|
||||
$time = (isset($site['SITE_INDEX_TIME']) && $site['SITE_INDEX_TIME'] ? $site['SITE_INDEX_TIME'] : 10) * 3600;
|
||||
foreach ([
|
||||
\Phpcmf\Service::L('html')->get_webpath($siteid,'site', 'index.html'),
|
||||
\Phpcmf\Service::L('html')->get_webpath($siteid,'site', 'mobile/index.html'),
|
||||
] as $file) {
|
||||
$ft = filemtime($file);
|
||||
if ($ft && SYS_TIME - $ft > $time) {
|
||||
unlink($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 执行队列
|
||||
$i = \Phpcmf\Service::M('cron')->run_cron(intval($_GET['num']));
|
||||
|
||||
// 最少100秒调用本程序
|
||||
//\Phpcmf\Service::L('input')->set_cookie('cron', 1, 100);
|
||||
|
||||
// 定义后台执行任务的时效
|
||||
//\Phpcmf\Service::L('input')->set_cookie('admin_cron', 1, 600);
|
||||
|
||||
// 任务计划
|
||||
\Phpcmf\Hooks::trigger('cron');
|
||||
|
||||
// 清理缓存数据
|
||||
if (!is_file(WRITEPATH.'config/run_auto_cache_time.php')) {
|
||||
$time = SYS_TIME;
|
||||
file_put_contents(WRITEPATH.'config/run_auto_cache_time.php', $time);
|
||||
} else {
|
||||
$time = file_get_contents(WRITEPATH.'config/run_auto_cache_time.php');
|
||||
}
|
||||
|
||||
// 多少天清理一次系统缓存
|
||||
$day = max(3, SYS_CACHE_CRON);
|
||||
if (SYS_TIME - $time > 3600 * 24 * $day) {
|
||||
// 缓存清理
|
||||
\Phpcmf\Service::M('cache')->update_data_cache(true);
|
||||
file_put_contents(WRITEPATH.'config/run_auto_cache_time.php', SYS_TIME);
|
||||
// 清理日志
|
||||
$map = dr_file_map(WRITEPATH.'error/');
|
||||
if ($map) {
|
||||
foreach ($map as $file) {
|
||||
if (strpos($file, 'log-') !== false) {
|
||||
$file = WRITEPATH.'error/'.$file;
|
||||
$time = filectime($file);
|
||||
if ($time && SYS_TIME - $time > 3600 * 24 * 30) {
|
||||
@unlink($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 项目计划
|
||||
if (is_file(MYPATH.'Config/Cron.php')) {
|
||||
require MYPATH.'Config/Cron.php';
|
||||
}
|
||||
|
||||
// 为插件单独执行计划
|
||||
$local = \Phpcmf\Service::Apps();
|
||||
if ($local) {
|
||||
foreach ($local as $dir => $path) {
|
||||
if (is_file($path.'Config/Cron.php')
|
||||
&& is_file($path.'Config/App.php')
|
||||
&& is_file($path.'install.lock')) {
|
||||
require $path.'Config/Cron.php';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 自动任务执行时间
|
||||
file_put_contents(WRITEPATH.'config/run_time.php', dr_date(SYS_TIME));
|
||||
|
||||
if ($fp) {
|
||||
flock ( $fp ,LOCK_UN);
|
||||
fclose( $fp );
|
||||
}
|
||||
|
||||
exit('任务执行成功:Run '.($i ? $i : 'Ok'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 线程任务接口
|
||||
*/
|
||||
public function cron() {
|
||||
|
||||
$file = WRITEPATH.'thread/'.dr_safe_filename(\Phpcmf\Service::L('input')->get('auth')).'.auth';
|
||||
if (!is_file($file)) {
|
||||
//log_message('error', '线程任务auth文件不存在:'.dr_now_url());
|
||||
exit('线程任务auth文件不存在'.$file);
|
||||
}
|
||||
|
||||
$time = (int)file_get_contents($file);
|
||||
unlink($file);
|
||||
if (SYS_TIME - $time > 500) {
|
||||
// 500秒外无效
|
||||
log_message('error', '线程任务auth过期:'.dr_now_url());
|
||||
exit('线程任务auth过期');
|
||||
}
|
||||
|
||||
switch (\Phpcmf\Service::L('input')->get('action')) {
|
||||
|
||||
case 'oauth_down_avatar': // 快捷登录下载头像
|
||||
|
||||
$id = intval(\Phpcmf\Service::L('input')->get('id'));
|
||||
$oauth = \Phpcmf\Service::M()->table('member_oauth')->get($id);
|
||||
if (!$oauth) {
|
||||
exit('oauth不存在');
|
||||
} elseif (!$oauth['uid']) {
|
||||
exit('oauth没有绑定账号');
|
||||
}
|
||||
|
||||
list($cache_path) = dr_avatar_path();
|
||||
$path = $cache_path.dr_avatar_dir($oauth['uid']);
|
||||
$file = $path.$oauth['uid'].'.jpg';
|
||||
if (is_file($file)) {
|
||||
\Phpcmf\Service::M()->db->table('member_data')->where('id', $oauth['uid'])->update(['is_avatar' => 1]);
|
||||
exit('头像已经存在');
|
||||
}
|
||||
|
||||
$avatar = dr_catcher_data($oauth['avatar']);
|
||||
if ($avatar) {
|
||||
if (!is_dir($path)) {
|
||||
dr_mkdirs($path);
|
||||
}
|
||||
if (file_put_contents($file, $avatar)) {
|
||||
\Phpcmf\Service::M()->db->table('member_data')->where('id', $oauth['uid'])->update(['is_avatar' => 1]);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'cron': // 队列任务
|
||||
|
||||
$id = intval(\Phpcmf\Service::L('input')->get('id'));
|
||||
$rt = \Phpcmf\Service::M('cron')->do_cron_id($id);
|
||||
if (!$rt['code']) {
|
||||
log_message('debug', '任务执行失败('.$rt['msg'].'):'.$rt['data']['value']);
|
||||
exit('任务执行失败('.$rt['msg'].')');
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
exit('ok');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
<?php namespace Phpcmf\Control\Api;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
// 同步登陆接口
|
||||
class Sso extends \Phpcmf\Common {
|
||||
|
||||
public function index() {
|
||||
|
||||
switch (\Phpcmf\Service::L('input')->get('action')) {
|
||||
|
||||
case 'logout': // 前台退出登录
|
||||
|
||||
header('P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"');
|
||||
\Phpcmf\Service::L('input')->set_cookie('member_uid', 0, -30000);
|
||||
\Phpcmf\Service::L('input')->set_cookie('admin_login_member', 0, -30000);
|
||||
\Phpcmf\Service::L('input')->set_cookie('member_cookie', 0, -30000);
|
||||
break;
|
||||
|
||||
case 'login': // 前台同步登录
|
||||
|
||||
$code = dr_authcode(\Phpcmf\Service::L('input')->get('code'), 'DECODE');
|
||||
if (!$code) {
|
||||
$this->_jsonp(0, '解密失败');
|
||||
}
|
||||
|
||||
list($uid, $salt) = explode('-', $code);
|
||||
if (!$uid || !$salt) {
|
||||
$this->_jsonp(0, '格式错误');
|
||||
}
|
||||
|
||||
$member = \Phpcmf\Service::M()->db->table('member')->where('id', $uid)->get()->getRowArray();
|
||||
if (!$member) {
|
||||
$this->_jsonp(0, '账号不存在');
|
||||
} elseif ($salt != $member['salt']) {
|
||||
$this->_jsonp(0, '账号验证失败');
|
||||
}
|
||||
|
||||
header('P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"');
|
||||
\Phpcmf\Service::M('member')->save_cookie($member, \Phpcmf\Service::L('input')->get('remember'));
|
||||
|
||||
break;
|
||||
|
||||
case 'alogin': // 后台登录授权
|
||||
|
||||
$code = dr_authcode(\Phpcmf\Service::L('input')->get('code'), 'DECODE');
|
||||
if (!$code) {
|
||||
$this->_jsonp(0, '解密失败');
|
||||
}
|
||||
|
||||
list($uid, $password) = explode('-', $code);
|
||||
|
||||
$admin = \Phpcmf\Service::L('cache')->get_data('admin_login_member');
|
||||
if (!$admin) {
|
||||
$this->_jsonp(0, '缓存失败');
|
||||
} elseif ($password != md5($admin['id'].$admin['password'])) {
|
||||
$this->_jsonp(0, '验证失败');
|
||||
}
|
||||
|
||||
// 存储状态
|
||||
header('P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"');
|
||||
\Phpcmf\Service::L('input')->set_cookie('admin_login_member', $uid.'-'.$admin['id'], 3600);
|
||||
$this->session()->set('admin_login_member_code', md5($uid.$admin['id'].$admin['password']));
|
||||
break;
|
||||
|
||||
case 'slogin': // 后台登录其他站点
|
||||
|
||||
exit('功能废弃');
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return $this->_jsonp(1, 'ok', [], true);
|
||||
}
|
||||
|
||||
public function login() {
|
||||
if (!IS_USE_MEMBER) {
|
||||
$this->_json(0, '没有安装用户系统插件');
|
||||
}
|
||||
require IS_USE_MEMBER.'Controllers/Login.php';
|
||||
$ci = new \Phpcmf\Controllers\Login($this);
|
||||
$ci->index();
|
||||
}
|
||||
|
||||
public function sms() {
|
||||
if (!IS_USE_MEMBER) {
|
||||
$this->_json(0, '没有安装用户系统插件');
|
||||
}
|
||||
require IS_USE_MEMBER.'Controllers/Login.php';
|
||||
$ci = new \Phpcmf\Controllers\Login($this);
|
||||
$ci->sms();
|
||||
}
|
||||
|
||||
public function oauth() {
|
||||
if (!IS_USE_MEMBER) {
|
||||
$this->_json(0, '没有安装用户系统插件');
|
||||
}
|
||||
require IS_USE_MEMBER.'Controllers/Login.php';
|
||||
$ci = new \Phpcmf\Controllers\Login($this);
|
||||
$ci->oauth();
|
||||
}
|
||||
|
||||
public function register() {
|
||||
if (!IS_USE_MEMBER) {
|
||||
$this->_json(0, '没有安装用户系统插件');
|
||||
}
|
||||
require IS_USE_MEMBER.'Controllers/Register.php';
|
||||
$ci = new \Phpcmf\Controllers\Register($this);
|
||||
$ci->index();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php namespace Phpcmf\Control\Api;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
// 测试信息
|
||||
class Test extends \Phpcmf\Common
|
||||
{
|
||||
|
||||
// test
|
||||
public function https() {
|
||||
echo 'xunruicms';
|
||||
}
|
||||
|
||||
public function index() {
|
||||
|
||||
$license = \Phpcmf\Service::R(MYPATH.'Config/License.php');
|
||||
if (isset($license['oem']) && $license['oem']) {
|
||||
echo $license['name'].' '.$license['cms'].' V'.$this->cmf_version['version'] . ' <span style="display: none">'.$license['license'].'</span>';exit;
|
||||
}
|
||||
|
||||
echo 'XunRuiCMS V'.$this->cmf_version['version'].'<hr>';
|
||||
|
||||
if (is_file(WEBPATH.'LICENSE')) {
|
||||
$file = WEBPATH.'LICENSE';
|
||||
} elseif (is_file(ROOTPATH.'LICENSE')) {
|
||||
$file = ROOTPATH.'LICENSE';
|
||||
} elseif (is_file(dirname(WEBPATH).'/LICENSE')) {
|
||||
$file = dirname(WEBPATH).'/LICENSE';
|
||||
} else {
|
||||
exit('<font color="red">LICENSE许可证文件不存在,请遵守迅睿MIT开源协议</font>');
|
||||
}
|
||||
|
||||
echo nl2br((string)file_get_contents($file));
|
||||
exit;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
<?php namespace Phpcmf\Control;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本代码基于MIT开源协议,协议规定此处版权信息不可去除
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
class Category extends \Phpcmf\Home\Module {
|
||||
|
||||
public function index() {
|
||||
|
||||
if (IS_POST) {
|
||||
$this->_json(0, '禁止提交,请检查提交地址是否有误');
|
||||
}
|
||||
|
||||
$id = (int)\Phpcmf\Service::L('input')->get('id');
|
||||
$dir = trim(dr_safe_replace(\Phpcmf\Service::L('input')->get('dir')), '/');
|
||||
$page = max(1, (int)\Phpcmf\Service::L('input')->get('page'));
|
||||
|
||||
$module = \Phpcmf\Service::L('cache')->get('module-'.SITE_ID.'-share');
|
||||
if (!$module) {
|
||||
$module = \Phpcmf\Service::L('cache')->get_file('module-'.SITE_ID.'-share');
|
||||
if (!$module) {
|
||||
$this->_msg(0, dr_lang('共享栏目缓存不存在'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 挂钩点
|
||||
$rt2 = \Phpcmf\Hooks::trigger_callback('module_category_share');
|
||||
if ($rt2 && isset($rt2['code']) && $rt2['code']) {
|
||||
$id = $rt2['data'];
|
||||
}
|
||||
|
||||
if ($id) {
|
||||
$cat = $module['category'][$id];
|
||||
if (!$cat) {
|
||||
$this->goto_404_page(dr_lang('栏目(%s)不存在', $id));
|
||||
}
|
||||
} elseif ($dir) {
|
||||
$id = intval($module['category_dir'][$dir]);
|
||||
$cat = $module['category'][$id];
|
||||
if (!$cat) {
|
||||
if (isset($module['category_dir'][$dir])) {
|
||||
$id = (int)$module['category_dir'][$dir];
|
||||
$cat = $module['category'][$id];
|
||||
} else {
|
||||
// 无法通过目录找到栏目时,尝试多及目录
|
||||
foreach ($module['category'] as $t) {
|
||||
if ($t['setting']['urlrule']) {
|
||||
$rule = \Phpcmf\Service::L('cache')->get('urlrule', $t['setting']['urlrule']);
|
||||
$rule['value']['catjoin'] = '/';
|
||||
if ($rule['value']['catjoin'] && strpos($dir, $rule['value']['catjoin'])) {
|
||||
$dir = trim(strchr($dir, $rule['value']['catjoin']), $rule['value']['catjoin']);
|
||||
if (isset($module['category_dir'][$dir])) {
|
||||
$id = (int)$module['category_dir'][$dir];
|
||||
$cat = $module['category'][$id];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 返回无法找到栏目
|
||||
if (!$id) {
|
||||
$this->goto_404_page(dr_lang('栏目(%s)不存在', $dir));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->goto_404_page(dr_lang('栏目参数不存在'));
|
||||
}
|
||||
|
||||
// 初始化模块
|
||||
if ($cat['tid'] == 1) {
|
||||
if ($cat['mid']) {
|
||||
$this->_module_init($cat['mid']);
|
||||
} else {
|
||||
$this->goto_404_page(dr_lang('栏目所属模块不存在'));
|
||||
}
|
||||
} else {
|
||||
$this->_module_init('share');
|
||||
}
|
||||
|
||||
// 调用栏目方法
|
||||
$this->_Category($id, $dir, $page);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php namespace Phpcmf\Control;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
class Home extends \Phpcmf\Common {
|
||||
|
||||
// 首页显示
|
||||
public function index() {
|
||||
|
||||
if (IS_POST) {
|
||||
$this->_json(0, '禁止提交,请检查提交地址是否有误');
|
||||
}
|
||||
|
||||
// 挂钩点 网站首页时
|
||||
$rs = \Phpcmf\Hooks::trigger_callback('index_page');
|
||||
if ($rs && isset($rs['code'])) {
|
||||
// 存在返回动作不加载模板
|
||||
} else {
|
||||
\Phpcmf\Service::L('Router')->is_redirect_url(dr_url_prefix('/'), 1);
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'indexc' => 1,
|
||||
'fix_html_now_url' => SITE_URL,
|
||||
]);
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'meta_title' => SITE_NAME,
|
||||
'meta_keywords' => SITE_NAME,
|
||||
'meta_description' => SITE_NAME
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('index.html');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 404 页面
|
||||
*/
|
||||
public function s404() {
|
||||
if (IS_DEV) {
|
||||
$uri = \Phpcmf\Service::L('input')->get('uri', true);
|
||||
$msg = '没有找到这个页面: '.$uri;
|
||||
} else {
|
||||
$msg = dr_lang('没有找到这个页面');
|
||||
}
|
||||
$this->goto_404_page($msg);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
<?php namespace Phpcmf\Control;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本代码基于MIT开源协议,协议规定此处版权信息不可去除
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
// 生成静态
|
||||
class Html extends \Phpcmf\Home\Module {
|
||||
|
||||
private $is_html;
|
||||
|
||||
// 首页动作
|
||||
public function _index_page() {
|
||||
|
||||
ob_start();
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'is_cms' => 1,
|
||||
'indexc' => 1,
|
||||
'fix_html_now_url' => defined('IS_MOBILE') && IS_MOBILE ? SITE_MURL : SITE_URL,
|
||||
]);
|
||||
\Phpcmf\Service::V()->assign($this->_index_seo());
|
||||
\Phpcmf\Service::V()->display('index.html');
|
||||
$html = ob_get_clean();
|
||||
|
||||
// 开启过首页静态时
|
||||
if ($this->site_info[SITE_ID]['SITE_INDEX_HTML'] && !defined('SC_HTML_FILE')) {
|
||||
if (IS_CLIENT) {
|
||||
// 自定义终端
|
||||
$file = dr_is_app('chtml') ? \Phpcmf\Service::L('html', 'chtml')->get_webpath(SITE_ID, 'site', IS_CLIENT.'/index.html') : WEBPATH.IS_CLIENT.'/index.html';
|
||||
$rt = file_put_contents($file, $html);
|
||||
!$rt && CI_DEBUG && log_message('error', '首页终端('.IS_CLIENT.')生成失败:'.$file);
|
||||
} elseif (defined('IS_MOBILE') && IS_MOBILE) {
|
||||
// 移动端,当移动端独立域名情况下才生成静态
|
||||
if (defined('SITE_IS_MOBILE_HTML') && SITE_IS_MOBILE_HTML && SITE_MURL == dr_now_url()) {
|
||||
$mfile = dr_is_app('chtml') ? \Phpcmf\Service::L('html', 'chtml')->get_webpath(SITE_ID, 'site', SITE_MOBILE_DIR.'/index.html') : WEBPATH.SITE_MOBILE_DIR.'/index.html';
|
||||
$mobile = file_put_contents($mfile, $html);
|
||||
!$mobile && CI_DEBUG && log_message('error', '首页移动端生成失败:'.$mfile);
|
||||
}
|
||||
} else {
|
||||
// pc
|
||||
$file = dr_is_app('chtml') ? \Phpcmf\Service::L('html', 'chtml')->get_webpath(SITE_ID, 'site', 'index.html') : WEBPATH.'index.html';
|
||||
$pc = file_put_contents($file, $html);
|
||||
!$pc && CI_DEBUG && log_message('error', '首页PC端首页生成失败:'.$file);
|
||||
}
|
||||
}
|
||||
|
||||
echo $html;
|
||||
}
|
||||
|
||||
// 首页显示
|
||||
public function index() {
|
||||
|
||||
if (IS_POST) {
|
||||
$this->_json(0, '禁止提交,请检查提交地址是否有误');
|
||||
}
|
||||
|
||||
|
||||
// 挂钩点 网站首页时
|
||||
\Phpcmf\Hooks::trigger_callback('cms_index');
|
||||
|
||||
\Phpcmf\Service::L('Router')->is_redirect_url(dr_url_prefix('/'), 1);
|
||||
|
||||
$this->_index_page();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 生成静态
|
||||
public function html() {
|
||||
|
||||
// 判断权限
|
||||
if (!dr_html_auth()) {
|
||||
$this->_json(0, '权限验证超时,请重新执行生成');
|
||||
}
|
||||
|
||||
// 标识变量
|
||||
!defined('SC_HTML_FILE') && define('SC_HTML_FILE', 1);
|
||||
|
||||
// 开启ob函数
|
||||
ob_start();
|
||||
$this->is_html = 1;
|
||||
\Phpcmf\Service::V()->init('pc');
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'fix_html_now_url' => SITE_URL, // 修复静态下的当前url变量
|
||||
]);
|
||||
$this->_index_page();
|
||||
$html = ob_get_clean();
|
||||
$file = dr_is_app('chtml') ? \Phpcmf\Service::L('html', 'chtml')->get_webpath(SITE_ID, 'site', 'index.html') : WEBPATH.'index.html';
|
||||
$pc = file_put_contents($file, $html, LOCK_EX);
|
||||
!$pc && CI_DEBUG && log_message('error', '首页PC端首页生成失败:'.$file);
|
||||
|
||||
if (SITE_MURL != SITE_URL) {
|
||||
// 开启ob函数
|
||||
ob_start();
|
||||
$this->is_html = 1;
|
||||
\Phpcmf\Service::V()->init('mobile');
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'fix_html_now_url' => SITE_MURL, // 修复静态下的当前url变量
|
||||
]);
|
||||
$this->_index_page();
|
||||
$html = ob_get_clean();
|
||||
$mfile = dr_is_app('chtml') ? \Phpcmf\Service::L('html', 'chtml')->get_webpath(SITE_ID, 'site', SITE_MOBILE_DIR.'/index.html') : WEBPATH.SITE_MOBILE_DIR.'/index.html';
|
||||
$mobile = file_put_contents($mfile, $html, LOCK_EX);
|
||||
!$mobile && CI_DEBUG && log_message('error', '首页移动端生成失败:'.$mfile);
|
||||
} else {
|
||||
CI_DEBUG && log_message('error', '首页移动端生成失败:移动端未绑定域名');
|
||||
}
|
||||
|
||||
$this->_json(1, dr_lang('电脑端 (%s),移动端 (%s)', dr_format_file_size($pc), dr_format_file_size($mobile)));
|
||||
}
|
||||
|
||||
private function _index_seo() {
|
||||
|
||||
$seo = [
|
||||
'meta_title' => \Phpcmf\Service::C()->get_cache('site', SITE_ID, 'seo', 'SITE_TITLE'),
|
||||
'meta_keywords' => \Phpcmf\Service::C()->get_cache('site', SITE_ID, 'seo', 'SITE_KEYWORDS'),
|
||||
'meta_description' => \Phpcmf\Service::C()->get_cache('site', SITE_ID, 'seo', 'SITE_DESCRIPTION')
|
||||
];
|
||||
|
||||
if (IS_CLIENT) {
|
||||
// 终端模式下
|
||||
$cdata = \Phpcmf\Service::R(WRITEPATH.'config/app_client_seo_'.SITE_ID.'.php');
|
||||
if ($cdata && isset($cdata[IS_CLIENT]) && $cdata[IS_CLIENT]) {
|
||||
$seo = [
|
||||
'meta_title' => $cdata[IS_CLIENT]['SITE_TITLE'],
|
||||
'meta_keywords' => $cdata[IS_CLIENT]['SITE_KEYWORDS'],
|
||||
'meta_description' => $cdata[IS_CLIENT]['SITE_DESCRIPTION']
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
!$seo['meta_title'] && $seo['meta_title'] = SITE_NAME;
|
||||
|
||||
if ($seo['meta_title'] && strpos($seo['meta_title'], '{page}') !== false) {
|
||||
$page = max(1, intval($_GET['page']));
|
||||
if ($page > 1) {
|
||||
$seo['meta_title'] = str_replace(array('[', ']'), '', $seo['meta_title']);
|
||||
$seo['meta_title'] = str_replace('{join}', SITE_SEOJOIN, $seo['meta_title']);
|
||||
$seo['meta_title'] = str_replace('{page}', $page, $seo['meta_title']);
|
||||
} else {
|
||||
$seo['meta_title'] = preg_replace('/\[.+\]/U', '', $seo['meta_title']);
|
||||
}
|
||||
}
|
||||
|
||||
return \Phpcmf\Service::L('Seo')->get_seo_value([], $seo);
|
||||
}
|
||||
|
||||
// 生成栏目
|
||||
public function category() {
|
||||
parent::_Category_Html();
|
||||
}
|
||||
|
||||
// 生成内容
|
||||
public function show() {
|
||||
parent::_Show_Html();
|
||||
}
|
||||
|
||||
// 生成栏目单页
|
||||
public function categoryfile() {
|
||||
parent::_Category_Html_File();
|
||||
}
|
||||
|
||||
// 生成内容单页
|
||||
public function showfile() {
|
||||
parent::_Show_Html_File();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,987 @@
|
||||
<?php namespace Phpcmf\Control;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
define('IS_INSTALL', 1);
|
||||
set_time_limit(0);
|
||||
|
||||
// 安装程序
|
||||
class Install extends \Phpcmf\Common {
|
||||
|
||||
public $db;
|
||||
private $lock;
|
||||
|
||||
/**
|
||||
* 初始化共享控制器
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
define('SITE_LANGUAGE', is_file(WRITEPATH.'lang.default') ? file_get_contents(WRITEPATH.'lang.default') : 'zh-cn');
|
||||
define('SITE_ID', 1);
|
||||
define('SITE_URL', '/');
|
||||
define('SITE_MURL', '/');
|
||||
define('IS_API_HTTP', 0);
|
||||
define('SITE_TEMPLATE', 'default');
|
||||
define('THEME_PATH', '/static/');
|
||||
define('ROOT_THEME_PATH', '/static/');
|
||||
define('LANG_PATH', '/api/language/'.SITE_LANGUAGE.'/');
|
||||
if (is_file(MYPATH.'Config/Version.php')) {
|
||||
$app = require MYPATH.'Config/Version.php';
|
||||
} else {
|
||||
$app = [
|
||||
'id' => 1,
|
||||
'name' => 'XunRui',
|
||||
'version' => 'dev',
|
||||
];
|
||||
}
|
||||
define('DR_CMS', $app['id']);
|
||||
define('DR_NAME', $app['name']);
|
||||
define('DR_VERSION', $app['version']);
|
||||
define('SITE_NAME', $app['name']);
|
||||
define('CMF_UPDATE_TIME', SYS_TIME);
|
||||
\Phpcmf\Service::V()->init('pc');
|
||||
\Phpcmf\Service::V()->admin();
|
||||
}
|
||||
|
||||
public function index() {
|
||||
|
||||
$this->lock = WRITEPATH.'install.lock';
|
||||
if (!IS_XRDEV && is_file($this->lock)) {
|
||||
exit(dr_lang('安装程序已经被锁定,重新安装请删除%s', 'cache/install.lock'));
|
||||
}
|
||||
|
||||
$data = [];
|
||||
$step = intval($_GET['step']);
|
||||
if (!$step && SITE_LANGUAGE != 'zh-cn') {
|
||||
$step = 1;
|
||||
}
|
||||
$error = '';
|
||||
$admin = 'admin';
|
||||
|
||||
switch ($step) {
|
||||
|
||||
case 0:
|
||||
$gsname = '四川迅睿云软件开发有限公司';
|
||||
if (is_file(MYPATH.'Config/License.php')) {
|
||||
$ls = require MYPATH.'Config/License.php';
|
||||
if (isset($ls['name']) && $ls['name']) {
|
||||
$gsname = $ls['name'];
|
||||
}
|
||||
}
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'gsname' => $gsname,
|
||||
]);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
|
||||
$error = 0;
|
||||
// 目录权限检查
|
||||
$dir = [
|
||||
WRITEPATH,
|
||||
WRITEPATH.'data/',
|
||||
WRITEPATH.'file/',
|
||||
WRITEPATH.'config/',
|
||||
WRITEPATH.'session/',
|
||||
WRITEPATH.'template/',
|
||||
WRITEPATH.'database/', CONFIGPATH,
|
||||
WEBPATH.'uploadfile/',
|
||||
];
|
||||
$path = [];
|
||||
foreach ($dir as $t) {
|
||||
$path[$t] = dr_check_put_path($t);
|
||||
if (!$path[$t]) {
|
||||
$error = 1;
|
||||
}
|
||||
}
|
||||
$php = [
|
||||
[
|
||||
'name' => dr_lang('PHP扩展%s', 'mbstring'),
|
||||
'code' => function_exists('mb_substr'),
|
||||
'help' => 'http://www.xunruicms.com/doc/742.html',
|
||||
],
|
||||
[
|
||||
'name' => dr_lang('PHP扩展%s', 'curl'),
|
||||
'code' => function_exists('curl_init'),
|
||||
'help' => 'http://www.xunruicms.com/doc/743.html',
|
||||
],
|
||||
];
|
||||
$db_ext = [
|
||||
[
|
||||
'name' => dr_lang('PHP扩展%s', 'mysqli').'(MySQLi)',
|
||||
'code' => function_exists('mysqli_init'),
|
||||
'help' => 'http://www.xunruicms.com/doc/741.html',
|
||||
],
|
||||
[
|
||||
'name' => dr_lang('PHP扩展%s', 'sqlite3').'(SQLite3)',
|
||||
'code' => extension_loaded('sqlite3'),
|
||||
'help' => '',
|
||||
],
|
||||
];
|
||||
// 数据库扩展:mysqli / sqlite3 至少启用一个即可
|
||||
$has_db_ext = function_exists('mysqli_init') || extension_loaded('sqlite3');
|
||||
if (!$has_db_ext) {
|
||||
$error = 1;
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'php' => $php,
|
||||
'db_ext' => $db_ext,
|
||||
'has_db_ext' => $has_db_ext,
|
||||
'path' => $path,
|
||||
'error' => $error,
|
||||
]);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
// 安装信息填写
|
||||
|
||||
$is_demo = is_file(MYPATH.'Config/demo.sql') && !is_file(MYPATH.'Config/Install.sql');
|
||||
|
||||
if (IS_AJAX_POST) {
|
||||
|
||||
$data = $_POST['data'];
|
||||
if (empty($data['name'])) {
|
||||
$this->_json(0, dr_lang('项目名称不能为空'));
|
||||
} elseif (empty($data['username'])) {
|
||||
$this->_json(0, dr_lang('创始人账号不能为空'));
|
||||
} elseif (empty($data['password'])) {
|
||||
$this->_json(0, dr_lang('创始人密码不能为空'));
|
||||
} elseif (empty($data['email'])) {
|
||||
$this->_json(0, dr_lang('创始人邮箱不能为空'));
|
||||
}
|
||||
|
||||
// 数据库驱动:扫描 System/Database 下可用驱动(目录不存在则默认 MySQLi)
|
||||
$drivers = $this->_scan_database_drivers($this->_my_install_sql_requires_mysql());
|
||||
$rawDriver = isset($data['db_driver']) ? trim((string) $data['db_driver']) : '';
|
||||
$selected = null;
|
||||
foreach ($drivers as $d) {
|
||||
if (strcasecmp($d['name'], $rawDriver) === 0) {
|
||||
$selected = $d;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$selected) {
|
||||
// 默认优先 MySQLi
|
||||
foreach ($drivers as $d) {
|
||||
if ($d['enabled']) {
|
||||
$selected = $d;
|
||||
if ($d['name'] === 'MySQLi') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!$selected || !$selected['enabled']) {
|
||||
$this->_json(0, dr_lang('不支持的数据库驱动:%s', $rawDriver !== '' ? $rawDriver : '-'));
|
||||
}
|
||||
$data['db_driver'] = $selected['name'];
|
||||
|
||||
// 自定义包 Install.sql 含 SQL 时仅允许 MySQLi
|
||||
if ($this->_my_install_sql_requires_mysql() && $data['db_driver'] !== 'MySQLi') {
|
||||
$this->_json(0, dr_lang('当前安装包存在自定义 Install.sql,仅支持 MySQLi 安装'));
|
||||
}
|
||||
|
||||
if (empty($data['db_prefix'])) {
|
||||
$this->_json(0, dr_lang('数据表前缀不能为空'));
|
||||
}
|
||||
|
||||
if ($data['db_driver'] === 'SQLite3') {
|
||||
// 路径与随机文件名由 _install_db_bootstrap 生成
|
||||
$data['db_host'] = isset($data['db_host']) ? $data['db_host'] : '';
|
||||
$data['db_user'] = isset($data['db_user']) ? $data['db_user'] : '';
|
||||
$data['db_pass'] = isset($data['db_pass']) ? $data['db_pass'] : '';
|
||||
} else {
|
||||
if (empty($data['db_host'])) {
|
||||
$this->_json(0, dr_lang('数据库地址不能为空'));
|
||||
} elseif (empty($data['db_user'])) {
|
||||
$this->_json(0, dr_lang('数据库账号不能为空'));
|
||||
} elseif (empty($data['db_name'])) {
|
||||
$this->_json(0, dr_lang('数据库名称不能为空'));
|
||||
} elseif (!isset($data['db_pass'])) {
|
||||
$this->_json(0, dr_lang('数据库密码不能为空'));
|
||||
}
|
||||
// 允许空密码(部分本地环境)
|
||||
if (is_numeric(substr($data['db_name'], 0, 1))) {
|
||||
$this->_json(0, dr_lang('数据库名称(%s)不能是数字开头', $data['db_name']));
|
||||
} elseif (strpos($data['db_name'], '.') !== false) {
|
||||
$this->_json(0, dr_lang('数据库名(%s)不能存在.号', $data['db_name']));
|
||||
}
|
||||
$data['db_name'] = dr_safe_filename($data['db_name']);
|
||||
}
|
||||
|
||||
$rt = $this->_install_db_bootstrap($data);
|
||||
if (!$rt['code']) {
|
||||
$this->_json(0, $rt['msg']);
|
||||
}
|
||||
// SQLite 可能规范化了相对路径(如补全 database/ 前缀)
|
||||
if (!empty($rt['data']) && is_array($rt['data'])) {
|
||||
$data = array_merge($data, $rt['data']);
|
||||
}
|
||||
|
||||
$data['db_prefix'] = strtolower($data['db_prefix']);
|
||||
|
||||
// 存储缓存文件中
|
||||
$size = file_put_contents(WRITEPATH.'install.info', dr_array2string($data));
|
||||
if (!$size || $size < 10) {
|
||||
$this->_json(0, dr_lang('临时数据存储失败,cahce目录无法写入'));
|
||||
}
|
||||
|
||||
// 写入数据库配置(显式 DBDriver,供驱动层 DDL/方言转换使用)
|
||||
$rt = $this->_write_database_config($data);
|
||||
if (!$rt['code']) {
|
||||
$this->_json(0, $rt['msg']);
|
||||
}
|
||||
|
||||
$this->_json(1, 'index.php?c=install&m=index&is_install_db='.(!$is_demo ? 0 : intval($_POST['is_install_db'])).'&step='.($step+1));
|
||||
}
|
||||
$force_mysqli = $this->_my_install_sql_requires_mysql();
|
||||
$db_drivers = $this->_scan_database_drivers($force_mysqli);
|
||||
$default_driver = 'MySQLi';
|
||||
$db_dir_missing = !is_dir(FRAMEPATH.'Database/');
|
||||
foreach ($db_drivers as $d) {
|
||||
if (!empty($d['enabled'])) {
|
||||
$default_driver = $d['name'];
|
||||
if ($d['name'] === 'MySQLi') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
$data = [
|
||||
'do_url' => '/index.php?c=install&m=index&is_install_db='.(!$is_demo ? 0 : intval($_POST['is_install_db'])).'&step=2',
|
||||
'is_demo' => $is_demo,
|
||||
'db_driver' => $default_driver,
|
||||
'db_drivers' => $db_drivers,
|
||||
'db_dir_missing' => $db_dir_missing,
|
||||
'db_host' => defined('INSTALL_DB_HOST') ? INSTALL_DB_HOST : '127.0.0.1',
|
||||
'db_user' => defined('INSTALL_DB_USER') ? INSTALL_DB_USER : '',
|
||||
'db_pass' => defined('INSTALL_DB_PASS') ? INSTALL_DB_PASS : '',
|
||||
'db_name' => defined('INSTALL_DB_NAME') ? INSTALL_DB_NAME : '',
|
||||
'db_prefix' => defined('INSTALL_DB_PREFIX') ? INSTALL_DB_PREFIX : 'dr_',
|
||||
'sqlite_name' => 'database/SQLite3/'.dr_lang('安装时随机生成'),
|
||||
'force_mysqli' => $force_mysqli,
|
||||
];
|
||||
\Phpcmf\Service::V()->assign($data);
|
||||
|
||||
break;
|
||||
|
||||
case 3:
|
||||
$page = intval($_GET['page']);
|
||||
$data = dr_string2array(file_get_contents(WRITEPATH.'install.info'));
|
||||
$error = '';
|
||||
file_put_contents(WRITEPATH.'install.error', '');
|
||||
if (empty($data)) {
|
||||
$error = dr_lang('临时数据获取失败,请返回前一页重新执行');
|
||||
} else {
|
||||
$this->db = \Phpcmf\Service::M()->db;
|
||||
// 检查数据库是否存在
|
||||
if (!$this->db->connect(false)) {
|
||||
// 链接失败,尝试创建数据库
|
||||
$error = dr_lang('数据库连接失败,请返回前一页重新执行');
|
||||
} elseif (!isset($_GET['doin']) && $this->db->tableExists($data['db_prefix'].'cron')) {
|
||||
// 判断是否安装过
|
||||
if (isset($data['db_driver']) && $data['db_driver'] === 'SQLite3') {
|
||||
$error = dr_lang('指定的数据库文件(%s)已经安装过表前缀(%s),你可以尝试修改数据库文件名或者数据表前缀', $data['db_name'], $data['db_prefix']);
|
||||
} else {
|
||||
$error = dr_lang('指定的数据库(%s)已经安装过表前缀(%s),你可以尝试修改数据库名或者数据表前缀', $data['db_name'], $data['db_prefix']);
|
||||
}
|
||||
} else {
|
||||
|
||||
// 导入数据结构
|
||||
if ($page) {
|
||||
// 优先规范化 Schema(Config/Install.php);自定义包仍可用 MYPATH Install.sql
|
||||
$schema_file = '';
|
||||
if (!is_file(MYPATH.'Config/Install.sql') && is_file(CMSPATH.'Config/Install.php')) {
|
||||
$schema_file = CMSPATH.'Config/Install.php';
|
||||
}
|
||||
if ($schema_file) {
|
||||
if ((int)$page === 1) {
|
||||
$schema = require $schema_file;
|
||||
if (!is_array($schema) || empty($schema['tables'])) {
|
||||
$this->_json(0, dr_lang('安装 Schema 无效:%s', $schema_file));
|
||||
}
|
||||
$rt = \Phpcmf\Service::M('table')->install_schema($schema);
|
||||
if (!$rt['code']) {
|
||||
$error = '**************************************************************************'
|
||||
.PHP_EOL.$rt['msg'].PHP_EOL
|
||||
.'**************************************************************************'.PHP_EOL;
|
||||
file_put_contents(WRITEPATH.'install.error', $error.PHP_EOL, FILE_APPEND);
|
||||
$this->_json(0, $rt['msg']);
|
||||
}
|
||||
$this->_json(1, dr_lang('表结构安装完成(%s张表)', intval($rt['data']['tables'] ?? 0)), ['page' => 99]);
|
||||
}
|
||||
$this->_json(1, dr_lang('执行完成,即将安装数据信息...'), ['page' => 99]);
|
||||
}
|
||||
|
||||
if (is_file(MYPATH.'Config/Install.sql')) {
|
||||
$sql = file_get_contents(MYPATH.'Config/Install.sql');
|
||||
if (strlen($sql) < 100) {
|
||||
$sql = file_get_contents(CMSPATH.'Config/Install.sql');
|
||||
}
|
||||
} else {
|
||||
$sql = file_get_contents(CMSPATH.'Config/Install.sql');
|
||||
}
|
||||
$sql = str_replace('{dbprefix}', $data['db_prefix'], $sql);
|
||||
// 每批条数过少会导致超大 Install.sql 需要数百次 AJAX,易中途超时;可按环境酌情调大
|
||||
$rows = $this->query_rows($sql, 40);
|
||||
$key = $page - 1;
|
||||
if (isset($rows[$key]) && $rows[$key]) {
|
||||
// 安装本次结构
|
||||
$last_sql = '';
|
||||
foreach ($rows[$key] as $statement) {
|
||||
if (!$statement) {
|
||||
continue;
|
||||
}
|
||||
$statement = trim($statement);
|
||||
if ($statement === '') {
|
||||
continue;
|
||||
}
|
||||
$last_sql = $statement;
|
||||
if (!$this->db->simpleQuery($statement)) {
|
||||
$rt = $this->db->error();
|
||||
$error = '**************************************************************************'
|
||||
.PHP_EOL.$statement.PHP_EOL.$rt['message'].PHP_EOL;
|
||||
$error.= '**************************************************************************'.PHP_EOL;
|
||||
file_put_contents(WRITEPATH.'install.error', $error.PHP_EOL, FILE_APPEND);
|
||||
$this->_json(0, 'SQL执行错误:'.$rt['message']);
|
||||
}
|
||||
}
|
||||
$this->_json(1, dr_lang('正在执行:%s', dr_strcut($last_sql, 70)), ['page' => $page + 1]);
|
||||
|
||||
} else {
|
||||
$this->_json(1, dr_lang('执行完成,即将安装数据信息...'), ['page' => 99]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'do_url' => 'index.php?c=install&m=index&step=3&doin=1&is_install_db='.intval($_GET['is_install_db']),
|
||||
]);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
|
||||
$data = dr_string2array(file_get_contents(WRITEPATH.'install.info'));
|
||||
if (empty($data)) {
|
||||
$error = dr_lang('临时数据获取失败,请返回前一页重新执行');
|
||||
} else {
|
||||
$this->db = \Phpcmf\Service::M()->db;
|
||||
// 检查数据库是否存在
|
||||
if (!$this->db->connect(false)) {
|
||||
// 链接失败,尝试创建数据库
|
||||
$error = dr_lang('数据库连接失败,请返回前一页重新执行');
|
||||
} else {
|
||||
// 导入默认安装数据
|
||||
$errorlog = file_get_contents(WRITEPATH.'install.error');
|
||||
if ($errorlog && strlen($errorlog) > 10) {
|
||||
// 出现错误了
|
||||
$error = $errorlog;
|
||||
} else {
|
||||
if (!\Phpcmf\Service::M()->is_table_exists('member')) {
|
||||
if (is_file(MYPATH.'Config/Install.sql')) {
|
||||
$sql = MYPATH.'Config/Install.sql';
|
||||
} elseif (is_file(CMSPATH.'Config/Install.php')) {
|
||||
$sql = CMSPATH.'Config/Install.php';
|
||||
} else {
|
||||
$sql = CMSPATH.'Config/Install.sql';
|
||||
}
|
||||
$error = dr_lang('安装文件:%s', $sql);
|
||||
$error.= '<br>'.dr_lang('关键数据表member结构不完整,检查安装包结构文件是否合理');
|
||||
} else {
|
||||
// 创建账号
|
||||
$pwd = md5(dr_safe_password($data['password']));
|
||||
$salt = substr(md5(rand(0, 999)), 0, 10);
|
||||
$prefix = \Phpcmf\Service::M()->prefix;
|
||||
if (\Phpcmf\Service::M()->table('member')->get(1)) {
|
||||
\Phpcmf\Service::M()->table('member')->update(1, [
|
||||
'email' => $data['email'],
|
||||
'username' => $data['username'],
|
||||
'password' => md5($pwd.$salt.$pwd),
|
||||
'salt' => $salt,
|
||||
'name' => dr_lang('创始人'),
|
||||
'phone' => '',
|
||||
'money' => 1000000,
|
||||
'freeze' => 0,
|
||||
'spend' => 0,
|
||||
'score' => 1000000,
|
||||
'experience' => 1000000,
|
||||
'regip' => '',
|
||||
'regtime' => SYS_TIME,
|
||||
'randcode' => 0,
|
||||
]);
|
||||
$id = 1;
|
||||
} else {
|
||||
$this->db->table('member')->insert([
|
||||
'email' => $data['email'],
|
||||
'username' => $data['username'],
|
||||
'password' => md5($pwd.$salt.$pwd),
|
||||
'salt' => $salt,
|
||||
'name' => dr_lang('创始人'),
|
||||
'phone' => '',
|
||||
'money' => 1000000,
|
||||
'freeze' => 0,
|
||||
'spend' => 0,
|
||||
'score' => 1000000,
|
||||
'experience' => 1000000,
|
||||
'regip' => '',
|
||||
'regtime' => SYS_TIME,
|
||||
'randcode' => 0,
|
||||
]);
|
||||
$id = $this->db->insertID();
|
||||
$this->db->table('member_data')->insert([
|
||||
'id' => $id,
|
||||
'is_lock' => 0,
|
||||
'is_admin' => 1,
|
||||
'is_verify' => 1,
|
||||
'is_mobile' => 1,
|
||||
'is_complete' => 1,
|
||||
]);
|
||||
}
|
||||
|
||||
// 加入管理员表
|
||||
if (!\Phpcmf\Service::M()->table('admin')->where('uid', $id)->counts()) {
|
||||
$this->db->table('admin')->insert([
|
||||
'uid' => $id,
|
||||
'setting' => '',
|
||||
'usermenu' => '',
|
||||
]);
|
||||
// 加入角色表
|
||||
$this->db->table('admin_role_index')->insert([
|
||||
'uid' => $id,
|
||||
'roleid' => 1,
|
||||
]);
|
||||
}
|
||||
|
||||
// 创建站点
|
||||
if (\Phpcmf\Service::M()->table('site')->get(1)) {
|
||||
\Phpcmf\Service::M()->table('site')->update(1, [
|
||||
'name' => $data['name'],
|
||||
'domain' => DOMAIN_NAME,
|
||||
]);
|
||||
} else {
|
||||
$this->db->table('site')->replace([
|
||||
'id' => 1,
|
||||
'name' => $data['name'],
|
||||
'domain' => DOMAIN_NAME,
|
||||
'setting' => '',
|
||||
'disabled' => 0,
|
||||
'displayorder' => 0,
|
||||
]);
|
||||
}
|
||||
|
||||
\Phpcmf\Service::M()->site = $this->site = [ 1 => 1 ];
|
||||
|
||||
$ssl = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') || (isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == '443') ? 1 : 0;;
|
||||
if (isset($_GET['protocol']) && trim($_GET['protocol'], ':') == 'https') {
|
||||
$ssl = 1;
|
||||
}
|
||||
|
||||
// 写配置文件
|
||||
$sys = [
|
||||
'SYS_DEBUG' => '1',
|
||||
'SYS_ADMIN_CODE' => '0',
|
||||
'SYS_ADMIN_LOG' => '0',
|
||||
'SYS_AUTO_FORM' => '0',
|
||||
'SYS_ADMIN_PAGESIZE' => '10',
|
||||
'SYS_SMS_IMG_CODE' => '0',
|
||||
'SYS_NOT_ADMIN_CACHE' => '0',
|
||||
'SYS_URL_ONLY' => '0',
|
||||
'SYS_THEME_ROOT_PATH' => '1',
|
||||
'SYS_URL_REL' => '1',
|
||||
'SYS_CRON_AUTH' => '0',
|
||||
'SYS_CSRF' => '0',
|
||||
'SYS_CSRF_TIME' => '0',
|
||||
'SYS_301' => '1',
|
||||
'SYS_NOT_UPDATE' => '1',
|
||||
'SYS_KEY' => 'PHPCMF'.md5($data['name'].rand(1, 999999)), //安全密匙
|
||||
'SYS_HTTPS' => $ssl,
|
||||
'SYS_ATTACHMENT_DB' => '',
|
||||
'SYS_ATTACHMENT_PATH' => '',
|
||||
'SYS_ATTACHMENT_URL' => '',
|
||||
'SYS_API_TOKEN' => '',
|
||||
];
|
||||
if (is_file(MYPATH.'Config/License.php')) {
|
||||
$ls = require MYPATH.'Config/License.php';
|
||||
if (isset($ls['oem']) && $ls['oem']) {
|
||||
$sys['SYS_DEBUG'] = 0;
|
||||
}
|
||||
}
|
||||
\Phpcmf\Service::M('System')->save_config($sys, $sys);
|
||||
|
||||
// 删除app的install.lock
|
||||
$local = \Phpcmf\Service::Apps();
|
||||
foreach ($local as $dir => $path) {
|
||||
if (is_file($path.'install.lock')) {
|
||||
unlink($path.'install.lock');
|
||||
}
|
||||
}
|
||||
|
||||
// 执行安装程序废除
|
||||
/*
|
||||
$sql = '';
|
||||
if (is_file(MYPATH.'Config/Install.sql')) {
|
||||
$sql = file_get_contents(MYPATH.'Config/Install.sql');
|
||||
$sql = str_replace('{dbprefix}', $data['db_prefix'], $sql);
|
||||
}
|
||||
|
||||
if (is_file(MYPATH.'Config/Install_site.sql')) {
|
||||
$s = file_get_contents(MYPATH.'Config/Install_site.sql');
|
||||
$sql.= PHP_EOL.str_replace('{dbprefix}', $data['db_prefix'].'1_', $s);
|
||||
}
|
||||
$this->query($sql);*/
|
||||
|
||||
// 运行自定义安装脚本
|
||||
if (is_file(MYPATH.'Config/Install.php')) {
|
||||
require MYPATH.'Config/Install.php';
|
||||
}
|
||||
|
||||
// 运行自定义安装脚本②
|
||||
if (is_file(MYPATH.'Config/Install_tpl.php')) {
|
||||
require MYPATH.'Config/Install_tpl.php';
|
||||
}
|
||||
|
||||
$errorlog = file_get_contents(WRITEPATH.'install.error');
|
||||
if ($errorlog && strlen($errorlog) > 10) {
|
||||
// 出现错误了
|
||||
$error = $errorlog;
|
||||
} else {
|
||||
// 安装完成
|
||||
file_put_contents($this->lock, time());
|
||||
file_put_contents(WRITEPATH.'update.txt', time());
|
||||
file_put_contents(WRITEPATH.'install.test', time());
|
||||
unlink(WRITEPATH.'install.info');
|
||||
unlink(WRITEPATH.'install.error');
|
||||
// 重命名后台入口
|
||||
$admin = 'admin'.substr(md5(SYS_TIME.rand(1, 999999)), 0, 12);
|
||||
$afile = WEBPATH.$admin.'.php';
|
||||
if (is_file(WEBPATH.'admin.php')) {
|
||||
copy(WEBPATH.'admin.php', $afile);
|
||||
}
|
||||
if (!is_file($afile)) {
|
||||
file_put_contents($afile, "<?php
|
||||
define('IS_ADMIN', TRUE);
|
||||
define('SELF', pathinfo(__FILE__, PATHINFO_BASENAME));
|
||||
require('index.php');");
|
||||
}
|
||||
if (is_file($afile)) {
|
||||
unlink(WEBPATH.'admin.php');
|
||||
} else {
|
||||
$admin = 'admin';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
\Phpcmf\Service::V()->assign([
|
||||
'data' => $data,
|
||||
'step' => $step,
|
||||
'error' => $error,
|
||||
'admin' => $admin,
|
||||
'pre_url' => 'index.php?c=install&m=index&step='.($step-1).'&is_install_db='.intval($_GET['is_install_db']),
|
||||
'next_url' => 'index.php?c=install&m=index&step='.($step+1).'&is_install_db='.intval($_GET['is_install_db']),
|
||||
]);
|
||||
\Phpcmf\Service::V()->display('install/'.$step.'.html');
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* 扫描 FRAMEPATH/Database 目录,列出可识别的数据库驱动
|
||||
*
|
||||
* @param bool $forceMysqli 自定义 Install.sql 时仅启用 MySQLi
|
||||
* @return array [['name','label','ext_ok','installable','enabled','form','tip'], ...]
|
||||
*/
|
||||
private function _scan_database_drivers($forceMysqli = false)
|
||||
{
|
||||
$base = FRAMEPATH.'Database/';
|
||||
$list = [];
|
||||
|
||||
// 无 System/Database 目录时,默认仅 MySQL(MySQLi)模式
|
||||
if (!is_dir($base)) {
|
||||
$extOk = function_exists('mysqli_init');
|
||||
return [[
|
||||
'name' => 'MySQLi',
|
||||
'label' => 'MySQLi',
|
||||
'ext_ok' => $extOk,
|
||||
'installable' => true,
|
||||
'enabled' => $extOk,
|
||||
'form' => 'server',
|
||||
'tip' => $extOk ? '' : dr_lang('PHP 未启用对应扩展'),
|
||||
]];
|
||||
}
|
||||
|
||||
// PHP 扩展检测
|
||||
$extMap = [
|
||||
'MySQLi' => function_exists('mysqli_init'),
|
||||
'SQLite3' => extension_loaded('sqlite3'),
|
||||
'Postgre' => extension_loaded('pgsql'),
|
||||
'SQLSRV' => extension_loaded('sqlsrv'),
|
||||
'OCI8' => extension_loaded('oci8'),
|
||||
];
|
||||
// 表单类型:sqlite 用文件表单,其余用服务器表单
|
||||
$formMap = [
|
||||
'SQLite3' => 'sqlite',
|
||||
];
|
||||
// 安装引导已实现的驱动(其余目录有驱动文件但安装流程未接好)
|
||||
$bootstrapOk = ['MySQLi' => true, 'SQLite3' => true];
|
||||
|
||||
$dirs = @scandir($base);
|
||||
if (!is_array($dirs) || $dirs === []) {
|
||||
$extOk = function_exists('mysqli_init');
|
||||
return [[
|
||||
'name' => 'MySQLi',
|
||||
'label' => 'MySQLi',
|
||||
'ext_ok' => $extOk,
|
||||
'installable' => true,
|
||||
'enabled' => $extOk,
|
||||
'form' => 'server',
|
||||
'tip' => $extOk ? '' : dr_lang('PHP 未启用对应扩展'),
|
||||
]];
|
||||
}
|
||||
|
||||
foreach ($dirs as $name) {
|
||||
if ($name === '.' || $name === '..' || !is_dir($base.$name)) {
|
||||
continue;
|
||||
}
|
||||
$conn = $base.$name.'/Connection.php';
|
||||
if (!is_file($conn)) {
|
||||
continue;
|
||||
}
|
||||
// 迅睿安装要求驱动实现 formatCreateSql;未实现的不展示在安装界面
|
||||
$code = @file_get_contents($conn);
|
||||
$hasDdl = is_string($code) && strpos($code, 'function formatCreateSql') !== false;
|
||||
if (!$hasDdl) {
|
||||
continue;
|
||||
}
|
||||
$extOk = isset($extMap[$name]) ? (bool) $extMap[$name] : true;
|
||||
$installable = !empty($bootstrapOk[$name]);
|
||||
$enabled = $installable && $extOk;
|
||||
if ($forceMysqli && $name !== 'MySQLi') {
|
||||
$enabled = false;
|
||||
}
|
||||
|
||||
$tip = '';
|
||||
if (empty($bootstrapOk[$name])) {
|
||||
$tip = dr_lang('安装引导暂未支持该驱动');
|
||||
} elseif (!$extOk) {
|
||||
$tip = dr_lang('PHP 未启用对应扩展');
|
||||
} elseif ($forceMysqli && $name !== 'MySQLi') {
|
||||
$tip = dr_lang('自定义 Install.sql 仅支持 MySQLi');
|
||||
}
|
||||
|
||||
$list[] = [
|
||||
'name' => $name,
|
||||
'label' => $name,
|
||||
'ext_ok' => $extOk,
|
||||
'installable' => $installable,
|
||||
'enabled' => $enabled,
|
||||
'form' => isset($formMap[$name]) ? $formMap[$name] : 'server',
|
||||
'tip' => $tip,
|
||||
];
|
||||
}
|
||||
|
||||
// 目录存在但未扫到任何驱动时,同样回退 MySQLi
|
||||
if (!$list) {
|
||||
$extOk = function_exists('mysqli_init');
|
||||
return [[
|
||||
'name' => 'MySQLi',
|
||||
'label' => 'MySQLi',
|
||||
'ext_ok' => $extOk,
|
||||
'installable' => true,
|
||||
'enabled' => $extOk,
|
||||
'form' => 'server',
|
||||
'tip' => $extOk ? '' : dr_lang('PHP 未启用对应扩展'),
|
||||
]];
|
||||
}
|
||||
|
||||
// MySQLi / SQLite3 排前面,其余按名称
|
||||
usort($list, static function ($a, $b) {
|
||||
$order = ['MySQLi' => 0, 'SQLite3' => 1];
|
||||
$oa = isset($order[$a['name']]) ? $order[$a['name']] : 50;
|
||||
$ob = isset($order[$b['name']]) ? $order[$b['name']] : 50;
|
||||
if ($oa === $ob) {
|
||||
return strcmp($a['name'], $b['name']);
|
||||
}
|
||||
return $oa - $ob;
|
||||
});
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否存在自定义 My/Config/Install.sql 且含有效 SQL(此时禁止选 SQLite3)
|
||||
*/
|
||||
private function _my_install_sql_requires_mysql()
|
||||
{
|
||||
$file = MYPATH.'Config/Install.sql';
|
||||
if (!is_file($file)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$sql = @file_get_contents($file);
|
||||
if ($sql === false || trim($sql) === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 去掉注释与空白后判断是否还有语句
|
||||
$lines = preg_split("/\r\n|\n|\r/", $sql);
|
||||
$buf = '';
|
||||
if (is_array($lines)) {
|
||||
foreach ($lines as $line) {
|
||||
$trim = ltrim($line);
|
||||
if ($trim === '' || strpos($trim, '--') === 0 || strpos($trim, '#') === 0) {
|
||||
continue;
|
||||
}
|
||||
$buf .= $trim;
|
||||
}
|
||||
}
|
||||
|
||||
$buf = trim(preg_replace('/\/\*.*?\*\//s', '', $buf) ?? '');
|
||||
if ($buf === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 至少像一条 SQL(含关键字或分号)
|
||||
return (bool) preg_match('/\b(CREATE|INSERT|REPLACE|ALTER|DROP|UPDATE|DELETE|SET)\b/i', $buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成 SQLite3 库文件路径:cache/database/SQLite3/{随机}.db
|
||||
*
|
||||
* @return array{rel:string,abs:string,name:string}
|
||||
*/
|
||||
private function _sqlite3_make_db_file()
|
||||
{
|
||||
try {
|
||||
$name = bin2hex(random_bytes(16)).'.db';
|
||||
} catch (\Throwable $e) {
|
||||
$name = md5(uniqid((string) mt_rand(), true).microtime(true)).'.db';
|
||||
}
|
||||
|
||||
$rel = 'database'.DIRECTORY_SEPARATOR.'SQLite3'.DIRECTORY_SEPARATOR.$name;
|
||||
// 配置与展示统一用正斜杠相对路径(WRITEPATH 拼接时再转系统分隔符)
|
||||
$rel_slash = 'database/SQLite3/'.$name;
|
||||
|
||||
return [
|
||||
'name' => $name,
|
||||
'rel' => $rel_slash,
|
||||
'abs' => WRITEPATH.str_replace('/', DIRECTORY_SEPARATOR, $rel_slash),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 安装阶段数据库引导连接。
|
||||
* 支持 MySQLi / SQLite3;配置写出后再由 CI 驱动执行 Schema/Install.sql。
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
private function _install_db_bootstrap(array $data)
|
||||
{
|
||||
$driver = isset($data['db_driver']) ? $data['db_driver'] : 'MySQLi';
|
||||
|
||||
if ($driver === 'SQLite3') {
|
||||
if (!extension_loaded('sqlite3') || !class_exists('SQLite3', false)) {
|
||||
return dr_return_data(0, dr_lang('PHP环境必须启用SQLite3扩展'));
|
||||
}
|
||||
// cache/database/SQLite3/{随机名}.db,避免固定路径被猜测
|
||||
$info = $this->_sqlite3_make_db_file();
|
||||
$data['db_name'] = $info['rel'];
|
||||
$file = $info['abs'];
|
||||
$dir = dirname($file);
|
||||
if (!is_dir($dir) && !@mkdir($dir, 0755, true)) {
|
||||
return dr_return_data(0, dr_lang('无法创建数据库目录:%s', $dir));
|
||||
}
|
||||
if (!is_writable($dir)) {
|
||||
return dr_return_data(0, dr_lang('数据库目录不可写:%s', $dir));
|
||||
}
|
||||
// 禁止目录浏览
|
||||
if (!is_file($dir.DIRECTORY_SEPARATOR.'index.html')) {
|
||||
@file_put_contents($dir.DIRECTORY_SEPARATOR.'index.html', '');
|
||||
}
|
||||
try {
|
||||
$flags = SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE;
|
||||
$pass = isset($data['db_pass']) ? (string) $data['db_pass'] : '';
|
||||
$db = ($pass !== '')
|
||||
? new \SQLite3($file, $flags, $pass)
|
||||
: new \SQLite3($file, $flags);
|
||||
$db->close();
|
||||
} catch (\Throwable $e) {
|
||||
return dr_return_data(0, dr_lang('无法创建或打开SQLite数据库:%s', $e->getMessage()));
|
||||
}
|
||||
|
||||
return dr_return_data(1, '', $data);
|
||||
}
|
||||
|
||||
if ($driver !== 'MySQLi') {
|
||||
return dr_return_data(0, dr_lang('暂不支持的数据库驱动:%s', $driver));
|
||||
}
|
||||
|
||||
if (!function_exists('mysqli_init')) {
|
||||
return dr_return_data(0, dr_lang('PHP环境必须启用Mysqli扩展'));
|
||||
}
|
||||
|
||||
$mysqli = mysqli_init();
|
||||
if (!$mysqli) {
|
||||
return dr_return_data(0, dr_lang('PHP环境必须启用Mysqli扩展'));
|
||||
}
|
||||
|
||||
if (!@mysqli_real_connect($mysqli, $data['db_host'], $data['db_user'], $data['db_pass'])) {
|
||||
if (SITE_LANGUAGE == 'zh-cn') {
|
||||
return dr_return_data(0, '['.mysqli_connect_errno().'] - 无法连接到数据库服务器('.$data['db_host'].'),请检查用户名('.$data['db_user'].')和密码('.$data['db_pass'].')是否正确');
|
||||
}
|
||||
return dr_return_data(0, mysqli_connect_errno().' '.mysqli_connect_error());
|
||||
}
|
||||
|
||||
if (!mysqli_select_db($mysqli, $data['db_name'])) {
|
||||
if (!mysqli_query($mysqli, 'CREATE DATABASE `'.$data['db_name'].'` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci')) {
|
||||
return dr_return_data(0, dr_lang('指定的数据库(%s)不存在,系统尝试创建失败,请通过其他方式建立数据库', $data['db_name']));
|
||||
}
|
||||
if (!mysqli_select_db($mysqli, $data['db_name'])) {
|
||||
return dr_return_data(0, dr_lang('指定的数据库(%s)不存在,系统尝试创建失败,请通过其他方式建立数据库', $data['db_name']));
|
||||
}
|
||||
}
|
||||
|
||||
if (!mysqli_set_charset($mysqli, 'utf8mb4')) {
|
||||
return dr_return_data(0, dr_lang('当前MySQL不支持utf8mb4编码(%s)建议升级MySQL版本', mysqli_error($mysqli)));
|
||||
}
|
||||
|
||||
return dr_return_data(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 写出 config/database.php(显式包含 DBDriver)
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
private function _write_database_config(array $data)
|
||||
{
|
||||
$driver = isset($data['db_driver']) && $data['db_driver'] ? $data['db_driver'] : 'MySQLi';
|
||||
$prefix = dr_safe_filename($data['db_prefix']);
|
||||
|
||||
if ($driver === 'SQLite3') {
|
||||
// 相对 WRITEPATH:database/SQLite3/{随机}.db
|
||||
$rel = isset($data['db_name']) ? (string) $data['db_name'] : '';
|
||||
if ($rel === '' || (strpos($rel, 'SQLite3/') === false && strpos($rel, 'SQLite3'.DIRECTORY_SEPARATOR) === false)) {
|
||||
$info = $this->_sqlite3_make_db_file();
|
||||
$rel = $info['rel'];
|
||||
$data['db_name'] = $rel;
|
||||
}
|
||||
$rel_fs = str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $rel);
|
||||
$rel_php = str_replace('\\', '\\\\', $rel_fs);
|
||||
$pass = str_replace("'", "\\'", (string) (isset($data['db_pass']) ? $data['db_pass'] : ''));
|
||||
$database = '<?php
|
||||
|
||||
/**
|
||||
* 数据库配置文件(SQLite3)
|
||||
* 库文件目录:cache/database/SQLite3/(文件名安装时随机生成)
|
||||
*/
|
||||
|
||||
$db[\'default\'] = [
|
||||
\'hostname\' => \'\',
|
||||
\'username\' => \'\',
|
||||
\'password\' => \''.$pass.'\',
|
||||
\'database\' => WRITEPATH.\''.$rel_php.'\',
|
||||
\'DBPrefix\' => \''.$prefix.'\',
|
||||
\'DBDriver\' => \'SQLite3\',
|
||||
\'charset\' => \'utf8\',
|
||||
\'DBCollat\' => \'\',
|
||||
];';
|
||||
} else {
|
||||
$database = '<?php
|
||||
|
||||
/**
|
||||
* 数据库配置文件
|
||||
*/
|
||||
|
||||
$db[\'default\'] = [
|
||||
\'hostname\' => \''.str_replace("'", "\\'", $data['db_host']).'\',
|
||||
\'username\' => \''.str_replace("'", "\\'", $data['db_user']).'\',
|
||||
\'password\' => \''.str_replace("'", "\\'", $data['db_pass']).'\',
|
||||
\'database\' => \''.str_replace("'", "\\'", $data['db_name']).'\',
|
||||
\'DBPrefix\' => \''.$prefix.'\',
|
||||
\'DBDriver\' => \'MySQLi\',
|
||||
\'charset\' => \'utf8mb4\',
|
||||
\'DBCollat\' => \'utf8mb4_general_ci\',
|
||||
];';
|
||||
}
|
||||
|
||||
$size = file_put_contents(CONFIGPATH.'database.php', $database);
|
||||
if (!$size || $size < 10) {
|
||||
return dr_return_data(0, dr_lang('数据库配置文件创建失败,config目录无法写入'));
|
||||
}
|
||||
|
||||
return dr_return_data(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将安装 SQL 拆成单条语句。
|
||||
* Install.sql 以 MySQL 方言为源,经 dr_format_create_sql → 驱动 formatCreateSql 转换。
|
||||
* 先统一为 \n 再占位,避免 Windows 换行在 Linux 下经 PHP_EOL 替换后出现双占位符,导致无法按 ; 拆分、多条语句粘成一条执行失败。
|
||||
* 拆分后还原真实换行交给数据库解析,避免逐行剔除 #/-- 时误伤多行字符串内的合法内容。
|
||||
*/
|
||||
private function split_install_sql_statements($sql)
|
||||
{
|
||||
if (!$sql) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$sql = dr_format_create_sql($sql);
|
||||
$sql = str_replace(["\r\n", "\r"], "\n", $sql);
|
||||
$ph = 'SQL_FINECMS_EOL';
|
||||
$sql = str_replace("\n", $ph, $sql);
|
||||
$sql_data = explode(';'.$ph, trim($sql));
|
||||
$rt = [];
|
||||
foreach ($sql_data as $chunk) {
|
||||
$chunk = trim($chunk);
|
||||
if ($chunk === '') {
|
||||
continue;
|
||||
}
|
||||
$rt[] = str_replace($ph, "\n", $chunk);
|
||||
}
|
||||
|
||||
return $rt;
|
||||
}
|
||||
|
||||
// 数据分组
|
||||
private function query_rows($sql, $num = 0)
|
||||
{
|
||||
if (!$sql) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$rt = $this->split_install_sql_statements($sql);
|
||||
|
||||
return $num ? array_chunk($rt, $num) : $rt;
|
||||
}
|
||||
|
||||
// 数据执行
|
||||
private function query($sql)
|
||||
{
|
||||
if (!$sql) {
|
||||
return '';
|
||||
}
|
||||
|
||||
foreach ($this->split_install_sql_statements($sql) as $ret) {
|
||||
if (!$this->db->simpleQuery($ret)) {
|
||||
$rt = $this->db->error();
|
||||
$error = '**************************************************************************'
|
||||
.PHP_EOL.$ret.PHP_EOL.$rt['message'].PHP_EOL;
|
||||
$error.= '**************************************************************************'.PHP_EOL;
|
||||
file_put_contents(WRITEPATH.'install.error', $error.PHP_EOL, FILE_APPEND);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php namespace Phpcmf\Control;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本代码基于MIT开源协议,协议规定此处版权信息不可去除
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
class Show extends \Phpcmf\Home\Module
|
||||
{
|
||||
|
||||
public function index() {
|
||||
|
||||
if (IS_POST) {
|
||||
$this->_json(0, '禁止提交,请检查提交地址是否有误');
|
||||
}
|
||||
|
||||
// 共享模块通过id查找内容
|
||||
$id = (int)\Phpcmf\Service::L('input')->get('id');
|
||||
$row = \Phpcmf\Service::M()->table(SITE_ID.'_share_index')->get($id);
|
||||
|
||||
// 挂钩点
|
||||
$rt2 = \Phpcmf\Hooks::trigger_callback('module_show_share', $row);
|
||||
if ($rt2 && isset($rt2['code']) && $rt2['code']) {
|
||||
$row = $rt2['data'];
|
||||
$id = $row['id'];
|
||||
}
|
||||
$mid = $row['mid'];
|
||||
if (!$mid) {
|
||||
$this->goto_404_page(dr_lang('无法通过id找到共享模块的模块目录'));
|
||||
}
|
||||
|
||||
// 初始化模块
|
||||
$this->_module_init($mid);
|
||||
|
||||
// 调用内容方法
|
||||
$this->_Show($id, null, max(1, (int)\Phpcmf\Service::L('input')->get('page')));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php namespace Phpcmf;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
// 应用公共继承类
|
||||
class App extends \Phpcmf\Common {
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
if (!dr_is_app(APP_DIR)) {
|
||||
if (is_file(APPPATH.'Config/App.php')) {
|
||||
$cfg = require APPPATH.'Config/App.php';
|
||||
$this->_msg(0, dr_lang('应用[%s]未安装', $cfg['name']));
|
||||
} else {
|
||||
$this->_msg(0, dr_lang('应用[%s]未安装', APP_DIR));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,254 @@
|
||||
<?php namespace Phpcmf;
|
||||
|
||||
/**
|
||||
* 自动加载识别程序
|
||||
*/
|
||||
|
||||
class Auto
|
||||
{
|
||||
/**
|
||||
* Stores namespaces as key, and path as values.
|
||||
*
|
||||
* @var array<string, array<string>>
|
||||
*/
|
||||
protected $prefixes = [];
|
||||
|
||||
/**
|
||||
* Stores class name as key, and path as values.
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
protected $classmap = [];
|
||||
|
||||
/**
|
||||
* Stores files as a list.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $files = [];
|
||||
|
||||
/**
|
||||
* Reads in the configuration array (described above) and stores
|
||||
* the valid parts that we'll need.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function initialize($config)
|
||||
{
|
||||
|
||||
if (empty($config->psr4) && empty($config->classmap)) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
if (isset($config->psr4)) {
|
||||
$this->addNamespace($config->psr4);
|
||||
}
|
||||
|
||||
if (isset($config->classmap)) {
|
||||
$this->classmap = $config->classmap;
|
||||
}
|
||||
|
||||
if (isset($config->files)) {
|
||||
$this->files = $config->files;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the loader with the SPL autoloader stack.
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
// Prepend the PSR4 autoloader for maximum performance.
|
||||
spl_autoload_register([$this, 'loadClass'], true, true);
|
||||
|
||||
// Now prepend another loader for the files in our class map.
|
||||
spl_autoload_register([$this, 'loadClassmap'], true, true);
|
||||
|
||||
// Load our non-class files
|
||||
foreach ($this->files as $file) {
|
||||
if (is_string($file)) {
|
||||
$this->includeFile($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers namespaces with the autoloader.
|
||||
*
|
||||
* @param array|string $namespace
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addNamespace($namespace, ?string $path = null)
|
||||
{
|
||||
if (is_array($namespace)) {
|
||||
foreach ($namespace as $prefix => $namespacedPath) {
|
||||
$prefix = trim($prefix, '\\');
|
||||
|
||||
if (is_array($namespacedPath)) {
|
||||
foreach ($namespacedPath as $dir) {
|
||||
$this->prefixes[$prefix][] = rtrim($dir, '\\/') . DIRECTORY_SEPARATOR;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->prefixes[$prefix][] = rtrim($namespacedPath, '\\/') . DIRECTORY_SEPARATOR;
|
||||
}
|
||||
} else {
|
||||
$this->prefixes[trim($namespace, '\\')][] = rtrim($path, '\\/') . DIRECTORY_SEPARATOR;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get namespaces with prefixes as keys and paths as values.
|
||||
*
|
||||
* If a prefix param is set, returns only paths to the given prefix.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getNamespace(?string $prefix = null)
|
||||
{
|
||||
if ($prefix === null) {
|
||||
return $this->prefixes;
|
||||
}
|
||||
|
||||
return $this->prefixes[trim($prefix, '\\')] ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a single namespace from the psr4 settings.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function removeNamespace(string $namespace)
|
||||
{
|
||||
if (isset($this->prefixes[trim($namespace, '\\')])) {
|
||||
unset($this->prefixes[trim($namespace, '\\')]);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a class using available class mapping.
|
||||
*
|
||||
* @return false|string
|
||||
*/
|
||||
public function loadClassmap(string $class)
|
||||
{
|
||||
$file = $this->classmap[$class] ?? '';
|
||||
|
||||
if (is_string($file) && $file !== '') {
|
||||
return $this->includeFile($file);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the class file for a given class name.
|
||||
*
|
||||
* @param string $class The fully qualified class name.
|
||||
*
|
||||
* @return false|string The mapped file on success, or boolean false
|
||||
* on failure.
|
||||
*/
|
||||
public function loadClass(string $class)
|
||||
{
|
||||
$class = trim($class, '\\');
|
||||
$class = str_ireplace('.php', '', $class);
|
||||
|
||||
return $this->loadInNamespace($class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the class file for a given class name.
|
||||
*
|
||||
* @param string $class The fully-qualified class name
|
||||
*
|
||||
* @return false|string The mapped file name on success, or boolean false on fail
|
||||
*/
|
||||
protected function loadInNamespace(string $class)
|
||||
{
|
||||
if (strpos($class, '\\') === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($this->prefixes as $namespace => $directories) {
|
||||
foreach ($directories as $directory) {
|
||||
$directory = rtrim($directory, '\\/');
|
||||
|
||||
if (strpos($class, $namespace) === 0) {
|
||||
$filePath = $directory . str_replace('\\', DIRECTORY_SEPARATOR, substr($class, strlen($namespace))) . '.php';
|
||||
$filename = $this->includeFile($filePath);
|
||||
|
||||
if ($filename) {
|
||||
return $filename;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// never found a mapped file
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* A central way to include a file. Split out primarily for testing purposes.
|
||||
*
|
||||
* @return false|string The filename on success, false if the file is not loaded
|
||||
*/
|
||||
protected function includeFile(string $file)
|
||||
{
|
||||
$file = $this->sanitizeFilename($file);
|
||||
|
||||
if (is_file($file)) {
|
||||
include_once $file;
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes a filename, replacing spaces with dashes.
|
||||
*
|
||||
* Removes special characters that are illegal in filenames on certain
|
||||
* operating systems and special characters requiring special escaping
|
||||
* to manipulate at the command line. Replaces spaces and consecutive
|
||||
* dashes with a single dash. Trim period, dash and underscore from beginning
|
||||
* and end of filename.
|
||||
*
|
||||
* @return string The sanitized filename
|
||||
*/
|
||||
public function sanitizeFilename(string $filename): string
|
||||
{
|
||||
// Only allow characters deemed safe for POSIX portable filenames.
|
||||
// Plus the forward slash for directory separators since this might be a path.
|
||||
// http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_278
|
||||
// Modified to allow backslash and colons for on Windows machines.
|
||||
$filename = preg_replace('/[^0-9\p{L}\s\/\-\_\.\:\\\\]/u', '', $filename);
|
||||
|
||||
// Clean up our filename edges.
|
||||
return trim($filename, '.-_');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 自动加载配置文件
|
||||
*/
|
||||
class AutoConfig
|
||||
{
|
||||
|
||||
public $psr4 = [];
|
||||
|
||||
public $classmap = [];
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,357 @@
|
||||
<?php namespace Phpcmf;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
define('EVENT_PRIORITY_LOW', 200);
|
||||
define('EVENT_PRIORITY_NORMAL', 10);
|
||||
define('EVENT_PRIORITY_HIGH', 10);
|
||||
|
||||
/**
|
||||
* 钩子类
|
||||
*/
|
||||
class Hooks {
|
||||
|
||||
protected static $initialized_hook = false;
|
||||
|
||||
/**
|
||||
* The list of listeners.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $listeners = [];
|
||||
|
||||
/**
|
||||
* Flag to let us know if we've read from the Config file(s)
|
||||
* and have all of the defined events.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected static $initialized = false;
|
||||
|
||||
/**
|
||||
* If true, events will not actually be fired.
|
||||
* Useful during testing.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected static $simulate = false;
|
||||
|
||||
/**
|
||||
* Stores information about the events
|
||||
* for display in the debug toolbar.
|
||||
*
|
||||
* @var array<array<string, float|string>>
|
||||
*/
|
||||
protected static $performanceLog = [];
|
||||
|
||||
/**
|
||||
* A list of found files.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected static $files = [];
|
||||
|
||||
/**
|
||||
* 重定义钩子类
|
||||
*/
|
||||
public static function initialize()
|
||||
{
|
||||
// 防止重复加载
|
||||
if (static::$initialized_hook)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 框架主钩子
|
||||
require CONFIGPATH.'hooks.php';
|
||||
|
||||
if (is_file(FRAMEPATH.'Extend/Hook.php')) {
|
||||
require FRAMEPATH.'Extend/Hook.php';
|
||||
}
|
||||
|
||||
static::$initialized = true;
|
||||
static::$initialized_hook = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers an action to happen on an event. The action can be any sort
|
||||
* of callable:
|
||||
*
|
||||
* Events::on('create', 'myFunction'); // procedural function
|
||||
* Events::on('create', ['myClass', 'myMethod']); // Class::method
|
||||
* Events::on('create', [$myInstance, 'myMethod']); // Method on an existing instance
|
||||
* Events::on('create', function() {}); // Closure
|
||||
*
|
||||
* @param string $eventName
|
||||
* @param callable $callback
|
||||
* @param int $priority
|
||||
*/
|
||||
public static function on($eventName, $callback, $priority = EVENT_PRIORITY_NORMAL)
|
||||
{
|
||||
if (! isset(static::$listeners[$eventName])) {
|
||||
static::$listeners[$eventName] = [
|
||||
true, // If there's only 1 item, it's sorted.
|
||||
[$priority],
|
||||
[$callback],
|
||||
];
|
||||
} else {
|
||||
static::$listeners[$eventName][0] = false; // Not sorted
|
||||
static::$listeners[$eventName][1][] = $priority;
|
||||
static::$listeners[$eventName][2][] = $callback;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes a single listener from an event.
|
||||
*
|
||||
* If the listener couldn't be found, returns FALSE, else TRUE if
|
||||
* it was removed.
|
||||
*
|
||||
* @param string $eventName
|
||||
*/
|
||||
public static function removeListener($eventName, callable $listener): bool
|
||||
{
|
||||
if (! isset(static::$listeners[$eventName])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (static::$listeners[$eventName][2] as $index => $check) {
|
||||
if ($check === $listener) {
|
||||
unset(
|
||||
static::$listeners[$eventName][1][$index],
|
||||
static::$listeners[$eventName][2][$index]
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all listeners.
|
||||
*
|
||||
* If the event_name is specified, only listeners for that event will be
|
||||
* removed, otherwise all listeners for all events are removed.
|
||||
*
|
||||
* @param string|null $eventName
|
||||
*/
|
||||
public static function removeAllListeners($eventName = null)
|
||||
{
|
||||
if ($eventName !== null) {
|
||||
unset(static::$listeners[$eventName]);
|
||||
} else {
|
||||
static::$listeners = [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the path to the file that routes are read from.
|
||||
*/
|
||||
public static function setFiles(array $files)
|
||||
{
|
||||
static::$files = $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the files that were found/loaded during this request.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getFiles()
|
||||
{
|
||||
return static::$files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns simulation on or off. When on, events will not be triggered,
|
||||
* simply logged. Useful during testing when you don't actually want
|
||||
* the tests to run.
|
||||
*/
|
||||
public static function simulate(bool $choice = true)
|
||||
{
|
||||
static::$simulate = $choice;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the performance log records.
|
||||
*
|
||||
* @return array<array<string, float|string>>
|
||||
*/
|
||||
public static function getPerformanceLogs()
|
||||
{
|
||||
return static::$performanceLog;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 插件中注册钩子
|
||||
*/
|
||||
public static function app_on($app, $eventName, $callback, $priority = EVENT_PRIORITY_NORMAL)
|
||||
{
|
||||
if (! isset(static::$listeners[$eventName])) {
|
||||
static::$listeners[$eventName] = [
|
||||
true, // If there's only 1 item, it's sorted.
|
||||
[$priority],
|
||||
[$callback],
|
||||
[$app],
|
||||
];
|
||||
} else {
|
||||
static::$listeners[$eventName][0] = false; // Not sorted
|
||||
static::$listeners[$eventName][1][] = $priority;
|
||||
static::$listeners[$eventName][2][] = $callback;
|
||||
static::$listeners[$eventName][3][] = $app;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of listeners for a single event. They are
|
||||
* sorted by priority.
|
||||
*
|
||||
* @param string $eventName
|
||||
*/
|
||||
public static function listeners($eventName): array
|
||||
{
|
||||
if (! isset(static::$listeners[$eventName])) {
|
||||
return [[], []];
|
||||
}
|
||||
|
||||
// The list is not sorted
|
||||
if (! static::$listeners[$eventName][0]) {
|
||||
// Sort it!
|
||||
array_multisort(static::$listeners[$eventName][1], SORT_NUMERIC, static::$listeners[$eventName][2]);
|
||||
|
||||
// Mark it as sorted already!
|
||||
static::$listeners[$eventName][0] = true;
|
||||
}
|
||||
|
||||
return [static::$listeners[$eventName][2], static::$listeners[$eventName][3]];
|
||||
}
|
||||
|
||||
/**
|
||||
* 运行带返回参数的钩子点,其中某个钩子返回值时终止运行
|
||||
*
|
||||
* @param string $eventName
|
||||
* @param mixed $arguments
|
||||
*
|
||||
* @return boolean | array
|
||||
*/
|
||||
public static function trigger_callback($eventName, ...$arguments)
|
||||
{
|
||||
|
||||
if (! static::$initialized)
|
||||
{
|
||||
static::initialize();
|
||||
}
|
||||
|
||||
list($listeners, $apps) = static::listeners($eventName);
|
||||
if (!$listeners) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$msg = '';
|
||||
$data = [];
|
||||
$is_rt = 0;
|
||||
|
||||
foreach ($listeners as $k => $listener) {
|
||||
|
||||
if (IS_POST && CI_DEBUG && !in_array($eventName, ['DBQuery', 'pre_system'])) {
|
||||
log_message('debug', ($apps && isset($apps[$k]) ? '插件【'.$apps[$k].'】' : '' ).'运行钩子【'.$eventName.'】');
|
||||
}
|
||||
|
||||
$start = microtime(true);
|
||||
$rt = call_user_func($listener, ...$arguments);
|
||||
|
||||
if (CI_DEBUG)
|
||||
{
|
||||
static::$performanceLog[] = [
|
||||
'start' => $start,
|
||||
'end' => microtime(true),
|
||||
'event' => strtolower($eventName),
|
||||
];
|
||||
}
|
||||
|
||||
if ($rt && isset($rt['code'])) {
|
||||
if ($rt['code'] == 0) {
|
||||
// 只要遇到返回成功的钩子就中断执行直接返回
|
||||
return $rt;
|
||||
}
|
||||
$msg = $rt['msg'];
|
||||
if (is_array($rt['data'])) {
|
||||
if (is_array($data)) {
|
||||
$data = dr_array22array($data, $rt['data']);
|
||||
} else {
|
||||
$data = $rt['data'];
|
||||
}
|
||||
} else {
|
||||
$data = $rt['data'];
|
||||
}
|
||||
if ($msg == 'merge') {
|
||||
$arguments[0] = dr_array22array($arguments[0], $data);
|
||||
}
|
||||
$is_rt = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ($is_rt) {
|
||||
return dr_return_data(1, $msg, $data);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 运行不带返回参数的钩子点
|
||||
*
|
||||
* @param string $eventName
|
||||
* @param mixed $arguments
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function trigger($eventName, ...$arguments): bool
|
||||
{
|
||||
// Read in our Config/Events file so that we have them all!
|
||||
if (! static::$initialized)
|
||||
{
|
||||
static::initialize();
|
||||
}
|
||||
|
||||
list($listeners, $apps) = static::listeners($eventName);
|
||||
if (!$listeners) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($listeners as $k => $listener) {
|
||||
|
||||
if (IS_POST && CI_DEBUG && !in_array($eventName, ['DBQuery', 'pre_system'])) {
|
||||
log_message('debug', ($apps && isset($apps[$k]) ? '插件【'.$apps[$k].'】' : '' ).'运行钩子【'.$eventName.'】');
|
||||
}
|
||||
|
||||
$start = microtime(true);
|
||||
$result = static::$simulate === false ? call_user_func($listener, ...$arguments) : true;
|
||||
|
||||
if (CI_DEBUG)
|
||||
{
|
||||
static::$performanceLog[] = [
|
||||
'start' => $start,
|
||||
'end' => microtime(true),
|
||||
'event' => strtolower($eventName),
|
||||
];
|
||||
}
|
||||
|
||||
if ($result === false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,543 @@
|
||||
<?php namespace Phpcmf;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
**/
|
||||
|
||||
class Service {
|
||||
|
||||
static private $instances = [];
|
||||
static private $help = [];
|
||||
static private $logs = [];
|
||||
static private $view;
|
||||
static private $model;
|
||||
static private $require;
|
||||
static private $apps = [
|
||||
1 => [],
|
||||
0 => [],
|
||||
];
|
||||
static private $mwhere_apps = [];
|
||||
static private $filters = [
|
||||
'home' => [
|
||||
'install/index',
|
||||
'api/ueditor',
|
||||
],
|
||||
'member' => [
|
||||
'api/ueditor',
|
||||
],
|
||||
'admin' => [
|
||||
'api/ueditor',
|
||||
],
|
||||
];
|
||||
static private $license = [];
|
||||
|
||||
// 获取应用自动加载
|
||||
public static function Auto($auto) {
|
||||
|
||||
$auto->psr4 = array_merge($auto->psr4, [
|
||||
|
||||
'Phpcmf\Controllers' => APPPATH.'Controllers',
|
||||
|
||||
'Phpcmf\Control' => CMSPATH.'Control',
|
||||
'Phpcmf\Extend' => FRAMEPATH.'Extend',
|
||||
'Phpcmf\Library' => CMSPATH.'Library',
|
||||
'Phpcmf\Field' => CMSPATH.'Field',
|
||||
'Phpcmf\ThirdParty' => FCPATH.'ThirdParty',
|
||||
|
||||
'My\Field' => MYPATH.'Field',
|
||||
'My\Library' => MYPATH.'Library',
|
||||
'My\Model' => MYPATH.'Model',
|
||||
]);
|
||||
|
||||
$classmap = [
|
||||
'Phpcmf\App' => CMSPATH.'Core/App.php',
|
||||
'Phpcmf\Table' => CMSPATH.'Core/Table.php',
|
||||
'Phpcmf\Model' => CMSPATH.'Core/Model.php',
|
||||
'Phpcmf\View' => CMSPATH.'Core/View.php',
|
||||
'Phpcmf\Common' => CMSPATH.'Core/Common.php',
|
||||
];
|
||||
|
||||
if (IS_USE_MODULE) {
|
||||
$classmap['Phpcmf\Home\Module'] = IS_USE_MODULE.'Extends/Home/Module.php';
|
||||
$classmap['Phpcmf\Admin\Config'] = IS_USE_MODULE.'Extends/Admin/Config.php';
|
||||
$classmap['Phpcmf\Admin\Module'] = IS_USE_MODULE.'Extends/Admin/Module.php';
|
||||
$classmap['Phpcmf\Model\Content'] = IS_USE_MODULE.'Models/Content.php';
|
||||
$classmap['Phpcmf\Model\Search'] = IS_USE_MODULE.'Models/Search.php';
|
||||
$classmap['Phpcmf\Admin\Category'] = IS_USE_MODULE.'Extends/Admin/Category.php';
|
||||
if (IS_USE_MEMBER) {
|
||||
$classmap['Phpcmf\Member\Module'] = IS_USE_MODULE.'Extends/Member/Module.php';
|
||||
}
|
||||
}
|
||||
|
||||
$auto->classmap = array_merge($auto->classmap, $classmap);
|
||||
|
||||
$local = \Phpcmf\Service::Apps();
|
||||
if ($local) {
|
||||
foreach ($local as $dir => $path) {
|
||||
if (!is_file($path.'install.lock')) {
|
||||
continue;
|
||||
}
|
||||
if (is_file($path.'Config/Auto.php')) {
|
||||
$app_auto = require $path.'Config/Auto.php';
|
||||
isset($app_auto['psr4']) && $app_auto['psr4'] && $auto->psr4 = array_merge($auto->psr4, $app_auto['psr4']);
|
||||
isset($app_auto['classmap']) && $app_auto['classmap'] && $auto->classmap = array_merge($auto->classmap, $app_auto['classmap']);
|
||||
unset($app_auto);
|
||||
}
|
||||
// 加载钩子
|
||||
if (is_file($path.'Config/Hooks.php')) {
|
||||
require $path.'Config/Hooks.php';
|
||||
}
|
||||
// 判断是否存在自定义where
|
||||
if (is_file($path.'Config/Mwhere.php')) {
|
||||
\Phpcmf\Service::Set_Mwhere_App($dir);
|
||||
}
|
||||
// 判断是否存在CSRF白名单
|
||||
if (is_file($path.'Config/Filters.php')) {
|
||||
$Filters = require $path.'Config/Filters.php';
|
||||
if ($Filters) {
|
||||
$Filters['home'] && static::$filters['home'] = array_merge(static::$filters['home'], $Filters['home']);
|
||||
$Filters['member'] && static::$filters['member'] = array_merge(static::$filters['member'], $Filters['member']);
|
||||
$Filters['admin'] && static::$filters['admin'] = array_merge(static::$filters['admin'], $Filters['admin']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $auto;
|
||||
}
|
||||
|
||||
// 获取应用目录
|
||||
public static function Apps($is_install = 0) {
|
||||
|
||||
$is_install = $is_install ? 1 : 0;
|
||||
|
||||
if (isset(static::$apps[$is_install]) && static::$apps[$is_install]) {
|
||||
return static::$apps[$is_install];
|
||||
}
|
||||
|
||||
static::$apps[$is_install] = [];
|
||||
$source_dir = dr_get_app_list();
|
||||
if ($fp = opendir($source_dir)) {
|
||||
while (FALSE !== ($file = readdir($fp))) {
|
||||
$path = dr_get_app_dir($file);
|
||||
if ($file === '.'
|
||||
OR $file === '..'
|
||||
OR $file === 'Module'
|
||||
OR $file[0] === '.'
|
||||
OR !is_dir($path)) {
|
||||
continue;
|
||||
}
|
||||
if ($is_install && !is_file($path . 'install.lock')) {
|
||||
continue;
|
||||
}
|
||||
static::$apps[$is_install][$file] = $path;
|
||||
}
|
||||
closedir($fp);
|
||||
}
|
||||
|
||||
if (function_exists('dr_get_app_extend')) {
|
||||
$extend = dr_get_app_extend($is_install);
|
||||
if ($extend) {
|
||||
foreach ($extend as $i => $t) {
|
||||
static::$apps[$is_install][$i] = $t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return static::$apps[$is_install];
|
||||
}
|
||||
|
||||
// 设置mwhere的插件名称
|
||||
public static function Set_Mwhere_App($dir) {
|
||||
static::$mwhere_apps[] = $dir;
|
||||
}
|
||||
|
||||
// 读取mwhere插件名称列表
|
||||
public static function Mwhere_Apps() {
|
||||
return static::$mwhere_apps;
|
||||
}
|
||||
|
||||
// 读取Filters白名单
|
||||
public static function Filters($type = 'auto') {
|
||||
|
||||
if ($type == 'auto') {
|
||||
if (IS_ADMIN) {
|
||||
$type = 'admin';
|
||||
} elseif (IS_MEMBER) {
|
||||
$type = 'member';
|
||||
} else {
|
||||
$type = 'home';
|
||||
}
|
||||
} elseif ($type == '') {
|
||||
return static::$filters;
|
||||
}
|
||||
|
||||
return isset(static::$filters[$type]) ? static::$filters[$type] : [];
|
||||
}
|
||||
|
||||
// 是否是电脑端模板
|
||||
public static function IS_PC_TPL() {
|
||||
return static::V()->is_pc();
|
||||
}
|
||||
public static function IS_PC() {
|
||||
return static::V()->is_pc();
|
||||
}
|
||||
|
||||
// 是否是移动端模板
|
||||
public static function IS_MOBILE_TPL() {
|
||||
return static::V()->is_mobile();
|
||||
}
|
||||
public static function IS_MOBILE() {
|
||||
return static::V()->is_mobile();
|
||||
}
|
||||
|
||||
// 当前客户端是否是移动端访问
|
||||
public static function IS_MOBILE_USER() {
|
||||
return dr_is_mobile();
|
||||
}
|
||||
public static function _is_mobile() {
|
||||
return dr_is_mobile();
|
||||
}
|
||||
|
||||
// 当前客户端是否是PC端访问
|
||||
public static function IS_PC_USER() {
|
||||
return !dr_is_mobile();
|
||||
}
|
||||
|
||||
// 错误日志记录
|
||||
public static function Log($level, $message, array $context = []) {
|
||||
|
||||
if ($level == 'debug' && defined('IS_FB_DEBUG') && IS_FB_DEBUG) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_object($message)) {
|
||||
|
||||
$msg = substr((string)$message->getMessage(), 0, 1048576);
|
||||
$code = md5($msg);
|
||||
|
||||
if (is_array( static::$logs) && in_array($code, static::$logs)) {
|
||||
return;
|
||||
}
|
||||
|
||||
static::$logs[] = $code;
|
||||
|
||||
$context['trace'] = $message->getTraceAsString();
|
||||
$context['sql'] = \Phpcmf\Service::M()->get_sql_query();
|
||||
$context['url'] = FC_NOW_URL;
|
||||
$context['user'] = dr_safe_replace($_SERVER['HTTP_USER_AGENT']);
|
||||
$context['referer'] = dr_safe_url($_SERVER['HTTP_REFERER'], true);
|
||||
|
||||
return \Phpcmf\Service::L('input')->log($level, $msg."\n#SQL:{sql}\n#URL:{url}\n#AGENT:{user}\n".($context['referer'] ? "#REFERER:{referer}\n" : "")."{trace}\n", $context);
|
||||
}
|
||||
|
||||
$message.= '---'.FC_NOW_URL.PHP_EOL;
|
||||
return \Phpcmf\Service::L('input')->log($level, $message, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* 模型类对象实例
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
public static function model() {
|
||||
|
||||
if (!is_object(static::$model)) {
|
||||
static::$model = new \Phpcmf\Model();
|
||||
}
|
||||
|
||||
return static::$model;
|
||||
}
|
||||
|
||||
/**
|
||||
* 控制器对象实例
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
public static function C() {
|
||||
return class_exists('\Phpcmf\Common') ? \Phpcmf\Common::get_instance() : null;
|
||||
}
|
||||
|
||||
|
||||
public static function LIC($type = '') {
|
||||
|
||||
if (defined('IS_XRDEV') && IS_XRDEV) {
|
||||
return $type ? 'DR-DEV' : 'DR-DEV';
|
||||
}
|
||||
|
||||
$version = static::R(MYPATH.'Config/Version.php');
|
||||
if ($version && is_array($version)) {
|
||||
if (isset($version['version']) && isset($version['id'])
|
||||
&& is_string($version['version'])
|
||||
&& intval(substr($version['version'], -1)) % 2 == 1
|
||||
&& in_array($version['id'], [18, 16])
|
||||
) {
|
||||
$lic = static::R(MYPATH.'Config/License.php');
|
||||
if ($lic && is_array($lic)) {
|
||||
if (isset($lic['type']) && $lic['type']) {
|
||||
return $type ? (stripos($lic['type'], $type) === false ? '' : $lic['type']) : $lic['type'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $type ? '' : 'MIT-LICENSE';
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件内容
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
public static function R($file, $clear = false) {
|
||||
|
||||
$_cname = md5($file);
|
||||
|
||||
if (!$clear) {
|
||||
if (isset(static::$require[$_cname])) {
|
||||
return static::$require[$_cname];
|
||||
} elseif (!is_file($file)) {
|
||||
//CI_DEBUG && log_message('debug', '引用文件不存在:'.$file);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static::$require[$_cname] = require $file;
|
||||
|
||||
return static::$require[$_cname];
|
||||
}
|
||||
|
||||
/**
|
||||
* 模板视图对象实例
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
public static function V() {
|
||||
|
||||
if (!is_object(static::$view)) {
|
||||
static::$view = new \Phpcmf\View();
|
||||
}
|
||||
|
||||
return static::$view;
|
||||
}
|
||||
|
||||
/**
|
||||
* 类对象实例
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
public static function L($name, $namespace = '') {
|
||||
|
||||
if (IS_USE_CMS && $namespace == 'module') {
|
||||
$namespace = 'cms';
|
||||
}
|
||||
|
||||
list($classFile, $extendFile, $appFile) = self::_get_class_file($name, $namespace, 'Library');
|
||||
|
||||
$_cname = md5($classFile.$extendFile.$appFile);
|
||||
$className = ucfirst($name);
|
||||
|
||||
if (!isset(static::$instances[$_cname]) or !is_object(static::$instances[$_cname])) {
|
||||
require_once $classFile;
|
||||
// 自定义继承类
|
||||
if ($extendFile && is_file($extendFile)) {
|
||||
if ($namespace && is_file($appFile)) {
|
||||
require $appFile;
|
||||
$newClassName = '\\Phpcmf\\Library\\'.ucfirst($namespace).'\\'.$className;
|
||||
} else {
|
||||
require $extendFile;
|
||||
$newClassName = '\\My\\Library\\'.$className;
|
||||
}
|
||||
} else {
|
||||
$newClassName = '\\Phpcmf\\Library\\'.$className;
|
||||
// 多个应用引用同一个类名称时的区别
|
||||
if ($namespace) {
|
||||
$newClassName2 = '\\Phpcmf\\Library\\'.ucfirst($namespace).'\\'.$className;
|
||||
if (class_exists($newClassName2)) {
|
||||
static::$instances[$_cname] = new $newClassName2();
|
||||
return static::$instances[$_cname];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static::$instances[$_cname] = new $newClassName();
|
||||
}
|
||||
|
||||
return static::$instances[$_cname];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 模型对象实例
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
public static function M($name = '', $namespace = '') {
|
||||
|
||||
if (!$name) {
|
||||
return static::model();
|
||||
}
|
||||
|
||||
$className = ucfirst($name);
|
||||
if (!$namespace) {
|
||||
switch ($className) {
|
||||
|
||||
case 'Content':
|
||||
if (!IS_USE_MODULE) {
|
||||
\dr_exit_msg(0, '没有安装「建站系统」插件');
|
||||
}
|
||||
$namespace = 'cms';
|
||||
break;
|
||||
|
||||
case 'Search':
|
||||
if (!IS_USE_MODULE) {
|
||||
\dr_exit_msg(0, '没有安装「建站系统」插件');
|
||||
}
|
||||
$namespace = 'cms';
|
||||
break;
|
||||
|
||||
case 'Category':
|
||||
if (!IS_USE_MODULE) {
|
||||
\dr_exit_msg(0, '没有安装「建站系统」插件');
|
||||
}
|
||||
$namespace = 'cms';
|
||||
break;
|
||||
|
||||
case 'Module':
|
||||
if (!IS_USE_MODULE) {
|
||||
\dr_exit_msg(0, '没有安装「建站系统」插件');
|
||||
}
|
||||
$namespace = 'cms';
|
||||
break;
|
||||
|
||||
case 'Pay':
|
||||
if (!dr_is_app('pay')) {
|
||||
\dr_exit_msg(0, '没有安装「支付系统」插件');
|
||||
}
|
||||
$namespace = 'pay';
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (IS_USE_MODULE && in_array($className, ['Content', 'Search'])
|
||||
&& !is_file(dr_get_app_dir($namespace).'Models/'.$className.'.php')) {
|
||||
$namespace = 'cms';
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_USE_CMS && $namespace == 'module') {
|
||||
$namespace = 'cms';
|
||||
}
|
||||
|
||||
list($classFile, $extendFile, $appFile) = self::_get_class_file($name, $namespace, 'Model');
|
||||
|
||||
$_cname = md5($classFile.$extendFile.$appFile);
|
||||
|
||||
if (!isset(static::$instances[$_cname]) or !is_object(static::$instances[$_cname])) {
|
||||
require_once $classFile;
|
||||
// 自定义继承类
|
||||
if ($extendFile && is_file($extendFile)) {
|
||||
if ($namespace && is_file($appFile)) {
|
||||
require_once $appFile;
|
||||
$newClassName = '\\Phpcmf\\Model\\'.ucfirst($namespace).'\\'.$className;
|
||||
} else {
|
||||
require $extendFile;
|
||||
$newClassName = '\\My\\Model\\'.$className;
|
||||
}
|
||||
} else {
|
||||
$newClassName = '\\Phpcmf\\Model\\'.$className;
|
||||
// 多个应用引用同一个类名称时的区别
|
||||
if ($namespace) {
|
||||
$newClassName2 = '\\Phpcmf\\Model\\'.ucfirst($namespace).'\\'.$className;
|
||||
if (class_exists($newClassName2)) {
|
||||
static::$instances[$_cname] = new $newClassName2();
|
||||
return static::$instances[$_cname];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static::$instances[$_cname] = new $newClassName();
|
||||
}
|
||||
|
||||
return static::$instances[$_cname];
|
||||
}
|
||||
|
||||
/**
|
||||
* 引用应用的helper
|
||||
*/
|
||||
public static function H($name, $namespace) {
|
||||
|
||||
if (IS_USE_CMS && $namespace == 'module') {
|
||||
$namespace = 'cms';
|
||||
}
|
||||
|
||||
$file = dr_get_app_dir($namespace).'Helpers/'.ucfirst($name).'.php';
|
||||
$_cname = md5($file);
|
||||
if (isset(static::$help[$_cname])) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_file($file)) {
|
||||
self::_error('函数文件:'.str_replace(FCPATH, '', $file).'不存在');
|
||||
}
|
||||
|
||||
static::$help[$_cname] = 1;
|
||||
|
||||
require $file;
|
||||
}
|
||||
|
||||
// 获取类文件路径
|
||||
private static function _get_class_file($name, $namespace, $class) {
|
||||
|
||||
$className = ucfirst($name);
|
||||
$classFile = CMSPATH.$class.'/'.$className.'.php';
|
||||
|
||||
// 自定义继承类文件
|
||||
$extendFile = MYPATH.$class.'/'.$className.'.php';
|
||||
|
||||
// 当前是app时优先考虑本级继承目录文件
|
||||
if ($namespace) {
|
||||
if (IS_USE_CMS && $namespace == 'module') {
|
||||
$namespace = 'cms';
|
||||
}
|
||||
$appFile = dr_get_app_dir($namespace).($class == 'Library' ? 'Librarie' : $class ).'s/'.$className.'.php';
|
||||
} else {
|
||||
$appFile = '';
|
||||
}
|
||||
|
||||
if (!is_file($extendFile) && $namespace) {
|
||||
// 当前是app时优先考虑本级继承目录文件
|
||||
$extendFile = $appFile;
|
||||
}
|
||||
|
||||
if (!is_file($classFile)) {
|
||||
// 相对于APP目录
|
||||
if ($namespace) {
|
||||
$classFile = $appFile;
|
||||
$extendFile = '';
|
||||
} else if (is_file($extendFile)) {
|
||||
$classFile = $extendFile;
|
||||
$extendFile = '';
|
||||
}
|
||||
// 都不存在就报错
|
||||
if (!$classFile || !is_file($classFile)) {
|
||||
self::_error('类文件:'.str_replace(FCPATH, '', $classFile).'不存在');
|
||||
}
|
||||
}
|
||||
|
||||
return [$classFile, $extendFile, $appFile];
|
||||
}
|
||||
|
||||
// 错误输出
|
||||
private static function _error($msg) {
|
||||
|
||||
if (defined('IS_API_HTTP') && IS_API_HTTP) {
|
||||
log_message('error', $msg . '('.FC_NOW_URL.')');
|
||||
\Phpcmf\Service::C()->_json(0, $msg); // api输出格式
|
||||
} else {
|
||||
// 报系统故障
|
||||
dr_show_error($msg);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,128 @@
|
||||
<?php namespace Phpcmf\Field;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本代码基于MIT开源协议,协议规定此处版权信息不可去除
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
class Cat extends \Phpcmf\Library\A_Field {
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
public function __construct(...$params) {
|
||||
parent::__construct(...$params);
|
||||
$this->fieldtype = ['INT' => 10];
|
||||
$this->defaulttype = 'INT';
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段相关属性参数
|
||||
*
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function option($option) {
|
||||
|
||||
$_option = '';
|
||||
$_module = \Phpcmf\Service::C()->get_cache('module-'.SITE_ID.'-content');
|
||||
if ($_module) {
|
||||
$_option.= '<option value="share" '.('share' == $option['module'] ? 'selected' : '').'>'.dr_lang('共享栏目').'</option>';
|
||||
foreach ($_module as $dir => $t) {
|
||||
if (!$t['share']) {
|
||||
$_option.= '<option value="'.$dir.'" '.($dir == $option['module'] ? 'selected' : '').'>'.$t['name'].'</option>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ['<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('内容模块').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><select class="form-control" name="data[setting][option][module]">
|
||||
'.$_option.'
|
||||
</select></label>
|
||||
<span class="help-block">'.dr_lang('必须选择一个模块作为栏目的数据源').'</span>
|
||||
</div>
|
||||
</div><div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('选择父栏目').'</label>
|
||||
<div class="col-md-9">
|
||||
<input type="checkbox" name="data[setting][option][parent]" '.($option['parent'] ? 'checked' : '').' value="1" data-on-text="'.dr_lang('已开启').'" data-off-text="'.dr_lang('已关闭').'" data-on-color="success" data-off-color="danger" class="make-switch" data-size="small">
|
||||
<span class="help-block">'.dr_lang('开启之后可以选择父级栏目').'</span>
|
||||
</div>
|
||||
</div><div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('启用选项搜索').'</label>
|
||||
<div class="col-md-9">
|
||||
<input type="checkbox" name="data[setting][option][is_search]" '.($option['is_search'] ? 'checked' : '').' value="1" data-on-text="'.dr_lang('已开启').'" data-off-text="'.dr_lang('已关闭').'" data-on-color="success" data-off-color="danger" class="make-switch" data-size="small">
|
||||
|
||||
<span class="help-block">'.dr_lang('当选项值过多时,可以在选择框中搜索选项值').'</span>
|
||||
</div>
|
||||
</div>', ''];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 字段输出
|
||||
*/
|
||||
public function output($value) {
|
||||
return intval($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段入库值
|
||||
*
|
||||
* @param array $field 字段信息
|
||||
* @return void
|
||||
*/
|
||||
public function insert_value($field) {
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname']] = intval(\Phpcmf\Service::L('Field')->post[$field['fieldname']]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单输入
|
||||
*
|
||||
* @param string $field 字段数组
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function input($field, $value = null) {
|
||||
|
||||
// 字段禁止修改时就返回显示字符串
|
||||
if ($this->_not_edit($field, $value)) {
|
||||
return $this->show($field, $value);
|
||||
}
|
||||
|
||||
// 字段存储名称
|
||||
$name = $field['fieldname'];
|
||||
|
||||
// 字段显示名称
|
||||
$text = ($field['setting']['validate']['required'] ? '<span class="required" aria-required="true"> * </span>' : '').dr_lang($field['name']);
|
||||
|
||||
// 字段提示信息
|
||||
$tips = ($name == 'title' && APP_DIR) || $field['setting']['validate']['tips'] ? '<span class="help-block" id="dr_'.$field['fieldname'].'_tips">'.$field['setting']['validate']['tips'].'</span>' : '';
|
||||
|
||||
// 开始输出
|
||||
$str = '';
|
||||
$str.= '<label style="min-width: 200px">'.\Phpcmf\Service::L('category', 'module')->select(
|
||||
$field['setting']['option']['module'],
|
||||
intval($value),
|
||||
' name=\'data['.$field['fieldname'].']\' data-actions-box="true" '.(isset($field['setting']['option']['is_search']) && $field['setting']['option']['is_search'] ? ' data-live-search="true" ' : ''),
|
||||
'', (isset($field['setting']['option']['parent']) && $field['setting']['option']['parent'] ? 0 : 1), 0
|
||||
).'</label>';
|
||||
$str.= '<span class="help-block">'.$tips.'</span>';
|
||||
return $this->input_format($name, $text, $str);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单显示
|
||||
*
|
||||
* @param string $field 字段数组
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function show($field, $value = null) {
|
||||
|
||||
return $this->input_format($field['fieldname'], $field['name'], '<div class="form-control-static">'.dr_catpos($value, ' - ', false, '', $field['setting']['option']['module']).'</div>');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
<?php namespace Phpcmf\Field;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本代码基于MIT开源协议,协议规定此处版权信息不可去除
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
class Catids extends \Phpcmf\Library\A_Field {
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
public function __construct(...$params) {
|
||||
parent::__construct(...$params);
|
||||
$this->fieldtype = ['TEXT' => ''];
|
||||
$this->defaulttype = 'TEXT';
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段相关属性参数
|
||||
*
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function option($option) {
|
||||
|
||||
|
||||
return ['
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('重要提醒').'</label>
|
||||
<div class="col-md-9"><label class="form-control-static">本字段名一定要是catids才能参与搜索</label></div>
|
||||
</div>
|
||||
', '<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('控件宽度').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" size="10" name="data[setting][option][width]" value="'.$option['width'].'"></label>
|
||||
<span class="help-block">'.dr_lang('[整数]表示固定宽度;[整数%]表示百分比').'</span>
|
||||
</div>
|
||||
</div>'];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 字段输出
|
||||
*/
|
||||
public function output($value) {
|
||||
return dr_string2array($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段入库值
|
||||
*
|
||||
* @param array $field 字段信息
|
||||
* @return void
|
||||
*/
|
||||
public function insert_value($field) {
|
||||
$save = [];
|
||||
$data = \Phpcmf\Service::L('Field')->post[$field['fieldname']];
|
||||
if ($data) {
|
||||
if (!IS_ADMIN) {
|
||||
// 验证发布权限
|
||||
$category = \Phpcmf\Service::C()->_get_module_member_category(\Phpcmf\Service::C()->module, 'add');
|
||||
if (!$category) {
|
||||
\Phpcmf\Service::C()->_json(1, dr_lang('模块[%s]没有可用栏目权限', \Phpcmf\Service::C()->module['dirname']));
|
||||
}
|
||||
foreach ($data as $t) {
|
||||
if ($t) {
|
||||
$save[] = $t;
|
||||
if (!$category[$t]) {
|
||||
\Phpcmf\Service::C()->_json(1, dr_lang('模块[%s]没有栏目(%s)权限', \Phpcmf\Service::C()->module['dirname'], $t));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
foreach ($data as $t) {
|
||||
if ($t) {
|
||||
$save[] = $t;
|
||||
}
|
||||
}
|
||||
}
|
||||
$save = array_unique($save);
|
||||
}
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname']] = dr_array2string($save);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单输入
|
||||
*
|
||||
* @param string $field 字段数组
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function input($field, $value = null) {
|
||||
|
||||
// 字段禁止修改时就返回显示字符串
|
||||
if ($this->_not_edit($field, $value)) {
|
||||
return $this->show($field, $value);
|
||||
}
|
||||
|
||||
// 字段存储名称
|
||||
$name = $field['fieldname'];
|
||||
|
||||
// 字段显示名称
|
||||
$text = ($field['setting']['validate']['required'] ? '<span class="required" aria-required="true"> * </span>' : '').dr_lang($field['name']);
|
||||
|
||||
// 字段提示信息
|
||||
$tips = ($name == 'title' && APP_DIR) || $field['setting']['validate']['tips'] ? '<span class="help-block" id="dr_'.$field['fieldname'].'_tips">'.$field['setting']['validate']['tips'].'</span>' : '';
|
||||
|
||||
// 开始输出
|
||||
$str = '';
|
||||
$str.= '<label style="min-width: 200px">'.\Phpcmf\Service::L('category', 'module')->select(
|
||||
\Phpcmf\Service::C()->module['dirname'],
|
||||
dr_string2array($value),
|
||||
' name=\'data['.$field['fieldname'].'][]\' multiple="multiple" data-actions-box="true"',
|
||||
'', 1, 1
|
||||
).'</label>';
|
||||
$str.= '<span class="help-block">'.$tips.'</span>';
|
||||
return $this->input_format($name, $text, $str);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单显示
|
||||
*
|
||||
* @param string $field 字段数组
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function show($field, $value = null) {
|
||||
|
||||
|
||||
return $this->input_format($field['fieldname'], $field['name'], '<div class="form-control-static">'.dr_linkagepos($field['setting']['option']['linkage'], $value, ' - ').'</div>');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
<?php namespace Phpcmf\Field;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本代码基于MIT开源协议,协议规定此处版权信息不可去除
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
class Cats extends \Phpcmf\Field\Cat {
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
public function __construct(...$params) {
|
||||
parent::__construct(...$params);
|
||||
$this->fieldtype = ['TEXT' => ''];
|
||||
$this->defaulttype = 'TEXT';
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段输出
|
||||
*/
|
||||
public function output($value) {
|
||||
return dr_string2array($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段入库值
|
||||
*
|
||||
* @param array $field 字段信息
|
||||
* @return void
|
||||
*/
|
||||
public function insert_value($field) {
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname']] = dr_array2string(\Phpcmf\Service::L('Field')->post[$field['fieldname']]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单输入
|
||||
*
|
||||
* @param string $field 字段数组
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function input($field, $value = null) {
|
||||
|
||||
// 字段禁止修改时就返回显示字符串
|
||||
if ($this->_not_edit($field, $value)) {
|
||||
return $this->show($field, $value);
|
||||
}
|
||||
|
||||
// 字段存储名称
|
||||
$name = $field['fieldname'];
|
||||
|
||||
// 字段显示名称
|
||||
$text = ($field['setting']['validate']['required'] ? '<span class="required" aria-required="true"> * </span>' : '').dr_lang($field['name']);
|
||||
|
||||
// 字段提示信息
|
||||
$tips = ($name == 'title' && APP_DIR) || $field['setting']['validate']['tips'] ? '<span class="help-block" id="dr_'.$field['fieldname'].'_tips">'.$field['setting']['validate']['tips'].'</span>' : '';
|
||||
|
||||
// 开始输出
|
||||
$str = '';
|
||||
$str.= '<label style="min-width: 200px">'.\Phpcmf\Service::L('category', 'module')->select(
|
||||
$field['setting']['option']['module'],
|
||||
dr_string2array($value),
|
||||
' name=\'data['.$field['fieldname'].'][]\' multiple="multiple" data-actions-box="true" '.(isset($field['setting']['option']['is_search']) && $field['setting']['option']['is_search'] ? ' data-live-search="true" ' : ''),
|
||||
'', (isset($field['setting']['option']['parent']) && $field['setting']['option']['parent'] ? 0 : 1), 0
|
||||
).'</label>';
|
||||
$str.= \Phpcmf\Service::L('Field')->get('select')->get_select_search_code().'<span class="help-block">'.$tips.'</span>';
|
||||
return $this->input_format($name, $text, $str);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单显示
|
||||
*
|
||||
* @param string $field 字段数组
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function show($field, $value = null) {
|
||||
|
||||
$html = '';
|
||||
$value = dr_string2array($value);
|
||||
if ($value) {
|
||||
foreach ($value as $t) {
|
||||
$html.= '<label class="btn btn-xs default">'.dr_catpos($t, ' - ', false, '', $field['setting']['option']['module']).'</label>';
|
||||
}
|
||||
}
|
||||
|
||||
return $this->input_format($field['fieldname'], $field['name'], '<div class="form-control-static">'.$html.'</div>');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
<?php namespace Phpcmf\Field;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
class Checkbox extends \Phpcmf\Library\A_Field {
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
public function __construct(...$params) {
|
||||
parent::__construct(...$params);
|
||||
$this->close_xss = 1;
|
||||
$this->fieldtype = ['TEXT' => ''];
|
||||
$this->defaulttype = 'TEXT';
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段相关属性参数
|
||||
*
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function option($option) {
|
||||
|
||||
$option['options'] = isset($option['options']) ? $option['options'] : 'name1|1'.PHP_EOL.'name2|2';
|
||||
|
||||
return [$this->_search_field().
|
||||
'
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('选项列表').'</label>
|
||||
<div class="col-md-9">
|
||||
<textarea class="form-control" name="data[setting][option][options]" style="height:150px;width:400px;">'.$option['options'].'</textarea>
|
||||
<span class="help-block">'.dr_lang('格式:选项名称|选项值[回车换行]选项名称2|值2....').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('默认选中项').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input id="field_default_value" type="text" class="form-control" size="20" value="'.$option['value'].'" name="data[setting][option][value]"></label>
|
||||
<label>'.$this->member_field_select().'</label>
|
||||
<span class="help-block">'.dr_lang('默认选中项,多个选中项用|分隔').'</span>
|
||||
</div>
|
||||
</div>
|
||||
'
|
||||
,
|
||||
'
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('显示格式').'</label>
|
||||
<div class="col-md-9">
|
||||
<div class="mt-radio-inline">
|
||||
<label class="mt-radio mt-radio-outline">
|
||||
<input type="radio" name="data[setting][option][show_type]" value="0" '.(!$option['option']['show_type'] ? 'checked' : '').'> '.dr_lang('横排显示').'
|
||||
<span></span>
|
||||
</label>
|
||||
<label class="mt-radio mt-radio-outline">
|
||||
<input type="radio" name="data[setting][option][show_type]" value="1" '.($option['option']['show_type'] ? 'checked' : '').'> '.dr_lang('竖排显示').'
|
||||
<span></span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段入库值
|
||||
*/
|
||||
public function insert_value($field) {
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname']] = dr_array2string(\Phpcmf\Service::L('Field')->post[$field['fieldname']]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段入库值
|
||||
*/
|
||||
public function output($value) {
|
||||
return dr_string2array($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单输入
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function input($field, $value = '') {
|
||||
|
||||
// 字段禁止修改时就返回显示字符串
|
||||
if ($this->_not_edit($field, $value)) {
|
||||
return $this->show($field, $value);
|
||||
}
|
||||
|
||||
// 字段存储名称
|
||||
$name = $field['fieldname'];
|
||||
|
||||
// 字段显示名称
|
||||
$text = ($field['setting']['validate']['required'] ? '<span class="required" aria-required="true"> * </span>' : '').dr_lang($field['name']);
|
||||
|
||||
// 表单附加参数
|
||||
$attr = $field['setting']['validate']['formattr'];
|
||||
|
||||
// 字段提示信息
|
||||
$tips = ($name == 'title' && APP_DIR) || $field['setting']['validate']['tips'] ? '<span class="help-block" id="dr_'.$field['fieldname'].'_tips">'.$field['setting']['validate']['tips'].'</span>' : '';
|
||||
|
||||
// 字段默认值
|
||||
if ($value) {
|
||||
$value = dr_string2array($value);
|
||||
} elseif ($field['setting']['option']['value']) {
|
||||
$value = $this->get_default_value($field['setting']['option']['value']);
|
||||
$value = is_array($value) ? $value : explode('|', $value);
|
||||
} else {
|
||||
$value = null;
|
||||
}
|
||||
|
||||
$str = '';
|
||||
|
||||
// 显示方式
|
||||
$show_type = (int)$field['setting']['option']['show_type'];
|
||||
|
||||
// 表单选项
|
||||
$options = dr_format_option_array($field['setting']['option']['options']);
|
||||
if ($options) {
|
||||
foreach ($options as $v => $n) {
|
||||
$s = is_array($value) && in_array($v, $value) ? ' checked' : '';
|
||||
$kj = '<input type="checkbox" name="data['.$name.'][]" value="'.$v.'" '.$s.' '.$attr.' />';
|
||||
$str.= '<label class="mt-checkbox mt-checkbox-outline">'.$kj.' '.dr_lang($n).' <span></span> </label>';
|
||||
}
|
||||
}
|
||||
|
||||
return $this->input_format($name, $text, '<div class="'.(!$show_type ? 'mt-checkbox-inline' : 'mt-checkbox-list').'">'.$str.'</div>'.$tips);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单显示
|
||||
*
|
||||
* @param string $field 字段数组
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function show($field, $value = null) {
|
||||
|
||||
$str = '';
|
||||
$value = dr_string2array($value);
|
||||
$options = dr_format_option_array($field['setting']['option']['options']);
|
||||
if ($options && $value) {
|
||||
foreach ($options as $v => $n) {
|
||||
is_array($value) && in_array($v, $value) && $str.= '<label class="label label-default"> '.dr_lang($n).' </label> ';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $this->input_format($field['fieldname'], $field['name'], '<div class="form-control-static">'.$str.'</div>');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
<?php namespace Phpcmf\Field;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
class Color extends \Phpcmf\Library\A_Field {
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
public function __construct(...$params) {
|
||||
parent::__construct(...$params);
|
||||
$this->fieldtype = ['VARCHAR' => 30];
|
||||
$this->defaulttype = 'VARCHAR';
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段相关属性参数
|
||||
*
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function option($option, $field = NULL) {
|
||||
|
||||
$_field = [
|
||||
'<option value=""> -- </option>'
|
||||
];
|
||||
if ($field) {
|
||||
foreach ($field as $t) {
|
||||
if ($t['fieldtype'] == 'Text') {
|
||||
$st = $option['field'] == $t['fieldname'] ? 'selected' : '';
|
||||
$_field[] = '<option '.$st.' value="'.$t['fieldname'].'">'.$t['name'].'</option>';
|
||||
}
|
||||
}
|
||||
$_field = implode('', array_unique($_field));
|
||||
}
|
||||
|
||||
return [$this->_search_field().'
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('附加到指定字段').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><select class="form-control" name="data[setting][option][field]">'.$_field.'</select></label>
|
||||
<span class="help-block">'.dr_lang('对文本类型字段有效,会实时变动颜色').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('默认填充值').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input id="field_default_value" type="text" class="form-control" size="20" value="'.$option['value'].'" name="data[setting][option][value]"></label>
|
||||
<label>'.$this->member_field_select().'</label>
|
||||
<span class="help-block">'.dr_lang('用于字段为空时显示该填充值,并不会去主动变更数据库中的实际值;可以设置会员表字段,表示用当前登录会员信息来填充这个值').'</span>
|
||||
</div>
|
||||
</div>
|
||||
',
|
||||
'
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('控件宽度').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" size="10" name="data[setting][option][width]" value="'.$option['width'].'"></label>
|
||||
<span class="help-block">'.dr_lang('[整数]表示固定宽度;[整数%]表示百分比').'</span>
|
||||
</div>
|
||||
</div>'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段输出
|
||||
*/
|
||||
public function output($value) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单输入
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function input($field, $value = '') {
|
||||
|
||||
// 字段禁止修改时就返回显示字符串
|
||||
if ($this->_not_edit($field, $value)) {
|
||||
return $this->show($field, $value);
|
||||
}
|
||||
|
||||
// 字段存储名称
|
||||
$name = $field['fieldname'];
|
||||
|
||||
// 字段显示名称
|
||||
$text = ($field['setting']['validate']['required'] ? '<span class="required" aria-required="true"> * </span>' : '').dr_lang($field['name']);
|
||||
|
||||
|
||||
// 字段提示信息
|
||||
$tips = $field['setting']['validate']['tips'] ? '<span class="help-block" id="dr_'.$name.'_tips">'.$field['setting']['validate']['tips'].'</span>' : '';
|
||||
|
||||
// 表单宽度设置
|
||||
$width = \Phpcmf\Service::IS_MOBILE_USER() ? '100%' : ($field['setting']['option']['width'] ? $field['setting']['option']['width'] : 200);
|
||||
|
||||
// 风格
|
||||
$style = 'style="width:'.$width.(is_numeric($width) ? 'px' : '').';"';
|
||||
|
||||
// 字段默认值
|
||||
$value = $value ? $value : $this->get_default_value($field['setting']['option']['value']);
|
||||
|
||||
$str = '';
|
||||
|
||||
// 加载js
|
||||
if (!$this->is_load_js($field['fieldtype'])) {
|
||||
$str.= '
|
||||
<link href="'.ROOT_THEME_PATH.'assets/global/plugins/bootstrap-colorpicker/css/colorpicker.css" rel="stylesheet" type="text/css" />
|
||||
<link href="'.ROOT_THEME_PATH.'assets/global/plugins/jquery-minicolors/jquery.minicolors.css" rel="stylesheet" type="text/css" />
|
||||
';
|
||||
$str.= '<script type="text/javascript" src="'.ROOT_THEME_PATH.'assets/global/plugins/bootstrap-colorpicker/js/bootstrap-colorpicker.js?v='.CMF_UPDATE_TIME.'"></script>';
|
||||
$str.= '<script type="text/javascript" src="'.ROOT_THEME_PATH.'assets/global/plugins/jquery-minicolors/jquery.minicolors.min.js?v='.CMF_UPDATE_TIME.'"></script>';
|
||||
$this->set_load_js($field['fieldtype'], 1);
|
||||
}
|
||||
|
||||
$default = '';
|
||||
if ($field['setting']['option']['field'] && $value) {
|
||||
$default = '$("#dr_'.$field['setting']['option']['field'].'").css("color", "'.$value.'");';
|
||||
}
|
||||
|
||||
$str.= '
|
||||
<input type="text" class="form-control color '.$field['setting']['option']['css'].'" data-control="brightness" name="data['.$name.']" id="dr_'.$name.'" '.$style.' value="'.$value.'" >';
|
||||
$js = \Phpcmf\Service::L('js_packer');
|
||||
$str.= $js->pack('
|
||||
<script type="text/javascript">
|
||||
$(function(){
|
||||
$("#dr_'.$name.'").minicolors({
|
||||
control: $("#dr_'.$name.'").attr("data-control") || "hue",
|
||||
defaultValue: $("#dr_'.$name.'").attr("data-defaultValue") || "",
|
||||
inline: "true" === $("#dr_'.$name.'").attr("data-inline"),
|
||||
letterCase: $("#dr_'.$name.'").attr("data-letterCase") || "lowercase",
|
||||
opacity: $("#dr_'.$name.'").attr("data-opacity"),
|
||||
position: $("#dr_'.$name.'").attr("data-position") || "bottom left",
|
||||
change: function(t, o) {
|
||||
t && (o && (t += ", " + o), "object" == typeof console && console.log(t));
|
||||
'.($field['setting']['option']['field'] ? '$("#dr_'.$field['setting']['option']['field'].'").css("color", $("#dr_'.$name.'").val());' : '').'
|
||||
},
|
||||
theme: "bootstrap"
|
||||
});
|
||||
'.$default.'
|
||||
});
|
||||
</script>', 0);
|
||||
|
||||
return $this->input_format($name, $text, $str.$tips);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单显示
|
||||
*
|
||||
* @param string $field 字段数组
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function show($field, $value = null) {
|
||||
|
||||
|
||||
return $this->input_format($field['fieldname'], $field['name'], '<div class="form-control-static"><span style="color:'.$value.'" class="label label-danger"> </span></div>');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,265 @@
|
||||
<?php namespace Phpcmf\Field;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
class Date extends \Phpcmf\Library\A_Field {
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
public function __construct(...$params) {
|
||||
parent::__construct(...$params);
|
||||
$this->fieldtype = ['BIGINT' => 10];
|
||||
$this->defaulttype = 'BIGINT';
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段相关属性参数
|
||||
*
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function option($option) {
|
||||
|
||||
return ['
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('字段格式').'</label>
|
||||
<div class="col-md-9">
|
||||
<div class="mt-radio-inline">
|
||||
<label class="mt-radio mt-radio-outline">
|
||||
<input type="radio" name="data[setting][option][format2]" value="0" '.(!$option['format2'] ? 'checked' : '').'> '.dr_lang('日期时间格式').'
|
||||
<span></span>
|
||||
</label>
|
||||
<label class="mt-radio mt-radio-outline">
|
||||
<input type="radio" name="data[setting][option][format2]" value="1" '.($option['format2'] ? 'checked' : '').'> '.dr_lang('日期格式').'
|
||||
<span></span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('图标显示').'</label>
|
||||
<div class="col-md-9">
|
||||
<div class="mt-radio-inline">
|
||||
<label class="mt-radio mt-radio-outline">
|
||||
<input type="radio" name="data[setting][option][is_left]" value="1" '.($option['is_left'] ? 'checked' : '').'> '.dr_lang('左侧图标').'
|
||||
<span></span>
|
||||
</label>
|
||||
<label class="mt-radio mt-radio-outline">
|
||||
<input type="radio" name="data[setting][option][is_left]" value="0" '.(!$option['is_left'] ? 'checked' : '').'> '.dr_lang('右侧图标').'
|
||||
<span></span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('默认存储值').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input id="field_default_value" type="text" class="form-control" size="20" value="'.$option['value'].'" name="data[setting][option][value]"></label>
|
||||
<label>'.$this->member_field_select().'</label>
|
||||
<span class="help-block">'.dr_lang('用于字段为空时显示该填充值,并不会去主动变更数据库中的实际值;可以设置会员表字段,表示用当前登录会员信息来填充这个值').'</span>
|
||||
</div>
|
||||
</div>
|
||||
'.$this->field_type($option['fieldtype'], $option['fieldlength'])
|
||||
|
||||
,
|
||||
|
||||
'
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('控件宽度').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" size="10" name="data[setting][option][width]" value="'.$option['width'].'"></label>
|
||||
<span class="help-block">'.dr_lang('[整数]表示固定宽度;[整数%]表示百分比').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('按钮颜色').'</label>
|
||||
<div class="col-md-9">
|
||||
<label>'.$this->_color_select('color', $option['color']).'</label>
|
||||
</div>
|
||||
</div>
|
||||
'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建sql语句
|
||||
*/
|
||||
public function create_sql($name, $option, $cname = '') {
|
||||
// 时间戳:BIGINT(10),默认 0
|
||||
$type = 'BIGINT(10)';
|
||||
$info = "DEFAULT '0'";
|
||||
$note = $cname ? (string)$cname : '';
|
||||
$db = $this->_db_for_field_sql();
|
||||
if ($db && method_exists($db, 'sqlAddField')) {
|
||||
return $db->sqlAddField($name, $type, $info, $note);
|
||||
}
|
||||
$tips = $note !== '' ? " COMMENT '".str_replace("'", "''", $note)."'" : '';
|
||||
return 'ALTER TABLE `{tablename}` ADD `'.$name.'` '.$type.' '.$info.$tips;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段输出
|
||||
*/
|
||||
public function output($value) {
|
||||
return dr_date($value, null, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段入库值
|
||||
*
|
||||
* @param array $field 字段信息
|
||||
* @return void
|
||||
*/
|
||||
public function insert_value($field) {
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname']] = strtotime((string)\Phpcmf\Service::L('Field')->post[$field['fieldname']]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单输入
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function input($field, $value = 0) {
|
||||
|
||||
// 字段存储名称
|
||||
$name = $field['fieldname'];
|
||||
|
||||
// 字段禁止修改时就返回显示字符串
|
||||
if ($this->_not_edit($field, $value)) {
|
||||
return $this->show($field, $value);
|
||||
}
|
||||
|
||||
// 字段显示名称
|
||||
$text = ($field['setting']['validate']['required'] ? '<span class="required" aria-required="true"> * </span>' : '').dr_lang($field['name']);
|
||||
|
||||
// 表单宽度设置
|
||||
$width = \Phpcmf\Service::IS_MOBILE_USER() ? '100%' : ($field['setting']['option']['width'] ? $field['setting']['option']['width'] : 200);
|
||||
|
||||
// 风格
|
||||
$style = 'style="width:'.$width.(is_numeric($width) ? 'px' : '').';"';
|
||||
|
||||
// 表单附加参数
|
||||
$attr = $field['setting']['validate']['formattr'];
|
||||
|
||||
// 按钮颜色
|
||||
$color = $field['setting']['option']['color'] ? $field['setting']['option']['color'] : 'default';
|
||||
|
||||
// 字段提示信息
|
||||
$tips = ($name == 'title' && APP_DIR) || $field['setting']['validate']['tips'] ? '<span class="help-block" id="dr_'.$field['fieldname'].'_tips">'.$field['setting']['validate']['tips'].'</span>' : '';
|
||||
|
||||
// 格式显示
|
||||
$format = (int)$field['setting']['option']['format2'];
|
||||
|
||||
// 是否必填
|
||||
$required = $field['setting']['validate']['required'] ? ' required="required"' : '';
|
||||
|
||||
$str = '';
|
||||
if (!$this->is_load_js($field['fieldtype'])) {
|
||||
$str.= '
|
||||
<link href="'.ROOT_THEME_PATH.'assets/global/plugins/bootstrap-daterangepicker/daterangepicker.min.css?v='.CMF_UPDATE_TIME.'" rel="stylesheet" type="text/css" />
|
||||
<link href="'.ROOT_THEME_PATH.'assets/global/plugins/bootstrap-datepicker/css/bootstrap-datepicker.min.css?v='.CMF_UPDATE_TIME.'" rel="stylesheet" type="text/css" />
|
||||
<link href="'.ROOT_THEME_PATH.'assets/global/plugins/bootstrap-datetimepicker/css/bootstrap-datetimepicker.min.css?v='.CMF_UPDATE_TIME.'" rel="stylesheet" type="text/css" />
|
||||
|
||||
<script src="'.ROOT_THEME_PATH.'assets/global/plugins/moment.min.js?v='.CMF_UPDATE_TIME.'" type="text/javascript"></script>
|
||||
<script src="'.ROOT_THEME_PATH.'assets/global/plugins/bootstrap-datepicker/js/bootstrap-datepicker.finecms.js?v='.CMF_UPDATE_TIME.'" type="text/javascript"></script>
|
||||
<script src="'.ROOT_THEME_PATH.'assets/global/plugins/bootstrap-datetimepicker/js/bootstrap-datetimepicker.finecms.js?v='.CMF_UPDATE_TIME.'" type="text/javascript"></script>
|
||||
';
|
||||
$this->set_load_js($field['fieldtype'], 1);
|
||||
}
|
||||
|
||||
$updatetime_select = 0;
|
||||
// 字段默认值
|
||||
!$value && $value = (string)$this->get_default_value($field['setting']['option']['value']);
|
||||
if (APP_DIR && $name == 'updatetime' && \Phpcmf\Service::C()->module) {
|
||||
$updatetime_select = isset(\Phpcmf\Service::C()->module['setting']['updatetime_select']) && \Phpcmf\Service::C()->module['setting']['updatetime_select'];
|
||||
if ($updatetime_select) {
|
||||
// 勾选不更新时
|
||||
!$value || $value == 'SYS_TIME' && $value = SYS_TIME;
|
||||
} else {
|
||||
$value = SYS_TIME;
|
||||
}
|
||||
} elseif ($value == 'SYS_TIME') {
|
||||
$value = SYS_TIME;
|
||||
} elseif (strpos($value, '-') === 0) {
|
||||
} elseif (strpos($value, '-') !== false) {
|
||||
$value = strtotime($value);
|
||||
}
|
||||
|
||||
$value = $format ? dr_date($value, 'Y-m-d') : dr_date($value, 'Y-m-d H:i:s');
|
||||
$shuru = '<input id="dr_'.$name.'" name="data['.$name.']" type="text" '.$style.' value="'.$value.'" '.$required.' class="form-control '.$field['setting']['option']['css'].'">';
|
||||
$tubiao = '<span class="input-group-btn">
|
||||
<button class="btn '.$color.' date-set" type="button">
|
||||
<i class="fa fa-calendar"></i>
|
||||
</button>
|
||||
</span>';
|
||||
$str.= '<div class="input-group date field_date_'.$name.'">';
|
||||
$str.= $field['setting']['option']['is_left'] ? $tubiao.$shuru : $shuru.$tubiao;
|
||||
$str.= '</div>';
|
||||
|
||||
if ($format) {
|
||||
// 日期
|
||||
$str.= '
|
||||
<script>
|
||||
$(function(){
|
||||
$(".field_date_'.$name.'").datepicker({
|
||||
isRTL: false,
|
||||
format: "yyyy-mm-dd",
|
||||
showMeridian: true,
|
||||
autoclose: true,
|
||||
pickerPosition: "bottom-right",
|
||||
todayBtn: "linked"
|
||||
});
|
||||
});
|
||||
</script>
|
||||
';
|
||||
} else {
|
||||
// 日期 + 时间
|
||||
$str.= '
|
||||
<script>
|
||||
$(function(){
|
||||
$(".field_date_'.$name.'").datetimepicker({
|
||||
isRTL: false,
|
||||
format: "yyyy-mm-dd hh:ii:ss",
|
||||
showMeridian: true,
|
||||
autoclose: true,
|
||||
pickerPosition: "bottom-right",
|
||||
todayBtn: "linked"
|
||||
});
|
||||
});
|
||||
</script>';
|
||||
}
|
||||
|
||||
if (APP_DIR && \Phpcmf\Service::C()->module && $name == 'updatetime') {
|
||||
$str.= '<label><input name="no_time" '.($updatetime_select ? ' checked' : '').' class="dr_no_time" type="checkbox" value="1" /> '.dr_lang('不更新').'</label>';
|
||||
}
|
||||
|
||||
$str.= $tips;
|
||||
|
||||
return $this->input_format($name, $text, '<div class="form-date input-group">'.$str.'</div>');
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单显示
|
||||
*
|
||||
* @param string $field 字段数组
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function show($field, $value = null) {
|
||||
|
||||
if (!is_numeric($value)) {
|
||||
$value = strtotime($value);
|
||||
}
|
||||
|
||||
$value = (int)$field['setting']['option']['format2'] ? dr_date($value, 'Y-m-d') : dr_date($value, 'Y-m-d H:i:s');
|
||||
|
||||
return $this->input_format($field['fieldname'], $field['name'], '<div class="form-control-static"><span> '.$value.' </span></div>');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
<?php namespace Phpcmf\Field;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
class Diy extends \Phpcmf\Library\A_Field {
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
public function __construct(...$params) {
|
||||
parent::__construct(...$params);
|
||||
$this->fieldtype = TRUE;
|
||||
$this->defaulttype = 'VARCHAR';
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段相关属性参数
|
||||
*
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function option($option) {
|
||||
|
||||
$option['type'] = isset($option['type']) ? $option['type'] : 0;
|
||||
$option['code'] = isset($option['code']) ? $option['code'] : '';
|
||||
$option['file'] = isset($option['file']) ? $option['file'] : '';
|
||||
|
||||
$str = '<select class="form-control" name="data[setting][option][file]"><option value=""> -- </option>';
|
||||
$files = dr_file_map(CONFIGPATH.'myfield/', 1);
|
||||
if ($this->app) {
|
||||
$files2 = dr_file_map(dr_get_app_dir($this->app).'Config/myfield/', 1);
|
||||
$files2 && $files = dr_array2array($files2, $files);
|
||||
}
|
||||
if ($files) {
|
||||
foreach ($files as $t) {
|
||||
if ($t && strpos($t, '.php') !== 0) {
|
||||
$str.= '<option value="'.$t.'" '.($option['file'] == $t ? 'selected' : '').'> '.$t.' </option>';
|
||||
}
|
||||
}
|
||||
}
|
||||
$str.= '</select>';
|
||||
|
||||
return ['
|
||||
<div class="form-group dr_type">
|
||||
<label class="col-md-2 control-label">'.dr_lang('自定义文件').'</label>
|
||||
<div class="col-md-9">
|
||||
<label>'.$str.'</label>
|
||||
<span class="help-block">'.dr_lang('将设计好的文件上传到./config/myfield/目录之下').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('默认值').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input id="field_default_value" type="text" class="form-control" size="20" value="'.$option['value'].'" name="data[setting][option][value]"></label>
|
||||
<label>'.$this->member_field_select().'</label>
|
||||
<span class="help-block">'.dr_lang('用于字段为空时显示该填充值,并不会去主动变更数据库中的实际值;可以设置会员表字段,表示用当前登录会员信息来填充这个值').'</span>
|
||||
</div>
|
||||
</div>'.$this->field_type($option['fieldtype'], $option['fieldlength'])];
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段入库值
|
||||
*/
|
||||
public function insert_value($field) {
|
||||
$data = \Phpcmf\Service::L('Field')->post[$field['fieldname']];
|
||||
$func = 'dr_diy_field_'.substr($field['setting']['option']['file'], 0, -4).'_insert_value';
|
||||
// 回调格式化函数
|
||||
if (function_exists($func)) {
|
||||
$data = call_user_func($func, $data);
|
||||
}
|
||||
is_array($data) && $data = dr_array2string($data);
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname']] = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段输出
|
||||
*
|
||||
* @param array $value 数据库值
|
||||
* @return string
|
||||
*/
|
||||
public function output($value) {
|
||||
|
||||
if (!$value) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
return strpos($value, '["') === 0 || strpos($value, '{"') === 0 ? dr_string2array($value) : $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单显示
|
||||
*
|
||||
* @param string $field 字段数组
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function show($field, $value = null) {
|
||||
|
||||
// 字段默认值
|
||||
$value = dr_strlen($value) ? $value : $this->get_default_value($field['setting']['option']['value']);
|
||||
|
||||
// 回调格式化函数
|
||||
$func = 'dr_diy_field_'.substr($field['setting']['option']['file'], 0, -4).'_show';
|
||||
if (function_exists($func)) {
|
||||
$str = call_user_func($func, $field, $value);
|
||||
} else {
|
||||
$str = '<div class="form-control-static"> '.htmlspecialchars_decode((string)$value).' </div>';
|
||||
}
|
||||
|
||||
return $this->input_format($field['fieldname'], $field['name'], $str);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单输入
|
||||
*
|
||||
* @param string $cname 字段
|
||||
* @param string $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function input($field, $value = 0) {
|
||||
|
||||
// 字段禁止修改时就返回显示字符串
|
||||
if ($this->_not_edit($field, $value)) {
|
||||
return $this->show($field, $value);
|
||||
}
|
||||
|
||||
// 字段显示名称
|
||||
$text = ($field['setting']['validate']['required'] ? '<span class="required" aria-required="true"> * </span>' : '').dr_lang($field['name']);
|
||||
|
||||
// 表单附加参数
|
||||
$attr = isset($field['setting']['validate']['formattr']) && $field['setting']['validate']['formattr'] ? $field['setting']['validate']['formattr'] : '';
|
||||
// 字段提示信息
|
||||
$tips = isset($field['setting']['validate']['tips']) && $field['setting']['validate']['tips'] ? '<span class="help-block" id="dr_'.$field['fieldname'].'_tips">'.$field['setting']['validate']['tips'].'</span>' : '';
|
||||
// 字段默认值
|
||||
$value = dr_strlen($value) ? $value : $this->get_default_value($field['setting']['option']['value']);
|
||||
|
||||
$name = $field['fieldname'];
|
||||
$code = '';
|
||||
|
||||
// 文件类型
|
||||
if (!$field['setting']['option']['file']) {
|
||||
$code = '<font color=red>没有设置文件</font>';
|
||||
} else {
|
||||
if (strpos((string)$field['setting']['option']['file'], '/') !== false
|
||||
&& is_file($field['setting']['option']['file'])) {
|
||||
require $field['setting']['option']['file'];
|
||||
} else {
|
||||
$file = CONFIGPATH.'myfield/'.$field['setting']['option']['file'];
|
||||
$file2 = dr_get_app_dir(APP_DIR).'Config/myfield/'.$field['setting']['option']['file'];
|
||||
if (is_file($file)) {
|
||||
require $file;
|
||||
} elseif (is_file($file2)) {
|
||||
require $file2;
|
||||
} elseif (!$field['setting']['option']['file']) {
|
||||
$code = '<font color=red>没有选择文件,在字段属性中选择</font>';
|
||||
} else {
|
||||
$code = '<font color=red>文件('.$file.')不存在</font>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->input_format($field['fieldname'], $text, $code);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,750 @@
|
||||
<?php namespace Phpcmf\Field;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
class Editor extends \Phpcmf\Library\A_Field {
|
||||
|
||||
protected $rid; // 附件入库标记字符
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
public function __construct(...$params) {
|
||||
parent::__construct(...$params);
|
||||
$this->fieldtype = ['MEDIUMTEXT' => ''];
|
||||
$this->defaulttype = 'MEDIUMTEXT';
|
||||
$this->rid = md5(FC_NOW_URL.\Phpcmf\Service::L('input')->get_user_agent().\Phpcmf\Service::L('input')->ip_address().\Phpcmf\Service::C()->uid);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段相关属性参数
|
||||
*
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function option($option) {
|
||||
|
||||
if (!isset($option['attach_size']) || !$option['attach_size']) {
|
||||
$option['attach_size'] = 200;
|
||||
}
|
||||
if (!isset($option['toolbar']) || !$option['toolbar']) {
|
||||
$option['toolbar'] = "['style', ['style']],
|
||||
['font', ['bold', 'italic', 'underline', 'clear']],
|
||||
['fontname', ['fontsize']],
|
||||
['color', ['color']],
|
||||
['para', ['ul', 'ol', 'paragraph']],
|
||||
['table', ['table']],
|
||||
['link', ['link']],
|
||||
['attach', ['attach']],
|
||||
['picture', ['qsimage', 'picture', 'help']],
|
||||
['video', ['video', 'llvideo']],
|
||||
['view', ['codeview'] ]";
|
||||
}
|
||||
if (!isset($option['toolbar_home']) || !$option['toolbar_home']) {
|
||||
$option['toolbar_home'] = "['style', ['style']],
|
||||
['font', ['bold', 'italic', 'underline', 'clear']],
|
||||
['fontname', ['fontsize']],
|
||||
['color', ['color']],
|
||||
['para', ['ul', 'ol', 'paragraph']],
|
||||
['table', ['table']],
|
||||
['link', ['link']],
|
||||
['attach', ['attach']],
|
||||
['picture', ['qsimage', 'picture', 'help']],
|
||||
['video', ['video', 'llvideo']],
|
||||
['view', ['codeview'] ]";
|
||||
}
|
||||
if (!isset($option['attach_ext']) || !$option['attach_ext']) {
|
||||
$option['attach_ext'] = 'zip,rar,txt,doc';
|
||||
}
|
||||
if (!isset($option['video_ext']) || !$option['video_ext']) {
|
||||
$option['video_ext'] = 'mp4';
|
||||
}
|
||||
if (!isset($option['video_size']) || !$option['video_size']) {
|
||||
$option['video_size'] = 500;
|
||||
}
|
||||
if (!isset($option['image_ext']) || !$option['image_ext']) {
|
||||
$option['image_ext'] = 'jpg,gif,png,webp,jpeg';
|
||||
}
|
||||
if (!isset($option['imagecut_ext']) || !$option['imagecut_ext']) {
|
||||
$option['imagecut_ext'] = '';
|
||||
}
|
||||
if (!isset($option['image_size']) || !$option['image_size']) {
|
||||
$option['image_size'] = 10;
|
||||
}
|
||||
|
||||
$wm = \Phpcmf\Service::C()->get_cache('site', SITE_ID, 'watermark', 'ueditor') ? '<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('图片水印').'</label>
|
||||
<div class="col-md-9">
|
||||
<div class="form-control-static">
|
||||
'.dr_lang('系统强制开启水印').'
|
||||
</div>
|
||||
</div>
|
||||
</div>' : '<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('图片水印').'</label>
|
||||
<div class="col-md-9">
|
||||
<div class="mt-radio-inline">
|
||||
<label class="mt-radio mt-radio-outline"><input type="radio" value="1" name="data[setting][option][watermark]" '.($option['watermark'] == 1 ? 'checked' : '').' > '.dr_lang('开启').' <span></span></label>
|
||||
|
||||
<label class="mt-radio mt-radio-outline"><input type="radio" value="0" name="data[setting][option][watermark]" '.($option['watermark'] == 0 ? 'checked' : '').' > '.dr_lang('关闭').' <span></span></label>
|
||||
</div>
|
||||
<span class="help-block">'.dr_lang('上传的图片会加上水印图').'</span>
|
||||
</div>
|
||||
</div>';
|
||||
|
||||
return [$this->_search_field().'
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('底部工具栏').'</label>
|
||||
<div class="col-md-9">
|
||||
<div class="mt-radio-inline">
|
||||
<label class="mt-radio mt-radio-outline"><input type="radio" onclick="$(\'#sdmrx\').show()" value="1" name="data[setting][option][show_bottom_boot]" '.($option['show_bottom_boot'] == 1 ? 'checked' : '').' > '.dr_lang('开启').' <span></span></label>
|
||||
|
||||
<label class="mt-radio mt-radio-outline"><input type="radio" onclick="$(\'#sdmrx\').hide()" value="0" name="data[setting][option][show_bottom_boot]" '.($option['show_bottom_boot'] == 0 ? 'checked' : '').' > '.dr_lang('关闭').' <span></span></label>
|
||||
</div>
|
||||
<span class="help-block">'.dr_lang('编辑器底部工具栏,有截取字符选择、提取缩略图、下载远程图等控制按钮').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" id="sdmrx" '.(!$option['show_bottom_boot'] ? 'style="display:none"' : '').'>
|
||||
<label class="col-md-1 control-label"> </label>
|
||||
<div class="col-md-9">
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang("提取描述").'</label>
|
||||
<div class="col-md-9">
|
||||
<input type="checkbox" name="data[setting][option][tool_select_2]" value="1" '.($option['tool_select_2'] ? 'checked' : '').' data-on-text="'.dr_lang("默认选中").'" data-off-text="'.dr_lang("默认不选").'" data-on-color="success" data-off-color="danger" class="make-switch" data-size="small">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang("提取缩略图").'</label>
|
||||
<div class="col-md-9">
|
||||
<input type="checkbox" name="data[setting][option][tool_select_1]" value="1" '.($option['tool_select_1'] ? 'checked' : '').' data-on-text="'.dr_lang("默认选中").'" data-off-text="'.dr_lang("默认不选").'" data-on-color="success" data-off-color="danger" class="make-switch" data-size="small">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang("去除站外链接").'</label>
|
||||
<div class="col-md-9">
|
||||
<input type="checkbox" name="data[setting][option][tool_select_4]" value="1" '.($option['tool_select_4'] ? 'checked' : '').' data-on-text="'.dr_lang("默认选中").'" data-off-text="'.dr_lang("默认不选").'" data-on-color="success" data-off-color="danger" class="make-switch" data-size="small">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang("下载远程图").'</label>
|
||||
<div class="col-md-9">
|
||||
<input type="checkbox" name="data[setting][option][tool_select_3]" value="1" '.($option['tool_select_3'] ? 'checked' : '').' data-on-text="'.dr_lang("启用").'" data-off-text="'.dr_lang("不启用").'" data-on-color="success" data-off-color="danger" class="make-switch" data-size="small">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" '.(!$option['show_bottom_boot'] ? 'style="display:none"' : '').'>
|
||||
<label class="col-md-2 control-label">'.dr_lang('提取缩略图限制').'</label>
|
||||
<div class="col-md-9">
|
||||
<div class="input-inline input-small">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon">'.dr_lang('宽大于').'</span>
|
||||
<input type="text" name="data[setting][option][thumb][width]" value="'.($option['thumb']['width']).'" class="form-control" placeholder="px">
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-inline input-small">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon">'.dr_lang('高大于').'</span>
|
||||
<input type="text" name="data[setting][option][thumb][height]" value="'.($option['thumb']['height']).'" class="form-control" placeholder="px">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('图片title').'</label>
|
||||
<div class="col-md-9">
|
||||
<div class="mt-radio-inline">
|
||||
<label class="mt-radio mt-radio-outline"><input type="radio" value="1" name="data[setting][option][imgtitle]" '.($option['imgtitle'] >0 ? 'checked' : '').' > '.dr_lang('内容标题').' <span></span></label>
|
||||
<label class="mt-radio mt-radio-outline"><input type="radio" value="0" name="data[setting][option][imgtitle]" '.(!$option['imgtitle'] ? 'checked' : '').' > '.dr_lang('图片名称').' <span></span></label>
|
||||
<label class="mt-radio mt-radio-outline"><input type="radio" value="-1" name="data[setting][option][imgtitle]" '.($option['imgtitle'] < 0 ? 'checked' : '').' > '.dr_lang('不显示').' <span></span></label>
|
||||
</div>
|
||||
<span class="help-block">'.dr_lang('将模块内容的标题作为图片title字符').'</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('图片alt').'</label>
|
||||
<div class="col-md-9">
|
||||
<div class="mt-radio-inline">
|
||||
<label class="mt-radio mt-radio-outline"><input type="radio" value="1" name="data[setting][option][imgalt]" '.($option['imgalt'] >0 ? 'checked' : '').' > '.dr_lang('内容标题').' <span></span></label>
|
||||
<label class="mt-radio mt-radio-outline"><input type="radio" value="0" name="data[setting][option][imgalt]" '.(!$option['imgalt'] ? 'checked' : '').' > '.dr_lang('图片名称').' <span></span></label>
|
||||
<label class="mt-radio mt-radio-outline"><input type="radio" value="-1" name="data[setting][option][imgalt]" '.($option['imgalt'] < 0 ? 'checked' : '').' > '.dr_lang('不显示').' <span></span></label>
|
||||
</div>
|
||||
<span class="help-block">'.dr_lang('将模块内容的标题作为图片alt字符').'</span>
|
||||
</div>
|
||||
</div>
|
||||
'.$wm.
|
||||
'
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('图片粘贴扩展名').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" name="data[setting][option][imagecut_ext]" value="'.$option['imagecut_ext'].'"></label>
|
||||
<span class="help-block">'.dr_lang('填写用于图片的扩展名格式,只能填写单个扩展名,用于截图粘贴时储存的扩展名').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('图片上传扩展名').'</label>
|
||||
<div class="col-md-9">
|
||||
<span><input type="text" class="form-control" name="data[setting][option][image_ext]" value="'.$option['image_ext'].'"></span>
|
||||
<span class="help-block">'.dr_lang('填写用于图片上传的扩展名格式,格式:jpg,gif,png,webp,jpeg').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('图片上传大小').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" name="data[setting][option][image_size]" value="'.$option['image_size'].'"></label>
|
||||
<span class="help-block">'.dr_lang('填写用于图片上传的最大允许上传的大小,单位MB').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('附件上传大小').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" name="data[setting][option][attach_size]" value="'.$option['attach_size'].'"></label>
|
||||
<span class="help-block">'.dr_lang('填写用于附件上传的最大允许上传的大小,单位MB').'</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('附件上传扩展名').'</label>
|
||||
<div class="col-md-9">
|
||||
<span><input type="text" class="form-control" name="data[setting][option][attach_ext]" value="'.$option['attach_ext'].'"></span>
|
||||
<span class="help-block">'.dr_lang('填写用于附件上传的扩展名,格式:rar,zip').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('视频上传扩展名').'</label>
|
||||
<div class="col-md-9">
|
||||
<span><input type="text" class="form-control" name="data[setting][option][video_ext]" value="'.$option['video_ext'].'"></span>
|
||||
<span class="help-block">'.dr_lang('填写用于视频上传的扩展名格式,格式:mp4,mov').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('视频上传大小').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" name="data[setting][option][video_size]" value="'.$option['video_size'].'"></label>
|
||||
<span class="help-block">'.dr_lang('填写用于视频上传的最大允许上传的大小,单位MB').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('后台工具栏图标').'</label>
|
||||
<div class="col-md-9">
|
||||
<textarea id="field_default_value" style="width: 90%;height: 100px;" class="form-control" name="data[setting][option][toolbar]">'.$option['toolbar'].'</textarea>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('前端工具栏图标').'</label>
|
||||
<div class="col-md-9">
|
||||
<textarea id="field_default_value" style="width: 90%;height: 100px;" class="form-control" name="data[setting][option][toolbar_home]">'.$option['toolbar_home'].'</textarea>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
'.$this->attachment($option, 0).'
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('默认存储值').'</label>
|
||||
<div class="col-md-9">
|
||||
<textarea id="field_default_value" style="width: 90%;height: 100px;" class="form-control" name="data[setting][option][value]">'.$option['value'].'</textarea>
|
||||
<p><label>'.$this->member_field_select().'</label>
|
||||
<span class="help-block">'.dr_lang('用于字段为空时显示该填充值,并不会去主动变更数据库中的实际值;可以设置会员表字段,表示用当前登录会员信息来填充这个值').'</span></p>
|
||||
</div>
|
||||
</div>
|
||||
'.$this->field_type($option['fieldtype'], $option['fieldlength']),
|
||||
|
||||
'<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('控件宽度').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" name="data[setting][option][width]" value="'.$option['width'].'"></label>
|
||||
<span class="help-block">'.dr_lang('[整数]表示固定宽度;[整数%]表示百分比').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('控件高度').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" name="data[setting][option][height]" value="'.$option['height'].'"></label>
|
||||
<label>px</label>
|
||||
</div>
|
||||
</div>'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证字段属性
|
||||
*/
|
||||
public function edit_config($post) {
|
||||
|
||||
if (isset($post['setting']['option']['imagecut_ext']) && $post['setting']['option']['imagecut_ext']) {
|
||||
if (strpos($post['setting']['option']['imagecut_ext'], ',') !== false) {
|
||||
return dr_return_data(0, dr_lang('图片粘贴扩展名只能填写单个扩展名'));
|
||||
}
|
||||
}
|
||||
|
||||
return dr_return_data(1, 'ok');
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段入库值
|
||||
*/
|
||||
public function insert_value($field) {
|
||||
|
||||
$value = str_replace('style=""', '', (string)$_POST['data'][$field['fieldname']]);
|
||||
$value = preg_replace("/cmsattachid=\"([0-9]+)\"/U", '', $value);
|
||||
// 第一张作为缩略图
|
||||
$slt = isset($_POST['data']['thumb']) && isset($_POST['is_auto_thumb_'.$field['fieldname']]) && !$_POST['data']['thumb'] && $_POST['is_auto_thumb_'.$field['fieldname']];
|
||||
|
||||
$base64 = strpos($value, ';base64,');
|
||||
|
||||
// 下载远程图片
|
||||
if ($slt || $base64) {
|
||||
$temp = preg_replace('/<pre(.*)<\/pre>/siU', '', $value);
|
||||
$temp = preg_replace('/<code(.*)<\/code>/siU', '', $temp);
|
||||
if (preg_match_all("/(src)=([\"|']?)([^ \"'>]+)\\2/i", $temp, $imgs)) {
|
||||
$reps = array_unique($imgs[3]);
|
||||
usort($reps, function ($a, $b) {
|
||||
return dr_strlen($b) - dr_strlen($a);
|
||||
});
|
||||
foreach ($reps as $img) {
|
||||
|
||||
if ($base64 && preg_match('/^(data:\s*image\/(\w+);base64,)/i', $img, $result)) {
|
||||
// 处理图片
|
||||
$ext = strtolower($result[2]);
|
||||
if (!in_array($ext, ['png', 'jpg', 'jpeg', 'gif', 'webp'])) {
|
||||
CI_DEBUG && log_message('debug', 'Editor编辑器图片粘贴失败:扩展名不符合'.$ext);
|
||||
continue;
|
||||
}
|
||||
$content = base64_decode(str_replace($result[1], '', $img));
|
||||
if (strlen($content) > 30000000) {
|
||||
CI_DEBUG && log_message('debug', 'Editor编辑器图片粘贴失败:图片内容过大,超过30MB');
|
||||
continue;
|
||||
}
|
||||
$rt = \Phpcmf\Service::L('upload')->base64_image([
|
||||
'ext' => isset($field['setting']['option']['imagecut_ext']) && $field['setting']['option']['imagecut_ext'] ? $field['setting']['option']['imagecut_ext'] : $ext,
|
||||
'content' => $content,
|
||||
'watermark' => \Phpcmf\Service::C()->get_cache('site', SITE_ID, 'watermark', 'ueditor') || $field['setting']['option']['watermark'] ? 1 : 0,
|
||||
'attachment' => \Phpcmf\Service::M('Attachment')->get_attach_info(intval($field['setting']['option']['attachment']), $field['setting']['option']['image_reduce']),
|
||||
]);
|
||||
if (!$rt['code']) {
|
||||
CI_DEBUG && log_message('debug', 'Editor编辑器图片粘贴失败:'.$rt['msg']);
|
||||
continue;
|
||||
}
|
||||
$att = \Phpcmf\Service::M('Attachment')->save_data($rt['data'], 'ueditor:'.$this->rid);
|
||||
if ($att['code']) {
|
||||
// 归档成功
|
||||
$value = str_replace($img, $rt['data']['url'], $value);
|
||||
$img = $att['code'];
|
||||
// 标记附件
|
||||
\Phpcmf\Service::M('Attachment')->save_ueditor_aid($this->rid, $att['code']);
|
||||
} else {
|
||||
CI_DEBUG && log_message('debug', 'Editor编辑器图片归档失败:'.$rt['msg']);
|
||||
}
|
||||
}
|
||||
// 缩略图
|
||||
if ($img && $slt) {
|
||||
$_field = \Phpcmf\Service::L('form')->fields;
|
||||
if (isset($_field['thumb']) && $_field['thumb']['fieldtype'] == 'File' && !\Phpcmf\Service::L('Field')->data[$_field['thumb']['ismain']]['thumb']) {
|
||||
if (!is_numeric($img)) {
|
||||
// 下载缩略图
|
||||
$width = isset($field['setting']['option']['thumb']['width']) ? $field['setting']['option']['thumb']['width'] : 0;
|
||||
$height = isset($field['setting']['option']['thumb']['height']) ? $field['setting']['option']['thumb']['height'] : 0;
|
||||
// 获取图片信息
|
||||
if ($width || $height) {
|
||||
$imageInfo = getimagesize($img);
|
||||
if ($imageInfo !== false) {
|
||||
// 宽度
|
||||
if ($width && $imageInfo[0] < $width) {
|
||||
$img = '';
|
||||
continue;
|
||||
}
|
||||
if ($height && $imageInfo[1] < $height) {
|
||||
$img = '';
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
$img = '';
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// 判断域名白名单
|
||||
$arr = parse_url($img);
|
||||
$domain = $arr['host'];
|
||||
if ($domain) {
|
||||
$sites = \Phpcmf\Service::R(WRITEPATH.'config/domain_site.php');
|
||||
if (isset($sites[$domain])) {
|
||||
// 过滤站点域名
|
||||
} elseif (strpos(SYS_UPLOAD_URL, $domain) !== false) {
|
||||
// 过滤附件白名单
|
||||
} else {
|
||||
$file = dr_catcher_data($img, 8);
|
||||
if (!$file) {
|
||||
CI_DEBUG && log_message('debug', '服务器无法下载图片:'.$img);
|
||||
} else {
|
||||
// 尝试找一找附件库
|
||||
$att = \Phpcmf\Service::M()->table('attachment')->like('related', 'ueditor')->where('filemd5', md5($file))->getRow();
|
||||
if ($att) {
|
||||
$img = $att['id'];
|
||||
} else {
|
||||
// 下载归档
|
||||
$rt = \Phpcmf\Service::L('upload')->down_file([
|
||||
'url' => html_entity_decode((string)$img),
|
||||
'timeout' => 5,
|
||||
'watermark' => \Phpcmf\Service::C()->get_cache('site', SITE_ID, 'watermark', 'ueditor') || $field['setting']['option']['watermark'] ? 1 : 0,
|
||||
'attachment' => \Phpcmf\Service::M('Attachment')->get_attach_info(intval($field['setting']['option']['attachment']), $field['setting']['option']['image_reduce']),
|
||||
'file_ext' => $ext,
|
||||
'file_content' => $file,
|
||||
]);
|
||||
if ($rt['code']) {
|
||||
$att = \Phpcmf\Service::M('Attachment')->save_data($rt['data'], 'ueditor:'.$this->rid);
|
||||
if ($att['code']) {
|
||||
// 归档成功
|
||||
$value = str_replace($img, $rt['data']['url'], $value);
|
||||
$img = $att['code'];
|
||||
// 标记附件
|
||||
\Phpcmf\Service::M('Attachment')->save_ueditor_aid($this->rid, $att['code']);
|
||||
}
|
||||
} else {
|
||||
CI_DEBUG && log_message('debug', 'Editor编辑器图片下载失败:'.$rt['msg']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
\Phpcmf\Service::L('Field')->data[$_field['thumb']['ismain']]['thumb'] = $_POST['data']['thumb'] = $img;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 去除站外链接
|
||||
if (isset($_POST['is_remove_a_'.$field['fieldname']]) && $_POST['is_remove_a_'.$field['fieldname']]
|
||||
&& preg_match_all("/<a (.*)href=(.+)>(.*)<\/a>/Ui", $value, $arrs)) {
|
||||
$sites = \Phpcmf\Service::R(WRITEPATH.'config/domain_site.php');
|
||||
foreach ($arrs[2] as $i => $a) {
|
||||
if (strpos($a, ' ') !== false) {
|
||||
list($a) = explode(' ', $a);
|
||||
}
|
||||
$a = trim($a, '"');
|
||||
$a = trim($a, '\'');
|
||||
$arr = parse_url($a);
|
||||
if ($arr && $arr['host'] && !isset($sites[$arr['host']])) {
|
||||
// 去除a标签
|
||||
$value = str_replace($arrs[0][$i], $arrs[3][$i], $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 提取描述信息
|
||||
if (isset($_POST['data']['description']) && isset($_POST['is_auto_description_'.$field['fieldname']])
|
||||
&& $_POST['is_auto_description_'.$field['fieldname']]) {
|
||||
\Phpcmf\Service::L('Field')->data[1]['description'] = $_POST['data']['description'] = dr_get_description($value);
|
||||
}
|
||||
|
||||
// 替换分页
|
||||
$value = str_replace('_ueditor_page_break_tag_', '<hr class="pagebreak">', $value);
|
||||
$value = str_replace(' style=""', '', $value);
|
||||
if (isset($field['setting']['validate']['xss']) && $field['setting']['validate']['xss']) {
|
||||
// 开启xss
|
||||
$value = \Phpcmf\Service::L('Security')->xss_clean($value);
|
||||
}
|
||||
// 入库操作
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname']] = htmlspecialchars($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取附件id
|
||||
*/
|
||||
public function get_attach_id($value) {
|
||||
return \Phpcmf\Service::M('Attachment')->get_ueditor_aid($this->rid);
|
||||
}
|
||||
|
||||
/**
|
||||
* 附件处理
|
||||
*/
|
||||
public function attach($data, $_data) {
|
||||
|
||||
$add = \Phpcmf\Service::M('Attachment')->get_ueditor_aid($this->rid, true);
|
||||
if (isset($_POST['data'][$this->field['fieldname']]) && $_POST['data'][$this->field['fieldname']]
|
||||
&& preg_match_all("/<([a-z]+) cmsattachid=\"([0-9]+)\"/Ui", $_POST['data'][$this->field['fieldname']], $att)) {
|
||||
if ($add && is_array($add)) {
|
||||
$add = array_merge($add, $att[2]);
|
||||
} else {
|
||||
$add = $att[2];
|
||||
}
|
||||
}
|
||||
|
||||
return [$add, NULL];
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段输出
|
||||
*
|
||||
* @param array $value 数据库值
|
||||
* @return string
|
||||
*/
|
||||
public function output($value) {
|
||||
return dr_ueditor_html($value, isset(\Phpcmf\Service::L('Field')->data['title']) ? \Phpcmf\Service::L('Field')->data['title'] : '');
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段显示
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function show($field, $value = null) {
|
||||
$html = '
|
||||
<div class="portlet bordered light">
|
||||
<div class="portlet-body">
|
||||
<div class="scroller" style="width:'.(\Phpcmf\Service::IS_MOBILE_USER() ? '100%' : ($field['setting']['option']['width'] ? $field['setting']['option']['width'].(is_numeric($field['setting']['option']['width']) ? 'px' : '') : '100%')).';height:'.($field['setting']['option']['height'] ? $field['setting']['option']['height'] : '300').'px" data-always-visible="1" data-rail-visible="1">
|
||||
'.htmlspecialchars_decode((string)$value).'
|
||||
</div>
|
||||
</div>
|
||||
</div>';
|
||||
return $this->input_format($field['fieldname'], $field['name'], $html);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单输入
|
||||
*
|
||||
*/
|
||||
public function input($field, $value = '') {
|
||||
|
||||
// 字段禁止修改时就返回显示字符串
|
||||
if ($this->_not_edit($field, $value)) {
|
||||
return $this->show($field, $value);
|
||||
}
|
||||
|
||||
// 字段存储名称
|
||||
$name = $field['fieldname'];
|
||||
|
||||
// 字段显示名称
|
||||
$text = ($field['setting']['validate']['required'] ? '<span class="required" aria-required="true"> * </span>' : '').dr_lang($field['name']);
|
||||
|
||||
// 表单宽度设置
|
||||
$width = \Phpcmf\Service::IS_MOBILE_USER() ? '100%' : ($field['setting']['option']['width'] ? $field['setting']['option']['width'] : '100%');
|
||||
|
||||
// 表单高度设置
|
||||
$height = $field['setting']['option']['height'] ? $field['setting']['option']['height'] : '';
|
||||
|
||||
// 字段提示信息
|
||||
$tips = $field['setting']['validate']['tips'] ? '<span class="help-block" id="dr_'.$name.'_tips">'.$field['setting']['validate']['tips'].'</span>' : '';
|
||||
|
||||
// 字段默认值
|
||||
$value = dr_strlen($value) ? $value : $this->get_default_value($field['setting']['option']['value']);
|
||||
|
||||
// 输出
|
||||
$str = '';
|
||||
|
||||
// 防止重复加载JS
|
||||
if (!$this->is_load_js($field['fieldtype'])) {
|
||||
$str.= '
|
||||
<link href="'.THEME_PATH.'assets/editor/summernote.css?v='.CMF_UPDATE_TIME.'" rel="stylesheet">
|
||||
<script type="text/javascript" src="'.THEME_PATH.'assets/editor/summernote'.(IS_XRDEV ? '' : '.min').'.js?v='.CMF_UPDATE_TIME.'"></script>
|
||||
';
|
||||
$this->set_load_js($field['fieldtype'], 1);
|
||||
}
|
||||
if (!isset($field['setting']['option']['attach_size']) || !$field['setting']['option']['attach_size']) {
|
||||
$option['attach_size'] = 200;
|
||||
}
|
||||
|
||||
$p = dr_authcode([
|
||||
'size' => (!isset($field['setting']['option']['video_size']) || !$field['setting']['option']['video_size']) ? 500 : $field['setting']['option']['video_size'],
|
||||
'exts' => (!isset($field['setting']['option']['video_ext']) || !$field['setting']['option']['video_ext']) ? 'mp4' : $field['setting']['option']['video_ext'],
|
||||
'count' => 100,
|
||||
'attachment' => $field['setting']['option']['attachment'],
|
||||
], 'ENCODE');
|
||||
$p2 = dr_authcode([
|
||||
'size' => (!isset($field['setting']['option']['image_size']) || !$field['setting']['option']['image_size']) ? 10 : $field['setting']['option']['image_size'],
|
||||
'exts' => (!isset($field['setting']['option']['image_ext']) || !$field['setting']['option']['image_ext']) ? 'jpg,gif,png,webp,jpeg' : $field['setting']['option']['image_ext'],
|
||||
'count' => 100,
|
||||
'attachment' => $field['setting']['option']['attachment'],
|
||||
'image_reduce' => $field['setting']['option']['image_reduce'],
|
||||
], 'ENCODE');
|
||||
$p3 = dr_authcode([
|
||||
'size' => (!isset($field['setting']['option']['attach_size']) || !$field['setting']['option']['attach_size']) ? 200 : $field['setting']['option']['attach_size'],
|
||||
'exts' => (!isset($field['setting']['option']['attach_ext']) || !$field['setting']['option']['attach_ext']) ? 'zip,rar,txt,doc' : $field['setting']['option']['attach_ext'],
|
||||
'count' => 100,
|
||||
'attachment' => $field['setting']['option']['attachment'],
|
||||
], 'ENCODE');
|
||||
$str.= "<textarea class=\"dr_ueditor\" name=\"data[$name]\" id=\"dr_$name\">$value</textarea>";
|
||||
|
||||
if ($field['setting']['option']['imgtitle'] > 0) {
|
||||
$title = UEDITOR_IMG_TITLE;
|
||||
} elseif ($field['setting']['option']['imgtitle'] < 0) {
|
||||
$title = 'none';
|
||||
} else {
|
||||
$title = '';
|
||||
}
|
||||
if ($field['setting']['option']['imgalt'] > 0) {
|
||||
$alt = UEDITOR_IMG_TITLE;
|
||||
} elseif ($field['setting']['option']['imgalt'] < 0) {
|
||||
$alt = 'none';
|
||||
} else {
|
||||
$alt = '';
|
||||
}
|
||||
$tool = '';
|
||||
if (IS_ADMIN) {
|
||||
if ($field['setting']['option']['toolbar']) {
|
||||
$tool = $this->_toolbar($field['setting']['option']['toolbar']);
|
||||
}
|
||||
} else {
|
||||
if ($field['setting']['option']['toolbar_home']) {
|
||||
$tool = $this->_toolbar($field['setting']['option']['toolbar_home']);
|
||||
}
|
||||
}
|
||||
|
||||
$wm = \Phpcmf\Service::C()->get_cache('site', SITE_ID, 'watermark', 'ueditor') || $field['setting']['option']['watermark'] ? 1 : 0;
|
||||
$str.= \Phpcmf\Service::L('js_packer')->pack("
|
||||
<script type=\"text/javascript\">
|
||||
function dr_is_auto_description_".$field['fieldname']."() {
|
||||
var v = $(\"#is_auto_description_".$field['fieldname']."\").is(\":checked\");
|
||||
if (v == true) {
|
||||
$(\"#dr_description\").prop(\"readonly\", true);
|
||||
} else {
|
||||
$(\"#dr_description\").prop(\"readonly\", false);
|
||||
}
|
||||
}
|
||||
$(function(){
|
||||
dr_is_auto_description_".$field['fieldname']."();
|
||||
$('#dr_".$name."').summernote({
|
||||
field: '".$field['fieldname']."',
|
||||
isMobileWidth: '".(\Phpcmf\Service::IS_MOBILE_USER() ? '95%' : '80%')."',
|
||||
llVideoUrl: '".dr_web_prefix(''.(IS_ADMIN ? SELF.'?c=api' : 'index.php?s=api&c=file').'&m=input_file_list&is_iframe=1&p=' . $p)."',
|
||||
llImageUrl: '".dr_web_prefix(''.(IS_ADMIN ? SELF.'?c=api' : 'index.php?s=api&c=file').'&m=input_file_list&is_iframe=1&p=' . $p2."&is_wm=".$wm)."',
|
||||
attachUrl: '".dr_web_prefix(''.(IS_ADMIN ? SELF.'?c=api' : 'index.php?s=api&c=file').'&m=input_file_list&is_iframe=1&p=' . $p3)."',
|
||||
videoUrl: '".dr_web_prefix(''.(IS_ADMIN ? SELF.'?c=api' : 'index.php?s=api&c=file').'&m=upload&is_iframe=1&token='.dr_get_csrf_token().'&rid='.$this->rid.'&p=' . $p)."',
|
||||
videoLinkUrl: '".dr_web_prefix(''.(IS_ADMIN ? SELF.'?c=api' : 'index.php?s=api&c=file').'&m=video&is_iframe=1&token='.dr_get_csrf_token().'&rid='.$this->rid.'&p=' . $p)."',
|
||||
isImageTitle:'".$title."',
|
||||
isImageAlt:'".$alt."',
|
||||
height:'".$height."',
|
||||
width:'".$width."'
|
||||
".($tool)."
|
||||
});
|
||||
});
|
||||
function dr_editor_down_img_".$field['fieldname']."(){
|
||||
var index = layer.load(2, {
|
||||
shade: [0.3,'#fff'], //0.1透明度的白色背景
|
||||
time: 100000000
|
||||
});
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: '".dr_web_prefix(''.(IS_ADMIN ? SELF.'?c=api' : 'index.php?s=api&c=file').'&m=down_img&is_iframe=1&token='.dr_get_csrf_token().'&rid='.$this->rid.'&p=' . $p2."&is_wm=".$wm)."',
|
||||
dataType: 'json',
|
||||
data: { value: $('#dr_".$field['fieldname']."').summernote('code') },
|
||||
success: function (json) {
|
||||
layer.close(index);
|
||||
if (json.code == 0) {
|
||||
dr_cmf_tips(0, json.msg, json.data.time);
|
||||
} else {
|
||||
|
||||
var width = '500px';
|
||||
var height = '70%';
|
||||
|
||||
if (is_mobile_cms == 1) {
|
||||
width = '95%';
|
||||
height = '90%';
|
||||
}
|
||||
|
||||
layer.open({
|
||||
type: 2,
|
||||
title: '',
|
||||
fix:true,
|
||||
scrollbar: false,
|
||||
maxmin: false,
|
||||
resize: true,
|
||||
shadeClose: true,
|
||||
shade: 0,
|
||||
area: [width, height],
|
||||
btn: [dr_lang('确定'), dr_lang('取消')],
|
||||
yes: function(index, layero){
|
||||
// 延迟加载
|
||||
var loading = layer.load(2, {
|
||||
shade: [0.3,'#fff'], //0.1透明度的白色背景
|
||||
time: 100000000
|
||||
});
|
||||
var body = layer.getChildFrame('body', index);
|
||||
$.ajax({type: 'POST',dataType:'json', url: json.msg, data: $(body).find('#myform').serialize(),
|
||||
success: function(json) {
|
||||
layer.close(loading);
|
||||
if (json.code) {
|
||||
layer.close(index);
|
||||
$('#dr_".$field['fieldname']."').summernote('reset');
|
||||
$('#dr_".$field['fieldname']."').summernote('pasteHTML', json.data);
|
||||
dr_cmf_tips(1, json.msg);
|
||||
} else {
|
||||
dr_cmf_tips(0, json.msg, json.data.time);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
error: function(HttpRequest, ajaxOptions, thrownError) {
|
||||
dr_ajax_alert_error(HttpRequest, this, thrownError);
|
||||
}
|
||||
});
|
||||
return false;
|
||||
},
|
||||
success: function(layero, index){
|
||||
// 主要用于后台权限验证
|
||||
var body = layer.getChildFrame('body', index);
|
||||
var json = $(body).html();
|
||||
if (json.indexOf('\"code\":0') > 0 && json.length < 500){
|
||||
var obj = JSON.parse(json);
|
||||
layer.close(index);
|
||||
dr_cmf_tips(0, obj.msg);
|
||||
}
|
||||
},
|
||||
content: json.msg+'&is_iframe=1'
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
},
|
||||
error: function(HttpRequest, ajaxOptions, thrownError) {
|
||||
dr_ajax_alert_error(HttpRequest, this, thrownError);
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
", 0);
|
||||
|
||||
|
||||
if (isset($field['setting']['option']['show_bottom_boot']) && $field['setting']['option']['show_bottom_boot']) {
|
||||
$str.= '<div class="mt-checkbox-inline" style="margin-top: 10px;">';
|
||||
$str.= ' <label style="margin-bottom: 0;" class="mt-checkbox mt-checkbox-outline">
|
||||
<input name="is_auto_thumb_'.$field['fieldname'].'" type="checkbox" '.($field['setting']['option']['tool_select_1'] ? 'checked' : '').' value="1"> '.dr_lang('提取第一个图片为缩略图').' <span></span>
|
||||
</label>';
|
||||
$str.= '
|
||||
<label style="margin-bottom: 0;" class="mt-checkbox mt-checkbox-outline">
|
||||
<input id="is_auto_description_'.$field['fieldname'].'" onclick="dr_is_auto_description_'.$field['fieldname'].'()" name="is_auto_description_'.$field['fieldname'].'" type="checkbox" '.($field['setting']['option']['tool_select_2'] ? 'checked' : '').' value="1"> '.dr_lang('提取内容作为描述信息').' <span></span>
|
||||
</label>';
|
||||
$str.= '
|
||||
<label style="margin-bottom: 0;" class="mt-checkbox mt-checkbox-outline">
|
||||
<input name="is_remove_a_'.$field['fieldname'].'" type="checkbox" '.($field['setting']['option']['tool_select_4'] ? 'checked' : '').' value="1"> '.dr_lang('去除站外链接').' <span></span>
|
||||
</label>';
|
||||
if ($field['setting']['option']['tool_select_3']) {
|
||||
$str.= '
|
||||
<label style="margin-bottom: 0;" class="mt-checkbox mt-checkbox-outline">
|
||||
<a class="btn blue btn-xs" onclick="dr_editor_down_img_'.$field['fieldname'].'()"> '.dr_lang('一键下载远程图片').' </a>
|
||||
</label>';
|
||||
}
|
||||
$str.= '</div>';
|
||||
}
|
||||
|
||||
|
||||
|
||||
return $this->input_format($name, $text, $str.$tips);
|
||||
}
|
||||
|
||||
private function _toolbar($json) {
|
||||
if (strpos($json, '"') !== false) {
|
||||
return '';
|
||||
}
|
||||
return ',toolbar: ['.$json.']';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
/**
|
||||
* 系统可用字段
|
||||
* id 文件名称
|
||||
* name 显示名称
|
||||
* used 数组 表示可以用到哪些地方
|
||||
* namespace 是哪个app专属的
|
||||
*/
|
||||
|
||||
return [
|
||||
[
|
||||
'id' => 'Text',
|
||||
'name' => '文本字段',
|
||||
],
|
||||
[
|
||||
'id' => 'Textbtn',
|
||||
'name' => '文本事件',
|
||||
],
|
||||
[
|
||||
'id' => 'Textselect',
|
||||
'name' => '文本选择',
|
||||
],
|
||||
[
|
||||
'id' => 'Textarea',
|
||||
'name' => '多行文本',
|
||||
],
|
||||
[
|
||||
'id' => 'Editor',
|
||||
'name' => '简化编辑器',
|
||||
],
|
||||
[
|
||||
'id' => 'Radio',
|
||||
'name' => '单选按钮',
|
||||
],
|
||||
[
|
||||
'id' => 'Select',
|
||||
'name' => '下拉选择(单选)',
|
||||
],
|
||||
[
|
||||
'id' => 'Selects',
|
||||
'name' => '下拉选择(多选)',
|
||||
],
|
||||
[
|
||||
'id' => 'Checkbox',
|
||||
'name' => '复选框',
|
||||
],
|
||||
[
|
||||
'id' => 'Color',
|
||||
'name' => '颜色选取',
|
||||
],
|
||||
[
|
||||
'id' => 'Date',
|
||||
'name' => '日期',
|
||||
],
|
||||
[
|
||||
'id' => 'Time',
|
||||
'name' => '时间',
|
||||
],
|
||||
[
|
||||
'id' => 'Diy',
|
||||
'name' => '自定义',
|
||||
],
|
||||
[
|
||||
'id' => 'File',
|
||||
'name' => '单文件',
|
||||
],
|
||||
[
|
||||
'id' => 'Files',
|
||||
'name' => '多文件',
|
||||
],
|
||||
[
|
||||
'id' => 'Group',
|
||||
'name' => '单行分组字段',
|
||||
],
|
||||
[
|
||||
'id' => 'Merge',
|
||||
'name' => '多行分组字段',
|
||||
'used' => ['module', 'form', 'mform', 'site'],
|
||||
],
|
||||
[
|
||||
'id' => 'Linkage',
|
||||
'name' => '联动菜单(单选)',
|
||||
],
|
||||
[
|
||||
'id' => 'Linkages',
|
||||
'name' => '联动菜单(多选)',
|
||||
],
|
||||
[
|
||||
'id' => 'Touchspin',
|
||||
'name' => '增减量',
|
||||
],
|
||||
[
|
||||
'id' => 'Property',
|
||||
'name' => '属性参数',
|
||||
],
|
||||
[
|
||||
'id' => 'Uid',
|
||||
'name' => '账号',
|
||||
],
|
||||
[
|
||||
'id' => 'Pay',
|
||||
'name' => '购买(单一)',
|
||||
],
|
||||
[
|
||||
'id' => 'Pays',
|
||||
'name' => '购买(组合)',
|
||||
],
|
||||
[
|
||||
'id' => 'Paystext',
|
||||
'name' => '购买(组合)参数',
|
||||
],
|
||||
[
|
||||
'id' => 'Image',
|
||||
'name' => '图片专用',
|
||||
],
|
||||
[
|
||||
'id' => 'Ftable',
|
||||
'name' => '填写表格',
|
||||
],
|
||||
[
|
||||
'id' => 'Join',
|
||||
'name' => '关联表',
|
||||
],
|
||||
|
||||
|
||||
];
|
||||
@@ -0,0 +1,362 @@
|
||||
<?php namespace Phpcmf\Field;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
class File extends \Phpcmf\Library\A_Field {
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
public function __construct(...$params) {
|
||||
parent::__construct(...$params);
|
||||
$this->fieldtype = TRUE;
|
||||
$this->defaulttype = 'VARCHAR'; // 当用户没有选择字段类型时的缺省值
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段相关属性参数
|
||||
*
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function option($option) {
|
||||
|
||||
$mthumb = '';
|
||||
if (\Phpcmf\Service::M('field')->relatedname == 'module') {
|
||||
$mthumb = '<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('首图作为缩略图').'</label>
|
||||
<div class="col-md-9">
|
||||
<input type="checkbox" name="data[setting][option][stslt]" '.($option['stslt'] ? 'checked' : '').' value="1" data-on-text="'.dr_lang('已开启').'" data-off-text="'.dr_lang('已关闭').'" data-on-color="success" data-off-color="danger" class="make-switch" data-size="small">
|
||||
<span class="help-block">'.dr_lang('当缩略图字段为空时,用本字段的图片来填充(仅对模块字段有效)').'</span>
|
||||
</div>
|
||||
</div>';
|
||||
}
|
||||
if ($this->field && $this->field['fieldname'] != 'thumb') {
|
||||
$mthumb = '';
|
||||
}
|
||||
|
||||
return [$this->field_type($option['fieldtype'], $option['fieldlength']).$this->_search_field().
|
||||
$mthumb.'
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('手动输入').'</label>
|
||||
<div class="col-md-9">
|
||||
<input type="checkbox" name="data[setting][option][input]" '.($option['input'] ? 'checked' : '').' value="1" data-on-text="'.dr_lang('已开启').'" data-off-text="'.dr_lang('已关闭').'" data-on-color="success" data-off-color="danger" class="make-switch" data-size="small">
|
||||
<span class="help-block">'.dr_lang('开启将会出现手动输入文件地址按钮').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('扩展名').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" size="40" name="data[setting][option][ext]" value="'.$option['ext'].'"></label>
|
||||
<span class="help-block">'.dr_lang('格式:jpg,gif,png,exe,html,php,rar,zip').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('文件大小').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" value="'.$option['size'].'" name="data[setting][option][size]"></label>
|
||||
<span class="help-block">'.dr_lang('单位MB').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('分段上传').'</label>
|
||||
<div class="col-md-9">
|
||||
<input type="checkbox" name="data[setting][option][chunk]" '.($option['chunk'] ? 'checked' : '').' value="1" data-on-text="'.dr_lang('已开启').'" data-off-text="'.dr_lang('已关闭').'" data-on-color="success" data-off-color="danger" class="make-switch" data-size="small">
|
||||
<span class="help-block">'.dr_lang('当文件太大时可以采取分段上传,可以提升上传效率').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('显示浏览附件').'</label>
|
||||
<div class="col-md-9">
|
||||
<input type="checkbox" name="data[setting][option][unused]" '.($option['unused'] ? 'checked' : '').' value="1" data-off-text="'.dr_lang('已开启').'" data-on-text="'.dr_lang('已关闭').'" data-off-color="success" data-on-color="danger" class="make-switch" data-size="small">
|
||||
<span class="help-block">'.dr_lang('允许用户选取自己已经上传的附件').'</span>
|
||||
</div>
|
||||
</div>
|
||||
'.$this->attachment($option).'
|
||||
'
|
||||
,
|
||||
'
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('提示扩展名显示').'</label>
|
||||
<div class="col-md-9">
|
||||
<div class="mt-radio-inline">
|
||||
<label class="mt-radio mt-radio-outline"><input type="radio" name="data[setting][option][is_ext_tips]" value="0" '.(!$option['is_ext_tips'] ? 'checked' : '').' /> '.dr_lang('已显示').' <span></span></label>
|
||||
<label class="mt-radio mt-radio-outline"><input type="radio" name="data[setting][option][is_ext_tips]" value="1" '.($option['is_ext_tips'] ? 'checked' : '').' /> '.dr_lang('已关闭').' <span></span></label>
|
||||
</div><span class="help-block">'.dr_lang('提示字段上传的扩展名和大小限制的文本信息').'</span>
|
||||
</div>
|
||||
</div>'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证字段属性
|
||||
*/
|
||||
public function edit_config($post) {
|
||||
|
||||
if (!isset($post['setting']['option']['ext']) || !$post['setting']['option']['ext']) {
|
||||
return dr_return_data(0, dr_lang('扩展名必须填写'));
|
||||
} elseif (!isset($post['setting']['option']['size']) || !$post['setting']['option']['size']) {
|
||||
return dr_return_data(0, dr_lang('文件大小必须填写'));
|
||||
}
|
||||
|
||||
return dr_return_data(1, 'ok');
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段输出
|
||||
*/
|
||||
public function output($value) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取附件id
|
||||
*/
|
||||
public function get_attach_id($value) {
|
||||
|
||||
$data = [];
|
||||
if (!$value || !is_numeric($value)) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
$data[] = $value;
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 附件处理
|
||||
*/
|
||||
public function attach($data, $_data) {
|
||||
|
||||
// 新旧数据都无附件就跳出
|
||||
if (!$data && !$_data) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 新旧数据都一样时表示没做改变就跳出
|
||||
if (dr_diff($data, $_data)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 当无新数据且有旧数据表示删除旧附件
|
||||
if (!$data && $_data) {
|
||||
return [
|
||||
[],
|
||||
[$_data]
|
||||
];
|
||||
}
|
||||
|
||||
// 当无旧数据且有新数据表示增加新附件
|
||||
if ($data && !$_data) {
|
||||
return [
|
||||
[$data],
|
||||
[]
|
||||
];
|
||||
}
|
||||
|
||||
// 剩下的情况就是删除旧文件增加新文件
|
||||
return [
|
||||
[$data],
|
||||
[$_data]
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 字段入库值
|
||||
*
|
||||
* @param array $field 字段信息
|
||||
* @return void
|
||||
*/
|
||||
public function insert_value($field) {
|
||||
|
||||
$value = \Phpcmf\Service::L('Field')->post[$field['fieldname']];
|
||||
|
||||
// 存在缩略图值时,自己就是缩略图
|
||||
if (!$value && $field['fieldname'] == 'thumb' && isset(\Phpcmf\Service::L('Field')->data[$field['ismain']]['thumb']) && \Phpcmf\Service::L('Field')->data[$field['ismain']]['thumb']) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 提取缩略图
|
||||
if ($value && $field['setting']['option']['stslt']) {
|
||||
$_field = \Phpcmf\Service::L('form')->fields;
|
||||
if (isset($_field['thumb']) && $_field['thumb']['fieldtype'] == 'File' && !\Phpcmf\Service::L('Field')->data[$_field['thumb']['ismain']]['thumb']) {
|
||||
$info = \Phpcmf\Service::C()->get_attachment($value, 1);
|
||||
if ($info && in_array($info['fileext'], ['jpg', 'jpeg', 'png', 'gif'])) {
|
||||
\Phpcmf\Service::L('Field')->data[$_field['thumb']['ismain']]['thumb'] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname']] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单输入
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function input($field, $value = '') {
|
||||
|
||||
// 字段禁止修改时就返回显示字符串
|
||||
if ($this->_not_edit($field, $value)) {
|
||||
return $this->show($field, $value);
|
||||
}
|
||||
|
||||
// 字段存储名称
|
||||
$name = $field['fieldname'];
|
||||
|
||||
// 字段显示名称
|
||||
$text = ($field['setting']['validate']['required'] ? '<span class="required" aria-required="true"> * </span>' : '').dr_lang($field['name']);
|
||||
|
||||
// 字段提示信息
|
||||
$tips = ($name == 'title' && APP_DIR) || $field['setting']['validate']['tips'] ? '<span class="help-block" id="dr_'.$field['fieldname'].'_tips">'.$field['setting']['validate']['tips'].'</span>' : '';
|
||||
|
||||
// 表单附加参数
|
||||
$attr = $field['setting']['validate']['formattr'];
|
||||
|
||||
$ts = dr_lang('上传格式要求:%s(%s)', str_replace(',', '、', (string)$field['setting']['option']['ext']), ($field['setting']['option']['size']).'MB');
|
||||
|
||||
$p = dr_authcode([
|
||||
'size' => ($field['setting']['option']['size']),
|
||||
'exts' => $field['setting']['option']['ext'],
|
||||
'attachment' => $field['setting']['option']['attachment'],
|
||||
'image_reduce' => $field['setting']['option']['image_reduce'],
|
||||
], 'ENCODE');
|
||||
|
||||
// 显示模板
|
||||
$tpl = '<div id="dr_'.$name.'_files_row" class="file_row_html files_row">';
|
||||
$tpl.= '<div class="files_row_preview preview">{preview}</div>';
|
||||
$tpl.= '<input type="hidden" '.$attr.' id="dr_'.$name.'" class="files_row_id" name="data['.$name.']" value="{id}" />';
|
||||
$tpl.= '</div>';
|
||||
|
||||
// 已保存数据
|
||||
$val = '';
|
||||
$file_url = '';
|
||||
$show_delete = 0;
|
||||
if ($value) {
|
||||
$file = \Phpcmf\Service::C()->get_attachment($value, 1);
|
||||
if ($file) {
|
||||
$preview = dr_file_preview_html($file['url'], $file['id']);
|
||||
$filepath = $file['attachment'];
|
||||
$title = $file['filename'];
|
||||
$upload = '';
|
||||
} else {
|
||||
$file_url = $filepath = $value;
|
||||
$preview = dr_file_preview_html($value);
|
||||
$upload = '';
|
||||
$title = '';
|
||||
}
|
||||
$val.= str_replace(
|
||||
['{title}', '{id}', '{filepath}', '{preview}', '{upload}'],
|
||||
[$title, $value, dr_strcut($filepath, 30), $preview, $upload],
|
||||
$tpl
|
||||
);
|
||||
$show_delete = 1;
|
||||
} else {
|
||||
$val.= '<input type="hidden" '.$attr.' id="dr_'.$name.'" name="data['.$name.']" value="" />';
|
||||
}
|
||||
|
||||
$json = json_encode([
|
||||
'name' => $name,
|
||||
'ext' => !$field['setting']['option']['ext'] || $field['setting']['option']['ext'] == '*' ? 'null' : ' /(\.|\/)('.str_replace(',', '|', $field['setting']['option']['ext']).')$/i',
|
||||
'size' => floatval($field['setting']['option']['size']) * 1024 * 1024,
|
||||
'url' => dr_web_prefix(''.(IS_ADMIN ? SELF.'?c=api' : 'index.php?s=api&c=file').'&is_iframe=1&token='.dr_get_csrf_token()).'&siteid='.SITE_ID.'&m=upload&p='.$p.'&fid='.$field['id'],
|
||||
'unused_url' => dr_web_prefix(''.(IS_ADMIN ? SELF.'?c=api' : 'index.php?s=api&c=file').'&m=input_file_list&is_iframe=1&p=' . $p . '&fid=' . $field['id']),
|
||||
'input_url' => dr_web_prefix(''.(IS_ADMIN ? SELF.'?c=api' : 'index.php?s=api&c=file').'&m=input_file_url&is_iframe=1&token='.dr_get_csrf_token().'&siteid='.SITE_ID.'&p='.$p.'&fid='.$field['id'].'&file='.urlencode($file_url).'&one=1'),
|
||||
'tpl' => $tpl,
|
||||
'area' => \Phpcmf\Service::IS_MOBILE_USER() ? ["95%", "90%"] : ["80%", "80%"],
|
||||
'url_area' => \Phpcmf\Service::IS_MOBILE_USER() ? ["95%", "90%"] : ["50%", "300px"],
|
||||
'chunk' => $field['setting']['option']['chunk'] ? 20 * 1024 * 1024 : 0,
|
||||
]);
|
||||
|
||||
$use = '';
|
||||
if (!$field['setting']['option']['unused'] && \Phpcmf\Service::C()->uid) {
|
||||
$use.= '<button type="button" class="btn red btn-sm fileinput-unused">
|
||||
<i class="fa fa-folder-open"></i>
|
||||
<span> '.dr_lang('浏览').' </span>
|
||||
</button>';
|
||||
}
|
||||
if ($field['setting']['option']['input']) {
|
||||
$use.= '<button style="margin-left: 5px;" type="button" class="btn green btn-sm fileinput-url">
|
||||
<i class="fa fa-edit"></i>
|
||||
<span> '.dr_lang('地址').' </span>
|
||||
</button>';
|
||||
}
|
||||
$use.= '<button onclick="fileupload_file_remove(\''.$name.'\')" style="margin-left: 5px;'.(!$show_delete ? 'display:none' : '').'" type="button" class="btn red btn-sm fileinput-delete">
|
||||
<i class="fa fa-trash"></i>
|
||||
<span> '.dr_lang('删除').' </span>
|
||||
</button>';
|
||||
|
||||
// 表单输出
|
||||
$str = '
|
||||
<div class="row fileupload-buttonbar" id="fileupload_'.$name.'">
|
||||
<div class="col-lg-12">
|
||||
<button class="btn blue btn-sm fileinput-button">
|
||||
<i class="fa fa-plus"></i>
|
||||
<span> '.dr_lang('上传').' </span>
|
||||
<input type="file" name="file_data">
|
||||
</button>
|
||||
|
||||
'.$use.'
|
||||
|
||||
<span class="fileupload-process"> </span>
|
||||
</div>
|
||||
<div class="col-lg-12 fileupload-progress fade" style="display:none">
|
||||
<div class="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100">
|
||||
<div class="progress-bar progress-bar-success" style="width:0%;"> </div>
|
||||
</div>
|
||||
</div>
|
||||
</div>';
|
||||
if (!$field['setting']['option']['is_ext_tips']) {
|
||||
$str.= '<p class="finecms-file-ts">'.$ts.'</p>';
|
||||
}
|
||||
$str.= '<div id="fileupload_'.$name.'_files" class="files">'.$val.'</div>';
|
||||
|
||||
if (!$this->is_load_js('File')) {
|
||||
$str.= '
|
||||
<link href="'.ROOT_THEME_PATH.'assets/global/plugins/jquery-fileupload/css/jquery.fileupload.css?v='.CMF_UPDATE_TIME.'" rel="stylesheet" type="text/css" />
|
||||
<script src="'.ROOT_THEME_PATH.'assets/global/plugins/jquery-fileupload/js/jquery.fileupload.min.js?v='.CMF_UPDATE_TIME.'" type="text/javascript"></script>
|
||||
';
|
||||
$this->set_load_js('File', 1);
|
||||
}
|
||||
|
||||
$str.= '<script type="text/javascript">
|
||||
$(function() {
|
||||
fileupload_file_init('.$json.');
|
||||
});
|
||||
</script>';
|
||||
|
||||
return $this->input_format($name, $text, $str.$tips);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 字段表单显示
|
||||
*
|
||||
* @param string $field 字段数组
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function show($field, $value = null) {
|
||||
|
||||
$html = '';
|
||||
|
||||
if ($value) {
|
||||
// 显示模板
|
||||
$file = \Phpcmf\Service::C()->get_attachment($value, 1);
|
||||
if ($file) {
|
||||
$preview = dr_file_preview_html($file['url'], $file['id']);
|
||||
} else {
|
||||
$preview = dr_file_preview_html($value);
|
||||
}
|
||||
$html = '<div class="files_row_preview preview">'.$preview.'</div>';
|
||||
}
|
||||
|
||||
return $this->input_format($field['fieldname'], $field['name'], $html);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,542 @@
|
||||
<?php namespace Phpcmf\Field;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
class Files extends \Phpcmf\Library\A_Field {
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
public function __construct(...$params) {
|
||||
parent::__construct(...$params);
|
||||
$this->close_xss = 1; // 关闭xss验证
|
||||
$this->fieldtype = ['TEXT' => ''];
|
||||
$this->defaulttype = 'TEXT';
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段相关属性参数
|
||||
*
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function option($option) {
|
||||
|
||||
$mthumb = '';
|
||||
if (\Phpcmf\Service::M('field')->relatedname == 'module') {
|
||||
$mthumb = '<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('首图作为缩略图').'</label>
|
||||
<div class="col-md-9">
|
||||
<input type="checkbox" name="data[setting][option][stslt]" '.($option['stslt'] ? 'checked' : '').' value="1" data-on-text="'.dr_lang('已开启').'" data-off-text="'.dr_lang('已关闭').'" data-on-color="success" data-off-color="danger" class="make-switch" data-size="small">
|
||||
<span class="help-block">'.dr_lang('当缩略图字段为空时,用本字段的图片来填充(仅对模块字段有效)').'</span>
|
||||
</div>
|
||||
</div>';
|
||||
}
|
||||
|
||||
return [$this->_search_field().$mthumb.'
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('手动输入').'</label>
|
||||
<div class="col-md-9">
|
||||
<input type="checkbox" name="data[setting][option][input]" '.($option['input'] ? 'checked' : '').' value="1" data-on-text="'.dr_lang('已开启').'" data-off-text="'.dr_lang('已关闭').'" data-on-color="success" data-off-color="danger" class="make-switch" data-size="small">
|
||||
<span class="help-block">'.dr_lang('开启将会出现手动输入文件地址按钮').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('附件名称').'</label>
|
||||
<div class="col-md-9">
|
||||
<input type="checkbox" name="data[setting][option][name]" '.($option['name'] ? 'checked' : '').' value="1" data-on-text="'.dr_lang('已开启').'" data-off-text="'.dr_lang('已关闭').'" data-on-color="success" data-off-color="danger" class="make-switch" data-size="small">
|
||||
<span class="help-block">'.dr_lang('开启将会出现单行文本输入框').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('描述文本').'</label>
|
||||
<div class="col-md-9">
|
||||
<input type="checkbox" name="data[setting][option][desc]" '.($option['desc'] ? 'checked' : '').' value="1" data-on-text="'.dr_lang('已开启').'" data-off-text="'.dr_lang('已关闭').'" data-on-color="success" data-off-color="danger" class="make-switch" data-size="small">
|
||||
<span class="help-block">'.dr_lang('开启将会出现多行文本输入框').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('文件大小').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input id="field_default_value" type="text" class="form-control" value="'.$option['size'].'" name="data[setting][option][size]"></label>
|
||||
<span class="help-block">'.dr_lang('单位MB').'</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('分段上传').'</label>
|
||||
<div class="col-md-9">
|
||||
<input type="checkbox" name="data[setting][option][chunk]" '.($option['chunk'] ? 'checked' : '').' value="1" data-on-text="'.dr_lang('已开启').'" data-off-text="'.dr_lang('已关闭').'" data-on-color="success" data-off-color="danger" class="make-switch" data-size="small">
|
||||
<span class="help-block">'.dr_lang('当文件太大时可以采取分段上传,可以提升上传效率').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('滚动显示').'</label>
|
||||
<div class="col-md-9">
|
||||
<input type="checkbox" name="data[setting][option][scroller]" '.($option['scroller'] ? 'checked' : '').' value="1" data-on-text="'.dr_lang('已开启').'" data-off-text="'.dr_lang('已关闭').'" data-on-color="success" data-off-color="danger" class="make-switch" data-size="small">
|
||||
<span class="help-block">'.dr_lang('当文件文件上传太多时,已上传文件列表可以以固定高度来下来滚动显示').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('显示方式').'</label>
|
||||
<div class="col-md-9">
|
||||
<input type="checkbox" name="data[setting][option][grid]" '.($option['grid'] ? 'checked' : '').' value="1" data-on-text="'.dr_lang('传统模式').'" data-off-text="'.dr_lang('卡片模式').'" data-on-color="success" data-off-color="danger" class="make-switch" data-size="small">
|
||||
<span class="help-block">'.dr_lang('上传后的文件列表采用卡片式显示,适用于图片类文件显示方式').'</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('上传数量').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" value="'.$option['count'].'" name="data[setting][option][count]"></label>
|
||||
<span class="help-block">'.dr_lang('每次最多上传的文件数量').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('扩展名').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" size="40" name="data[setting][option][ext]" value="'.$option['ext'].'"></label>
|
||||
<span class="help-block">'.dr_lang('格式:jpg,gif,png,exe,html,php,rar,zip').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('显示浏览附件').'</label>
|
||||
<div class="col-md-9">
|
||||
<input type="checkbox" name="data[setting][option][unused]" '.($option['unused'] ? 'checked' : '').' value="1" data-off-text="'.dr_lang('已开启').'" data-on-text="'.dr_lang('已关闭').'" data-off-color="success" data-on-color="danger" class="make-switch" data-size="small">
|
||||
<span class="help-block">'.dr_lang('允许用户选取自己已经上传的附件').'</span>
|
||||
</div>
|
||||
</div>
|
||||
'.$this->attachment($option).'',
|
||||
|
||||
'
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('提示扩展名显示').'</label>
|
||||
<div class="col-md-9">
|
||||
<div class="mt-radio-inline">
|
||||
<label class="mt-radio mt-radio-outline"><input type="radio" name="data[setting][option][is_ext_tips]" value="0" '.(!$option['is_ext_tips'] ? 'checked' : '').' /> '.dr_lang('已显示').' <span></span></label>
|
||||
<label class="mt-radio mt-radio-outline"><input type="radio" name="data[setting][option][is_ext_tips]" value="1" '.($option['is_ext_tips'] ? 'checked' : '').' /> '.dr_lang('已关闭').' <span></span></label>
|
||||
</div>
|
||||
<span class="help-block">'.dr_lang('提示字段上传的扩展名和大小限制的文本信息').'</span>
|
||||
</div>
|
||||
</div>'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证字段属性
|
||||
*/
|
||||
public function edit_config($post) {
|
||||
|
||||
if (!isset($post['setting']['option']['ext']) || !$post['setting']['option']['ext']) {
|
||||
return dr_return_data(0, dr_lang('扩展名必须填写'));
|
||||
} elseif (!isset($post['setting']['option']['size']) || !$post['setting']['option']['size']) {
|
||||
return dr_return_data(0, dr_lang('文件大小必须填写'));
|
||||
} elseif (!isset($post['setting']['option']['count']) || !$post['setting']['option']['count']) {
|
||||
return dr_return_data(0, dr_lang('上传数量必须填写'));
|
||||
}
|
||||
|
||||
return dr_return_data(1, 'ok');
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段输出
|
||||
*/
|
||||
public function output($value) {
|
||||
return dr_get_files($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取附件id
|
||||
*/
|
||||
public function get_attach_id($value) {
|
||||
|
||||
$data = [];
|
||||
$value = dr_string2array($value);
|
||||
|
||||
if (!$value) {
|
||||
return $data;
|
||||
} elseif (!isset($value['file'])) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
foreach ($value['file'] as $i => $file) {
|
||||
is_numeric($file) && $data[] = $file;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段入库值
|
||||
*/
|
||||
public function insert_value($field) {
|
||||
|
||||
$data = [];
|
||||
$value = \Phpcmf\Service::L('Field')->post[$field['fieldname']];
|
||||
if ($value && is_array($value) && $value['id']) {
|
||||
foreach ($value['id'] as $id => $aid) {
|
||||
$title = (string)$value['title'][$id];
|
||||
$data['file'][$id] = $aid ? $aid : (string)$value['file'][$id];
|
||||
$data['title'][$id] = trim($title);
|
||||
$data['description'][$id] = $value['description'][$id] ? trim($value['description'][$id]) : '';
|
||||
}
|
||||
}
|
||||
|
||||
// 提取缩略图
|
||||
if ($data['file'] && is_array($data['file']) && $field['setting']['option']['stslt']) {
|
||||
$_field = \Phpcmf\Service::L('form')->fields;
|
||||
if (isset($_field['thumb']) && $_field['thumb']['fieldtype'] == 'File' && !\Phpcmf\Service::L('Field')->data[intval($_field['thumb']['ismain'])]['thumb']) {
|
||||
$one = array_key_first($data['file']);
|
||||
if ($data['file'][$one]) {
|
||||
$info = \Phpcmf\Service::C()->get_attachment($data['file'][$one], 1);
|
||||
if ($info && in_array($info['fileext'], ['jpg', 'jpeg', 'png', 'gif'])) {
|
||||
\Phpcmf\Service::L('Field')->data[intval($_field['thumb']['ismain'])]['thumb'] = $data['file'][$one];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname']] = dr_array2string($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 附件处理
|
||||
*/
|
||||
public function attach($data, $_data) {
|
||||
|
||||
$data = dr_string2array($data);
|
||||
$_data = dr_string2array($_data);
|
||||
|
||||
!isset($_data['file']) && $_data =['file' => NULL];
|
||||
!isset($data['file']) && $data = ['file' => NULL];
|
||||
|
||||
// 新旧数据都无附件就跳出
|
||||
if (!$data['file'] && !$_data['file']) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 新旧数据都一样时表示没做改变就跳出
|
||||
if (dr_diff($data['file'], $_data['file'])) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 当无新数据且有旧数据表示删除旧附件
|
||||
if (!$data['file'] && $_data['file']) {
|
||||
return [ [], $_data['file'] ];
|
||||
}
|
||||
|
||||
// 当无旧数据且有新数据表示增加新附件
|
||||
if ($data['file'] && !$_data['file']) {
|
||||
|
||||
return [$data['file'], []];
|
||||
}
|
||||
|
||||
// 剩下的情况就是删除旧文件增加新文件
|
||||
|
||||
|
||||
// 新旧附件的交集,表示固定的
|
||||
$intersect = array_intersect($data['file'], $_data['file']);
|
||||
|
||||
return [
|
||||
array_diff($data['file'], $intersect), // 固有的与新文件中的差集表示新增的附件
|
||||
array_diff($_data['file'], $intersect), // 固有的与旧文件中的差集表示待删除的附件
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证加载变量设置
|
||||
*/
|
||||
public function set_load_js($name, $value) {
|
||||
\Phpcmf\Service::C()->loadjs['File'] = \Phpcmf\Service::C()->loadjs[$name] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单输入
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function input($field, $value = '') {
|
||||
|
||||
// 字段禁止修改时就返回显示字符串
|
||||
if ($this->_not_edit($field, $value)) {
|
||||
return $this->show($field, $value);
|
||||
}
|
||||
|
||||
// 字段存储名称
|
||||
$name = $field['fieldname'];
|
||||
|
||||
// 字段显示名称
|
||||
$text = ($field['setting']['validate']['required'] ? '<span class="required" aria-required="true"> * </span>' : '') . dr_lang($field['name']);
|
||||
|
||||
// 字段提示信息
|
||||
$tips = ($name == 'title' && APP_DIR) || $field['setting']['validate']['tips'] ? '<span class="help-block" id="dr_' . $field['fieldname'] . '_tips">' . $field['setting']['validate']['tips'] . '</span>' : '';
|
||||
|
||||
$count = intval($field['setting']['option']['count']);
|
||||
$ts = dr_lang('上传格式要求:%s(%s),最多上传%s个文件', str_replace(',', '、', (string)$field['setting']['option']['ext']), ($field['setting']['option']['size']) . 'MB', $count);
|
||||
|
||||
|
||||
$p = dr_authcode([
|
||||
'size' => ($field['setting']['option']['size']),
|
||||
'exts' => $field['setting']['option']['ext'],
|
||||
'attachment' => $field['setting']['option']['attachment'],
|
||||
'image_reduce' => $field['setting']['option']['image_reduce'],
|
||||
'count' => $count,
|
||||
], 'ENCODE');
|
||||
// 显示模板
|
||||
if (!$field['setting']['option']['grid']) {
|
||||
|
||||
$tpl = '<div class="grid-item files_row">';
|
||||
$tpl.= '<div class="files_row_preview preview">{preview}</div>';
|
||||
$tpl.= '<input type="hidden" class="files_row_id" name="data[' . $name . '][id][]" value="{id}">';
|
||||
$tpl.= '<input class="files_row_name" {disabled} type="hidden" name="data[' . $name . '][file][]" value="{filepath}">';
|
||||
|
||||
|
||||
$tpl.= '<div class="op-btn">';
|
||||
$tpl.= '<label><button onclick="dr_file_remove(this)" type="button" class="btn red file_delete btn-xs"><i class="fa fa-trash"></i></button></label>';
|
||||
|
||||
|
||||
$tpl.= $js_rm = '<label><button onclick="fileupload_file_edit(\''.$name.'\',this)" type="button" class="fileinput-button btn green file_edit btn-xs"><i class="fa fa-upload"></i>{upload}</button></label>';
|
||||
|
||||
$tpl.= '</div>';
|
||||
|
||||
if ($field['setting']['option']['name']) {
|
||||
$tpl.= '<div class="col-md-12 files_show_title_html">';
|
||||
$tpl .= '<input placeholder="'.dr_lang('名称').'" class="form-control files_row_title" type="text" name="data[' . $name . '][title][]" value="{title}">';
|
||||
$tpl.= '</div>';
|
||||
}
|
||||
|
||||
if ($field['setting']['option']['desc']) {
|
||||
$tpl.= '<div class="col-md-12 files_show_description_html">';
|
||||
$tpl.= '<textarea placeholder="'.dr_lang('描述').'" class="form-control files_row_description" name="data['.$name.'][description][]">{description}</textarea>';
|
||||
$tpl.= '</div>';
|
||||
}
|
||||
|
||||
$tpl.= '</div>';
|
||||
} else {
|
||||
// 普通table模式
|
||||
if ($field['setting']['option']['name'] or $field['setting']['option']['desc']) {
|
||||
// 有名字和描述
|
||||
$tpl = '<tr class="template-download files_row">';
|
||||
$tpl.= '<td style="text-align:center;width: 80px;">';
|
||||
$tpl.= '<div class="files_row_preview preview">{preview}</div>';
|
||||
$tpl.= '</td>';
|
||||
$tpl.= '<td class="files_show_info">';
|
||||
$tpl.= '<div class="row">';
|
||||
$tpl.= '<div class="col-md-12 files_show_title_html">';
|
||||
if ($field['setting']['option']['name']) {
|
||||
$tpl .= '<input placeholder="'.dr_lang('名称').'" class="form-control files_row_title" type="text" name="data[' . $name . '][title][]" value="{title}">';
|
||||
}
|
||||
$tpl.= '<input type="hidden" class="files_row_id" name="data[' . $name . '][id][]" value="{id}">';
|
||||
$tpl.= '<input class="files_row_name" {disabled} type="hidden" name="data[' . $name . '][file][]" value="{filepath}">';
|
||||
$tpl.= '</div>';
|
||||
if ($field['setting']['option']['desc']) {
|
||||
$tpl.= '<div class="col-md-12 files_show_description_html">';
|
||||
$tpl.= '<textarea placeholder="'.dr_lang('描述').'" class="form-control files_row_description" name="data['.$name.'][description][]">{description}</textarea>';
|
||||
$tpl.= '</div>';
|
||||
}
|
||||
$tpl.= '</div>';
|
||||
$tpl.= '</td>';
|
||||
|
||||
$tpl.= '<td style="text-align:center;width: 80px;">';
|
||||
$tpl.= '<label><button onclick="dr_file_remove(this)" type="button" class="btn red file_delete btn-sm"><i class="fa fa-trash"></i></button></label>';
|
||||
|
||||
$tpl.= $js_rm = '<label><button onclick="fileupload_file_edit(\''.$name.'\',this)" type="button" class="fileinput-button btn green file_edit btn-sm"><i class="fa fa-upload"></i>{upload}</button></label>';
|
||||
|
||||
$tpl.= '</td>';
|
||||
$tpl.= '</tr>';
|
||||
} else {
|
||||
// 没有描述和名字修改
|
||||
$tpl = '<div class="template-download files_row">';
|
||||
$tpl.= '<div class="files_row_preview preview">{preview}</div>';
|
||||
$tpl.= '<input type="hidden" class="files_row_id" name="data[' . $name . '][id][]" value="{id}">';
|
||||
$tpl.= '<input class="files_row_name" {disabled} type="hidden" name="data[' . $name . '][file][]" value="{filepath}">';
|
||||
|
||||
$tpl.= '<div class="op-btn">';
|
||||
$tpl.= '<label><button onclick="dr_file_remove(this)" type="button" class="btn red file_delete btn-xs"><i class="fa fa-trash"></i></button></label>';
|
||||
$tpl.= $js_rm = '<label><button onclick="fileupload_file_edit(\''.$name.'\',this)" type="button" class="fileinput-button btn green file_edit btn-xs"><i class="fa fa-edit"></i>{upload}</button></label>';
|
||||
|
||||
$tpl.= '</div>';
|
||||
$tpl.= '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
// 已保存数据
|
||||
$val = '';
|
||||
$value = dr_get_files($value);
|
||||
if ($value) {
|
||||
foreach ($value as $i => $t) {
|
||||
$id = $t['id'] ? $t['id'] : $t['file'];
|
||||
$file = \Phpcmf\Service::C()->get_attachment($id, 1);
|
||||
$description = $t['description'] ? htmlspecialchars($t['description']) : '';
|
||||
if ($file) {
|
||||
$disabled = 'readonly';
|
||||
$preview = dr_file_preview_html($file['url'], $file['id']);
|
||||
$filepath = dr_strcut($file['attachment'], 30);
|
||||
$upload = '<input type="file" name="file_data">';
|
||||
} else {
|
||||
$disabled = '';
|
||||
$filepath = htmlspecialchars((string)$id);
|
||||
$preview = dr_file_preview_html($id);
|
||||
$upload = '';
|
||||
//$id = '';
|
||||
}
|
||||
$val.= str_replace(
|
||||
['{title}', '{description}', '{id}', '{file}', '{filepath}', '{disabled}', '{preview}', '{upload}'],
|
||||
[htmlspecialchars((string)$t['title']), $description, $id, $id, $filepath, $disabled, $preview, $upload],
|
||||
$tpl
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$field['setting']['option']['grid']) {
|
||||
$val = '<div id="fileupload_'.$name.'_files" class="files-grid-list">'.$val.'</div>';
|
||||
} else {
|
||||
if ($field['setting']['option']['name'] or $field['setting']['option']['desc']) {
|
||||
$val = '<table role="presentation" class="table table-striped table-fc-upload clearfix">
|
||||
<tbody id="fileupload_'.$name.'_files" class="files scroller_body">'.$val.'</tbody>
|
||||
</table>';
|
||||
} else {
|
||||
$val = '<div id="fileupload_'.$name.'_files" class="files scroller_body files-image-list">'.$val.'</div>';
|
||||
}
|
||||
}
|
||||
|
||||
$json = json_encode([
|
||||
'name' => $name,
|
||||
'ext' => !$field['setting']['option']['ext'] || $field['setting']['option']['ext'] == '*' ? 'null' : ' /(\.|\/)('.str_replace(',', '|', $field['setting']['option']['ext']).')$/i',
|
||||
'size' => floatval($field['setting']['option']['size']) * 1024 * 1024,
|
||||
'url' => dr_web_prefix(''.(IS_ADMIN ? SELF.'?c=api' : 'index.php?s=api&c=file').'&is_iframe=1&token='.dr_get_csrf_token()).'&siteid=' . SITE_ID . '&m=upload&p=' . $p . '&fid=' . $field['id'],
|
||||
'unused_url' => dr_web_prefix(''.(IS_ADMIN ? SELF.'?c=api' : 'index.php?s=api&c=file').'&m=input_file_list&is_iframe=1&token='.dr_get_csrf_token()).'&siteid='.SITE_ID.'&p=' . $p . '&fid=' . $field['id'],
|
||||
'input_url' => dr_web_prefix(''.(IS_ADMIN ? SELF.'?c=api' : 'index.php?s=api&c=file').'&m=input_file_url&is_iframe=1&token='.dr_get_csrf_token()).'&siteid='.SITE_ID.'&p='.$p.'&fid='.$field['id'].'&one='.($field['setting']['option']['name']?0:1),
|
||||
'tpl' => str_replace($js_rm, '', $tpl),
|
||||
'area' => \Phpcmf\Service::IS_MOBILE_USER() ? ["95%", "90%"] : ["80%", "80%"],
|
||||
'url_area' => \Phpcmf\Service::IS_MOBILE_USER() ? ["95%", "90%"] : ["50%", "340px"],
|
||||
'count' => $count,
|
||||
'error' => dr_lang('上传文件不能超过%s个', $count).(CI_DEBUG ? '(可在自定义字段中设置本字段的个数值)' : ''),
|
||||
'chunk' => $field['setting']['option']['chunk'] ? 20 * 1024 * 1024 : 0,
|
||||
]);
|
||||
|
||||
$use = '';
|
||||
if (!$field['setting']['option']['unused'] && \Phpcmf\Service::C()->uid) {
|
||||
$use.= '<button type="button" class="btn red btn-sm fileinput-unused">
|
||||
<i class="fa fa-folder-open"></i>
|
||||
<span> '.dr_lang('浏览').' </span>
|
||||
</button>';
|
||||
}
|
||||
if ($field['setting']['option']['input']) {
|
||||
$use.= '<button style="margin-left: 5px;" type="button" class="btn green btn-sm fileinput-url">
|
||||
<i class="fa fa-edit"></i>
|
||||
<span> '.dr_lang('地址').' </span>
|
||||
</button>';
|
||||
}
|
||||
|
||||
// 表单输出
|
||||
$str = '
|
||||
<div class="row fileupload-buttonbar" id="fileupload_'.$name.'">
|
||||
<div class="col-lg-12">
|
||||
<button class="btn blue btn-sm fileinput-button">
|
||||
<i class="fa fa-plus"></i>
|
||||
<span> '.dr_lang('上传').' </span>
|
||||
<input type="file" name="file_data" multiple="">
|
||||
</button>
|
||||
|
||||
'.$use.'
|
||||
|
||||
<span class="fileupload-process"> </span>
|
||||
</div>
|
||||
<div class="col-lg-12 fileupload-progress fade" style="display:none">
|
||||
<div class="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100">
|
||||
<div class="progress-bar progress-bar-success" style="width:0%;"> </div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
';
|
||||
if (!$field['setting']['option']['is_ext_tips']) {
|
||||
$str.= '<p class="finecms-file-ts">'.$ts.'</p>';
|
||||
}
|
||||
$str.= '
|
||||
<div class="scroller_'.$name.'_files">
|
||||
<div class="'.($field['setting']['option']['scroller'] ? 'scroller"' : '').'" data-inited="0" data-initialized="1" data-always-visible="1" data-rail-visible="1">
|
||||
'.$val.'
|
||||
</div>
|
||||
</div>
|
||||
';
|
||||
|
||||
if (!$this->is_load_js('File')) {
|
||||
$str.= '
|
||||
<link href="'.ROOT_THEME_PATH.'assets/global/plugins/jquery-fileupload/css/jquery.fileupload.css?v='.CMF_UPDATE_TIME.'" rel="stylesheet" type="text/css" />
|
||||
<script src="'.ROOT_THEME_PATH.'assets/global/plugins/jquery-fileupload/js/jquery.fileupload.min.js?v='.CMF_UPDATE_TIME.'" type="text/javascript"></script>
|
||||
';
|
||||
$this->set_load_js('File', 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
$str.= '<script type="text/javascript">
|
||||
var files_json_'.$name.' = '.$json.';
|
||||
$(function() {
|
||||
fileupload_files_init(files_json_'.$name.');
|
||||
'.($field['setting']['option']['scroller'] && dr_count($value)>10 ? '$(".scroller_'.$name.'_files .scroller").height("450");' : '').'
|
||||
});
|
||||
</script>
|
||||
|
||||
';
|
||||
|
||||
|
||||
// 输出最终表单显示
|
||||
return $this->input_format($name, $text, $str.$tips);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单显示
|
||||
*
|
||||
* @param string $field 字段数组
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function show($field, $value = null) {
|
||||
|
||||
$html = '';
|
||||
$value = dr_get_files($value);
|
||||
if ($value) {
|
||||
|
||||
// 显示模板
|
||||
$tpl = '<tr class="template-download files_row">';
|
||||
$tpl.= '<td style="text-align:center;width:90px;border-top:0">';
|
||||
$tpl.= '<div class="files_row_preview preview">{preview}</div>';
|
||||
$tpl.= '</td>';
|
||||
$tpl.= '<td style="border-top:0">';
|
||||
$tpl.= '{title} {description}';
|
||||
$tpl.= '</td>';
|
||||
$tpl.= '</tr>';
|
||||
$html.= '<table role="presentation" class="table table-striped table-fc-upload clearfix">';
|
||||
$html.= '<tbody class="files">';
|
||||
foreach ($value as $i => $t) {
|
||||
$id = $t['id'] ? $t['id'] : $t['file'];
|
||||
$file = \Phpcmf\Service::C()->get_attachment($id, 1);
|
||||
$description = $t['description'] ? $t['description'] : '';
|
||||
if ($file) {
|
||||
$preview = dr_file_preview_html($file['url'], $file['id']);
|
||||
$filepath = $file['attachment'];
|
||||
$upload = '';
|
||||
} else {
|
||||
$filepath = $id;
|
||||
$preview = dr_file_preview_html($id);
|
||||
$upload = '';
|
||||
}
|
||||
$html.= str_replace(
|
||||
['{title}', '{description}', '{id}', '{filepath}', '{preview}', '{upload}'],
|
||||
[$t['title'], $description, $value, $filepath, $preview, $upload],
|
||||
$tpl
|
||||
);
|
||||
}
|
||||
$html.= '</tbody>';
|
||||
$html.= '</table>';
|
||||
}
|
||||
|
||||
return $this->input_format($field['fieldname'], $field['name'], $html);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,614 @@
|
||||
<?php namespace Phpcmf\Field;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
class Ftable extends \Phpcmf\Library\A_Field {
|
||||
|
||||
protected $_load_date;
|
||||
protected $_load_datetime;
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
public function __construct(...$params) {
|
||||
parent::__construct(...$params);
|
||||
$this->fieldtype = ['TEXT' => ''];
|
||||
$this->defaulttype = 'TEXT';
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段相关属性参数
|
||||
*
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function option($option) {
|
||||
|
||||
$html = '';
|
||||
$max = dr_count($option['field'])+5;
|
||||
for ($i = 1; $i <= $max; $i++) {
|
||||
$html.= '<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('表格第%s列', $i).'</label>
|
||||
<div class="col-md-9">
|
||||
<label>'.$this->_field_type_select($i, $option['field'][$i]['type']).'</label>
|
||||
<label><input type="text" placeholder="'.dr_lang('列名称').'" class="form-control" size="20" value="'.$option['field'][$i]['name'].'" name="data[setting][option][field]['.$i.'][name]"></label>
|
||||
<label><input type="text" placeholder="'.dr_lang('列宽度').'" class="form-control" size="20" value="'.$option['field'][$i]['width'].'" name="data[setting][option][field]['.$i.'][width]"></label>
|
||||
<label id="dr_h_type_2"><input type="text" placeholder="'.dr_lang('选项配置').'" class="form-control input-xlarge" size="20" value="'.$option['field'][$i]['option'].'" name="data[setting][option][field]['.$i.'][option]">
|
||||
</label><label> <a href="javascript:dr_help(\'1234\');"><i class="fa fa-question-circle"></i></a>
|
||||
</label>
|
||||
</div>
|
||||
</div>';
|
||||
}
|
||||
|
||||
$hang = '';
|
||||
$hs = (int)$option['count'];
|
||||
!$hs && $hs = 5;
|
||||
for ($i = 1; $i <= $hs; $i++) {
|
||||
$hang.= '<div class="form-group is_first_hang">
|
||||
<label class="col-md-2 control-label">'.dr_lang('表格第%s行', $i).'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" placeholder="'.dr_lang('行名称').'" class="form-control" size="20" value="'.$option['hang'][$i]['name'].'" name="data[setting][option][hang]['.$i.'][name]"></label>
|
||||
</div>
|
||||
</div>';
|
||||
}
|
||||
|
||||
return [$this->_search_field().'
|
||||
<script>
|
||||
$(function() {
|
||||
dr_is_first_hang('.(int)$option['is_first_hang'].');
|
||||
dr_is_add_hang('.(int)$option['is_add'].');
|
||||
});
|
||||
function dr_is_first_hang(v) {
|
||||
if (v == 1) {
|
||||
$(".is_first_hang").show();
|
||||
} else {
|
||||
$(".is_first_hang").hide();
|
||||
}
|
||||
}
|
||||
function dr_is_add_hang(v) {
|
||||
if (v == 1) {
|
||||
$(".is_add_hang").hide();
|
||||
} else {
|
||||
$(".is_add_hang").show();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('无限添加行数').'</label>
|
||||
<div class="col-md-9">
|
||||
<div class="mt-radio-inline">
|
||||
<label class="mt-radio mt-radio-outline"><input type="radio" onclick="dr_is_add_hang(this.value)" name="data[setting][option][is_add]" value="1" '.($option['is_add'] ? 'checked' : '').'> '.dr_lang('开启').' <span></span></label>
|
||||
<label class="mt-radio mt-radio-outline"><input type="radio" onclick="dr_is_add_hang(this.value)" name="data[setting][option][is_add]" value="0" '.(!$option['is_add'] ? 'checked' : '').'> '.dr_lang('关闭').' <span></span></label>
|
||||
</div>
|
||||
<span class="help-block">'.dr_lang('开启后可以在录入数据时自由添加行数,关闭时就只能是固定行数').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group is_add_hang">
|
||||
<label class="col-md-2 control-label">'.dr_lang('表格的首行').'</label>
|
||||
<div class="col-md-9">
|
||||
<div class="mt-radio-inline">
|
||||
<label class="mt-radio mt-radio-outline"><input type="radio" onclick="dr_is_first_hang(this.value)" name="data[setting][option][is_first_hang]" value="1" '.($option['is_first_hang'] ? 'checked' : '').'> '.dr_lang('显示').' <span></span></label>
|
||||
<label class="mt-radio mt-radio-outline"><input type="radio" onclick="dr_is_first_hang(this.value)" name="data[setting][option][is_first_hang]" value="0" '.(!$option['is_first_hang'] ? 'checked' : '').'> '.dr_lang('隐藏').' <span></span></label>
|
||||
</div>
|
||||
<span class="help-block">'.dr_lang('首行表示每行的行名').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="is_add_hang">
|
||||
<div class="form-group ">
|
||||
<label class="col-md-2 control-label">'.dr_lang('表格行数').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" size="10" name="data[setting][option][count]" value="'.$option['count'].'"></label>
|
||||
<span class="help-block">'.dr_lang('填写表格的行数,1表示只有一行表格,至少属于1行表格').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group is_first_hang">
|
||||
<label class="col-md-2 control-label">'.dr_lang('表格首行名').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" size="10" name="data[setting][option][first_cname]" value="'.$option['first_cname'].'"></label>
|
||||
<span class="help-block">'.dr_lang('表格第一行的显示名称,不填写就不显示名称').'</span>
|
||||
</div>
|
||||
</div>'.$hang.'
|
||||
</div>'.$html.'
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label"></label>
|
||||
<div class="col-md-9">
|
||||
<p>'.dr_lang('列名称:是表格列的显示名称').'</p>
|
||||
<p>'.dr_lang('列宽度:是表格列的宽度,[整数]表示固定宽度;[整数%]表示百分比').'</p>
|
||||
<p>'.dr_lang('选择项:仅用于下拉选择框和复选框的选项,多个选项用半角,分开').'</p>
|
||||
<p>'.dr_lang('行名称:是表格每一行的显示名称,如果不填就按照默认行名称显示,如果默认行名称也没有填写就不显示行名').'</p>
|
||||
<span class="help-block"> <a href="javascript:dr_help(\'644\');"> '.dr_lang('了解此字段的使用方法').'</a> </span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
'.$this->attachment($option).'
|
||||
',
|
||||
'<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('控件宽度').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" size="10" name="data[setting][option][width]" value="'.$option['width'].'"></label>
|
||||
<span class="help-block">'.dr_lang('[整数]表示固定宽度;[整数%]表示百分比').'</span>
|
||||
</div>
|
||||
</div>'
|
||||
];
|
||||
}
|
||||
|
||||
// 属性类别
|
||||
protected function _field_type_select($id, $type) {
|
||||
|
||||
$arr = [
|
||||
0 => dr_lang('不使用'),
|
||||
1 => dr_lang('文本框'),
|
||||
2 => dr_lang('下拉框'),
|
||||
4 => dr_lang('复选框'),
|
||||
3 => dr_lang('文件'),
|
||||
5 => dr_lang('日期'),
|
||||
6 => dr_lang('日期时间'),
|
||||
7 => dr_lang('多行文本'),
|
||||
//8 => dr_lang('富文本框'), 实验失败
|
||||
];
|
||||
|
||||
$html = '<select class="form-control" name="data[setting][option][field]['.$id.'][type]">';
|
||||
foreach ($arr as $i => $name) {
|
||||
$html.= '<option '.($i == $type ? 'selected' : '').' value="'.$i.'">'.$name.'</option>';
|
||||
}
|
||||
$html.= '</select>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
// 对应的html
|
||||
protected function _field_type_html($config, $cname, $value, $hang, $lie, $field = []) {
|
||||
|
||||
$html = '';
|
||||
if ($config['type'] == 1) {
|
||||
$html.= '<input type="text" class="form-control" name="data['.$cname.']['.$hang.']['.$lie.']" value="'.htmlspecialchars((string)$value[$hang][$lie]).'">';
|
||||
} elseif ($config['type'] == 2) {
|
||||
$html = '<select class="form-control" name="data['.$cname.']['.$hang.']['.$lie.']">';
|
||||
$arr = explode(',', $config['option']);
|
||||
foreach ($arr as $name) {
|
||||
$html.= '<option '.($value[$hang][$lie] == $name ? 'selected' : '').' value="'.$name.'">'.$name.'</option>';
|
||||
}
|
||||
$html.= '</select>';
|
||||
} elseif ($config['type'] == 3) {
|
||||
// 文件
|
||||
$link = '';
|
||||
$preview = ROOT_THEME_PATH.'assets/images/ext/url.png';
|
||||
if ($value[$hang][$lie]) {
|
||||
$file = \Phpcmf\Service::C()->get_attachment((string)$value[$hang][$lie], 1);
|
||||
if ($file) {
|
||||
$link = $file['url'];
|
||||
if (dr_is_image($file['fileext'])) {
|
||||
$preview = $link;
|
||||
} elseif (is_file(ROOTPATH.'static/assets/images/ext/'.$file['fileext'].'.png')) {
|
||||
$preview = ROOT_THEME_PATH.'assets/images/ext/'.$file['fileext'].'.png';
|
||||
}
|
||||
} elseif (dr_is_image($value[$hang][$lie])) {
|
||||
$preview = $link = $value[$hang][$lie];
|
||||
}
|
||||
}
|
||||
if ($config['option'] && strpos((string)$config['option'], '-') !== false) {
|
||||
list($size, $exts) = explode('-', $config['option']);
|
||||
} else {
|
||||
$size = 10;
|
||||
$exts = $config['option'];
|
||||
}
|
||||
$url = '/'.(IS_ADMIN ? SELF.'?c=api' : 'index.php?s=api&c=file').'&m=input_file_list&token='.dr_get_csrf_token().'&siteid='.SITE_ID.'&p='.dr_authcode([
|
||||
'size' => $size ? $size : 10,
|
||||
'exts' => $exts ? $exts : 'jpg,gif,png,jpeg',
|
||||
'count' => 1,
|
||||
'attachment' => $field['setting']['option']['attachment'],
|
||||
'image_reduce' => $field['setting']['option']['image_reduce'],
|
||||
], 'ENCODE').'&ct=0&one=1';
|
||||
$html = '<label><input class="form-control2 form-control-file" type="hidden" name="data['.$cname.']['.$hang.']['.$lie.']" value="'.$value[$hang][$lie].'">';
|
||||
$html.= '<input class="form-control-link" type="hidden" value="'.$link.'">';
|
||||
$html.= '<input class="form-control-preview" type="hidden" value="'.$preview.'">';
|
||||
$html.= '<a href="javascript:;" onclick="dr_ftable_myfileinput(this, \''.$url.'\')" class="ftable-fileinput btn green btn-sm">'.dr_lang('上传').'</a>';
|
||||
$html.= '<a href="javascript:;" onclick="dr_ftable_myshow(this)" '.($value[$hang][$lie] ? '':'style="display:none"').' class="ftable-show btn blue btn-sm">'.dr_lang('预览').'</a>
|
||||
<a href="javascript:;" onclick="dr_ftable_mydelete(this)" '.($value[$hang][$lie] ? '':'style="display:none"').' class="ftable-delete btn red btn-sm">'.dr_lang('删除').'</a> ';
|
||||
$html.= '</label>';
|
||||
} elseif ($config['type'] == 5) {
|
||||
// 日期
|
||||
if ($config['option'] == 'SYS_TIME' && !$value[$hang][$lie]) {
|
||||
$value[$hang][$lie] = dr_date(SYS_TIME, 'Y-m-d');
|
||||
}
|
||||
$html.= '<div class="input-group date field_date_ftable_'.$cname.'">';
|
||||
$html.= '<input class="form-control" type="text" name="data['.$cname.']['.$hang.']['.$lie.']" value="'.$value[$hang][$lie].'">';
|
||||
$html.= '<span class="input-group-btn">
|
||||
<button class="btn date-set" type="button">
|
||||
<i class="fa fa-calendar"></i>
|
||||
</button>
|
||||
</span>';
|
||||
$html.= '</div>';
|
||||
$html.= '
|
||||
<script>
|
||||
$(function(){
|
||||
$(".field_date_ftable_'.$cname.'").datepicker({
|
||||
isRTL: false,
|
||||
format: "yyyy-mm-dd",
|
||||
showMeridian: true,
|
||||
autoclose: true,
|
||||
pickerPosition: "bottom-right",
|
||||
todayBtn: "linked"
|
||||
});
|
||||
});
|
||||
</script>
|
||||
';
|
||||
} elseif ($config['type'] == 6) {
|
||||
// 日期时间
|
||||
if ($config['option'] == 'SYS_TIME' && !$value[$hang][$lie]) {
|
||||
$value[$hang][$lie] = dr_date(SYS_TIME, 'Y-m-d H:i:s');
|
||||
}
|
||||
$html.= '<div class="input-group date field_datetime_ftable_'.$cname.'">';
|
||||
$html.= '<input class="form-control" type="text" name="data['.$cname.']['.$hang.']['.$lie.']" value="'.$value[$hang][$lie].'">';
|
||||
$html.= '<span class="input-group-btn">
|
||||
<button class="btn date-set" type="button">
|
||||
<i class="fa fa-calendar"></i>
|
||||
</button>
|
||||
</span>';
|
||||
$html.= '</div>';
|
||||
$html.= '
|
||||
<script>
|
||||
$(function(){
|
||||
$(".field_datetime_ftable_'.$cname.'").datetimepicker({
|
||||
isRTL: false,
|
||||
format: "yyyy-mm-dd hh:ii:ss",
|
||||
showMeridian: true,
|
||||
autoclose: true,
|
||||
pickerPosition: "bottom-right",
|
||||
todayBtn: "linked"
|
||||
});
|
||||
});
|
||||
</script>
|
||||
';
|
||||
} elseif ($config['type'] == 4) {
|
||||
$html = '<div class="table-scrollable" style="border: none; margin: 0!important"><div class="mt-checkbox-inline">';
|
||||
$arr = explode(',', $config['option']);
|
||||
foreach ($arr as $name) {
|
||||
$s = is_array($value[$hang][$lie]) && in_array($name, $value[$hang][$lie]) ? ' checked' : '';
|
||||
$kj = '<input type="checkbox" name="data['.$cname.']['.$hang.']['.$lie.'][]" value="'.$name.'" '.$s.' />';
|
||||
$html.= '<label class="mt-checkbox mt-checkbox-outline">'.$kj.' '.$name.' <span></span> </label>';
|
||||
}
|
||||
$html.= '</div></div>';
|
||||
} elseif ($config['type'] == 7) {
|
||||
$name = 'ftable_'.$cname.'_'.$hang.'_'.$lie;
|
||||
$html = '<textarea style="display:none" id="'.$name.'" name="data['.$cname.']['.$hang.']['.$lie.']">'.$value[$hang][$lie].'</textarea>';
|
||||
$html.= '<a href="javascript:;" onclick="dr_ftable_textareainput(\''.$name.'\')" class="ftable-fileinput btn green btn-sm">'.dr_lang('录入内容').'</a>';
|
||||
} elseif ($config['type'] == 8) {
|
||||
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 字段显示
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function show($field, $value = null) {
|
||||
|
||||
// 字段默认值
|
||||
$value = dr_string2array($value);
|
||||
|
||||
$str = '<div class="table-scrollable">';
|
||||
$str.= dr_get_ftable($field['id'], $value);
|
||||
$str.= '</div>';
|
||||
|
||||
return $this->input_format($field['fieldname'], $field['name'], $str);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段输出
|
||||
*/
|
||||
public function output($value) {
|
||||
return dr_string2array($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段入库值
|
||||
*/
|
||||
public function insert_value($field) {
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname']] = dr_array2string(\Phpcmf\Service::L('Field')->post[$field['fieldname']]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取附件id
|
||||
*/
|
||||
public function get_attach_id($value) {
|
||||
|
||||
if (!$this->field) {
|
||||
return NULL;
|
||||
} elseif (!isset($this->field['setting']['option']['field'])) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
$data = [];
|
||||
$value = dr_string2array($value);
|
||||
|
||||
if ($value) {
|
||||
foreach ($value as $tt) {
|
||||
foreach ($this->field['setting']['option']['field'] as $lie => $t) {
|
||||
if ($t['type'] == 3 && isset($tt[$lie]) && $tt[$lie]) {
|
||||
$data[] = (int)$tt[$lie];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 附件处理
|
||||
*/
|
||||
public function attach($data, $_data) {
|
||||
|
||||
if (!$this->field) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
$data = $this->get_attach_id($data);
|
||||
$_data = $this->get_attach_id($_data);
|
||||
|
||||
if (!isset($_data)) {
|
||||
$_data = [];
|
||||
}
|
||||
|
||||
if (!isset($data)) {
|
||||
$data = [];
|
||||
}
|
||||
|
||||
// 新旧数据都无附件就跳出
|
||||
if (!$data && !$_data) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 新旧数据都一样时表示没做改变就跳出
|
||||
if (dr_diff($data, $_data)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 当无新数据且有旧数据表示删除旧附件
|
||||
if (!$data && $_data) {
|
||||
return [
|
||||
[],
|
||||
$_data
|
||||
];
|
||||
}
|
||||
|
||||
// 当无旧数据且有新数据表示增加新附件
|
||||
if ($data && !$_data) {
|
||||
return [
|
||||
$data,
|
||||
[]
|
||||
];
|
||||
}
|
||||
|
||||
// 剩下的情况就是删除旧文件增加新文件
|
||||
|
||||
// 新旧附件的交集,表示固定的
|
||||
$intersect = array_intersect($data, $_data);
|
||||
|
||||
return [
|
||||
array_diff($data, $intersect), // 固有的与新文件中的差集表示新增的附件
|
||||
array_diff($_data, $intersect), // 固有的与旧文件中的差集表示待删除的附件
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单输入
|
||||
*/
|
||||
public function input($field, $value = '') {
|
||||
|
||||
// 字段禁止修改时就返回显示字符串
|
||||
if ($this->_not_edit($field, $value)) {
|
||||
return $this->show($field, $value);
|
||||
}
|
||||
|
||||
// 字段存储名称
|
||||
$name = $field['fieldname'];
|
||||
|
||||
// 字段显示名称
|
||||
$text = ($field['setting']['validate']['required'] ? '<span class="required" aria-required="true"> * </span>' : '').dr_lang($field['name']);
|
||||
|
||||
// 表单宽度设置
|
||||
$width = \Phpcmf\Service::IS_MOBILE_USER() ? '100%' : ($field['setting']['option']['width'] ? $field['setting']['option']['width'] : '100%');
|
||||
|
||||
// 字段提示信息
|
||||
$tips = ($name == 'title' && APP_DIR) || $field['setting']['validate']['tips'] ? '<span class="help-block" id="dr_'.$field['fieldname'].'_tips">'.$field['setting']['validate']['tips'].'</span>' : '';
|
||||
|
||||
// 字段默认值
|
||||
$value = dr_string2array($value);
|
||||
|
||||
$this->_load_date = $this->_load_datetime = 0;
|
||||
|
||||
$str = '<div class="table-scrollable" style="width:'.$width.(is_numeric($width) ? 'px !important' : '').';">';
|
||||
$str.= '<table class="table fc-sku-table table-nomargin table-bordered table-striped table-bordered table-advance" >';
|
||||
$str.= ' <thead><tr>';
|
||||
if ($field['setting']['option']['is_first_hang'] && !$field['setting']['option']['is_add']) {
|
||||
$str.= ' <th> '.dr_lang($field['setting']['option']['first_cname']).' </th>';
|
||||
}
|
||||
if ($field['setting']['option']['field']) {
|
||||
foreach ($field['setting']['option']['field'] as $t) {
|
||||
if ($t['type']) {
|
||||
$style = $t['width'] ? 'style="width:'.$t['width'].(is_numeric($t['width']) ? 'px' : '').';"' : '';
|
||||
$str.= ' <th '.$style.'>'.dr_lang($t['name']).'</th>';
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($field['setting']['option']['is_add']) {
|
||||
$str.= ' <th width="70" style="text-align: center">';
|
||||
$str.= '<button type="button" class="btn blue btn-xs" onClick="dr_add_table_'.$name.'()"> <i class="fa fa-plus"></i> </button>';
|
||||
$str.'</th>';
|
||||
}
|
||||
$str.= ' </tr></thead>';
|
||||
$str.= ' <tbody id="dr_'.$name.'_body">';
|
||||
|
||||
if ($field['setting']['option']['is_add']) {
|
||||
// 支持添加列
|
||||
$tpl = ' <tr id="dr_ftable_'.$name.'_row_{hang}">';
|
||||
if ($field['setting']['option']['field']) {
|
||||
foreach ($field['setting']['option']['field'] as $n => $t) {
|
||||
if ($t['type']) {
|
||||
$tpl.= ' <td>'.$this->_field_type_html($t, $name, $value, '{hang}', $n, $field).'</td>';
|
||||
}
|
||||
}
|
||||
}
|
||||
$tpl.= ' <td style="text-align: center"><button type="button" class="btn red btn-xs" onClick="dr_del_table_'.$name.'(this)"> <i class="fa fa-trash"></i> </button></td>';
|
||||
$tpl.= ' </tr>';
|
||||
$ksids = [];
|
||||
if ($value) {
|
||||
foreach ($value as $hang => $t) {
|
||||
$str.= ' <tr id="dr_ftable_'.$name.'_row_'.$hang.'">';
|
||||
if ($field['setting']['option']['field']) {
|
||||
foreach ($field['setting']['option']['field'] as $n => $t) {
|
||||
if ($t['type']) {
|
||||
$str.= ' <td>'.$this->_field_type_html($t, $name, $value, $hang, $n, $field).'</td>';
|
||||
}
|
||||
}
|
||||
}
|
||||
$str.= ' <td style="text-align: center"><button type="button" class="btn red btn-xs" onClick="dr_del_table_'.$name.'(this)"> <i class="fa fa-trash"></i> </button></td>';
|
||||
$str.= ' </tr>';
|
||||
$ksids[] = $hang;
|
||||
}
|
||||
$ksid = is_array($ksids) && $ksids ? max($ksids) : 0; // 开始ID
|
||||
}
|
||||
} else {
|
||||
// 固定列
|
||||
for ($i = 1; $i <= (int)$field['setting']['option']['count']; $i++) {
|
||||
|
||||
$str.= ' <tr id="dr_ftable_'.$name.'_row_'.$i.'">';
|
||||
if ($field['setting']['option']['is_first_hang']) {
|
||||
$str.= ' <td> '.($field['setting']['option']['hang'][$i]['name'] ? $field['setting']['option']['hang'][$i]['name'] : '未命名').' </td>';
|
||||
}
|
||||
if ($field['setting']['option']['field']) {
|
||||
foreach ($field['setting']['option']['field'] as $n => $t) {
|
||||
if ($t['type']) {
|
||||
$str.= ' <td>'.$this->_field_type_html($t, $name, $value, $i, $n, $field).'</td>';
|
||||
}
|
||||
}
|
||||
}
|
||||
$str.= ' </tr>';
|
||||
}
|
||||
}
|
||||
|
||||
$str.= ' </tbody>';
|
||||
$str.= '</table>';
|
||||
$str.= '</div>';
|
||||
|
||||
if (!$this->is_load_js('Date')) {
|
||||
$str.= '
|
||||
<link href="'.ROOT_THEME_PATH.'assets/global/plugins/bootstrap-daterangepicker/daterangepicker.min.css?v='.CMF_UPDATE_TIME.'" rel="stylesheet" type="text/css" />
|
||||
<link href="'.ROOT_THEME_PATH.'assets/global/plugins/bootstrap-datepicker/css/bootstrap-datepicker.min.css?v='.CMF_UPDATE_TIME.'" rel="stylesheet" type="text/css" />
|
||||
<link href="'.ROOT_THEME_PATH.'assets/global/plugins/bootstrap-datetimepicker/css/bootstrap-datetimepicker.min.css?v='.CMF_UPDATE_TIME.'" rel="stylesheet" type="text/css" />
|
||||
|
||||
<script src="'.ROOT_THEME_PATH.'assets/global/plugins/moment.min.js?v='.CMF_UPDATE_TIME.'" type="text/javascript"></script>
|
||||
<script src="'.ROOT_THEME_PATH.'assets/global/plugins/bootstrap-datepicker/js/bootstrap-datepicker.finecms.js?v='.CMF_UPDATE_TIME.'" type="text/javascript"></script>
|
||||
<script src="'.ROOT_THEME_PATH.'assets/global/plugins/bootstrap-datetimepicker/js/bootstrap-datetimepicker.finecms.js?v='.CMF_UPDATE_TIME.'" type="text/javascript"></script>
|
||||
';
|
||||
$this->set_load_js('Date', 1);
|
||||
}
|
||||
if ($field['setting']['option']['is_add']) {
|
||||
$str.= '<script>
|
||||
var ks_'.$name.' = '.json_encode(['tpl' => $tpl, 'id' => $ksid]).';
|
||||
function dr_del_table_'.$name.'(e) {
|
||||
layer.confirm(\'确定删除本条数据吗?\', {
|
||||
shade: 0,
|
||||
title: \'提示\',
|
||||
}, function(index, layero){
|
||||
layer.close(index);
|
||||
$(e).parent().parent().remove();
|
||||
});
|
||||
}
|
||||
function dr_add_table_'.$name.'() {
|
||||
var tpl = ks_'.$name.'.tpl;
|
||||
ks_'.$name.'.id ++;
|
||||
tpl = tpl.replace(/\{hang\}/g, ks_'.$name.'.id);
|
||||
$(\'#dr_'.$name.'_body\').append(tpl);
|
||||
}
|
||||
</script>';
|
||||
}
|
||||
$str.= '<script> $("#dr_'.$name.'_body").sortable();';
|
||||
|
||||
|
||||
|
||||
$str.="
|
||||
$(\"#dr_".$name."_body\").sortable();
|
||||
</script>
|
||||
";
|
||||
|
||||
return $this->input_format($name, $text, $str.$tips);
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示输出表格
|
||||
*/
|
||||
public function show_table($field, $value, $class = '') {
|
||||
|
||||
// class属性
|
||||
!$class && $class = 'table fc-sku-table table-nomargin table-bordered table-striped table-bordered table-advance';
|
||||
|
||||
// 字段默认值
|
||||
$value = dr_string2array($value);
|
||||
// 表单宽度设置
|
||||
$width = \Phpcmf\Service::IS_MOBILE_USER() ? '100%' : ($field['setting']['option']['width'] ? $field['setting']['option']['width'] : '100%');
|
||||
|
||||
$str = '<table id="dr_table_'.$field['fieldname'].'" class="'.$class.'" style="width:'.$width.(is_numeric($width) ? 'px' : '').';">';
|
||||
$str.= ' <thead><tr>';
|
||||
|
||||
if ($field['setting']['option']['is_first_hang'] && !$field['setting']['option']['is_add']) {
|
||||
$str .= ' <th> ' . dr_lang($field['setting']['option']['first_cname']) . ' </th>';
|
||||
}
|
||||
|
||||
if ($field['setting']['option']['field']) {
|
||||
foreach ($field['setting']['option']['field'] as $t) {
|
||||
if ($t['type']) {
|
||||
$style = $t['width'] ? 'style="width:'.$t['width'].(is_numeric($t['width']) ? 'px' : '').';"' : '';
|
||||
$str.= ' <th '.$style.'>'.dr_lang($t['name']).'</th>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$str.= ' </tr></thead>';
|
||||
$str.= ' <tbody>';
|
||||
|
||||
$i = 1;
|
||||
foreach ($value as $ii => $val) {
|
||||
|
||||
$str.= ' <tr>';
|
||||
if ($field['setting']['option']['is_first_hang'] && !$field['setting']['option']['is_add']) {
|
||||
$hname = $field['setting']['option']['hang'][$i]['name'] ? $field['setting']['option']['hang'][$i]['name'] : '未命名';
|
||||
$str .= ' <td> ' . $hname . ' </td>';
|
||||
}
|
||||
|
||||
if ($field['setting']['option']['field']) {
|
||||
foreach ($field['setting']['option']['field'] as $n => $t) {
|
||||
if ($t['type']) {
|
||||
$td = $val[$n];
|
||||
if ($td && $t['type'] == 3) {
|
||||
// 图片
|
||||
$td = '<img src="'.dr_get_file($td).'" class="ftable_img">';
|
||||
} elseif ($td && $t['type'] == 4) {
|
||||
// 复选
|
||||
$td = implode('、', $td);
|
||||
}
|
||||
$str.= ' <td>'.$td.'</td>';
|
||||
}
|
||||
}
|
||||
}
|
||||
$i++;
|
||||
$str.= ' </tr>';
|
||||
}
|
||||
|
||||
$str.= ' </tbody>';
|
||||
$str.= '</table>';
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
<?php namespace Phpcmf\Field;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
class Group extends \Phpcmf\Library\A_Field {
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
public function __construct(...$params) {
|
||||
parent::__construct(...$params);
|
||||
$this->close_xss = 1; // 关闭xss验证
|
||||
$this->is_validate = false; // 不允许字段验证
|
||||
$this->is_edit = false; // 不允许修改字段类别
|
||||
$this->fieldtype = ''; // TRUE表全部可用字段类型,自定义格式为 array('可用字段类型名称' => '默认长度', ... )
|
||||
$this->defaulttype = ''; // 当用户没有选择字段类型时的缺省值
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段相关属性参数
|
||||
*
|
||||
* @param array $value 值
|
||||
* @param array $field 字段集合
|
||||
* @return string
|
||||
*/
|
||||
public function option($option, $field = NULL) {
|
||||
$group = [];
|
||||
$option['value'] = isset($option['value']) ? $option['value'] : '';
|
||||
if ($field) {
|
||||
foreach ($field as $t) {
|
||||
if ($t['fieldtype'] == 'Group') {
|
||||
$t['setting'] = dr_string2array($t['setting']);
|
||||
if (preg_match_all('/\{(.+)\}/U', $t['setting']['option']['value'], $value)) {
|
||||
foreach ($value[1] as $v) {
|
||||
$group[] = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$_field = [];
|
||||
$_field[] = '<option value=""> -- </option>';
|
||||
foreach ($field as $t) {
|
||||
$t['fieldtype'] != 'Group'
|
||||
&& !dr_in_array($t['fieldname'], $group)
|
||||
&& $_field[] = '<option value="'.$t['fieldname'].'">'.$t['name'].'</option>';
|
||||
}
|
||||
$_field = implode('', array_unique($_field));
|
||||
}
|
||||
|
||||
return [$this->_search_field().'
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('可用字段').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><select class="form-control" name="xx" id="fxx">'.$_field.'</select></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('分组规则').'</label>
|
||||
<div class="col-md-9">
|
||||
<textarea name="data[setting][option][value]" id="fvalue" style="height:120px;" class="form-control">'.$option['value'].'</textarea>
|
||||
<span class="help-block">'.dr_lang('分组规则支持html标签,注意每个字段只能存在于一个分组中,否则会出错;此字段只能用于模块中').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
$("#fxx").change(function(){
|
||||
var value = $(this).val();
|
||||
var fvalue = $("#fvalue").val();
|
||||
var text = $("#fxx").find("option:selected").text();
|
||||
$("#fxx option[value=\'"+value+"\']").remove();
|
||||
$("#fvalue").val(fvalue+" "+text+": {"+value+"}");
|
||||
});
|
||||
});
|
||||
</script>
|
||||
'];
|
||||
}
|
||||
|
||||
/**
|
||||
* create_sql
|
||||
*/
|
||||
public function create_sql($name, $value, $cname = '') {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* alter_sql
|
||||
*/
|
||||
public function alter_sql($name, $value, $cname = '') {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* drop_sql
|
||||
*/
|
||||
public function drop_sql($name) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* test
|
||||
*/
|
||||
public function test_sql($tables, $field) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段入库值
|
||||
*/
|
||||
public function insert_value($field) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单输入
|
||||
* @return string
|
||||
*/
|
||||
public function input($field, $value = '') {
|
||||
|
||||
// 字段禁止修改时就返回显示字符串
|
||||
if ($this->_not_edit($field, $value)) {
|
||||
return $this->show($field, $value);
|
||||
}
|
||||
|
||||
// 字段显示名称
|
||||
$text = ($field['setting']['validate']['required'] ? '<span class="required" aria-required="true"> * </span>' : '').dr_lang($field['name']);
|
||||
|
||||
// 字段提示信息
|
||||
$tips = isset($field['setting']['validate']['tips']) && $field['setting']['validate']['tips'] ? '<div class="help-block" id="dr_'.$field['fieldname'].'_tips">'.$field['setting']['validate']['tips'].'</div>' : '';
|
||||
|
||||
// 字段默认值
|
||||
$value = str_replace(['{', '}'], ['{|', '|}'], $field['setting']['option']['value']);
|
||||
|
||||
return $this->input_format($field['fieldname'], $text, $value.$tips);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,379 @@
|
||||
<?php namespace Phpcmf\Field;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
class Image extends \Phpcmf\Library\A_Field {
|
||||
|
||||
protected $img_ext;
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
public function __construct(...$params) {
|
||||
parent::__construct(...$params);
|
||||
$this->close_xss = 1; // 关闭xss验证
|
||||
$this->fieldtype = ['TEXT' => ''];
|
||||
$this->defaulttype = 'TEXT';
|
||||
$this->img_ext = 'jpg,gif,png,jpeg,svg,webp';
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段相关属性参数
|
||||
*
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function option($option) {
|
||||
|
||||
|
||||
$mthumb = '';
|
||||
if (\Phpcmf\Service::M('field')->relatedname == 'module') {
|
||||
$mthumb = '<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('首图作为缩略图').'</label>
|
||||
<div class="col-md-9">
|
||||
<input type="checkbox" name="data[setting][option][stslt]" '.($option['stslt'] ? 'checked' : '').' value="1" data-on-text="'.dr_lang('已开启').'" data-off-text="'.dr_lang('已关闭').'" data-on-color="success" data-off-color="danger" class="make-switch" data-size="small">
|
||||
<span class="help-block">'.dr_lang('当缩略图字段为空时,用本字段的图片来填充(仅对模块字段有效)').'</span>
|
||||
</div>
|
||||
</div>';
|
||||
}
|
||||
|
||||
return [$this->_search_field().$mthumb.'
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('文件大小').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input id="field_default_value" type="text" class="form-control" value="'.$option['size'].'" name="data[setting][option][size]"></label>
|
||||
<span class="help-block">'.dr_lang('单位MB').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('上传数量').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" value="'.$option['count'].'" name="data[setting][option][count]"></label>
|
||||
<span class="help-block">'.dr_lang('每次最多上传的文件数量').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group hidden">
|
||||
<label class="col-md-2 control-label">'.dr_lang('扩展名').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" size="40" name="data[setting][option][ext]" value="'.$this->img_ext.'"></label>
|
||||
</div>
|
||||
</div>'.$this->attachment($option).'',
|
||||
|
||||
'<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('控件宽度').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" size="10" name="data[setting][option][width]" value="'.$option['width'].'"></label>
|
||||
<span class="help-block">'.dr_lang('[整数]表示固定宽度;[整数%]表示百分比').'</span>
|
||||
</div>
|
||||
</div><div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('提示扩展名显示').'</label>
|
||||
<div class="col-md-9">
|
||||
<div class="mt-radio-inline">
|
||||
<label class="mt-radio mt-radio-outline"><input type="radio" name="data[setting][option][is_ext_tips]" value="0" '.(!$option['is_ext_tips'] ? 'checked' : '').' /> '.dr_lang('已显示').' <span></span></label>
|
||||
<label class="mt-radio mt-radio-outline"><input type="radio" name="data[setting][option][is_ext_tips]" value="1" '.($option['is_ext_tips'] ? 'checked' : '').' /> '.dr_lang('已关闭').' <span></span></label>
|
||||
</div><span class="help-block">'.dr_lang('提示字段上传的扩展名和大小限制的文本信息').'</span>
|
||||
</div>
|
||||
</div>'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证字段属性
|
||||
*/
|
||||
public function edit_config($post) {
|
||||
|
||||
if (!isset($post['setting']['option']['size']) || !$post['setting']['option']['size']) {
|
||||
return dr_return_data(0, dr_lang('文件大小必须填写'));
|
||||
} elseif (!isset($post['setting']['option']['count']) || !$post['setting']['option']['count']) {
|
||||
return dr_return_data(0, dr_lang('上传数量必须填写'));
|
||||
}
|
||||
|
||||
return dr_return_data(1, 'ok');
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段输出
|
||||
*/
|
||||
public function output($value) {
|
||||
return dr_string2array($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取附件id
|
||||
*/
|
||||
public function get_attach_id($value) {
|
||||
return dr_string2array($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段入库值
|
||||
*/
|
||||
public function insert_value($field) {
|
||||
|
||||
$data = \Phpcmf\Service::L('Field')->post[$field['fieldname']];
|
||||
if ($data) {
|
||||
if ($field['setting']['option']['stslt']) {
|
||||
$_field = \Phpcmf\Service::L('form')->fields;
|
||||
if (isset($_field['thumb']) && $_field['thumb']['fieldtype'] == 'File' && !\Phpcmf\Service::L('Field')->data[$_field['thumb']['ismain']]['thumb']) {
|
||||
$one = array_key_first($data);
|
||||
if ($data[$one]) {
|
||||
\Phpcmf\Service::L('Field')->data[1]['thumb'] = $data[$one];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dr_count($data) > $field['setting']['option']['count']) {
|
||||
$data = array_slice($data, 0, $field['setting']['option']['count']-2);
|
||||
}
|
||||
}
|
||||
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname']] = dr_array2string($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 附件处理
|
||||
*/
|
||||
public function attach($data, $_data) {
|
||||
|
||||
$data = dr_string2array($data);
|
||||
$_data = dr_string2array($_data);
|
||||
|
||||
if (!isset($_data)) {
|
||||
$_data = [];
|
||||
}
|
||||
|
||||
if (!isset($data)) {
|
||||
$data = [];
|
||||
}
|
||||
|
||||
// 新旧数据都无附件就跳出
|
||||
if (!$data && !$_data) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 新旧数据都一样时表示没做改变就跳出
|
||||
if (dr_diff($data, $_data)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 当无新数据且有旧数据表示删除旧附件
|
||||
if (!$data && $_data) {
|
||||
return [
|
||||
[],
|
||||
$_data
|
||||
];
|
||||
}
|
||||
|
||||
// 当无旧数据且有新数据表示增加新附件
|
||||
if ($data && !$_data) {
|
||||
return [
|
||||
$data,
|
||||
[]
|
||||
];
|
||||
}
|
||||
|
||||
// 剩下的情况就是删除旧文件增加新文件
|
||||
|
||||
// 新旧附件的交集,表示固定的
|
||||
$intersect = array_intersect($data, $_data);
|
||||
|
||||
return [
|
||||
array_diff($data, $intersect), // 固有的与新文件中的差集表示新增的附件
|
||||
array_diff($_data, $intersect), // 固有的与旧文件中的差集表示待删除的附件
|
||||
];
|
||||
}
|
||||
|
||||
protected function _format_file_size($fileSize, $round = 2) {
|
||||
|
||||
if (!$fileSize) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$i = 0;
|
||||
$inv = 1 / 1024;
|
||||
$unit = [' Bytes', ' KB', ' MB', ' GB', ' TB', ' PB', ' EB', ' ZB', ' YB'];
|
||||
|
||||
while ($fileSize >= 1024 && $i < 8) {
|
||||
$fileSize *= $inv;
|
||||
++$i;
|
||||
}
|
||||
|
||||
$temp = sprintf("%.2f", $fileSize);
|
||||
$value = $temp - (int) $temp ? $temp : $fileSize;
|
||||
|
||||
return '<strong>'.round($value, $round).'</strong>' . $unit[$i];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 字段表单输入
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function input($field, $value = '')
|
||||
{
|
||||
|
||||
// 字段禁止修改时就返回显示字符串
|
||||
if ($this->_not_edit($field, $value)) {
|
||||
return $this->show($field, $value);
|
||||
}
|
||||
|
||||
// 字段存储名称
|
||||
$name = $field['fieldname'];
|
||||
|
||||
// 字段显示名称
|
||||
$text = ($field['setting']['validate']['required'] ? '<span class="required" aria-required="true"> * </span>' : '') . dr_lang($field['name']);
|
||||
// 表单宽度设置
|
||||
$width = \Phpcmf\Service::IS_MOBILE_USER() ? '100%' : ($field['setting']['option']['width'] ? $field['setting']['option']['width'] : '100%');
|
||||
|
||||
// 字段提示信息
|
||||
$tips = ($name == 'title' && APP_DIR) || $field['setting']['validate']['tips'] ? '<span class="help-block" id="dr_' . $field['fieldname'] . '_tips">' . $field['setting']['validate']['tips'] . '</span>' : '';
|
||||
|
||||
$size = ($field['setting']['option']['size']);
|
||||
!$size && $size = 0;
|
||||
$count = intval($field['setting']['option']['count']);
|
||||
|
||||
$p = dr_authcode([
|
||||
'size' => $size,
|
||||
'exts' => $this->img_ext,
|
||||
'attachment' => $field['setting']['option']['attachment'],
|
||||
'image_reduce' => $field['setting']['option']['image_reduce'],
|
||||
], 'ENCODE');
|
||||
$url = WEB_DIR.''.(IS_ADMIN ? SELF.'?c=api' : 'index.php?s=api&c=file').'&token='.dr_get_csrf_token().'&siteid=' . SITE_ID . '&m=upload&p=' . $p . '&fid=' . $field['id'];
|
||||
|
||||
// 显示模板
|
||||
$i = 0;
|
||||
$tpl = '';
|
||||
if ($value) {
|
||||
$value = dr_string2array($value);
|
||||
if ($value) {
|
||||
foreach ($value as $id) {
|
||||
$file = \Phpcmf\Service::C()->get_attachment($id, 1);
|
||||
if ($file) {
|
||||
$editname = '';
|
||||
if ($file['uid'] == \Phpcmf\Service::C()->uid || IS_ADMIN) {
|
||||
$editname = ' onclick="dr_iframe(\''.dr_lang('修改名称').'\', \''.dr_web_prefix((IS_ADMIN ? SELF.'?c=api' : 'index.php?s=api&c=file').'&m=name_edit&id='.$file['id']).'\', \'350px\', \'220px\');" title="'.dr_lang('修改名称').'"';
|
||||
}
|
||||
$tpl.= '<div id="image-'.$name.'-'.$id.'" class="dz-preview dz-processing dz-success dz-complete dz-image-preview">';
|
||||
$tpl.= '<div class="dz-image">';
|
||||
$tpl.= ' <img data-dz-thumbnail="" src="'.dr_get_file($id).'">';
|
||||
$tpl.= '</div>';
|
||||
|
||||
$tpl.= ' <div class="dz-details"><div class="dz-size" onclick="dr_preview_image(\''.$file['url'].'\');" title="'.dr_lang('放大图片').'"><span data-dz-size="">'.$this->_format_file_size($file['filesize']).'</span></div><div class="dz-filename" '.$editname.'><span data-dz-name="">'.$file['filename'].'</span></div></div>';
|
||||
|
||||
$tpl.= '<a class="dz-remove" href="javascript:dr_delete_image_'.$name.'('.$id.');" title="'.dr_lang('删除图片').'">';
|
||||
$tpl.= ' <i class="fa fa-times-circle"></i>';
|
||||
$tpl.= ' </a>';
|
||||
$tpl.= '<input class="dr_dropzone_'.$name.'" type="hidden" name="data['.$name.'][]" value="'.$id.'" />';
|
||||
$tpl.= '</div>';
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$tpl.= '<input class="dr_dropzone_'.$name.'_total" type="hidden" value="'.$i.'" />';
|
||||
$ts = dr_lang('每张图片最大%s,最多上传%s张图片', $size . 'MB', intval($field['setting']['option']['count']));
|
||||
|
||||
// 表单输出
|
||||
$str = '<div class="dropzone2 dropzone-file-area dropzone-images-area" id="my-dropzone-'.$name.'" style="width:'.$width.(is_numeric($width) ? 'px' : '').';">
|
||||
</div>
|
||||
';
|
||||
if (!$field['setting']['option']['is_ext_tips']) {
|
||||
$str.= '<div class="finecms-file-ts">'.$ts.'</div>';
|
||||
}
|
||||
|
||||
if (!$this->is_load_js($field['fieldtype'])) {
|
||||
$str.= '
|
||||
<link href="'.ROOT_THEME_PATH.'assets/global/plugins/dropzone/dropzone.min.css?v='.CMF_UPDATE_TIME.'" rel="stylesheet" type="text/css" />
|
||||
<script src="'.ROOT_THEME_PATH.'assets/global/plugins/dropzone/dropzone.min.js?v='.CMF_UPDATE_TIME.'" type="text/javascript"></script>
|
||||
';
|
||||
$this->set_load_js($field['fieldtype'], 1);
|
||||
}
|
||||
|
||||
$js = \Phpcmf\Service::L('js_packer');
|
||||
$str.= $js->pack('
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
$(function() {
|
||||
$("#my-dropzone-'.$name.'").sortable();
|
||||
Dropzone.autoDiscover = false;
|
||||
$("#my-dropzone-'.$name.'").dropzone({
|
||||
addRemoveLinks:true,
|
||||
maxFiles:99999,
|
||||
maxFilesize: '.$size.',
|
||||
acceptedFiles: "image/*",
|
||||
dictMaxFilesExceeded: "'.dr_lang("最多只能上传%s张图片", $count).(CI_DEBUG ? '(可在自定义字段中设置本字段的个数值)' : '').'",
|
||||
dictResponseError: \'文件上传失败\',
|
||||
dictInvalidFileType: "不能上传该类型文件",
|
||||
dictFallbackMessage:"浏览器不受支持",
|
||||
dictFileTooBig:"文件过大上传文件最大支持",
|
||||
url: "'.$url.'",
|
||||
init: function() {
|
||||
this.on("addedfile", function(file) {
|
||||
var activeFiles = this.getActiveFiles();
|
||||
var num = parseInt($(".dr_dropzone_'.$name.'_total").val());
|
||||
if (num+activeFiles.length+1 > '.$count.') {
|
||||
this.options.maxFiles = -1;
|
||||
}
|
||||
});
|
||||
this.on("success", function(file, res) {
|
||||
var rt = JSON.parse(res);
|
||||
if(rt.code){
|
||||
var num = parseInt($(".dr_dropzone_'.$name.'_total").val());
|
||||
$(".dr_dropzone_'.$name.'_total").val(num+1);
|
||||
var input = \'<input class="dr_dropzone_'.$name.'" type="hidden" name="data['.$name.'][]" value="\'+rt.id+\'" />\';
|
||||
$(file.previewElement).append(input);
|
||||
}else{
|
||||
dr_tips(0, rt.msg);
|
||||
file.previewElement.classList.remove("dz-success");
|
||||
file.previewElement.classList.add("dz-error");
|
||||
file.previewElement.classList.add("dz-error");
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
});
|
||||
$("#my-dropzone-'.$name.'").append("'.addslashes($tpl).'");
|
||||
});
|
||||
function dr_delete_image_'.$name.'(e) {
|
||||
var num = parseInt($(".dr_dropzone_'.$name.'_total").val());
|
||||
$(".dr_dropzone_'.$name.'_total").val(num-1);
|
||||
$("#image-'.$name.'-"+e).remove();
|
||||
}
|
||||
</script>
|
||||
|
||||
', 0);
|
||||
|
||||
// 输出最终表单显示
|
||||
return $this->input_format($name, $text, $str.$tips);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单显示
|
||||
*
|
||||
* @param string $field 字段数组
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function show($field, $value = null) {
|
||||
|
||||
$html = '';
|
||||
$value = dr_string2array($value);
|
||||
if ($value) {
|
||||
$html.= '<div class="row">';
|
||||
foreach ($value as $id) {
|
||||
$html.= '<div class="col-sm-3 col-md-2">';
|
||||
$html.= '<a href="javascript:dr_preview_image(\''.dr_get_file($id).'\');" class="thumbnail">';
|
||||
$html.= '<img src="'.dr_get_file($id).'" style="width:100%">';
|
||||
$html.= '</a>';
|
||||
$html.= '</div>';
|
||||
}
|
||||
$html.= '</div>';
|
||||
}
|
||||
|
||||
return $this->input_format($field['fieldname'], $field['name'], $html);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,366 @@
|
||||
<?php namespace Phpcmf\Field;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
class Join extends \Phpcmf\Library\A_Field {
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
public function __construct(...$params) {
|
||||
parent::__construct(...$params);
|
||||
$this->fieldtype = ['TEXT' => '']; // TRUE表全部可用字段类型,自定义格式为 array('可用字段类型名称' => '默认长度', ... )
|
||||
$this->defaulttype = 'TEXT'; // 当用户没有选择字段类型时的缺省值
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段相关属性参数
|
||||
*
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function option($option) {
|
||||
|
||||
if ($option['field']) {
|
||||
foreach ($option['field'] as $k => $v) {
|
||||
if (!$v['field']) {
|
||||
unset($option['field'][$k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$html = '';
|
||||
$max = dr_count($option['field'])+2;
|
||||
for ($i = 1; $i <= $max; $i++) {
|
||||
$html.= '<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('表格第%s列', $i).'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" placeholder="'.dr_lang('字段名').'" class="form-control" size="20" value="'.$option['field'][$i]['field'].'" name="data[setting][option][field]['.$i.'][field]"></label>
|
||||
<label><input type="text" placeholder="'.dr_lang('显示名').'" class="form-control" size="20" value="'.$option['field'][$i]['name'].'" name="data[setting][option][field]['.$i.'][name]"></label>
|
||||
<label><input type="text" placeholder="'.dr_lang('宽度').'" class="form-control" size="20" value="'.$option['field'][$i]['width'].'" name="data[setting][option][field]['.$i.'][width]"></label>
|
||||
</label>
|
||||
<label><input type="text" placeholder="'.dr_lang('回调函数').'" class="form-control" size="20" value="'.$option['field'][$i]['func'].'" name="data[setting][option][field]['.$i.'][func]"></label>
|
||||
</label>
|
||||
</div>
|
||||
</div>';
|
||||
}
|
||||
|
||||
return [$this->_search_field().'
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('关联表').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" name="data[setting][option][table]" value="'.$option['table'].'"></label>
|
||||
<span class="help-block">'.dr_lang('输入表名称,不带表前缀,如:article').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('最大选择数').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" name="data[setting][option][limit]" value="'.$option['limit'].'"></label>
|
||||
<span class="help-block">'.dr_lang('最大能选择的数量限制').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('每页显示条数').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" name="data[setting][option][pagesize]" value="'.$option['pagesize'].'"></label>
|
||||
<span class="help-block">'.dr_lang('选择列表分页条数,按多少条数据分页').'</span>
|
||||
</div>
|
||||
</div>'.$html.''];
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段输出
|
||||
*/
|
||||
public function output($value) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段入库值
|
||||
*/
|
||||
public function insert_value($field) {
|
||||
|
||||
$data = \Phpcmf\Service::L('Field')->post[$field['fieldname']];
|
||||
$limit = intval($field['setting']['option']['limit']);
|
||||
if ($limit && $data && count($data) > $limit) {
|
||||
// 超限了
|
||||
$value = implode(',', dr_arraycut($data, $limit));
|
||||
} else {
|
||||
$value = !$data ? '' : implode(',', $data);
|
||||
}
|
||||
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname']] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单输入
|
||||
*
|
||||
* @param string $cname 字段别名
|
||||
* @param string $name 字段名称
|
||||
* @param array $cfg 字段配置
|
||||
* @param string $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function input($field, $value = '') {
|
||||
|
||||
// 字段禁止修改时就返回显示字符串
|
||||
if ($this->_not_edit($field, $value)) {
|
||||
return $this->show($field, $value);
|
||||
}
|
||||
|
||||
|
||||
$is_show = 0;
|
||||
|
||||
// 字段存储名称
|
||||
$name = $field['fieldname'];
|
||||
// 字段提示信息
|
||||
$tips = isset($field['setting']['validate']['tips']) && $field['setting']['validate']['tips'] ? '<span class="help-block" id="dr_'.$name.'_tips">'.$field['setting']['validate']['tips'].'</span>' : '';
|
||||
// 区域大小
|
||||
$area = \Phpcmf\Service::IS_MOBILE_USER() ? '["95%", "90%"]' : '["50%", "65%"]';
|
||||
// 关联表名称
|
||||
$table = isset($field['setting']['option']['table']) ? $field['setting']['option']['table'] : '';
|
||||
// 字段显示名称
|
||||
$text = ($field['setting']['validate']['required'] ? '<span class="required" aria-required="true"> * </span>' : '').dr_lang($field['name']);
|
||||
// 选择数量限制
|
||||
$limit = intval($field['setting']['option']['limit']);
|
||||
!$limit && $limit = 99999;
|
||||
|
||||
if (!$table) {
|
||||
if (CI_DEBUG) {
|
||||
return $this->input_format($name, $text, '<div class="form-control-static" style="color:red">关联字段没有设置关联表名称</div>');
|
||||
}
|
||||
return $this->input_format($name, $text, '');
|
||||
} elseif (!\Phpcmf\Service::M()->is_table_exists($table)) {
|
||||
if (CI_DEBUG) {
|
||||
return $this->input_format($name, $text, '<div class="form-control-static" style="color:red">关联字段设置的表【'.$table.'】不存在</div>');
|
||||
}
|
||||
return $this->input_format($name, $text, '');
|
||||
}
|
||||
|
||||
$value = $value ? trim($value, ',') : '';
|
||||
$mylist = [];
|
||||
if ($value && is_string($value)) {
|
||||
$arr = explode(',', $value);
|
||||
if ($arr) {
|
||||
$value = '';
|
||||
foreach ($arr as $a) {
|
||||
$a = intval($a);
|
||||
if ($a) {
|
||||
$value.= ','.$a;
|
||||
}
|
||||
}
|
||||
if ($value) {
|
||||
$value = trim($value, ',');
|
||||
$ids = array_values(array_filter(array_map('intval', explode(',', $value))));
|
||||
$mylist = [];
|
||||
if ($ids) {
|
||||
$rows = \Phpcmf\Service::M()->db->table($table)->whereIn('id', $ids)->get();
|
||||
$rows = $rows ? $rows->getResultArray() : [];
|
||||
$map = [];
|
||||
foreach ($rows as $r) {
|
||||
$map[(int) $r['id']] = $r;
|
||||
}
|
||||
foreach ($ids as $id) {
|
||||
if (isset($map[$id])) {
|
||||
$mylist[] = $map[$id];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$tpl = is_file(MYPATH.'View/api_join_field_'.$field['fieldname'].'.html') ? MYPATH.'View/api_join_field_'.$field['fieldname'].'.html' : COREPATH.'View/api_join_field.html';
|
||||
if (!is_file($tpl)) {
|
||||
if (CI_DEBUG) {
|
||||
return $this->input_format($name, $text, '<div class="form-control-static" style="color:red">模板文件【'.$tpl.'】不存在</div>');
|
||||
}
|
||||
return $this->input_format($name, $text, '');
|
||||
}
|
||||
$code = file_get_contents($tpl);
|
||||
if (!$code) {
|
||||
if (CI_DEBUG) {
|
||||
return $this->input_format($name, $text, '<div class="form-control-static" style="color:red">模板文件【'.$tpl.'】内容为空</div>');
|
||||
}
|
||||
return $this->input_format($name, $text, '');
|
||||
}
|
||||
$file = \Phpcmf\Service::V()->code2php($code);
|
||||
ob_start();
|
||||
require $file;
|
||||
$str = ob_get_clean();
|
||||
|
||||
$str.= $tips;
|
||||
$js = \Phpcmf\Service::L('js_packer');
|
||||
$str.= $js->pack('
|
||||
<script type="text/javascript">
|
||||
var dr_join_'.$name.'_btn = null;
|
||||
function dr_join_body_'.$name.'(btn) {
|
||||
var $box = btn ? $(btn).closest(".scroller_'.$name.'_files") : $(".scroller_'.$name.'_files").first();
|
||||
return $box.find("tbody.scroller_body").first();
|
||||
}
|
||||
function dr_join_len_'.$name.'(btn) {
|
||||
var n = 0, seen = {}, $body = dr_join_body_'.$name.'(btn || dr_join_'.$name.'_btn);
|
||||
$body.children("tr").each(function(){
|
||||
var id = $(this).attr("id");
|
||||
if (id && id.indexOf("dr_items_'.$name.'_") === 0 && !seen[id]) {
|
||||
seen[id] = 1;
|
||||
n++;
|
||||
}
|
||||
});
|
||||
return n;
|
||||
}
|
||||
function dr_join_sortable_'.$name.'(btn) {
|
||||
var $body = dr_join_body_'.$name.'(btn);
|
||||
if ($body.data("ui-sortable")) {
|
||||
return;
|
||||
}
|
||||
$body.sortable({
|
||||
items: "> tr",
|
||||
axis: "y",
|
||||
containment: "parent",
|
||||
helper: function(e, tr) {
|
||||
var $originals = tr.children();
|
||||
var $helper = tr.clone();
|
||||
$helper.children().each(function(index) {
|
||||
$(this).width($originals.eq(index).width());
|
||||
});
|
||||
return $helper;
|
||||
}
|
||||
});
|
||||
}
|
||||
dr_slimScroll_init(".scroller_'.$name.'_files", 300);
|
||||
dr_join_sortable_'.$name.'($(".scroller_'.$name.'_files").first());
|
||||
function dr_add_join_'.$name.'(btn) {
|
||||
dr_join_'.$name.'_btn = btn;
|
||||
var len = dr_join_len_'.$name.'(btn);
|
||||
if (len >= '.$limit.') {
|
||||
dr_tips(0, "'.dr_lang('关联数量不得超过%s个', $limit).'");
|
||||
return;
|
||||
}
|
||||
var url = "'.dr_web_prefix('index.php?s=api&c=api&m=join&fid=').$field['id'].'&is_iframe=1";
|
||||
layer.open({
|
||||
type: 2,
|
||||
title: \'<i class="fa fa-cog"></i> '.dr_lang($field['name']).'\',
|
||||
fix:true,
|
||||
shadeClose: true,
|
||||
shade: 0,
|
||||
area: '.$area.',
|
||||
btn: ["'.dr_lang('关联').'"],
|
||||
success: function (json) {
|
||||
if (json.code == 0) {
|
||||
layer.close();
|
||||
dr_tips(json.code, json.msg);
|
||||
}
|
||||
},
|
||||
yes: function(index, layero){
|
||||
var body = layer.getChildFrame(\'body\', index);
|
||||
var $joinBody = dr_join_body_'.$name.'(dr_join_'.$name.'_btn);
|
||||
// 延迟加载
|
||||
var loading = layer.load(2, {
|
||||
time: 10000
|
||||
});
|
||||
$.ajax({type: "POST",dataType:"json", url: url, data: $(body).find(\'#myform\').serialize(),
|
||||
success: function(json) {
|
||||
layer.close(loading);
|
||||
if (json.code == 1) {
|
||||
layer.close(index);
|
||||
var len = dr_join_len_'.$name.'(dr_join_'.$name.'_btn);
|
||||
if (len + json.data.ids.length > '.$limit.') {
|
||||
dr_tips(0, "'.dr_lang('关联数量超限').'");
|
||||
return;
|
||||
}
|
||||
for(var i in json.data.ids){
|
||||
var vid = json.data.ids[i];
|
||||
if (typeof vid != "undefined") {
|
||||
if($joinBody.find("#dr_items_'.$name.'_"+vid).length>0) {
|
||||
dr_tips(0, "'.dr_lang('已经存在').'");
|
||||
return;
|
||||
}
|
||||
if (dr_join_len_'.$name.'(dr_join_'.$name.'_btn) >= '.$limit.') {
|
||||
dr_tips(0, "'.dr_lang('关联数量超限').'");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
$joinBody.append(json.data.html);
|
||||
dr_slimScroll_init(".scroller_'.$name.'_files", 300);
|
||||
dr_tips(1, json.msg);
|
||||
} else {
|
||||
dr_tips(0, json.msg);
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
},
|
||||
content: url
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
</script>', 0);
|
||||
|
||||
return $this->input_format($name, $text, $str);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单显示
|
||||
*
|
||||
* @param string $field 字段数组
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function show($field, $value = null) {
|
||||
|
||||
$cname = ($field['setting']['option']['title'] ? $field['setting']['option']['title'] : dr_lang('主题'));
|
||||
$value = @trim($value, ',');
|
||||
$mylist = [];
|
||||
$is_show = 1;
|
||||
$table = isset($field['setting']['option']['table']) ? $field['setting']['option']['table'] : '';
|
||||
if ($value && is_string($value) && $table) {
|
||||
$arr = explode(',', $value);
|
||||
if ($arr) {
|
||||
$value = '';
|
||||
foreach ($arr as $a) {
|
||||
$a = intval($a);
|
||||
if ($a) {
|
||||
$value.= ','.$a;
|
||||
}
|
||||
}
|
||||
if ($value) {
|
||||
$value = trim($value, ',');
|
||||
$ids = array_values(array_filter(array_map('intval', explode(',', $value))));
|
||||
$mylist = [];
|
||||
if ($ids) {
|
||||
$rows = \Phpcmf\Service::M()->db->table($table)->whereIn('id', $ids)->get();
|
||||
$rows = $rows ? $rows->getResultArray() : [];
|
||||
$map = [];
|
||||
foreach ($rows as $r) {
|
||||
$map[(int) $r['id']] = $r;
|
||||
}
|
||||
foreach ($ids as $id) {
|
||||
if (isset($map[$id])) {
|
||||
$mylist[] = $map[$id];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$tpl = $field['fieldname'];
|
||||
$file = \Phpcmf\Service::V()->code2php(
|
||||
file_get_contents(is_file(MYPATH.'View/api_join_field_'.$tpl.'.html') ? MYPATH.'View/api_join_field_'.$tpl.'.html' : COREPATH.'View/api_join_field.html')
|
||||
);
|
||||
ob_start();
|
||||
require $file;
|
||||
$str = ob_get_clean();
|
||||
|
||||
return $this->input_format($field['fieldname'], $field['name'], $str);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,322 @@
|
||||
<?php namespace Phpcmf\Field;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
class Linkage extends \Phpcmf\Library\A_Field {
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
public function __construct(...$params) {
|
||||
parent::__construct(...$params);
|
||||
$this->fieldtype = ['mediumint' => 8];
|
||||
$this->defaulttype = 'mediumint';
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段相关属性参数
|
||||
*
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function option($option) {
|
||||
|
||||
$str = '<select class="form-control" name="data[setting][option][linkage]">';
|
||||
$data = \Phpcmf\Service::M()->table('linkage')->getAll();
|
||||
if ($data) {
|
||||
$linkage = isset($option['linkage']) ? $option['linkage'] : '';
|
||||
foreach ($data as $t) {
|
||||
$str.= '<option value="'.$t['code'].'" '.($linkage == $t['code'] ? 'selected' : '').'> '.$t['name'].'('.$t['code'].') </option>';
|
||||
}
|
||||
}
|
||||
$str.= '</select>';
|
||||
|
||||
$str2 = '<select class="form-control" name="data[setting][option][file]"><option value=""> -- </option>';
|
||||
$files = dr_file_map(CONFIGPATH.'mylinkage/', 1);
|
||||
$files2 = dr_file_map(dr_get_app_dir($this->app).'Config/mylinkage/', 1);
|
||||
$files2 && $files = dr_array2array($files2, $files);
|
||||
if ($files) {
|
||||
foreach ($files as $t) {
|
||||
$t && strpos($t, '.php') !== 0 && $str2.= '<option value="'.$t.'" '.($option['file'] == $t ? 'selected' : '').'> '.$t.' </option>';
|
||||
}
|
||||
}
|
||||
$str2.= '</select>';
|
||||
|
||||
return ['<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('选择菜单').'</label>
|
||||
<div class="col-md-9"><label>'.$str.'</label></div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('强制选择最终项').'</label>
|
||||
<div class="col-md-9">
|
||||
<div class="mt-radio-inline">
|
||||
<label class="mt-radio mt-radio-outline"><input type="radio" value="1" name="data[setting][option][ck_child]" '.($option['ck_child'] == 1 ? 'checked' : '').' > '.dr_lang('开启').' <span></span></label>
|
||||
|
||||
<label class="mt-radio mt-radio-outline"><input type="radio" value="0" name="data[setting][option][ck_child]" '.($option['ck_child'] == 0 ? 'checked' : '').' > '.dr_lang('关闭').' <span></span></label>
|
||||
</div>
|
||||
<span class="help-block">'.dr_lang('开启后会强制要求用户选择最终一个选项,需要启用必须验证才会生效').'</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('输入框显示方式').'</label>
|
||||
<div class="col-md-9">
|
||||
<div class="mt-radio-inline">
|
||||
<label class="mt-radio mt-radio-outline"><input type="radio" value="1" name="data[setting][option][new]" '.($option['new'] == 1 ? 'checked' : '').' > '.dr_lang('折叠弹窗模式').' <span></span></label>
|
||||
|
||||
<label class="mt-radio mt-radio-outline"><input type="radio" value="0" name="data[setting][option][new]" '.($option['new'] == 0 ? 'checked' : '').' > '.dr_lang('经典模式').' <span></span></label>
|
||||
|
||||
</div>
|
||||
<span class="help-block">'.dr_lang('针对输入框效果的显示方式').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('默认选择值').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input id="field_default_value" type="text" class="form-control" size="20" value="'.$option['value'].'" name="data[setting][option][value]"></label>
|
||||
<label>'.$this->member_field_select().'</label>
|
||||
<span class="help-block">'.dr_lang('用于字段为空时显示该填充值,并不会去主动变更数据库中的实际值;可以设置会员表字段,表示用当前登录会员信息来填充这个值').'</span>
|
||||
</div>
|
||||
</div>
|
||||
', ''];
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建sql语句
|
||||
*/
|
||||
public function create_sql($name, $option, $cname = '') {
|
||||
// 联动菜单 ID:mediumint(8) UNSIGNED
|
||||
$type = 'mediumint(8)';
|
||||
$info = 'UNSIGNED NULL';
|
||||
$note = $cname ? (string)$cname : '';
|
||||
$db = $this->_db_for_field_sql();
|
||||
if ($db && method_exists($db, 'sqlAddField')) {
|
||||
return $db->sqlAddField($name, $type, $info, $note);
|
||||
}
|
||||
$tips = $note !== '' ? " COMMENT '".str_replace("'", "''", $note)."'" : '';
|
||||
return 'ALTER TABLE `{tablename}` ADD `'.$name.'` '.$type.' '.$info.$tips;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段输出
|
||||
*/
|
||||
public function output($value) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段入库值
|
||||
*
|
||||
* @param array $field 字段信息
|
||||
* @return void
|
||||
*/
|
||||
public function insert_value($field) {
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname']] = (int)\Phpcmf\Service::L('Field')->post[$field['fieldname']];
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证字段值
|
||||
*
|
||||
* @param string $field 字段类型
|
||||
* @param string $value 字段值
|
||||
* @return
|
||||
*/
|
||||
public function check_value($field, $value) {
|
||||
|
||||
$value = intval($value);
|
||||
if ($value) {
|
||||
$link = dr_linkage($field['setting']['option']['linkage'], $value);
|
||||
if (!$link) {
|
||||
return dr_lang('选项无效');
|
||||
} elseif ($field['setting']['option']['ck_child'] && $link['child']) {
|
||||
return dr_lang('需要选择下级选项');
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证必填字段值
|
||||
*
|
||||
* @param string $field 字段类型
|
||||
* @param string $value 字段值
|
||||
* @return
|
||||
*/
|
||||
public function check_required($field, $value) {
|
||||
|
||||
$value = intval($value);
|
||||
if (!$value) {
|
||||
// 验证值为空
|
||||
return dr_lang('%s不能为空', $field['name']);
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单输入
|
||||
*
|
||||
* @param string $field 字段数组
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function input($field, $value = null) {
|
||||
|
||||
// 字段禁止修改时就返回显示字符串
|
||||
if ($this->_not_edit($field, $value)) {
|
||||
return $this->show($field, $value);
|
||||
}
|
||||
|
||||
// 字段存储名称
|
||||
$name = $field['fieldname'];
|
||||
|
||||
// 字段显示名称
|
||||
$text = ($field['setting']['validate']['required'] ? '<span class="required" aria-required="true"> * </span>' : '').dr_lang($field['name']);
|
||||
|
||||
// 字段提示信息
|
||||
$tips = ($name == 'title' && APP_DIR) || $field['setting']['validate']['tips'] ? '<span class="help-block" id="dr_'.$field['fieldname'].'_tips">'.$field['setting']['validate']['tips'].'</span>' : '';
|
||||
|
||||
// 字段默认值
|
||||
$value = $value ? $value : $this->get_default_value($field['setting']['option']['value']);
|
||||
|
||||
|
||||
if ($field['setting']['option']['new']) {
|
||||
// 开始输出
|
||||
$str = '';
|
||||
if (!$this->is_load_js($field['fieldtype'])) {
|
||||
$str.= '
|
||||
<link rel="stylesheet" type="text/css" href="'.ROOT_THEME_PATH.'assets/layui/css/layui.css?v='.CMF_UPDATE_TIME.'"/>
|
||||
<link rel="stylesheet" type="text/css" href="'.ROOT_THEME_PATH.'assets/layui/cascader/cascader.css?v='.CMF_UPDATE_TIME.'"/>
|
||||
<script src="'.ROOT_THEME_PATH.'assets/layui/layui.js?v='.CMF_UPDATE_TIME.'"></script>
|
||||
<script src="'.ROOT_THEME_PATH.'assets/layui/cascader/cascader'.(IS_XRDEV ? '' : '.min').'.js?v='.CMF_UPDATE_TIME.'"></script>
|
||||
';
|
||||
$this->set_load_js($field['fieldtype'], 1);
|
||||
}
|
||||
|
||||
// 输出js支持
|
||||
$str.= '<input type="hidden" name="data['.$name.']" id="dr_'.$name.'" value="'.(int)$value.'" />
|
||||
<script src="'.WEB_DIR.'index.php?s=api&c=api&m=linkage&mid='.APP_DIR.'&file='.$field['setting']['option']['file'].'&code='.$field['setting']['option']['linkage'].'"></script>
|
||||
<script type="text/javascript">
|
||||
$(function (){
|
||||
layui.use(\'layCascader\', function () {
|
||||
var layCascader = layui.layCascader;
|
||||
layCascader({
|
||||
elem: \'#dr_'.$name.'\',
|
||||
value: \''.(int)$value.'\',
|
||||
clearable: true,
|
||||
filterable: true,
|
||||
options: linkage_'.$field['setting']['option']['linkage'].',
|
||||
props: {
|
||||
checkStrictly: '.($field['setting']['option']['ck_child'] ? 'false' : 'true').',
|
||||
}
|
||||
});
|
||||
})
|
||||
});
|
||||
</script>'.$tips;
|
||||
} else {
|
||||
// 联动菜单缓存
|
||||
$linkage = dr_linkage_list($field['setting']['option']['linkage'], 0);
|
||||
if (!$linkage) {
|
||||
if (CI_DEBUG) {
|
||||
return $this->input_format($name, $text, '<div class="form-control-static" style="color:red">联动菜单【'.$field['setting']['option']['linkage'].'】没有数据</div>');
|
||||
}
|
||||
return $this->input_format($name, $text, '');
|
||||
}
|
||||
|
||||
// 最大几层
|
||||
$linklevel = dr_linkage_level($field['setting']['option']['linkage']) + 1;
|
||||
|
||||
// 开始输出
|
||||
$str = '<input type="hidden" name="data['.$name.']" id="dr_'.$name.'" value="'.(int)$value.'">';
|
||||
if (!$this->is_load_js($field['fieldtype'].'_LD')) {
|
||||
$str.= '<script type="text/javascript" src="'.ROOT_THEME_PATH.'assets/js/jquery.ld.js?v='.CMF_UPDATE_TIME.'"></script>';
|
||||
$this->set_load_js($field['fieldtype'].'_LD', 1);
|
||||
}
|
||||
$level = 1;
|
||||
$default = '';
|
||||
if ($value) {
|
||||
$link = dr_linkage($field['setting']['option']['linkage'], $value);
|
||||
if ($link) {
|
||||
$pids = substr($link['pids'], 2);
|
||||
$level = substr_count($pids, ',') + 1;
|
||||
$default = !$pids ? '["'.$value.'"]' : '["'.str_replace(',', '","', $pids).'","'.$value.'"]';
|
||||
}
|
||||
}
|
||||
// 输出默认菜单
|
||||
$str.= '<span id="dr_linkage_'.$name.'_select" style="'.($value ? 'display:none' : '').'">';
|
||||
for ($i = 1; $i <= $linklevel; $i++) {
|
||||
$style = $i > $level ? 'style="display:none"' : '';
|
||||
$str.= '<label style="padding-right:10px;"><select class="form-control finecms-select-'.$name.'" name="'.$name.'-'.$i.'" id="'.$name.'-'.$i.'" width="100" '.$style.'><option value=""> -- </option></select></label>';
|
||||
}
|
||||
$str.= '<label id="dr_linkage_'.$name.'_html"></label>';
|
||||
$str.= '</span>';
|
||||
// 重新选择
|
||||
if ($value) {
|
||||
$str.= '<div id="dr_linkage_'.$name.'_cxselect">';
|
||||
$edit_html = '<div class="form-control-static" >'.dr_linkagepos($field['setting']['option']['linkage'], $value, ' » ').' <a href="javascript:;" onclick="dr_linkage_select_'.$name.'()" style="color:blue">'.dr_lang('[重新选择]').'</a></div>';
|
||||
if ($field['setting']['option']['file']) {
|
||||
$data = dr_linkage($field['setting']['option']['linkage'], $value);
|
||||
$file = CONFIGPATH.'mylinkage/'.$field['setting']['option']['file'];
|
||||
$file2 = dr_get_app_dir(APP_DIR).'Config/mylinkage/'.$field['setting']['option']['file'];
|
||||
if (is_file($file)) {
|
||||
require $file;
|
||||
} elseif (is_file($file2)) {
|
||||
require $file2;
|
||||
} else {
|
||||
log_message('error', '联动菜单自定义程序文件【'.$field['setting']['option']['file'].'】不存在');
|
||||
if (CI_DEBUG) {
|
||||
$edit_html.= '联动菜单自定义程序文件【'.$field['setting']['option']['file'].'】不存在';
|
||||
}
|
||||
}
|
||||
}
|
||||
$str.= $edit_html;
|
||||
$str.= '</div>';
|
||||
}
|
||||
// 输出js支持
|
||||
$str.= '
|
||||
<script type="text/javascript">
|
||||
function dr_linkage_select_'.$name.'() {
|
||||
$("#dr_linkage_'.$name.'_select").show();
|
||||
$("#dr_linkage_'.$name.'_cxselect").hide();
|
||||
}
|
||||
$(function(){
|
||||
var $ld5 = $(".finecms-select-'.$name.'");
|
||||
$ld5.ld({ajaxOptions:{"url": "'.WEB_DIR.'index.php?s=api&c=api&m=linkage_ld&mid='.APP_DIR.'&file='.$field['setting']['option']['file'].'&code='.$field['setting']['option']['linkage'].'"},inputId:"dr_linkage_'.$name.'_html",defaultParentId:0});
|
||||
var ld5_api = $ld5.ld("api");
|
||||
ld5_api.selected('.$default.');
|
||||
$ld5.bind("change", function(e){
|
||||
var $target = $(e.target);
|
||||
var index = $ld5.index($target);
|
||||
//$("#'.$name.'-'.$i.'").remove();
|
||||
var vv = $ld5.eq(index).show().val();
|
||||
$("#dr_'.$name.'").val(vv);
|
||||
index ++;
|
||||
$ld5.eq(index).show();
|
||||
//console.log("value="+vv);
|
||||
});
|
||||
})
|
||||
</script>'.$tips;
|
||||
}
|
||||
|
||||
|
||||
return $this->input_format($name, $text, $str);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单显示
|
||||
*
|
||||
* @param string $field 字段数组
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function show($field, $value = null) {
|
||||
|
||||
return $this->input_format($field['fieldname'], $field['name'], '<div class="form-control-static">'.dr_linkagepos($field['setting']['option']['linkage'], $value, ' - ').'</div>');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,383 @@
|
||||
<?php namespace Phpcmf\Field;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
class Linkages extends \Phpcmf\Library\A_Field {
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
public function __construct(...$params) {
|
||||
parent::__construct(...$params);
|
||||
$this->fieldtype = ['TEXT' => ''];
|
||||
$this->defaulttype = 'TEXT';
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段相关属性参数
|
||||
*
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function option($option) {
|
||||
|
||||
$str = '<select class="form-control" name="data[setting][option][linkage]">';
|
||||
$data = \Phpcmf\Service::M()->table('linkage')->getAll();
|
||||
if ($data) {
|
||||
$linkage = isset($option['linkage']) ? $option['linkage'] : '';
|
||||
foreach ($data as $t) {
|
||||
$str.= '<option value="'.$t['code'].'" '.($linkage == $t['code'] ? 'selected' : '').'> '.$t['name'].'('.$t['code'].') </option>';
|
||||
}
|
||||
}
|
||||
$str.= '</select>';
|
||||
|
||||
return [$this->_search_field().'<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('选择菜单').'</label>
|
||||
<div class="col-md-9"><label>'.$str.'</label></div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('最大选择数').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" size="10" name="data[setting][option][limit]" value="'.$option['limit'].'"></label>
|
||||
<span class="help-block">'.dr_lang('最大能选择的数量限制').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('强制选择最终项').'</label>
|
||||
<div class="col-md-9">
|
||||
<div class="mt-radio-inline">
|
||||
<label class="mt-radio mt-radio-outline"><input type="radio" value="1" name="data[setting][option][ck_child]" '.($option['ck_child'] == 1 ? 'checked' : '').' > '.dr_lang('开启').' <span></span></label>
|
||||
|
||||
<label class="mt-radio mt-radio-outline"><input type="radio" value="0" name="data[setting][option][ck_child]" '.($option['ck_child'] == 0 ? 'checked' : '').' > '.dr_lang('关闭').' <span></span></label>
|
||||
</div>
|
||||
<span class="help-block">'.dr_lang('开启后会强制要求用户选择最终一个选项,需要启用必须验证才会生效').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('折叠显示到一行').'</label>
|
||||
<div class="col-md-9">
|
||||
<div class="mt-radio-inline">
|
||||
<label class="mt-radio mt-radio-outline"><input type="radio" value="0" name="data[setting][option][collapse]" '.($option['collapse'] == 0 ? 'checked' : '').' > '.dr_lang('开启').' <span></span></label>
|
||||
|
||||
<label class="mt-radio mt-radio-outline"><input type="radio" value="1" name="data[setting][option][collapse]" '.($option['collapse'] == 1 ? 'checked' : '').' > '.dr_lang('关闭').' <span></span></label>
|
||||
|
||||
</div>
|
||||
<span class="help-block">'.dr_lang('多选模式下是否折叠显示选择值').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('输入框显示方式').'</label>
|
||||
<div class="col-md-9">
|
||||
<div class="mt-radio-inline">
|
||||
<label class="mt-radio mt-radio-outline"><input type="radio" value="1" name="data[setting][option][new]" '.($option['new'] == 1 ? 'checked' : '').' > '.dr_lang('折叠弹窗模式').' <span></span></label>
|
||||
|
||||
<label class="mt-radio mt-radio-outline"><input type="radio" value="0" name="data[setting][option][new]" '.($option['new'] == 0 ? 'checked' : '').' > '.dr_lang('经典模式').' <span></span></label>
|
||||
|
||||
</div>
|
||||
<span class="help-block">'.dr_lang('针对输入框效果的显示方式').'</span>
|
||||
</div>
|
||||
</div>
|
||||
', '<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('控件宽度').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" size="10" name="data[setting][option][width]" value="'.$option['width'].'"></label>
|
||||
<span class="help-block">'.dr_lang('[整数]表示固定宽度;[整数%]表示百分比').'</span>
|
||||
</div>
|
||||
</div>'];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 字段输出
|
||||
*/
|
||||
public function output($value) {
|
||||
return dr_string2array($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段入库值
|
||||
*
|
||||
* @param array $field 字段信息
|
||||
* @return void
|
||||
*/
|
||||
public function insert_value($field) {
|
||||
|
||||
$save = [];
|
||||
$data = \Phpcmf\Service::L('Field')->post[$field['fieldname']];
|
||||
if ($data) {
|
||||
$data = dr_string2array($data);
|
||||
if ($data) {
|
||||
foreach ($data as $t) {
|
||||
if ($t) {
|
||||
$save[] = $t;
|
||||
}
|
||||
}
|
||||
$save = array_unique($save);
|
||||
}
|
||||
}
|
||||
// 判断超限
|
||||
if ($field['setting']['option']['limit'] && dr_count($save) > $field['setting']['option']['limit']) {
|
||||
$save = array_slice($save, 0, $field['setting']['option']['limit']);
|
||||
}
|
||||
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname']] = dr_array2string($save);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证字段值
|
||||
*
|
||||
* @param string $field 字段类型
|
||||
* @param string $value 字段值
|
||||
* @return
|
||||
*/
|
||||
public function check_value($field, $value) {
|
||||
|
||||
$values = dr_string2array($value);
|
||||
if ($values) {
|
||||
foreach ($values as $value) {
|
||||
$link = dr_linkage($field['setting']['option']['linkage'], $value);
|
||||
if (!$link) {
|
||||
return dr_lang('选项无效');
|
||||
} elseif ($field['setting']['option']['ck_child'] && $link['child']) {
|
||||
return dr_lang('需要选择下级选项');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证必填字段值
|
||||
*
|
||||
* @param string $field 字段类型
|
||||
* @param string $value 字段值
|
||||
* @return
|
||||
*/
|
||||
public function check_required($field, $values) {
|
||||
|
||||
if (!$values) {
|
||||
// 验证值为空
|
||||
return dr_lang('%s不能为空', $field['name']);
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证加载变量设置
|
||||
*/
|
||||
public function set_load_js($name, $value) {
|
||||
\Phpcmf\Service::C()->loadjs['Linkage'] = \Phpcmf\Service::C()->loadjs[$name] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单输入
|
||||
*
|
||||
* @param string $field 字段数组
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function input($field, $value = null) {
|
||||
|
||||
// 字段禁止修改时就返回显示字符串
|
||||
if ($this->_not_edit($field, $value)) {
|
||||
return $this->show($field, $value);
|
||||
}
|
||||
|
||||
// 字段存储名称
|
||||
$name = $field['fieldname'];
|
||||
|
||||
// 字段显示名称
|
||||
$text = ($field['setting']['validate']['required'] ? '<span class="required" aria-required="true"> * </span>' : '').dr_lang($field['name']);
|
||||
|
||||
// 字段提示信息
|
||||
$tips = ($name == 'title' && APP_DIR) || $field['setting']['validate']['tips'] ? '<span class="help-block" id="dr_'.$field['fieldname'].'_tips">'.$field['setting']['validate']['tips'].'</span>' : '';
|
||||
|
||||
if ($field['setting']['option']['new']) {
|
||||
// 字段默认值
|
||||
$value = $value ? $value : $this->get_default_value($field['setting']['option']['value']);
|
||||
$value = dr_string2array($value);
|
||||
if (is_array($value)) {
|
||||
$new = [];
|
||||
foreach ($value as $t) {
|
||||
$new[] = (string)$t;
|
||||
}
|
||||
$value = json_encode($new);
|
||||
} else {
|
||||
$value = '[]';
|
||||
}
|
||||
|
||||
// 开始输出
|
||||
$str = '';
|
||||
if (!$this->is_load_js('Linkage')) {
|
||||
$str.= '
|
||||
<link rel="stylesheet" type="text/css" href="'.ROOT_THEME_PATH.'assets/layui/css/layui.css?v='.CMF_UPDATE_TIME.'"/>
|
||||
<link rel="stylesheet" type="text/css" href="'.ROOT_THEME_PATH.'assets/layui/cascader/cascader.css?v='.CMF_UPDATE_TIME.'"/>
|
||||
<script src="'.ROOT_THEME_PATH.'assets/layui/layui.js?v='.CMF_UPDATE_TIME.'"></script>
|
||||
<script src="'.ROOT_THEME_PATH.'assets/layui/cascader/cascader.js?v='.CMF_UPDATE_TIME.'"></script>
|
||||
';
|
||||
$this->set_load_js('Linkage', 1);
|
||||
}
|
||||
|
||||
// 输出js支持
|
||||
$str.= '<input type="hidden" name="data['.$name.']" id="dr_'.$name.'" value="'.$value.'" />
|
||||
<script src="'.WEB_DIR.'index.php?s=api&c=api&m=linkage&mid='.APP_DIR.'&file='.$field['setting']['option']['file'].'&code='.$field['setting']['option']['linkage'].'"></script>
|
||||
<script type="text/javascript">
|
||||
$(function (){
|
||||
layui.use(\'layCascader\', function () {
|
||||
var layCascader = layui.layCascader;
|
||||
layCascader({
|
||||
elem: \'#dr_'.$name.'\',
|
||||
value: '.$value.',
|
||||
clearable: true,
|
||||
filterable: false,
|
||||
maxSize: '.intval($field['setting']['option']['limit']).',
|
||||
collapseTags: '.($field['setting']['option']['collapse'] ? 'false' : 'true').',
|
||||
minCollapseTagsNumber: 0,
|
||||
options: linkage_'.$field['setting']['option']['linkage'].',
|
||||
props: {
|
||||
multiple: true,
|
||||
checkStrictly: '.($field['setting']['option']['ck_child'] ? 'false' : 'true').',
|
||||
}
|
||||
});
|
||||
})
|
||||
});
|
||||
</script>'.$tips;
|
||||
} else {
|
||||
// 经典模式
|
||||
// 联动菜单缓存
|
||||
$linkage = dr_linkage_list($field['setting']['option']['linkage'], 0);
|
||||
if (!$linkage) {
|
||||
if (CI_DEBUG) {
|
||||
return $this->input_format($name, $text, '<div class="form-control-static" style="color:red">联动菜单【'.$field['setting']['option']['linkage'].'】没有数据</div>');
|
||||
}
|
||||
return $this->input_format($name, $text, '');
|
||||
}
|
||||
|
||||
// 最大几层
|
||||
$linklevel = dr_linkage_level($field['setting']['option']['linkage']) + 1;
|
||||
// 开始输出
|
||||
$str = '';
|
||||
if (!$this->is_load_js($field['fieldtype'].'_LD')) {
|
||||
$str.= '<script type="text/javascript" src="'.ROOT_THEME_PATH.'assets/js/jquery.ld.js?v='.CMF_UPDATE_TIME.'"></script>';
|
||||
$this->set_load_js($field['fieldtype'].'_LD', 1);
|
||||
}
|
||||
|
||||
// 表单宽度设置
|
||||
$width = \Phpcmf\Service::IS_MOBILE_USER() ? '100%' : ($field['setting']['option']['width'] ? $field['setting']['option']['width'] : '100%');
|
||||
$str.= '<div class="dropzone-file-area" style="text-align:left" id="linkages-'.$name.'-sort-items" style="width:'.$width.(is_numeric($width) ? 'px' : '').';">';
|
||||
$level = 1;
|
||||
|
||||
// 输出默认菜单
|
||||
$tpl = '<div class="linkages_'.$name.'_row" id="dr_linkages_'.$name.'_row_{id}">';
|
||||
$tpl.= '<label style="margin-right: 10px;"><a class="btn btn-sm " href="javascript:;" onclick="$(\'#dr_linkages_'.$name.'_row_{id}\').remove()"> <i class="fa fa-close"></i> </a></label>';
|
||||
$tpl.= '<input type="hidden" name="data['.$name.'][{id}]" id="dr_'.$name.'_{id}" value="{value}" />';
|
||||
$tpl.= '<input type="hidden" id="dr_'.$name.'_{id}_default" value="" />';
|
||||
$tpl.= '<span id="dr_linkages_'.$name.'_select_{id}" style="display:{display}">';
|
||||
for ($i = 1; $i <= $linklevel; $i++) {
|
||||
$style = $i > $level ? 'style="display:none"' : '';
|
||||
$tpl.= '<label style="padding-right:10px;"><select class="form-control finecms-selects-'.$name.'-{id}" name="'.$name.'-'.$i.'-{id}" id="'.$name.'-'.$i.'-{id}" width="100" '.$style.'><option value=""> -- </option></select></label>';
|
||||
}
|
||||
$tpl.= '</span>';
|
||||
$tpl.= '</div>';
|
||||
|
||||
// 字段默认值
|
||||
$values = dr_string2array($value);
|
||||
if ($values) {
|
||||
foreach ($values as $id => $value) {
|
||||
if ($value) {
|
||||
$link = dr_linkage($field['setting']['option']['linkage'], $value);
|
||||
if (!$link) {
|
||||
continue;
|
||||
}
|
||||
$pids = substr((string)$link['pids'], 2);
|
||||
$level = substr_count($pids, ',') + 1;
|
||||
$default = !$pids ? '["'.$value.'"]' : '["'.str_replace(',', '","', $pids).'","'.$value.'"]';
|
||||
$str.= '<div class="linkages_'.$name.'_row" id="dr_linkages_'.$name.'_row_'.$id.'">';
|
||||
$str.= '<label style="margin-right: 10px;"><a class="btn btn-sm " href="javascript:;" onclick="$(\'#dr_linkages_'.$name.'_row_'.$id.'\').remove()"> <i class="fa fa-close"></i> </a></label>';
|
||||
$str.= '<input type="hidden" name="data['.$name.']['.$id.']" id="dr_'.$name.'_'.$id.'" value="'.$value.'" />';
|
||||
$str.= '<input type="hidden" id="dr_'.$name.'_'.$id.'_default" value="'.addslashes($default).'" />';
|
||||
$str.= '<span id="dr_linkages_'.$name.'_select_'.$id.'" style="display:none">';
|
||||
for ($i = 1; $i <= $linklevel; $i++) {
|
||||
$style = $i > $level ? 'style="display:none"' : '';
|
||||
$str.= '<label style="padding-right:10px;"><select class="form-control finecms-selects-'.$name.'-'.$id.'" name="'.$name.'-'.$i.'-'.$id.'" id="'.$name.'-'.$i.'-'.$id.'" width="100" '.$style.'><option value=""> -- </option></select></label>';
|
||||
}
|
||||
$str.= '</span>';
|
||||
$str.= '<label class="form-control-static" id="dr_linkages_'.$name.'_cxselect_'.$id.'">'.dr_linkagepos($field['setting']['option']['linkage'], $value, ' » ').' <a href="javascript:;" onclick="dr_linkages_select_'.$name.'('.$id.')" style="color:blue">'.dr_lang('[重新选择]').'</a></label>';
|
||||
$str.= '</div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 整体
|
||||
$str.= '</div>';
|
||||
$str.= '<div class="margin-top-10"> <a href="javascript:;" class="btn blue btn-sm" onClick="dr_add_linkages_'.$name.'()"> <i class="fa fa-plus"></i> '.dr_lang('添加').' </a>';
|
||||
$str.= '</div>';
|
||||
$str.= '<script type="text/javascript">
|
||||
$("#linkages-'.$name.'-sort-items").sortable();
|
||||
function dr_add_linkages_'.$name.'() {
|
||||
var num = $("#linkages-'.$name.'-sort-items .linkages_'.$name.'_row").length;
|
||||
if ('.(int)$field['setting']['option']['limit'].' > 0 && num >= '.(int)$field['setting']['option']['limit'].') {
|
||||
dr_tips(0, "'.dr_lang('最多可以选择%s项', $field['setting']['option']['limit']).'");
|
||||
return;
|
||||
}
|
||||
var id=(num + 1) * 10;
|
||||
var html = "'.addslashes($tpl).'";
|
||||
html = html.replace(/\{id\}/g, id);
|
||||
html = html.replace(/\{display\}/g, "blank");
|
||||
html = html.replace(/\{value\}/g, "0");
|
||||
$("#linkages-'.$name.'-sort-items").append(html);
|
||||
dr_linkages_init_'.$name.'(id);
|
||||
}
|
||||
function dr_linkages_select_'.$name.'(id) {
|
||||
$("#dr_linkages_'.$name.'_select_"+id).show();
|
||||
$("#dr_linkages_'.$name.'_cxselect_"+id).hide();
|
||||
dr_linkages_init_'.$name.'(id);
|
||||
}
|
||||
function dr_linkages_init_'.$name.'(id) {
|
||||
var $ld5 = $(".finecms-selects-'.$name.'-"+id);
|
||||
$ld5.ld({ajaxOptions:{"url": "'.WEB_DIR.'index.php?s=api&c=api&m=linkage_ld&code='.$field['setting']['option']['linkage'].'"},defaultParentId:0})
|
||||
var ld5_api = $ld5.ld("api");
|
||||
ld5_api.selected($("#dr_'.$name.'_"+id+"_default").val());
|
||||
$ld5.bind("change", function(e){
|
||||
var $target = $(e.target);
|
||||
var index = $ld5.index($target);
|
||||
$("#dr_'.$name.'_"+id).val($ld5.eq(index).show().val());
|
||||
index ++;
|
||||
$ld5.eq(index).show();
|
||||
});
|
||||
|
||||
}
|
||||
</script><span class="help-block">'.$tips.'</span>';
|
||||
}
|
||||
|
||||
|
||||
return $this->input_format($name, $text, $str);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单显示
|
||||
*
|
||||
* @param string $field 字段数组
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function show($field, $value = null) {
|
||||
|
||||
$str = '';
|
||||
$values = dr_string2array($value);
|
||||
if ($values) {
|
||||
foreach ($values as $value) {
|
||||
$str.= '<div class="form-control-static">'.dr_linkagepos($field['setting']['option']['linkage'], $value, ' - ').'</div>';
|
||||
}
|
||||
}
|
||||
|
||||
return $this->input_format($field['fieldname'], $field['name'], $str);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,249 @@
|
||||
<?php namespace Phpcmf\Field;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
class Members extends \Phpcmf\Library\A_Field {
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
public function __construct(...$params) {
|
||||
parent::__construct(...$params);
|
||||
$this->fieldtype = ['TEXT' => '']; // TRUE表全部可用字段类型,自定义格式为 array('可用字段类型名称' => '默认长度', ... )
|
||||
$this->defaulttype = 'TEXT'; // 当用户没有选择字段类型时的缺省值
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段相关属性参数
|
||||
*
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function option($option) {
|
||||
|
||||
$group = '<div class="mt-checkbox-inline">';
|
||||
foreach (\Phpcmf\Service::C()->member_cache['group'] as $t) {
|
||||
$group.= '<label class="mt-checkbox mt-checkbox-outline"><input type="checkbox" value="'.$t['id'].'" name="data[setting][option][group][]" '.(dr_in_array($t['id'], $option['group']) ? 'checked' : '').' /> '.dr_lang($t['name']).' <span></span></label>';
|
||||
}
|
||||
$group.= '</div>';
|
||||
|
||||
return [$this->_search_field().'
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('最大选择数').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" size="10" name="data[setting][option][limit]" value="'.$option['limit'].'"></label>
|
||||
<span class="help-block">'.dr_lang('最大能选择的数量限制').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('每页显示条数').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" size="10" name="data[setting][option][pagesize]" value="'.$option['pagesize'].'"></label>
|
||||
<span class="help-block">'.dr_lang('选择列表分页条数,按多少条数据分页').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('指定用户组').'</label>
|
||||
<div class="col-md-9">
|
||||
'.$group.'
|
||||
<span class="help-block">'.dr_lang('列出指定用户组的用户列表,如果不选择时将显示全部用户').'</span>
|
||||
</div>
|
||||
</div>'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段输出
|
||||
*/
|
||||
public function output($value) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段入库值
|
||||
*/
|
||||
public function insert_value($field) {
|
||||
|
||||
$data = \Phpcmf\Service::L('Field')->post[$field['fieldname']];
|
||||
$value = !$data ? '' : implode(',', $data);
|
||||
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname']] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单输入
|
||||
*
|
||||
* @param string $cname 字段别名
|
||||
* @param string $name 字段名称
|
||||
* @param array $cfg 字段配置
|
||||
* @param string $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function input($field, $value = '') {
|
||||
|
||||
// 字段禁止修改时就返回显示字符串
|
||||
if ($this->_not_edit($field, $value)) {
|
||||
return $this->show($field, $value);
|
||||
}
|
||||
|
||||
$is_show = 0;
|
||||
|
||||
// 字段存储名称
|
||||
$name = $field['fieldname'];
|
||||
// 字段提示信息
|
||||
$tips = isset($field['setting']['validate']['tips']) && $field['setting']['validate']['tips'] ? '<span class="help-block" id="dr_'.$name.'_tips">'.$field['setting']['validate']['tips'].'</span>' : '';
|
||||
|
||||
// 区域大小
|
||||
$area = \Phpcmf\Service::IS_MOBILE_USER() ? '["95%", "90%"]' : '["50%", "65%"]';
|
||||
|
||||
// 选择数量限制
|
||||
$limit = intval($field['setting']['option']['limit']);
|
||||
!$limit && $limit = 99999;
|
||||
// 字段显示名称
|
||||
$text = ($field['setting']['validate']['required'] ? '<span class="required" aria-required="true"> * </span>' : '').dr_lang($field['name']);
|
||||
|
||||
$value = $value ? trim($value, ',') : '';
|
||||
$mylist = [];
|
||||
if ($value && is_string($value)) {
|
||||
$arr = explode(',', $value);
|
||||
if ($arr) {
|
||||
$value = '';
|
||||
foreach ($arr as $a) {
|
||||
$a = intval($a);
|
||||
if ($a) {
|
||||
$value .= ',' . $a;
|
||||
}
|
||||
}
|
||||
if ($value) {
|
||||
$value = trim($value, ',');
|
||||
$db = \Phpcmf\Service::M()->db->query('select * from '.\Phpcmf\Service::M()->dbprefix('member').' where id IN ('.$value.') order by FIELD(id, '.$value.')');
|
||||
$mylist = $db ? $db->getResultArray() : [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$file = \Phpcmf\Service::V()->code2php(
|
||||
file_get_contents(is_file(MYPATH.'View/api_members_field_'.$field['fieldname'].'.html') ? MYPATH.'View/api_members_field_'.$field['fieldname'].'.html' : COREPATH.'View/api_members_field.html')
|
||||
);
|
||||
ob_start();
|
||||
require $file;
|
||||
$str = ob_get_clean();
|
||||
|
||||
$str.= $tips;
|
||||
$js = \Phpcmf\Service::L('js_packer');
|
||||
$str.= $js->pack('
|
||||
<script type="text/javascript">
|
||||
$("#rmember_'.$name.'-sort-items").sortable();
|
||||
dr_slimScroll_init(".scroller_'.$name.'_files", 300);
|
||||
function dr_add_rmember_'.$name.'() {
|
||||
var len = $(\'#rmember_'.$name.'-sort-items tr\').length;
|
||||
if (len >= '.$limit.') {
|
||||
dr_tips(0, "'.dr_lang('关联数量超限').'");
|
||||
return;
|
||||
}
|
||||
var url = "/index.php?&is_iframe=1&s=member&c=api&m=members&name='.$name.'&diy='.$field['fieldname'].'&pagesize='.intval($field['setting']['option']['pagesize']).'&group='.($field['setting']['option']['group'] ? implode(',', $field['setting']['option']['group']) : '').'";
|
||||
layer.open({
|
||||
type: 2,
|
||||
title: \'<i class="fa fa-user"></i> '.dr_lang('关联用户').'\',
|
||||
fix:true,
|
||||
shadeClose: true,
|
||||
shade: 0,
|
||||
area: '.$area.',
|
||||
btn: ["'.dr_lang('关联').'"],
|
||||
success: function (json) {
|
||||
if (json.code == 0) {
|
||||
layer.close();
|
||||
dr_tips(json.code, json.msg);
|
||||
}
|
||||
},
|
||||
yes: function(index, layero){
|
||||
var body = layer.getChildFrame(\'body\', index);
|
||||
// 延迟加载
|
||||
var loading = layer.load(2, {
|
||||
time: 10000
|
||||
});
|
||||
$.ajax({type: "POST",dataType:"json", url: url, data: $(body).find(\'#myform\').serialize(),
|
||||
success: function(json) {
|
||||
layer.close(loading);
|
||||
if (json.code == 1) {
|
||||
layer.close(index);
|
||||
for(var i in json.data.ids){
|
||||
var vid = json.data.ids[i];
|
||||
if (typeof vid != "undefined") {
|
||||
if($("#dr_items_'.$name.'_"+vid).length>0) {
|
||||
dr_tips(0, "'.dr_lang('已经存在').'");
|
||||
return;
|
||||
}
|
||||
if ($(\'#rmember_'.$name.'-sort-items tr\').length >= '.$limit.') {
|
||||
dr_tips(0, "'.dr_lang('关联数量超限').'");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
$(\'#rmember_'.$name.'-sort-items\').append(json.data.html);
|
||||
dr_slimScroll_init(".scroller_'.$name.'_files", 300);
|
||||
dr_tips(1, json.msg);
|
||||
} else {
|
||||
dr_tips(0, json.msg);
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
},
|
||||
content: url
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
</script>', 0);
|
||||
|
||||
return $this->input_format($name, $text, $str);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单显示
|
||||
*
|
||||
* @param string $field 字段数组
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function show($field, $value = null) {
|
||||
|
||||
$value = @trim($value, ',');
|
||||
$mylist = [];
|
||||
$is_show = 1;
|
||||
if ($value && is_string($value)) {
|
||||
$arr = explode(',', $value);
|
||||
if ($arr) {
|
||||
$value = '';
|
||||
foreach ($arr as $a) {
|
||||
$a = intval($a);
|
||||
if ($a) {
|
||||
$value .= ',' . $a;
|
||||
}
|
||||
}
|
||||
if ($value) {
|
||||
$value = trim($value, ',');
|
||||
$db = \Phpcmf\Service::M()->db->query('select * from '.\Phpcmf\Service::M()->dbprefix('member').' where id IN ('.$value.') order by FIELD(id, '.$value.')');
|
||||
$mylist = $db ? $db->getResultArray() : [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$file = \Phpcmf\Service::V()->code2php(
|
||||
file_get_contents(is_file(MYPATH.'View/api_members_field_'.$field['fieldname'].'.html') ? MYPATH.'View/api_members_field_'.$field['fieldname'].'.html' : COREPATH.'View/api_members_field.html')
|
||||
);
|
||||
ob_start();
|
||||
require $file;
|
||||
$str = ob_get_clean();
|
||||
|
||||
return $this->input_format($field['fieldname'], $field['name'], $str);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
<?php namespace Phpcmf\Field;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
class Merge extends \Phpcmf\Library\A_Field {
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
public function __construct(...$params) {
|
||||
parent::__construct(...$params);
|
||||
$this->close_xss = 1; // 关闭xss验证
|
||||
$this->is_edit = false; // 不允许修改字段类别
|
||||
$this->fieldtype = ['TEXT'];
|
||||
$this->defaulttype = 'TEXT';
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段相关属性参数
|
||||
*
|
||||
* @param array $value 值
|
||||
* @param array $field 字段集合
|
||||
* @return string
|
||||
*/
|
||||
public function option($option, $field = NULL) {
|
||||
$Merge = [];
|
||||
$option['value'] = isset($option['value']) ? $option['value'] : '';
|
||||
if ($field) {
|
||||
foreach ($field as $t) {
|
||||
if ($t['fieldtype'] == 'Merge') {
|
||||
$t['setting'] = dr_string2array($t['setting']);
|
||||
if (preg_match_all('/\{(.+)\}/U', $t['setting']['option']['value'], $value)) {
|
||||
foreach ($value[1] as $v) {
|
||||
$Merge[] = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$_field = [];
|
||||
$_field[] = '<option value=""> -- </option>';
|
||||
foreach ($field as $t) {
|
||||
$t['fieldtype'] != 'Merge' && !dr_in_array($t['fieldname'], $Merge) && $_field[] = '<option value="'.$t['fieldname'].'">'.$t['name'].'</option>';
|
||||
}
|
||||
$_field = implode('', array_unique($_field));
|
||||
}
|
||||
|
||||
return ['
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('可用字段').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><select class="form-control" name="xx" id="fxx">'.$_field.'</select></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('分组规则').'</label>
|
||||
<div class="col-md-9">
|
||||
<textarea name="data[setting][option][value]" id="fvalue" style="height:120px;" class="form-control">'.$option['value'].'</textarea>
|
||||
<span class="help-block">'.dr_lang('分组规则不支持html标签,注意每个字段只能存在于一个分组中,否则会出错;此字段只能用于模块中').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
$("#fxx").change(function(){
|
||||
var value = $(this).val();
|
||||
var fvalue = $("#fvalue").val();
|
||||
var text = $("#fxx").find("option:selected").text();
|
||||
$("#fxx option[value=\'"+value+"\']").remove();
|
||||
$("#fvalue").val(fvalue+"\n{"+value+"}");
|
||||
});
|
||||
});
|
||||
</script>
|
||||
'];
|
||||
}
|
||||
|
||||
/**
|
||||
* create_sql
|
||||
*/
|
||||
public function create_sql($name, $value, $cname = '') {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* alter_sql
|
||||
*/
|
||||
public function alter_sql($name, $value, $cname = '') {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* drop_sql
|
||||
*/
|
||||
public function drop_sql($name) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* test
|
||||
*/
|
||||
public function test_sql($tables, $field) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段入库值
|
||||
*/
|
||||
public function insert_value($field) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单输入
|
||||
* @return string
|
||||
*/
|
||||
public function input($field, $value = '') {
|
||||
|
||||
// 字段禁止修改时就返回显示字符串
|
||||
if ($this->_not_edit($field, $value)) {
|
||||
return $this->show($field, $value);
|
||||
}
|
||||
|
||||
return $this->input_format($field['fieldname'], $field['name'], $field['setting']['option']['value']);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
<?php namespace Phpcmf\Field;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
class Pay extends \Phpcmf\Library\A_Field {
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
public function __construct(...$params) {
|
||||
parent::__construct(...$params);
|
||||
$this->fieldtype = ['DECIMAL' => '10,2']; // TRUE表全部可用字段类型,自定义格式为 array('可用字段类型名称' => '默认长度', ... )
|
||||
$this->defaulttype = 'DECIMAL'; // 当用户没有选择字段类型时的缺省值
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段相关属性参数
|
||||
*
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function option($option) {
|
||||
|
||||
!$option['payfile'] && $option['payfile'] = 'buy.html';
|
||||
|
||||
$opt = '
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('模板文件').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" size="20" name="data[setting][option][payfile]" value="'.$option['payfile'].'"></label>
|
||||
<span class="help-block">'.dr_lang('模板位于./config/pay/模板文件名').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('余额付款').'</label>
|
||||
<div class="col-md-9">
|
||||
<input type="checkbox" name="data[setting][option][is_finecms]" '.($option['is_finecms'] ? 'checked' : '').' value="1" data-on-text="'.dr_lang('已开启').'" data-off-text="'.dr_lang('已关闭').'" data-on-color="success" data-off-color="danger" class="make-switch" data-size="small">
|
||||
</div>
|
||||
</div>
|
||||
';
|
||||
|
||||
$style = '
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('控件宽度').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" size="10" name="data[setting][option][width]" value="'.$option['width'].'"></label>
|
||||
<span class="help-block">'.dr_lang('[整数]表示固定宽度;[整数%]表示百分比').'</span>
|
||||
</div>
|
||||
</div>
|
||||
';
|
||||
|
||||
return [$opt, $style];
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段入库值
|
||||
*
|
||||
* @param array $field 字段信息
|
||||
* @return void
|
||||
*/
|
||||
public function insert_value($field) {
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname']] = (float)\Phpcmf\Service::L('Field')->post[$field['fieldname']];
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单输入
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function input($field, $value = '', $html = []) {
|
||||
|
||||
if (!defined('FC_PAY') && (IS_MEMBER || IS_ADMIN)) {
|
||||
// 字段显示名称
|
||||
$text = ($field['setting']['validate']['required'] ? '<span class="required" aria-required="true"> * </span>' : '').dr_lang($field['name']);
|
||||
// 表单宽度设置
|
||||
$width = \Phpcmf\Service::IS_MOBILE_USER() ? '100%' : ((int)$field['setting']['option']['width'] ? $field['setting']['option']['width'] : 250);
|
||||
|
||||
// 表单附加参数
|
||||
$attr = 'style="width:'.$width.(is_numeric($width) ? 'px' : '').';" '.$field['setting']['validate']['formattr'];
|
||||
// 字段提示信息
|
||||
$tips = $field['setting']['validate']['tips'] ? '<span class="help-block" id="dr_'.$field['fieldname'].'_tips">'.$field['setting']['validate']['tips'].'</span>' : '';
|
||||
// 当字段必填时,加入html5验证标签
|
||||
$required = $field['setting']['validate']['required'] ? ' required="required"' : '';
|
||||
// 字段默认值
|
||||
$value = dr_strlen($value) ? $value : $this->get_default_value($field['setting']['option']['value']);
|
||||
$ipt = '<input class="form-control '.$field['setting']['option']['css'].'" type="text" name="data['.$field['fieldname'].']" id="dr_'.$field['fieldname'].'" value="'.$value.'" '.$required.' '.$attr.' />';
|
||||
|
||||
return $this->input_format($field['fieldname'], $text, $ipt.$tips);
|
||||
} else {
|
||||
|
||||
// 付款金额
|
||||
$html['pay_value'] = $value ? $value : 0;
|
||||
|
||||
if (!dr_is_app('pay')) {
|
||||
return '没有安装「支付系统」插件';
|
||||
}
|
||||
// 付款方式
|
||||
$html['pay_type'] = \Phpcmf\Service::M('pay', 'pay')->get_pay_type(\Phpcmf\Service::C()->member && $field['setting']['option']['is_finecms'] && is_file(ROOTPATH.'api/pay/finecms/config.php'));
|
||||
|
||||
// 取默认第一个
|
||||
if ($html['pay_type']) {
|
||||
reset($html['pay_type']);
|
||||
$html['pay_default'] = key($html['pay_type']);
|
||||
}
|
||||
|
||||
// 付款界面模板
|
||||
if (isset($html['tpl']) && $html['tpl'] && is_file($html['tpl'])) {
|
||||
$htmlfile = $html['tpl'];
|
||||
// 验证路径合法性
|
||||
if (!\Phpcmf\Service::V()->_safe_template_path($htmlfile)) {
|
||||
return '支付表单模板文件路径不合法:'.$htmlfile.'<br>'.(\Phpcmf\Service::V()->_safe_template_error);
|
||||
}
|
||||
} else {
|
||||
$htmlfile = CONFIGPATH.'pay/buy.html';
|
||||
if ($field['setting']['option']['payfile']) {
|
||||
if (is_file(WEBPATH.'config/pay/'.$field['setting']['option']['payfile'])) {
|
||||
$htmlfile = WEBPATH.'config/pay/'.$field['setting']['option']['payfile'];
|
||||
} elseif (is_file(CONFIGPATH.'pay/'.$field['setting']['option']['payfile'])) {
|
||||
$htmlfile = CONFIGPATH.'pay/'.$field['setting']['option']['payfile'];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!is_file($htmlfile)) {
|
||||
return '支付表单模板文件不存在:'.$htmlfile;
|
||||
}
|
||||
|
||||
$member = \Phpcmf\Service::C()->member;
|
||||
$pay_url = \Phpcmf\Service::L('router')->member_url('pay/pay/index');
|
||||
|
||||
// 获取付款界面代码
|
||||
ob_start();
|
||||
$file = \Phpcmf\Service::V()->code2php(file_get_contents($htmlfile));
|
||||
require $file;
|
||||
$code = ob_get_clean();
|
||||
|
||||
return $code;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单显示
|
||||
*
|
||||
* @param string $field 字段数组
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function show($field, $value = null) {
|
||||
return $this->input_format($field['fieldname'], $field['name'], '<div class="form-control-static">¥'.$value.'元</div>');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,857 @@
|
||||
<?php namespace Phpcmf\Field;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
class Pays extends \Phpcmf\Library\A_Field {
|
||||
|
||||
protected $showfield = [
|
||||
'image' => '图片',
|
||||
'price' => '价格',
|
||||
'quantity' => '数量',
|
||||
'sn' => '编码',
|
||||
];
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
public function __construct(...$params) {
|
||||
parent::__construct(...$params);
|
||||
$this->fieldtype = ['DECIMAL' => '10,2']; // TRUE表全部可用字段类型,自定义格式为 array('可用字段类型名称' => '默认长度', ... )
|
||||
$this->defaulttype = 'DECIMAL'; // 当用户没有选择字段类型时的缺省值
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段相关属性参数
|
||||
*
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function option($option, $field = null) {
|
||||
|
||||
$myfield = $this->showfield;
|
||||
!$option['field'] && $option['field'] = [];
|
||||
!$option['payfile'] && $option['payfile'] = 'buy.html';
|
||||
foreach ($field as $t) {
|
||||
$t['fieldtype'] == 'Paystext' && $myfield[$t['fieldname']] = $t['name'];
|
||||
}
|
||||
$param_html = '';
|
||||
foreach ($myfield as $id => $t) {
|
||||
$param_html.= '<p style="margin-bottom:10px">';
|
||||
$param_html.= '<input type="checkbox" name="data[setting][option][field][]" '.(dr_in_array($id, $option['field']) ? 'checked' : '').' value="'.$id.'" data-on-text="'.dr_lang('%s已显示', dr_lang($t)).'" data-off-text="'.dr_lang('%s已禁用', dr_lang($t)).'" data-on-color="success" data-off-color="danger" class="make-switch" data-size="small">
|
||||
';
|
||||
$param_html.= '</p>';
|
||||
}
|
||||
|
||||
$tpl_group = $this->_get_tpl_group('data[setting][option][sku]');
|
||||
$tpl_value = $this->_get_tpl_value('data[setting][option][sku]');
|
||||
$value = $option;
|
||||
|
||||
// 显示字段
|
||||
|
||||
$result = '';
|
||||
if (isset($value['sku']['group']) && $value['sku']['group']) {
|
||||
foreach ($value['sku']['group'] as $id => $name) {
|
||||
$html = '';
|
||||
if (isset($value['sku']['name'][$id]) && $value['sku']['name'][$id]) {
|
||||
foreach ($value['sku']['name'][$id] as $iid => $vname) {
|
||||
$html.= str_replace(
|
||||
['{id}', '{name}', '{iid}'],
|
||||
[$id, $vname, $iid],
|
||||
$tpl_value
|
||||
);
|
||||
}
|
||||
}
|
||||
$result.= str_replace(
|
||||
['{id}', '{name}', '{value}'],
|
||||
[$id, $name, $html],
|
||||
$tpl_group
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$opt = '
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('模板文件').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" size="20" name="data[setting][option][payfile]" value="'.$option['payfile'].'"></label>
|
||||
<span class="help-block">'.dr_lang('模板位于./config/pay/模板文件名').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('定价模式').'</label>
|
||||
<div class="col-md-9">
|
||||
<div class="mt-radio-inline">
|
||||
<label class="mt-radio mt-radio-outline"><input type="radio" value="0" name="data[setting][option][close_one]" '.(!$option['close_one'] ? 'checked' : '').' > '.dr_lang('单一定价+组合定价').' <span></span></label>
|
||||
|
||||
<label class="mt-radio mt-radio-outline"><input type="radio" value="1" name="data[setting][option][close_one]" '.($option['close_one'] ? 'checked' : '').' > '.dr_lang('组合定价').' <span></span></label>
|
||||
|
||||
</div>
|
||||
<span class="help-block">'.dr_lang('可以选择单一定价+组合定价模式、组合定价模式两种方式').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('固定组合规格').'</label>
|
||||
<div class="col-md-9">
|
||||
<div class="mt-radio-inline">
|
||||
<label class="mt-radio mt-radio-outline"><input onclick="$(\'.gdggb\').show()" type="radio" value="1" name="data[setting][option][is_sku]" '.($option['is_sku'] ? 'checked' : '').' > '.dr_lang('开启').' <span></span></label>
|
||||
|
||||
<label class="mt-radio mt-radio-outline"><input onclick="$(\'.gdggb\').hide()" type="radio" value="0" name="data[setting][option][is_sku]" '.(!$option['is_sku'] ? 'checked' : '').' > '.dr_lang('关闭').' <span></span></label>
|
||||
</div>
|
||||
<span class="help-block">'.dr_lang('固定规格会调用指定的规格表,用户不能修改和添加属性').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group gdggb" style="display: '.($option['is_sku'] ? 'blank' : 'none').'" >
|
||||
<label class="col-md-2 control-label">'.dr_lang('指定规格表').'</label>
|
||||
<div class="col-md-9">
|
||||
<div id="dr_field_pays">
|
||||
<label><button type="button" class="btn blue btn-sm" onclick="dr_sku_add_group()"> <i class="fa fa-plus"></i> '.dr_lang('添加属性').'</button></label>
|
||||
<div class="portlet light bordered">
|
||||
<div id="dr_sku_result">
|
||||
'.$result.'
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
var arrayValue = new Array();
|
||||
var tpl_group = "'.$this->_js_var($tpl_group).'";
|
||||
var tpl_value = "'.$this->_js_var($tpl_value).'";
|
||||
var field_name = "_sku";
|
||||
var sku_field_name = "";
|
||||
var sku_field_id = "";
|
||||
</script>
|
||||
<script type="text/javascript" src="'.ROOT_THEME_PATH.'assets/js/sku.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(function(){
|
||||
dr_sku_init();
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('余额付款').'</label>
|
||||
<div class="col-md-9">
|
||||
<input type="checkbox" name="data[setting][option][is_finecms]" '.($option['is_finecms'] ? 'checked' : '').' value="1" data-on-text="'.dr_lang('已开启').'" data-off-text="'.dr_lang('已关闭').'" data-on-color="success" data-off-color="danger" class="make-switch" data-size="small">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('显示参数').'</label>
|
||||
<div class="col-md-9">
|
||||
'.$param_html.'
|
||||
</div>
|
||||
</div>
|
||||
';
|
||||
|
||||
$style = '
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('控件宽度').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" size="10" name="data[setting][option][width]" value="'.$option['width'].'"></label>
|
||||
<span class="help-block">'.dr_lang('[整数]表示固定宽度;[整数%]表示百分比').'</span>
|
||||
</div>
|
||||
</div>
|
||||
';
|
||||
|
||||
return [$this->_search_field().$opt, $style];
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建sql语句
|
||||
*/
|
||||
public function create_sql($name, $value, $cname = '') {
|
||||
|
||||
$columns = [
|
||||
['name' => $name, 'type' => 'DECIMAL(9,2)', 'info' => 'NULL'],
|
||||
['name' => $name.'_sku', 'type' => 'TEXT', 'info' => 'NULL'],
|
||||
['name' => $name.'_quantity', 'type' => 'INT(10)', 'info' => 'UNSIGNED NULL'],
|
||||
['name' => $name.'_sn', 'type' => 'VARCHAR(10)', 'info' => 'NULL'],
|
||||
];
|
||||
$db = $this->_db_for_field_sql();
|
||||
if ($db && method_exists($db, 'sqlAddFields')) {
|
||||
return $db->sqlAddFields($columns);
|
||||
}
|
||||
|
||||
// 驱动未就绪时回退 MySQL 方言
|
||||
return 'ALTER TABLE `{tablename}` ADD `'.$name.'` DECIMAL(9,2) NULL, ADD `'.$name.'_sku` TEXT NULL, ADD `'.$name.'_quantity` INT(10) UNSIGNED NULL, ADD `'.$name.'_sn` VARCHAR(10) NULL';
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改sql语句
|
||||
*/
|
||||
public function alter_sql($name, $value, $cname = '') {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除sql语句
|
||||
*/
|
||||
public function drop_sql($name) {
|
||||
|
||||
$names = [$name, $name.'_sku', $name.'_quantity', $name.'_sn'];
|
||||
$db = $this->_db_for_field_sql();
|
||||
if ($db && method_exists($db, 'sqlDropFields')) {
|
||||
return $db->sqlDropFields($names);
|
||||
}
|
||||
|
||||
return 'ALTER TABLE `{tablename}` DROP `'.$name.'`, DROP `'.$name.'_sku`, DROP `'.$name.'_quantity`, DROP `'.$name.'_sn`';
|
||||
}
|
||||
|
||||
// 测试字段是否被创建成功,默认成功为0,需要继承开发
|
||||
public function test_sql($tables, $field) {
|
||||
|
||||
if (!$tables) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
foreach ($tables as $table) {
|
||||
if (!\Phpcmf\Service::M()->db->fieldExists($field.'_sku', $table)) {
|
||||
return '给表['.$table.']创建字段['.$field.'_sku'.']失败';
|
||||
}
|
||||
if (!\Phpcmf\Service::M()->db->fieldExists($field.'_quantity', $table)) {
|
||||
return '给表['.$table.']创建字段['.$field.'_quantity'.']失败';
|
||||
}
|
||||
if (!\Phpcmf\Service::M()->db->fieldExists($field.'_sn', $table)) {
|
||||
return '给表['.$table.']创建字段['.$field.'_sn'.']失败';
|
||||
}
|
||||
if (!\Phpcmf\Service::M()->db->fieldExists($field, $table)) {
|
||||
return '给表['.$table.']创建字段['.$field.']失败';
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 显示字段
|
||||
protected function _get_myfield($field) {
|
||||
|
||||
$my = [];
|
||||
$_field = \Phpcmf\Service::L('field')->fields;
|
||||
foreach ($field['setting']['option']['field'] as $ff) {
|
||||
if (isset($this->showfield[$ff])) {
|
||||
$my[$ff] = $this->showfield[$ff];
|
||||
} elseif (isset($_field[$ff])) {
|
||||
$my[$ff] = $_field[$ff]['name'];
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return $my;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段入库值
|
||||
*
|
||||
* @param array $field 字段信息
|
||||
* @return void
|
||||
*/
|
||||
public function insert_value($field) {
|
||||
|
||||
if (isset($field['setting']['option']['close_one']) && $field['setting']['option']['close_one']) {
|
||||
$is_field_pay = 1;
|
||||
} else {
|
||||
$is_field_pay = (int)$_POST['is_field_pay'];
|
||||
}
|
||||
|
||||
if ($is_field_pay) {
|
||||
// 组合
|
||||
$price = 0;
|
||||
$quantity = 0;
|
||||
if (isset($field['setting']['option']['is_sku']) && $field['setting']['option']['is_sku']) {
|
||||
$sku = $field['setting']['option']['sku'];
|
||||
$sku['value'] = $_POST['data'][$field['fieldname'].'_sku']['value'];
|
||||
} else {
|
||||
$sku = $_POST['data'][$field['fieldname'].'_sku'];
|
||||
}
|
||||
if ($sku['value']) {
|
||||
$price_array = [];
|
||||
foreach ($sku['value'] as $v) {
|
||||
$quantity+= intval($v['quantity']);
|
||||
$price_array[] = $v['price'];
|
||||
}
|
||||
$price = min($price_array);
|
||||
}
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname']] = (float)$price;
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname'].'_sn'] = '';
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname'].'_sku'] = dr_array2string($sku);
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname'].'_quantity'] = abs((int)$quantity);
|
||||
} else {
|
||||
// 单一
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname']] = (float)$_POST[$field['fieldname']]['price'];
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname'].'_sn'] = dr_safe_replace($_POST[$field['fieldname']]['sn']);
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname'].'_sku'] = '';
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname'].'_quantity'] = (int)$_POST[$field['fieldname']]['quantity'];
|
||||
$_field = \Phpcmf\Service::L('form')->fields;
|
||||
foreach ($field['setting']['option']['field'] as $ff) {
|
||||
if (isset($_field[$ff])) {
|
||||
\Phpcmf\Service::L('Field')->data[$_field[$ff]['ismain']][$ff] = (string)$_POST[$field['fieldname']][$ff];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取附件id
|
||||
*/
|
||||
public function get_attach_id($value) {
|
||||
|
||||
if (!$this->field) {
|
||||
return NULL;
|
||||
} elseif (!dr_in_array('image', $this->field['setting']['option']['field'])) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
$data = [];
|
||||
$value = dr_string2array($value);
|
||||
|
||||
if ($value) {
|
||||
foreach ($value as $tt) {
|
||||
if (isset($tt['image']) && $tt['image']) {
|
||||
$data[] = intval($tt['image']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 附件处理
|
||||
*/
|
||||
public function attach($data, $_data) {
|
||||
|
||||
if (!$this->field) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
$data = isset($_POST['data'][$this->field['fieldname'].'_sku']['value']) ? $_POST['data'][$this->field['fieldname'].'_sku']['value'] : [];
|
||||
if (isset(\Phpcmf\Service::L('Field')->old[$this->field['fieldname'].'_sku'])) {
|
||||
$old = dr_string2array(\Phpcmf\Service::L('Field')->old[$this->field['fieldname'].'_sku']);
|
||||
$_data = isset($old['value']) ? $old['value'] : [];
|
||||
}
|
||||
|
||||
$data = $this->get_attach_id($data);
|
||||
$_data = $this->get_attach_id($_data);
|
||||
|
||||
if (!isset($_data)) {
|
||||
$_data = [];
|
||||
}
|
||||
|
||||
if (!isset($data)) {
|
||||
$data = [];
|
||||
}
|
||||
|
||||
// 新旧数据都无附件就跳出
|
||||
if (!$data && !$_data) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 新旧数据都一样时表示没做改变就跳出
|
||||
if (dr_diff($data, $_data)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 当无新数据且有旧数据表示删除旧附件
|
||||
if (!$data && $_data) {
|
||||
return [
|
||||
[],
|
||||
$_data
|
||||
];
|
||||
}
|
||||
|
||||
// 当无旧数据且有新数据表示增加新附件
|
||||
if ($data && !$_data) {
|
||||
return [
|
||||
$data,
|
||||
[]
|
||||
];
|
||||
}
|
||||
|
||||
// 剩下的情况就是删除旧文件增加新文件
|
||||
|
||||
// 新旧附件的交集,表示固定的
|
||||
$intersect = array_intersect($data, $_data);
|
||||
|
||||
return [
|
||||
array_diff($data, $intersect), // 固有的与新文件中的差集表示新增的附件
|
||||
array_diff($_data, $intersect), // 固有的与旧文件中的差集表示待删除的附件
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证必填字段值
|
||||
*
|
||||
* @param string $field 字段类型
|
||||
* @param string $value 字段值
|
||||
* @return
|
||||
*/
|
||||
public function check_required($field, $value) {
|
||||
|
||||
if (isset($field['setting']['option']['close_one']) && $field['setting']['option']['close_one']) {
|
||||
$is_field_pay = 1;
|
||||
} else {
|
||||
$is_field_pay = (int)$_POST['is_field_pay'];
|
||||
}
|
||||
|
||||
if ($is_field_pay) {
|
||||
if (isset($field['setting']['option']['is_sku']) && $field['setting']['option']['is_sku']) {
|
||||
$sku = $field['setting']['option']['sku'];
|
||||
$sku['value'] = $_POST['data'][$field['fieldname'].'_sku']['value'];
|
||||
} else {
|
||||
$sku = $_POST['data'][$field['fieldname'].'_sku'];
|
||||
}
|
||||
if ($sku['value']) {
|
||||
foreach ($sku['value'] as $v) {
|
||||
if (strlen($v['price']) == 0) {
|
||||
return dr_lang('%s不能为空', $field['name']);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (strlen($_POST[$field['fieldname']]['price']) == 0) {
|
||||
return dr_lang('%s不能为空', $field['name']);
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段值
|
||||
*/
|
||||
public function get_value($name, $data) {
|
||||
|
||||
$value = [
|
||||
'price' => $data[$name],
|
||||
'sku' => dr_string2array($data[$name.'_sku']),
|
||||
'sn' => $data[$name.'_sn'],
|
||||
'quantity' => $data[$name.'_quantity'],
|
||||
];
|
||||
|
||||
$field = \Phpcmf\Service::L('field')->fields;
|
||||
|
||||
foreach ($field[$name]['setting']['option']['field'] as $ff ) {
|
||||
if ($field[$ff]['fieldtype'] == 'Paystext') {
|
||||
$value[$ff] = (string)$data[$ff];
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付时获取商品属性
|
||||
*/
|
||||
public function get_pay_info($rt, $field, $sku) {
|
||||
|
||||
$rt[$field['fieldname'].'_sku'] = dr_string2array($rt[$field['fieldname'].'_sku']);
|
||||
if (!$sku && $rt[$field['fieldname'].'_sku']) {
|
||||
return dr_return_data(0, dr_lang('没有选择商品属性'));
|
||||
} elseif (!isset($rt[$field['fieldname'].'_sku']['value'][$sku]) || !$rt[$field['fieldname'].'_sku']['value'][$sku]) {
|
||||
return dr_return_data(0, dr_lang('商品(#'.$rt['id'].')属性(#'.$sku.')无效'));
|
||||
}
|
||||
|
||||
$sn = (string)$rt[$field['fieldname'].'_sku']['value'][$sku]['sn'];
|
||||
$quantity = (int)$rt[$field['fieldname'].'_sku']['value'][$sku]['quantity'];
|
||||
list($sku_name, $sku_string) = dr_sku_name($sku, $rt[$field['fieldname'].'_sku'], 1);
|
||||
|
||||
return dr_return_data(1, '', [$sn, $quantity, $sku_name, $sku_string]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段输出
|
||||
*
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function output($value) {
|
||||
return (float)$value;
|
||||
}
|
||||
|
||||
protected function _get_tpl_value($name) {
|
||||
return '
|
||||
<div class="fc-sku-group-value col-md-4" id="dr_sku_value_{id}_{iid}" did="{iid}">
|
||||
<div class="input-group input-group-sm">
|
||||
<input type="text" class="fc-sku-value-name-input form-control" onblur="dr_sku_init()" name="'.$name.'[name][{id}][{iid}]" fname="{id}_{iid}" value="{name}">
|
||||
<span class="input-group-btn">
|
||||
<button class="btn red" onclick="javascript:dr_sku_del_value(\'{id}\', \'{iid}\');" type="button"><i class="fa fa-trash"></i></button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
';
|
||||
}
|
||||
protected function _get_tpl_group($name) {
|
||||
|
||||
return '
|
||||
<div class="portlet-body fc-sku-group" id="dr_sku_group_{id}" did="{id}">
|
||||
<input type="hidden" id="dr_sku_group_text_{id}" name="'.$name.'[group][{id}]" value="{name}">
|
||||
<div class="row fc-sku-group-name">
|
||||
<div class="col-md-6 fc-sku-group-name-input">{name}</div>
|
||||
<div class="text-right col-md-6">
|
||||
<button onclick="javascript:dr_sku_add_value(\'{id}\');" type="button" class="btn green btn-sm"> '.dr_lang('添加值').'</button>
|
||||
<button onclick="javascript:dr_sku_edit_group(\'{id}\');" type="button" class="edit btn blue btn-sm"> '.dr_lang('修改').'</button>
|
||||
<button onclick="javascript:dr_sku_save_group(\'{id}\');" type="button" class="save btn blue btn-sm" style="display:none"> '.dr_lang('保存').'</button>
|
||||
<button onclick="javascript:dr_sku_del_group(\'{id}\');" type="button" class="btn red btn-sm"> '.dr_lang('删除').'</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row fc-sku-group-body" id="dr_sku_value_{id}">
|
||||
{value}
|
||||
</div>
|
||||
</div>
|
||||
';
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单输入
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function input($field, $value = [], $html = []) {
|
||||
|
||||
if (!defined('FC_PAY') && (IS_MEMBER || IS_ADMIN)) {
|
||||
|
||||
if (!$field['setting']['option']['field']) {
|
||||
return $this->input_format($field['fieldname'], $field['name'], '<div class="form-control-static">字段Pays没有设置显示参数</div>');
|
||||
}
|
||||
|
||||
// 字段显示名称
|
||||
$text = ($field['setting']['validate']['required'] ? '<span class="required" aria-required="true"> * </span>' : '').dr_lang($field['name']);
|
||||
|
||||
// 字段提示信息
|
||||
$tips = $field['setting']['validate']['tips'] ? '<span class="help-block" id="dr_'.$field['fieldname'].'_tips">'.$field['setting']['validate']['tips'].'</span>' : '';
|
||||
|
||||
$tpl_group = $this->_get_tpl_group('data['.$field['fieldname'].'_sku]');
|
||||
|
||||
$tpl_value = $this->_get_tpl_value('data['.$field['fieldname'].'_sku]');
|
||||
|
||||
$image_url ='/'.(IS_ADMIN ? SELF.'?c=api' : 'index.php?s=api&c=file').'&m=input_file_list&token='.dr_get_csrf_token().'&siteid='.SITE_ID.'&p='.dr_authcode([
|
||||
'size' => 10,
|
||||
'count' => 1,
|
||||
'exts' => 'jpg,gif,png',
|
||||
'attachment' => 0,
|
||||
'image_reduce' => 0,
|
||||
], 'ENCODE').'&ct=0&one=1';
|
||||
// 显示字段
|
||||
$pay_html = ''; // 单一模式下的输出
|
||||
$myfield = $this->_get_myfield($field);
|
||||
$sku_field_name = '';
|
||||
$sku_field_id = [];
|
||||
foreach ($myfield as $ff => $name) {
|
||||
if ($ff == 'image') {
|
||||
|
||||
} else {
|
||||
$pay_html.= '<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.$name.'</label>
|
||||
<div class="col-md-7">
|
||||
<input type="text" name="'.$field['fieldname'].'['.$ff.']" value="'.(isset($value[$ff]) ? $value[$ff] : '').'" class="form-control input-inline input-medium">
|
||||
</div>
|
||||
</div>';
|
||||
}
|
||||
|
||||
$sku_field_name.= '<th>'.$name.'</th>';
|
||||
$sku_field_id[] = $ff;
|
||||
}
|
||||
|
||||
|
||||
if (isset($field['setting']['option']['is_sku']) && $field['setting']['option']['is_sku']) {
|
||||
$value['sku']['name'] = $field['setting']['option']['sku']['name'];
|
||||
$value['sku']['group'] = $field['setting']['option']['sku']['group'];
|
||||
}
|
||||
|
||||
$result = '';
|
||||
if (isset($value['sku']['group']) && $value['sku']['group']) {
|
||||
foreach ($value['sku']['group'] as $id => $name) {
|
||||
$html = '';
|
||||
if (isset($value['sku']['name'][$id]) && $value['sku']['name'][$id]) {
|
||||
foreach ($value['sku']['name'][$id] as $iid => $vname) {
|
||||
$html.= str_replace(
|
||||
['{id}', '{name}', '{iid}'],
|
||||
[$id, $vname, $iid],
|
||||
$tpl_value
|
||||
);
|
||||
}
|
||||
}
|
||||
$result.= str_replace(
|
||||
['{id}', '{name}', '{value}'],
|
||||
[$id, $name, $html],
|
||||
$tpl_group
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$ovalue = [];
|
||||
if (isset($value['sku']['value']) && $value['sku']['value']) {
|
||||
foreach ($value['sku']['value'] as $ii => $t) {
|
||||
foreach ($sku_field_id as $if) {
|
||||
$ovalue[$ii.'_'.$if] = $t[$if];
|
||||
if ($if == 'image' && $t[$if]) {
|
||||
$ovalue[$ii.'_'.$if.'_url'] = dr_get_file($t[$if]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$str = '';
|
||||
|
||||
// 是否单一模式
|
||||
if (isset($field['setting']['option']['close_one']) && $field['setting']['option']['close_one']) {
|
||||
$is_field_pay = 1;
|
||||
$sku_html = '<p class="margin-bottom-20">
|
||||
<label><button type="button" class="btn blue btn-sm" onclick="dr_sku_add_group()"> <i class="fa fa-plus"></i> '.dr_lang('添加属性').'</button></label>
|
||||
<label><button type="button" class="btn green btn-sm" onclick="dr_sku_init()"> <i class="fa fa-refresh"></i> '.dr_lang('更新属性').'</button></label>
|
||||
</p>
|
||||
<div class="portlet light isbordered">
|
||||
<div id="dr_sku_result">
|
||||
'.$result.'
|
||||
</div>
|
||||
</div>';
|
||||
} else {
|
||||
$is_field_pay = $result && $ovalue ? 1 : 0;
|
||||
$str.= '<div class="mt-radio-inline">
|
||||
<label class="mt-radio">
|
||||
<input type="radio" onclick="$(\'#dr_field_pay\').show();$(\'#dr_field_pays\').hide();" name="is_field_pay" value="0" '.(!$is_field_pay ? 'checked' : '').'> '.dr_lang('单一价格').'
|
||||
<span></span>
|
||||
</label>
|
||||
<label class="mt-radio">
|
||||
<input type="radio" onclick="$(\'#dr_field_pays\').show();$(\'#dr_field_pay\').hide();" name="is_field_pay" value="1" '.($is_field_pay ? 'checked' : '').'> '.dr_lang('组合价格').'
|
||||
<span></span>
|
||||
</label>
|
||||
</div>';
|
||||
$sku_html = '<p class="margin-bottom-20">
|
||||
<label><button type="button" class="btn blue btn-sm" onclick="dr_sku_add_group()"> <i class="fa fa-plus"></i> '.dr_lang('添加属性').'</button></label>
|
||||
<label><button type="button" class="btn green btn-sm" onclick="dr_sku_init()"> <i class="fa fa-refresh"></i> '.dr_lang('更新属性').'</button></label>
|
||||
</p>
|
||||
<div class="portlet light isbordered">
|
||||
<div id="dr_sku_result">
|
||||
'.$result.'
|
||||
</div>
|
||||
</div>';
|
||||
}
|
||||
|
||||
|
||||
$str.= '
|
||||
|
||||
<div id="dr_field_pay" style="display:'.(!$is_field_pay ? 'block' : 'none').';">
|
||||
<div class="portlet light isbordered">
|
||||
<div class="form-body" style="padding:30px 0 10px 0">
|
||||
'.$pay_html.'
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="dr_field_pays" style="display:'.($is_field_pay ? 'block' : 'none').';">
|
||||
'.$sku_html.'
|
||||
<div id="dr_sku_table">
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
var arrayValue = new Array();
|
||||
var tpl_group = "'.$this->_js_var($tpl_group).'";
|
||||
var tpl_value = "'.$this->_js_var($tpl_value).'";
|
||||
var field_name = "'.$field['fieldname'].'_sku";
|
||||
var sku_field_name = "'.$this->_js_var($sku_field_name).'";
|
||||
var sku_image_url = "'.$image_url.'";
|
||||
var sku_field_id = '.dr_array2string($sku_field_id).';
|
||||
arrayValue = '.($ovalue ? dr_array2string($ovalue) : 'new Array()').';
|
||||
</script>
|
||||
<script type="text/javascript" src="'.ROOT_THEME_PATH.'assets/js/sku.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(function(){
|
||||
dr_sku_init();
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
';
|
||||
return $this->input_format($field['fieldname'], $text, $str.$tips);
|
||||
} else {
|
||||
|
||||
// 付款金额
|
||||
$html['pay_value'] = $value ? $value : 0;
|
||||
if (!dr_is_app('pay')) {
|
||||
return '没有安装「支付系统」插件';
|
||||
}
|
||||
// 付款方式
|
||||
$html['pay_type'] = \Phpcmf\Service::M('pay', 'pay')->get_pay_type(\Phpcmf\Service::C()->member && $field['setting']['option']['is_finecms'] && is_file(ROOTPATH.'api/pay/finecms/config.php'));
|
||||
|
||||
// 取默认第一个
|
||||
if ($html['pay_type']) {
|
||||
reset($html['pay_type']);
|
||||
$html['pay_default'] = key($html['pay_type']);
|
||||
}
|
||||
|
||||
|
||||
// 付款界面模板
|
||||
if (isset($html['tpl']) && $html['tpl'] && is_file($html['tpl'])) {
|
||||
$htmlfile = $html['tpl'];
|
||||
// 验证路径合法性
|
||||
if (!\Phpcmf\Service::V()->_safe_template_path($htmlfile)) {
|
||||
return '支付表单模板文件路径不合法:'.$htmlfile.'<br>'.(\Phpcmf\Service::V()->_safe_template_error);
|
||||
}
|
||||
} else {
|
||||
$htmlfile = CONFIGPATH.'pay/buy.html';
|
||||
if ($field['setting']['option']['payfile']) {
|
||||
if (is_file(WEBPATH.'config/pay/'.$field['setting']['option']['payfile'])) {
|
||||
$htmlfile = WEBPATH.'config/pay/'.$field['setting']['option']['payfile'];
|
||||
} elseif (is_file(CONFIGPATH.'pay/'.$field['setting']['option']['payfile'])) {
|
||||
$htmlfile = CONFIGPATH.'pay/'.$field['setting']['option']['payfile'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_file($htmlfile)) {
|
||||
return '支付表单模板文件不存在:'.$htmlfile;
|
||||
}
|
||||
|
||||
$member = \Phpcmf\Service::C()->member;
|
||||
$pay_url = \Phpcmf\Service::L('router')->member_url('pay/pay/index');
|
||||
|
||||
// 获取付款界面代码
|
||||
ob_start();
|
||||
$file = \Phpcmf\Service::V()->code2php(file_get_contents($htmlfile));
|
||||
require_once $file;
|
||||
$code = ob_get_clean();
|
||||
|
||||
return $code;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单显示
|
||||
*
|
||||
* @param string $field 字段数组
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function show($field, $value = null) {
|
||||
|
||||
// 字段显示名称
|
||||
$text = ($field['setting']['validate']['required'] ? '<span class="required" aria-required="true"> * </span>' : '').$field['name'];
|
||||
|
||||
$tpl_group = '
|
||||
<div class="portlet-body fc-sku-group" id="dr_sku_group_{id}" did="{id}">
|
||||
<input type="hidden" id="dr_sku_group_text_{id}" name="data['.$field['fieldname'].'_sku][group][{id}]" value="{name}">
|
||||
<div class="row fc-sku-group-name">
|
||||
<div class="col-md-6 fc-sku-group-name-input">{name}</div>
|
||||
</div>
|
||||
<div class="row fc-sku-group-body" id="dr_sku_value_{id}">
|
||||
{value}
|
||||
</div>
|
||||
</div>
|
||||
';
|
||||
|
||||
$tpl_value = '
|
||||
<div class="fc-sku-group-value col-md-4" id="dr_sku_value_{id}_{iid}" did="{iid}">
|
||||
<div class="input-group input-group-sm">
|
||||
<input type="text" class="fc-sku-value-name-input form-control" onblur="dr_sku_init()" name="data['.$field['fieldname'].'_sku][name][{id}][{iid}]" fname="{id}_{iid}" value="{name}">
|
||||
<span class="input-group-btn">
|
||||
<button class="btn red" onclick="javascript:dr_sku_del_value(\'{id}\', \'{iid}\');" type="button"><i class="fa fa-trash"></i></button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
';
|
||||
|
||||
// 显示字段
|
||||
$pay_html = '';
|
||||
$myfield = $this->_get_myfield($field);
|
||||
$sku_field_name = '';
|
||||
$sku_field_id = [];
|
||||
foreach ($myfield as $ff => $name) {
|
||||
$pay_html.= '<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.$name.'</label>
|
||||
<div class="col-md-7">
|
||||
<div class="form-control-static">'.$value[$ff].'</div>
|
||||
</div>
|
||||
</div>';
|
||||
$sku_field_name.= '<th>'.$name.'</th>';
|
||||
$sku_field_id[] = $ff;
|
||||
}
|
||||
|
||||
$result = '';
|
||||
if (isset($value['sku']['group']) && $value['sku']['group']) {
|
||||
foreach ($value['sku']['group'] as $id => $name) {
|
||||
$html = '';
|
||||
if (isset($value['sku']['name'][$id]) && $value['sku']['name'][$id]) {
|
||||
foreach ($value['sku']['name'][$id] as $iid => $vname) {
|
||||
$html.= str_replace(
|
||||
['{id}', '{name}', '{iid}'],
|
||||
[$id, $vname, $iid],
|
||||
$tpl_value
|
||||
);
|
||||
}
|
||||
}
|
||||
$result.= str_replace(
|
||||
['{id}', '{name}', '{value}'],
|
||||
[$id, $name, $html],
|
||||
$tpl_group
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$ovalue = $oimg = [];
|
||||
if (isset($value['sku']['value']) && $value['sku']['value']) {
|
||||
foreach ($value['sku']['value'] as $ii => $t) {
|
||||
foreach ($sku_field_id as $if) {
|
||||
$ovalue[$ii.'_'.$if] = $t[$if];
|
||||
if ($if == 'image') {
|
||||
$ovalue[$ii.'_'.$if.'_url'] = dr_get_file($t[$if]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 是否单一模式
|
||||
$is_field_pay = $result && $ovalue ? 1 : 0;
|
||||
|
||||
$str = '
|
||||
|
||||
<div id="dr_field_pay" style="display:'.(!$is_field_pay ? 'block' : 'none').';">
|
||||
<div class="portlet light isbordered">
|
||||
|
||||
<div class="form-body" style="padding:30px 0 10px 0">
|
||||
|
||||
'.$pay_html.'
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="dr_field_pays" style="display:'.($is_field_pay ? 'block' : 'none').';">
|
||||
|
||||
<div class="hide">
|
||||
|
||||
<div id="dr_sku_result">
|
||||
'.$result.'
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div id="dr_sku_table">
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
var arrayValue = new Array();
|
||||
var tpl_group = "'.$this->_js_var($tpl_group).'";
|
||||
var tpl_value = "'.$this->_js_var($tpl_value).'";
|
||||
var field_name = "'.$field['fieldname'].'_sku";
|
||||
var sku_field_name = "'.$this->_js_var($sku_field_name).'";
|
||||
var sku_field_id = '.dr_array2string($sku_field_id).';
|
||||
arrayValue = '.dr_array2string($ovalue).';
|
||||
</script>
|
||||
<script type="text/javascript" src="'.ROOT_THEME_PATH.'assets/js/sku.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(function(){
|
||||
dr_sku_init();
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
';
|
||||
return $this->input_format($field['fieldname'], $text, $str);
|
||||
}
|
||||
|
||||
// 格式化js变量
|
||||
protected function _js_var($html) {
|
||||
return str_replace([PHP_EOL, chr(13)], "", addslashes($html));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php namespace Phpcmf\Field;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
class PaysText extends \Phpcmf\Library\A_Field {
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
public function __construct(...$params) {
|
||||
parent::__construct(...$params);
|
||||
$this->fieldtype = TRUE;
|
||||
$this->defaulttype = 'VARCHAR';
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段相关属性参数
|
||||
*
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function option($option) {
|
||||
return ['<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('字段作用').' </label>
|
||||
<div class="col-md-9"><label class="form-control-static" style="color: red">'.dr_lang('本类型字段需要在Pays类型的字段中启用后才能生效').'</label></div>
|
||||
</div>'.$this->field_type($option['fieldtype'], $option['fieldlength']).'
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('默认填充值').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input id="field_default_value" type="text" class="form-control" size="20" value="'.$option['value'].'" name="data[setting][option][value]"></label>
|
||||
<label>'.$this->member_field_select().'</label>
|
||||
<span class="help-block">'.dr_lang('用于字段为空时显示该填充值,并不会去主动变更数据库中的实际值;可以设置会员表字段,表示用当前登录会员信息来填充这个值').'</span>
|
||||
</div>
|
||||
</div>', '<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('控件宽度').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" size="10" name="data[setting][option][width]" value="'.$option['width'].'"></label>
|
||||
<span class="help-block">'.dr_lang('[整数]表示固定宽度;[整数%]表示百分比').'</span>
|
||||
</div>
|
||||
</div>'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段入库值
|
||||
*
|
||||
* @param array $field 字段信息
|
||||
* @return void
|
||||
*/
|
||||
public function insert_value($field) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单输入
|
||||
*
|
||||
* @param string $field 字段数组
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function input($field, $value = null) {
|
||||
return '';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,313 @@
|
||||
<?php namespace Phpcmf\Field;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
class Property extends \Phpcmf\Library\A_Field {
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
public function __construct(...$params) {
|
||||
parent::__construct(...$params);
|
||||
$this->close_xss = 1; // 关闭xss验证
|
||||
$this->fieldtype = ['TEXT' => ''];
|
||||
$this->defaulttype = 'TEXT';
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段相关属性参数
|
||||
*
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function option($option) {
|
||||
|
||||
unset($option['width']);
|
||||
if (!isset($option['name_value']) || !$option['name_value']) {
|
||||
$option['name_value'] = dr_lang('名称');
|
||||
}
|
||||
if (!isset($option['value_value']) || !$option['value_value']) {
|
||||
$option['value_value'] = dr_lang('值');
|
||||
}
|
||||
$str = '
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('选项名称').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" size="20" value="'.$option['name_value'].'" name="data[setting][option][name_value]"></label>
|
||||
<label><input type="text" class="form-control" size="20" value="'.$option['value_value'].'" name="data[setting][option][value_value]"></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group dr_option" id="dr_option_0">
|
||||
<label class="col-md-2 control-label">'.dr_lang('字段说明').'</label>
|
||||
<div class="col-md-9"><div class="form-control-static">'.dr_lang('选择框与复选框类型的选项值以,分隔').'</div><br>
|
||||
<a href="javascript:;" class="btn btn-sm red" onclick="dr_add_option()"><i class="fa fa-plus"></i> '.dr_lang('增加属性选项').'</a>
|
||||
</div>
|
||||
</div>';
|
||||
unset($option['name_value']);
|
||||
unset($option['value_value']);
|
||||
$i = 0;
|
||||
if ($option['default_value']) {
|
||||
foreach ($option['default_value'] as $i => $t) {
|
||||
$str.= '<div class="form-group dr_option" id="dr_option_'.$i.'" >';
|
||||
$str.= '<label class="col-md-2 control-label">'.dr_lang('属性名称').'</label>';
|
||||
$str.= '<div class="col-md-9"><label><input type="text" name="data[setting][option][default_value]['.$i.'][name]" value="'.$t['name'].'" class="form-control" /></label>';
|
||||
$str.= '<label> '.dr_lang('类型').':</label><label><select class="form-control" name="data[setting][option][default_value]['.$i.'][type]">';
|
||||
$str.= '<option value="1" '.($t['type'] == 1 ? "selected" : "").'> - '.dr_lang('文本框').' - </option>';
|
||||
$str.= '<option value="2" '.($t['type'] == 2 ? "selected" : "").'> - '.dr_lang('选择框').' - </option>';
|
||||
$str.= '<option value="3" '.($t['type'] == 3 ? "selected" : "").'> - '.dr_lang('复选框').' - </option>';
|
||||
$str.= '</select></label>';
|
||||
$str.= '<label> '.dr_lang('默认值/选项值').':</label><label><input type="text" name="data[setting][option][default_value]['.$i.'][value]" value="'.$t['value'].'" class="form-control input-xlarge"></label> <label><a onclick="$(\'#dr_option_'.$i.'\').remove()" href="javascript:;">'.dr_lang('删除').'</a></label>';
|
||||
$str.= '</div></div>';
|
||||
}
|
||||
}
|
||||
|
||||
$str.= '
|
||||
<script type="text/javascript">
|
||||
var id='.$i.';
|
||||
function dr_add_option() {
|
||||
id ++;
|
||||
if ($("#dr_option_"+id).length>0) {
|
||||
dr_tips(0, \''.dr_lang("序列生成重复,请重新添加").'\');
|
||||
return;
|
||||
}
|
||||
var html = "";
|
||||
html+= "<div class=\"form-group dr_option\" id=\"dr_option_"+id+"\" >";
|
||||
html+= "<label class=\"col-md-2 control-label\">'.dr_lang('属性名称').' "+id+"</label>";
|
||||
html+= "<div class=\"col-md-9\">";
|
||||
html+= "<label><input type=\"text\" name=\"data[setting][option][default_value]["+id+"][name]\" value=\"\" class=\"form-control\" /></label>";
|
||||
html+= "<label> '.dr_lang('类型').':</label><label><select class=\"form-control\" name=\"data[setting][option][default_value]["+id+"][type]\">";
|
||||
html+= "<option value=\"1\"> - '.dr_lang('文本框').' - </option>";
|
||||
html+= "<option value=\"2\"> - '.dr_lang('选择框').' - </option>";
|
||||
html+= "<option value=\"3\"> - '.dr_lang('复选框').' - </option>";
|
||||
html+= "</select></label>";
|
||||
html+= "<label> '.dr_lang('默认值/选项值').':</label><label><input type=\"text\" name=\"data[setting][option][default_value]["+id+"][value]\" class=\"form-control input-xlarge\"></label> <label><a onclick=\"$(\'#dr_option_"+id+"\').remove()\" href=\"javascript:;\">'.dr_lang('删除').'</a></label>";
|
||||
html+= "</div>";
|
||||
html+= "</div>";
|
||||
$("#dr_option_rows").append(html);
|
||||
}
|
||||
</script>
|
||||
<div id="dr_option_rows"></div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('行数模式').'</label>
|
||||
<div class="col-md-9">
|
||||
<div class="mt-radio-inline">
|
||||
<label class="mt-radio mt-radio-outline"><input type="radio" name="data[setting][option][is_hang]" value="1" '.($option['is_hang'] ? 'checked' : '').'> '.dr_lang('固定').' <span></span></label>
|
||||
<label class="mt-radio mt-radio-outline"><input type="radio" name="data[setting][option][is_hang]" value="0" '.(!$option['is_hang'] ? 'checked' : '').'> '.dr_lang('无限').' <span></span></label>
|
||||
</div>
|
||||
<span class="help-block">'.dr_lang('无限行数可以在录入数据时自由添加行数,固定行数就只能是录入上述的固定属性行数').'</span>
|
||||
</div>
|
||||
</div>
|
||||
';
|
||||
return ['
|
||||
'.$str];
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段输出
|
||||
*/
|
||||
public function output($value) {
|
||||
return dr_string2array($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段入库值
|
||||
*/
|
||||
public function insert_value($field) {
|
||||
|
||||
$data = [];
|
||||
$value = \Phpcmf\Service::L('Field')->post[$field['fieldname']];
|
||||
if ($value) {
|
||||
$i = 1;
|
||||
foreach ($value as $t) {
|
||||
$data[$i] = $t;
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname']] = dr_array2string($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单输入
|
||||
*
|
||||
* @param string $cname 字段别名
|
||||
* @param string $name 字段名称
|
||||
* @param array $cfg 字段配置
|
||||
* @param string $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function input($field, $value = '') {
|
||||
// 字段禁止修改时就返回显示字符串
|
||||
if ($this->_not_edit($field, $value)) {
|
||||
return $this->show($field, $value);
|
||||
}
|
||||
// 字段存储名称
|
||||
$name = $field['fieldname'];
|
||||
// 字段显示名称
|
||||
$text = ($field['setting']['validate']['required'] ? '<span class="required" aria-required="true"> * </span>' : '').dr_lang($field['name']);
|
||||
// 字段默认值
|
||||
$value = $value ? dr_string2array($value) : array();
|
||||
$str = '';
|
||||
$str.= ' <div class="scroller_'.$name.'_files">
|
||||
<div class="scroller" data-inited="0" data-initialized="1" data-always-visible="1" data-rail-visible="1">
|
||||
|
||||
<table class="table fc-sku-table table-striped table-bordered table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="200" style="border-left-width: 1px!important;">'.dr_lang($field['setting']['option']['name_value'] ? $field['setting']['option']['name_value'] : dr_lang('名称')).' </th>
|
||||
<th>'.dr_lang($field['setting']['option']['value_value'] ? $field['setting']['option']['value_value'] : dr_lang('值')).' </th>';
|
||||
if (!$field['setting']['option']['is_hang']) {
|
||||
$str.='
|
||||
<th width="70" style="text-align: center"> ';
|
||||
|
||||
$str.= ' <a href="javascript:;" class="btn blue btn-xs" onClick="dr_add_property_'.$name.'()"> <i class="fa fa-plus"></i></a>';
|
||||
$str.='</th>';
|
||||
}
|
||||
$str.= '
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="property_'.$name.'-sort-items" class="scroller_body">';
|
||||
$i = 0;
|
||||
|
||||
unset($field['setting']['width']);
|
||||
// 固定属性选项
|
||||
if (isset($field['setting']['option']['default_value']) && $field['setting']['option']['default_value']) {
|
||||
$i = 1;
|
||||
foreach ($field['setting']['option']['default_value'] as $t) {
|
||||
if (!isset($t['name']) && $t['name']) {
|
||||
continue;
|
||||
}
|
||||
$str.= '<tr id="dr_items_'.$name.'_'.$i.'" class="dr_items_readonly">';
|
||||
$str.= '<td class="highlight"><input type="text" readonly class="form-control input-sm" value="'.$t['name'].'" name="data['.$name.']['.$i.'][name]"></td>';
|
||||
$str.= '<td>';
|
||||
switch ($t['type']) {
|
||||
case 1:
|
||||
$v = $value[$i]['value'] ? $value[$i]['value'] : $t['value'];
|
||||
$str.= '<input type="text" class="form-control input-sm" value="'.htmlspecialchars((string)$v).'" name="data['.$name.']['.$i.'][value]" />';
|
||||
break;
|
||||
case 2:
|
||||
$v = explode(',', $t['value']);
|
||||
$str.= '<select class="form-control" name="data['.$name.']['.$i.'][value]">';
|
||||
$str.= '<option value=""> -- </option>';
|
||||
if ($v) {
|
||||
foreach ($v as $c) {
|
||||
$selected = isset($value[$i]['value']) && $value[$i]['value'] == $c ? 'selected' : '';
|
||||
$str.= '<option value="'.$c.'" '.$selected.'> '.$c.' </option>';
|
||||
}
|
||||
}
|
||||
$str.= '</select>';
|
||||
break;
|
||||
case 3:
|
||||
$v = explode(',', $t['value']);
|
||||
if ($v) {
|
||||
foreach ($v as $c) {
|
||||
$selected = isset($value[$i]['value']) && dr_in_array($c, $value[$i]['value']) ? 'checked' : '';
|
||||
$str.= '<input type="checkbox" name="data['.$name.']['.$i.'][value][]" value="'.$c.'" ' . $selected . ' />'.$c.'';
|
||||
}
|
||||
}
|
||||
}
|
||||
$str.= '</td>';
|
||||
if (!$field['setting']['option']['is_hang']) {
|
||||
$str.= '<td>';
|
||||
$str.= '</td>';
|
||||
}
|
||||
$str.= '</tr>';
|
||||
unset($value[$i]);
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
// 剩下自定义属性
|
||||
if ($value && !$field['setting']['option']['is_hang']) {
|
||||
foreach ($value as $t) {
|
||||
$str.= '<tr id="dr_items_'.$name.'_'.$i.'" class="dr_items_sort">';
|
||||
$str.= '<td><input type="text" class="form-control input-sm" value="'.htmlspecialchars((string)$t['name']).'" name="data['.$name.']['.$i.'][name]"></td>';
|
||||
$str.= '<td>';
|
||||
$str.= '<input type="text" class="form-control input-sm" value="'.htmlspecialchars((string)$t['value']).'" name="data['.$name.']['.$i.'][value]" />';
|
||||
$str.= '</td>';
|
||||
$str.= '<td style="text-align: center"><a class="btn btn-xs red" href="javascript:;" onclick="$(\'#dr_items_'.$name.'_'.$i.'\').remove()"> <i class="fa fa-trash"></i> </a>';
|
||||
$str.= '</td>';
|
||||
$str.= '</tr>';
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
|
||||
$str.= '
|
||||
</tbody>
|
||||
</table></div></div>';
|
||||
if (!$field['setting']['option']['is_hang']) {
|
||||
$js = \Phpcmf\Service::L('js_packer');
|
||||
$str.= $js->pack('<script type="text/javascript">
|
||||
$("#property_'.$name.'-sort-items").sortable({
|
||||
items: ".dr_items_sort"
|
||||
});
|
||||
dr_slimScroll_init(".scroller_'.$name.'_files", 300);
|
||||
var id='.($i).';
|
||||
function dr_add_property_'.$name.'() {
|
||||
if ($("#dr_items_'.$name.'_"+id).length>0) {
|
||||
id++;
|
||||
dr_tips(0, \''.dr_lang("序列生成重复,请重新添加").'\');
|
||||
return;
|
||||
}
|
||||
var html = "<tr id=\"dr_items_'.$name.'_"+id+"\">";
|
||||
html+= "<td><input type=\"text\" class=\"form-control input-sm\" value=\"\" name=\"data['.$name.']["+id+"][name]\"></td>";
|
||||
html+= "<td><input type=\"text\" class=\"form-control input-sm\" value=\"\" name=\"data['.$name.']["+id+"][value]\"></td>";
|
||||
html+= "<td style=\"text-align: center\"><a class=\"btn btn-xs red\" href=\"javascript:;\" onclick=\"$(\'#dr_items_'.$name.'_"+id+"\').remove()\"> <i class=\"fa fa-trash\"></i> </a></td></tr>";
|
||||
$("#property_'.$name.'-sort-items").append(html);
|
||||
dr_slimScroll_init(".scroller_'.$name.'_files", 300);
|
||||
id++;
|
||||
}
|
||||
</script>', 0);
|
||||
}
|
||||
|
||||
$str.= '<span class="help-block">'.$field['setting']['validate']['tips'].'</span>';
|
||||
return $this->input_format($field['fieldname'], $text, $str);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 字段表单显示
|
||||
*
|
||||
* @param string $field 字段数组
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function show($field, $value = null) {
|
||||
|
||||
$str = '
|
||||
<table class="table table-striped table-bordered table-advance ">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="200" style="border-left-width: 1px!important;">'.dr_lang($field['setting']['option']['name_value'] ? $field['setting']['option']['name_value'] : dr_lang('名称')).' </th>
|
||||
<th>'.dr_lang($field['setting']['option']['value_value'] ? $field['setting']['option']['value_value'] : dr_lang('值')).' </th>
|
||||
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>';
|
||||
$i = 0;
|
||||
|
||||
unset($field['setting']['width']);
|
||||
// 默认属性选项
|
||||
if ($value) {
|
||||
$value = dr_string2array($value);
|
||||
foreach ($value as $t) {
|
||||
|
||||
$str.= '<tr>';
|
||||
$str.= '<td class="highlight">'.$t['name'].'</td>';
|
||||
$str.= '<td>'.$t['value'].'</td>';
|
||||
$str.= '</tr>';
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$str.= '
|
||||
</tbody>
|
||||
</table>';
|
||||
|
||||
return $this->input_format($field['fieldname'], $field['name'], $str);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,244 @@
|
||||
<?php namespace Phpcmf\Field;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
class Radio extends \Phpcmf\Library\A_Field {
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
public function __construct(...$params) {
|
||||
parent::__construct(...$params);
|
||||
$this->fieldtype = TRUE; // TRUE表全部可用字段类型,自定义格式为 array('可用字段类型名称' => '默认长度', ... )
|
||||
$this->defaulttype = 'VARCHAR'; // 当用户没有选择字段类型时的缺省值
|
||||
}
|
||||
|
||||
// 调出字段遍历出来
|
||||
protected function _get_select_field($option, $field, $id, $at) {
|
||||
|
||||
$str = '<div class="mt-checkbox-list">';
|
||||
foreach ($field as $t) {
|
||||
if ($t['disabled']) {
|
||||
continue;
|
||||
} elseif ($t['fieldtype'] == 'Merge') {
|
||||
continue;
|
||||
} elseif ($t['fieldtype'] == 'Group') {
|
||||
continue;
|
||||
}
|
||||
$str.= '<label class="mt-checkbox mt-checkbox-outline">';
|
||||
$str.= '<input type="checkbox" '.(dr_in_array($t['fieldname'], $option['field_ld'][$id][$at]) ? 'checked' : '').' name="data[setting][option][field_ld]['.$id.']['.$at.'][]" value="'.$t['fieldname'].'"> '
|
||||
.($t['setting']['validate']['required'] ? '<b class="required" aria-required="true"> * </b>' : '').$t['name'].' ';
|
||||
$str.= '<span></span>';
|
||||
$str.= '</label>';
|
||||
}
|
||||
$str.= '</div>';
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段相关属性参数
|
||||
*
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function option($option, $field = NULL) {
|
||||
|
||||
$data = dr_format_option_array($option['options']);
|
||||
if (!$data) {
|
||||
$ld = dr_lang('需要保存字段配置后才能配置联动关系');
|
||||
} else {
|
||||
$ld = '<div class="table-scrollable">';
|
||||
$ld.= '<table class="table table-striped table-bordered table-advance ">';
|
||||
$ld.= '<thead>';
|
||||
$ld.= '<tr>';
|
||||
$ld.= '<th width="120">'.dr_lang('选项').'</th>';
|
||||
$ld.= '<th>'.dr_lang('隐藏字段').'</th>';
|
||||
$ld.= '</tr>';
|
||||
$ld.= '</thead>';
|
||||
$ld.= '<tbody>';
|
||||
$data['dr_null'] = dr_lang('未选择时');
|
||||
foreach ($data as $id => $name) {
|
||||
$ld.= '<tr>';
|
||||
$ld.= '<td>'.$name.'</td>';
|
||||
$ld.= '<td>'.$this->_get_select_field($option, $field, $id, 'hide').'</td>';
|
||||
$ld.= '</tr>';
|
||||
}
|
||||
$ld.= '</tbody>';
|
||||
$ld.= '</table>';
|
||||
$ld.= '</div>';
|
||||
}
|
||||
|
||||
$option['options'] = isset($option['options']) ? $option['options'] : 'name1|1'.PHP_EOL.'name2|2';
|
||||
|
||||
|
||||
|
||||
return [
|
||||
'
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('选项列表').'</label>
|
||||
<div class="col-md-9">
|
||||
<textarea class="form-control" name="data[setting][option][options]" style="height:150px;width:400px;">'.$option['options'].'</textarea>
|
||||
<span class="help-block">'.dr_lang('格式:选项名称|选项值[回车换行]选项名称2|值2....').'</span>
|
||||
<span class="help-block">'.dr_lang('选项值建议使用从1开始的数字,不得带符号,也可以省略不写').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('多语言翻译').'</label>
|
||||
<div class="col-md-9">
|
||||
<div class="mt-radio-inline">
|
||||
<label class="mt-radio mt-radio-outline"><input type="radio" value="0" name="data[setting][option][lang]" '.(!$option['lang'] ? 'checked' : '').' > '.dr_lang('开启').' <span></span></label>
|
||||
|
||||
<label class="mt-radio mt-radio-outline"><input type="radio" value="1" name="data[setting][option][lang]" '.($option['lang'] ? 'checked' : '').' > '.dr_lang('关闭').' <span></span></label>
|
||||
</div>
|
||||
<span class="help-block">'.dr_lang('开启后选项值被系统语言包翻译,否则就保持原样显示').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('条件联动关联').'</label>
|
||||
<div class="col-md-9">
|
||||
<div class="mt-radio-inline">
|
||||
<label class="mt-radio mt-radio-outline">
|
||||
<input type="radio" name="data[setting][option][is_field_ld]" onclick="$(\'#ldtjxx\').hide()" value="0" '.(!$option['is_field_ld'] ? 'checked' : '').'> '.dr_lang('关闭').'
|
||||
<span></span>
|
||||
</label>
|
||||
<label class="mt-radio mt-radio-outline">
|
||||
<input type="radio" name="data[setting][option][is_field_ld]" onclick="$(\'#ldtjxx\').show()" value="1" '.($option['is_field_ld'] ? 'checked' : '').'> '.dr_lang('启用').'
|
||||
<span></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" id="ldtjxx" style="'.(!$option['is_field_ld'] ? 'display: none' : '').'">
|
||||
<label class="col-md-2 control-label">'.dr_lang('设置条件').'</label>
|
||||
<div class="col-md-9">
|
||||
'.$ld.'
|
||||
<span class="help-block">'.dr_lang('当选择某一个选项时会联动显示或隐藏指定的字段').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('默认选中项').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input id="field_default_value" type="text" class="form-control" size="20" value="'.$option['value'].'" name="data[setting][option][value]"></label>
|
||||
<label>'.$this->member_field_select().'</label>
|
||||
<span class="help-block">'.dr_lang('用于字段为空时显示该填充值,并不会去主动变更数据库中的实际值;可以设置会员表字段,表示用当前登录会员信息来填充这个值').'</span>
|
||||
</div>
|
||||
</div>'.$this->field_type($option['fieldtype'], $option['fieldlength']).'
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('显示格式').'</label>
|
||||
<div class="col-md-9">
|
||||
<div class="mt-radio-inline">
|
||||
<label class="mt-radio mt-radio-outline">
|
||||
<input type="radio" name="data[setting][option][show_type]" value="0" '.(!$option['show_type'] ? 'checked' : '').'> '.dr_lang('横排显示').'
|
||||
<span></span>
|
||||
</label>
|
||||
<label class="mt-radio mt-radio-outline">
|
||||
<input type="radio" name="data[setting][option][show_type]" value="1" '.($option['show_type'] ? 'checked' : '').'> '.dr_lang('竖排显示').'
|
||||
<span></span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单输入
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function input($field, $value = '') {
|
||||
|
||||
// 字段禁止修改时就返回显示字符串
|
||||
if ($this->_not_edit($field, $value)) {
|
||||
return $this->show($field, $value);
|
||||
}
|
||||
|
||||
// 字段存储名称
|
||||
$name = $field['fieldname'];
|
||||
|
||||
// 字段显示名称
|
||||
$text = ($field['setting']['validate']['required'] ? '<span class="required" aria-required="true"> * </span>' : '').dr_lang($field['name']);
|
||||
|
||||
// 字段提示信息
|
||||
$tips = ($name == 'title' && APP_DIR) || $field['setting']['validate']['tips'] ? '<span class="help-block" id="dr_'.$field['fieldname'].'_tips">'.$field['setting']['validate']['tips'].'</span>' : '';
|
||||
|
||||
// 字段默认值
|
||||
$value = dr_strlen($value) ? $value : $this->get_default_value($field['setting']['option']['value']);
|
||||
|
||||
$str = '';
|
||||
|
||||
// 显示方式
|
||||
$show_type = (int)$field['setting']['option']['show_type'];
|
||||
|
||||
if ($field['setting']['option']['is_field_ld'] && $field['setting']['option']['field_ld']) {
|
||||
$str.= '<script>function field_ld_'.$name.'(v) {';
|
||||
$show = [];
|
||||
foreach ($field['setting']['option']['field_ld'] as $ii => $t) {
|
||||
if ($t['hide']) {
|
||||
foreach ($t['hide'] as $f) {
|
||||
if (in_array($f, $show)) {
|
||||
continue;
|
||||
}
|
||||
$show[] = $f;
|
||||
$str.= PHP_EOL.'$("#dr_row_'.$f.'").show();';
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($field['setting']['option']['field_ld'] as $ii => $t) {
|
||||
$str.= PHP_EOL.'if (v == "'.($ii == 'dr_null' ? '' : $ii).'") {';
|
||||
/*
|
||||
if ($t['show']) {
|
||||
foreach ($t['show'] as $f) {
|
||||
$str.= PHP_EOL.'$("#dr_row_'.$f.'").show();';
|
||||
}
|
||||
}*/
|
||||
if ($t['hide']) {
|
||||
foreach ($t['hide'] as $f) {
|
||||
$str.= PHP_EOL.'$("#dr_row_'.$f.'").hide();';
|
||||
}
|
||||
}
|
||||
$str.= PHP_EOL.'}';
|
||||
}
|
||||
$str.= '}';
|
||||
$str.= '$(function(){
|
||||
field_ld_'.$name.'("'.$value.'");
|
||||
});';
|
||||
$str.= '</script>';
|
||||
$field['setting']['validate']['formattr'].= ' onclick="field_ld_'.$name.'(this.value)"';
|
||||
}
|
||||
|
||||
// 表单选项
|
||||
$options = dr_format_option_array($field['setting']['option']['options']);
|
||||
if ($options) {
|
||||
foreach ($options as $v => $n) {
|
||||
$s = $v == $value ? ' checked' : '';
|
||||
$kj = '<input type="radio" name="data['.$name.']" value="'.$v.'" '.$s.' '.$field['setting']['validate']['formattr'].' />';
|
||||
$str.= '<label class="mt-radio mt-radio-outline">'.$kj.' '.(isset($field['setting']['option']['lang']) && $field['setting']['option']['lang'] ? $n : dr_lang($n)).' <span></span> </label>';
|
||||
}
|
||||
}
|
||||
|
||||
return $this->input_format($name, $text, '<div class="'.(!$show_type ? 'mt-radio-inline' : 'mt-radio-list').'">'.$str.'</div>'.$tips);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单显示
|
||||
*
|
||||
* @param string $field 字段数组
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function show($field, $value = null) {
|
||||
|
||||
$options = dr_format_option_array($field['setting']['option']['options']);
|
||||
|
||||
$str = '<div class="form-control-static"> '.(isset($options[$value]) ? dr_lang($options[$value]) : dr_lang('未选择')).' </div>';
|
||||
|
||||
return $this->input_format($field['fieldname'], $field['name'], $str);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
<?php namespace Phpcmf\Field;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本代码基于MIT开源协议,协议规定此处版权信息不可去除
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
class Redirect extends \Phpcmf\Library\A_Field {
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
public function __construct(...$params) {
|
||||
parent::__construct(...$params);
|
||||
$this->fieldtype = TRUE;
|
||||
$this->defaulttype = 'TEXT';
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段相关属性参数
|
||||
*
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function option($option) {
|
||||
$option['width'] = isset($option['width']) ? $option['width'] : 400;
|
||||
return ['<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('适应范围').'</label>
|
||||
<div class="col-md-9">
|
||||
<p class="form-control-static">'.dr_lang('此字段只能用于模块内容自定义字段').'</p>
|
||||
</div>
|
||||
</div>', '
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('控件宽度').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" size="10" name="data[setting][option][width]" value="'.$option['width'].'"></label>
|
||||
<span class="help-block">'.dr_lang('[整数]表示固定宽度;[整数%]表示百分比').'</span>
|
||||
</div>
|
||||
</div>
|
||||
'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段入库值
|
||||
*
|
||||
* @param array $field 字段信息
|
||||
* @return void
|
||||
*/
|
||||
public function insert_value($field) {
|
||||
|
||||
$value = \Phpcmf\Service::L('Field')->post[$field['fieldname']];
|
||||
if ($value && !dr_is_url($value)) {
|
||||
$value = dr_url_prefix($value);
|
||||
}
|
||||
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname']] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单输入
|
||||
*
|
||||
* @param string $field 字段数组
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function input($field, $value = null) {
|
||||
|
||||
// 字段禁止修改时就返回显示字符串
|
||||
if ($this->_not_edit($field, $value)) {
|
||||
return $this->show($field, $value);
|
||||
}
|
||||
|
||||
// 字段存储名称
|
||||
$name = $field['fieldname'];
|
||||
|
||||
// 字段显示名称
|
||||
$text = ($field['setting']['validate']['required'] ? '<span class="required" aria-required="true"> * </span>' : '').dr_lang($field['name']);
|
||||
|
||||
// 表单宽度设置
|
||||
$width = \Phpcmf\Service::IS_MOBILE_USER() ? '100%' : ($field['setting']['option']['width'] ? $field['setting']['option']['width'] : 200);
|
||||
|
||||
// 风格
|
||||
$style = 'style="width:'.$width.(is_numeric($width) ? 'px' : '').';"';
|
||||
|
||||
// 表单附加参数
|
||||
$attr = $field['setting']['validate']['formattr'];
|
||||
|
||||
// 字段提示信息
|
||||
$tips = isset($field['setting']['validate']['tips']) && $field['setting']['validate']['tips'] ? '<span class="help-block" id="dr_'.$name.'_tips">'.$field['setting']['validate']['tips'].'</span>' : '';
|
||||
|
||||
// 字段默认值
|
||||
$value = $value && strlen($value) ? $value : $this->get_default_value($field['setting']['option']['value']);
|
||||
|
||||
// 当字段必填时,加入html5验证标签
|
||||
isset($field['setting']['validate']['required']) && $field['setting']['validate']['required'] == 1 && $attr.= ' required="required"';
|
||||
|
||||
$str = '<input class="form-control" type="text" name="data['.$name.']" id="dr_'.$name.'" value="'.$value.'" '.$style.' '.$attr.' />'.$tips;
|
||||
return $this->input_format($name, $text, $str);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单显示
|
||||
*
|
||||
* @param string $field 字段数组
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function show($field, $value = null) {
|
||||
|
||||
|
||||
return $this->input_format($field['fieldname'], $field['name'], '<div class="form-control-static"><a href="'.$value.'" target="_blank">'.$value.'</a></div>');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,304 @@
|
||||
<?php namespace Phpcmf\Field;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本代码基于MIT开源协议,协议规定此处版权信息不可去除
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
class Related extends \Phpcmf\Library\A_Field {
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
public function __construct(...$params) {
|
||||
parent::__construct(...$params);
|
||||
$this->fieldtype = ['TEXT' => '']; // TRUE表全部可用字段类型,自定义格式为 array('可用字段类型名称' => '默认长度', ... )
|
||||
$this->defaulttype = 'TEXT'; // 当用户没有选择字段类型时的缺省值
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段相关属性参数
|
||||
*
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function option($option) {
|
||||
|
||||
$_option = '';
|
||||
$_module = \Phpcmf\Service::C()->get_cache('module-'.SITE_ID.'-content');
|
||||
if ($_module) {
|
||||
foreach ($_module as $dir => $t) {
|
||||
$_option.= '<option value="'.$dir.'" '.($dir == $option['module'] ? 'selected' : '').'>'.$t['name'].'</option>';
|
||||
}
|
||||
}
|
||||
|
||||
return [$this->_search_field().'<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('内容模块').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><select class="form-control" name="data[setting][option][module]">
|
||||
'.$_option.'
|
||||
</select></label>
|
||||
<span class="help-block">'.dr_lang('必须选择一个模块作为关联数据源').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('显示归属内容').'</label>
|
||||
<div class="col-md-9">
|
||||
<input type="checkbox" name="data[setting][option][my]" '.($option['my'] ? 'checked' : '').' value="1" data-on-text="'.dr_lang('已开启').'" data-off-text="'.dr_lang('已关闭').'" data-on-color="success" data-off-color="danger" class="make-switch" data-size="small">
|
||||
<span class="help-block">'.dr_lang('开启之后只显示当前登录的用户自己所发布的内容').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('主题显示名称').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" size="10" name="data[setting][option][title]" value="'.($option['title'] ? $option['title'] : dr_lang('主题')).'"></label>
|
||||
<span class="help-block">'.dr_lang('用于显示管理的主题字段名称,默认是:主题').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('最大选择数').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" size="10" name="data[setting][option][limit]" value="'.$option['limit'].'"></label>
|
||||
<span class="help-block">'.dr_lang('最大能选择的数量限制').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('每页显示条数').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" size="10" name="data[setting][option][pagesize]" value="'.$option['pagesize'].'"></label>
|
||||
<span class="help-block">'.dr_lang('选择列表分页条数,按多少条数据分页').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('友情提示').'</label>
|
||||
<div class="col-md-9">
|
||||
<div class="form-control-static">'.dr_lang('此字段不能参与搜索条件筛选').'</div>
|
||||
</div>
|
||||
</div>'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段输出
|
||||
*/
|
||||
public function output($value) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段入库值
|
||||
*/
|
||||
public function insert_value($field) {
|
||||
|
||||
$data = \Phpcmf\Service::L('Field')->post[$field['fieldname']];
|
||||
$limit = intval($field['setting']['option']['limit']);
|
||||
if ($limit && $data && count($data) > $limit) {
|
||||
// 超限了
|
||||
$value = implode(',', dr_arraycut($data, $limit));
|
||||
} else {
|
||||
$value = !$data ? '' : implode(',', $data);
|
||||
}
|
||||
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname']] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单输入
|
||||
*
|
||||
* @param string $cname 字段别名
|
||||
* @param string $name 字段名称
|
||||
* @param array $cfg 字段配置
|
||||
* @param string $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function input($field, $value = '') {
|
||||
|
||||
// 字段禁止修改时就返回显示字符串
|
||||
if ($this->_not_edit($field, $value)) {
|
||||
return $this->show($field, $value);
|
||||
}
|
||||
|
||||
if (!IS_USE_MODULE) {
|
||||
return '使用本字段类别需要安装【建站系统】插件';
|
||||
}
|
||||
|
||||
$is_show = 0;
|
||||
|
||||
// 字段存储名称
|
||||
$name = $field['fieldname'];
|
||||
// 字段提示信息
|
||||
$tips = isset($field['setting']['validate']['tips']) && $field['setting']['validate']['tips'] ? '<span class="help-block" id="dr_'.$name.'_tips">'.$field['setting']['validate']['tips'].'</span>' : '';
|
||||
// 区域大小
|
||||
$area = \Phpcmf\Service::IS_MOBILE_USER() ? '["95%", "90%"]' : '["50%", "65%"]';
|
||||
// 模块名称
|
||||
$module = $mid = isset($field['setting']['option']['module']) ? $field['setting']['option']['module'] : '';
|
||||
// 字段显示名称
|
||||
$text = ($field['setting']['validate']['required'] ? '<span class="required" aria-required="true"> * </span>' : '').dr_lang($field['name']);
|
||||
// 选择数量限制
|
||||
$limit = intval($field['setting']['option']['limit']);
|
||||
!$limit && $limit = 99999;
|
||||
// 输出信息
|
||||
$cname = ($field['setting']['option']['title'] ? $field['setting']['option']['title'] : dr_lang('主题'));
|
||||
|
||||
if (!$module) {
|
||||
if (CI_DEBUG) {
|
||||
return $this->input_format($name, $text, '<div class="form-control-static" style="color:red">关联字段没有设置关联模块</div>');
|
||||
}
|
||||
return $this->input_format($name, $text, '');
|
||||
} elseif (!dr_is_module($module)) {
|
||||
if (CI_DEBUG) {
|
||||
return $this->input_format($name, $text, '<div class="form-control-static" style="color:red">关联字段设置的模块【'.$module.'】没有被安装</div>');
|
||||
}
|
||||
return $this->input_format($name, $text, '');
|
||||
}
|
||||
|
||||
$value = $value ? trim($value, ',') : '';
|
||||
$mylist = [];
|
||||
if ($value && is_string($value)) {
|
||||
$arr = explode(',', $value);
|
||||
if ($arr) {
|
||||
$value = '';
|
||||
foreach ($arr as $a) {
|
||||
$a = intval($a);
|
||||
if ($a) {
|
||||
$value.= ','.$a;
|
||||
}
|
||||
}
|
||||
if ($value) {
|
||||
$value = trim($value, ',');
|
||||
$db = \Phpcmf\Service::M()->db->query('select * from '.\Phpcmf\Service::M()->dbprefix(dr_module_table_prefix($module)).' where id IN ('.$value.') order by FIELD(id, '.$value.')');
|
||||
$mylist = $db ? $db->getResultArray() : [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$file = \Phpcmf\Service::V()->code2php(
|
||||
file_get_contents(is_file(MYPATH.'View/api_related_field_'.$field['fieldname'].'.html') ? MYPATH.'View/api_related_field_'.$field['fieldname'].'.html' : COREPATH.'View/api_related_field.html')
|
||||
);
|
||||
ob_start();
|
||||
require $file;
|
||||
$str = ob_get_clean();
|
||||
|
||||
$str.= $tips;
|
||||
$js = \Phpcmf\Service::L('js_packer');
|
||||
$str.= $js->pack('
|
||||
<script type="text/javascript">
|
||||
|
||||
dr_slimScroll_init(".scroller_'.$name.'_files", 300);
|
||||
$("#related_'.$name.'-sort-items").sortable();
|
||||
function dr_add_related_'.$name.'() {
|
||||
var len = $(\'#related_'.$name.'-sort-items tr\').length;
|
||||
if (len >= '.$limit.') {
|
||||
dr_tips(0, "'.dr_lang('关联数量超限').'");
|
||||
return;
|
||||
}
|
||||
var url = "'.dr_web_prefix('index.php?s=module&c=api&m=related&name=').$name.'&site='.SITE_ID.'&module='.$module.'&diy='.$field['fieldname'].'&my='.intval($field['setting']['option']['my']).'&pagesize='.intval($field['setting']['option']['pagesize']).'&is_iframe=1";
|
||||
layer.open({
|
||||
type: 2,
|
||||
title: \'<i class="fa fa-cog"></i> '.dr_lang('关联内容').'\',
|
||||
fix:true,
|
||||
shadeClose: true,
|
||||
shade: 0,
|
||||
area: '.$area.',
|
||||
btn: ["'.dr_lang('关联').'"],
|
||||
success: function (json) {
|
||||
if (json.code == 0) {
|
||||
layer.close();
|
||||
dr_tips(json.code, json.msg);
|
||||
}
|
||||
},
|
||||
yes: function(index, layero){
|
||||
var body = layer.getChildFrame(\'body\', index);
|
||||
// 延迟加载
|
||||
var loading = layer.load(2, {
|
||||
time: 10000
|
||||
});
|
||||
$.ajax({type: "POST",dataType:"json", url: url, data: $(body).find(\'#myform\').serialize(),
|
||||
success: function(json) {
|
||||
layer.close(loading);
|
||||
if (json.code == 1) {
|
||||
layer.close(index);
|
||||
if (len + json.data.ids.length > '.$limit.') {
|
||||
dr_tips(0, "'.dr_lang('关联数量超限').'");
|
||||
return;
|
||||
}
|
||||
for(var i in json.data.ids){
|
||||
var vid = json.data.ids[i];
|
||||
if (typeof vid != "undefined") {
|
||||
if($("#dr_items_'.$name.'_"+vid).length>0) {
|
||||
dr_tips(0, "'.dr_lang('已经存在').'");
|
||||
return;
|
||||
}
|
||||
if ($(\'#related_'.$name.'-sort-items tr\').length >= '.$limit.') {
|
||||
dr_tips(0, "'.dr_lang('关联数量超限').'");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
$(\'#related_'.$name.'-sort-items\').append(json.data.html);
|
||||
dr_slimScroll_init(".scroller_'.$name.'_files", 300);
|
||||
dr_tips(1, json.msg);
|
||||
} else {
|
||||
dr_tips(0, json.msg);
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
},
|
||||
content: url
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
</script>', 0);
|
||||
|
||||
return $this->input_format($name, $text, $str);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单显示
|
||||
*
|
||||
* @param string $field 字段数组
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function show($field, $value = null) {
|
||||
|
||||
|
||||
$cname = ($field['setting']['option']['title'] ? $field['setting']['option']['title'] : dr_lang('主题'));
|
||||
$value = @trim($value, ',');
|
||||
$mylist = [];
|
||||
$is_show = 1;
|
||||
$module = $mid = isset($field['setting']['option']['module']) ? $field['setting']['option']['module'] : '';
|
||||
if ($value && is_string($value) && $module) {
|
||||
$arr = explode(',', $value);
|
||||
if ($arr) {
|
||||
$value = '';
|
||||
foreach ($arr as $a) {
|
||||
$a = intval($a);
|
||||
if ($a) {
|
||||
$value.= ','.$a;
|
||||
}
|
||||
}
|
||||
if ($value) {
|
||||
$value = trim($value, ',');
|
||||
$db = \Phpcmf\Service::M()->db->query('select * from '.\Phpcmf\Service::M()->dbprefix(dr_module_table_prefix($module)).' where id IN ('.$value.') order by FIELD(id, '.$value.')');
|
||||
$mylist = $db ? $db->getResultArray() : [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$tpl = $field['fieldname'];
|
||||
$file = \Phpcmf\Service::V()->code2php(
|
||||
file_get_contents(is_file(MYPATH.'View/api_'.$tpl.'_field.html') ? MYPATH.'View/api_'.$tpl.'_field.html' : COREPATH.'View/api_related_field.html')
|
||||
);
|
||||
ob_start();
|
||||
require $file;
|
||||
$str = ob_get_clean();
|
||||
|
||||
return $this->input_format($field['fieldname'], $field['name'], $str);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
<?php namespace Phpcmf\Field;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
class Score extends \Phpcmf\Library\A_Field {
|
||||
|
||||
/**
|
||||
* 字段相关属性参数
|
||||
*/
|
||||
public function option($option, $field = null) {
|
||||
return ['', '<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('显示游客组').'</label>
|
||||
<div class="col-md-9">
|
||||
<input type="checkbox" name="data[setting][option][guest]" '.($option['guest'] ? 'checked' : '').' value="1" data-on-text="'.dr_lang('已开启').'" data-off-text="'.dr_lang('已关闭').'" data-on-color="success" data-off-color="danger" class="make-switch" data-size="small">
|
||||
|
||||
<span class="help-block">'.dr_lang('把游客组作为一个用户组来显示').'</span>
|
||||
</div>
|
||||
</div>'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建sql语句
|
||||
*/
|
||||
public function create_sql($name, $value, $cname = '') {
|
||||
$sql = 'ALTER TABLE `{tablename}` ADD `'.$name.'` varchar(255) NULL , ADD `'.$name.'_sku` TEXT NULL';
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改sql语句
|
||||
*/
|
||||
public function alter_sql($name, $value, $cname = '') {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除sql语句
|
||||
*/
|
||||
public function drop_sql($name) {
|
||||
$sql = 'ALTER TABLE `{tablename}` DROP `'.$name.'`, DROP `'.$name.'_sku`';
|
||||
return $sql;
|
||||
}
|
||||
|
||||
// 测试字段是否被创建成功,默认成功为0,需要继承开发
|
||||
public function test_sql($tables, $field) {
|
||||
|
||||
if (!$tables) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
foreach ($tables as $table) {
|
||||
if (!\Phpcmf\Service::M()->db->fieldExists($field.'_sku', $table)) {
|
||||
return '给表['.$table.']创建字段['.$field.'_sku'.']失败';
|
||||
}
|
||||
if (!\Phpcmf\Service::M()->db->fieldExists($field.'', $table)) {
|
||||
return '给表['.$table.']创建字段['.$field.''.']失败';
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段入库值
|
||||
*/
|
||||
public function insert_value($field) {
|
||||
|
||||
if ((int)$_POST['is_field_'.$field['fieldname']]) {
|
||||
// 用户组
|
||||
$sku = $_POST['data'][$field['fieldname'].'_sku'];
|
||||
$price = min($sku);
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname']] = $price;
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname'].'_sku'] = dr_array2string($sku);
|
||||
} else {
|
||||
// 单一
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname']] = $_POST['data'][$field['fieldname']];
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname'].'_sku'] = '';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段输出
|
||||
*
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function output($value) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单输入
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function input($field, $value = []) {
|
||||
|
||||
// 字段显示名称
|
||||
$text = ($field['setting']['validate']['required'] ? '<span class="required" aria-required="true"> * </span>' : '').dr_lang($field['name']);
|
||||
|
||||
// 字段提示信息
|
||||
$tips = $field['setting']['validate']['tips'] ? '<span class="help-block" id="dr_'.$field['fieldname'].'_tips">'.$field['setting']['validate']['tips'].'</span>' : '';
|
||||
|
||||
// 模式
|
||||
$sku = dr_string2array(\Phpcmf\Service::L('Field')->value[$field['fieldname'].'_sku']);
|
||||
$html = '';
|
||||
if ($field['setting']['option']['guest']) {
|
||||
$group = dr_array22array([
|
||||
0 => [
|
||||
'id' => 0,
|
||||
'name' => dr_lang('游客'),
|
||||
],
|
||||
], \Phpcmf\Service::C()->member_cache['group']);
|
||||
} else {
|
||||
$group = \Phpcmf\Service::C()->member_cache['group'];
|
||||
}
|
||||
foreach ($group as $g) {
|
||||
$html.= '<label><div class="input-group">
|
||||
<span class="input-group-addon">'.$g['name'].'</span>
|
||||
<input type="text" class="form-control" name="data['.$field['fieldname'].'_sku]['.$g['id'].']" value="'.(string)$sku[$g['id']].'" />
|
||||
</div></label>';
|
||||
}
|
||||
$is_field = $sku? 1 : 0;
|
||||
|
||||
$str = '
|
||||
<div class="mt-radio-inline">
|
||||
<label class="mt-radio">
|
||||
<input type="radio" onclick="$(\'#dr_field_'.$field['fieldname'].'\').show();$(\'#dr_field_'.$field['fieldname'].'2\').hide();" name="is_field_'.$field['fieldname'].'" value="0" '.(!$is_field ? 'checked' : '').'> '.dr_lang('全局').'
|
||||
<span></span>
|
||||
</label>
|
||||
<label class="mt-radio">
|
||||
<input type="radio" onclick="$(\'#dr_field_'.$field['fieldname'].'2\').show();$(\'#dr_field_'.$field['fieldname'].'\').hide();" name="is_field_'.$field['fieldname'].'" value="1" '.($is_field ? 'checked' : '').'> '.dr_lang('用户组').'
|
||||
<span></span>
|
||||
</label>
|
||||
</div>
|
||||
<div id="dr_field_'.$field['fieldname'].'" style="display:'.(!$is_field ? 'block' : 'none').';">
|
||||
<label><input class="form-control " type="text" name="data['.$field['fieldname'].']" id="dr_'.$field['fieldname'].'" value="'.$value.'" /></label>
|
||||
</div>
|
||||
<div id="dr_field_'.$field['fieldname'].'2" style="display:'.($is_field ? 'block' : 'none').';">
|
||||
<div style="width: 50%">
|
||||
'.$html.'
|
||||
</div>
|
||||
</div>
|
||||
';
|
||||
return $this->input_format($field['fieldname'], $text, $str.$tips);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单显示
|
||||
*/
|
||||
public function show($field, $value = null) {
|
||||
|
||||
// 字段显示名称
|
||||
$text = ($field['setting']['validate']['required'] ? '<span class="required" aria-required="true"> * </span>' : '').$field['name'];
|
||||
|
||||
// 字段提示信息
|
||||
$tips = $field['setting']['validate']['tips'] ? '<span class="help-block" id="dr_'.$field['fieldname'].'_tips">'.$field['setting']['validate']['tips'].'</span>' : '';
|
||||
|
||||
// 模式
|
||||
$sku = dr_string2array(\Phpcmf\Service::L('Field')->value['score_sku']);
|
||||
$html = '';
|
||||
if ($field['setting']['option']['guest']) {
|
||||
$group = dr_array22array([
|
||||
0 => [
|
||||
'id' => 0,
|
||||
'name' => dr_lang('游客'),
|
||||
],
|
||||
], \Phpcmf\Service::C()->member_cache['group']);
|
||||
} else {
|
||||
$group = \Phpcmf\Service::C()->member_cache['group'];
|
||||
}
|
||||
foreach ($group as $g) {
|
||||
$html.= '<label><div class="input-group">
|
||||
<span class="input-group-addon">'.$g['name'].'</span>
|
||||
<input type="text" class="form-control" readonly name="data['.$field['fieldname'].'_sku]['.$g['id'].']" value="'.(string)$sku[$g['id']].'" />
|
||||
</div></label>';
|
||||
}
|
||||
|
||||
$is_field = $sku? 1 : 0;
|
||||
|
||||
$str = '
|
||||
<div id="dr_field_'.$field['fieldname'].'" style="display:'.(!$is_field ? 'block' : 'none').';">
|
||||
<label><input class="form-control " readonly type="text" name="data['.$field['fieldname'].']" id="dr_'.$field['fieldname'].'" value="'.$value.'" /></label>
|
||||
</div>
|
||||
<div id="dr_field_'.$field['fieldname'].'2" style="display:'.($is_field ? 'block' : 'none').';">
|
||||
<div style="width: 50%">
|
||||
'.$html.'
|
||||
</div>
|
||||
</div>
|
||||
';
|
||||
return $this->input_format($field['fieldname'], $text, $str.$tips);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
<?php namespace Phpcmf\Field;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
class Select extends \Phpcmf\Library\A_Field {
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
public function __construct(...$params) {
|
||||
parent::__construct(...$params);
|
||||
$this->fieldtype = TRUE;
|
||||
$this->defaulttype = 'VARCHAR';
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段相关属性参数
|
||||
*
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function option($option) {
|
||||
|
||||
$option['options'] = isset($option['options']) ? $option['options'] : 'name1|1'.PHP_EOL.'name2|2';
|
||||
|
||||
return [
|
||||
'
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('选项列表').'</label>
|
||||
<div class="col-md-9">
|
||||
<textarea class="form-control" name="data[setting][option][options]" style="height:150px;width:400px;">'.$option['options'].'</textarea>
|
||||
<span class="help-block">'.dr_lang('格式:选项名称|选项值[回车换行]选项名称2|值2....').'</span>
|
||||
<span class="help-block">'.dr_lang('选项值建议使用从1开始的数字,不得带符号,也可以省略不写').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('多语言翻译').'</label>
|
||||
<div class="col-md-9">
|
||||
<div class="mt-radio-inline">
|
||||
<label class="mt-radio mt-radio-outline"><input type="radio" value="0" name="data[setting][option][lang]" '.(!$option['lang'] ? 'checked' : '').' > '.dr_lang('开启').' <span></span></label>
|
||||
|
||||
<label class="mt-radio mt-radio-outline"><input type="radio" value="1" name="data[setting][option][lang]" '.($option['lang'] ? 'checked' : '').' > '.dr_lang('关闭').' <span></span></label>
|
||||
</div>
|
||||
<span class="help-block">'.dr_lang('开启后选项值被系统语言包翻译,否则就保持原样显示').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('默认选中项').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input id="field_default_value" type="text" class="form-control" size="20" value="'.$option['value'].'" name="data[setting][option][value]"></label>
|
||||
<label>'.$this->member_field_select().'</label>
|
||||
<span class="help-block">'.dr_lang('用于字段为空时显示该填充值,并不会去主动变更数据库中的实际值;可以设置会员表字段,表示用当前登录会员信息来填充这个值').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('启用选项搜索').'</label>
|
||||
<div class="col-md-9">
|
||||
<input type="checkbox" name="data[setting][option][is_search]" '.($option['is_search'] ? 'checked' : '').' value="1" data-on-text="'.dr_lang('已开启').'" data-off-text="'.dr_lang('已关闭').'" data-on-color="success" data-off-color="danger" class="make-switch" data-size="small">
|
||||
|
||||
<span class="help-block">'.dr_lang('当选项值过多时,可以在选择框中搜索选项值').'</span>
|
||||
</div>
|
||||
</div>
|
||||
'
|
||||
.
|
||||
$this->field_type($option['fieldtype'], $option['fieldlength'])
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单输入
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function input($field, $value = '') {
|
||||
|
||||
// 字段禁止修改时就返回显示字符串
|
||||
if ($this->_not_edit($field, $value)) {
|
||||
return $this->show($field, $value);
|
||||
}
|
||||
|
||||
// 字段存储名称
|
||||
$name = $field['fieldname'];
|
||||
|
||||
// 字段显示名称
|
||||
$text = ($field['setting']['validate']['required'] ? '<span class="required" aria-required="true"> * </span>' : '').dr_lang($field['name']);
|
||||
|
||||
// 表单附加参数
|
||||
$attr = $field['setting']['validate']['formattr'];
|
||||
|
||||
// 字段提示信息
|
||||
$tips = ($name == 'title' && APP_DIR) || $field['setting']['validate']['tips'] ? '<span class="help-block" id="dr_'.$field['fieldname'].'_tips">'.$field['setting']['validate']['tips'].'</span>' : '';
|
||||
|
||||
// 是否必填
|
||||
$required = $field['setting']['validate']['required'] ? ' required="required"' : '';
|
||||
|
||||
// 字段默认值
|
||||
$value = dr_strlen($value) ? $value : $this->get_default_value($field['setting']['option']['value']);
|
||||
|
||||
$str = '<label><select '.$required.' class="'.(isset($field['setting']['option']['is_search']) && $field['setting']['option']['is_search'] ? 'bs-select' : '').' form-control '.$field['setting']['option']['css'].'" '.(isset($field['setting']['option']['is_search']) && $field['setting']['option']['is_search'] ? ' data-live-search="true" ' : '').' name="data['.$name.']" id="dr_'.$name.'" '.$attr.' >';
|
||||
|
||||
// 表单选项
|
||||
$options = dr_format_option_array($field['setting']['option']['options']);
|
||||
if ($options) {
|
||||
foreach ($options as $v => $n) {
|
||||
$str.= '<option value="'.$v.'" '.($v == $value ? ' selected' : '').'>'.
|
||||
(isset($field['setting']['option']['lang']) && $field['setting']['option']['lang'] ? $n : dr_lang($n)).'</option>';
|
||||
}
|
||||
}
|
||||
|
||||
$str.= '</select></label>'.$tips;
|
||||
|
||||
if (isset($field['setting']['option']['is_search']) && $field['setting']['option']['is_search']) {
|
||||
// 防止重复加载JS
|
||||
if (!$this->is_load_js($field['fieldtype'])) {
|
||||
$str.= $this->get_select_search_code();
|
||||
}
|
||||
}
|
||||
|
||||
return $this->input_format($name, $text, $str);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 字段表单显示
|
||||
*
|
||||
* @param string $field 字段数组
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function show($field, $value = null) {
|
||||
|
||||
$options = dr_format_option_array($field['setting']['option']['options']);
|
||||
|
||||
$str = '<div class="form-control-static"> '.(isset($options[$value]) ? dr_lang($options[$value]) : dr_lang('未选择')).' </div>';
|
||||
|
||||
return $this->input_format($field['fieldname'], $field['name'], $str);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
<?php namespace Phpcmf\Field;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
class Selects extends \Phpcmf\Library\A_Field {
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
public function __construct(...$params) {
|
||||
parent::__construct(...$params);
|
||||
$this->fieldtype = TRUE;
|
||||
$this->defaulttype = 'VARCHAR';
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段相关属性参数
|
||||
*
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function option($option) {
|
||||
|
||||
$option['options'] = isset($option['options']) ? $option['options'] : 'name1|1'.PHP_EOL.'name2|2';
|
||||
|
||||
return [
|
||||
$this->_search_field().'
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('选项列表').'</label>
|
||||
<div class="col-md-9">
|
||||
<textarea class="form-control" name="data[setting][option][options]" style="height:150px;width:400px;">'.$option['options'].'</textarea>
|
||||
<span class="help-block">'.dr_lang('格式:选项名称|选项值[回车换行]选项名称2|值2....').'</span>
|
||||
<span class="help-block">'.dr_lang('选项值建议使用从1开始的数字,不得带符号,也可以省略不写').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('多语言翻译').'</label>
|
||||
<div class="col-md-9">
|
||||
<div class="mt-radio-inline">
|
||||
<label class="mt-radio mt-radio-outline"><input type="radio" value="0" name="data[setting][option][lang]" '.(!$option['lang'] ? 'checked' : '').' > '.dr_lang('开启').' <span></span></label>
|
||||
|
||||
<label class="mt-radio mt-radio-outline"><input type="radio" value="1" name="data[setting][option][lang]" '.($option['lang'] ? 'checked' : '').' > '.dr_lang('关闭').' <span></span></label>
|
||||
</div>
|
||||
<span class="help-block">'.dr_lang('开启后选项值被系统语言包翻译,否则就保持原样显示').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('默认选中项').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input id="field_default_value" type="text" class="form-control" size="20" value="'.$option['value'].'" name="data[setting][option][value]"></label>
|
||||
<label>'.$this->member_field_select().'</label>
|
||||
<span class="help-block">'.dr_lang('用于字段为空时显示该填充值,并不会去主动变更数据库中的实际值;可以设置会员表字段,表示用当前登录会员信息来填充这个值').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('启用选项搜索').'</label>
|
||||
<div class="col-md-9">
|
||||
<input type="checkbox" name="data[setting][option][is_search]" '.($option['is_search'] ? 'checked' : '').' value="1" data-on-text="'.dr_lang('已开启').'" data-off-text="'.dr_lang('已关闭').'" data-on-color="success" data-off-color="danger" class="make-switch" data-size="small">
|
||||
|
||||
<span class="help-block">'.dr_lang('当选项值过多时,可以在选择框中搜索选项值').'</span>
|
||||
</div>
|
||||
</div>
|
||||
'
|
||||
.
|
||||
$this->field_type($option['fieldtype'], $option['fieldlength'])
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段入库值
|
||||
*/
|
||||
public function insert_value($field) {
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname']] = dr_array2string(\Phpcmf\Service::L('Field')->post[$field['fieldname']]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段入库值
|
||||
*/
|
||||
public function output($value) {
|
||||
return dr_string2array($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单输入
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function input($field, $value = '') {
|
||||
|
||||
// 字段禁止修改时就返回显示字符串
|
||||
if ($this->_not_edit($field, $value)) {
|
||||
return $this->show($field, $value);
|
||||
}
|
||||
|
||||
// 字段存储名称
|
||||
$name = $field['fieldname'];
|
||||
|
||||
// 字段显示名称
|
||||
$text = ($field['setting']['validate']['required'] ? '<span class="required" aria-required="true"> * </span>' : '').dr_lang($field['name']);
|
||||
|
||||
// 表单附加参数
|
||||
$attr = $field['setting']['validate']['formattr'];
|
||||
|
||||
// 字段提示信息
|
||||
$tips = ($name == 'title' && APP_DIR) || $field['setting']['validate']['tips'] ? '<span class="help-block" id="dr_'.$field['fieldname'].'_tips">'.$field['setting']['validate']['tips'].'</span>' : '';
|
||||
|
||||
// 是否必填
|
||||
$required = $field['setting']['validate']['required'] ? ' required="required"' : '';
|
||||
|
||||
// 字段默认值
|
||||
if ($value) {
|
||||
$value = dr_string2array($value);
|
||||
} elseif ($field['setting']['option']['value']) {
|
||||
$value = $this->get_default_value($field['setting']['option']['value']);
|
||||
$value = is_array($value) ? $value : explode('|', $value);
|
||||
} else {
|
||||
$value = null;
|
||||
}
|
||||
|
||||
$str = '<label style="min-width: 200px"><select '.$required.' class="bs-select form-control '.$field['setting']['option']['css'].'" '.(isset($field['setting']['option']['is_search']) && $field['setting']['option']['is_search'] ? ' data-live-search="true" ' : '').' data-actions-box="true" multiple="multiple" name="data['.$name.'][]" id="dr_'.$name.'" '.$attr.' >';
|
||||
|
||||
// 表单选项
|
||||
$options = dr_format_option_array($field['setting']['option']['options']);
|
||||
if ($options) {
|
||||
foreach ($options as $v => $n) {
|
||||
$str.= '<option value="'.$v.'" '.(dr_in_array($v, $value) ? ' selected' : '').'>'.(isset($field['setting']['option']['lang']) && $field['setting']['option']['lang'] ? $n : dr_lang($n)).'</option>';
|
||||
}
|
||||
}
|
||||
|
||||
$str.= '</select></label>'.$tips;
|
||||
|
||||
// 防止重复加载JS
|
||||
if (!$this->is_load_js('Select')) {
|
||||
$str.= $this->get_select_search_code();
|
||||
}
|
||||
|
||||
return $this->input_format($name, $text, $str);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 字段表单显示
|
||||
*
|
||||
* @param string $field 字段数组
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function show($field, $value = null) {
|
||||
|
||||
$str = '';
|
||||
$value = dr_string2array($value);
|
||||
$options = dr_format_option_array($field['setting']['option']['options']);
|
||||
if ($options && $value) {
|
||||
foreach ($options as $v => $n) {
|
||||
is_array($value) && in_array($v, $value) && $str.= '<label class="label label-default"> '.$n.' </label> ';
|
||||
}
|
||||
}
|
||||
|
||||
return $this->input_format($field['fieldname'], $field['name'], '<div class="form-control-static">'.$str.'</div>');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
<?php namespace Phpcmf\Field;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
class Text extends \Phpcmf\Library\A_Field {
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
public function __construct(...$params) {
|
||||
parent::__construct(...$params);
|
||||
$this->fieldtype = TRUE;
|
||||
$this->defaulttype = 'VARCHAR';
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段相关属性参数
|
||||
*
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function option($option) {
|
||||
|
||||
$mcf = '';
|
||||
if (\Phpcmf\Service::M('field')->relatedname == 'module') {
|
||||
$mcf = '<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('验证重复').'</label>
|
||||
<div class="col-md-9">
|
||||
<input type="checkbox" name="data[setting][option][unique]" '.($option['unique'] ? 'checked' : '').' value="1" data-on-text="'.dr_lang('已开启').'" data-off-text="'.dr_lang('已关闭').'" data-on-color="success" data-off-color="danger" class="make-switch" data-size="small">
|
||||
<span class="help-block">'.dr_lang('开启将会判断此字段的唯一性(本字段只对内容模块主表有效)').'</span>
|
||||
</div>
|
||||
</div>';
|
||||
}
|
||||
|
||||
$style = '
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('控件宽度').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" size="10" name="data[setting][option][width]" value="'.$option['width'].'"></label>
|
||||
<span class="help-block">'.dr_lang('[整数]表示固定宽度;[整数%]表示百分比').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('密码框模式').'</label>
|
||||
<div class="col-md-9">
|
||||
<input type="checkbox" name="data[setting][option][ispwd]" '.($option['ispwd'] ? 'checked' : '').' value="1" data-on-text="'.dr_lang('开启').'" data-off-text="'.dr_lang('关闭').'" data-on-color="success" data-off-color="danger" class="make-switch" data-size="small">
|
||||
|
||||
<span class="help-block">'.dr_lang('开启之后它将作为密码框来显示').'</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
'.$mcf;
|
||||
|
||||
$option = $this->field_type($option['fieldtype'], $option['fieldlength']).'
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('默认填充值').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input id="field_default_value" type="text" class="form-control" size="20" value="'.$option['value'].'" name="data[setting][option][value]"></label>
|
||||
<label>'.$this->member_field_select().'</label>
|
||||
<span class="help-block">'.dr_lang('用于字段为空时显示该填充值,并不会去主动变更数据库中的实际值;可以设置会员表字段,表示用当前登录会员信息来填充这个值').'</span>
|
||||
</div>
|
||||
</div>
|
||||
';
|
||||
|
||||
return [$option, $style];
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段入库值
|
||||
*
|
||||
* @param array $field 字段信息
|
||||
* @return void
|
||||
*/
|
||||
public function insert_value($field) {
|
||||
// 格式化入库值
|
||||
$value = \Phpcmf\Service::L('Field')->post[$field['fieldname']];
|
||||
if (in_array($field['setting']['option']['fieldtype'], array('INT', 'TINYINT', 'SMALLINT'))) {
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname']] = $value ? (int)$value : 0;
|
||||
} elseif (in_array($field['setting']['option']['fieldtype'], array('DECIMAL', 'FLOAT'))) {
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname']] = $value ? (float)$value : 0;
|
||||
} elseif ($field['setting']['option']['fieldtype'] == 'MEDIUMINT') {
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname']] = $value ? $value : 0;
|
||||
} elseif (dr_strlen($value) == 1 && $value == '0') {
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname']] = '0';
|
||||
} else {
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname']] = dr_htmlspecialchars($value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单输入
|
||||
*
|
||||
* @param string $field 字段数组
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function input($field, $value = null) {
|
||||
|
||||
// 字段禁止修改时就返回显示字符串
|
||||
if ($this->_not_edit($field, $value)) {
|
||||
return $this->show($field, $value);
|
||||
}
|
||||
|
||||
// 字段存储名称
|
||||
$name = $field['fieldname'];
|
||||
|
||||
// 字段显示名称
|
||||
$text = ($field['setting']['validate']['required'] ? '<span class="required" aria-required="true"> * </span>' : '').dr_lang($field['name']);
|
||||
|
||||
// 表单宽度设置
|
||||
$width = \Phpcmf\Service::IS_MOBILE_USER() ? '100%' : ($field['setting']['option']['width'] ? $field['setting']['option']['width'] : 200);
|
||||
|
||||
// 风格
|
||||
$style = 'style="width:'.$width.(is_numeric($width) ? 'px' : '').';"';
|
||||
|
||||
// 表单附加参数
|
||||
$attr = $field['setting']['validate']['formattr'];
|
||||
|
||||
// 字段提示信息
|
||||
$tips = ($name == 'title' && APP_DIR) || $field['setting']['validate']['tips'] ? '<span class="help-block" id="dr_'.$field['fieldname'].'_tips">'.$field['setting']['validate']['tips'].'</span>' : '';
|
||||
|
||||
// 当字段必填时,加入html5验证标签
|
||||
$required = $field['setting']['validate']['required'] ? ' required="required"' : '';
|
||||
|
||||
// 是否密码框
|
||||
$type = $field['setting']['option']['ispwd'] ? 'password' : 'text';
|
||||
|
||||
// 字段默认值
|
||||
$value = dr_strlen($value) ? $value : $this->get_default_value($field['setting']['option']['value']);
|
||||
|
||||
$str = '<input class="form-control '.($field['setting']['validate']['required'] ? 'dr_required' : '').' '.$field['setting']['option']['css'].'" type="'.$type.'" name="data['.$field['fieldname'].']" id="dr_'.$field['fieldname'].'" value="'.$value.'" '.$style.' '.$required.' '.$attr.' />';
|
||||
|
||||
return $this->input_format($field['fieldname'], $text, $str.$tips);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
<?php namespace Phpcmf\Field;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
class Textarea extends \Phpcmf\Library\A_Field {
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
public function __construct(...$params) {
|
||||
parent::__construct(...$params);
|
||||
$this->fieldtype = TRUE;
|
||||
$this->defaulttype = 'TEXT';
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段相关属性参数
|
||||
*
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function option($option) {
|
||||
|
||||
|
||||
return ['
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('默认存储值').'</label>
|
||||
<div class="col-md-9">
|
||||
<textarea id="field_default_value" style="width: 90%;height: 100px;" class="form-control" name="data[setting][option][value]">'.$option['value'].'</textarea>
|
||||
<p><label>'.$this->member_field_select().'</label>
|
||||
<span class="help-block">'.dr_lang('用于字段为空时显示该填充值,并不会去主动变更数据库中的实际值;可以设置会员表字段,表示用当前登录会员信息来填充这个值').'</span></p>
|
||||
</div>
|
||||
</div>
|
||||
'.$this->field_type($option['fieldtype'], $option['fieldlength']),
|
||||
'<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('控件宽度').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" size="10" name="data[setting][option][width]" value="'.$option['width'].'"></label>
|
||||
<span class="help-block">'.dr_lang('[整数]表示固定宽度;[整数%]表示百分比').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('控件高度').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" size="10" name="data[setting][option][height]" value="'.$option['height'].'"></label>
|
||||
<label>px</label>
|
||||
</div>
|
||||
</div>'
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 字段显示
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function show($field, $value = null) {
|
||||
$html = '
|
||||
<div class="portlet bordered light">
|
||||
<div class="portlet-body">
|
||||
<div class="scroller" style="width:'.(\Phpcmf\Service::IS_MOBILE_USER() ? '100%' : ($field['setting']['option']['width'] ? ($field['setting']['option']['width'].(is_numeric($field['setting']['option']['width']) ? 'px' : '')) : '400px')).';height:'.($field['setting']['option']['height'] ? $field['setting']['option']['height'] : '100').'px" data-always-visible="1" data-rail-visible="1">
|
||||
'.nl2br(htmlspecialchars_decode((string)$value)).'
|
||||
</div>
|
||||
</div>
|
||||
</div>';
|
||||
return $this->input_format($field['fieldname'], $field['name'], $html);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单输入
|
||||
*/
|
||||
public function input($field, $value = '') {
|
||||
|
||||
// 字段禁止修改时就返回显示字符串
|
||||
if ($this->_not_edit($field, $value)) {
|
||||
return $this->show($field, $value);
|
||||
}
|
||||
|
||||
// 字段存储名称
|
||||
$name = $field['fieldname'];
|
||||
|
||||
// 字段显示名称
|
||||
$text = ($field['setting']['validate']['required'] ? '<span class="required" aria-required="true"> * </span>' : '').dr_lang($field['name']);
|
||||
|
||||
// 表单宽度设置
|
||||
$width = \Phpcmf\Service::IS_MOBILE_USER() ? '100%' : ($field['setting']['option']['width'] ? $field['setting']['option']['width'] : '100%');
|
||||
|
||||
// 表单附加参数
|
||||
$attr = $field['setting']['validate']['formattr'];
|
||||
|
||||
// 字段提示信息
|
||||
$tips = ($name == 'title' && APP_DIR) || $field['setting']['validate']['tips'] ? '<span class="help-block" id="dr_'.$field['fieldname'].'_tips">'.$field['setting']['validate']['tips'].'</span>' : '';
|
||||
|
||||
// 表单高度设置
|
||||
$height = $field['setting']['option']['height'] ? $field['setting']['option']['height'] : '100';
|
||||
|
||||
// 字段默认值
|
||||
$value = dr_strlen($value) ? $value : $this->get_default_value($field['setting']['option']['value']);
|
||||
|
||||
$str = '<textarea class="form-control" style="height:'.$height.'px; width:'.$width.(is_numeric($width) ? 'px' : '').';" name="data['.$name.']" id="dr_'.$name.'" '.$attr.'>'.$value.'</textarea>';
|
||||
|
||||
return $this->input_format($name, $text, $str.$tips);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
<?php namespace Phpcmf\Field;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
class Textbtn extends \Phpcmf\Library\A_Field {
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
public function __construct(...$params) {
|
||||
parent::__construct(...$params);
|
||||
$this->fieldtype = TRUE;
|
||||
$this->defaulttype = 'VARCHAR';
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段相关属性参数
|
||||
*
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function option($option) {
|
||||
|
||||
|
||||
$style = '
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('控件宽度').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" size="10" name="data[setting][option][width]" value="'.$option['width'].'"></label>
|
||||
<span class="help-block">'.dr_lang('[整数]表示固定宽度;[整数%]表示百分比').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('图标样式').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" size="10" name="data[setting][option][icon]" value="'.$option['icon'].'"></label>
|
||||
<span class="help-block">'.dr_lang('例如: fa fa-user').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('图标名称').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" size="10" name="data[setting][option][name]" value="'.$option['name'].'"></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('按钮颜色').'</label>
|
||||
<div class="col-md-9">
|
||||
<label>'.$this->_color_select('color', $option['color']).'</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('点击JS函数').'</label>
|
||||
<div class="col-md-9">
|
||||
<input type="text" class="form-control Large" size="10" name="data[setting][option][func]" value="'.$option['func'].'">
|
||||
<span class="help-block">'.dr_lang('单击按钮时执行的js函数').'</span>
|
||||
</div>
|
||||
</div>
|
||||
';
|
||||
|
||||
|
||||
$option = $this->field_type($option['fieldtype'], $option['fieldlength']).'
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('默认填充值').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input id="field_default_value" type="text" class="form-control" size="20" value="'.$option['value'].'" name="data[setting][option][value]"></label>
|
||||
<label>'.$this->member_field_select().'</label>
|
||||
<span class="help-block">'.dr_lang('用于字段为空时显示该填充值,并不会去主动变更数据库中的实际值;可以设置会员表字段,表示用当前登录会员信息来填充这个值').'</span>
|
||||
</div>
|
||||
</div>
|
||||
';
|
||||
|
||||
return [$option, $style];
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段入库值
|
||||
*
|
||||
* @param array $field 字段信息
|
||||
* @return void
|
||||
*/
|
||||
public function insert_value($field) {
|
||||
|
||||
// 格式化入库值
|
||||
$value = \Phpcmf\Service::L('Field')->post[$field['fieldname']];
|
||||
|
||||
if (isset($field['setting']['option']['diy_insert_value']) && $field['setting']['option']['diy_insert_value']) {
|
||||
// 扩展字段函数
|
||||
list($a, $method) = explode(':', $field['setting']['option']['diy_insert_value']);
|
||||
$obj = \Phpcmf\Service::M($a);
|
||||
if (method_exists($obj, $method)) {
|
||||
$value = call_user_func([$obj, $method], $value);
|
||||
} else {
|
||||
log_message('error', '扩展函数方法 '.$field['setting']['option']['diy_insert_value'].' 不存在!');
|
||||
}
|
||||
}
|
||||
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname']] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单输入
|
||||
*
|
||||
* @param string $field 字段数组
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function input($field, $value = null) {
|
||||
|
||||
// 字段禁止修改时就返回显示字符串
|
||||
if ($this->_not_edit($field, $value)) {
|
||||
return $this->show($field, $value);
|
||||
}
|
||||
|
||||
// 字段默认值
|
||||
$value = dr_strlen($value) ? $value : $this->get_default_value($field['setting']['option']['value']);
|
||||
|
||||
if (isset($field['setting']['option']['diy_show_value']) && $field['setting']['option']['diy_show_value']) {
|
||||
// 扩展字段函数
|
||||
list($a, $method) = explode(':', $field['setting']['option']['diy_show_value']);
|
||||
$obj = \Phpcmf\Service::M($a);
|
||||
if (method_exists($obj, $method)) {
|
||||
$value = call_user_func([$obj, $method], $value);
|
||||
} else {
|
||||
log_message('error', '扩展函数方法 '.$field['setting']['option']['diy_show_value'].' 不存在!');
|
||||
}
|
||||
}
|
||||
|
||||
// 字段存储名称
|
||||
$name = $field['fieldname'];
|
||||
|
||||
// 字段显示名称
|
||||
$text = ($field['setting']['validate']['required'] ? '<span class="required" aria-required="true"> * </span>' : '').dr_lang($field['name']);
|
||||
|
||||
// 表单宽度设置
|
||||
$width = \Phpcmf\Service::IS_MOBILE_USER() ? '100%' : ($field['setting']['option']['width'] ? $field['setting']['option']['width'] : 200);
|
||||
|
||||
// 风格
|
||||
$style = 'style="width:'.$width.(is_numeric($width) ? 'px' : '').';"';
|
||||
|
||||
// 表单附加参数
|
||||
$attr = $field['setting']['validate']['formattr'];
|
||||
|
||||
// 字段提示信息
|
||||
$tips = $field['setting']['validate']['tips'] ? '<span class="help-block" id="dr_'.$field['fieldname'].'_tips">'.$field['setting']['validate']['tips'].'</span>' : '';
|
||||
|
||||
// 当字段必填时,加入html5验证标签
|
||||
$required = $field['setting']['validate']['required'] ? ' required="required"' : '';
|
||||
|
||||
// 按钮颜色
|
||||
$color = $field['setting']['option']['color'] ? $field['setting']['option']['color'] : 'default';
|
||||
|
||||
// 函数
|
||||
$func = $field['setting']['option']['func'] ? $field['setting']['option']['func'] : 'dr_diy_func';
|
||||
|
||||
$ipt = '<input class="form-control '.$field['setting']['option']['css'].'" type="text" name="data['.$field['fieldname'].']" id="dr_'.$field['fieldname'].'" value="'.$value.'" '.$required.' '.$attr.' />';
|
||||
$str = '
|
||||
<div class="input-group" '.$style.'>
|
||||
'.$ipt.'
|
||||
<span class="input-group-btn">
|
||||
<a class="btn btn-success " style="border-color:'.$color.';background-color:'.$color.'" href="javascript:'.$func.'(\''.$name.'\');" ><i class="'.dr_icon($field['setting']['option']['icon']).'" /></i> '.dr_lang($field['setting']['option']['name']).'</a>
|
||||
</span>
|
||||
</div>
|
||||
';
|
||||
|
||||
return $this->input_format($field['fieldname'], $text, $str.$tips);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单显示
|
||||
*
|
||||
* @param string $field 字段数组
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function show($field, $value = null) {
|
||||
|
||||
// 字段默认值
|
||||
$value = dr_strlen($value) ? $value : $this->get_default_value($field['setting']['option']['value']);
|
||||
if (isset($field['setting']['option']['diy_show_value']) && $field['setting']['option']['diy_show_value']) {
|
||||
// 扩展字段函数
|
||||
list($a, $method) = explode(':', $field['setting']['option']['diy_show_value']);
|
||||
$obj = \Phpcmf\Service::M($a);
|
||||
if (method_exists($obj, $method)) {
|
||||
$value = call_user_func([$obj, $method], $value);
|
||||
} else {
|
||||
log_message('error', '扩展函数方法 '.$field['setting']['option']['diy_show_value'].' 不存在!');
|
||||
}
|
||||
}
|
||||
|
||||
$str = '<div class="form-control-static"> '.htmlspecialchars_decode((string)$value).' </div>';
|
||||
|
||||
return $this->input_format($field['fieldname'], $field['name'], $str);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
<?php namespace Phpcmf\Field;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
class Textselect extends \Phpcmf\Library\A_Field {
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
public function __construct(...$params) {
|
||||
parent::__construct(...$params);
|
||||
$this->fieldtype = TRUE;
|
||||
$this->defaulttype = 'TEXT';
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段相关属性参数
|
||||
*
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function option($option) {
|
||||
|
||||
$option['options'] = isset($option['options']) ? $option['options'] : '选项名称1'.PHP_EOL.'选项名称2';
|
||||
|
||||
|
||||
$style = '
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('控件宽度').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" size="10" name="data[setting][option][width]" value="'.$option['width'].'"></label>
|
||||
<span class="help-block">'.dr_lang('[整数]表示固定宽度;[整数%]表示百分比').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('密码框模式').'</label>
|
||||
<div class="col-md-9">
|
||||
<input type="checkbox" name="data[setting][option][ispwd]" '.($option['ispwd'] ? 'checked' : '').' value="1" data-on-text="'.dr_lang('开启').'" data-off-text="'.dr_lang('关闭').'" data-on-color="success" data-off-color="danger" class="make-switch" data-size="small">
|
||||
|
||||
<span class="help-block">'.dr_lang('开启之后它将作为密码框来显示').'</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
';
|
||||
|
||||
$option = $this->field_type($option['fieldtype'], $option['fieldlength']).'
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('选项列表').'</label>
|
||||
<div class="col-md-9">
|
||||
<textarea class="form-control" name="data[setting][option][options]" style="height:150px;width:400px;">'.$option['options'].'</textarea>
|
||||
<span class="help-block">'.dr_lang('格式:选项名称1[回车换行]选项名称2....').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('默认填充值').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input id="field_default_value" type="text" class="form-control" size="20" value="'.$option['value'].'" name="data[setting][option][value]"></label>
|
||||
<label>'.$this->member_field_select().'</label>
|
||||
<span class="help-block">'.dr_lang('用于字段为空时显示该填充值,并不会去主动变更数据库中的实际值;可以设置会员表字段,表示用当前登录会员信息来填充这个值').'</span>
|
||||
</div>
|
||||
</div>
|
||||
';
|
||||
|
||||
return [$option, $style];
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段入库值
|
||||
*
|
||||
* @param array $field 字段信息
|
||||
* @return void
|
||||
*/
|
||||
public function insert_value($field) {
|
||||
// 格式化入库值
|
||||
$value = \Phpcmf\Service::L('Field')->post[$field['fieldname']];
|
||||
if (in_array($field['setting']['option']['fieldtype'], array('INT', 'TINYINT', 'SMALLINT'))) {
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname']] = $value ? (int)$value : 0;
|
||||
} elseif (in_array($field['setting']['option']['fieldtype'], array('DECIMAL', 'FLOAT'))) {
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname']] = $value ? (float)$value : 0;
|
||||
} elseif ($field['setting']['option']['fieldtype'] == 'MEDIUMINT') {
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname']] = $value ? $value : 0;
|
||||
} elseif (dr_strlen($value) == 1 && $value == '0') {
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname']] = '0';
|
||||
} else {
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname']] = dr_htmlspecialchars($value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单输入
|
||||
*
|
||||
* @param string $field 字段数组
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function input($field, $value = null) {
|
||||
|
||||
// 字段禁止修改时就返回显示字符串
|
||||
if ($this->_not_edit($field, $value)) {
|
||||
return $this->show($field, $value);
|
||||
}
|
||||
|
||||
// 字段存储名称
|
||||
$name = $field['fieldname'];
|
||||
|
||||
// 字段显示名称
|
||||
$text = ($field['setting']['validate']['required'] ? '<span class="required" aria-required="true"> * </span>' : '').dr_lang($field['name']);
|
||||
|
||||
// 表单宽度设置
|
||||
$width = \Phpcmf\Service::IS_MOBILE_USER() ? '100%' : ($field['setting']['option']['width'] ? $field['setting']['option']['width'] : 200);
|
||||
|
||||
// 风格
|
||||
$style = 'style="width:'.$width.(is_numeric($width) ? 'px' : '').';"';
|
||||
|
||||
// 表单附加参数
|
||||
$attr = $field['setting']['validate']['formattr'];
|
||||
|
||||
// 字段提示信息
|
||||
$tips = $field['setting']['validate']['tips'] ? '<span class="help-block" id="dr_'.$field['fieldname'].'_tips">'.$field['setting']['validate']['tips'].'</span>' : '';
|
||||
|
||||
// 当字段必填时,加入html5验证标签
|
||||
$required = $field['setting']['validate']['required'] ? ' required="required"' : '';
|
||||
|
||||
|
||||
// 字段默认值
|
||||
$value = dr_strlen($value) ? $value : $this->get_default_value($field['setting']['option']['value']);
|
||||
|
||||
|
||||
$str = '';
|
||||
if (!$this->is_load_js($field['fieldtype'])) {
|
||||
$str.= '
|
||||
<link href="'.ROOT_THEME_PATH.'assets/global/plugins/jquery.editable-select/jquery.editable-select.min.css?v='.CMF_UPDATE_TIME.'" rel="stylesheet" type="text/css" />
|
||||
<script src="'.ROOT_THEME_PATH.'assets/global/plugins/jquery.editable-select/jquery.editable-select.min.js?v='.CMF_UPDATE_TIME.'" type="text/javascript"></script>
|
||||
';
|
||||
$this->set_load_js($field['fieldtype'], 1);
|
||||
}
|
||||
|
||||
//$str = '<input class="form-control '.($field['setting']['validate']['required'] ? 'dr_required' : '').' '.$field['setting']['option']['css'].'" type="'.$type.'" name="data['.$field['fieldname'].']" id="dr_'.$field['fieldname'].'" value="'.$value.'" '.$style.' '.$required.' '.$attr.' />';
|
||||
|
||||
$options = dr_format_option_array($field['setting']['option']['options']);
|
||||
$str.= '
|
||||
<select id="editable-select-'.$name.'" class="form-control es-input '.($field['setting']['validate']['required'] ? 'dr_required' : '').' '.$field['setting']['option']['css'].'" name="data['.$field['fieldname'].']" id="dr_'.$field['fieldname'].'" value="'.$value.'" '.$style.' '.$required.' '.$attr.'></select>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
var data = '.json_encode($options).';
|
||||
$.each(data, function (i, r) {
|
||||
$("#editable-select-'.$name.'").append(\'<option>\' + r + \'</option>\');
|
||||
});
|
||||
$(\'#editable-select-'.$name.'\').editableSelect({
|
||||
effects: \'slide\',//点击的时候,下拉框的过渡效果 有default,slide,fade三个值,默认是default
|
||||
filter: false,//选择option以后,是否过滤 默认 true
|
||||
duration: \'fast\',//下拉选项框展示的过度动画速度
|
||||
});
|
||||
});
|
||||
</script>
|
||||
';
|
||||
|
||||
return $this->input_format($field['fieldname'], $text, $str.$tips);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
<?php namespace Phpcmf\Field;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
class Time extends \Phpcmf\Library\A_Field {
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
public function __construct(...$params) {
|
||||
parent::__construct(...$params);
|
||||
$this->fieldtype = ['VARCHAR' => 100];
|
||||
$this->defaulttype = 'VARCHAR';
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段相关属性参数
|
||||
*
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function option($option) {
|
||||
|
||||
return ['
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('字段格式').'</label>
|
||||
<div class="col-md-9">
|
||||
<div class="mt-radio-inline">
|
||||
<label class="mt-radio mt-radio-outline">
|
||||
<input type="radio" name="data[setting][option][format2]" value="0" '.(!$option['option']['format2'] ? 'checked' : '').'> '.dr_lang('时分格式').'
|
||||
<span></span>
|
||||
</label>
|
||||
<label class="mt-radio mt-radio-outline">
|
||||
<input type="radio" name="data[setting][option][format2]" value="1" '.($option['option']['format2'] ? 'checked' : '').'> '.dr_lang('时分秒格式').'
|
||||
<span></span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('默认存储值').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input id="field_default_value" type="text" class="form-control" size="20" value="'.$option['value'].'" name="data[setting][option][value]"></label>
|
||||
<label>'.$this->member_field_select().'</label>
|
||||
<span class="help-block">'.dr_lang('用于字段为空时显示该填充值,并不会去主动变更数据库中的实际值;可以设置会员表字段,表示用当前登录会员信息来填充这个值').'</span>
|
||||
</div>
|
||||
</div>
|
||||
'.$this->field_type($option['fieldtype'], $option['fieldlength'])
|
||||
|
||||
,
|
||||
|
||||
'
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('控件宽度').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" size="10" name="data[setting][option][width]" value="'.$option['width'].'"></label>
|
||||
<span class="help-block">'.dr_lang('[整数]表示固定宽度;[整数%]表示百分比').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('按钮颜色').'</label>
|
||||
<div class="col-md-9">
|
||||
<label>'.$this->_color_select('color', $option['color']).'</label>
|
||||
</div>
|
||||
</div>
|
||||
'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建sql语句
|
||||
*/
|
||||
public function create_sql($name, $option, $cname = '') {
|
||||
// 时间字符串:VARCHAR(100)
|
||||
$type = 'VARCHAR(100)';
|
||||
$info = 'DEFAULT NULL';
|
||||
$note = $cname ? (string)$cname : '';
|
||||
$db = $this->_db_for_field_sql();
|
||||
if ($db && method_exists($db, 'sqlAddField')) {
|
||||
return $db->sqlAddField($name, $type, $info, $note);
|
||||
}
|
||||
$tips = $note !== '' ? " COMMENT '".str_replace("'", "''", $note)."'" : '';
|
||||
return 'ALTER TABLE `{tablename}` ADD `'.$name.'` '.$type.' '.$info.$tips;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段输出
|
||||
*/
|
||||
public function output($value) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单输入
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function input($field, $value = 0) {
|
||||
|
||||
// 字段存储名称
|
||||
$name = $field['fieldname'];
|
||||
|
||||
// 字段禁止修改时就返回显示字符串
|
||||
if ($this->_not_edit($field, $value)) {
|
||||
return $this->show($field, $value);
|
||||
}
|
||||
|
||||
// 字段显示名称
|
||||
$text = ($field['setting']['validate']['required'] ? '<span class="required" aria-required="true"> * </span>' : '').dr_lang($field['name']);
|
||||
|
||||
// 表单宽度设置
|
||||
$width = \Phpcmf\Service::IS_MOBILE_USER() ? '100%' : ($field['setting']['option']['width'] ? $field['setting']['option']['width'] : 100);
|
||||
|
||||
// 风格
|
||||
$style = 'style="width:'.$width.(is_numeric($width) ? 'px' : '').';"';
|
||||
|
||||
// 表单附加参数
|
||||
$attr = $field['setting']['validate']['formattr'];
|
||||
|
||||
// 字段提示信息
|
||||
$tips = ($name == 'title' && APP_DIR) || $field['setting']['validate']['tips'] ? '<span class="help-block" id="dr_'.$field['fieldname'].'_tips">'.$field['setting']['validate']['tips'].'</span>' : '';
|
||||
|
||||
// 格式显示
|
||||
$format = (int)$field['setting']['option']['format2'] ? 'H:i:s' : 'H:i';
|
||||
// 按钮颜色
|
||||
$color = $field['setting']['option']['color'] ? $field['setting']['option']['color'] : 'default';
|
||||
|
||||
// 是否必填
|
||||
$required = $field['setting']['validate']['required'] ? ' required="required"' : '';
|
||||
|
||||
$str = '';
|
||||
if (!$this->is_load_js($field['fieldtype'])) {
|
||||
$str.= '
|
||||
<link href="'.ROOT_THEME_PATH.'assets/global/plugins/bootstrap-timepicker/css/bootstrap-timepicker.min.css?v='.CMF_UPDATE_TIME.'" rel="stylesheet" type="text/css" />
|
||||
<script src="'.ROOT_THEME_PATH.'assets/global/plugins/bootstrap-timepicker/js/bootstrap-timepicker.min.js?v='.CMF_UPDATE_TIME.'" type="text/javascript"></script>
|
||||
';
|
||||
$this->set_load_js($field['fieldtype'], 1);
|
||||
}
|
||||
|
||||
// 字段默认值
|
||||
!$value && $value = $this->get_default_value($field['setting']['option']['value']);
|
||||
if ($value == 'SYS_TIME') {
|
||||
$value = dr_date(SYS_TIME, $format);
|
||||
}
|
||||
|
||||
$str.= '<div class="input-group ">';
|
||||
$shuru = '<input name="data['.$name.']" type="text" '.$style.' value="'.$value.'" '.$required.' class="form-control timepicker field_time_'.$name.' '.$field['setting']['option']['css'].'">';
|
||||
$tubiao = '<span class="input-group-btn"><button class="btn '.$color.'" type="button">
|
||||
<i class="fa fa-clock-o"></i>
|
||||
</button>
|
||||
</span>';
|
||||
$str.= $field['setting']['option']['is_left'] ? $tubiao.$shuru : $shuru.$tubiao;
|
||||
|
||||
$str.= '</div>';
|
||||
$js = \Phpcmf\Service::L('js_packer');
|
||||
$str.= $js->pack('
|
||||
<script>
|
||||
$(function(){
|
||||
$(".field_time_'.$name.'").timepicker({
|
||||
autoclose: true,
|
||||
defaultTime:"'.($value ? $value : dr_date(SYS_TIME, $format)).'",
|
||||
minuteStep: 1,
|
||||
secondStep: 1,
|
||||
showSeconds: '.($format == 'H:i:s' ? 'true' : 'false').',
|
||||
showMeridian: false
|
||||
});
|
||||
$(".timepicker").parent(".input-group").on("click", ".input-group-btn", function(e){
|
||||
$(this).parent(".input-group").find(".timepicker").timepicker("showWidget");
|
||||
});
|
||||
$( document ).scroll(function(){
|
||||
$(".field_time_'.$name.'").timepicker("place");
|
||||
});
|
||||
});
|
||||
</script>
|
||||
', 0);
|
||||
$str.= $tips;
|
||||
|
||||
return $this->input_format($name, $text, '<div class="form-date input-group">'.$str.'</div>');
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单显示
|
||||
*
|
||||
* @param string $field 字段数组
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function show($field, $value = null) {
|
||||
|
||||
$value = (int)$field['setting']['option']['format2'] ? dr_date($value, 'Y-m-d') : dr_date($value, 'Y-m-d H:i:s');
|
||||
|
||||
return $this->input_format($field['fieldname'], $field['name'], '<div class="form-control-static"><span> '.$value.' </span></div>');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
<?php namespace Phpcmf\Field;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
class Touchspin extends \Phpcmf\Library\A_Field {
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
public function __construct(...$params) {
|
||||
parent::__construct(...$params);
|
||||
$this->fieldtype = ['INT','TINYINT','SMALLINT','MEDIUMINT','DECIMAL','FLOAT'];
|
||||
$this->defaulttype = 'INT';
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段相关属性参数
|
||||
*
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function option($option) {
|
||||
|
||||
|
||||
$style = '
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('控件宽度').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" size="10" name="data[setting][option][width]" value="'.$option['width'].'"></label>
|
||||
<span class="help-block">'.dr_lang('[整数]表示固定宽度;[整数%]表示百分比').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('显示模式').'</label>
|
||||
<div class="col-md-9">
|
||||
<input type="checkbox" name="data[setting][option][show]" '.($option['show'] ? 'checked' : '').' value="1" data-on-text="'.dr_lang('按钮').'" data-off-text="'.dr_lang('箭头').'" data-on-color="success" data-off-color="danger" class="make-switch" data-size="small">
|
||||
<span class="help-block">'.dr_lang('按钮模式是左右两个加减按钮;箭头模式是左边上下箭头符号').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('加按钮class').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" size="10" name="data[setting][option][up]" value="'.$option['up'].'"></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('减按钮class').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" size="10" name="data[setting][option][down]" value="'.$option['down'].'"></label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
';
|
||||
|
||||
|
||||
$option = '
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('最大值').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" size="10" name="data[setting][option][max]" value="'.$option['max'].'"></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('最小值').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" size="10" name="data[setting][option][min]" value="'.$option['min'].'"></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('步长值').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" size="10" name="data[setting][option][step]" value="'.$option['step'].'"></label>
|
||||
</div>
|
||||
</div>
|
||||
'.$this->field_type($option['fieldtype'], $option['fieldlength']).'
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('默认填充值').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input id="field_default_value" type="text" class="form-control" size="20" value="'.$option['value'].'" name="data[setting][option][value]"></label>
|
||||
<label>'.$this->member_field_select().'</label>
|
||||
<span class="help-block">'.dr_lang('用于字段为空时显示该填充值,并不会去主动变更数据库中的实际值;可以设置会员表字段,表示用当前登录会员信息来填充这个值').'</span>
|
||||
</div>
|
||||
</div>
|
||||
';
|
||||
|
||||
return [$option, $style];
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段入库值
|
||||
*
|
||||
* @param array $field 字段信息
|
||||
* @return void
|
||||
*/
|
||||
public function insert_value($field) {
|
||||
|
||||
// 格式化入库值
|
||||
$value = \Phpcmf\Service::L('Field')->post[$field['fieldname']];
|
||||
$value = in_array($field['setting']['option']['fieldtype'], ['DECIMAL', 'FLOAT']) ? ($value ? (float)$value : 0) : ($value ? (int)$value : 0);
|
||||
|
||||
// 最大值判断
|
||||
$field['setting']['option']['max'] && $value = min($field['setting']['option']['max'], $value);
|
||||
|
||||
// 最小值判断
|
||||
$field['setting']['option']['min'] && $value = max($field['setting']['option']['min'], $value);
|
||||
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname']] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单输入
|
||||
*
|
||||
* @param string $field 字段数组
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function input($field, $value = null) {
|
||||
|
||||
// 字段禁止修改时就返回显示字符串
|
||||
if ($this->_not_edit($field, $value)) {
|
||||
return $this->show($field, $value);
|
||||
}
|
||||
|
||||
// 字段显示名称
|
||||
$text = ($field['setting']['validate']['required'] ? '<span class="required" aria-required="true"> * </span>' : '').dr_lang($field['name']);
|
||||
|
||||
// 表单宽度设置
|
||||
$width = \Phpcmf\Service::IS_MOBILE_USER() ? '100%' : ($field['setting']['option']['width'] ? $field['setting']['option']['width'] : 200);
|
||||
|
||||
// 风格
|
||||
$style = 'style="width:'.$width.(is_numeric($width) ? 'px' : '').';"';
|
||||
|
||||
// 表单附加参数
|
||||
$attr = $field['setting']['validate']['formattr'];
|
||||
|
||||
// 字段提示信息
|
||||
$tips = $field['setting']['validate']['tips'] ? '<span class="help-block" id="dr_'.$field['fieldname'].'_tips">'.$field['setting']['validate']['tips'].'</span>' : '';
|
||||
|
||||
// 当字段必填时,加入html5验证标签
|
||||
$required = $field['setting']['validate']['required'] ? ' required="required"' : '';
|
||||
|
||||
// 按钮颜色
|
||||
$up = $field['setting']['option']['up'] ? $field['setting']['option']['up'] : 'default';
|
||||
$down = $field['setting']['option']['down'] ? $field['setting']['option']['down'] : 'default';
|
||||
|
||||
// 字段默认值
|
||||
$value = dr_strlen($value) ? $value : $this->get_default_value($field['setting']['option']['value']);
|
||||
|
||||
$str = '';
|
||||
|
||||
if (!$this->is_load_js($field['fieldtype'])) {
|
||||
$str.= '
|
||||
<link href="'.ROOT_THEME_PATH.'assets/global/plugins/bootstrap-touchspin/bootstrap.touchspin.min.css?v='.CMF_UPDATE_TIME.'" rel="stylesheet" type="text/css" />
|
||||
<script src="'.ROOT_THEME_PATH.'assets/global/plugins/fuelux/js/spinner.min.js?v='.CMF_UPDATE_TIME.'" type="text/javascript"></script>
|
||||
<script src="'.ROOT_THEME_PATH.'assets/global/plugins/bootstrap-touchspin/bootstrap.touchspin.js?v='.CMF_UPDATE_TIME.'" type="text/javascript"></script>
|
||||
';
|
||||
$this->set_load_js($field['fieldtype'], 1);
|
||||
}
|
||||
|
||||
!$field['setting']['option']['max'] && $field['setting']['option']['max'] = 999999999999999;
|
||||
!$field['setting']['option']['min'] && $field['setting']['option']['min'] = 0;
|
||||
|
||||
$str.= '<div '.$style.'><input class="form-control '.$field['setting']['option']['css'].'" type="text" name="data['.$field['fieldname'].']" id="dr_'.$field['fieldname'].'" value="'.$value.'" '.$required.' '.$attr.' /></div>';
|
||||
$js = \Phpcmf\Service::L('js_packer');
|
||||
$xs = 0;
|
||||
if (strpos($field['setting']['option']['step'], '.')) {
|
||||
list($a, $b) = explode('.', $field['setting']['option']['step']);
|
||||
$xs = dr_strlen($b);
|
||||
}
|
||||
|
||||
$str.= $js->pack('<script type="text/javascript">
|
||||
$(function(){
|
||||
$("#dr_'.$field['fieldname'].'").TouchSpin({
|
||||
buttondown_class: "btn '.$down.'",
|
||||
buttonup_class: "btn '.$up.'",
|
||||
verticalbuttons: '.(!$field['setting']['option']['show'] ? 'true' : 'false').',
|
||||
decimals: '.$xs.',
|
||||
step: '.$field['setting']['option']['step'].',
|
||||
min: '.$field['setting']['option']['min'].',
|
||||
max: '.$field['setting']['option']['max'].'
|
||||
});
|
||||
});
|
||||
</script>', 0);
|
||||
|
||||
|
||||
return $this->input_format($field['fieldname'], $text, $str.$tips);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
<?php namespace Phpcmf\Field;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
class Uid extends \Phpcmf\Library\A_Field {
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
public function __construct(...$params) {
|
||||
parent::__construct(...$params);
|
||||
$this->fieldtype = ['INT' => 10];
|
||||
$this->defaulttype = 'INT';
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段相关属性参数
|
||||
*
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function option($option) {
|
||||
|
||||
|
||||
$style = '
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('控件宽度').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" size="10" name="data[setting][option][width]" value="'.$option['width'].'"></label>
|
||||
<span class="help-block">'.dr_lang('[整数]表示固定宽度;[整数%]表示百分比').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('图标样式').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" size="10" name="data[setting][option][icon]" value="'.$option['icon'].'"></label>
|
||||
<span class="help-block">'.dr_lang('例如: fa fa-user').'</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('图标名称').'</label>
|
||||
<div class="col-md-9">
|
||||
<label><input type="text" class="form-control" size="10" name="data[setting][option][name]" value="'.$option['name'].'"></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('按钮颜色').'</label>
|
||||
<div class="col-md-9">
|
||||
<label>'.$this->_color_select('color', $option['color']).'</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-2 control-label">'.dr_lang('点击JS函数').'</label>
|
||||
<div class="col-md-9">
|
||||
<input type="text" class="form-control Large" size="10" name="data[setting][option][func]" value="'.$option['func'].'">
|
||||
<span class="help-block">'.dr_lang('单击按钮时执行的js函数').'</span>
|
||||
</div>
|
||||
</div>
|
||||
';
|
||||
|
||||
return ['', $style];
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段入库值
|
||||
*
|
||||
* @param array $field 字段信息
|
||||
* @return void
|
||||
*/
|
||||
public function insert_value($field) {
|
||||
|
||||
// 格式化入库值
|
||||
$value = \Phpcmf\Service::L('Field')->post[$field['fieldname']];
|
||||
if ($value) {
|
||||
$value = \Phpcmf\Service::M('member')->uid($value);
|
||||
}
|
||||
|
||||
\Phpcmf\Service::L('Field')->data[$field['ismain']][$field['fieldname']] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单输入
|
||||
*
|
||||
* @param string $field 字段数组
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function input($field, $value = null) {
|
||||
|
||||
// 字段禁止修改时就返回显示字符串
|
||||
if ($this->_not_edit($field, $value)) {
|
||||
return $this->show($field, $value);
|
||||
}
|
||||
|
||||
// 字段默认值
|
||||
if (dr_strlen($value)) {
|
||||
if (is_numeric($value)) {
|
||||
// 由uid获取用户名
|
||||
$user = \Phpcmf\Service::M('member')->username($value);
|
||||
if ($user) {
|
||||
$value = $user;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$value = \Phpcmf\Service::C()->member ? \Phpcmf\Service::C()->member['username'] : '';
|
||||
}
|
||||
|
||||
// 字段存储名称
|
||||
$name = $field['fieldname'];
|
||||
|
||||
// 字段显示名称
|
||||
$text = ($field['setting']['validate']['required'] ? '<span class="required" aria-required="true"> * </span>' : '').dr_lang($field['name']);
|
||||
|
||||
// 表单宽度设置
|
||||
$width = \Phpcmf\Service::IS_MOBILE_USER() ? '100%' : ($field['setting']['option']['width'] ? $field['setting']['option']['width'] : 200);
|
||||
|
||||
// 风格
|
||||
$style = 'style="width:'.$width.(is_numeric($width) ? 'px' : '').';"';
|
||||
|
||||
// 表单附加参数
|
||||
$attr = $field['setting']['validate']['formattr'];
|
||||
|
||||
// 字段提示信息
|
||||
$tips = $field['setting']['validate']['tips'] ? '<span class="help-block" id="dr_'.$field['fieldname'].'_tips">'.$field['setting']['validate']['tips'].'</span>' : '';
|
||||
|
||||
// 当字段必填时,加入html5验证标签
|
||||
$required = $field['setting']['validate']['required'] ? ' required="required"' : '';
|
||||
|
||||
// 按钮颜色
|
||||
$color = $field['setting']['option']['color'] ? $field['setting']['option']['color'] : 'default';
|
||||
|
||||
$ipt = '<input class="form-control '.$field['setting']['option']['css'].'" type="text" name="data['.$field['fieldname'].']" id="dr_'.$field['fieldname'].'" value="'.$value.'" '.$required.' '.$attr.' />';
|
||||
if (IS_ADMIN) {
|
||||
$str = '
|
||||
<div class="input-group" '.$style.'>
|
||||
'.$ipt.'
|
||||
<span class="input-group-btn">
|
||||
<a class="btn btn-success " style="border-color:'.$color.';background-color:'.$color.'" href="javascript:dr_show_member(\''.$name.'\');" ><i class="fa fa-user" /></i> '.dr_lang('资料').'</a>
|
||||
</span>
|
||||
</div>
|
||||
';
|
||||
} else {
|
||||
$str = $ipt;
|
||||
}
|
||||
|
||||
return $this->input_format($field['fieldname'], $text, $str.$tips);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段表单显示
|
||||
*
|
||||
* @param string $field 字段数组
|
||||
* @param array $value 值
|
||||
* @return string
|
||||
*/
|
||||
public function show($field, $value = null) {
|
||||
|
||||
// 字段默认值
|
||||
if ($value) {
|
||||
$value = \Phpcmf\Service::M('member')->author($value);
|
||||
} else {
|
||||
$value = \Phpcmf\Service::C()->member ? \Phpcmf\Service::C()->member['username'] : '';
|
||||
}
|
||||
|
||||
$str = '<div class="form-control-static"> '.htmlspecialchars_decode((string)$value).' </div>';
|
||||
|
||||
return $this->input_format($field['fieldname'], $field['name'], $str);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,666 @@
|
||||
<?php
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件
|
||||
*
|
||||
* (c) 北斯云
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
**/
|
||||
|
||||
// CMS框架目录
|
||||
if (!defined('FRAMEPATH')) {
|
||||
$frame = 'System';
|
||||
if (is_file(WRITEPATH.'frame.lock')) {
|
||||
$name = (string)file_get_contents(WRITEPATH.'frame.lock');
|
||||
if (is_file(FCPATH.$name.'/Init.php')) {
|
||||
$frame = $name;
|
||||
}
|
||||
}
|
||||
// 低版本兼容
|
||||
if ($frame == 'System' && version_compare(PHP_VERSION, '8.0') < 0 && is_file(FCPATH.'CodeIgniter/Init.php')) {
|
||||
$frame = 'CodeIgniter';
|
||||
} elseif ($frame == 'System' && version_compare(PHP_VERSION, '7.4') < 0 && is_file(FCPATH.'CodeIgniter72/Init.php')) {
|
||||
$frame = 'CodeIgniter72';
|
||||
}
|
||||
define('FRAMEPATH', FCPATH.$frame.'/');
|
||||
}
|
||||
|
||||
// CMS公共程序目录
|
||||
!defined('CMSPATH') && define('CMSPATH', FCPATH.'Fcms/');
|
||||
!defined('MAX_CATEGORY') && define('MAX_CATEGORY', 300); // 老版本
|
||||
define('COREPATH', CMSPATH); // 老版本别名
|
||||
define('BASEPATH', FRAMEPATH.'System/'); // 老版本别名
|
||||
// 主配置目录
|
||||
!defined('CONFIGPATH') && define('CONFIGPATH', ROOTPATH.'config/');
|
||||
// App程序目录
|
||||
!defined('APPSPATH') && define('APPSPATH', FCPATH.'App/');
|
||||
// 程序初始化
|
||||
!defined('MYPATH') && define('MYPATH', FCPATH.'My/');
|
||||
// 定义模板目录
|
||||
!defined('TPLPATH') && define('TPLPATH', dirname(FCPATH).'/template/');
|
||||
// 是否可编辑后模板
|
||||
!defined('IS_EDIT_TPL') && define('IS_EDIT_TPL', 0);
|
||||
// 是否启用高级开发模式
|
||||
!defined('IS_XRDEV') && define('IS_XRDEV', 0);
|
||||
// 定义移动端模板目录
|
||||
!defined('MOBILE_TPL_DIR') && define('MOBILE_TPL_DIR', 'mobile');
|
||||
// 编辑器的图片的title和alt默认占位字符
|
||||
!defined('UEDITOR_IMG_TITLE') && define('UEDITOR_IMG_TITLE', '{cms_img_title}');
|
||||
// tests
|
||||
define('TESTPATH', WRITEPATH.'tests/');
|
||||
// temp目录
|
||||
define('TEMPPATH', CMSPATH.'Temp/');
|
||||
// COMPOSER文件
|
||||
!defined('COMPOSER_PATH') && define('COMPOSER_PATH', is_file(FCPATH . 'Vendor/autoload.php') ? FCPATH . 'Vendor/autoload.php' : (is_file(FCPATH . 'vendor/autoload.php') ? FCPATH . 'vendor/autoload.php' : ROOTPATH . 'vendor/autoload.php'));
|
||||
// 是否来自ajax提交
|
||||
define('IS_AJAX', (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest'));
|
||||
// 是否来自post提交
|
||||
define('IS_POST', isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] == 'POST' ? TRUE : FALSE);
|
||||
define('IS_AJAX_POST', IS_POST);
|
||||
// 当前系统时间戳
|
||||
define('SYS_TIME', $_SERVER['REQUEST_TIME'] ? $_SERVER['REQUEST_TIME'] : time());
|
||||
|
||||
// 自定义函数库
|
||||
if (is_file(WEBPATH.'config/custom.php')) {
|
||||
require WEBPATH.'config/custom.php';
|
||||
} elseif (is_file(CONFIGPATH.'custom.php')) {
|
||||
require CONFIGPATH.'custom.php';
|
||||
}
|
||||
if (is_file(MYPATH.'Helper.php')) {
|
||||
require MYPATH.'Helper.php';
|
||||
}
|
||||
|
||||
// 系统变量
|
||||
$system = [
|
||||
'SYS_DEBUG' => 0,
|
||||
'SYS_ADMIN_CODE' => 0,
|
||||
'SYS_ADMIN_LOG' => 0,
|
||||
'SYS_AUTO_FORM' => 0,
|
||||
'SYS_ADMIN_PAGESIZE' => 10,
|
||||
'SYS_CRON_AUTH' => '',
|
||||
'SYS_TABLE_ISFOOTER' => 0,
|
||||
'SYS_SMS_IMG_CODE' => 0,
|
||||
'SYS_GO_404' => 0,
|
||||
'SYS_THEME_ROOT_PATH' => 0,
|
||||
'SYS_301' => 0,
|
||||
'SYS_NOT_UPDATE' => 0,
|
||||
'SYS_URL_ONLY' => 0,
|
||||
'SYS_URL_REL' => 0,
|
||||
'SYS_KEY' => 'xunruicms',
|
||||
'SYS_API_TOKEN' => '',
|
||||
'SYS_CSRF' => 1,
|
||||
'SYS_CSRF_TIME' => 0,
|
||||
'SYS_API_REL' => 0,
|
||||
'SYS_HTTPS' => 0,
|
||||
'SYS_NOT_ADMIN_CACHE' => 1,
|
||||
'SYS_ADMIN_MODE' => 0,
|
||||
'SYS_ADMIN_LOGINS' => 0,
|
||||
'SYS_ADMIN_LOGIN_AES' => 0,
|
||||
'SYS_ATTACHMENT_DOWN_REMOTE' => 0,
|
||||
'SYS_ATTACHMENT_DOWN_SIZE' => 50,
|
||||
'SYS_ADMIN_LOGIN_TIME' => 0,
|
||||
'SYS_LOGIN_AES' => 0,
|
||||
'SYS_ADMIN_OAUTH' => 0,
|
||||
'SYS_ADMIN_SMS_LOGIN' => 0,
|
||||
'SYS_ADMIN_SMS_CHECK' => 0,
|
||||
'SYS_ATTACHMENT_DB' => 1,
|
||||
'SYS_ATTACHMENT_PAGESIZE' => 36,
|
||||
'SYS_ATTACHMENT_GUEST' => 0,
|
||||
'SYS_ATTACHMENT_CF' => 0,
|
||||
'SYS_ATTACHMENT_REL' => 0,
|
||||
'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_CODE' => '',
|
||||
'SYS_ATTACHMENT_SAFE' => '',
|
||||
];
|
||||
if (is_file(WRITEPATH.'config/system.php')) {
|
||||
$my = require WRITEPATH.'config/system.php';
|
||||
} else {
|
||||
$my = [];
|
||||
}
|
||||
|
||||
// 强制禁用301
|
||||
if (defined('IS_NOT_301') && IS_NOT_301) {
|
||||
$my['SYS_301'] = 1;
|
||||
}
|
||||
|
||||
foreach ($system as $var => $value) {
|
||||
if (!defined($var)) {
|
||||
define($var, isset($my[$var]) ? $my[$var] : $value);
|
||||
}
|
||||
}
|
||||
unset($my, $system);
|
||||
|
||||
!defined('IS_ADMIN_CACHE') && define('IS_ADMIN_CACHE', '1'); // 已废弃
|
||||
!defined('SQGS') && define('SQGS', '迅睿开源框架');
|
||||
!defined('CI_DEBUG') && define('CI_DEBUG', IS_DEV ? true : IS_ADMIN && SYS_DEBUG);
|
||||
!defined('IS_FB_DEBUG') && define('IS_FB_DEBUG', CI_DEBUG ? 0 : 1);
|
||||
|
||||
// 显示错误提示
|
||||
IS_ADMIN || IS_DEV ? error_reporting(E_ALL ^ E_NOTICE ^ E_WARNING ^ E_DEPRECATED) : error_reporting(0);
|
||||
|
||||
// 显示错误提示
|
||||
if (CI_DEBUG) {
|
||||
ini_set('display_errors', 1);
|
||||
// 重置Zend OPcache
|
||||
function_exists('opcache_reset') && opcache_reset();
|
||||
define('ENVIRONMENT', 'development');
|
||||
} else {
|
||||
ini_set('display_errors', 0);
|
||||
!defined('ENVIRONMENT') && define('ENVIRONMENT', 'production');
|
||||
}
|
||||
|
||||
// 缓存变量
|
||||
$cache = [];
|
||||
if (is_file(WRITEPATH.'config/cache.php')) {
|
||||
$cache = require WRITEPATH.'config/cache.php';
|
||||
IS_DEV && $cache['SYS_CACHE'] = 0; // 开发者模式下关闭缓存
|
||||
}
|
||||
foreach ([
|
||||
'SYS_CACHE',
|
||||
'SYS_CACHE_TYPE',
|
||||
'SYS_CACHE_SHOW',
|
||||
'SYS_CACHE_LIST',
|
||||
'SYS_CACHE_SEARCH',
|
||||
'SYS_CACHE_SMS',
|
||||
'SYS_CACHE_CRON',
|
||||
'SYS_CACHE_CLEAR',
|
||||
] as $name) {
|
||||
define($name, isset($cache[$name]) ? floatval($cache[$name]) : 0);
|
||||
}
|
||||
unset($cache);
|
||||
|
||||
// 自定义开发目录分布
|
||||
if (IS_XRDEV) {
|
||||
require MYPATH.'Dev.php';
|
||||
} else {
|
||||
|
||||
// 判断是否是app目录
|
||||
function dr_is_app_dir($name) {
|
||||
if (!$name) {
|
||||
return false;
|
||||
} elseif ($name == 'module') {
|
||||
$name = 'cms';
|
||||
}
|
||||
return is_dir(APPSPATH.ucfirst($name));
|
||||
}
|
||||
|
||||
// 获取指定app目录
|
||||
function dr_get_app_dir($name) {
|
||||
if (!$name) {
|
||||
return false;
|
||||
} elseif ($name == 'module') {
|
||||
$name = 'cms';
|
||||
}
|
||||
return APPSPATH.ucfirst($name).'/';
|
||||
}
|
||||
|
||||
// 获取模板目录
|
||||
function dr_get_app_tpl($name = '') {
|
||||
return TPLPATH;
|
||||
}
|
||||
|
||||
// 获取app目录
|
||||
function dr_get_app_list() {
|
||||
return APPSPATH;
|
||||
}
|
||||
|
||||
// 获取app的css地址
|
||||
function dr_get_app_css($name) {
|
||||
if ($name == 'module') {
|
||||
$name = 'cms';
|
||||
}
|
||||
return (defined('THEME_PATH') ? THEME_PATH : '/static/').$name.'/';
|
||||
}
|
||||
|
||||
// 获取app的css目录
|
||||
function dr_get_app_css_dir($name) {
|
||||
if ($name == 'module') {
|
||||
$name = 'cms';
|
||||
}
|
||||
return WEBPATH.'static/'.$name.'/';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 重写日志记录函数
|
||||
*/
|
||||
function log_message($level, $message, array $context = []) {
|
||||
return \Phpcmf\Service::Log($level, $message, $context);
|
||||
}
|
||||
|
||||
// 兼容错误提示
|
||||
function dr_show_error($msg, $dev = '') {
|
||||
|
||||
if (CI_DEBUG) {
|
||||
$log = 'ERROR - '.date('Y-m-d H:i:s'). ' --> '.$msg . '('.FC_NOW_URL.')';
|
||||
$file = WRITEPATH . 'error/log-'.date('Y-m-d').'.php';
|
||||
if (!is_file($file)) {
|
||||
file_put_contents($file, "<?php if (!defined('BASEPATH')) exit('No direct script access allowed');?>".PHP_EOL.$log);
|
||||
} else {
|
||||
file_put_contents($file, $log.PHP_EOL, FILE_APPEND);
|
||||
}
|
||||
}
|
||||
|
||||
if ($dev && !CI_DEBUG) {
|
||||
$msg = $dev;
|
||||
}
|
||||
|
||||
if (!IS_ADMIN) {
|
||||
// 前端不显示错误详情
|
||||
if (CI_DEBUG) {
|
||||
$url = '<p>'.FC_NOW_URL.'</p>';
|
||||
} else {
|
||||
$url = '<p>在index.php中开启开发者模式可以看到故障详细情况</p>';
|
||||
$msg = '您的系统遇到了故障,请联系管理员处理';
|
||||
http_response_code(404);
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_AJAX) {
|
||||
$msg = json_encode([
|
||||
'code' => 0,
|
||||
'msg' => $msg
|
||||
],JSON_UNESCAPED_UNICODE);
|
||||
if (isset($_GET['callback']) && $_GET['callback']) {
|
||||
echo $_GET['callback'].'('.$msg.')';exit;
|
||||
} else {
|
||||
echo $msg;exit;
|
||||
}
|
||||
} else {
|
||||
exit("<!DOCTYPE html><html lang=\"zh-cn\"><head><meta charset=\"utf-8\"><title>系统错误</title><style> div.logo { height: 200px; width: 155px; display: inline-block; opacity: 0.08; position: absolute; top: 2rem; left: 50%; margin-left: -73px; } body { height: 100%; background: #fafafa; font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif; color: #777; font-weight: 300; } h1 { font-weight: lighter; letter-spacing: 0.8; font-size: 3rem; margin-top: 0; margin-bottom: 0; color: #222; } .wrap { max-width: 1024px; margin: 5rem auto; padding: 2rem; background: #fff; text-align: center; border: 1px solid #efefef; border-radius: 0.5rem; position: relative; } pre { white-space: normal; margin-top: 1.5rem; } code { background: #fafafa; border: 1px solid #efefef; padding: 0.5rem 1rem; border-radius: 5px; display: block; } p { margin-top: 1.5rem; } .footer { margin-top: 2rem; border-top: 1px solid #efefef; padding: 1em 2em 0 2em; font-size: 85%; color: #999; } a:active, a:link, a:visited { color: #dd4814; }</style></head><body><div class=\"wrap\"><p>{$msg}</p>{$url}</div></body></html>");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 全局返回消息
|
||||
*/
|
||||
function dr_exit_msg($code, $msg, $data = [], $token = []) {
|
||||
|
||||
if (!CI_DEBUG) {
|
||||
ob_end_clean();
|
||||
}
|
||||
|
||||
$rt = [
|
||||
'code' => $code,
|
||||
'msg' => $msg,
|
||||
'data' => $data,
|
||||
'token' => $token,
|
||||
];
|
||||
|
||||
if (isset($_GET['callback'])) {
|
||||
// jsonp
|
||||
header('HTTP/1.1 200 OK');
|
||||
log_message('error', $msg . '('.FC_NOW_URL.')');
|
||||
echo ($_GET['callback'] ? $_GET['callback'] : 'callback').'('.json_encode($rt, JSON_UNESCAPED_UNICODE).')';
|
||||
} else if (($_GET['is_ajax'] || (defined('IS_API_HTTP') && IS_API_HTTP) || IS_AJAX)) {
|
||||
// json
|
||||
header('HTTP/1.1 200 OK');
|
||||
log_message('error', $msg . '('.FC_NOW_URL.')');
|
||||
echo json_encode($rt, JSON_UNESCAPED_UNICODE);
|
||||
} else {
|
||||
// html
|
||||
dr_show_error($msg);
|
||||
}
|
||||
exit;
|
||||
}
|
||||
|
||||
/*
|
||||
* 伪静态中获取uri
|
||||
*/
|
||||
if (!function_exists('dr_get_rewrite_uri')) {
|
||||
function dr_get_rewrite_uri($uu) {
|
||||
// 以index.php或者?开头的uri不做处理
|
||||
return strpos($uu, SELF) === 0 || strpos($uu, '?') === 0 ? '' : $uu;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 读取伪静态路由储存路径
|
||||
*/
|
||||
function dr_rewrite_routes_path($uri) {
|
||||
$uri = trim($uri, '/');
|
||||
$path = WRITEPATH . 'route/'.(defined('SITE_ID') ? SITE_ID : 1).'/'; // 路由缓存根目录
|
||||
$hash = md5($uri); // 用MD5做均匀散列(核心:解决目录拥挤)
|
||||
$dir1 = substr($hash, 0, 2); // 一级目录
|
||||
$dir2 = substr($hash, 2, 2); // 二级目录
|
||||
$save = $path . '/' . $dir1 . '/' . $dir2; // 最终目录
|
||||
return [$save, $hash];
|
||||
}
|
||||
|
||||
/*
|
||||
* 读取伪静态路由文件
|
||||
*/
|
||||
function dr_get_rewrite_routes($uri) {
|
||||
if (!$uri) {
|
||||
return '';
|
||||
}
|
||||
if (SYS_301 || !SYS_URL_ONLY) {
|
||||
// 自由参数或模糊匹配
|
||||
list($uri, $query) = explode('?', $uri);
|
||||
}
|
||||
$uri = urldecode($uri);
|
||||
// uri中存在分页参数,则替换为{page}
|
||||
if (preg_match_all('/\d+/', $uri, $m, PREG_OFFSET_CAPTURE)) {
|
||||
// 倒序数组
|
||||
$nums = array_reverse($m[0]);
|
||||
foreach ($nums as $p) {
|
||||
list($save, $hash) = dr_rewrite_routes_path(str_replace($p[0], '{page}', $uri));
|
||||
$file = $save . '/' . $hash . '.txt';
|
||||
if (is_file($file)) {
|
||||
return str_replace('{page}', $p[0], (string)file_get_contents($file));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
list($save, $hash) = dr_rewrite_routes_path($uri);
|
||||
if (!is_dir($save)) {
|
||||
mkdir($save, 0755, true);
|
||||
}
|
||||
$file = $save . '/' . $hash . '.txt';
|
||||
if (is_file($file)) {
|
||||
return file_get_contents($file);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/*
|
||||
* 储存伪静态路由文件
|
||||
*/
|
||||
function dr_save_rewrite_routes($uri, $routes) {
|
||||
if (!$uri || !$routes) {
|
||||
return '';
|
||||
}
|
||||
$uri = trim($uri, '/');
|
||||
$uri = urldecode($uri);
|
||||
$routes = urldecode($routes);
|
||||
$uri = str_replace(['[page]', '%7Bpage%7D', '%5Bpage%5D', '%7bpage%7d', '%5bpage%5d'], '{page}', $uri);
|
||||
$routes = str_replace(['[page]', '%7Bpage%7D', '%5Bpage%5D', '%7bpage%7d', '%5bpage%5d'], '{page}', $routes);
|
||||
list($save, $hash) = dr_rewrite_routes_path($uri);
|
||||
if (!is_dir($save)) {
|
||||
mkdir($save, 0755, true);
|
||||
}
|
||||
file_put_contents($save . '/' . $hash . '.txt', $routes);
|
||||
}
|
||||
|
||||
/*
|
||||
* 删除伪静态路由文件
|
||||
*/
|
||||
function dr_del_rewrite_routes($uri) {
|
||||
$uri = trim($uri, '/');
|
||||
list($save, $hash) = dr_rewrite_routes_path($uri);
|
||||
$file = $save . '/' . $hash . '.txt';
|
||||
if (is_file($file)) {
|
||||
@unlink($file);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* 函数是否被启用
|
||||
*/
|
||||
if (!function_exists('locale_set_default')) {
|
||||
function locale_set_default($a) { }
|
||||
}
|
||||
|
||||
/*
|
||||
* url后缀参数格式化
|
||||
*/
|
||||
function dr_url_safe_params($url) {
|
||||
|
||||
if (!$url) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
// 移除所有非URL合法字符
|
||||
$url = preg_replace('/[^a-zA-Z0-9\%:\/?#\[\]@!$&\'()*+,;=._~-]/', '', $url);
|
||||
// 移除JavaScript事件处理器
|
||||
$url = preg_replace('/on\w+\s*=/i', '', $url);
|
||||
// 移除HTML标签
|
||||
$url = strip_tags($url);
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/*
|
||||
* 重写is_cli
|
||||
*/
|
||||
function is_cli(): bool {
|
||||
if (stripos(PHP_SAPI, 'cli') !== false || defined('STDIN')) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// 是否使用建站系统
|
||||
define('IS_USE_CMS', is_file(dr_get_app_dir('cms').'/install.lock') ? dr_get_app_dir('cms') : '');
|
||||
define('IS_USE_MODULE', IS_USE_CMS);
|
||||
// 是否使用用户系统
|
||||
define('IS_USE_MEMBER', is_file(dr_get_app_dir('member').'/install.lock') ? dr_get_app_dir('member') : '');
|
||||
|
||||
if (is_cli()) {
|
||||
// CLI命令行模式
|
||||
define('ADMIN_URL', 'http://localhost/');
|
||||
define('FC_NOW_URL', 'http://localhost/');
|
||||
define('FC_NOW_HOST', 'http://localhost/');
|
||||
define('DOMAIN_NAME', 'http://localhost/');
|
||||
define('WEB_DIR', '/');
|
||||
if ($_SERVER["argv"]) {
|
||||
foreach ($_SERVER["argv"] as $val) {
|
||||
if (strpos($val, '=') !== false) {
|
||||
list($name) = explode('=', $val);
|
||||
$_GET[$name] = substr($val, strlen($name)+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 正常访问模式
|
||||
// 当前URL
|
||||
$url = 'http';
|
||||
if ((!IS_ADMIN && isset($system['SYS_HTTPS']) && $system['SYS_HTTPS'])
|
||||
|| (defined('IS_HTTPS_FIX') && IS_HTTPS_FIX)
|
||||
|| (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on')
|
||||
|| (isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == '443')
|
||||
|| (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')
|
||||
|| (isset($_SERVER['HTTP_FROM_HTTPS']) && $_SERVER['HTTP_FROM_HTTPS'] == 'on')
|
||||
|| (!empty($_SERVER['HTTP_FRONT_END_HTTPS']) && strtolower($_SERVER['HTTP_FRONT_END_HTTPS']) != 'off')
|
||||
) {
|
||||
$url.= 's';
|
||||
}
|
||||
$host = strtolower($_SERVER['HTTP_HOST']);
|
||||
if (defined('IS_PORT_FIX') && IS_PORT_FIX && strpos($host, ':') === false) {
|
||||
// 端口修复
|
||||
$host.= ':'.IS_PORT_FIX;
|
||||
} elseif (strpos($host, ':') !== false) {
|
||||
list($nhost, $port) = explode(':', $host);
|
||||
if ($port == 80) {
|
||||
$host = $nhost; // 排除80端口
|
||||
}
|
||||
}
|
||||
|
||||
$url.= '://'.$host;
|
||||
IS_ADMIN && define('ADMIN_URL', $url.'/'); // 优先定义后台域名
|
||||
// url后缀参数
|
||||
$end = ($_SERVER['REQUEST_URI'] ? $_SERVER['REQUEST_URI'] : (isset($_SERVER['QUERY_STRING']) && $_SERVER['QUERY_STRING'] ? $_SERVER['PHP_SELF'].'?'.$_SERVER['QUERY_STRING'] : $_SERVER['PHP_SELF']));
|
||||
define('FC_NOW_URL', $url.dr_url_safe_params($end));
|
||||
define('FC_NOW_HOST', $url.'/'); // 域名部分
|
||||
define('DOMAIN_NAME', $host); // 当前域名
|
||||
|
||||
// 伪静态字符串
|
||||
$uu = isset($_SERVER['HTTP_X_REWRITE_URL']) || trim($_SERVER['REQUEST_URI'], '/') == SELF ? trim($_SERVER['HTTP_X_REWRITE_URL'], '/') : ($_SERVER['REQUEST_URI'] ? trim($_SERVER['REQUEST_URI'], '/') : NULL);
|
||||
if (defined('FIX_WEB_DIR') && FIX_WEB_DIR && strpos($uu, FIX_WEB_DIR) !== false && strpos($uu, FIX_WEB_DIR) === 0) {
|
||||
$uu = trim(substr($uu, strlen(FIX_WEB_DIR)), '/');
|
||||
define('WEB_DIR', '/'.trim(FIX_WEB_DIR, '/').'/');
|
||||
} else {
|
||||
define('WEB_DIR', '/');
|
||||
}
|
||||
|
||||
// 当前URI
|
||||
$uri = dr_get_rewrite_uri($uu);
|
||||
define('CMSURI', $uri);
|
||||
|
||||
// 根据自定义URL规则来识别路由
|
||||
if (!IS_ADMIN && CMSURI && !defined('IS_API') && !defined('FIX_WEB_URL')) {
|
||||
|
||||
// 读取伪静态路由文件
|
||||
$rcache = dr_get_rewrite_routes(CMSURI);
|
||||
if ($rcache) {
|
||||
$routes = [
|
||||
CMSURI => $rcache,
|
||||
];
|
||||
} else {
|
||||
// 自定义URL解析规则
|
||||
$routes = [];
|
||||
$routes['index\.html(.*)'] = 'index.php?c=home&m=index';
|
||||
$routes['404\.html(.*)'] = 'index.php?&c=home&m=s404&uri='.CMSURI;
|
||||
$routes['cms-license(.*)'] = 'index.php?s=api&c=rewrite&m=license';
|
||||
$routes['rewrite-test.html(.*)'] = 'index.php?s=api&c=rewrite&m=test';
|
||||
if (is_file(WEBPATH.'config/rewrite.php')) {
|
||||
$my = require WEBPATH.'config/rewrite.php';
|
||||
if ($my && is_array($my)) {
|
||||
$routes = array_merge($routes, $my);
|
||||
}
|
||||
} elseif (is_file(CONFIGPATH.'rewrite.php')) {
|
||||
$my = require CONFIGPATH.'rewrite.php';
|
||||
if ($my && is_array($my)) {
|
||||
$routes = array_merge($routes, $my);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 正则匹配路由规则
|
||||
$is_404 = 1;
|
||||
foreach ($routes as $key => $val) {
|
||||
$rewrite = $match = []; //(defined('SYS_URL_PREG') && SYS_URL_PREG ? '' : '$')
|
||||
if ($key == CMSURI || preg_match('/^'.$key.'$/U', CMSURI, $match)) {
|
||||
unset($match[0]);
|
||||
// 开始匹配
|
||||
$is_404 = 0;
|
||||
// 开始解析路由 URL参数模式
|
||||
$_GET = [];
|
||||
$queryParts = explode('&', str_replace(['index.php?', '/index.php?'], '', $val));
|
||||
if ($queryParts) {
|
||||
foreach ($queryParts as $param) {
|
||||
$item = explode('=', $param);
|
||||
$_GET[$item[0]] = $item[1];
|
||||
if (strpos($item[1], '$') !== FALSE) {
|
||||
$id = (int)substr($item[1], 1);
|
||||
$_GET[$item[0]] = isset($match[$id]) ? $match[$id] : $item[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
!$_GET['c'] && $_GET['c'] = 'home';
|
||||
!$_GET['m'] && $_GET['m'] = 'index';
|
||||
// 结束匹配
|
||||
break;
|
||||
}
|
||||
}
|
||||
// 说明是404
|
||||
if ($is_404) {
|
||||
$_GET['s'] = '';
|
||||
$_GET['c'] = 'home';
|
||||
$_GET['m'] = 's404';
|
||||
$_GET['uri'] = CMSURI;
|
||||
}
|
||||
}
|
||||
// 自定义路由模式
|
||||
if (is_file(WEBPATH.'config/router.php')) {
|
||||
require WEBPATH.'config/router.php';
|
||||
} elseif (is_file(CONFIGPATH.'router.php')) {
|
||||
require CONFIGPATH.'router.php';
|
||||
}
|
||||
}
|
||||
|
||||
!defined('CMSURI') && define('CMSURI', '');
|
||||
|
||||
// API接口项目标识 放到后面是为了识别api 的伪静态
|
||||
!defined('IS_API') && define('IS_API', isset($_GET['s']) && $_GET['s'] == 'api');
|
||||
|
||||
// 解析自定义域名
|
||||
if (!IS_API && $_GET['s'] != 'api' && is_file(WRITEPATH.'config/domain_app.php')){
|
||||
$domain = require WRITEPATH.'config/domain_app.php';
|
||||
// 强制定义为模块
|
||||
if (isset($domain[DOMAIN_NAME]) && $domain[DOMAIN_NAME] && is_dir(APPSPATH.ucfirst($domain[DOMAIN_NAME]))) {
|
||||
$_GET['s'] = $domain[DOMAIN_NAME];
|
||||
}
|
||||
unset($domain);
|
||||
}
|
||||
|
||||
// 自定义入口执行
|
||||
if (function_exists('cms_init')) {
|
||||
cms_init();
|
||||
}
|
||||
|
||||
// 判断自定义首页入口
|
||||
if (defined('CMSURI')
|
||||
&& !CMSURI && !IS_ADMIN
|
||||
&& !IS_API && !isset($_GET['s'])
|
||||
&& is_file(WRITEPATH.'index.lock')
|
||||
) {
|
||||
$index = file_get_contents(WRITEPATH.'index.lock');
|
||||
if ($index) {
|
||||
list($a, $b, $c) = explode('/', trim($index));
|
||||
if ($a && dr_is_app_dir($a) && $b && $c) {
|
||||
$_GET['s'] = $a;
|
||||
$_GET['c'] = trim($b);
|
||||
$_GET['m'] = trim($c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_USE_CMS && isset($_GET['s']) && $_GET['s'] == 'module') {
|
||||
$_GET['s'] = 'cms';
|
||||
}
|
||||
|
||||
// 判断s参数,“应用程序”文件夹目录
|
||||
if (!IS_API && isset($_GET['s']) && preg_match('/^[a-z_]+$/i', $_GET['s'])) {
|
||||
// 判断会员模块,排除后台调用
|
||||
$dir = ucfirst($_GET['s']);
|
||||
if (!IS_ADMIN && $dir == 'Member') {
|
||||
// 用户系统
|
||||
if (!IS_USE_MEMBER) {
|
||||
dr_show_error('用户系统插件未安装', '无权限使用用户系统');
|
||||
}
|
||||
if ($_GET['app'] && dr_is_app_dir($_GET['app'])) {
|
||||
// 模块应用
|
||||
define('APPPATH', dr_get_app_dir($_GET['app']));
|
||||
define('APP_DIR', strtolower($_GET['app'])); // 应用目录名称
|
||||
} else {
|
||||
// 表示会员模块
|
||||
define('APPPATH', IS_USE_MEMBER);
|
||||
define('APP_DIR', 'member'); // 模块目录名称
|
||||
}
|
||||
define('IS_MEMBER', TRUE);
|
||||
} elseif (dr_is_app_dir($dir)) {
|
||||
// 模块应用
|
||||
define('APPPATH', dr_get_app_dir($dir));
|
||||
define('APP_DIR', strtolower($dir)); // 应用目录名称
|
||||
define('IS_MEMBER', FALSE);
|
||||
} else {
|
||||
// 不存在的应用
|
||||
dr_show_error('应用程序('.dr_get_app_dir($dir).')不存在', '应用程序('.strtolower($dir).')不存在');
|
||||
}
|
||||
} else {
|
||||
// 系统主目录
|
||||
!defined('APPPATH') && define('APPPATH', FRAMEPATH);
|
||||
!defined('APP_DIR') && define('APP_DIR', '');
|
||||
define('IS_MEMBER', FALSE);
|
||||
}
|
||||
|
||||
// 是否前端
|
||||
define('IS_HOME', !IS_ADMIN && !IS_MEMBER);
|
||||
|
||||
// 系统函数库
|
||||
require CMSPATH.'Core/Helper.php';
|
||||
|
||||
// 进入系统框架加载
|
||||
require FRAMEPATH.'Init.php';
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,295 @@
|
||||
<?php namespace Phpcmf\Library;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
|
||||
/**
|
||||
* cms缓存
|
||||
*/
|
||||
|
||||
class Cache {
|
||||
|
||||
private $cache;
|
||||
|
||||
// 文件缓存目录
|
||||
private $file_dir;
|
||||
|
||||
// 认证数据缓存目录
|
||||
private $auth_dir;
|
||||
|
||||
// 缓存临时数据
|
||||
private $data = [];
|
||||
|
||||
/**
|
||||
* 构造函数,初始化变量
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->file_dir = WRITEPATH.'data/'; // 设置缓存目录
|
||||
$this->auth_dir = WRITEPATH.'authcode/'; // 认证数据缓存目录
|
||||
}
|
||||
|
||||
/**
|
||||
* 分析缓存文件名
|
||||
*/
|
||||
private function parse_cache_file($file_name, $cache_dir = null) {
|
||||
return ($cache_dir ? WRITEPATH.$cache_dir.'/' : $this->file_dir).$file_name.'.cache';
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置缓存目录
|
||||
*/
|
||||
public function init_file($dir) {
|
||||
$this->file_dir = WRITEPATH.trim($dir, '/').'/'; // 设置缓存目录
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置缓存
|
||||
*/
|
||||
public function set_file($key, $value, $cache_dir = null) {
|
||||
|
||||
if (dr_is_empty($key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$cache_file = self::parse_cache_file(strtolower($key), $cache_dir); // 分析缓存文件
|
||||
$value = dr_array2string($value); // 分析缓存内容
|
||||
|
||||
// 分析缓存目录
|
||||
$cache_dir = ($cache_dir ? WRITEPATH.$cache_dir.'/' : $this->file_dir);
|
||||
!is_dir($cache_dir) && dr_mkdirs($cache_dir, 0777);
|
||||
|
||||
// 重置Zend OPcache
|
||||
function_exists('opcache_reset') && opcache_reset();
|
||||
$rt = file_put_contents($cache_file, $value, LOCK_EX);
|
||||
|
||||
if ($rt === false) {
|
||||
log_message('error', '缓存文件['.$cache_file.']无法写入');
|
||||
}
|
||||
|
||||
return $rt ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取一个已经缓存的变量
|
||||
*/
|
||||
public function get_file($key, $cache_dir = null, $is_cache = true) {
|
||||
|
||||
if (dr_is_empty($key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$cache_file = self::parse_cache_file(strtolower($key), $cache_dir); // 分析缓存文件
|
||||
if (!isset($this->data[$cache_file]) || !$is_cache) {
|
||||
if (is_file($cache_file)) {
|
||||
$code = file_get_contents($cache_file);
|
||||
$json = json_decode($code, true);
|
||||
if ($code && !$json) {
|
||||
$json = $code;
|
||||
}
|
||||
$this->data[$cache_file] = $json;
|
||||
} else {
|
||||
$this->data[$cache_file] = false;
|
||||
#log_message('debug', '缓存文件['.$cache_file.']不存在');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $this->data[$cache_file];
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除缓存
|
||||
*
|
||||
* @param string $key
|
||||
* @return void
|
||||
*/
|
||||
public function del_file($key, $cache_dir = null) {
|
||||
|
||||
if (dr_is_empty($key)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$cache_file = self::parse_cache_file(strtolower($key), $cache_dir); // 分析缓存文件
|
||||
|
||||
return is_file($cache_file) ? unlink($cache_file) : true;
|
||||
}
|
||||
|
||||
// 删除全部文件缓存
|
||||
public function del_all($dir = 'data') {
|
||||
|
||||
!$dir && $dir = 'data';
|
||||
$path = WRITEPATH.$dir.'/';
|
||||
|
||||
dr_dir_delete($path);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------------
|
||||
|
||||
// 存储内容
|
||||
public function set_auth_data($name, $value, $siteid = SITE_ID) {
|
||||
|
||||
// 重置Zend OPcache
|
||||
function_exists('opcache_reset') && opcache_reset();
|
||||
|
||||
dr_mkdirs($this->auth_dir);
|
||||
|
||||
file_put_contents($this->auth_dir.md5($siteid.$name), is_array($value) ? dr_array2string($value) : $value, LOCK_EX);
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
// 获取内容
|
||||
public function get_auth_data($name, $siteid = SITE_ID, $time = 0) {
|
||||
|
||||
$code_file = $this->auth_dir.md5($siteid.$name);
|
||||
if (is_file($code_file)) {
|
||||
if ($time) {
|
||||
$ft = filemtime($code_file);
|
||||
if ($ft) {
|
||||
$st = SYS_TIME - $ft;
|
||||
if ($st > $time) {
|
||||
unlink($code_file);
|
||||
log_message('debug', '缓存('.$name.')自动失效('.dr_now_url().')超时: '.$st.'秒');
|
||||
return ''; // 超出了指定的时间时
|
||||
}
|
||||
}
|
||||
}
|
||||
$rt = file_get_contents($code_file);
|
||||
if ($rt) {
|
||||
$arr = dr_string2array($rt);
|
||||
if (is_array($arr)) {
|
||||
return $arr;
|
||||
}
|
||||
return $rt;
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
// 删除内容
|
||||
public function del_auth_data($name, $siteid = SITE_ID) {
|
||||
|
||||
$code_file = $this->auth_dir.md5($siteid.$name);
|
||||
if (!is_file($code_file)) {
|
||||
return;
|
||||
}
|
||||
|
||||
unlink($code_file);
|
||||
|
||||
// 重置Zend OPcache
|
||||
function_exists('opcache_reset') && opcache_reset();
|
||||
}
|
||||
|
||||
// 验证内容
|
||||
public function check_auth_data($name, $time = 3600, $siteid = SITE_ID) {
|
||||
|
||||
$code_file = $this->auth_dir.md5($siteid.$name);
|
||||
if (is_file($code_file)) {
|
||||
if (SYS_TIME - filemtime($code_file) > $time) {
|
||||
return '';
|
||||
}
|
||||
$rt = file_get_contents($code_file);
|
||||
if ($rt) {
|
||||
return $rt;
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
//------------------------------------------------
|
||||
|
||||
// 调用框架缓存
|
||||
public function init() {
|
||||
|
||||
if ($this->cache) {
|
||||
return $this->cache;
|
||||
}
|
||||
|
||||
if (is_file(FRAMEPATH.'Extend/Cache.php')) {
|
||||
require FRAMEPATH.'Extend/Cache.php';
|
||||
$this->cache = new \Frame\Cache();
|
||||
} else {
|
||||
$this->cache = cache();
|
||||
}
|
||||
|
||||
return $this->cache;
|
||||
}
|
||||
|
||||
//------------------------------------------------
|
||||
|
||||
// 存储内容
|
||||
public function set_data($name, $value, $time = 3600) {
|
||||
|
||||
// 重置Zend OPcache
|
||||
function_exists('opcache_reset') && opcache_reset();
|
||||
|
||||
$time && self::init()->save(md5(SITE_ID.'-'.$name), $value, $time);
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
// 获取内容
|
||||
public function get_data($name) {
|
||||
return self::init()->get(md5(SITE_ID.'-'.$name));
|
||||
}
|
||||
|
||||
// 删除内容
|
||||
public function del_data($name) {
|
||||
function_exists('opcache_reset') && opcache_reset();
|
||||
return self::init()->delete(md5(SITE_ID.'-'.$name));
|
||||
}
|
||||
|
||||
// 删除缓存
|
||||
public function clear($name) {
|
||||
|
||||
if (!$name) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->del_data($name);
|
||||
}
|
||||
|
||||
//------------------------------------------------
|
||||
|
||||
// 使用框架
|
||||
public function get() {
|
||||
|
||||
$param = func_get_args();
|
||||
if (!$param) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 取第一个参数作为缓存变量名称
|
||||
$name = strtolower(array_shift($param));
|
||||
if (SYS_CACHE) {
|
||||
$result = $this->get_data($name);
|
||||
if (!$result) {
|
||||
// 缓存不存在时重写缓存
|
||||
$result = self::get_file($name);
|
||||
// 任然不存在就表示没有数据
|
||||
if (!$result) {
|
||||
return null;
|
||||
}
|
||||
// 存储缓存
|
||||
$this->set_data($name, $result, 3600);
|
||||
}
|
||||
} else {
|
||||
// 读取配置文件
|
||||
$result = self::get_file($name);
|
||||
}
|
||||
|
||||
if (!$param) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
return dr_get_param_var($result, $param);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
<?php namespace Phpcmf\Library;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
/**
|
||||
* 验证码类
|
||||
*/
|
||||
class Captcha {
|
||||
|
||||
private $code;
|
||||
private $charset = 'adehkmnprswyADEFGHKMNPRSTVWY683457'; //设置随机生成因子
|
||||
private $width;
|
||||
private $height;
|
||||
private $img;
|
||||
private $font;
|
||||
private $fontsize = 16;
|
||||
private $fontcolor;
|
||||
private $randstring = ['*', '@', '$', '%', '&', '!'];
|
||||
|
||||
public function __construct() {
|
||||
if (function_exists('my_captcha_ttf()')) {
|
||||
$this->font = my_captcha_ttf();
|
||||
} else {
|
||||
$this->font = WRITEPATH.'captcha.ttf';
|
||||
if (!is_file($this->font)) {
|
||||
// 加载老版本的字体文件
|
||||
$this->font = CONFIGPATH.'font/1.ttf';
|
||||
if (!is_file($this->font)) {
|
||||
log_message('error', '验证码字体文件('.WRITEPATH.'captcha.ttf)不存在,可能无法生成验证码');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// todo
|
||||
public function create($width = 120, $height = 32) {
|
||||
|
||||
$this->_code();
|
||||
|
||||
$this->width = min(200, $width > 0 ? abs((int)$width) : 120);
|
||||
$this->height = min(100, $height > 0 ? abs((int)$height) : 32);
|
||||
|
||||
$this->_bg();
|
||||
$this->_line();
|
||||
$this->_font();
|
||||
$this->_show();
|
||||
|
||||
|
||||
return $this->code;
|
||||
}
|
||||
|
||||
//生成随机验证码
|
||||
private function _code() {
|
||||
|
||||
if ($this->code) {
|
||||
return $this->code;
|
||||
}
|
||||
|
||||
$code = '';
|
||||
$charset_len = strlen($this->charset) - 1;
|
||||
for ($i = 0; $i < 4; $i++) {
|
||||
$code.= $this->charset[rand(1, $charset_len)];
|
||||
}
|
||||
|
||||
$this->code = trim($code);
|
||||
}
|
||||
|
||||
//生成背景
|
||||
private function _bg() {
|
||||
|
||||
$this->img = imagecreatetruecolor($this->width, $this->height);
|
||||
$color = imagecolorallocate($this->img,255,255,255);
|
||||
imagecolortransparent($this->img, $color);
|
||||
imagefill($this->img,0,0, $color);
|
||||
}
|
||||
|
||||
//生成文字
|
||||
private function _font() {
|
||||
$_x = $this->width / 4;
|
||||
$this->fontcolor = imagecolorallocate($this->img, mt_rand(0,180), mt_rand(0,180), mt_rand(0,180));
|
||||
for ($i=0; $i<4; $i++) {
|
||||
imagettftext(
|
||||
$this->img,
|
||||
$this->fontsize,
|
||||
mt_rand(-30,30),
|
||||
intval($_x*$i+mt_rand(1,5)),
|
||||
intval($this->height / 1.4),
|
||||
$this->fontcolor,
|
||||
$this->font,
|
||||
$this->code[$i]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//生成干扰线条
|
||||
private function _line() {
|
||||
for ($i=0;$i<5;$i++) {
|
||||
$color = imagecolorallocate($this->img, mt_rand(0,180), mt_rand(0,180), mt_rand(0,180));
|
||||
imageline(
|
||||
$this->img,
|
||||
mt_rand(0,$this->width),
|
||||
mt_rand(0,$this->height),
|
||||
mt_rand(0,$this->width),
|
||||
mt_rand(0,$this->height),
|
||||
$color
|
||||
);
|
||||
}
|
||||
for ($i=0;$i<30;$i++) {
|
||||
$color = imagecolorallocate($this->img, mt_rand(100,255), mt_rand(100,255), mt_rand(100,255));
|
||||
imagestring(
|
||||
$this->img,
|
||||
mt_rand(1,5),
|
||||
mt_rand(0,$this->width),
|
||||
mt_rand(0,$this->height),
|
||||
$this->randstring[rand(0, 5)],
|
||||
$color
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//显示
|
||||
private function _show() {
|
||||
@ob_start();
|
||||
@ob_clean(); //关键代码,防止出现'图像因其本身有错无法显示'的问题。
|
||||
header('Content-type:image/png');
|
||||
imagepng($this->img);
|
||||
imagedestroy($this->img);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
<?php namespace Phpcmf\Library;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
|
||||
// 配置文件生成
|
||||
class Config {
|
||||
|
||||
private $file;
|
||||
private $space = 32;
|
||||
private $header;
|
||||
|
||||
/**
|
||||
* 配置文件
|
||||
*
|
||||
* @param string $file 文件绝对地址
|
||||
* @param string $name 文件备注名称
|
||||
* @return object
|
||||
*/
|
||||
public function file($file, $name = '', $space = 32) {
|
||||
$this->file = $file;
|
||||
$this->space = $space;
|
||||
$this->header = '<?php'.PHP_EOL.PHP_EOL.
|
||||
'if (!defined(\'BASEPATH\')) exit(\'No direct script access allowed\');'.PHP_EOL.PHP_EOL.
|
||||
'/**'.PHP_EOL.
|
||||
' * '.$name.PHP_EOL.
|
||||
' */'.PHP_EOL.PHP_EOL
|
||||
;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成require一维数组文件
|
||||
*
|
||||
* @param array $var 变量标识 array('变量名称' => '备注信息'), ...
|
||||
* @param array $data 对应值数组 array('变量名称' => '变量值'), ... 为空时直接生成$var
|
||||
* @return int
|
||||
*/
|
||||
public function to_require_one($var, $data = []) {
|
||||
|
||||
$body = $this->header.'return ['.PHP_EOL.PHP_EOL;
|
||||
if ($data) {
|
||||
foreach ($var as $name => $note) {
|
||||
if (is_array($data[$name])) {
|
||||
continue;
|
||||
}
|
||||
$name = $this->_safe_replace($name);
|
||||
$body.= ' \''.$name.'\''.$this->_space($name).'=> '.$this->_format_value($data[$name]).', //'.$note.PHP_EOL;
|
||||
}
|
||||
} elseif ($var) {
|
||||
foreach ($var as $name => $val) {
|
||||
if (is_array($val)) {
|
||||
continue;
|
||||
}
|
||||
$name = $this->_safe_replace($name);
|
||||
$body.= ' \''.$name.'\''.$this->_space($name).'=> '.$this->_format_value($val).','.PHP_EOL;
|
||||
}
|
||||
}
|
||||
$body.= PHP_EOL.'];';
|
||||
!is_dir(dirname($this->file)) && dr_mkdirs(dirname($this->file));
|
||||
|
||||
// 重置Zend OPcache
|
||||
function_exists('opcache_reset') && opcache_reset();
|
||||
|
||||
return @file_put_contents($this->file, $body, LOCK_EX);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 生成require N维数组文件
|
||||
*
|
||||
* @param array data
|
||||
* @return int
|
||||
*/
|
||||
public function to_require($data) {
|
||||
|
||||
if (!is_array($data)) {
|
||||
$data = [];
|
||||
}
|
||||
|
||||
$body = $this->header.'return ';
|
||||
$body .= str_replace(array(' ', '
|
||||
'), array(' ', ' '), var_export($data, TRUE));
|
||||
$body .= ';';
|
||||
!is_dir(dirname($this->file)) && dr_mkdirs(dirname($this->file));
|
||||
|
||||
// 重置Zend OPcache
|
||||
function_exists('opcache_reset') && opcache_reset();
|
||||
|
||||
return @file_put_contents($this->file, $body, LOCK_EX);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成require N维数组文件
|
||||
*
|
||||
* @param array data
|
||||
* @return int
|
||||
*/
|
||||
public function to_require_array($value) {
|
||||
|
||||
if (!$value) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
$body = $this->header.'return ['.PHP_EOL.PHP_EOL;
|
||||
foreach ($value as $id => $data) {
|
||||
|
||||
$body.= ' '.$id .' => ['.PHP_EOL.PHP_EOL;
|
||||
foreach ($data as $name => $val) {
|
||||
if (is_array($data[$name])) {
|
||||
continue;
|
||||
}
|
||||
$name = $this->_safe_replace($name);
|
||||
$body.= ' \''.$name.'\''.$this->_space($name).'=> '.$this->_format_value($data[$name]).','.PHP_EOL;
|
||||
}
|
||||
$body.= PHP_EOL.' ],'.PHP_EOL.PHP_EOL;
|
||||
}
|
||||
$body.= PHP_EOL.'];';
|
||||
|
||||
!is_dir(dirname($this->file)) && dr_mkdirs(dirname($this->file));
|
||||
|
||||
// 重置Zend OPcache
|
||||
function_exists('opcache_reset') && opcache_reset();
|
||||
|
||||
return @file_put_contents($this->file, $body, LOCK_EX);
|
||||
}
|
||||
|
||||
/**
|
||||
* 补空格
|
||||
*/
|
||||
private function _space($name) {
|
||||
$len = dr_strlen($name) + 2;
|
||||
$cha = $this->space - $len;
|
||||
$str = '';
|
||||
for ($i = 0; $i < $cha; $i ++) $str .= ' ';
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化值
|
||||
*/
|
||||
private function _format_value($value) {
|
||||
return is_numeric($value) && strlen($value) <= 10 ? $value : '\''.str_replace(['\'', '\\'], '', (string)$value).'\'';
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全替换
|
||||
*/
|
||||
private function _safe_replace($name) {
|
||||
return str_replace(
|
||||
['..', '\\', '<', '>', "{", '}', ';', '[', ']', '\'', '"', '*', '?'],
|
||||
'',
|
||||
(string)$name
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,211 @@
|
||||
<?php namespace Phpcmf\Library;
|
||||
/**
|
||||
* https://www.besyun.com
|
||||
* BESCMS
|
||||
* 本文件是框架系统文件,二次开发时不可以修改本文件,可以通过继承类方法来重写此文件
|
||||
**/
|
||||
|
||||
/**
|
||||
* SMTP邮件发送类
|
||||
*/
|
||||
|
||||
class Email {
|
||||
|
||||
public $error;
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* 样式配置文件
|
||||
*/
|
||||
public function set($config) {
|
||||
$this->config = [
|
||||
'port' => $config['port'],
|
||||
'auth' => 1,
|
||||
'from' => $config['from'],
|
||||
'server' => $config['host'],
|
||||
'mailsend' => 2,
|
||||
'mailusername' => 1,
|
||||
'maildelimiter' => 1,
|
||||
'auth_username' => $config['user'],
|
||||
'auth_password' => $config['pass'],
|
||||
];
|
||||
return $this;
|
||||
}
|
||||
|
||||
// mail 发送
|
||||
public function mail($toemail, $subject, $message, $fname = '') {
|
||||
|
||||
$subject = "=?UTF-8?B?".base64_encode($subject)."?=";
|
||||
$from_user = "=?UTF-8?B?".base64_encode($fname ? $fname : SITE_NAME)."?=";
|
||||
$headers = "From: ".$from_user." <".$this->config['from'].">\r\n".
|
||||
"MIME-Version: 1.0" . "\r\n" .
|
||||
"Content-type: text/html; charset=UTF-8" . "\r\n";
|
||||
|
||||
return mail($toemail, $subject, $message, $headers);
|
||||
}
|
||||
|
||||
// smtp发送
|
||||
public function send($toemail, $subject, $message, $fname = '') {
|
||||
|
||||
$mail = $this->config;
|
||||
if (!$mail['server']) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ($mail['server'] == 'mail') {
|
||||
return $this->mail($toemail, $subject, $message, $fname);
|
||||
}
|
||||
|
||||
$cfg = [];
|
||||
$cfg['charset'] = $charset = 'utf-8';
|
||||
$cfg['server'] = $mail['server'];
|
||||
$cfg['port'] = $mail['port'];
|
||||
$cfg['from'] = $mail['from'];
|
||||
$cfg['auth_username'] = $mail['auth_username'];
|
||||
$cfg['auth_password'] = $mail['auth_password'];
|
||||
unset($mail);
|
||||
|
||||
$is_starttls = 0;
|
||||
if (strpos($cfg['server'], 'starttls://') === 0) {
|
||||
$is_starttls = 1;
|
||||
$cfg['server'] = str_replace('starttls://', '', $cfg['server']);
|
||||
}
|
||||
|
||||
$mailusername = 1;
|
||||
$maildelimiter = "\r\n"; //换行符
|
||||
$cfg['port'] = $cfg['port'] ? $cfg['port'] : 25;
|
||||
|
||||
$email_from = '=?'.$cfg['charset'].'?B?'.base64_encode($fname ? $fname : SITE_NAME)."?= <".$cfg['from'].">";
|
||||
$email_to = preg_match('/^(.+?) \<(.+?)\>$/',$toemail, $mats) ? ($mailusername ? '=?'.$cfg['charset'].'?B?'.base64_encode($mats[1])."?= <$mats[2]>" : $mats[2]) : $toemail;
|
||||
$email_subject = '=?'.$cfg['charset'].'?B?'.base64_encode(preg_replace("/[\r|\n]/", '', $subject)).'?=';
|
||||
$email_message = chunk_split(base64_encode(str_replace("\n", "\r\n", str_replace("\r", "\n", str_replace("\r\n", "\n", str_replace("\n\r", "\r", $message))))));
|
||||
|
||||
$host = $_SERVER['HTTP_HOST'];
|
||||
$headers = "From: $email_from{$maildelimiter}X-Priority: 3{$maildelimiter}X-Mailer: $host {$maildelimiter}MIME-Version: 1.0{$maildelimiter}Content-type: text/html; charset=".$cfg['charset']."{$maildelimiter}Content-Transfer-Encoding: base64{$maildelimiter}";
|
||||
|
||||
if(!$fp = fsockopen($cfg['server'], $cfg['port'], $errno, $errstr, 30)) {
|
||||
$this->runlog($cfg['server'].' - '.$cfg['auth_username'].' - '.$toemail, "fsockopen 无法连接到邮件服务器 [".$errno."-".$errstr."]");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
stream_set_blocking($fp, true);
|
||||
$lastmessage = fgets($fp, 512);
|
||||
if(substr($lastmessage, 0, 3) != '220') {
|
||||
$this->runlog($cfg['server'].' - '.$cfg['auth_username'].' - '.$toemail, "连接失败", $lastmessage);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
fputs($fp, "EHLO phpcmf\r\n");
|
||||
$lastmessage = fgets($fp, 512);
|
||||
if(substr($lastmessage, 0, 3) != 220 && substr($lastmessage, 0, 3) != 250) {
|
||||
$this->runlog($cfg['server'].' - '.$cfg['auth_username'].' - '.$toemail, "EHLO", $lastmessage);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// 是否starttls
|
||||
if ($is_starttls) {
|
||||
fputs($fp, "STARTTLS phpcmf\r\n");
|
||||
$lastmessage = fgets($fp, 512);
|
||||
if(substr($lastmessage, 0, 3) != 220 && substr($lastmessage, 0, 3) != 250) {
|
||||
$this->runlog($cfg['server'].' - '.$cfg['auth_username'].' - '.$toemail, "STARTTLS", $lastmessage);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
while(1) {
|
||||
if(substr($lastmessage, 3, 1) != '-' || empty($lastmessage)) {
|
||||
break;
|
||||
}
|
||||
$lastmessage = fgets($fp, 512);
|
||||
}
|
||||
|
||||
//$crypto = stream_socket_enable_crypto($fp, true, STREAM_CRYPTO_METHOD_TLS_CLIENT);
|
||||
|
||||
|
||||
// 登录账号认证
|
||||
fputs($fp, "AUTH LOGIN\r\n");
|
||||
$lastmessage = fgets($fp, 512);
|
||||
if(substr($lastmessage, 0, 3) != 334) {
|
||||
$this->runlog($cfg['server'].' - '.$cfg['auth_username'].' - '.$toemail, "认证登录失败", $lastmessage);
|
||||
return FALSE;
|
||||
}
|
||||
fputs($fp, base64_encode($cfg['auth_username']) . "\r\n");
|
||||
$lastmessage = fgets($fp, 512);
|
||||
if(substr($lastmessage, 0, 3) != 334) {
|
||||
$this->runlog($cfg['server'].' - '.$cfg['auth_username'].' - '.$toemail, "账号验证失败", $lastmessage);
|
||||
return FALSE;
|
||||
}
|
||||
fputs($fp, base64_encode($cfg['auth_password']) . "\r\n");
|
||||
$lastmessage = fgets($fp, 512);
|
||||
if(substr($lastmessage, 0, 3) != 235) {
|
||||
$this->runlog($cfg['server'].' - '.$cfg['auth_username'].' - '.$toemail, "密码验证失败", $lastmessage);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$email_from = $cfg['from'];
|
||||
|
||||
fputs($fp, "MAIL FROM: <".preg_replace("/.*\<(.+?)\>.*/", "\\1", $email_from).">\r\n");
|
||||
$lastmessage = fgets($fp, 512);
|
||||
if(substr($lastmessage, 0, 3) != 250) {
|
||||
fputs($fp, "MAIL FROM: <".preg_replace("/.*\<(.+?)\>.*/", "\\1", $email_from).">\r\n");
|
||||
$lastmessage = fgets($fp, 512);
|
||||
if(substr($lastmessage, 0, 3) != 250) {
|
||||
$this->runlog($cfg['server'].' - '.$cfg['auth_username'].' - '.$toemail, "MAIL FROM", $lastmessage);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
fputs($fp, "RCPT TO: <".preg_replace("/.*\<(.+?)\>.*/", "\\1", $toemail).">\r\n");
|
||||
$lastmessage = fgets($fp, 512);
|
||||
if(substr($lastmessage, 0, 3) != 250) {
|
||||
fputs($fp, "RCPT TO: <".preg_replace("/.*\<(.+?)\>.*/", "\\1", $toemail).">\r\n");
|
||||
$lastmessage = fgets($fp, 512);
|
||||
$this->runlog($cfg['server'].' - '.$cfg['auth_username'].' - '.$toemail, "RCPT TO", $lastmessage);
|
||||
return FALSE;
|
||||
}
|
||||
fputs($fp, "DATA\r\n");
|
||||
$lastmessage = fgets($fp, 512);
|
||||
if(substr($lastmessage, 0, 3) != 354) {
|
||||
$this->runlog($cfg['server'].' - '.$cfg['auth_username'].' - '.$toemail, "DATA", $lastmessage);
|
||||
return FALSE;
|
||||
}
|
||||
$headers .= 'Message-ID: <'.gmdate('YmdHs').'.'.substr(md5($email_message.microtime()), 0, 6).rand(100000, 999999).'@'.$_SERVER['HTTP_HOST'].">{$maildelimiter}";
|
||||
|
||||
fputs($fp, "Date: ".gmdate('r')."\r\n");
|
||||
fputs($fp, "To: ".$email_to."\r\n");
|
||||
fputs($fp, "Subject: ".$email_subject."\r\n");
|
||||
fputs($fp, $headers."\r\n");
|
||||
fputs($fp, "\r\n\r\n");
|
||||
fputs($fp, "$email_message\r\n.\r\n");
|
||||
$lastmessage = fgets($fp, 512);
|
||||
if(substr($lastmessage, 0, 3) != 250) {
|
||||
$this->runlog($cfg['server'].' - '.$cfg['auth_username'].' - '.$toemail, "END", $lastmessage);
|
||||
return FALSE;
|
||||
}
|
||||
fputs($fp, "QUIT\r\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
public function error() {
|
||||
return $this->error;
|
||||
}
|
||||
|
||||
protected function runlog($server, $name, $msg = '') {
|
||||
|
||||
if ($msg && $this->is_gb2312($msg) && function_exists('iconv')) {
|
||||
$new = iconv('GB2312', 'UTF-8', $msg);
|
||||
if ($new) {
|
||||
$msg = $new;
|
||||
}
|
||||
}
|
||||
|
||||
$this->error = $name.'-'.$msg;
|
||||
|
||||
@file_put_contents(WRITEPATH.'email_log.txt', date('Y-m-d H:i:s').' ['.$server.'] '.str_replace([PHP_EOL, chr(13), chr(10)], '', $msg).PHP_EOL, FILE_APPEND);
|
||||
}
|
||||
|
||||
protected function is_gb2312($str) {
|
||||
return function_exists('mb_detect_encoding') && mb_detect_encoding($str,"UTF-8, ISO-8859-1, GBK")!="UTF-8";
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user