This commit is contained in:
Gitea
2022-01-24 10:43:35 +08:00
commit 15dfc6576b
786 changed files with 219240 additions and 0 deletions

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,349 @@
<?php
/**
* @copyright (C)2016-2099 Hnaoyun Inc.
* @author XingMeng
* @email hnxsh@foxmail.com
* @date 2017年3月13日
* 默认主页
*/
namespace app\admin\controller;
use core\basic\Controller;
use app\admin\model\IndexModel;
class IndexController extends Controller
{
private $model;
public function __construct()
{
$this->model = new IndexModel();
}
// 登录页面
public function index()
{
if (session('sid')) {
location(url('admin/Index/home'));
}
$this->assign('admin_check_code', $this->config('admin_check_code'));
$this->display('index.html');
}
// 主页面
public function home()
{
// 手动修改数据名称
if (get('action') == 'moddb') {
if ($this->modDB()) {
alert_back('修改成功!');
} else {
alert_back('修改失败!');
}
}
// 删除修改后老数据库(上一步无法直接修改删除)
if (issetSession('deldb')) {
@unlink(ROOT_PATH . session('deldb'));
unset($_SESSION['deldb']);
}
$dbsecurity = true;
// 如果是sqlite数据库并且路径为默认的则标记为不安全
if (get_db_type() == 'sqlite') {
if (strpos($this->config('database.dbname'), 'pbootcms') !== false) {
if (get_user_ip() != '127.0.0.1' && $this->modDB()) { // 非本地测试时尝试自动修改数据库名称
$dbsecurity = true;
} else {
$dbsecurity = false;
}
}
} elseif (file_exists(ROOT_PATH . '/data/pbootcms.db')) {
rename(ROOT_PATH . '/data/pbootcms.db', ROOT_PATH . '/data/' . get_uniqid() . '.db');
}
$this->assign('dbsecurity', $dbsecurity);
if (! session('pwsecurity')) {
location(url('/admin/Index/ucenter'));
}
$this->assign('server', get_server_info());
$this->assign('branch', $this->config('upgrade_branch') == '3.X.dev' ? '3.X.dev' : '3.X');
$this->assign('revise', $this->config('revise_version') ?: '0');
$this->assign('snuser', $this->config('sn_user') ?: '0');
$this->assign('site', get_http_url());
$this->assign('user_info', $this->model->getUserInfo(session('ucode')));
$this->assign('sum_msg', model('admin.content.Message')->getCount());
// 内容模型菜单
$model = model('admin.content.Model');
$models = $model->getModelMenu();
foreach ($models as $key => $value) {
$models[$key]->count = $model->getModelCount($value->mcode)->count;
}
$this->assign('model_msg', $models);
$this->display('system/home.html');
}
// 异步登录验证
public function login()
{
if (! $_POST) {
return;
}
// 在安装了gd库时才执行验证码验证
if (extension_loaded("gd") && $this->config('admin_check_code') && strtolower(post('checkcode', 'var')) != session('checkcode')) {
json(0, '验证码错误!');
}
// 就收数据
$username = post('username');
$password = post('password');
if (! preg_match('/^[\x{4e00}-\x{9fa5}\w\-\.@]+$/u', $username)) {
json(0, '用户名含有不允许的特殊字符!');
}
if (! $username) {
json(0, '用户名不能为空!');
}
if (! $password) {
json(0, '密码不能为空!');
}
if (! ! $time = $this->checkLoginBlack()) {
$this->log('登录锁定!');
json(0, '您登录失败次数太多已被锁定,请' . $time . '秒后再试!');
}
// 执行用户登录
$where = array(
'username' => $username,
'password' => encrypt_string($password)
);
// 判断数据库写入权限
if ((get_db_type() == 'sqlite') && ! is_writable(ROOT_PATH . $this->config('database.dbname'))) {
json(0, '数据库目录写入权限不足!');
}
if (! ! $login = $this->model->login($where)) {
session_regenerate_id(true);
session('sid', encrypt_string(session_id() . $login->id)); // 会话标识
session('M', M);
session('id', $login->id); // 用户id
session('ucode', $login->ucode); // 用户编码
session('username', $login->username); // 用户名
session('realname', $login->realname); // 真实名字
if ($where['password'] != '14e1b600b1fd579f47433b88e8d85291') {
session('pwsecurity', true);
}
session('acodes', $login->acodes); // 用户管理区域
if ($login->acodes) { // 当前显示区域
session('acode', $login->acodes[0]);
} else {
session('acode', '');
}
session('rcodes', $login->rcodes); // 用户角色代码表
session('levels', $login->levels); // 用户权限URL列表
session('menu_tree', $login->menus); // 菜单树
session('area_map', $login->area_map); // 区域代码名称映射表
session('area_tree', $login->area_tree); // 用户区域树
$this->log('登录成功!');
json(1, url('admin/Index/home'));
} else {
$this->setLoginBlack();
$this->log('登录失败!');
session('checkcode', mt_rand(10000, 99999)); // 登录失败,随机打乱原有验证码
json(0, '用户名或密码错误!');
}
}
// 退出登录
public function loginOut()
{
session_unset();
location(url('/admin/Index/index'));
}
// 用户中心,修改密码
public function ucenter()
{
if ($_POST) {
$username = post('username'); // 用户名
$realname = post('realname'); // 真实姓名
$cpassword = post('cpassword'); // 现在密码
$password = post('password'); // 新密码
$rpassword = post('rpassword'); // 确认密码
if (! $username) {
alert_back('用户名不能为空!');
}
if (! $cpassword) {
alert_back('当前密码不能为空!');
}
if (! preg_match('/^[\x{4e00}-\x{9fa5}\w\-\.@]+$/u', $username)) {
alert_back('用户名含有不允许的特殊字符!');
}
$data = array(
'username' => $username,
'realname' => $realname,
'update_user' => $username
);
// 如果有修改密码,则添加数据
if ($password) {
if ($password != $rpassword) {
alert_back('确认密码不正确!');
}
$data['password'] = encrypt_string($password);
if ($data['password'] != '14e1b600b1fd579f47433b88e8d85291') {
session('pwsecurity', true);
} else {
session('pwsecurity', false);
}
}
// 检查现有密码
if ($this->model->checkUserPwd(encrypt_string($cpassword))) {
if ($this->model->modUserInfo($data)) {
session('username', post('username'));
session('realname', post('realname'));
$this->log('用户资料成功!');
success('用户资料修改成功!', - 1);
}
} else {
$this->log('用户资料修改时当前密码错误!');
alert_location('当前密码错误!', - 1);
}
}
$this->display('system/ucenter.html');
}
// 切换显示的数据区域
public function area()
{
if ($_POST) {
$acode = post('acode');
if (in_array($acode, session('acodes'))) {
session('acode', $acode);
cookie('lg', $acode); // 同步切换前台语言
}
location(url('admin/Index/home'));
}
}
// 清理缓存
public function clearCache()
{
if (get('delall')) {
$rs = path_delete(RUN_PATH);
} else {
$rs = (path_delete(RUN_PATH . '/cache') && path_delete(RUN_PATH . '/complile') && path_delete(RUN_PATH . '/config') && path_delete(RUN_PATH . '/upgrade') && path_delete(RUN_PATH . '/image'));
}
if ($rs) {
if (extension_loaded('Zend OPcache')) {
opcache_reset(); // 在启用了OPcache加速器时同时清理
}
$this->log('清理缓存成功!');
alert_back('清理缓存成功!');
} else {
$this->log('清理缓存失败!');
alert_back('清理缓存失败!');
}
}
// 文件上传方法
public function upload()
{
$upload = upload('upload');
if (is_array($upload)) {
json(1, $upload);
} else {
json(0, $upload);
}
}
// 检查是否在黑名单
private function checkLoginBlack()
{
// 读取黑名单
$ip_black = RUN_PATH . '/data/' . md5('login_black') . '.php';
if (file_exists($ip_black)) {
$data = require $ip_black;
$user_ip = get_user_ip();
$lock_time = $this->config('lock_time') ?: 900;
$lock_count = $this->config('lock_count') ?: 5;
if (isset($data[$user_ip]) && $data[$user_ip]['count'] >= $lock_count && time() - $data[$user_ip]['time'] < $lock_time) {
return $lock_time - (time() - $data[$user_ip]['time']); // 返回剩余秒数
}
}
return false;
}
// 添加登录黑名单
private function setLoginBlack()
{
// 读取黑名单
$ip_black = RUN_PATH . '/data/' . md5('login_black') . '.php';
if (file_exists($ip_black)) {
$data = require $ip_black;
} else {
$data = array();
}
// 添加IP
$user_ip = get_user_ip();
$lock_time = $this->config('lock_time') ?: 900;
$lock_count = $this->config('lock_count') ?: 5;
if (isset($data[$user_ip]) && $data[$user_ip]['count'] < $lock_count && time() - $data[$user_ip]['time'] < $lock_time) {
$data[$user_ip] = array(
'time' => time(),
'count' => $data[get_user_ip()]['count'] + 1
);
} else {
$data[$user_ip] = array(
'time' => time(),
'count' => 1
);
}
// 写入黑名单
check_file($ip_black, true);
return file_put_contents($ip_black, "<?php\nreturn " . var_export($data, true) . ";");
}
// 修改数据库名称
private function modDB()
{
$file = CONF_PATH . '/database.php';
$sname = $this->config('database.dbname');
$dname = '/data/' . get_uniqid() . '.db';
$sconfig = file_get_contents($file);
$dconfig = str_replace($sname, $dname, $sconfig);
if (file_put_contents($file, $dconfig)) {
if (! copy(ROOT_PATH . $sname, ROOT_PATH . $dname)) {
file_put_contents($file, $sconfig); // 回滚配置
} else {
session('deldb', $sname);
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,557 @@
<?php
/**
* @copyright (C)2016-2099 Hnaoyun Inc.
* @author XingMeng
* @email hnxsh@foxmail.com
* @date 2017年12月26日
* 内容栏目控制器
*/
namespace app\admin\controller\content;
use core\basic\Controller;
use app\admin\model\content\ContentSortModel;
class ContentSortController extends Controller
{
private $count;
private $blank;
private $outData = array();
private $model;
public function __construct()
{
$this->model = new ContentSortModel();
}
// 内容栏目列表
public function index()
{
$this->assign('list', true);
$tree = $this->model->getList();
$sorts = $this->makeSortList($tree);
$this->assign('sorts', $sorts);
// 内容模型
$models = model('admin.content.Model');
$this->assign('allmodels', $models->getSelectAll());
$this->assign('models', $models->getSelect());
// 内容栏目下拉表
$sort_tree = $this->model->getSelect();
$sort_select = $this->makeSortSelect($sort_tree);
$this->assign('sort_select', $sort_select);
// 模板文件
$htmldir = $this->config('tpl_html_dir') ? '/' . $this->config('tpl_html_dir') : '';
$this->assign('tpls', file_list(ROOT_PATH . current($this->config('tpl_dir')) . '/' . $this->model->getTheme() . $htmldir));
// 前端地址连接符判断
$url_break_char = $this->config('url_break_char') ?: '_';
$this->assign('url_break_char', $url_break_char);
// 获取会员分组
$this->assign('groups', model('admin.member.MemberGroup')->getSelect());
$this->display('content/contentsort.html');
}
// 生成无限级内容栏目列表
private function makeSortList($tree)
{
// 循环生成
foreach ($tree as $value) {
$this->count ++;
$this->outData[$this->count] = new \stdClass();
$this->outData[$this->count]->id = $value->id;
$this->outData[$this->count]->blank = $this->blank;
$this->outData[$this->count]->name = $value->name;
$this->outData[$this->count]->subname = $value->subname;
$this->outData[$this->count]->scode = $value->scode;
$this->outData[$this->count]->pcode = $value->pcode;
$this->outData[$this->count]->mcode = $value->mcode;
$this->outData[$this->count]->listtpl = $value->listtpl;
$this->outData[$this->count]->contenttpl = $value->contenttpl;
$this->outData[$this->count]->ico = $value->ico;
$this->outData[$this->count]->pic = $value->pic;
$this->outData[$this->count]->keywords = $value->keywords;
$this->outData[$this->count]->description = $value->description;
$this->outData[$this->count]->outlink = $value->outlink;
$this->outData[$this->count]->sorting = $value->sorting;
$this->outData[$this->count]->status = $value->status;
$this->outData[$this->count]->filename = $value->filename;
$this->outData[$this->count]->type = $value->type;
$this->outData[$this->count]->urlname = $value->urlname;
$this->outData[$this->count]->create_user = $value->create_user;
$this->outData[$this->count]->update_user = $value->update_user;
$this->outData[$this->count]->create_time = $value->create_time;
$this->outData[$this->count]->update_time = $value->update_time;
if ($value->son) {
$this->outData[$this->count]->son = true;
} else {
$this->outData[$this->count]->son = false;
}
// 子菜单处理
if ($value->son) {
$this->blank .= '  ';
$this->makeSortList($value->son);
}
}
// 循环完后回归缩进位置
$this->blank = substr($this->blank, 6);
return $this->outData;
}
// 内容栏目增加
public function add()
{
if ($_POST) {
if (! ! $multiplename = post('multiplename')) {
$multiplename = str_replace('', ',', $multiplename);
$pcode = post('pcode', 'var');
$type = post('type');
$mcode = post('mcode');
$listtpl = basename(post('listtpl'));
$contenttpl = basename(post('contenttpl'));
$status = post('status');
if (! $pcode) { // 父编码默认为0
$pcode = 0;
}
if (! $mcode) {
alert_back('栏目模型必须选择!');
}
if (! $type) {
alert_back('栏目类型不能为空!');
}
$names = explode(',', $multiplename);
$lastcode = $this->model->getLastCode();
$scode = get_auto_code($lastcode);
foreach ($names as $key => $value) {
$data[] = array(
'acode' => session('acode'),
'pcode' => $pcode,
'scode' => $scode,
'name' => $value,
'mcode' => $mcode,
'listtpl' => $listtpl,
'contenttpl' => $contenttpl,
'status' => $status,
'gid' => 0,
'gtype' => 4,
'subname' => '',
'filename' => '',
'outlink' => '',
'ico' => '',
'pic' => '',
'title' => '',
'keywords' => '',
'description' => '',
'sorting' => 255,
'create_user' => session('username'),
'update_user' => session('username')
);
$scode = get_auto_code($scode);
}
} else {
// 获取数据
$scode = get_auto_code($this->model->getLastCode()); // 自动编码;
$pcode = post('pcode', 'var');
$name = post('name');
$type = post('type');
$mcode = post('mcode');
$listtpl = basename(post('listtpl'));
$contenttpl = basename(post('contenttpl'));
$status = post('status');
$subname = post('subname');
$filename = post('filename');
$outlink = post('outlink');
$ico = post('ico');
$pic = post('pic');
$title = post('title');
$keywords = post('keywords');
$description = post('description');
$gid = post('gid', 'int') ?: 0;
$gtype = post('gtype', 'int') ?: 4;
$gnote = post('gnote');
$def1 = post('def1');
$def2 = post('def2');
$def3 = post('def3');
if (! $scode) {
alert_back('编码不能为空!');
}
if (! $pcode) { // 父编码默认为0
$pcode = 0;
}
if (! $name) {
alert_back('栏目名不能为空!');
}
if (! $mcode) {
alert_back('栏目模型必须选择!');
}
if (! $type) {
alert_back('栏目类型不能为空!');
}
if ($filename && ! preg_match('/^[a-zA-Z0-9\-]+$/', $filename)) {
alert_back('URL名称只允许字母、数字、横线组成!');
}
if ($filename && $this->model->checkUrlname($filename)) {
alert_back('URL名称与模型URL名称冲突请换一个名称');
}
// 缩放缩略图
if ($ico) {
resize_img(ROOT_PATH . $ico, '', $this->config('ico.max_width'), $this->config('ico.max_height'));
}
// 检查编码
if ($this->model->checkSort("scode='$scode'")) {
alert_back('该内容栏目编号已经存在,不能再使用!');
}
// 检查自定义URL名称
if ($filename) {
while ($this->model->checkFilename($filename)) {
$filename = $filename . '_' . mt_rand(1, 20);
}
}
// 构建数据
$data = array(
'acode' => session('acode'),
'pcode' => $pcode,
'scode' => $scode,
'name' => $name,
'mcode' => $mcode,
'listtpl' => $listtpl,
'contenttpl' => $contenttpl,
'status' => $status,
'gid' => $gid,
'gtype' => $gtype,
'gnote' => $gnote,
'subname' => $subname,
'def1' => $def1,
'def2' => $def2,
'def3' => $def3,
'filename' => $filename,
'outlink' => $outlink,
'ico' => $ico,
'pic' => $pic,
'title' => $title,
'keywords' => $keywords,
'description' => $description,
'sorting' => 255,
'create_user' => session('username'),
'update_user' => session('username')
);
}
// 执行添加
if ($this->model->addSort($data)) {
if ($type == 1 && ! $outlink) { // 在填写了外链时不生成单页
if ($multiplename) {
foreach ($data as $key => $value) {
$this->addSingle($value['scode'], $value['name']);
}
} else {
$this->addSingle($scode, $name);
}
}
$this->log('新增数据内容栏目' . $scode . '成功!');
success('新增成功!', url('/admin/ContentSort/index'));
} else {
$this->log('新增数据内容栏目' . $scode . '失败!');
error('新增失败!', - 1);
}
}
}
// 生成内容栏目下拉选择
private function makeSortSelect($tree, $selectid = null)
{
$list_html = '';
foreach ($tree as $value) {
// 默认选择项
if ($selectid == $value->scode) {
$select = "selected='selected'";
} else {
$select = '';
}
if (get('scode') != $value->scode) { // 不显示本身,避免出现自身为自己的父节点
$list_html .= "<option value='{$value->scode}' $select>{$this->blank}{$value->name}</option>";
}
// 子菜单处理
if ($value->son) {
$this->blank .= '  ';
$list_html .= $this->makeSortSelect($value->son, $selectid);
}
}
// 循环完后回归位置
$this->blank = substr($this->blank, 0, - 6);
return $list_html;
}
// 内容栏目删除
public function del()
{
// 执行批量删除
if ($_POST) {
if (! ! $list = post('list')) {
if ($this->model->delSortList($list)) {
$this->log('批量删除栏目成功!');
success('批量删除成功!', - 1);
} else {
$this->log('批量删除栏目失败!');
error('批量删除失败!', - 1);
}
} else {
alert_back('请选择要删除的栏目!');
}
}
if (! $scode = get('scode', 'var')) {
error('传递的参数值错误!', - 1);
}
if ($this->model->delSort($scode)) {
$this->log('删除数据内容栏目' . $scode . '成功!');
success('删除成功!', - 1);
} else {
$this->log('删除数据内容栏目' . $scode . '失败!');
error('删除失败!', - 1);
}
}
// 内容栏目修改
public function mod()
{
if (! ! $submit = post('submit')) {
switch ($submit) {
case 'sorting': // 修改列表排序
$listall = post('listall');
if ($listall) {
$sorting = post('sorting');
foreach ($listall as $key => $value) {
if ($sorting[$key] === '' || ! is_numeric($sorting[$key]))
$sorting[$key] = 255;
$this->model->modSortSorting($value, "sorting=" . $sorting[$key]);
}
$this->log('批量修改栏目排序成功!');
success('修改成功!', - 1);
} else {
alert_back('排序失败,无任何内容!');
}
break;
}
}
if (! $scode = get('scode', 'var')) {
error('传递的参数值错误!', - 1);
}
// 单独修改状态
if (($field = get('field', 'var')) && ! is_null($value = get('value', 'var'))) {
if ($this->model->modSort($scode, "$field='$value',update_user='" . session('username') . "'")) {
$this->log('修改数据内容栏目' . $scode . '状态' . $value . '成功!');
location(- 1);
} else {
$this->log('修改数据内容栏目' . $scode . '状态' . $value . '失败!');
alert_back('修改失败!');
}
}
// 修改操作
if ($_POST) {
// 获取数据
$pcode = post('pcode', 'var');
$name = post('name');
$mcode = post('mcode');
$type = post('type');
$listtpl = basename(post('listtpl'));
$contenttpl = basename(post('contenttpl'));
$status = post('status');
$subname = post('subname');
$filename = post('filename');
$outlink = post('outlink');
$ico = post('ico');
$pic = post('pic');
$title = post('title');
$keywords = post('keywords');
$description = post('description');
$modsub = post('modsub', 'int');
$gid = post('gid', 'int') ?: 0;
$gtype = post('gtype', 'int') ?: 4;
$gnote = post('gnote');
$def1 = post('def1');
$def2 = post('def2');
$def3 = post('def3');
if (! $pcode) { // 父编码默认为0
$pcode = 0;
}
if (! $name) {
alert_back('栏目名不能为空!');
}
if (! $mcode) {
alert_back('栏目模型必须选择!');
}
if (! $type) {
alert_back('栏目类型不能为空!');
}
if ($filename && ! preg_match('/^[a-zA-Z0-9\-]+$/', $filename)) {
alert_back('URL名称只允许字母、数字、横线组成!');
}
if ($filename && $this->model->checkUrlname($filename)) {
alert_back('URL名称与模型URL名称冲突请换一个名称');
}
// 缩放缩略图
if ($ico) {
resize_img(ROOT_PATH . $ico, '', $this->config('ico.max_width'), $this->config('ico.max_height'));
}
if ($filename) {
while ($this->model->checkFilename($filename, "scode<>'$scode'")) {
$filename = $filename . '-' . mt_rand(1, 20);
}
}
// 构建数据
$data = array(
'pcode' => $pcode,
'name' => $name,
'mcode' => $mcode,
'listtpl' => $listtpl,
'contenttpl' => $contenttpl,
'status' => $status,
'gid' => $gid,
'gtype' => $gtype,
'gnote' => $gnote,
'subname' => $subname,
'def1' => $def1,
'def2' => $def2,
'def3' => $def3,
'filename' => $filename,
'outlink' => $outlink,
'ico' => $ico,
'pic' => $pic,
'title' => $title,
'keywords' => $keywords,
'description' => $description,
'update_user' => session('username')
);
// 执行添加
if ($this->model->modSort($scode, $data, $modsub)) {
// 如果修改为单页并且跳转,则删除单页内容,否则判断是否存在内容,不存在则添加
if ($type == 1 && $outlink) {
$this->model->delContent($scode);
} elseif ($type == 1 && ! $this->model->findContent($scode)) {
$this->addSingle($scode, $name);
}
$this->log('修改数据内容栏目' . $scode . '成功!');
success('修改成功!', url('/admin/ContentSort/index'));
} else {
location(- 1);
}
} else { // 调取修改内容
$this->assign('mod', true);
$sort = $this->model->getSort($scode);
if (! $sort) {
error('编辑的内容已经不存在!', - 1);
}
$this->assign('sort', $sort);
// 父编码下拉选择
$sort_tree = $this->model->getSelect();
$sort_select = $this->makeSortSelect($sort_tree, $sort->pcode);
$this->assign('sort_select', $sort_select);
// 模板文件
$htmldir = $this->config('tpl_html_dir') ? '/' . $this->config('tpl_html_dir') : '';
$this->assign('tpls', file_list(ROOT_PATH . current($this->config('tpl_dir')) . '/' . $this->model->getTheme() . $htmldir));
// 内容模型
$models = model('admin.content.Model');
$this->assign('models', $models->getSelect());
// 获取会员分组
$this->assign('groups', model('admin.member.MemberGroup')->getSelect());
$this->display('content/contentsort.html');
}
}
// 添加栏目时执行单页内容增加
public function addSingle($scode, $title)
{
// 构建数据
$data = array(
'acode' => session('acode'),
'scode' => $scode,
'subscode' => '',
'title' => $title,
'titlecolor' => '#333333',
'subtitle' => '',
'filename' => '',
'author' => session('realname'),
'source' => '本站',
'outlink' => '',
'date' => date('Y-m-d H:i:s'),
'ico' => '',
'pics' => '',
'content' => '',
'tags' => '',
'enclosure' => '',
'keywords' => '',
'description' => '',
'sorting' => 255,
'status' => 1,
'istop' => 0,
'isrecommend' => 0,
'isheadline' => 0,
'gid' => 0,
'gtype' => 4,
'gnote' => '',
'visits' => 0,
'likes' => 0,
'oppose' => 0,
'create_user' => session('username'),
'update_user' => session('username')
);
// 执行添加
if ($this->model->addSingle($data)) {
return true;
} else {
return false;
}
}
}

View File

@@ -0,0 +1,259 @@
<?php
/**
* @copyright (C)2016-2099 Hnaoyun Inc.
* @author XingMeng
* @email hnxsh@foxmail.com
* @date 2017年12月15日
* 单页内容控制器
*/
namespace app\admin\controller\content;
use core\basic\Controller;
use app\admin\model\content\SingleModel;
class SingleController extends Controller
{
private $model;
private $blank;
public function __construct()
{
$this->model = new SingleModel();
}
// 单页内容列表
public function index()
{
if ((! ! $id = get('id', 'int')) && $result = $this->model->getSingle($id)) {
$this->assign('more', true);
$this->assign('content', $result);
} else {
$this->assign('list', true);
if (! $mcode = get('mcode', 'var')) {
error('传递的模型编码参数有误,请核对后重试!');
}
if (! ! ($field = get('field', 'var')) && ! ! ($keyword = get('keyword', 'vars'))) {
$result = $this->model->findSingle($mcode, $field, $keyword);
} else {
$result = $this->model->getList($mcode);
}
$this->assign('baidu_zz_token', $this->config('baidu_zz_token'));
$this->assign('baidu_ks_token', $this->config('baidu_ks_token'));
// 模型名称
$this->assign('model_name', model('admin.content.Model')->getName($mcode));
// 前端地址连接符判断
$url_break_char = $this->config('url_break_char') ?: '_';
$this->assign('url_break_char', $url_break_char);
$this->assign('contents', $result);
}
$this->display('content/single.html');
}
// 单页内容删除
public function del()
{
if (! $id = get('id', 'int')) {
error('传递的参数值错误!', - 1);
}
if ($this->model->delSingle($id)) {
$this->log('删除单页内容' . $id . '成功!');
success('删除成功!', - 1);
} else {
$this->log('删除单页内容' . $id . '失败!');
error('删除失败!', - 1);
}
}
// 单页内容修改
public function mod()
{
// 前端地址连接符判断
if (get('baiduzz') || get('baiduxzh')) {
$url_break_char = $this->config('url_break_char') ?: '_';
$url_rule_sort_suffix = $this->config('url_rule_sort_suffix') ? true : false;
}
// 站长普通推送
if (! ! $id = get('baiduzz')) {
$domain = get_http_url();
if (! $token = $this->config('baidu_zz_token')) {
alert_back('请先到系统配置中填写百度普通收录推送token值');
}
$api = "http://data.zz.baidu.com/urls?site=$domain&token=$token";
$data = $this->model->getSingle($id);
$data->urlname = $data->urlname ?: 'about';
if ($data->outlink) {
alert_back('链接类型不允许推送!');
}
if ($data->filename) {
$urls[] = $domain . homeurl('/home/Index/' . $data->filename, $url_rule_sort_suffix);
} else {
$urls[] = $domain . homeurl('/home/Index/' . $data->urlname . $url_break_char . $data->scode, $url_rule_sort_suffix);
}
$result = post_baidu($api, $urls);
if (isset($result->error)) {
$this->log('百度普通收录推送失败:' . $urls[0]);
alert_back('推送发生错误:' . $result->message);
} elseif (isset($result->success)) {
$this->log('百度普通收录推送成功:' . $urls[0]);
alert_back('成功推送' . $result->success . '条,今天剩余可推送' . $result->remain . '条数!');
} else {
alert_back('发生未知错误!');
}
}
// 站长快速推送
if (! ! $id = get('baiduks')) {
$domain = get_http_url();
if (! $token = $this->config('baidu_ks_token')) {
alert_back('请先到系统配置中填写百度快速收录推送token值');
}
$api = "http://data.zz.baidu.com/urls?site=$domain&token=$token&type=daily";
$data = $this->model->getSingle($id);
$data->urlname = $data->urlname ?: 'about';
if ($data->outlink) {
alert_back('链接类型不允许推送!');
}
if ($data->filename) {
$urls[] = $domain . homeurl('/home/Index/' . $data->filename, $url_rule_sort_suffix);
} else {
$urls[] = $domain . homeurl('/home/Index/' . $data->urlname . $url_break_char . $data->scode, $url_rule_sort_suffix);
}
$result = post_baidu($api, $urls);
if (isset($result->error)) {
$this->log('百度快速收录推送失败:' . $urls[0]);
alert_back('推送发生错误:' . $result->message);
} elseif (isset($result->success_daily)) {
$this->log('百度快速收录推送成功:' . $urls[0]);
alert_back('成功推送' . $result->success_daily . '条,今天剩余可推送' . $result->remain_daily . '条数!');
} else {
alert_back('发生未知错误!');
}
}
if (! $id = get('id', 'int')) {
error('传递的参数值错误!', - 1);
}
// 单独修改状态
if (($field = get('field', 'var')) && ! is_null($value = get('value', 'var'))) {
if ($this->model->modSingle($id, "$field='$value',update_user='" . session('username') . "'")) {
location(- 1);
} else {
alert_back('修改失败!');
}
}
// 修改操作
if ($_POST) {
// 获取数据
$title = post('title');
$author = post('author');
$source = post('source');
$ico = post('ico');
$pics = post('pics');
$content = post('content');
$tags = str_replace('', ',', post('tags'));
$titlecolor = post('titlecolor');
$subtitle = post('subtitle');
$outlink = post('outlink');
$date = post('date');
$enclosure = post('enclosure');
$keywords = post('keywords');
$description = post('description');
$status = post('status', 'int');
if (! $title) {
alert_back('单页内容标题不能为空!');
}
// 自动提起前一百个字符为描述
if (! $description && isset($_POST['content'])) {
$description = escape_string(clear_html_blank(substr_both(strip_tags($_POST['content']), 0, 150)));
}
// 缩放缩略图
if ($ico) {
resize_img(ROOT_PATH . $ico, '', $this->config('ico.max_width'), $this->config('ico.max_height'));
}
// 构建数据
$data = array(
'title' => $title,
'content' => $content,
'tags' => $tags,
'author' => $author,
'source' => $source,
'ico' => $ico,
'pics' => $pics,
'titlecolor' => $titlecolor,
'subtitle' => $subtitle,
'outlink' => $outlink,
'date' => $date,
'enclosure' => $enclosure,
'keywords' => $keywords,
'description' => clear_html_blank($description),
'status' => $status,
'update_user' => session('username')
);
// 执行添加
if ($this->model->modSingle($id, $data)) {
// 扩展内容修改
foreach ($_POST as $key => $value) {
if (preg_match('/^ext_[\w\-]+$/', $key)) {
$temp = post($key);
if (is_array($temp)) {
$data2[$key] = implode(',', $temp);
} else {
$data2[$key] = str_replace("\r\n", '<br>', $temp);
}
}
}
if (isset($data2)) {
if ($this->model->findContentExt($id)) {
$this->model->modContentExt($id, $data2);
} else {
$data2['contentid'] = $id;
$this->model->addContentExt($data2);
}
}
$this->log('修改单页内容' . $id . '成功!');
if (! ! $backurl = get('backurl')) {
success('修改成功!', base64_decode($backurl));
} else {
success('修改成功!', url('/admin/Single/index/mcode/1'));
}
} else {
location(- 1);
}
} else {
// 调取修改内容
$this->assign('mod', true);
if (! $result = $this->model->getSingle($id)) {
error('编辑的内容已经不存在!', - 1);
}
$this->assign('content', $result);
// 扩展字段
if (! $mcode = get('mcode', 'var')) {
error('传递的模型编码参数有误,请核对后重试!');
}
$this->assign('extfield', model('admin.content.ExtField')->getModelField($mcode));
$this->display('content/single.html');
}
}
}

View File

@@ -0,0 +1,132 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="renderer" content="webkit">
<title>网站管理中心-V{APP_VERSION}-{RELEASE_TIME}</title>
<link rel="shortcut icon" href="{SITE_DIR}/favicon.ico" type="image/x-icon">
<link rel="stylesheet" href="{APP_THEME_DIR}/layui/css/layui.css?v=v2.5.4">
<link rel="stylesheet" href="{APP_THEME_DIR}/font-awesome/css/font-awesome.min.css?v=v4.7.0" type="text/css">
<link rel="stylesheet" href="{APP_THEME_DIR}/css/comm.css?v=v3.0.6">
<link href="{APP_THEME_DIR}/css/jquery.treetable.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="{APP_THEME_DIR}/js/jquery-1.12.4.min.js"></script>
<script type="text/javascript" src="{APP_THEME_DIR}/js/jquery.treetable.js"></script>
</head>
<body class="layui-layout-body">
<!--定义部分地址方便JS调用-->
<div style="display: none">
<span id="controller" data-controller="{C}"></span>
<span id="url" data-url="{URL}"></span>
<span id="preurl" data-preurl="{fun=url('/admin',false)}"></span>
<span id="sitedir" data-sitedir="{SITE_DIR}"></span>
<span id="mcode" data-mcode="{$get.mcode}"></span>
</div>
<div class="layui-layout layui-layout-admin">
<div class="layui-header">
<div class="layui-logo">
<a href="{url./admin/Index/home}">
后台管理中心
{if(LICENSE==3)}
<span class="layui-badge">SVIP</span>
{else}
<span class="layui-badge layui-bg-gray">V{APP_VERSION}</span>
{/if}
</a>
</div>
<ul class="menu">
<li class="menu-ico" title="显示或隐藏侧边栏"><i class="fa fa-bars" aria-hidden="true"></i></li>
</ul>
{if(![$one_area])}
<form method="post" action="{url./admin/Index/area}" class="area-select">
<input type="hidden" name="formcheck" value="{$formcheck}" >
<div class="layui-col-xs8">
<select name="acode">
{$area_html}
</select>
</div>
<div class="layui-col-xs4">
<button type="submit" class="layui-btn layui-btn-sm">切换</button>
</div>
</form>
{/if}
<ul class="layui-nav layui-layout-right">
<li class="layui-nav-item layui-hide-xs">
<a href="{SITE_DIR}/" target="_blank"><i class="fa fa-home" aria-hidden="true"></i> 网站主页</a>
</li>
<li class="layui-nav-item layui-hide-xs">
<a href="{url./admin/Index/clearCache}"><i class="fa fa-trash-o" aria-hidden="true"></i> 清理缓存</a>
</li>
<li class="layui-nav-item layui-hide-xs">
<a href="javascript:;">
<i class="fa fa-user-circle-o" aria-hidden="true"></i> {$session.realname}
</a>
<dl class="layui-nav-child">
<dd><a href="{url./admin/Index/ucenter}"><i class="fa fa-address-card-o" aria-hidden="true"></i> 资料修改</a></dd>
<dd><a href="{url./admin/Index/loginOut}"><i class="fa fa-sign-out" aria-hidden="true"></i> 退出登录</a></dd>
</dl>
</li>
</ul>
</div>
<div class="layui-side layui-bg-black">
<div class="layui-side-scroll">
<!-- 左侧导航区域可配合layui已有的垂直导航 -->
<ul class="layui-nav layui-nav-tree" id="nav" lay-shrink="all">
{foreach $menu_tree(key,value)}
<li class="layui-nav-item nav-item {if([$primary_menu_url]==$value->url)}layui-nav-itemed{/if}">
<a class="" href="javascript:;"><i class="fa [value->ico]" aria-hidden="true"></i>[value->name]</a>
<dl class="layui-nav-child">
{if($value->mcode=='M130')}
{foreach $menu_models(key3,value3,num3)}
{if($value3->type==1)}
<dd><a href="{url./admin/Single/index/mcode/'.$value3->mcode.'}"><i class="fa fa-file-text-o" aria-hidden="true"></i>[value3->name]内容</a></dd>
{/if}
{if($value3->type==2)}
<dd><a href="{url./admin/Content/index/mcode/'.$value3->mcode.'}"><i class="fa fa-file-text-o" aria-hidden="true"></i>[value3->name]内容</a></dd>
{/if}
{/foreach}
{else}
{foreach $value->son(key2,value2,num2)}
{if(!isset($value2->status)|| $value2->status==1)}
<dd><a href="{url.'.$value2->url.'}"><i class="fa [value2->ico]" aria-hidden="true"></i>[value2->name]</a></dd>
{/if}
{/foreach}
{if($value->mcode=='M101' && session('ucode')==10001)}
<dd><a href="{url./admin/Upgrade/index}"><i class="fa fa-cloud-upload" aria-hidden="true"></i>在线更新</a></dd>
{/if}
{/if}
</dl>
</li>
{/foreach}
<li style="height:1px;background:#666" class="layui-hide-sm"></li>
<li class="layui-nav-item layui-hide-sm">
<a href="{SITE_DIR}/" target="_blank"><i class="fa fa-home" aria-hidden="true"></i> 网站主页</a>
</li>
<li class="layui-nav-item layui-hide-sm">
<a href="{url./admin/Index/ucenter}"><i class="fa fa-address-card-o" aria-hidden="true"></i> 资料修改</a>
</li>
<li class="layui-nav-item layui-hide-sm">
<a href="{url./admin/Index/clearCache}"><i class="fa fa-trash-o" aria-hidden="true"></i> 清理缓存</a>
</li>
<li class="layui-nav-item layui-hide-sm">
<a href="{url./admin/Index/loginOut}"><i class="fa fa-sign-out" aria-hidden="true"></i> 退出登录</a>
</li>
</ul>
</div>
</div>

View File

@@ -0,0 +1,102 @@
{include file='common/head.html'}
<div class="layui-body">
<div class="layui-tab layui-tab-brief" lay-filter="tab">
<ul class="layui-tab-title">
<li class="layui-this">公司信息</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
<form action="{url./admin/Company/mod}" method="post">
<input type="hidden" name="formcheck" value="{$formcheck}" >
<div class="layui-form-item">
<label class="layui-form-label">公司名称</label>
<div class="layui-input-block">
<input type="text" name="name" value="{$companys->name}" placeholder="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">公司地址</label>
<div class="layui-input-block">
<input type="text" name="address" value="{$companys->address}" placeholder="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">联系人</label>
<div class="layui-input-block">
<input type="text" name="contact" value="{$companys->contact}" placeholder="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">手机号码</label>
<div class="layui-input-block">
<input type="text" name="mobile" value="{$companys->mobile}" placeholder="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">电话号码</label>
<div class="layui-input-block">
<input type="text" name="phone" value="{$companys->phone}" placeholder="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">传真号码</label>
<div class="layui-input-block">
<input type="text" name="fax" value="{$companys->fax}" placeholder="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">电子邮箱</label>
<div class="layui-input-block">
<input type="text" name="email" value="{$companys->email}" placeholder="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">QQ号码</label>
<div class="layui-input-block">
<input type="text" name="qq" value="{$companys->qq}" placeholder="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">微信图标</label>
<div class="layui-input-inline">
<input type="text" name="weixin" id="weixin" value="{$companys->weixin}" placeholder="" class="layui-input">
</div>
<button type="button" class="layui-btn upload" data-des="weixin">
<i class="layui-icon">&#xe67c;</i>上传图片
</button>
<div id="weixin_box" class="pic"><dl><dt>{if(@[$companys->weixin])}<img src="{SITE_DIR}{$companys->weixin}" data-url="{$companys->weixin}"></dt><dd>删除</dd></dl>{/if}</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">其它信息</label>
<div class="layui-input-block">
<input type="text" name="other" value="{$companys->other}" placeholder="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit>立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
{include file='common/foot.html'}

View File

@@ -0,0 +1,425 @@
{include file='common/head.html'}
<div class="layui-body">
{if([$list])}
<div class="layui-tab layui-tab-brief" lay-filter="tab">
<ul class="layui-tab-title">
<li class="layui-this" lay-id="t1">{$model_name}内容</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
<form action="{url./admin/Single/index/mcode/'.get('mcode').'}" method="get" class="layui-form">
<div class="layui-form-item nospace">
<div class="layui-input-inline">
{$pathinfo}
<select name="field" class="form-control input-sm" style="width:auto;">
<option value="b.name" {if(get('field')=='b.name')}selected="selected" {/if}>栏目名称</option>
<option value="a.title" {if(get('field')=='a.title')}selected="selected" {/if} >文章标题</option>
<option value="a.content" {if(get('field')=='a.content')}selected="selected" {/if}>文章内容</option>
</select>
</div>
<div class="layui-input-inline">
<input type="text" name="keyword" value="{$get.keyword}" placeholder="请输入搜索关键字" class="layui-input">
</div>
<div class="layui-input-inline">
<button class="layui-btn" lay-submit>搜索</button>
<a class="layui-btn layui-btn-primary" href="{url./admin/Single/index/mcode/'.get('mcode').'}">清除搜索</a>
</div>
</div>
</form>
<table class="layui-table">
<thead>
<tr>
<th>ID</th>
<th>栏目</th>
<th>标题</th>
<th>时间</th>
<th>状态</th>
<th>访问量</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{foreach $contents(key,value)}
<tr>
<td>[value->id]</td>
<td title="[value->scode]">[value->sortname]</td>
<td title="[value->title]">
{fun=substr_both($value->title,0,15)}
{if($value->ico)}
<span class="layui-badge layui-bg-orange"></span>
{/if}
{if($value->pics)}
<span class="layui-badge"></span>
{/if}
{if($value->outlink)}
<span class="layui-badge layui-bg-black"></span>
{/if}
</td>
<td>[value->date]</td>
<td>
{if($value->status)}
<a href="{url./admin/'.C.'/mod/id/'.$value->id.'/field/status/value/0}"><i class='fa fa-toggle-on' title="点击关闭"></i></a>
{else}
<a href="{url./admin/'.C.'/mod/id/'.$value->id.'/field/status/value/1}"><i class='fa fa-toggle-off' title="点击开启"></i></a>
{/if}
</td>
<td>[value->visits]</td>
<td>
{if(!$value->outlink)}
{php}
$value->urlname=$value->urlname?:'about';
$url_rule_sort_suffix = \core\basic\Config::get('url_rule_sort_suffix') ? true : false;
{/php}
{if($value->filename)}
<a href="{fun=homeurl('/home/Index/'.$value->filename,$url_rule_sort_suffix)}" class="layui-btn layui-btn-xs layui-btn-primary" target="_blank">查看</a>
{else}
<a href="{fun=homeurl('/home/Index/'.$value->urlname.[$url_break_char].$value->scode,$url_rule_sort_suffix)}" class="layui-btn layui-btn-xs layui-btn-primary" target="_blank">查看</a>
{/if}
{/if}
{if(check_level('mod'))}
<a href="{url./admin/Single/mod/mcode/'.$value->mcode.'/id/'.$value->id.'}{$btnqs}" class="layui-btn layui-btn-xs" >修改</a>
{if([$baidu_zz_token] && !$value->outlink)}
<a href="{url./admin/'.C.'/mod/baiduzz/'.$value->id.'}" class="layui-btn layui-btn-xs layui-btn-primary" >百度普通推送</a>
{/if}
{if([$baidu_ks_token] && !$value->outlink)}
<a href="{url./admin/'.C.'/mod/baiduks/'.$value->id.'}" class="layui-btn layui-btn-xs layui-btn-primary" >百度快速推送</a>
{/if}
{/if}
</td>
</tr>
{/foreach}
</tbody>
</table>
</div>
</div>
</div>
{/if}
{if([$mod])}
<div class="layui-tab layui-tab-brief" lay-filter="tab">
<ul class="layui-tab-title">
<li class="layui-this">单页修改</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
<form action="{url./admin/Single/mod/id/'.[$get.id].'}{$backurl}" method="post" class="layui-form" id="edit">
<input type="hidden" name="formcheck" value="{$formcheck}" >
<div class="layui-tab">
<ul class="layui-tab-title">
<li class="layui-this">基本内容</li>
<li>高级内容</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
<div class="layui-form-item">
<label class="layui-form-label">内容标题 <span class="layui-text-red">*</span></label>
<div class="layui-input-block">
<input type="text" name="title" required lay-verify="required" value="{$content->title}" placeholder="请输入内容标题" class="layui-input">
</div>
</div>
{foreach $extfield(key,value)}
{if($value->type==1)} <!-- 单行文本 -->
<div class="layui-form-item">
<label class="layui-form-label">[value->description]</label>
<div class="layui-input-block">
<input type="text" name="[value->name]" value="{$content->{$value->name}}" placeholder="请输入[value->description]" class="layui-input">
</div>
</div>
{/if}
{if($value->type==2)}<!-- 多行文本 -->
<div class="layui-form-item">
<label class="layui-form-label">[value->description]</label>
<div class="layui-input-block">
<textarea name="[value->name]" class="layui-textarea" placeholder="请输入[value->description]">{php}$name=$value->name;echo str_replace('<br>', "\r\n",$this->vars['content']->$name);{/php}</textarea>
</div>
</div>
{/if}
{if($value->type==3)}<!-- 单选 -->
<div class="layui-form-item">
<label class="layui-form-label">[value->description]</label>
<div class="layui-input-block">
<div>
{php}
$radios=explode(',',$value->value);
$name=$value->name;
foreach ($radios as $value2) {
if($this->vars['content']->$name==$value2){
echo '<input type="radio" name="'.$value->name.'" value="'.$value2.'" title="'.$value2.'" checked>';
}else{
echo '<input type="radio" name="'.$value->name.'" value="'.$value2.'" title="'.$value2.'">';
}
}
{/php}
</div>
</div>
</div>
{/if}
{if($value->type==4)}<!-- 多选 -->
<div class="layui-form-item">
<label class="layui-form-label">[value->description]</label>
<div class="layui-input-block">
<div>
{php}
$checkboxs=explode(',',$value->value);
$name=$value->name;
echo '<input name="'.$value->name.'" type="hidden">';//占位清空
$values=explode(',',$this->vars['content']->$name);
foreach ($checkboxs as $value2) {
if(in_array($value2,$values)){
echo '<input type="checkbox" name="'.$value->name.'[]" value="'.$value2.'" title="'.$value2.'" checked>';
}else{
echo '<input type="checkbox" name="'.$value->name.'[]" value="'.$value2.'" title="'.$value2.'">';
}
}
{/php}
</div>
</div>
</div>
{/if}
{if($value->type==5)}<!-- 图片 -->
<div class="layui-form-item">
<label class="layui-form-label">[value->description]</label>
<div class="layui-input-inline">
<input type="text" name="[value->name]" id="[value->name]" value="{$content->{$value->name}}" placeholder="请上传[value->description]" class="layui-input">
</div>
<button type="button" class="layui-btn upload watermark" data-des="[value->name]">
<i class="layui-icon">&#xe67c;</i>上传图片
</button>
{php}$name=$value->name; {/php}
<div id="[value->name]_box" class="pic"><dl><dt>{if([$content]->$name)}<img src='{SITE_DIR}{$content->{$value->name}}' data-url="{$content->{$value->name}}"></dt><dd>删除</dd></dl>{/if}</div>
</div>
{/if}
{if($value->type==6)}<!-- 文件 -->
<div class="layui-form-item">
<label class="layui-form-label">[value->description]</label>
<div class="layui-input-inline">
<input type="text" name="[value->name]" id="[value->name]" value="{$content->{$value->name}}" placeholder="请上传[value->description]" class="layui-input">
</div>
<button type="button" class="layui-btn file" data-des="[value->name]">
<i class="layui-icon">&#xe67c;</i>上传文件
</button>
</div>
{/if}
{if($value->type==7)}<!-- 日期 -->
<div class="layui-form-item">
<label class="layui-form-label">[value->description]</label>
<div class="layui-input-block">
<input type="text" name="[value->name]" value="{$content->{$value->name}}" readonly placeholder="请选择[value->description]" class="layui-input datetime">
</div>
</div>
{/if}
{if($value->type==8)}<!-- 编辑器 -->
<div class="layui-form-item">
<label class="layui-form-label">[value->description]</label>
<div class="layui-input-block">
{php}
$name=@$value->name;
{/php}
<script type="text/plain" id="editor_[value->name]" name="[value->name]" style="width:100%;height:240px;">{fun=decode_string([$content->$name])}</script>
<script>
//初始化编辑器
$(document).ready(function (e) {
var ue = UE.getEditor('editor_[value->name]',{
maximumWords:10000
});
})
</script>
</div>
</div>
{/if}
{if($value->type==9)}<!-- 下拉 -->
<div class="layui-form-item">
<label class="layui-form-label">[value->description]</label>
<div class="layui-input-block">
<select name="[value->name]">
{php}
$selects=explode(',',$value->value);
$name=$value->name;
foreach ($selects as $value2) {
if($this->vars['content']->$name==$value2){
echo '<option value="'.$value2.'" selected>'.$value2.'</option>';
}else{
echo '<option value="'.$value2.'">'.$value2.'</option>';
}
}
{/php}
</select>
</div>
</div>
{/if}
{/foreach}
<div class="layui-form-item">
<label class="layui-form-label">内容</label>
<div class="layui-input-block">
<script type="text/plain" id="editor" name="content" style="width:100%;height:240px;">{fun=decode_string([$content->content])}</script>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">tags</label>
<div class="layui-input-block">
<input type="text" name="tags" placeholder="请输入文章tag英文逗号隔开" value="{$content->tags}" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">作者</label>
<div class="layui-input-block">
<input type="text" name="author" placeholder="请输入作者" value="{$content->author}" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">来源</label>
<div class="layui-input-block">
<input type="text" name="source" placeholder="请输入来源" value="{$content->source}" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">缩略图</label>
<div class="layui-input-inline">
<input type="text" name="ico" id="ico" value="{$content->ico}" placeholder="请上传缩略图" class="layui-input">
</div>
<button type="button" class="layui-btn upload watermark" data-des="ico">
<i class="layui-icon">&#xe67c;</i>上传图片
</button>
<div id="ico_box" class="pic addedit">{if([$content->ico])}<dl><dt><img src="{SITE_DIR}{$content->ico}" data-url="{$content->ico}"></dt><dd>删除</dd></dl>{/if}</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">轮播多图</label>
<div class="layui-input-inline">
<input type="text" name="pics" id="pics" value="{$content->pics}" placeholder="请上传轮播多图" class="layui-input">
</div>
<button type="button" class="layui-btn uploads watermark" data-des="pics">
<i class="layui-icon">&#xe67c;</i>上传多图
</button>
<div id="pics_box" class="pic addedit">
<dl></dl> <!-- 规避空内容拖动bug -->
{php}
if([$content->pics]){
$pics=explode(',',[$content->pics]);
}else{
$pics = array();
}
foreach ($pics as $value) {
echo "<dl><dt><img src='".SITE_DIR.$value."' data-url='".$value."'></dt><dd>删除</dd></dl></dl>";
}
{/php}
</div>
</div>
</div>
<div class="layui-tab-item ">
<div class="layui-form-item">
<label class="layui-form-label">标题颜色</label>
<div class="layui-input-inline">
<input type="text" name="titlecolor" value="{$content->titlecolor}" placeholder="请选择标题颜色" class="layui-input jscolor {hash:true}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">副标题</label>
<div class="layui-input-block">
<input type="text" name="subtitle" value="{$content->subtitle}" placeholder="请输入副标题" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">时间</label>
<div class="layui-input-inline">
<input type="text" name="date" value="{$content->date}" readonly placeholder="请选择发布时间" class="layui-input datetime">
</div>
<div class="layui-form-mid layui-word-aux">温馨提示:单页不支持定时发布!</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">附件</label>
<div class="layui-input-inline">
<input type="text" name="enclosure" id="enclosure" value="{$content->enclosure}" placeholder="请上传附件" class="layui-input">
</div>
<button type="button" class="layui-btn file" data-des="enclosure">
<i class="layui-icon">&#xe67c;</i>上传附件
</button>
</div>
<div class="layui-form-item">
<label class="layui-form-label">SEO关键字</label>
<div class="layui-input-block">
<input type="text" name="keywords" value="{$content->keywords}" placeholder="请输入详情页SEO关键字" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">SEO描述</label>
<div class="layui-input-block">
<textarea name="description" placeholder="请输入详情页SEO描述" class="layui-textarea">{$content->description}</textarea>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">状态</label>
<div class="layui-input-block">
<input type="radio" name="status" value="1" title="显示" {if([$content->status]==1)} checked="checked"{/if}>
<input type="radio" name="status" value="0" title="隐藏" {if([$content->status]==0)} checked="checked"{/if}>
</div>
</div>
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit>立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
{fun=get_btn_back()}
</div>
</div>
</form>
</div>
</div>
</div>
{/if}
</div>
<style>.placeHolder {border:dashed 2px gray; }</style>
<script type="text/javascript" src="{APP_THEME_DIR}/js/jquery.dragsort-0.5.2.min.js"></script>
<script type="text/javascript">
$("#pics_box").dragsort({
dragSelector: "dl",
dragSelectorExclude: "input,textarea,dd",
dragBetween: false,
dragEnd: saveOrder,
placeHolderTemplate: "<dl class='placeHolder'><dt></dt></dl>"
});
function saveOrder() {
var data = $("#pics_box dl dt img").map(function() {
return $(this).data("url");
}).get();
$("input[name=pics]").val(data.join(","))
};
</script>
<script type="text/javascript" src="{APP_THEME_DIR}/js/jscolor.js"></script>
{include file='common/ueditor.html'}
{include file='common/foot.html'}

View File

@@ -0,0 +1,101 @@
{include file='common/head.html'}
<div class="layui-body">
<div class="layui-tab layui-tab-brief" lay-filter="tab">
<ul class="layui-tab-title">
<li class="layui-this">站点信息</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
<form action="{url./admin/Site/mod}" method="post" class="layui-form">
<input type="hidden" name="formcheck" value="{$formcheck}" >
<div class="layui-form-item">
<label class="layui-form-label">站点标题</label>
<div class="layui-input-block">
<input type="text" name="title" value="{$sites->title}" placeholder="请输入站点标题" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">站点域名</label>
<div class="layui-input-block">
<input type="text" name="domain" value="{$sites->domain}" placeholder="请输入站点域名" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">站点LOGO</label>
<div class="layui-input-inline">
<input type="text" name="logo" id="logo" value="{$sites->logo}" placeholder="请上传站点LOGO图" class="layui-input">
</div>
<button type="button" class="layui-btn upload" data-des="logo">
<i class="layui-icon">&#xe67c;</i>上传图片
</button>
<div id="logo_box" class="pic"><dl><dt>{if(@[$sites->logo])}<img src="{SITE_DIR}{$sites->logo}" data-url="{$sites->logo}"></dt><dd>删除</dd></dl>{/if}</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">站点关键字</label>
<div class="layui-input-block">
<input type="text" name="keywords" value="{$sites->keywords}" placeholder="请输入站点关键字" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">站点描述</label>
<div class="layui-input-block">
<textarea name="description" placeholder="请输入站点描述" class="layui-textarea">{$sites->description}</textarea>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">站点备案</label>
<div class="layui-input-block">
<input type="text" name="icp" value="{$sites->icp}" placeholder="请输入站点备案" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">站点模板</label>
<div class="layui-input-block">
<select name="theme">
{foreach $themes(key,value)}
{if($value == [$sites->theme])}
<option value="[value]" selected='selected'>[value]</option>
{else}
<option value="[value]">[value]</option>
{/if}
{/foreach}
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">统计代码</label>
<div class="layui-input-block">
<textarea name="statistical" placeholder="请输入统计代码" class="layui-textarea">{$sites->statistical}</textarea>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">尾部信息</label>
<div class="layui-input-block">
<textarea name="copyright" placeholder="请输入尾部信息" class="layui-textarea">{$sites->copyright}</textarea>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit>立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
{include file='common/foot.html'}

View File

@@ -0,0 +1,78 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="renderer" content="webkit">
<title>网站管理中心-V{APP_VERSION}-{RELEASE_TIME}</title>
<link rel="shortcut icon" href="{SITE_DIR}/favicon.ico" type="image/x-icon">
<link rel="stylesheet" href="{APP_THEME_DIR}/layui/css/layui.css?v=v2.5.4">
<link rel="stylesheet" href="{APP_THEME_DIR}/font-awesome/css/font-awesome.min.css?v=v4.7.0" type="text/css">
<link rel="stylesheet" href="{APP_THEME_DIR}/css/login.css?v=v1.1.6">
<script type="text/javascript" src="{APP_THEME_DIR}/js/jquery-1.12.4.min.js"></script>
</head>
<body>
<div class="user-login" >
<div class="user-login-main">
<div class="user-login-header">
<h2>
网站管理中心
</h2>
<p>高效、简洁、强悍的PHP企业网站管理系统</p>
</div>
<form action="{url./admin/Index/login}" onsubmit="return false" class="layui-form" id="dologin">
<input type="hidden" name="formcheck" id="formcheck" value="{$formcheck}" >
<div class="user-login-box">
<div class="layui-form-item">
<label class="user-login-icon layui-icon layui-icon-username"></label>
<input name="username" id="username" type="text" lay-verify="required" placeholder="用户名" autocomplete="off" class="layui-input">
</div>
<div class="layui-form-item">
<label class="user-login-icon layui-icon layui-icon-password"></label>
<input name="password" id="password" type="password" lay-verify="required" placeholder="密码" autocomplete="off" class="layui-input">
</div>
{if([$config.admin_check_code])}
<div class="layui-form-item">
<div class="layui-row">
<div class="layui-col-xs7 layui-col-sm8">
<label class="user-login-icon layui-icon layui-icon-vercode" ></label>
<input name="checkcode" id="checkcode" type="text" lay-verify="required" placeholder="验证码" autocomplete="off" class="layui-input">
</div>
<div class="layui-col-xs5 layui-col-sm4">
<div style="margin-left: 10px;">
<img title="点击刷新" src="{CORE_DIR}/code.php" class="user-login-codeimg" id="codeimg" onclick="this.src='{CORE_DIR}/code.php?'+Math.round(Math.random()*10);" />
</div>
</div>
</div>
</div>
{/if}
<div class="layui-form-item">
<button class="layui-btn layui-btn-fluid" lay-submit lay-filter="login-submit" >登 录</button>
</div>
<div style="color:red;" id="note"></div>
</div>
</form>
</div>
<div class="layui-trans user-login-footer">
<p>© 2018-{fun=date('Y')}</p>
</div>
</div>
<script type="text/javascript" src="{APP_THEME_DIR}/layui/layui.all.js?v=v2.5.4"></script>
<script type="text/javascript" src="{APP_THEME_DIR}/js/mylayui.js?v=v1.1.6"></script>
<!-- 让IE8/9支持媒体查询从而兼容栅格 -->
<!--[if lt IE 9]>
<script src="https://cdn.staticfile.org/html5shiv/r29/html5.min.js"></script>
<script src="https://cdn.staticfile.org/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
</body>
</html>

View File

@@ -0,0 +1,806 @@
{include file='common/head.html'}
<div class="layui-body">
<div class="layui-tab layui-tab-brief" lay-filter="tab">
<ul class="layui-tab-title">
<li class="layui-this" lay-id="t1">基本配置</li>
<li lay-id="t2">邮件通知</li>
<li lay-id="t3">百度接口</li>
<li lay-id="t4">WebAPI</li>
<li lay-id="t5">图片水印</li>
<li lay-id="t6">安全配置</li>
<li lay-id="t7">URL规则</li>
<li lay-id="t8">标题样式</li>
<li lay-id="t9">会员配置</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
<form action="{url./admin/Config/index}" method="post" class="layui-form">
<input type="hidden" name="formcheck" value="{$formcheck}" >
<div class="layui-form-item">
<label class="layui-form-label">网站状态</label>
<div class="layui-input-block">
<input type="radio" name="close_site" value="1" {if([$configs.close_site.value]==1)} checked="checked" {/if} title="关闭">
<input type="radio" name="close_site" value="0" {if([$configs.close_site.value]==0)} checked="checked" {/if} title="开启">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">关站提示</label>
<div class="layui-input-inline">
<textarea name="close_site_note" placeholder="" class="layui-textarea">{$configs.close_site_note.value}</textarea>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">独立手机版</label>
<div class="layui-input-block">
<input type="radio" name="open_wap" value="1" {if([$configs.open_wap.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="open_wap" value="0" {if([$configs.open_wap.value]==0)} checked="checked" {/if} title="禁用">
<span class="layui-icon layui-icon-about tips" data-content="使用响应式模板的用户请不要开启!"></span>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">手机版域名绑定</label>
<div class="layui-input-inline">
<input type="text" name="wap_domain" value="{$configs.wap_domain.value}" placeholder="如m.baidu.com" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">动态缓存</label>
<div class="layui-input-block">
<input type="radio" name="tpl_html_cache" value="1" {if([$configs.tpl_html_cache.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="tpl_html_cache" value="0" {if([$configs.tpl_html_cache.value]==0)} checked="checked" {/if} title="禁用">
<span class="layui-icon layui-icon-about tips" data-content="本功能效果接近生成静态,开启后将提高前端访问速度及并发能力!"></span>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">缓存有效期(秒)</label>
<div class="layui-input-inline">
<input type="text" name="tpl_html_cache_time" value="{$configs.tpl_html_cache_time.value}" placeholder="请输入缓存有效期(秒)" class="layui-input">
</div>
<div class="layui-form-mid layui-word-aux"></div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">Gzip页面压缩</label>
<div class="layui-input-block">
<input type="radio" name="gzip" value="1" {if([$configs.gzip.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="gzip" value="0" {if([$configs.gzip.value]==0)} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">会话文件路径</label>
<div class="layui-input-block">
<input type="radio" name="session_in_sitepath" value="1" {if([$configs.session_in_sitepath.value]==1)} checked="checked" {/if} title="站内">
<input type="radio" name="session_in_sitepath" value="0" {if([$configs.session_in_sitepath.value]==0)} checked="checked" {/if} title="系统">
<span class="layui-icon layui-icon-about tips" data-content="站内则使用站点下runtime路径系统则使用操作系统的缓存路径"></span>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">跨语言自动切换</label>
<div class="layui-input-block">
<input type="radio" name="lgautosw" value="1" {if([$configs.lgautosw.value]=='1'||[$configs.lgautosw.value]=='')} checked="checked" {/if} title="启用">
<input type="radio" name="lgautosw" value="0" {if([$configs.lgautosw.value]=='0')} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">自动转HTTPS</label>
<div class="layui-input-block">
<input type="radio" name="to_https" value="1" {if([$configs.to_https.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="to_https" value="0" {if([$configs.to_https.value]==0)} checked="checked" {/if} title="禁用">
<span class="layui-icon layui-icon-about tips" data-content="访问非HTPPS地址时自动跳转"></span>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">自动转主域名</label>
<div class="layui-input-block">
<input type="radio" name="to_main_domain" value="1" {if([$configs.to_main_domain.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="to_main_domain" value="0" {if([$configs.to_main_domain.value]==0)} checked="checked" {/if} title="禁用">
<span class="layui-icon layui-icon-about tips" data-content="访问非主域名地址时自动跳转!"></span>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">网站主域名</label>
<div class="layui-input-inline">
<input type="text" name="main_domain" value="{$configs.main_domain.value}" placeholder="如www.baidu.com" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">分页数字条数量</label>
<div class="layui-input-inline">
<input type="text" name="pagenum" value="{$configs.pagenum.value}" placeholder="请输入前端分页数字条显示数量" class="layui-input">
</div>
<div class="layui-form-mid layui-word-aux"></div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">内链替换次数</label>
<div class="layui-input-inline">
<input type="text" name="content_tags_replace_num" value="{$configs.content_tags_replace_num.value}" placeholder="请输入文章内链替换次数默认3次" class="layui-input">
</div>
<div class="layui-form-mid layui-word-aux"></div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">敏感词过滤</label>
<div class="layui-input-inline">
<textarea name="content_keyword_replace" placeholder="请输入需要过滤的关键词,多个之间逗号隔开" class="layui-textarea">{$configs.content_keyword_replace.value}</textarea>
<div class="layui-form-mid layui-word-aux">注:多个敏感词之间用逗号隔开!</div>
</div>
</div>
{if(LICENSE<2)}
<div class="layui-form-item">
<label class="layui-form-label">系统授权码</label>
<div class="layui-input-inline">
<input type="text" name="sn" value="{$configs.sn.value}" placeholder="请输入授权码,多个授权码用逗号隔开" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">授权码手机</label>
<div class="layui-input-inline">
<input type="text" name="sn_user" value="{$configs.sn_user.value}" placeholder="请购买了万能授权码的用户填写" class="layui-input">
</div>
</div>
{/if}
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit name="submit" value="basic">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
<div class="layui-tab-item">
<form action="{url./admin/Config/index}" method="post" class="layui-form">
<input type="hidden" name="formcheck" value="{$formcheck}" >
<div class="layui-form-item">
<label class="layui-form-label">服务器状态 </label>
<div class="layui-input-block" style="line-height:36px;">
stream_socket_client函数<i class="layui-icon layui-icon-ok-circle" style="color: {php}echo function_exists('stream_socket_client')?'#5FB878':'#f2f2f2';{/php}"></i>&nbsp;&nbsp;&nbsp;
fsockopen函数 <i class="layui-icon layui-icon-ok-circle" style="color: {php}echo function_exists('fsockopen')?'#5FB878':'#f2f2f2';{/php}"></i>
<span class="layui-icon layui-icon-about tips" data-content="至少需要支持其中一个函数才能正常使用!"></span>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">SMTP服务器</label>
<div class="layui-input-inline">
<input type="text" name="smtp_server" value="{$configs.smtp_server.value}" placeholder="请输入SMTP服务器" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">SMTP端口</label>
<div class="layui-input-inline">
<input type="text" name="smtp_port" value="{$configs.smtp_port.value}" placeholder="请输入SMTP端口,一般SSL为465普通为25" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">是否为SSL</label>
<div class="layui-input-block">
<input type="radio" name="smtp_ssl" value="1" {if([$configs.smtp_ssl.value]==1)} checked="checked" {/if} title="是">
<input type="radio" name="smtp_ssl" value="0" {if([$configs.smtp_ssl.value]==0)} checked="checked" {/if} title="否">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">邮箱账号</label>
<div class="layui-input-inline">
<input type="text" name="smtp_username" value="{$configs.smtp_username.value}" placeholder="请输入邮箱账号" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">邮箱密码</label>
<div class="layui-input-inline">
<input type="password" name="smtp_password" value="{$configs.smtp_password.value}" placeholder="请输入邮箱密码或邮箱授权码" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">测试账号</label>
<div class="layui-input-inline">
<input type="text" name="smtp_username_test" id="smtp_username_test" value="{$configs.smtp_username_test.value}" placeholder="请输入用于接受测试邮件的账号" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">留言发送邮件</label>
<div class="layui-input-block">
<input type="radio" name="message_send_mail" value="1" {if([$configs.message_send_mail.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="message_send_mail" value="0" {if([$configs.message_send_mail.value]==0)} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">表单发送邮件</label>
<div class="layui-input-block">
<input type="radio" name="form_send_mail" value="1" {if([$configs.form_send_mail.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="form_send_mail" value="0" {if([$configs.form_send_mail.value]==0)} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">评论发送邮件</label>
<div class="layui-input-block">
<input type="radio" name="comment_send_mail" value="1" {if([$configs.comment_send_mail.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="comment_send_mail" value="0" {if([$configs.comment_send_mail.value]==0)} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">信息接收邮箱</label>
<div class="layui-input-inline">
<input type="text" name="message_send_to" value="{$configs.message_send_to.value}" placeholder="请输入信息接收邮箱" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit name="submit" value="email">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
<a href="{url./admin/Config/index/action/sendemail}" onclick="return sendtest(this,'#smtp_username_test')" class="layui-btn layui-btn-primary">发送测试邮件</a>
</div>
</div>
<script>
function sendtest(obj,to){
$(obj).attr('href',$(obj).attr('href')+'&to='+$(to).val());
return true;
}
</script>
</form>
</div>
<div class="layui-tab-item">
<form action="{url./admin/Config/index}" method="post" class="layui-form">
<input type="hidden" name="formcheck" value="{$formcheck}" >
<div class="layui-form-item">
<label class="layui-form-label">普通收录token</label>
<div class="layui-input-inline">
<input type="text" name="baidu_zz_token" value="{$configs.baidu_zz_token.value}" placeholder="请输入普通收录token" class="layui-input">
</div>
<span class="layui-icon layui-icon-about tips" data-content="请到百度站长中心获取!"></span>
</div>
<div class="layui-form-item">
<label class="layui-form-label">快速收录token</label>
<div class="layui-input-inline">
<input type="text" name="baidu_ks_token" value="{$configs.baidu_ks_token.value}" placeholder="请输入快速收录token" class="layui-input">
</div>
<span class="layui-icon layui-icon-about tips" data-content="请到百度站长中心获取!"></span>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit name="submit" value="baidu">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
<div class="layui-tab-item">
<form action="{url./admin/Config/index}" method="post" class="layui-form">
<input type="hidden" name="formcheck" value="{$formcheck}" >
<div class="layui-form-item">
<label class="layui-form-label">API状态</label>
<div class="layui-input-block">
<input type="radio" name="api_open" value="1" {if(@[$configs.api_open.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="api_open" value="0" {if(@[$configs.api_open.value]==0)} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">API强制认证</label>
<div class="layui-input-block">
<input type="radio" name="api_auth" value="1" {if(@[$configs.api_auth.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="api_auth" value="0" {if(@[$configs.api_auth.value]==0)} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">API认证用户</label>
<div class="layui-input-inline">
<input type="text" name="api_appid" value="{$configs.api_appid.value}" placeholder="请输入API认证用户名" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">API认证密钥</label>
<div class="layui-input-inline">
<input type="password" name="api_secret" value="{$configs.api_secret.value}" placeholder="请输入API认证密钥" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit name="submit" value="api">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
<div class="layui-tab-item">
<form action="{url./admin/Config/index}" method="post" class="layui-form">
<input type="hidden" name="formcheck" value="{$formcheck}" >
<div class="layui-form-item">
<label class="layui-form-label">状态</label>
<div class="layui-input-block">
<input type="radio" name="watermark_open" value="1" {if(@[$configs.watermark_open.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="watermark_open" value="0" {if(@[$configs.watermark_open.value]==0)} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">水印文字</label>
<div class="layui-input-inline">
<input type="text" name="watermark_text" value="{$configs.watermark_text.value}" placeholder="请输入水印文字Baidu" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">文字字体</label>
<div class="layui-input-inline">
<input type="text" name="watermark_text_font" id="watermark_text_font" value="{$configs.watermark_text_font.value}" placeholder="请上传水印文字字体" class="layui-input">
</div>
<button type="button" class="layui-btn file" data-des="watermark_text_font">
<i class="layui-icon">&#xe67c;</i>上传字体
</button>
</div>
<div class="layui-form-item">
<label class="layui-form-label">文字大小</label>
<div class="layui-input-inline">
<input type="text" name="watermark_text_size" value="{$configs.watermark_text_size.value}" placeholder="请输入水印文字大小20" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">文字颜色</label>
<div class="layui-input-inline">
<input type="text" name="watermark_text_color" value="{$configs.watermark_text_color.value}" placeholder="请输入水印文字颜色100,100,100" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">水印图片</label>
<div class="layui-input-inline">
<input type="text" name="watermark_pic" id="watermark_pic" value="{$configs.watermark_pic.value}" placeholder="请上传水印图片,优先文字水印" class="layui-input">
</div>
<button type="button" class="layui-btn upload" data-des="watermark_pic">
<i class="layui-icon">&#xe67c;</i>上传图片
</button>
<div id="watermark_pic_box" class="pic"><dl><dt>{if(@[$configs.watermark_pic.value])}<img src="{SITE_DIR}{$configs.watermark_pic.value}" data-url="{$configs.watermark_pic.value}"></dt><dd>删除</dd></dl>{/if}</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">水印位置</label>
<div class="layui-input-block">
<input type="radio" name="watermark_position" value="1" {if(@[$configs.watermark_position.value]==1)} checked="checked" {/if} title="左上">
<input type="radio" name="watermark_position" value="2" {if(@[$configs.watermark_position.value]==2)} checked="checked" {/if} title="右上">
<input type="radio" name="watermark_position" value="3" {if(@[$configs.watermark_position.value]==3)} checked="checked" {/if} title="左下">
<input type="radio" name="watermark_position" value="4" {if(@[$configs.watermark_position.value]==4)} checked="checked" {/if} title="右下">
<input type="radio" name="watermark_position" value="5" {if(@[$configs.watermark_position.value]==5)} checked="checked" {/if} title="中间">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit name="submit" value="watermark">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
<div class="layui-tab-item">
<form action="{url./admin/Config/index}" method="post" class="layui-form">
<input type="hidden" name="formcheck" value="{$formcheck}" >
<div class="layui-form-item">
<label class="layui-form-label">留言功能</label>
<div class="layui-input-block">
<input type="radio" name="message_status" value="1" {if([$configs.message_status.value]=='1'||[$configs.message_status.value]=='')} checked="checked" {/if} title="启用">
<input type="radio" name="message_status" value="0" {if([$configs.message_status.value]=='0')} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">留言验证码</label>
<div class="layui-input-block">
<input type="radio" name="message_check_code" value="1" {if([$configs.message_check_code.value]=='1'||[$configs.message_check_code.value]=='')} checked="checked" {/if} title="启用">
<input type="radio" name="message_check_code" value="0" {if([$configs.message_check_code.value]=='0')} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">留言审核</label>
<div class="layui-input-block">
<input type="radio" name="message_verify" value="1" {if([$configs.message_verify.value]=='1'||[$configs.message_verify.value]=='')} checked="checked" {/if} title="启用">
<input type="radio" name="message_verify" value="0" {if([$configs.message_verify.value]=='0')} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">留言需登录</label>
<div class="layui-input-block">
<input type="radio" name="message_rqlogin" value="1" {if([$configs.message_rqlogin.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="message_rqlogin" value="0" {if([$configs.message_rqlogin.value]==0)} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">表单功能</label>
<div class="layui-input-block">
<input type="radio" name="form_status" value="1" {if([$configs.form_status.value]=='1'||[$configs.form_status.value]=='')} checked="checked" {/if} title="启用">
<input type="radio" name="form_status" value="0" {if([$configs.form_status.value]=='0')} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">表单验证码</label>
<div class="layui-input-block">
<input type="radio" name="form_check_code" value="1" {if([$configs.form_check_code.value]=='1'||[$configs.form_check_code.value]=='')} checked="checked" {/if} title="启用">
<input type="radio" name="form_check_code" value="0" {if([$configs.form_check_code.value]=='0')} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">模板子目录</label>
<div class="layui-input-inline">
<input type="text" name="tpl_html_dir" value="{$configs.tpl_html_dir.value}" placeholder="首次请手动移动模板文件到填写的目录!" class="layui-input">
</div>
<span class="layui-icon layui-icon-about tips" data-content="一定程度上防盗,如填 html则默认模板情况下路径为 default/html 目录!"></span>
</div>
<div class="layui-form-item">
<label class="layui-form-label">IP黑名单</label>
<div class="layui-input-inline">
<textarea name="ip_deny" placeholder="请输入需要禁止访问的IP多个之间逗号隔开IP地址支持使用/掩码位数模式192.168.1.0/24, 192.168.2.100" class="layui-textarea">{$configs.ip_deny.value}</textarea>
</div>
<span class="layui-icon layui-icon-about tips" data-content="请输入需要禁止访问的IP多个之间逗号隔开IP地址支持使用/掩码位数模式192.168.1.0/24, 192.168.2.100"></span>
</div>
<div class="layui-form-item">
<label class="layui-form-label">IP白名单</label>
<div class="layui-input-inline">
<textarea name="ip_allow" placeholder="请输入需要允许访问的IP多个之间逗号隔开IP地址支持使用/掩码位数模式192.168.1.0/24, 192.168.2.100" class="layui-textarea">{$configs.ip_allow.value}</textarea>
</div>
<span class="layui-icon layui-icon-about tips" data-content="请输入需要允许访问的IP多个之间逗号隔开IP地址支持使用/掩码位数模式192.168.1.0/24,192.168.2.100"></span>
</div>
<hr>
<div class="layui-form-item">
<label class="layui-form-label">后台验证码</label>
<div class="layui-input-block">
<input type="radio" name="admin_check_code" value="1" {if([$configs.admin_check_code.value]=='1'||[$configs.admin_check_code.value]=='')} checked="checked" {/if} title="启用">
<input type="radio" name="admin_check_code" value="0" {if([$configs.admin_check_code.value]=='0')} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">后台登录阀值</label>
<div class="layui-input-inline">
<input type="text" name="lock_count" value="{$configs.lock_count.value}" placeholder="请输入后台登录失败几次后锁定IP默认5次" class="layui-input">
</div>
<div class="layui-form-mid layui-word-aux"></div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">失败锁定时间</label>
<div class="layui-input-inline">
<input type="text" name="lock_time" value="{$configs.lock_time.value}" placeholder="请输入后台登录异常锁定时间默认为900秒" class="layui-input">
</div>
<div class="layui-form-mid layui-word-aux"></div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit name="submit" value="security">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
<div class="layui-tab-item">
<form action="{url./admin/Config/index}" method="post" class="layui-form">
<input type="hidden" name="formcheck" value="{$formcheck}" >
<div class="layui-form-item">
<label class="layui-form-label">地址模式</label>
<div class="layui-input-block">
<P>
<input type="radio" name="url_rule_type" value="1" {if([$configs.url_rule_type.value]==1)} checked="checked" {/if} title="普通模式,类似:/index.php/product/1.html">
<span class="layui-icon layui-icon-about tips" data-content="基本模式需要服务器支持pathinfo,特别是nginx下pathinfo要手动配置"></span>
</P>
<P>
<input type="radio" name="url_rule_type" value="2" {if([$configs.url_rule_type.value]==2)} checked="checked" {/if} title="伪静态模式,类似:/product/1.html">
<span class="layui-icon layui-icon-about tips" data-content="伪静态时需要服务器环境的支持,并需要添加伪静态规则!"></span>
</P>
<P>
<input type="radio" name="url_rule_type" value="3" {if([$configs.url_rule_type.value]==3||![$configs.url_rule_type.value])} checked="checked" {/if} title="兼容模式,类似:/?product/1.html">
</P>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">栏目显示后缀</label>
<div class="layui-input-block">
<input type="radio" name="url_rule_sort_suffix" value="1" {if([$configs.url_rule_sort_suffix.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="url_rule_sort_suffix" value="0" {if([$configs.url_rule_sort_suffix.value]==0)} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit name="submit" value="urlrule">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
<div class="layui-tab-item">
<form action="{url./admin/Config/index}" method="post" class="layui-form">
<input type="hidden" name="formcheck" value="{$formcheck}" >
<div class="layui-form-item">
<label class="layui-form-label">常用组合标签: </label>
<div class="layui-input-block" style="line-height:36px;">
<p>全局标签:{pboot:sitetitle}站点标题、{pboot:sitesubtitle}站点副标题</p>
<p>列表或内容页:{sort:name}栏目名称、{sort:title}栏目标题</p>
<p>内容页:{content:title}内容标题</p>
<p>搜索结果页:{pboot:keyword}搜索关键字</p>
<p>个人中心:{user:nickname}会员昵称</p>
<p>例如定义内容页样式:{content:title}-{sort:name}-{pboot:sitetitle}-{pboot:sitesubtitle}</p>
<p>以下配置参数不设置时将使用系统默认规则。</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">首页</label>
<div class="layui-input-block">
<input type="text" name="index_title" value="{$configs.index_title.value}" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">专题页</label>
<div class="layui-input-block">
<input type="text" name="about_title" value="{$configs.about_title.value}" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">列表页</label>
<div class="layui-input-block">
<input type="text" name="list_title" value="{$configs.list_title.value}" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">内容页</label>
<div class="layui-input-block">
<input type="text" name="content_title" value="{$configs.content_title.value}" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">搜索结果页</label>
<div class="layui-input-block">
<input type="text" name="search_title" value="{$configs.search_title.value}" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">会员注册页</label>
<div class="layui-input-block">
<input type="text" name="register_title" value="{$configs.register_title.value}" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">会员登录页</label>
<div class="layui-input-block">
<input type="text" name="login_title" value="{$configs.login_title.value}" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">个人中心页</label>
<div class="layui-input-block">
<input type="text" name="ucenter_title" value="{$configs.ucenter_title.value}" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">资料修改页</label>
<div class="layui-input-block">
<input type="text" name="umodify_title" value="{$configs.umodify_title.value}" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">其它页</label>
<div class="layui-input-block">
<input type="text" name="other_title" value="{$configs.other_title.value}" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit name="submit" value="pagetitle">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
<div class="layui-tab-item">
<form action="{url./admin/Config/index}" method="post" class="layui-form">
<input type="hidden" name="formcheck" value="{$formcheck}" >
<div class="layui-form-item">
<label class="layui-form-label">会员注册</label>
<div class="layui-input-block">
<input type="radio" name="register_status" value="1" {if([$configs.register_status.value]=='1'||[$configs.register_status.value]=='')} checked="checked" {/if} title="启用">
<input type="radio" name="register_status" value="0" {if([$configs.register_status.value]=='0')} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">会员注册类型</label>
<div class="layui-input-block">
<input type="radio" name="register_type" value="1" {if([$configs.register_type.value]=='1'||[$configs.register_type.value]=='')} checked="checked" {/if} title="用户名">
<input type="radio" name="register_type" value="2" {if([$configs.register_type.value]=='2')} checked="checked" {/if} title="邮箱账号">
<input type="radio" name="register_type" value="3" {if([$configs.register_type.value]=='3')} checked="checked" {/if} title="手机号码">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">会员注册验证码</label>
<div class="layui-input-block">
<input type="radio" name="register_check_code" value="0" {if([$configs.register_check_code.value]=='0')} checked="checked" {/if} title="禁用">
<input type="radio" name="register_check_code" value="1" {if([$configs.register_check_code.value]=='1'||[$configs.register_check_code.value]=='')} checked="checked" {/if} title="普通验证码">
<input type="radio" name="register_check_code" value="2" {if([$configs.register_check_code.value]=='2')} checked="checked" {/if} title="邮箱验证码">
<!-- <input type="radio" name="register_check_code" value="3" {if([$configs.register_check_code.value]=='3')} checked="checked" {/if} title="短信验证码"> -->
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">会员注册审核</label>
<div class="layui-input-block">
<input type="radio" name="register_verify" value="1" {if([$configs.register_verify.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="register_verify" value="0" {if([$configs.register_verify.value]==0)} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">会员登录</label>
<div class="layui-input-block">
<input type="radio" name="login_status" value="1" {if([$configs.login_status.value]=='1'||[$configs.login_status.value]=='')} checked="checked" {/if} title="启用">
<input type="radio" name="login_status" value="0" {if([$configs.login_status.value]=='0')} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">会员登录验证码</label>
<div class="layui-input-block">
<input type="radio" name="login_check_code" value="1" {if([$configs.login_check_code.value]=='1'||[$configs.login_check_code.value]=='')} checked="checked" {/if} title="启用">
<input type="radio" name="login_check_code" value="0" {if([$configs.login_check_code.value]=='0')} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">不等待跳登录</label>
<div class="layui-input-block">
<input type="radio" name="login_no_wait" value="1" {if([$configs.login_no_wait.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="login_no_wait" value="0" {if([$configs.login_no_wait.value]==0)} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">评论功能</label>
<div class="layui-input-block">
<input type="radio" name="comment_status" value="1" {if([$configs.comment_status.value]=='1'||[$configs.comment_status.value]=='')} checked="checked" {/if} title="启用">
<input type="radio" name="comment_status" value="0" {if([$configs.comment_status.value]=='0')} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">匿名评论</label>
<div class="layui-input-block">
<input type="radio" name="comment_anonymous" value="1" {if([$configs.comment_anonymous.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="comment_anonymous" value="0" {if([$configs.comment_anonymous.value]==0)} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">评论验证码</label>
<div class="layui-input-block">
<input type="radio" name="comment_check_code" value="1" {if([$configs.comment_check_code.value]=='1'||[$configs.comment_check_code.value]=='')} checked="checked" {/if} title="启用">
<input type="radio" name="comment_check_code" value="0" {if([$configs.comment_check_code.value]=='0')} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">评论审核</label>
<div class="layui-input-block">
<input type="radio" name="comment_verify" value="1" {if([$configs.comment_verify.value]=='1'||[$configs.comment_verify.value]=='')} checked="checked" {/if} title="启用">
<input type="radio" name="comment_verify" value="0" {if([$configs.comment_verify.value]=='0')} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">会员注册积分</label>
<div class="layui-input-inline">
<input type="text" name="register_score" value="{$configs.register_score.value}" placeholder="请输入会员注册初始积分" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">会员登录积分</label>
<div class="layui-input-inline">
<input type="text" name="login_score" value="{$configs.login_score.value}" placeholder="请输入会员每次登录积分" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">会员默认等级</label>
<div class="layui-input-inline">
<select name="register_gcode">
<option value="">请选择</option>
{foreach $groups(key,value)}
<option value="[value->gcode]" {if([$configs.register_gcode.value]==$value->gcode)}selected{/if}>[value->gname]</option>
{/foreach}
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">允许上传格式</label>
<div class="layui-input-inline">
<input type="text" name="home_upload_ext" value="{$configs.home_upload_ext.value}" placeholder="以英文逗号隔开!" class="layui-input">
</div>
<span class="layui-icon layui-icon-about tips" data-content="以英文逗号隔开默认jpg, jpeg, png, gif, xls, xlsx, doc, docx, ppt, pptx, rar, zip, pdf, txt"></span>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit name="submit" value="member">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
{include file='common/foot.html'}

View File

@@ -0,0 +1,178 @@
{include file='common/head.html'}
<div class="layui-body">
{if(![$dbsecurity]||![$session.pwsecurity])}
<blockquote class="layui-elem-quote layui-text-red" id="note">
{if(![$dbsecurity])}
<p>
<i class="fa fa-info-circle" aria-hidden="true"></i>
您的数据库文件存在安全隐患,可能被下载,请尽快修改数据库路径!<a class="layui-btn layui-btn-sm" href="{url./admin/Index/home}&action=moddb">自动修改</a>
</p>
{/if}
{if(![$session.pwsecurity])}
<p>
<i class="fa fa-info-circle" aria-hidden="true"></i>
您的账号密码为初始密码,存在安全隐患,请尽快修改密码!<a class="layui-btn layui-btn-sm" href="{url./admin/Index/ucenter}">立即修改</a>
</p>
{/if}
</blockquote>
{/if}
<blockquote class="layui-elem-quote">
当前登录用户:{$user_info->username} {$user_info->realname},登录时间:{$user_info->update_time}登录IP{fun=long2ip([$user_info->last_login_ip])},累计登录次数:{$user_info->login_count}
</blockquote>
<fieldset class="layui-elem-field">
<legend>快捷操作</legend>
<div class="layui-field-box">
<div class="layui-row">
{foreach $model_msg(key,value)}
<div class="layui-col-xs6 layui-col-sm4 layui-col-md3 layui-col-lg2">
{if($value->type==1)}
<a href="{url./admin/Single/index/mcode/'.$value->mcode.'}">
{else}
<a href="{url./admin/Content/index/mcode/'.$value->mcode.'}">
{/if}
<dl class="deskbox center-block">
<dt>[value->name]</dt>
<dd>[value->count]</dd>
</dl>
</a>
</div>
{/foreach}
<div class="layui-col-xs6 layui-col-sm4 layui-col-md3 layui-col-lg2">
<a href="{url./admin/Message/index}">
<dl class="deskbox center-block">
<dt>留言</dt>
<dd>{$sum_msg}</dd>
</dl>
</a>
</div>
</div>
</div>
</fieldset>
{if(CMSNAME=='PbootCMS')}
<div class="layui-row layui-col-space10">
<div class="layui-col-xs12 layui-col-md6">
<table class="layui-table table-two">
<thead>
<tr>
<th colspan="2">系统信息</th>
</tr>
</thead>
<tbody>
<tr>
<th width="100">应用版本</th>
<td>V{APP_VERSION}-{RELEASE_TIME}
{if(session('ucode')==10001)}
<a href="{url./admin/Upgrade/index}" class="layui-btn layui-btn-xs" id="check">在线更新</a>
{/if}
</td>
</tr>
<tr>
<th>主机系统</th>
<td>{$server->php_os}</td>
</tr>
<tr>
<th>主机地址</th>
<td>{$server->server_name}{$server->server_addr}:{$server->server_port}</td>
</tr>
<tr>
<th>WEB软件</th>
<td>{$server->server_software}</td>
</tr>
<tr>
<th>PHP版</th>
<td>{$server->php_version}</td>
</tr>
<tr>
<th>数据库驱动</th>
<td>{$server->db_driver}</td>
</tr>
<tr>
<th>文件上传限制</th>
<td>{$server->upload_max_filesize}</td>
</tr>
<tr>
<th>表单提交限制</th>
<td>{$server->post_max_size}</td>
</tr>
</tbody>
</table>
</div>
<div class="layui-col-xs12 layui-col-md6">
<table class="layui-table table-two">
<thead>
<tr>
<th colspan="2">开发信息</th>
</tr>
</thead>
<tbody>
<tr>
<th>系统名称</th>
<td>企业网站开发建设管理系统</td>
</tr>
<tr>
<th>模板下载</th>
<td>
<a href="http://www.adminbuy.cn/" style="color:#666" target="_blank">AB模板网</a>
</td>
</tr>
<tr>
<th>素材图标</th>
<td>
<a href="http://sc.adminbuy.cn/" style="color:#666" target="_blank">图标库</a>
</td>
</tr>
<tr>
<th>网站定制</th>
<td>
<a href="http://fang.adminbuy.cn/" style="color:#666" target="_blank">仿站</a>
</td>
</tr>
<tr>
<th>系统开发</th>
<td>星梦</td>
</tr>
<tr>
<th>友情贡献者</th>
<td>
感谢交流群各网友对我们发展的大力支持;
感谢LayUI提供的前端框架
感谢百度提供的富文本编辑器;
感谢星梦开发团队的日夜奋斗。
</td>
</tr>
</tbody>
</table>
</div>
</div>
{/if}
</div>
<script>
$.ajax({
type: 'GET',
url: 'https://www.pbootcms.com/index.php?p=/upgrade/check&version={APP_VERSION}.{RELEASE_TIME}.{$revise}&branch={$branch}&snuser={$snuser}&site={$site}',
dataType: 'json',
success: function (response, status) {
if(response.code==1){
$("#check").html($("#check").html()+'<span class="layui-badge-dot"></span>');
}
}
});
</script>
{include file='common/foot.html'}

View File

@@ -0,0 +1,196 @@
<?php
/**
* @copyright (C)2016-2099 Hnaoyun Inc.
* @author XingMeng
* @email hnxsh@foxmail.com
* @date 2016年12月25日
* 应用公共控制类
*/
namespace app\common;
use core\basic\Controller;
class AdminController extends Controller
{
public function __construct()
{
// 自动缓存基础信息
cache_config();
// 从配置文件读取cmsname参数来设置系统名称
define("CMSNAME", $this->config("cmsname") ?: 'PbootCMS');
// 检测登录,未登录跳转登录页面,已登录执行数据处理
if ($this->checkLogin()) {
// 权限检测
$this->checkLevel();
$this->getSecondMenu(); // 获取同级菜单
$this->assign('menu_tree', session('menu_tree')); // 注入菜单树
if (session('area_tree')) {
$area_html = make_area_Select(session('area_tree'), session('acode'));
$this->assign('area_html', $area_html);
if (count(session('area_tree')) == 1) {
$this->assign('one_area', true);
}
} else {
session_unset();
error('您账号的区域权限设置有误,无法正常登录!', url('/admin/Index/index'), 10);
}
// 内容模型菜单注入
$models = model('admin.content.Model');
$this->assign('menu_models', $models->getModelMenu());
// 注入编码后的回跳地址
$this->assign('btnqs', get_btn_qs());
$this->assign('backurl', get_backurl());
// 兼容模式form使用get搜索时注入pathinfo隐藏域
if ($_GET['p'] && $this->config('app_url_type') == 3) {
$this->assign('pathinfo', '<input name="p" type="hidden" value="' . get('p') . '">');
}
}
// 不进行表单检验的控制器
$nocheck = array(
'Upgrade'
);
// POST表单提交校验
if ($_POST && ! in_array(C, $nocheck) && session('formcheck') != post('formcheck')) {
// 检查会话目录权限问题
if (session_save_path()) {
preg_match('/^((\s+)?([0-9]+)(\s+)?;)?(.*)/', session_save_path(), $matches);
// 自动创建会话主目录
if (! check_dir($matches[5], true)) {
error('会话目录创建失败!' . $matches[5]);
}
// 检查会话目录写入权限
if (! is_writable($matches[5])) {
error('会话目录权限不足!' . $matches[5]);
}
// 自动创建层级会话目录
if ($matches[3]) {
create_session_dir($matches[5], $matches[3]);
}
} elseif (isset($_SERVER['TMP']) && ! file_exists($_SERVER['TMP'] . '/sess_' . session_id())) {
error(' 操作系统缓存目录写入权限不足!' . $_SERVER['TMP']);
}
alert_back('表单提交校验失败,请刷新后重试!');
}
// 首次加载时,生成页面验证码
if (! issetSession('formcheck')) {
session('formcheck', get_uniqid());
}
$this->assign('formcheck', session('formcheck')); // 注入formcheck模板变量
}
// 后台用户登录状态检查
private function checkLogin()
{
// 免登录可访问页面
$public_path = array(
'/admin/Index/index', // 登录页面
'/admin/Index/login' // 执行登录
);
if (session('sid') && $this->checkSid()) { // 如果已经登录直接true
return true;
} elseif (in_array('/' . M . '/' . C . '/' . F, $public_path)) { // 免登录可访问页面
return false;
} else { // 未登录跳转到登录页面
location(url('/admin/Index/index'));
}
}
// 检查会话id
private function checkSid()
{
$sid = encrypt_string(session_id() . session('id'));
if ($sid != session('sid') || session('M') != M) {
session_destroy();
return false;
} else {
return true;
}
}
// 访问权限检查
private function checkLevel()
{
// 免权限等级认证页面,即所有登录用户都可以访问
$public_path = array(
'/admin/Index/index', // 登录页
'/admin/Index/home', // 主页
'/admin/Index/loginOut', // 退出登录
'/admin/Index/ucenter', // 用户中心
'/admin/Index/area', // 区域选择
'/admin/Index/clearCache', // 清理缓存
'/admin/Index/upload' // 上传文件
);
$levals = session('levels');
$path1 = '/' . M . '/' . C;
$path2 = '/' . M . '/' . C . '/' . F;
if (session('id') == 1 || in_array(URL, $levals) || in_array($path2, $levals) || in_array($path1, $public_path) || in_array($path2, $public_path)) {
return true;
} else {
error('您的账号权限不足,您无法执行该操作!');
}
}
// 当前菜单的父类的子菜单,即同级菜单二级菜单
private function getSecondMenu()
{
$menu_tree = session('menu_tree');
$url = '/' . M . '/' . C . '/' . F;
$len = 0;
$primary_menu_url = '';
$second_menu = array();
// 直接比对找出最长匹配URL
foreach ($menu_tree as $key => $value) {
if (is_array($value->son)) {
foreach ($value->son as $key2 => $value2) {
if (! $value2->url) // 如果为空,则跳过
continue;
$pos = strpos($url, $value2->url);
if ($pos !== false) {
$templen = strlen($value2->url);
if ($templen > $len) {
$len = $templen;
$primary_menu_url = $value->url;
$second_menu = $value->son;
}
break; // 如果匹配到已经找到父类,则结束
}
}
}
}
// 前面第一种无法匹配,则选择子菜单匹配,只需控制器通过即可,如翻页、增、改、删操作
if (! $second_menu) {
foreach ($menu_tree as $key => $value) {
if (is_array($value->son)) {
foreach ($value->son as $key2 => $value2) {
if (strpos($value2->url, '/' . M . '/' . C . '/') === 0) {
$primary_menu_url = $value->url;
$second_menu = $value->son;
break;
}
}
}
if ($second_menu) { // 已经获取二级菜单到后退出
break;
}
}
}
$this->assign('primary_menu_url', $primary_menu_url);
$this->assign('second_menu', $second_menu);
}
}

View File

@@ -0,0 +1,12 @@
<?php
return array(
// 应用版本
'app_version' => '3.0.6',
// 发布时间
'release_time' => '20210929',
// 修订版本
'revise_version' => '0'
);

View File

@@ -0,0 +1,297 @@
<?php
/**
* @copyright (C)2016-2099 Hnaoyun Inc.
* @author XingMeng
* @email hnxsh@foxmail.com
* @date 2018年2月14日
* 首页控制器
*/
namespace app\home\controller;
use core\basic\Controller;
use app\home\model\ParserModel;
use core\basic\Config;
use core\basic\Url;
class IndexController extends Controller
{
protected $parser;
protected $model;
protected $htmldir;
public function __construct()
{
$this->parser = new ParserController();
$this->model = new ParserModel();
$this->htmldir = $this->config('tpl_html_dir') ? $this->config('tpl_html_dir') . '/' : '';
}
// 空拦截器, 实现文章路由转发
public function _empty()
{
// 地址类型
$url_rule_type = $this->config('url_rule_type') ?: 3;
if (P) { // 采用pathinfo模式及p参数伪静态模式
if ($url_rule_type == 2 && stripos(URL, $_SERVER['SCRIPT_NAME']) !== false) { // 禁止伪静态时带index.php访问
_404('您访问的内容不存在,请核对后重试!');
}
$path = explode('/', P);
if (! defined('URL_BIND')) {
array_shift($path); // 去除模块部分
}
} elseif ($url_rule_type == 3 && isset($_SERVER["QUERY_STRING"]) && $qs = $_SERVER["QUERY_STRING"]) { // 采用简短传参模式
parse_str($qs, $output);
unset($output['page']); // 去除分页
if ($output && ! current($output)) { // 第一个路径参数不能有值,否则非标准路径参数
$path = key($output); // 第一个参数为路径信息注意PHP数组会自动将key点符号转换下划线
$path = trim($path, '/'); // 去除两端斜杠
$url_rule_suffix = substr($this->config('url_rule_suffix'), 1);
if (preg_match('/_' . $url_rule_suffix . '$/', $path) && (! ! $pos = strripos($path, '_' . $url_rule_suffix))) {
$path = substr($path, 0, $pos); // 去扩展
}
$path = explode('/', $path);
} elseif (get('tag')) { // 对于兼容模式tag需要自动跳转tag独立页面
$tag = new TagController();
$tag->index();
} elseif (get('keyword')) { // 兼容模式搜索处理
$search = new SearchController();
$search->index();
}
}
if (isset($path) && is_array($path)) {
// 地址分隔符
$url_break_char = $this->config('url_break_char') ?: '_';
// 判断第一个参数中组合信息
if (strpos($path[0], $url_break_char)) {
$param = explode($url_break_char, $path[0]);
} else {
$param[] = $path[0];
}
// 判断第一个参数是模型还是自定义分类
if (! ! ($model = $this->model->checkModelUrlname($param[0])) || preg_match('/^(list_[0-9]+)|(^about_[0-9]+)/', $path[0])) {
$scode = $param[1];
if (isset($param[2])) {
$_GET['page'] = $param[2]; // 分页
}
} else {
define('CMS_PAGE_CUSTOM', true); // 自定义名称后分页比正常少了一个参数 (list_1_1=>product_1)
$scode = $param[0];
if (isset($param[1])) {
$_GET['page'] = $param[1]; // 分页
}
}
// 路由
switch ($param[0]) {
case 'search':
case 'keyword':
$search = new SearchController();
$search->index();
break;
case 'message':
$msg = new MessageController();
$msg->index();
break;
case 'form':
$_GET['fcode'] = $path[1];
$form = new FormController();
$form->index();
break;
case 'sitemap':
case 'Sitemap':
$sitemap = new SitemapController();
$sitemap->index();
break;
case 'tag':
$tag = new TagController();
$tag->index();
break;
case 'member':
$member = new MemberController();
$member->{$path[1]}();
break;
case 'comment':
$comment = new CommentController();
$comment->{$path[1]}();
break;
default:
if (get($param[0])) {
$this->getIndex();
} else {
if (count($path) > 1) {
define('CMS_PAGE', false); // 使用普通分页处理模型
if (! ! ($data = $this->model->getContent($path[1])) && ($data->scode == $scode || $data->sortfilename == $scode) && $data->type == 2) {
if ($data->acode != get_lg() && Config::get('lgautosw') !== '0') {
cookie('lg', $data->acode); // 调用内容语言与当前语言不一致时,自动切换语言
}
$this->getContent($data);
} else {
_404('您访问的内容不存在,请核对后重试!');
}
} else {
define('CMS_PAGE', true); // 使用cms分页处理模型
if (! ! $sort = $this->model->getSort($scode)) {
if ($sort->acode != get_lg() && Config::get('lgautosw') !== '0') {
cookie('lg', $sort->acode); // 调用栏目语言与当前语言不一致时,自动切换语言
}
if ($sort->type == 1) {
$this->getAbout($sort);
} else {
$this->getList($sort);
}
} else {
_404('您访问的栏目不存在,请核对后重试!');
}
}
}
}
} else {
$this->getIndex();
}
}
// 首页
private function getIndex()
{
$content = parent::parser($this->htmldir . 'index.html'); // 框架标签解析
$content = $this->parser->parserBefore($content); // CMS公共标签前置解析
$content = str_replace('{pboot:pagetitle}', $this->config('index_title') ?: '{pboot:sitetitle}-{pboot:sitesubtitle}', $content);
$content = $this->parser->parserPositionLabel($content, - 1, '首页', SITE_INDEX_DIR . '/'); // CMS当前位置标签解析
$content = $this->parser->parserSpecialPageSortLabel($content, 0, '', SITE_INDEX_DIR . '/'); // 解析分类标签
$content = $this->parser->parserAfter($content); // CMS公共标签后置解析
$this->cache($content, true);
}
// 列表
private function getList($sort)
{
if ($sort->listtpl) {
$this->checkPageLevel($sort->gcode, $sort->gtype, $sort->gnote);
$content = parent::parser($this->htmldir . $sort->listtpl); // 框架标签解析
$content = $this->parser->parserBefore($content); // CMS公共标签前置解析
$pagetitle = $sort->title ? "{sort:title}" : "{sort:name}"; // 页面标题
$content = str_replace('{pboot:pagetitle}', $this->config('list_title') ?: ($pagetitle . '-{pboot:sitetitle}-{pboot:sitesubtitle}'), $content);
$content = str_replace('{pboot:pagekeywords}', '{sort:keywords}', $content);
$content = str_replace('{pboot:pagedescription}', '{sort:description}', $content);
$content = $this->parser->parserPositionLabel($content, $sort->scode); // CMS当前位置标签解析
$content = $this->parser->parserSortLabel($content, $sort); // CMS分类信息标签解析
$content = $this->parser->parserListLabel($content, $sort->scode); // CMS分类列表标签解析
$content = $this->parser->parserAfter($content); // CMS公共标签后置解析
} else {
error('请到后台设置分类栏目列表页模板!');
}
$this->cache($content, true);
}
// 详情页
private function getContent($data)
{
// 读取模板
if (! ! $sort = $this->model->getSort($data->scode)) {
if ($sort->contenttpl) {
$this->checkPageLevel($sort->gcode, $sort->gtype, $sort->gnote); // 检查栏目权限
$this->checkPageLevel($data->gcode, $data->gtype, $data->gnote); // 检查内容权限
$content = parent::parser($this->htmldir . $sort->contenttpl); // 框架标签解析
$content = $this->parser->parserBefore($content); // CMS公共标签前置解析
$content = str_replace('{pboot:pagetitle}', $this->config('content_title') ?: '{content:title}-{sort:name}-{pboot:sitetitle}-{pboot:sitesubtitle}', $content);
$content = str_replace('{pboot:pagekeywords}', '{content:keywords}', $content);
$content = str_replace('{pboot:pagedescription}', '{content:description}', $content);
$content = $this->parser->parserPositionLabel($content, $sort->scode); // CMS当前位置标签解析
$content = $this->parser->parserSortLabel($content, $sort); // CMS分类信息标签解析
$content = $this->parser->parserCurrentContentLabel($content, $sort, $data); // CMS内容标签解析
$content = $this->parser->parserCommentLabel($content); // 文章评论
$content = $this->parser->parserAfter($content); // CMS公共标签后置解析
} else {
error('请到后台设置分类栏目内容页模板!');
}
} else {
_404('您访问内容的分类已经不存在,请核对后再试!');
}
$this->cache($content, true);
}
// 单页
private function getAbout($sort)
{
// 读取数据
if (! $data = $this->model->getAbout($sort->scode)) {
_404('您访问的内容不存在,请核对后重试!');
}
if ($sort->contenttpl) {
$this->checkPageLevel($sort->gcode, $sort->gtype, $sort->gnote);
$content = parent::parser($this->htmldir . $sort->contenttpl); // 框架标签解析
$content = $this->parser->parserBefore($content); // CMS公共标签前置解析
$pagetitle = $sort->title ? "{sort:title}" : "{content:title}"; // 页面标题
$content = str_replace('{pboot:pagetitle}', $this->config('about_title') ?: ($pagetitle . '-{pboot:sitetitle}-{pboot:sitesubtitle}'), $content);
$content = str_replace('{pboot:pagekeywords}', '{content:keywords}', $content);
$content = str_replace('{pboot:pagedescription}', '{content:description}', $content);
$content = $this->parser->parserPositionLabel($content, $sort->scode); // CMS当前位置标签解析
$content = $this->parser->parserSortLabel($content, $sort); // CMS分类信息标签解析
$content = $this->parser->parserCurrentContentLabel($content, $sort, $data); // CMS内容标签解析
$content = $this->parser->parserCommentLabel($content); // 文章评论
$content = $this->parser->parserAfter($content); // CMS公共标签后置解析
} else {
error('请到后台设置分类栏目内容页模板!');
}
$this->cache($content, true);
}
// 检查页面权限
private function checkPageLevel($gcode, $gtype, $gnote)
{
if ($gcode) {
$deny = false;
$gtype = $gtype ?: 4;
switch ($gtype) {
case 1:
if ($gcode <= session('pboot_gcode')) {
$deny = true;
}
break;
case 2:
if ($gcode < session('pboot_gcode')) {
$deny = true;
}
break;
case 3:
if ($gcode != session('pboot_gcode')) {
$deny = true;
}
break;
case 4:
if ($gcode > session('pboot_gcode')) {
$deny = true;
}
break;
case 5:
if ($gcode >= session('pboot_gcode')) {
$deny = true;
}
break;
}
if ($deny) {
$gnote = $gnote ?: '您的权限不足,无法浏览本页面!';
if (session('pboot_uid')) { // 已经登录
error($gnote);
} else {
if ($this->config('login_no_wait')) {
location(Url::home('member/login', null, "backurl=" . urlencode(get_current_url())));
} else {
error($gnote, Url::home('member/login', null, "backurl=" . urlencode(get_current_url())));
}
}
}
}
}
}

View File

@@ -0,0 +1,982 @@
<?php
/**
* @copyright (C)2016-2099 Hnaoyun Inc.
* @author XingMeng
* @email hnxsh@foxmail.com
* @date 2018年2月14日
* 标签解析引擎模型
*/
namespace app\home\model;
use core\basic\Model;
class ParserModel extends Model
{
// 存储分类及子编码
protected $scodes = array();
// 存储分类查询数据
protected $sorts;
// 存储栏目位置
protected $position = array();
// 上一篇
protected $pre;
// 下一篇
protected $next;
// 获取模型数据
public function checkModelUrlname($urlname)
{
return parent::table('ay_model')->where("urlname='$urlname'")->find();
}
// 站点配置信息
public function getSite()
{
return parent::table('ay_site')->where("acode='" . get_lg() . "'")->find();
}
// 公司信息
public function getCompany()
{
return parent::table('ay_company')->where("acode='" . get_lg() . "'")->find();
}
// 自定义标签,不区分语言,兼容跨语言
public function getLabel()
{
return parent::table('ay_label')->decode()->column('value,type', 'name');
}
// 单个分类信息,不区分语言,兼容跨语言
public function getSort($scode)
{
$field = array(
'a.*',
'c.name AS parentname',
'b.type',
'b.urlname',
'd.gcode'
);
$join = array(
array(
'ay_model b',
'a.mcode=b.mcode',
'LEFT'
),
array(
'ay_content_sort c',
'a.pcode=c.scode',
'LEFT'
),
array(
'ay_member_group d',
'a.gid=d.id',
'LEFT'
)
);
return parent::table('ay_content_sort a')->field($field)
->where("a.scode='$scode' OR a.filename='$scode'")
->join($join)
->find();
}
// 多个分类信息,不区分语言,兼容跨语言
public function getMultSort($scodes)
{
$field = array(
'a.*',
'c.name AS parentname',
'b.type',
'b.urlname'
);
$join = array(
array(
'ay_model b',
'a.mcode=b.mcode',
'LEFT'
),
array(
'ay_content_sort c',
'a.pcode=c.scode',
'LEFT'
)
);
return parent::table('ay_content_sort a')->field($field)
->in('a.scode', $scodes)
->join($join)
->order('a.sorting,a.id')
->select();
}
// 指定分类数量
public function getSortRows($scode)
{
$this->scodes = array(); // 先清空
// 获取多分类子类
$arr = explode(',', $scode);
foreach ($arr as $value) {
$scodes = $this->getSubScodes(trim($value));
}
// 拼接条件
$where1 = array(
"scode in (" . implode_quot(',', $scodes) . ")",
"subscode='$scode'"
);
$where2 = array(
"acode='" . get_lg() . "'",
'status=1',
"date<'" . date('Y-m-d H:i:s') . "'"
);
$result = parent::table('ay_content')->where($where1, 'OR')
->where($where2)
->column('id');
return count($result);
}
// 分类栏目列表关系树
public function getSortsTree()
{
$fields = array(
'a.*',
'b.type',
'b.urlname'
);
$join = array(
'ay_model b',
'a.mcode=b.mcode',
'LEFT'
);
$result = parent::table('ay_content_sort a')->where("a.acode='" . get_lg() . "'")
->where('a.status=1')
->join($join)
->order('a.pcode,a.sorting,a.id')
->column($fields, 'scode');
foreach ($result as $key => $value) {
if ($value['pcode']) {
$result[$value['pcode']]['son'][] = $value; // 记录到关系树
} else {
$data['top'][] = $value; // 记录顶级菜单
}
}
$data['tree'] = $result;
return $data;
}
// 获取分类名称
public function getSortName($scode)
{
$result = $this->getSortList();
return $result[$scode]['name'];
}
// 分类顶级编码
public function getSortTopScode($scode)
{
$result = $this->getSortList();
return $this->getTopParent($scode, $result);
}
// 获取位置
public function getPosition($scode)
{
$result = $this->getSortList();
$this->position = array(); // 重置
$this->getTopParent($scode, $result);
return array_reverse($this->position);
}
// 分类顶级编码
private function getTopParent($scode, $sorts)
{
if (! $scode || ! $sorts) {
return;
}
$this->position[] = $sorts[$scode];
if ($sorts[$scode]['pcode']) {
return $this->getTopParent($sorts[$scode]['pcode'], $sorts);
} else {
return $sorts[$scode]['scode'];
}
}
// 分类子类集
private function getSubScodes($scode)
{
if (! $scode) {
return;
}
$this->scodes[] = $scode;
$subs = parent::table('ay_content_sort')->where("pcode='$scode'")->column('scode');
if ($subs) {
foreach ($subs as $value) {
$this->getSubScodes($value);
}
}
return $this->scodes;
}
// 获取栏目清单
private function getSortList()
{
if (! isset($this->sorts)) {
$fields = array(
'a.id',
'a.pcode',
'a.scode',
'a.name',
'a.filename',
'a.outlink',
'b.type',
'b.urlname'
);
$join = array(
'ay_model b',
'a.mcode=b.mcode',
'LEFT'
);
$this->sorts = parent::table('ay_content_sort a')->where("a.acode='" . get_lg() . "'")
->join($join)
->column($fields, 'scode');
}
return $this->sorts;
}
// 获取筛选字段数据
public function getSelect($field)
{
return parent::table('ay_extfield')->where("name='$field'")->value('value');
}
// 列表内容,带分页,不区分语言,兼容跨语言
public function getLists($scode, $num, $order, $filter = array(), $tags = array(), $select = array(), $fuzzy = true, $start = 1, $lfield = null, $lg = null)
{
$ext_table = false;
if ($lfield) {
$lfield .= ',id,outlink,type,scode,sortfilename,filename,urlname'; // 附加必须字段
$fields = explode(',', $lfield);
$fields = array_unique($fields); // 去重
foreach ($fields as $key => $value) {
if (strpos($value, 'ext_') === 0) {
$ext_table = true;
$fields[$key] = 'e.' . $value;
} elseif ($value == 'sortname') {
$fields[$key] = 'b.name as sortname';
} elseif ($value == 'sortfilename') {
$fields[$key] = 'b.filename as sortfilename';
} elseif ($value == 'subsortname') {
$fields[$key] = 'c.name as subsortname';
} elseif ($value == 'subfilename') {
$fields[$key] = 'c.filename as subfilename';
} elseif ($value == 'type' || $value == 'urlname') {
$fields[$key] = 'd.' . $value;
} elseif ($value == 'modelname') {
$fields[$key] = 'd.name as modelname';
} else {
$fields[$key] = 'a.' . $value;
}
}
} else {
$ext_table = true;
$fields = array(
'a.*',
'b.name as sortname',
'b.filename as sortfilename',
'c.name as subsortname',
'c.filename as subfilename',
'd.type',
'd.name as modelname',
'd.urlname',
'e.*',
'f.gcode'
);
}
$join = array(
array(
'ay_content_sort b',
'a.scode=b.scode',
'LEFT'
),
array(
'ay_content_sort c',
'a.subscode=c.scode',
'LEFT'
),
array(
'ay_model d',
'b.mcode=d.mcode',
'LEFT'
),
array(
'ay_member_group f',
'a.gid=f.id',
'LEFT'
)
);
// 加载扩展字段表
if ($ext_table) {
$join[] = array(
'ay_content_ext e',
'a.id=e.contentid',
'LEFT'
);
}
$scode_arr = array();
if ($scode) {
// 获取所有子类分类编码
$this->scodes = array(); // 先清空
$arr = explode(',', $scode); // 传递有多个分类时进行遍历
foreach ($arr as $value) {
$scodes = $this->getSubScodes(trim($value));
}
// 拼接条件
$scode_arr = array(
"a.scode in (" . implode_quot(',', $scodes) . ")",
"a.subscode='$scode'"
);
}
$where = array(
'a.status=1',
'd.type=2',
"a.date<'" . date('Y-m-d H:i:s') . "'"
);
if ($lg) {
$where['a.acode'] = $lg;
}
// 筛选条件支持模糊匹配
return parent::table('ay_content a')->field($fields)
->where($scode_arr, 'OR')
->where($where)
->where($select, 'AND', 'AND', $fuzzy)
->where($filter, 'OR')
->where($tags, 'OR')
->join($join)
->order($order)
->page(1, $num, $start)
->decode()
->select();
}
// 列表内容,不带分页,不区分语言,兼容跨语言
public function getList($scode, $num, $order, $filter = array(), $tags = array(), $select = array(), $fuzzy = true, $start = 1, $lfield = null, $lg = null)
{
$ext_table = false;
if ($lfield) {
$lfield .= ',id,outlink,type,scode,sortfilename,filename,urlname'; // 附加必须字段
$fields = explode(',', $lfield);
$fields = array_unique($fields); // 去重
foreach ($fields as $key => $value) {
if (strpos($value, 'ext_') === 0) {
$ext_table = true;
$fields[$key] = 'e.' . $value;
} elseif ($value == 'sortname') {
$fields[$key] = 'b.name as sortname';
} elseif ($value == 'sortfilename') {
$fields[$key] = 'b.filename as sortfilename';
} elseif ($value == 'subsortname') {
$fields[$key] = 'c.name as subsortname';
} elseif ($value == 'subfilename') {
$fields[$key] = 'c.filename as subfilename';
} elseif ($value == 'type' || $value == 'urlname') {
$fields[$key] = 'd.' . $value;
} elseif ($value == 'modelname') {
$fields[$key] = 'd.name as modelname';
} else {
$fields[$key] = 'a.' . $value;
}
}
} else {
$ext_table = true;
$fields = array(
'a.*',
'b.name as sortname',
'b.filename as sortfilename',
'c.name as subsortname',
'c.filename as subfilename',
'd.type',
'd.name as modelname',
'd.urlname',
'e.*',
'f.gcode'
);
}
$join = array(
array(
'ay_content_sort b',
'a.scode=b.scode',
'LEFT'
),
array(
'ay_content_sort c',
'a.subscode=c.scode',
'LEFT'
),
array(
'ay_model d',
'b.mcode=d.mcode',
'LEFT'
),
array(
'ay_member_group f',
'a.gid=f.id',
'LEFT'
)
);
// 加载扩展字段表
if ($ext_table) {
$join[] = array(
'ay_content_ext e',
'a.id=e.contentid',
'LEFT'
);
}
$scode_arr = array();
if ($scode) {
// 获取所有子类分类编码
$this->scodes = array(); // 先清空
$arr = explode(',', $scode); // 传递有多个分类时进行遍历
foreach ($arr as $value) {
$scodes = $this->getSubScodes(trim($value));
}
// 拼接条件
$scode_arr = array(
"a.scode in (" . implode_quot(',', $scodes) . ")",
"a.subscode='$scode'"
);
}
$where = array(
'a.status=1',
'd.type=2',
"a.date<'" . date('Y-m-d H:i:s') . "'"
);
if ($lg) {
$where['a.acode'] = $lg;
}
// 筛选条件支持模糊匹配
return parent::table('ay_content a')->field($fields)
->where($scode_arr, 'OR')
->where($where)
->where($select, 'AND', 'AND', $fuzzy)
->where($filter, 'OR')
->where($tags, 'OR')
->join($join)
->order($order)
->limit($start - 1, $num)
->decode()
->select();
}
// 内容详情,不区分语言,兼容跨语言
public function getContent($id)
{
$field = array(
'a.*',
'b.name as sortname',
'b.filename as sortfilename',
'b.outlink as sortoutlink',
'c.name as subsortname',
'c.filename as subfilename',
'd.type',
'd.name as modelname',
'd.urlname',
'e.*',
'f.gcode'
);
$join = array(
array(
'ay_content_sort b',
'a.scode=b.scode',
'LEFT'
),
array(
'ay_content_sort c',
'a.subscode=c.scode',
'LEFT'
),
array(
'ay_model d',
'b.mcode=d.mcode',
'LEFT'
),
array(
'ay_content_ext e',
'a.id=e.contentid',
'LEFT'
),
array(
'ay_member_group f',
'a.gid=f.id',
'LEFT'
)
);
$result = parent::table('ay_content a')->field($field)
->where("a.id='$id' OR a.filename='$id'")
->where('a.status=1')
->join($join)
->decode()
->find();
return $result;
}
// 单篇详情,不区分语言,兼容跨语言
public function getAbout($scode)
{
$field = array(
'a.*',
'b.name as sortname',
'b.filename as sortfilename',
'c.name as subsortname',
'c.filename as subfilename',
'd.type',
'd.name as modelname',
'd.urlname',
'e.*',
'f.gcode'
);
$join = array(
array(
'ay_content_sort b',
'a.scode=b.scode',
'LEFT'
),
array(
'ay_content_sort c',
'a.subscode=c.scode',
'LEFT'
),
array(
'ay_model d',
'b.mcode=d.mcode',
'LEFT'
),
array(
'ay_content_ext e',
'a.id=e.contentid',
'LEFT'
),
array(
'ay_member_group f',
'a.gid=f.id',
'LEFT'
)
);
$result = parent::table('ay_content a')->field($field)
->where("a.scode='$scode' OR b.filename='$scode'")
->where('a.status=1')
->join($join)
->decode()
->order('id DESC')
->find();
return $result;
}
// 指定内容多图
public function getContentPics($id)
{
$result = parent::table('ay_content')->field("pics,picstitle")
->where("id='$id'")
->where('status=1')
->find();
return $result;
}
// 指定内容多选调用
public function getContentCheckbox($id, $field)
{
$result = parent::table('ay_content_ext')->where("contentid='$id'")->value($field);
return $result;
}
// 指定内容标签调用
public function getContentTags($id)
{
$result = parent::table('ay_content')->field('scode,tags')
->where("id='$id'")
->where('status=1')
->find();
return $result;
}
// 指定分类标签调用
public function getSortTags($scode)
{
$join = array(
array(
'ay_content_sort b',
'a.scode=b.scode',
'LEFT'
),
array(
'ay_model c',
'b.mcode=c.mcode',
'LEFT'
)
);
$scode_arr = array();
if ($scode) {
// 获取所有子类分类编码
$this->scodes = array(); // 先清空
$scodes = $this->getSubScodes(trim($scode)); // 获取子类
// 拼接条件
$scode_arr = array(
"a.scode in (" . implode_quot(',', $scodes) . ")",
"a.subscode='$scode'"
);
}
$result = parent::table('ay_content a')->where("c.type=2 AND a.tags<>''")
->where($scode_arr, 'OR')
->join($join)
->where('a.status=1')
->order('a.visits DESC')
->column('a.tags');
return $result;
}
// 上一篇内容
public function getContentPre($scode, $id)
{
if (! $this->pre) {
$this->scodes = array();
$scodes = $this->getSubScodes($scode);
$field = array(
'a.id',
'a.title',
'a.filename',
'a.ico',
'a.scode',
'b.filename as sortfilename',
'c.type',
'c.urlname'
);
$join = array(
array(
'ay_content_sort b',
'a.scode=b.scode',
'LEFT'
),
array(
'ay_model c',
'b.mcode=c.mcode',
'LEFT'
)
);
$this->pre = parent::table('ay_content a')->field($field)
->where("a.id<$id")
->join($join)
->in('a.scode', $scodes)
->where("a.acode='" . get_lg() . "'")
->where('a.status=1')
->order('a.id DESC')
->find();
}
return $this->pre;
}
// 下一篇内容
public function getContentNext($scode, $id)
{
if (! $this->next) {
$this->scodes = array();
$scodes = $this->getSubScodes($scode);
$field = array(
'a.id',
'a.title',
'a.filename',
'a.ico',
'a.scode',
'b.filename as sortfilename',
'c.type',
'c.urlname'
);
$join = array(
array(
'ay_content_sort b',
'a.scode=b.scode',
'LEFT'
),
array(
'ay_model c',
'b.mcode=c.mcode',
'LEFT'
)
);
$this->next = parent::table('ay_content a')->field($field)
->where("a.id>$id")
->join($join)
->in('a.scode', $scodes)
->where("a.acode='" . get_lg() . "'")
->where('a.status=1')
->order('a.id ASC')
->find();
}
return $this->next;
}
// 幻灯片
public function getSlides($gid, $num, $start = 1)
{
$result = parent::table('ay_slide')->where("gid='$gid'")
->order('sorting ASC,id ASC')
->limit($start - 1, $num)
->select();
return $result;
}
// 友情链接
public function getLinks($gid, $num, $start = 1)
{
$result = parent::table('ay_link')->where("gid='$gid'")
->order('sorting ASC,id ASC')
->limit($start - 1, $num)
->select();
return $result;
}
// 获取留言
public function getMessage($num, $page = true, $start = 1, $lg = null)
{
if ($lg == 'all') {
$where = array();
} elseif ($lg) {
$where = array(
'a.acode' => $lg
);
} else {
$where = array(
'a.acode' => get_lg()
);
}
$field = array(
'a.*',
'b.username',
'b.nickname',
'b.headpic'
);
$join = array(
'ay_member b',
'a.uid=b.id',
'LEFT'
);
if ($page) {
return parent::table('ay_message a')->field($field)
->join($join)
->where("a.status=1")
->where($where)
->order('a.id DESC')
->decode(false)
->page(1, $num, $start)
->select();
} else {
return parent::table('ay_message a')->field($field)
->join($join)
->where("a.status=1")
->where($where)
->order('a.id DESC')
->decode(false)
->limit($start - 1, $num)
->select();
}
}
// 新增留言
public function addMessage($data)
{
return parent::table('ay_message')->autoTime()->insert($data);
}
// 获取表单字段
public function getFormField($fcode)
{
$field = array(
'a.table_name',
'a.form_name',
'b.name',
'b.required',
'b.description'
);
$join = array(
'ay_form_field b',
'a.fcode=b.fcode',
'LEFT'
);
return parent::table('ay_form a')->field($field)
->where("a.fcode='$fcode'")
->join($join)
->order('b.sorting ASC,b.id ASC')
->select();
}
// 获取表单表名称
public function getFormTable($fcode)
{
return parent::table('ay_form')->where("fcode='$fcode'")->value('table_name');
}
// 获取表单数据
public function getForm($table, $num, $page = true, $start = 1)
{
if ($page) {
return parent::table($table)->order('id DESC')
->decode(false)
->page(1, $num, $start)
->select();
} else {
return parent::table($table)->order('id DESC')
->decode(false)
->limit($start - 1, $num)
->select();
}
}
// 新增表单数据
public function addForm($table, $data)
{
return parent::table($table)->insert($data);
}
// 文章内链
public function getTags()
{
return parent::table('ay_tags')->field('name,link')
->where("acode='" . get_lg() . "'")
->order('length(name) desc')
->select();
}
// 新增评论
public function addComment($data)
{
return parent::table('ay_member_comment')->insert($data);
}
// 文章评论
public function getComment($contentid, $pid, $num, $order, $page = false, $start = 1)
{
$field = array(
'a.*',
'b.username',
'b.nickname',
'b.headpic',
'c.username as pusername',
'c.nickname as pnickname',
'c.headpic as pheadpic'
);
$join = array(
array(
'ay_member b',
'a.uid=b.id',
'LEFT'
),
array(
'ay_member c',
'a.puid=c.id',
'LEFT'
)
);
if ($page) {
return parent::table('ay_member_comment a')->field($field)
->join($join)
->where("a.contentid='$contentid'")
->where('a.pid=' . $pid)
->where("a.status=1")
->order($order)
->page(1, $num, $start)
->select();
} else {
return parent::table('ay_member_comment a')->field($field)
->join($join)
->where("a.contentid='$contentid'")
->where('a.pid=' . $pid)
->where("a.status=1")
->order($order)
->limit($start - 1, $num)
->select();
}
}
// 我的评论
public function getMyComment($num, $order, $page = false, $start = 1)
{
$field = array(
'a.*',
'b.username',
'b.nickname',
'b.headpic',
'c.username as pusername',
'c.nickname as pnickname',
'c.headpic as pheadpic',
'd.title'
);
$join = array(
array(
'ay_member b',
'a.uid=b.id',
'LEFT'
),
array(
'ay_member c',
'a.puid=c.id',
'LEFT'
),
array(
'ay_content d',
'a.contentid=d.id',
'LEFT'
)
);
if ($page) {
return parent::table('ay_member_comment a')->field($field)
->join($join)
->where("uid='" . session('pboot_uid') . "'")
->order($order)
->page(1, $num, $start)
->select();
} else {
return parent::table('ay_member_comment a')->field($field)
->join($join)
->where("uid='" . session('pboot_uid') . "'")
->order($order)
->limit($start - 1, $num)
->select();
}
}
// 删除评论
public function delComment($id)
{
return parent::table('ay_member_comment')->where("uid='" . session('pboot_uid') . "'")
->where("id=$id")
->delete();
}
}

View File

@@ -0,0 +1,976 @@
<?php
/**
* @copyright (C)2016-2099 Hnaoyun Inc.
* @author XingMeng
* @email hnxsh@foxmail.com
* @date 2017年11月5日
*
*/
use core\basic\Config;
// 获取用户浏览器类型
function get_user_bs($bs = null)
{
if (isset($_SERVER["HTTP_USER_AGENT"])) {
$user_agent = strtolower($_SERVER["HTTP_USER_AGENT"]);
} else {
return null;
}
// 直接检测传递的值
if ($bs) {
if (strpos($user_agent, strtolower($bs))) {
return true;
} else {
return false;
}
}
// 固定检测
if (strpos($user_agent, 'micromessenger')) {
$user_bs = 'Weixin';
} elseif (strpos($user_agent, 'qq')) {
$user_bs = 'QQ';
} elseif (strpos($user_agent, 'weibo')) {
$user_bs = 'Weibo';
} elseif (strpos($user_agent, 'alipayclient')) {
$user_bs = 'Alipay';
} elseif (strpos($user_agent, 'trident/7.0')) {
$user_bs = 'IE11'; // 新版本IE优先避免360等浏览器的兼容模式检测错误
} elseif (strpos($user_agent, 'trident/6.0')) {
$user_bs = 'IE10';
} elseif (strpos($user_agent, 'trident/5.0')) {
$user_bs = 'IE9';
} elseif (strpos($user_agent, 'trident/4.0')) {
$user_bs = 'IE8';
} elseif (strpos($user_agent, 'msie 7.0')) {
$user_bs = 'IE7';
} elseif (strpos($user_agent, 'msie 6.0')) {
$user_bs = 'IE6';
} elseif (strpos($user_agent, 'edge')) {
$user_bs = 'Edge';
} elseif (strpos($user_agent, 'firefox')) {
$user_bs = 'Firefox';
} elseif (strpos($user_agent, 'chrome') || strpos($user_agent, 'android')) {
$user_bs = 'Chrome';
} elseif (strpos($user_agent, 'safari')) {
$user_bs = 'Safari';
} elseif (strpos($user_agent, 'mj12bot')) {
$user_bs = 'MJ12bot';
} else {
$user_bs = 'Other';
}
return $user_bs;
}
// 获取用户操作系统类型
function get_user_os($osstr = null)
{
if (isset($_SERVER["HTTP_USER_AGENT"])) {
$user_agent = strtolower($_SERVER["HTTP_USER_AGENT"]);
} else {
return null;
}
// 直接检测传递的值
if ($osstr) {
if (strpos($user_agent, strtolower($osstr))) {
return true;
} else {
return false;
}
}
if (strpos($user_agent, 'windows nt 5.0')) {
$user_os = 'Windows 2000';
} elseif (strpos($user_agent, 'windows nt 9')) {
$user_os = 'Windows 9X';
} elseif (strpos($user_agent, 'windows nt 5.1')) {
$user_os = 'Windows XP';
} elseif (strpos($user_agent, 'windows nt 5.2')) {
$user_os = 'Windows 2003';
} elseif (strpos($user_agent, 'windows nt 6.0')) {
$user_os = 'Windows Vista';
} elseif (strpos($user_agent, 'windows nt 6.1')) {
$user_os = 'Windows 7';
} elseif (strpos($user_agent, 'windows nt 6.2')) {
$user_os = 'Windows 8';
} elseif (strpos($user_agent, 'windows nt 6.3')) {
$user_os = 'Windows 8.1';
} elseif (strpos($user_agent, 'windows nt 10')) {
$user_os = 'Windows 10';
} elseif (strpos($user_agent, 'windows phone')) {
$user_os = 'Windows Phone';
} elseif (strpos($user_agent, 'android')) {
$user_os = 'Android';
} elseif (strpos($user_agent, 'iphone')) {
$user_os = 'iPhone';
} elseif (strpos($user_agent, 'ipad')) {
$user_os = 'iPad';
} elseif (strpos($user_agent, 'mac')) {
$user_os = 'Mac';
} elseif (strpos($user_agent, 'sunos')) {
$user_os = 'Sun OS';
} elseif (strpos($user_agent, 'bsd')) {
$user_os = 'BSD';
} elseif (strpos($user_agent, 'ubuntu')) {
$user_os = 'Ubuntu';
} elseif (strpos($user_agent, 'linux')) {
$user_os = 'Linux';
} elseif (strpos($user_agent, 'unix')) {
$user_os = 'Unix';
} else {
$user_os = 'Other';
}
return $user_os;
}
// 获取用户IP
function get_user_ip()
{
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$cip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
$cip = $_SERVER['HTTP_CLIENT_IP'];
} else {
$cip = $_SERVER['REMOTE_ADDR'];
}
if ($cip == '::1') { // 使用localhost时
$cip = '127.0.0.1';
}
if (! preg_match('/^[0-9\.]+$/', $cip)) { // 非标准的IP
$cip = '0.0.0.0';
}
return htmlspecialchars($cip);
}
// 执行URL请求并返回数据
function get_url($url, $fields = array(), $UserAgent = null, $vfSSL = false)
{
$SSL = substr($url, 0, 8) == "https://" ? true : false;
$ch = curl_init();
if ($UserAgent) { // 在HTTP请求中包含一个"User-Agent: "头的字符串。
curl_setopt($ch, CURLOPT_USERAGENT, $UserAgent);
} else {
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER["HTTP_USER_AGENT"]);
}
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60); // 在发起连接前等待的时间如果设置为0则无限等待
curl_setopt($ch, CURLOPT_TIMEOUT, 90); // 设置cURL允许执行的最长秒数
curl_setopt($ch, CURLOPT_URL, $url); // 设置请求地址
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // 设置cURL 参数,要求结果保存到字符串中还是输出到屏幕上。
// SSL验证
if ($SSL) {
if ($vfSSL) {
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_CAINFO, CORE_PATH . '/cacert.pem');
} else {
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 信任任何证书
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); // 不检查证书中是否设置域名
}
}
// 数据字段
if ($fields) {
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
}
$output = curl_exec($ch);
if (curl_errno($ch)) {
error('请求远程地址错误:' . curl_error($ch));
}
curl_close($ch);
return $output;
}
// 返回时间戳格式化日期时间,默认当前
function get_datetime($timestamp = null)
{
if (! $timestamp)
$timestamp = time();
return date('Y-m-d H:i:s', $timestamp);
}
// 返回时间戳格式化日期,默认当前
function get_date($timestamp = null)
{
if (! $timestamp)
$timestamp = time();
return date('Y-m-d', $timestamp);
}
// 返回时间戳差值部分,年、月、日
function get_date_diff($startstamp, $endstamp, $return = 'm')
{
$y = date('Y', $endstamp) - date('Y', $startstamp);
$m = date('m', $endstamp) - date('m', $startstamp);
switch ($return) {
case 'y':
if ($y <= 1) {
$y = $m / 12;
}
$string = $y;
break;
case 'm':
$string = $y * 12 + $m;
break;
case 'd':
$string = ($endstamp - $startstamp) / 86400;
break;
}
return $string;
}
// 生成无限极树,$data为二维数组数据
function get_tree($data, $tid, $idField, $pidField, $sonName = 'son')
{
$tree = array();
foreach ($data as $key => $value) {
if (is_array($value)) {
if ($value[$pidField] == "$tid") { // 父亲找到儿子
$value[$sonName] = get_tree($data, $value[$idField], $idField, $pidField, $sonName);
$tree[] = $value;
}
} else {
if ($value->$pidField == "$tid") { // 父亲找到儿子
$temp = clone $value;
$temp->$sonName = get_tree($data, $value->$idField, $idField, $pidField, $sonName);
$tree[] = $temp;
}
}
}
return $tree;
}
// 获取数据数组的映射数组
function get_mapping($array, $vValue, $vKey = null)
{
if (! $array)
return array();
foreach ($array as $key => $value) {
if (is_array($value)) {
if ($vKey) {
$result[$value[$vKey]] = $value[$vValue];
} else {
$result[] = $value[$vValue];
}
} elseif (is_object($value)) {
if ($vKey) {
$result[$value->$vKey] = $value->$vValue;
} else {
$result[] = $value->$vValue;
}
} else {
return $array;
}
}
return $result;
}
// 页码赋值异常返回1
function get_page()
{
if (isset($_GET['page'])) {
$value = trim($_GET['page']);
if (preg_match('/^[0-9]+$/', $value)) {
return $value;
}
}
return 1;
}
// 返回请求类型
function get_request_method()
{
return $_SERVER['REQUEST_METHOD'];
}
// 获取当前完整URL地址
function get_current_url()
{
$http_type = is_https() ? 'https://' : 'http://';
return $http_type . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
}
// 获取字符串第N次出现位置
function get_strpos($string, $find, $n)
{
$pos = strpos($string, $find);
for ($i = 2; $i <= $n; $i ++) {
$pos = strpos($string, $find, $pos + 1);
}
return $pos;
}
// array_column向下兼容低版本PHP
if (! function_exists('array_column')) {
function array_column($input, $columnKey, $indexKey = null)
{
$columnKeyIsNumber = (is_numeric($columnKey)) ? true : false;
$indexKeyIsNull = (is_null($indexKey)) ? true : false;
$indexKeyIsNumber = (is_numeric($indexKey)) ? true : false;
$result = array();
foreach ((array) $input as $key => $row) {
if ($columnKeyIsNumber) {
$tmp = array_slice($row, $columnKey, 1);
$tmp = (is_array($tmp) && ! empty($tmp)) ? current($tmp) : null;
} else {
$tmp = isset($row[$columnKey]) ? $row[$columnKey] : null;
}
if (! $indexKeyIsNull) {
if ($indexKeyIsNumber) {
$key = array_slice($row, $indexKey, 1);
$key = (is_array($key) && ! empty($key)) ? current($key) : null;
$key = is_null($key) ? 0 : $key;
} else {
$key = isset($row[$indexKey]) ? $row[$indexKey] : 0;
}
}
$result[$key] = $tmp;
}
return $result;
}
}
/**
* 系统信息弹出解析函数
*
* @param string $info_tpl模板
* @param string $string内容
* @param string $jump_url跳转地址
* @param number $time时间
*/
function parse_info_tpl($info_tpl, $string, $jump_url = null, $time = 0)
{
if (file_exists($info_tpl)) {
$tpl_content = file_get_contents($info_tpl);
if ($jump_url) {
$timeout_js = "<script>var timeout = {time};var showbox = document.getElementById('time');show();function show(){showbox.innerHTML = timeout+ ' 秒后自动跳转';timeout--;if (timeout == 0) {window.location.href = '{url}';}else {setTimeout(function(){show();}, 1000);}}</script>";
} else {
$timeout_js = '';
}
$tpl_content = str_replace('{js}', $timeout_js, $tpl_content);
$tpl_content = str_replace('{info}', $string, $tpl_content);
$tpl_content = str_replace('{url}', $jump_url, $tpl_content);
$tpl_content = str_replace('{time}', $time, $tpl_content);
$tpl_content = str_replace('{sitedir}', SITE_DIR, $tpl_content);
$tpl_content = str_replace('{coredir}', CORE_DIR, $tpl_content);
$tpl_content = str_replace('{appversion}', APP_VERSION, $tpl_content);
$tpl_content = str_replace('{serveros}', PHP_OS, $tpl_content);
$tpl_content = str_replace('{serversoft}', $_SERVER['SERVER_SOFTWARE'], $tpl_content);
return $tpl_content;
} else {
exit('<div style="font-size:50px;">:(</div>提示信息的模板文件不存在!');
}
}
// 获取转义数据,支持字符串、数组、对象
function escape_string($string)
{
if (! $string)
return $string;
if (is_array($string)) { // 数组处理
foreach ($string as $key => $value) {
$string[$key] = escape_string($value);
}
} elseif (is_object($string)) { // 对象处理
foreach ($string as $key => $value) {
$string->$key = escape_string($value);
}
} else { // 字符串处理
$string = htmlspecialchars(trim($string), ENT_QUOTES, 'UTF-8');
$string = addslashes($string);
}
return $string;
}
// 字符反转义html实体及斜杠支持字符串、数组、对象
function decode_string($string)
{
if (! $string)
return $string;
if (is_array($string)) { // 数组处理
foreach ($string as $key => $value) {
$string[$key] = decode_string($value);
}
} elseif (is_object($string)) { // 对象处理
foreach ($string as $key => $value) {
$string->$key = decode_string($value);
}
} else { // 字符串处理
$string = stripcslashes($string);
$string = htmlspecialchars_decode($string, ENT_QUOTES);
}
$string = preg_replace_r('/pboot:if/i', 'pboot@if', $string); // 避免解码绕过问题
return $string;
}
// 字符反转义斜杠,支持字符串、数组、对象
function decode_slashes($string)
{
if (! $string)
return $string;
if (is_array($string)) { // 数组处理
foreach ($string as $key => $value) {
$string[$key] = decode_slashes($value);
}
} elseif (is_object($string)) { // 对象处理
foreach ($string as $key => $value) {
$string->$key = decode_slashes($value);
}
} else { // 字符串处理
$string = stripcslashes($string);
}
return $string;
}
// 字符串双层MD5加密
function encrypt_string($string)
{
return md5(md5($string));
}
// 生成唯一标识符
function get_uniqid()
{
return encrypt_string(uniqid(mt_rand(), true));
}
// 清洗html代码的空白符号
function clear_html_blank($string)
{
$string = str_replace("\r\n", '', $string); // 清除换行符
$string = str_replace("\n", '', $string); // 清除换行符
$string = str_replace("\t", '', $string); // 清除制表符
$string = str_replace(' ', '', $string); // 清除大空格
$string = str_replace('&nbsp;', '', $string); // 清除 &nbsp;
$string = preg_replace('/\s+/', ' ', $string); // 清除空格
return $string;
}
// 去除字符串两端斜线
function trim_slash($string)
{
return trim($string, '/');
}
// 驼峰转换下划线加小写字母
function hump_to_underline($string)
{
return strtolower(preg_replace('/(?<=[a-z])([A-Z])/', '_$1', $string));
}
// 转换对象为数组
function object_to_array($object)
{
return json_decode(json_encode($object), true);
}
// 转换数组为对象
function array_to_object($array)
{
return json_decode(json_encode($array));
}
// 值是否在对象中
function in_object($needle, $object)
{
foreach ($object as $value) {
if ($needle == $value)
return true;
}
}
// 结果集中查找指定字段父节点是否存在
function result_value_search($needle, $result, $skey)
{
foreach ($result as $key => $value) {
if ($value->$skey == $needle) {
return $key;
}
}
return false;
}
// 多维数组合并
function mult_array_merge($array1, $array2)
{
if (is_array($array2)) {
foreach ($array2 as $key => $value) {
if (is_array($value)) {
if (array_key_exists($key, $array1)) {
$array1[$key] = mult_array_merge($array1[$key], $value);
} else {
$array1[$key] = $value;
}
} else {
$array1[$key] = $value;
}
}
}
return $array1;
}
// 数组转换为带引号字符串
function implode_quot($glue, array $pieces, $diffnum = false)
{
if (! $pieces)
return "''";
foreach ($pieces as $key => $value) {
if ($diffnum && ! is_numeric($value)) {
$value = "'$value'";
} elseif (! $diffnum) {
$value = "'$value'";
}
if (isset($string)) {
$string .= $glue . $value;
} else {
$string = $value;
}
}
return $string;
}
// 是否为多维数组,是返回true
function is_multi_array($array)
{
if (is_array($array)) {
return (count($array) != count($array, 1));
} else {
return false;
}
}
// 是否为移动设备
function is_mobile()
{
$os = get_user_os();
if ($os == 'Android' || $os == 'iPhone' || $os == 'Windows Phone' || $os == 'iPad') {
return true;
}
}
// 是否为POST请求
function is_post()
{
if ($_POST) {
return true;
} else {
return false;
}
}
// 是否为GET请求
function is_get()
{
if ($_GET) {
return true;
} else {
return false;
}
}
// 是否为PUT请求
function is_put()
{
if ($_SERVER['REQUEST_METHOD'] == 'PUT') {
return true;
} else {
return false;
}
}
// 是否为PATCH请求
function is_patch()
{
if ($_SERVER['REQUEST_METHOD'] == 'PATCH') {
return true;
} else {
return false;
}
}
// 是否为DELETE请求
function is_delete()
{
if ($_SERVER['REQUEST_METHOD'] == 'DELETE') {
return true;
} else {
return false;
}
}
// 是否为AJAX请求
function is_ajax()
{
if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
return true;
} else {
return false;
}
}
// 判断当前是否为https
function is_https()
{
if ((isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on')) {
return true;
} elseif (isset($_SERVER['REQUEST_SCHEME']) && strtolower($_SERVER['REQUEST_SCHEME']) == 'https') {
return true;
} elseif (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) == 'https') {
return true;
} elseif (isset($_SERVER['HTTP_X_CLIENT_SCHEME']) && strtolower($_SERVER['HTTP_X_CLIENT_SCHEME']) == 'https') {
return true;
} else {
return false;
}
}
// 获取当前访问地址
function get_http_url($noport = false)
{
if (is_https()) {
$url = 'https://' . $_SERVER['HTTP_HOST'];
} else {
$url = 'http://' . $_SERVER['HTTP_HOST'];
}
if ($noport) {
$url = str_replace(':' . $_SERVER['SERVER_PORT'], '', $url);
}
return $url;
}
// 获取当前访问域名
function get_http_host($noport = true)
{
if ($noport) {
return str_replace(':' . $_SERVER['SERVER_PORT'], '', $_SERVER['HTTP_HOST']);
} else {
return $_SERVER['HTTP_HOST'];
}
}
// 服务器信息
function get_server_info()
{
// 定义输出常量
define('YES', 'Yes');
define('NO', '<span style="color:red">No</span>');
// 服务器系统
$data['php_os'] = PHP_OS;
// 服务器访问地址
$data['http_host'] = $_SERVER['HTTP_HOST'];
// 服务器名称
$data['server_name'] = $_SERVER['SERVER_NAME'];
// 服务器端口
$data['server_port'] = $_SERVER['SERVER_PORT'];
// 服务器地址
$data['server_addr'] = isset($_SERVER['LOCAL_ADDR']) ? $_SERVER['LOCAL_ADDR'] : $_SERVER['SERVER_ADDR'];
// 服务器软件
$data['server_software'] = $_SERVER['SERVER_SOFTWARE'];
// 站点目录
$data['document_root'] = isset($_SERVER['DOCUMENT_ROOT']) ? $_SERVER['DOCUMENT_ROOT'] : DOC_PATH;
// PHP版本
$data['php_version'] = PHP_VERSION;
// 数据库驱动
$data['db_driver'] = Config::get('database.type');
// php配置文件
$data['php_ini'] = @php_ini_loaded_file();
// 最大上传
$data['upload_max_filesize'] = ini_get('upload_max_filesize');
// 最大提交
$data['post_max_size'] = ini_get('post_max_size');
// 最大提交文件数
$data['max_file_uploads'] = ini_get('max_file_uploads');
// 内存限制
$data['memory_limit'] = ini_get('memory_limit');
// 检测gd扩展
$data['gd'] = extension_loaded('gd') ? YES : NO;
// 检测imap扩展
$data['imap'] = extension_loaded('imap') ? YES : NO;
// 检测socket扩展
$data['sockets'] = extension_loaded('sockets') ? YES : NO;
// 检测curl扩展
$data['curl'] = extension_loaded('curl') ? YES : NO;
// 会话保存路径
$data['session_save_path'] = session_save_path() ?: $_SERVER['TMP'];
// 检测standard库是否存在
$data['standard'] = extension_loaded('standard') ? YES : NO;
// 检测多线程支持
$data['pthreads'] = extension_loaded('pthreads') ? YES : NO;
// 检测XCache支持
$data['xcache'] = extension_loaded('XCache') ? YES : NO;
// 检测APC支持
$data['apc'] = extension_loaded('APC') ? YES : NO;
// 检测eAccelerator支持
$data['eaccelerator'] = extension_loaded('eAccelerator') ? YES : NO;
// 检测wincache支持
$data['wincache'] = extension_loaded('wincache') ? YES : NO;
// 检测ZendOPcache支持
$data['zendopcache'] = extension_loaded('Zend OPcache') ? YES : NO;
// 检测memcache支持
$data['memcache'] = extension_loaded('memcache') ? YES : NO;
// 检测memcached支持
$data['memcached'] = extension_loaded('memcached') ? YES : NO;
// 已经安装模块
$loaded_extensions = get_loaded_extensions();
$extensions = '';
foreach ($loaded_extensions as $key => $value) {
$extensions .= $value . ', ';
}
$data['extensions'] = $extensions;
return json_decode(json_encode($data));
}
// 获取数据库类型
function get_db_type()
{
switch (Config::get('database.type')) {
case 'mysqli':
case 'pdo_mysql':
$db = 'mysql';
break;
case 'sqlite':
case 'pdo_sqlite':
$db = 'sqlite';
break;
case 'pdo_pgsql':
$db = 'pgsql';
break;
default:
$db = null;
}
return $db;
}
// 获取间隔的月份的起始及结束日期
function get_month_days($date, $start = 0, $interval = 1, $retamp = false)
{
$timestamp = strtotime($date) ?: $date;
$first_day = strtotime(date('Y', $timestamp) . '-' . date('m', $timestamp) . '-01 +' . $start . ' month');
$last_day = strtotime(date('Y-m-d', $first_day) . ' +' . $interval . ' month -1 day');
if ($retamp) {
$return = array(
'first' => $first_day,
'last' => $last_day
);
} else {
$return = array(
'first' => date('Y-m-d', $first_day),
'last' => date('Y-m-d', $last_day)
);
}
return $return;
}
// 框架地址地址前缀
function url_index_path($indexfile = null)
{
$indexfile = $indexfile ?: $_SERVER["SCRIPT_NAME"];
if (Config::get('app_url_type') == 2 && strripos($indexfile, 'index.php') !== false) {
return SITE_DIR;
} elseif (Config::get('app_url_type') == 3 && strripos($indexfile, 'index.php') !== false) {
return SITE_DIR . '/?p=';
} elseif (Config::get('app_url_type') == 3 && strripos($indexfile, 'index.php') === false) {
return $indexfile . '?p=';
} else {
return $indexfile;
}
}
// 获取服务端web软件
function get_server_soft()
{
$soft = strtolower($_SERVER["SERVER_SOFTWARE"]);
if (strpos($soft, 'iis')) {
return 'iis';
} elseif (strpos($soft, 'apache')) {
return 'apache';
} elseif (strpos($soft, 'nginx')) {
return 'nginx';
} else {
return 'other';
}
}
// 创建会话层级目录
function create_session_dir($path, $depth)
{
if ($depth < 1) {
return;
} else {
$depth --;
}
$char = array(
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
'j',
'k',
'l',
'm',
'n',
'o',
'p',
'q',
'r',
's',
't',
'u',
'v'
);
foreach ($char as $value) {
if (! check_dir($path . '/' . $value, true)) {
error('会话目录写入权限不足!');
}
create_session_dir($path . '/' . $value, $depth);
}
}
// 中英混合的字符串截取,以一个汉字为一个单位长度,英文为半个
function substr_both($string, $strat, $length)
{
$s = 0; // 起始位置
$i = 0; // 实际Byte计数
$n = 0; // 字符串长度计数
$str_length = strlen($string); // 字符串的字节长度
while (($n < $length) and ($i < $str_length)) {
$ascnum = Ord(substr($string, $i, 1)); // 得到字符串中第$i位字符的ascii码
if ($ascnum >= 224) { // 根据UTF-8编码规范将3个连续的字符计为单个字符
$i += 3;
$n ++;
} elseif ($ascnum >= 192) { // 根据UTF-8编码规范将2个连续的字符计为单个字符
$i += 2;
$n ++;
} else {
$i += 1;
$n += 0.5;
}
if ($s == 0 && $strat > 0 && $n >= $strat) {
$s = $i; // 记录起始位置
}
}
if ($n < $strat) { // 起始位置大于字符串长度
return;
}
return substr($string, $s, $i);
}
// 中英混合的字符串长度,以一个汉字为一个单位长度,英文为半个
function strlen_both($string)
{
$i = 0; // 实际Byte计数
$n = 0; // 字符串长度计数
$str_length = strlen($string); // 字符串的字节长度
while ($i < $str_length) {
$ascnum = Ord(substr($string, $i, 1)); // 得到字符串中第$i位字符的ascii码
if ($ascnum >= 224) { // 根据UTF-8编码规范将3个连续的字符计为单个字符
$i += 3;
$n ++;
} elseif ($ascnum >= 192) { // 根据UTF-8编码规范将2个连续的字符计为单个字符
$i += 2;
$n ++;
} else {
$i += 1;
$n += 0.5;
}
}
return $n;
}
// 获取地址参数
function query_string($unset = null)
{
if (isset($_SERVER["QUERY_STRING"]) && ! ! $qs = $_SERVER["QUERY_STRING"]) {
parse_str($qs, $output);
unset($output['page']);
$unset = strpos($unset, ',') ? explode(',', $unset) : $unset;
if (is_array($unset)) {
foreach ($unset as $value) {
if (isset($output[$value])) {
unset($output[$value]);
}
}
} else {
if (isset($output[$unset])) {
unset($output[$unset]);
}
}
// 避免路径参数编码
if (isset($output['p'])) {
$p = 'p=' . $output['p'];
unset($output['p']);
$qs = $output ? $p . '&' . http_build_query($output) : $p;
} else {
$qs = http_build_query($output);
}
}
return $qs ? '?' . $qs : '';
}
// 判断是否在子网
function network_match($ip, $network)
{
if (strpos($network, '/') > 0) {
$network = explode('/', $network);
$move = 32 - $network[1];
if ($network[1] == 0) {
return true;
}
return ((ip2long($ip) >> $move) === (ip2long($network[0]) >> $move)) ? true : false;
} elseif ($network == $ip) {
return true;
} else {
return false;
}
}
// 递归替换
function preg_replace_r($search, $replace, $subject)
{
while (preg_match($search, $subject)) {
$subject = preg_replace($search, $replace, $subject);
}
return $subject;
}
// 生成随机验证码
function create_code($len = 4)
{
$charset = 'ABCDEFGHKMNPRTUVWXY23456789';
$charset = str_shuffle($charset);
$charlen = strlen($charset) - 1;
$code = '';
for ($i = 0; $i < $len; $i ++) {
$code .= $charset[mt_rand(0, $charlen)];
}
return $code;
}

View File

@@ -0,0 +1,25 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>错误信息</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0" />
<meta name="apple-mobile-web-app-capable" content="yes" />
</head>
<body>
<div style="margin-left:10%;margin-top:5%;">
<div style="margin-bottom:20px;"><img src="{coredir}/template/face02.png" height="120"></div>
<div style="font-size:20px;margin-bottom:20px;">{info} <span id="time" style="font-size:18px;"></span></div>
<div><span style="font-size:12px;border-top:1px solid #ccc;color:#ccc;padding-top:2px;">
程序版本:{appversion}
操作系统:{serveros}
WEB应用{serversoft}
</span></div>
</div>
{js}
</body>
</html>

View File

@@ -0,0 +1,669 @@
##########################################
官方网站https://www.pbootcms.com
标签手册https://www.pbootcms.com/docs.html
##########################################
PbootCMS V3.0.6 build 2021-09-29
1、新增文章多图标题功能,前台标签:[pics:title]
2、新增在config中定义cmsname变量修改系统显示名称
3、去除后台底部版权区域扩大操作范围
4、支持修改CMS名称后自动隐藏官方信息
5、栏目新增def1-def3三个备用描述字段
PbootCMS V3.0.5 build 2021-06-18
1、修复系统存在的安全漏洞重要
PbootCMS V3.0.4 build 2021-02-14
1、新增{pboot:sql sql="语句"}[sql:字段]{/pboot:sql}万能循环标签;
2、新增自动跳转HTTPS功能参数
3、新增自动跳转主域名功能参数
4、修复地址栏扩展后可附带任意字符问题;
5、修复部分主机CDN后台跳转异常
6、升级layui为最新版本
7、修复系统存在的安全问题
8、优化内容含有标签的处理
PbootCMS V3.0.3 build 2020-10-07
1、修复上版本出现的地址后缀不一致问题
2、修复搜索功能多语言混乱问题
3、新增{pboot:isregister}用于js检查用户名是否已经注册
4、修复已经注册的邮箱仍然发送验证码问题
5、修复系统存在的安全问题
PbootCMS V3.0.2 build 2020-08-04
1、修复会员评论无昵称时不解析标签问题
2、修复默认模板留言页面判断错误问题
3、修复两处存在安全隐患的漏洞
4、修复首页筛选兼容模式错误
5、修复tag标签地址错误问题
6、修复扩展类文件地址错误问题
7、修复文章关闭后tag依然调用问题
8、修复后台设置搜索词标题不解析问题
9、修复内置附件标签不支持截取问题
10、其他问题修复与优化
PbootCMS V3.0.1 build 2020-07-09
1、修复会员权限不足报错页面被404覆盖掉问题
2、新增对循环体标签整体进行访问权限控制如list,nav等
3、新增内容权限不足时调整登录界面“不等待跳登录”参数控制
PbootCMS V3.0.0 build 2020-07-06
1、新增会员功能支持注册、登录、资料、积分等操作;
2、支持对会员相关功能进行后台配置;
3、支持对栏目设置会员权限、权限类型、权限提示
4、支持对内容设置会员权限、权限类型、权限提示
5、支持模板中设置指定页面必须登录
6、支持模板中设置标签指定权限可见或隐藏
7、支持内容评论功能(参考默认模板)
8、支持会员注册邮件验证码功能
9、支持留言关联登录用户新增标签nickname、username、headpic
//相关表单字段
username、password、checkcode //登录必填
username、nickname、password、rpassword、checkcode //注册必填
comment、checkcode //评论必填
//会员页面标签
{pboot:ucenter} 个人中心地址
{pboot:login} 登录地址
{pboot:register} 注册地址
{pboot:umodify} 资料修改地址
{pboot:logout} 退出登录地址
{pboot:upload} 文件上传AJAX接口
{pboot:islogin} 是否登录状态
{pboot:mustlogin} 设置页面必须登录
{pboot:sendemail} 发送邮件验证码接口,参数to
{pboot:registercodestatus} 会员注册验证码状态0、1、2
{pboot:logincodestatus} 会员登录验证码状态
{pboot:registerstatus} 是否开启注册
{pboot:loginstatus} 是否开启登录
{pboot:commentstatus} 是否开启评论
//会员模板控制标签,如:{content:title showgcode=1}
showgcode=* 指定等级显示,支持多个逗号隔开
showucode=* 指定用户显示,支持多个逗号隔开
hidegcode=* 指定等级隐藏,支持多个逗号隔开
hideucode=* 指定用户隐藏,支持多个逗号隔开
showgcodelt=* 等级小于显示
showgcodegt=* 等级大于显示
showgcodele=* 等级小于等于显示
showgcodege=* 等级大于等于显示
hidegcodelt=* 等级小于隐藏
hidegcodegt=* 等级大于隐藏
hidegcodele=* 等级小于等于隐藏
hidegcodege=* 等级大于等于隐藏
showlogin=1 登录后显示
hidelogin=1 登录后隐藏
对于内容及栏目,也支持在后台直接控制
//会员资料标签,全局可用
{user:ucode} 会员编码
{user:username} 会员用户名
{user:useremail} 会员邮箱
{user:usermobile} 会员手机
{user:gcode} 等级编码
{user:gname} 等级名称
{user:registertime} 注册时间
{user:logincount} 登录次数
{user:lastloginip} 最后登录IP
{user:lastlogintime} 最后登录时间
{user:headpic} 头像URL
{user:***} 自定义会员字段,如果{user:sex}
//文章评论
{pboot:commentcodestatus} 验证码是否开启
{pboot:commentaction} 评论提交地址
{pboot:comment contentid={content:id}}
[comment:i] 序号0开始
[comment:n] 序号1开始
[comment:pid] 父评论ID
[comment:contentid] 评论文章ID
[comment:comment] 评论内容
[comment:ip] IP地址
[comment:os] 操作系统
[comment:bs] 浏览器
[comment:date] 日期
[comment:uid] 评论人ID
[comment:username] 评论人账号
[comment:nickname] 评论人昵称
[comment:headpic] 评论人头像
[comment:pid] 父评论人ID
[comment:pusername] 父评论人账号
[comment:pnickname] 父评论人昵称
[comment:pheadpic] 父评论人头像
[comment:likes] 点赞数量
[comment:oppose] 反对数量
[comment:replyaction] 评论回复提交地址
{pboot:commentsub} 子评论输出
[commentsub:***] 子评论调用字段同上
{/pboot:commentsub}
{/pboot:comment}
//我的评论
{pboot:mycommentpage} 我的评论页面地址
{pboot:mycomment}
[mycomment:i] 序号0开始
[mycomment:n] 序号1开始
[mycomment:pid] 父评论ID
[mycomment:contentid] 评论文章ID
[mycomment:comment] 评论内容
[mycomment:title] 文章标题
[mycomment:ip] IP地址
[mycomment:os] 操作系统
[mycomment:bs] 浏览器
[mycomment:date] 日期
[mycomment:uid] 评论人ID
[mycomment:username] 评论人账号
[mycomment:nickname] 评论人昵称
[mycomment:headpic] 评论人头像
[mycomment:pid] 父评论人ID
[mycomment:pusername] 父评论人账号
[mycomment:pnickname] 父评论人昵称
[mycomment:pheadpic] 父评论人头像
[mycomment:likes] 点赞数量
[mycomment:oppose] 反对数量
[mycomment:status] 评论状态1审核2待审核
[mycomment:replyaction] 评论回复提交地址
[mycomment:delaction] 评论删除地址
{/pboot:mycomment}
PbootCMS V2.0.9 build 2020-06-18
1、新增多语言分享链接自动切换功能并新增后台开关;
2、新增后台设置网站页面标题样式功能;
3、修复列表序号翻页不连续问题;
4、修复地址生成函数特殊情况后缀判断不准问题
5、新增百度快速推送功能
6、系统安全问题修复
PbootCMS V2.0.8 build 2020-04-26
1、修复兼容模式分享链接导致打不开页面问题
2、修复几处可能影响系统安全的漏洞
3、修改使用IP访问不再需要域名授权码
4、修复个别空间的兼容性问题。
PbootCMS V2.0.7 build 2020-04-06
1、修复后台被登录成功后系统更新处可能造成的安全漏洞
2、修复dropblank不支持全角空格过滤问题;
3、新增万能码用户后台SVIP尊贵标识
4、修复模板子目录在目标文件夹存在时失败问题
5、修复后台内容编辑页面切换语言导致无限循环问题
6、新增后台切换多语言时同步切换前台语言
PbootCMS V2.0.6 build 2020-03-18
1、修复搜索结果关键字标红无法正常匹配大小写问题
2、新增后台“安全配置”中配置模板文件子目录功能
3、修复operate参数无法使用小数问题
4、新增tags列表支持指定参数target=tag跳转到tag.html模板参考默认模板
5、新增home下ExtLabelController控制器文件扩展个人标签升级不覆盖
6、优化调整前台代码结构
7、新增后台内容列表每页显示数量选择
8、修复tags重复显示问题
9、新增config/route.php文件自定义二开路由支持
10、新增API内容列表返回自适应的内容网页链接地址contentlink
11、修复API内容API链接错误并修改参数为apilink
12、修复API留言及表单无法关闭功能问题
PbootCMS V2.0.5 build 2020-01-31
1、优化前台404.html并支持内容内{info}自适应提示文字;
2、优化内容列表排序方式,并修复api使用随机排序无效问题
3、修复后台入口文件修改名字后在线升级无法自适应问题
4、新增lfield="a,b,*"限制列表查询字段,提高大数据时速度;
5、新增系统自适应入口文件子目录的能力
6、新增留言及表单数据清空功能(管理员)
7、新增留言及表单数据导出功能
8、新增mark=1标签参数对搜索结果关键字进行标红[search:title mark=1]
9、其他问题修复与优化。
PbootCMS V2.0.4 build 2020-01-21
1、修复部分循环体控制参数无效问题
2、修复一处安全漏洞并全局加强系统安全过滤
3、修复面包屑参数中不能使用html的问题
4、修复API接口中post方式page无效问题
5、新增程序全自动修改数据库名
6、新增operate参数对标签进行加减乘除等运算[list:i operate=+100]
7、新增站点关闭功能
8、新增站点访问IP黑白名单功能
9、升级layui到最新版本。
PbootCMS V2.0.3 build 2019-10-25
1、修复一处PHP7环境下的安全漏洞
2、新增关闭留言、表单功能的开关
3、新增缩略图未上传时自动获取文章图片
4、其他问题修复与优化。
PbootCMS V2.0.2 build 2019-09-15
1、伪静态时不再允许访问普通模式地址
2、新增xx:ispics判断是否有多图
3、新增页面内容关键词过滤功能
4、升级layui到最新版本
5、其他问题修复与优化。
PbootCMS V2.0.1 build 2019-08-15
1、优化编辑器工具栏浮动功能
2、优化数据库备份文件名称;
3、优化基础环境组件检查功能
4、修复默认模板一处链接错误
5、修复API一处提示文字错误
6、修复内链替换alt、title内容的问题;
7、去除内置测试账号避免被恶意利用
PbootCMS V2.0.0 build 2019-08-12
1、全新多种URL地址模式上线模型、栏目、内容自由后台设置
2、后台不再依赖pathinfo提高环境兼容性
3、新增模型下面有栏目时不允许直接删除
4、调整跨语言区域调用内容不再自动切换区域;
5、新增上下篇preico标签调用缩略图
6、优化在线更新文件过多时下载问题
7、优化sitamap生成格式
8、其他大量系统框架优化及调整;
9、修复个别空间商的兼容性问题
PbootCMS V1.4.3 build 2019-08-10
1、修复调用指定内容单页链接指向错误问题
2、优化调整模板引擎链接生成过程
3、优化在线更新功能
4、新增升级到2.X分支版本的通道
5、其他问题修复与优化
PbootCMS V1.4.2 build 2019-07-22
1、修复内容tags为空时也有代码输出问题
2、新增文章内链替换次数系统配置参数
3、新增修改栏目时可选同步修改子栏目模板的功能
4、新增批量添加栏目功能
5、新增自定义表单添加到左侧导航菜单功能
6、修复角色修改时区域数量显示不全问题
7、修复IE浏览器翻页兼容性问题
8、优化调整内链替换为长关键字优先
9、新增连续多次登录失败后锁定IP功能
10、新增自动记住上次添加内容栏目功能
11、修复一处可能被利用的安全漏洞感谢stick.wang@Zionlab
12、新增表单提交验证码独立开关并优化邮箱提醒标题
13、其他问题修复与优化
PbootCMS V1.4.1 build 2019-07-12
1、扩大自定义字段默认长度
2、升级layui为最新版本
3、修复后台IE浏览器部分兼容性问题
4、修复新增区域无法绑定域名问题
5、修复图片无法拖动排序问题
6、修复单独修改用户角色不成功问题
7、修复微信分享参数导致安全拦截提示问题
8、修复登录失败时验证码不刷新问题
9、修复编辑器未能按设置大小缩放图片问题
10、优化合并邮箱配置功能到系统配置
11、增加会话文件路径后台切换功能
12、新增单页模型也在左侧导航中显示
13、新增文章图片水印功能
14、新增文章内容内链功能
15、其他问题修复与优化
PbootCMS V1.4.0 build 2019-06-07
1、修复部分浏览器多图无法删除的问题
2、新增万能授权码填写后自动后台隐藏功能
3、修复QQ中打开搜索页面附加参数导致错误问题
4、修复后台密码泄露后系统配置可能构成的安全问题
PbootCMS V1.3.9 build 2019-05-15
1、优化相关目录权限不足报错机制
2、修复PHP56有时后台更新无法使用问题
3、优化后台在线升级功能
4、新增中文路径部署检测
5、优化升级系统框架模板引擎
6、新增自定义路由正则匹配的支持
7、新增后台配置数字分页条数量
8、其他问题修复与优化
PbootCMS V1.3.8 build 2019-04-12
1、新增同时支持fsockopen及stream_socket_client发送邮件
2、优化邮件发送失败错误提示信息
3、新增手机版绑定域名后自动跳转到对应域名地址上
4、修改会话文件默认为使用系统环境缓存路径
5、修复mysqli配置文件读取端口不一致问题
6、修复tags为空时仍然会输出代码字符问题
7、修复开启缓存功能后异样地址会导致文件产生问题
8、修复编辑器在PHP7下多图上传名字重复问题
9、修复编辑器多图上传位置错乱问题
PbootCMS V1.3.7 build 2019-03-12
1、修复部分情况数据库语句执行发生的错误不能正常显示的问题
2、修复搜索时表单传递字段控制被过滤掉的问题
3、新增多个搜索通过传递searchtpl字段自定义不同搜索结果页模板
4、修复分享非默认语言链接后无法直接访问问题
5、新增跨语言调用内容及列表的支持
6、新增留言使用lg=*调取指定语言留言记录功能;
7、新增order=random调取随机排序内容列表
8、修复上传图片字段使用网络图片时地址错误问题
9、修复栏目seo标题使用自动标题时不显示问题
PbootCMS V1.3.6 build 2019-01-12
1、框架问题修复与优化;
2、优化后台在线升级功能;
3、修复api内容列表无法传递自定义排序问题;
4、去除后台执行sql语句功能;
5、新增超级管理员清空日志功能
6、修复测试邮件发送失败返回中文乱码的问题;
PbootCMS V1.3.5 build 2018-12-24
1、修复邮件测试功能被误拦截问题;
2、修复使用首页分页与筛选时出现两种链接类型问题;
3、修复编辑器工具栏不能正常浮动到顶部及视频插入问题;
4、修复gif不能正常缩放及png透明图片缩放后背景变黑问题;
5、新增内容截取时使用more='*'设置省略号内容;
6、新增调节参数maxwidth、maxheight、height、width对图片进行处理;
7、进一步加强系统入侵防御能力;
8、后台主页、验证码、上传、默认模板等的改进与优化;
9、其他问题修复与优化;
PbootCMS V1.3.3 build 2018-11-29
1、新增sort指定栏目输出支持后台排序规则;
2、修复PHP7.3环境下的一些兼容性问题;
3、修改自定义表单数据调用列表为formlist标签避免标签冲突问题;
4、修复多个列表的页面筛选对非筛选列表干扰问题;
5、修复if判断详情内容是否为空无效问题;
6、修复自定义字段英文单词之间空格被过滤掉的问题;
7、修复一处可能导致恶意利用的漏洞重要;
8、进一步增强系统框架安全防御策略;
9、验证码加入英文字母增强复杂度;
PbootCMS V1.3.2 build 2018-11-22
1、修复用户名验证规则不统一导致修改特殊字符后无法登录问题;
2、修复js无法获取到点赞及反对cookie的问题;
3、修复content标签无法使用scode调取单页问题;
4、新增start=*设置数据列表起始数据;
5、加强后台执行数据库脚本功能的安全性;
6、新增默认正文内容不再对PB标签进行解析;
7、修复上版本API搜索接口无法正常实现功能的问题;
8、新增lencn=* 截取长度,解决中英文显示长度不同问题;
9、其他问题修复与优化。
PbootCMS V1.3.1 build 2018-11-14
1、优化在线升级功能;
2、修复表单Ajax提交返回状态码不正确问题;
3、优化会话层级目录创建避免会话目录缺失导致登录失败的情况;
PbootCMS V1.3.0 build 2018-11-12
1、优化会话创建机制,避免会话文件过多问题;
2、修复一些可能导致注入的安全问题(感谢topsec(zhan_ran)及CNVD的反馈);
3、修复搜索结果无法按预期显示的的问题;
4、新增内容页、列表页404自动匹配的支持;
5、新增支持在根目录定义sn.html文件自定义免费授权码填写提示;
6、新增API通过scode来调用单篇内容;
7、新增[nav:rows]输出该菜单下内容数量;
8、新增[sort:rows]输出该栏目下内容数量;
9、新增[sort:toprows]输出顶级栏目下内容数量;
10、新增[sort:parentrows]输出父栏目下内容数量;
11、新增内置tags功能不再需要扩展字段实现;
12、新增输出指定内容或栏目tags标签功能;
13、新增列表使用参数tags='*,*'过滤列表;
14、新增列表使用参数scode=*匹配全部栏目;
15、新增指定内容输出单页时支持scode来指定内容;
16、新增栏目独立seo标题设置字段[nav:title];
17、新增开启iis\apache伪静态时自动拷贝伪静态规则;
18、新增后台内容列表百度站长推送及熊掌号推送;
19、新增多语言\区域绑定域名功能(站群系统);
20、新增留言及表单记录调用时使用page=0关闭分页;
21、其他问题修复与优化。
PbootCMS V1.2.2 build 2018-10-12
1、修复自定义表单多选类型提交数据错误问题;
2、修复发送邮件设置完成不立即生效问题;
3、修复发送测试邮件不能正确返回状态的问题;
4、修复分页代码数字条省略号不准问题;
5、修复后台编辑器的一些问题;
6、修复自定义标签的图片不自适应多级目录问题;
7、修复使用mysql数据库时可能导致的安全问题;
8、修复列表筛选与指定分类列表冲突问题;
9、修复多次调用内容标签导致重复计算访问量问题;
10、大幅提高Sqlite数据库数据写入速度;
11、优化后台登录错误处理机制;
12、优化数据列表排序方式;
13、新增模板嵌套引用的支持;
14、新增在线更新涉及数据库时自动备份数据库;
15、新增在线更新分支选择功能;
16、新增对指定代码块不做标签解析的标签;
17、新增列表多条件排序自定义任意组合的支持,如:order='istop desc,id asc'
18、新增MySQL数据库事务的支持;
19、新增自定义标签多行文本类型;
20、新增文章定时发布的支持;
21、其它问题修复与优化。
PbootCMS V1.2.1 build 2018-09-12
1、新增在线升级新版本红点提示;
2、新增程序部署到非根目录时虚拟目录大小写不区分;
3、新增表单提交频率安全检测;
4、调整程序非伪静态时不再显示html后缀;
5、调整程序留言表单外的自定义表单不再要求验证码;
6、修复上版本首页分页不正常问题;
7、优化完善默认模板;
PbootCMS V1.2.0 build 2018-09-04
1、系统优化及安全修复;
2、修复API搜索与页面实现不统一;
3、优化后台内容页栏目显示逻辑;
4、新增后台轮播、链接页面批量排序;
5、升级layui到最新版本;
6、新增列表标签isico、ispics、istop、isrecommend、isheadline调节参数;
7、新增面包屑连接符separatoriconc及indexicon参数设置字体图标class;
8、优化分页条代码;
9、新增内容截取时自动添加省略号;
10、基于bootstrap v4的全新默认模板正式上线;
11、修复在线更新浏览器兼容性问题;
PbootCMS V1.1.9 build 2018-08-17
1、系统优化及安全修复(重要);
2、修复自定义表单Mysql时添加失败问题;
3、修复后台模板一些小错误;
4、修复影响缓存效果的一些问题;
5、新增后台在线更新功能;
6、新增附件大小标签;
PbootCMS V1.1.8 build 2018-08-07
1、修复提交表单多选字段接收数据问题;
2、修复登录过程中二次登录在页面不刷新时验证失败问题;
3、新增搜索结果fuzzy参数来控制是否模糊匹配;
4、新增父分类、顶级分类名称及链接独立标签具体见手册;
5、新增内容多图拖动排序功能;
PbootCMS V1.1.7 build 2018-08-01
1、修复测试邮件不发送到填写的测试邮箱问题;
2、修复友情链接添加时排序报错问题;
3、修复API幻灯片及友情链接排序无效;
4、修复站内Ajax调用API数据时间戳过期问题;
5、新增自定义标签开关类型;
6、新增自定义表单数据调取标签;
7、新增单页设置跳转后内容不再出现管理列表中;
8、新增搜索支持多字段同时匹配;
9、新增点击上传的图片自动添加到编辑器;
10、优化表单提交验证;
11、其它问题修复与优化;
PbootCMS V1.1.6 build 2018-07-21
1、优化编辑器配置及安全加固;
2、优化内容管理列表布局;
3、增强系统后台及标签解析引擎安全性;
4、调整runtime标签展示方式;
5、新增Gzip页面压缩功能及后台开关;
6、新增支持根目录定义404.html匹配错误URL访问;
7、新增缩略图自动缩放更小图功能;
8、新增config/route.php文件里定义路由规则的支持;
9、新增调用指定栏目 标签scode支持多个分类;
10、新增如果栏目及内容关键字标签为空时自动使用全局关键字;
11、新增如果栏目及内容描述标签为空时自动使用全局描述;
12、新增全局自动页面标题标签{pboot:pagetitle};
13、新增全局自动页面关键字标签{pboot:pagekeywords};
14、新增全局自动页面描述标签{pboot:pagedescription}
15、新增留言表单添加更多字段的支持;
16、新增幻灯片、友情链接、扩展字段排序的支持;
17、新增sitemap生成读取地址/index.php/sitemap;
18、新增URL路径支持中文;
19、新增中文用户名登录的支持;
20、新增API正文内容返回图片路径自动添加网址路径;
21、新增邮件配置中发送测试邮件功能;
22、新增API调用自定义表单数据接口;
23、其它问题修复与优化;
注意:升级到此版本需要同时升级数据库,脚本见升级包中。
PbootCMS V1.1.5 build 2018-07-10
1、修复开启静态缓存后无法切换语言问题;
2、修复开启静态缓存后无法自动切换手机版;
3、修复数据库安全检查不准问题;
4、修复后台多选字段无法取消问题;
5、新增调试模式后台开关;
6、新增访问地址不存在时404状态信息;
7、新增运行时间标签{pboot:runtime};
8、新增留言验证码判断标签{pboot:checkcodestatus};
9、新增筛选全部按钮的class和active分别设置;
10、新增类似filter=title|php,asp多条件过滤支持;
11、新增搜索列表scode、field调节控制参数支持;
12、新增任意字段搜索及综合搜索支持;
13、新增列表零开头序号标签[list:n];
14、新增loop循环语句标签;
15、新增模型字段下拉选择类型;
16、优化内容页访问量代码插入方式;
17、优化会话文件处理方式;
18、优化框架模板解析引擎;
19、优化后台单页数据读取方式;
20、优化系统配置载入方式;
21、优化API数据读取;
PbootCMS V1.1.4 build 2018-06-25
1、修复自定义表单表名重复仍然添加成功问题;
2、修复分享到微信导致页面错误的问题;
3、修复静态缓存失效问题并提高缓存效果;
4、新增多条件筛选时多选类型支持;
5、新增全站多条件筛选的支持;
6、新增登录时数据库目录写入权限判断提示;
7、新增后台开启高速静态缓存功能;
8、新增后台填写授权码功能;
9、新增指定列表scode使用逗号调用多个分类功能;
10、新增{pboot:keyword}标签;
11、新增数据库安全提示及修改功能;
PbootCMS V1.1.3 build 2018-06-15
1、优化Sqlite查询过程高并发锁死问题;
2、优化编辑器配置;
3、优化标签参数获取方法;
4、修复部分环境截取描述文本出现乱码问题;
5、修复API搜索数据获取方式错误;
6、新增API获取指定分类子类接口;
7、新增多条件筛选功能;
8、新增无缩略图时自动调用默认图功能;
9、新增上下篇标签参数notext定义"没有了"文本;
10、新增内容管理复制和移动功能;
PbootCMS V1.1.2 build 2018-06-12
1、修复httpurl非标准端口时解析错误;
2、修复内容为空时提取描述报警告问题;
3、修复非根目录情况下图片路径使用IF判断不准问题;
4、修复授权码带空格时导致无法正常匹配问题;
5、修复数据库中存在乱码时读取异常问题;
6、修复面包屑不显示当前分类的问题;
7、修复API中数据调用的一些错误;
8、新增表单数据删除功能;
9、新增栏目自定义路径名称功能;
10、新增留言和自定义表单提交API;
PbootCMS V1.1.1 build 2018-06-03
1、更新Layui到最新版本;
2、修复表备份无数据时处理错误;
3、优化添加自定义字段数据库处理方式;
4、修复修改模型时类型默认不选中问题;
5、修复在单页面多次调用面包屑数据重复问题;
6、修复访客留言不显示问题;
7、新增删除栏目时彻底删除本类及子类内容;
8、修复单页预览按钮地址错误;
9、新增自定义表单功能,调用方法见手册;
10、新增二维码生成标签及当前域名获取标签;
11、新增添加内容时自动提取内容描述文字;
12、新增文件上传过程提示图标;
13、新增数据库管理执行Sql脚本功能;
注意:升级到此版本需要同时升级数据库,脚本见升级包中。
PbootCMS V1.1.0 build 2018-05-24
1、修复新增语言后站点和公司信息图片首次出现警告问题;
2、优化文章访问量计数方式;
3、新增扩展字段编辑器类型;
4、新增后台文章列表有图的标注;
5、修复模板部分手误错误;
6、增强搜索时字段安全性;
7、新增PHP环境自动转义判断;
8、新增总页数、总行数分页标签;
9、调整独立分页标签为不带文字的链接;
10、修复多图多次输出num干扰问题;
11、修复新增语言后未做保存导致手机版切换错误;
PbootCMS V1.0.9 build 2018-05-14
1、新增图片上传直接显示及删除功能;
2、修复内容过滤参数及状态失效问题;
3、优化后台菜单显示视觉流畅性;
4、框架入口文件安全加强;
5、面包屑新增indextext参数配置"首页"文字;
6、新增API认证签名生成标签方便进行Ajax加载具体见手册示例;
7、新增上一篇及下一篇链接及标题独立标签并支持len截取;
PbootCMS V1.0.8 build 2018-05-07
1、修复后台菜单高亮错误;
2、修改编辑器为不替换div和不自动拉高;
3、修复删除栏目时子类未全部删除问题;
4、新增后台栏目管理折叠功能;
5、新增手机版绑定独立域名功能;
6、修复多语言切换时栏目编码导致报错;
7、修复副栏目内容无法正常调取问题;
8、新增指定内容扩展字段多选输出标签;
PbootCMS V1.0.7 build 2018-05-02
1、采用LayUI新版管理后台;
2、修复后台单页无法显示更多问题;
3、调整默认分页数字条长度为5;
4、修复API调用全部自定义标签错误;
5、新增内容批量删除功能;
6、新增栏目批量删除功能;
7、修复面包屑对外链跳转问题;
8、修复栏目修改直接保存类型错误;
9、其它问题修复和优化;
PbootCMS V1.0.6 build 2018-04-24
1、修复无任何内容执行排序报错;
2、修复可能存在的跨站请求伪造漏洞;
PbootCMS V1.0.5 build 2018-04-23
1、新增后台配置项自动新增功能;
2、修复logo不自适应多级目录路径;
3、新增十类API调用方便小程序、APP、Ajax等数据获取;
4、修复个别虚拟主机分页代码报警告问题;
5、新增服务器未开启sockets导致非加密发送邮件错误提示;
PbootCMS V1.0.4 build 2018-04-19
1、优化框架配置文件载入方式;
2、修复当前分类列表页过滤参数无效;
3、新增首页分页功能大家可以做博客了;
4、新增模型类菜单桌面同步显示;
5、新增当前栏目位置标签;
PbootCMS V1.0.3 build 2018-04-16
1、修复多图输出只输出一张问题;
2、修复PHP7.1中合并多维数组警告;
3、修复登录地址末尾带有斜杠时错误;
4、新增配置文件自动去除Bom,避免空白;
PbootCMS V1.0.2 build 2018-04-14
1、新增自动去除模板的Bom信息避免空白;
2、优化编辑器可见按钮;
3、修复编辑器无法插入动态地图问题;
4、修复文章排序无法按预期排列问题;
PbootCMS V1.0.1 build 2018-04-13
1、修复数据库导出未正常解码问题;
2、修复系统栏目出现多个新闻内容问题;
3、新增默认及内置区域不允许删除;
4、新增删除区域后强制重新登录;
5、修复前端多语言无法正常切换问题;
6、修复新增语言无法匹配默认模板问题;
7、Mysql脚本默认内容解码有问题大家重新导入sql;
8、修复友情链接图片无法自适应多级目录;
PbootCMS V1.0.0 build 2018-04-12
1、正式发布第一个版本。

View File

@@ -0,0 +1,113 @@
{include file='common/head.html'}
<div class="layui-body">
<div class="layui-tab layui-tab-brief" lay-filter="tab">
<ul class="layui-tab-title">
<li class="layui-this">公司信息</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
<form action="{url./admin/Company/mod}" method="post">
<input type="hidden" name="formcheck" value="{$formcheck}" >
<div class="layui-form-item">
<label class="layui-form-label">公司名称</label>
<div class="layui-input-block">
<input type="text" name="name" value="{$companys->name}" placeholder="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">公司地址</label>
<div class="layui-input-block">
<input type="text" name="address" value="{$companys->address}" placeholder="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">邮政编码</label>
<div class="layui-input-block">
<input type="text" name="postcode" value="{$companys->postcode}" placeholder="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">联系人</label>
<div class="layui-input-block">
<input type="text" name="contact" value="{$companys->contact}" placeholder="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">手机号码</label>
<div class="layui-input-block">
<input type="text" name="mobile" value="{$companys->mobile}" placeholder="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">电话号码</label>
<div class="layui-input-block">
<input type="text" name="phone" value="{$companys->phone}" placeholder="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">传真号码</label>
<div class="layui-input-block">
<input type="text" name="fax" value="{$companys->fax}" placeholder="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">电子邮箱</label>
<div class="layui-input-block">
<input type="text" name="email" value="{$companys->email}" placeholder="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">QQ号码</label>
<div class="layui-input-block">
<input type="text" name="qq" value="{$companys->qq}" placeholder="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">微信二维码</label>
<div class="layui-input-inline">
<input type="text" name="weixin" id="weixin" value="{$companys->weixin}" placeholder="" class="layui-input">
</div>
<button type="button" class="layui-btn upload" data-des="weixin">
<i class="layui-icon">&#xe67c;</i>上传图片
</button>
<div id="weixin_box" class="pic"><dl><dt>{if(@[$companys->weixin])}<img src="{SITE_DIR}{$companys->weixin}" data-url="{$companys->weixin}"></dt><dd>删除</dd></dl>{/if}</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">营业执照代码</label>
<div class="layui-input-block">
<input type="text" name="blicense" value="{$companys->blicense}" placeholder="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">其它信息</label>
<div class="layui-input-block">
<input type="text" name="other" value="{$companys->other}" placeholder="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit>立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
{include file='common/foot.html'}

View File

@@ -0,0 +1,806 @@
{include file='common/head.html'}
<div class="layui-body">
<div class="layui-tab layui-tab-brief" lay-filter="tab">
<ul class="layui-tab-title">
<li class="layui-this" lay-id="t1">基本配置</li>
<li lay-id="t2">邮件通知</li>
<li lay-id="t3">百度接口</li>
<li lay-id="t4">WebAPI</li>
<li lay-id="t5">图片水印</li>
<li lay-id="t6">安全配置</li>
<li lay-id="t7">URL规则</li>
<li lay-id="t8">标题样式</li>
<li lay-id="t9">会员配置</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
<form action="{url./admin/Config/index}" method="post" class="layui-form">
<input type="hidden" name="formcheck" value="{$formcheck}" >
<div class="layui-form-item">
<label class="layui-form-label">网站状态</label>
<div class="layui-input-block">
<input type="radio" name="close_site" value="1" {if([$configs.close_site.value]==1)} checked="checked" {/if} title="关闭">
<input type="radio" name="close_site" value="0" {if([$configs.close_site.value]==0)} checked="checked" {/if} title="开启">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">关站提示</label>
<div class="layui-input-inline">
<textarea name="close_site_note" placeholder="" class="layui-textarea">{$configs.close_site_note.value}</textarea>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">独立手机版</label>
<div class="layui-input-block">
<input type="radio" name="open_wap" value="1" {if([$configs.open_wap.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="open_wap" value="0" {if([$configs.open_wap.value]==0)} checked="checked" {/if} title="禁用">
<span class="layui-icon layui-icon-about tips" data-content="使用响应式模板的用户请不要开启!"></span>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">手机版域名绑定</label>
<div class="layui-input-inline">
<input type="text" name="wap_domain" value="{$configs.wap_domain.value}" placeholder="如m.baidu.com" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">动态缓存</label>
<div class="layui-input-block">
<input type="radio" name="tpl_html_cache" value="1" {if([$configs.tpl_html_cache.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="tpl_html_cache" value="0" {if([$configs.tpl_html_cache.value]==0)} checked="checked" {/if} title="禁用">
<span class="layui-icon layui-icon-about tips" data-content="本功能效果接近生成静态,开启后将提高前端访问速度及并发能力!"></span>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">缓存有效期(秒)</label>
<div class="layui-input-inline">
<input type="text" name="tpl_html_cache_time" value="{$configs.tpl_html_cache_time.value}" placeholder="请输入缓存有效期(秒)" class="layui-input">
</div>
<div class="layui-form-mid layui-word-aux"></div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">Gzip页面压缩</label>
<div class="layui-input-block">
<input type="radio" name="gzip" value="1" {if([$configs.gzip.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="gzip" value="0" {if([$configs.gzip.value]==0)} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">会话文件路径</label>
<div class="layui-input-block">
<input type="radio" name="session_in_sitepath" value="1" {if([$configs.session_in_sitepath.value]==1)} checked="checked" {/if} title="站内">
<input type="radio" name="session_in_sitepath" value="0" {if([$configs.session_in_sitepath.value]==0)} checked="checked" {/if} title="系统">
<span class="layui-icon layui-icon-about tips" data-content="站内则使用站点下runtime路径系统则使用操作系统的缓存路径"></span>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">跨语言自动切换</label>
<div class="layui-input-block">
<input type="radio" name="lgautosw" value="1" {if([$configs.lgautosw.value]=='1'||[$configs.lgautosw.value]=='')} checked="checked" {/if} title="启用">
<input type="radio" name="lgautosw" value="0" {if([$configs.lgautosw.value]=='0')} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">自动转HTTPS</label>
<div class="layui-input-block">
<input type="radio" name="to_https" value="1" {if([$configs.to_https.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="to_https" value="0" {if([$configs.to_https.value]==0)} checked="checked" {/if} title="禁用">
<span class="layui-icon layui-icon-about tips" data-content="访问非HTPPS地址时自动跳转"></span>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">自动转主域名</label>
<div class="layui-input-block">
<input type="radio" name="to_main_domain" value="1" {if([$configs.to_main_domain.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="to_main_domain" value="0" {if([$configs.to_main_domain.value]==0)} checked="checked" {/if} title="禁用">
<span class="layui-icon layui-icon-about tips" data-content="访问非主域名地址时自动跳转!"></span>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">网站主域名</label>
<div class="layui-input-inline">
<input type="text" name="main_domain" value="{$configs.main_domain.value}" placeholder="如www.baidu.com" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">分页数字条数量</label>
<div class="layui-input-inline">
<input type="text" name="pagenum" value="{$configs.pagenum.value}" placeholder="请输入前端分页数字条显示数量" class="layui-input">
</div>
<div class="layui-form-mid layui-word-aux"></div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">内链替换次数</label>
<div class="layui-input-inline">
<input type="text" name="content_tags_replace_num" value="{$configs.content_tags_replace_num.value}" placeholder="请输入文章内链替换次数默认3次" class="layui-input">
</div>
<div class="layui-form-mid layui-word-aux"></div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">敏感词过滤</label>
<div class="layui-input-inline">
<textarea name="content_keyword_replace" placeholder="请输入需要过滤的关键词,多个之间逗号隔开" class="layui-textarea">{$configs.content_keyword_replace.value}</textarea>
<div class="layui-form-mid layui-word-aux">注:多个敏感词之间用逗号隔开!</div>
</div>
</div>
{if(LICENSE<2)}
<div class="layui-form-item">
<label class="layui-form-label">系统授权码</label>
<div class="layui-input-inline">
<input type="text" name="sn" value="{$configs.sn.value}" placeholder="请输入授权码,多个授权码用逗号隔开" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">授权码手机</label>
<div class="layui-input-inline">
<input type="text" name="sn_user" value="{$configs.sn_user.value}" placeholder="请购买了万能授权码的用户填写" class="layui-input">
</div>
</div>
{/if}
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit name="submit" value="basic">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
<div class="layui-tab-item">
<form action="{url./admin/Config/index}" method="post" class="layui-form">
<input type="hidden" name="formcheck" value="{$formcheck}" >
<div class="layui-form-item">
<label class="layui-form-label">服务器状态 </label>
<div class="layui-input-block" style="line-height:36px;">
stream_socket_client函数<i class="layui-icon layui-icon-ok-circle" style="color: {php}echo function_exists('stream_socket_client')?'#5FB878':'#f2f2f2';{/php}"></i>&nbsp;&nbsp;&nbsp;
fsockopen函数 <i class="layui-icon layui-icon-ok-circle" style="color: {php}echo function_exists('fsockopen')?'#5FB878':'#f2f2f2';{/php}"></i>
<span class="layui-icon layui-icon-about tips" data-content="至少需要支持其中一个函数才能正常使用!"></span>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">SMTP服务器</label>
<div class="layui-input-inline">
<input type="text" name="smtp_server" value="{$configs.smtp_server.value}" placeholder="请输入SMTP服务器" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">SMTP端口</label>
<div class="layui-input-inline">
<input type="text" name="smtp_port" value="{$configs.smtp_port.value}" placeholder="请输入SMTP端口,一般SSL为465普通为25" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">是否为SSL</label>
<div class="layui-input-block">
<input type="radio" name="smtp_ssl" value="1" {if([$configs.smtp_ssl.value]==1)} checked="checked" {/if} title="是">
<input type="radio" name="smtp_ssl" value="0" {if([$configs.smtp_ssl.value]==0)} checked="checked" {/if} title="否">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">邮箱账号</label>
<div class="layui-input-inline">
<input type="text" name="smtp_username" value="{$configs.smtp_username.value}" placeholder="请输入邮箱账号" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">邮箱密码</label>
<div class="layui-input-inline">
<input type="password" name="smtp_password" value="{$configs.smtp_password.value}" placeholder="请输入邮箱密码或邮箱授权码" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">测试账号</label>
<div class="layui-input-inline">
<input type="text" name="smtp_username_test" id="smtp_username_test" value="{$configs.smtp_username_test.value}" placeholder="请输入用于接受测试邮件的账号" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">留言发送邮件</label>
<div class="layui-input-block">
<input type="radio" name="message_send_mail" value="1" {if([$configs.message_send_mail.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="message_send_mail" value="0" {if([$configs.message_send_mail.value]==0)} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">表单发送邮件</label>
<div class="layui-input-block">
<input type="radio" name="form_send_mail" value="1" {if([$configs.form_send_mail.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="form_send_mail" value="0" {if([$configs.form_send_mail.value]==0)} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">评论发送邮件</label>
<div class="layui-input-block">
<input type="radio" name="comment_send_mail" value="1" {if([$configs.comment_send_mail.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="comment_send_mail" value="0" {if([$configs.comment_send_mail.value]==0)} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">信息接收邮箱</label>
<div class="layui-input-inline">
<input type="text" name="message_send_to" value="{$configs.message_send_to.value}" placeholder="请输入信息接收邮箱" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit name="submit" value="email">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
<a href="{url./admin/Config/index/action/sendemail}" onclick="return sendtest(this,'#smtp_username_test')" class="layui-btn layui-btn-primary">发送测试邮件</a>
</div>
</div>
<script>
function sendtest(obj,to){
$(obj).attr('href',$(obj).attr('href')+'&to='+$(to).val());
return true;
}
</script>
</form>
</div>
<div class="layui-tab-item">
<form action="{url./admin/Config/index}" method="post" class="layui-form">
<input type="hidden" name="formcheck" value="{$formcheck}" >
<div class="layui-form-item">
<label class="layui-form-label">普通收录token</label>
<div class="layui-input-inline">
<input type="text" name="baidu_zz_token" value="{$configs.baidu_zz_token.value}" placeholder="请输入普通收录token" class="layui-input">
</div>
<span class="layui-icon layui-icon-about tips" data-content="请到百度站长中心获取!"></span>
</div>
<div class="layui-form-item">
<label class="layui-form-label">快速收录token</label>
<div class="layui-input-inline">
<input type="text" name="baidu_ks_token" value="{$configs.baidu_ks_token.value}" placeholder="请输入快速收录token" class="layui-input">
</div>
<span class="layui-icon layui-icon-about tips" data-content="请到百度站长中心获取!"></span>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit name="submit" value="baidu">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
<div class="layui-tab-item">
<form action="{url./admin/Config/index}" method="post" class="layui-form">
<input type="hidden" name="formcheck" value="{$formcheck}" >
<div class="layui-form-item">
<label class="layui-form-label">API状态</label>
<div class="layui-input-block">
<input type="radio" name="api_open" value="1" {if(@[$configs.api_open.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="api_open" value="0" {if(@[$configs.api_open.value]==0)} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">API强制认证</label>
<div class="layui-input-block">
<input type="radio" name="api_auth" value="1" {if(@[$configs.api_auth.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="api_auth" value="0" {if(@[$configs.api_auth.value]==0)} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">API认证用户</label>
<div class="layui-input-inline">
<input type="text" name="api_appid" value="{$configs.api_appid.value}" placeholder="请输入API认证用户名" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">API认证密钥</label>
<div class="layui-input-inline">
<input type="password" name="api_secret" value="{$configs.api_secret.value}" placeholder="请输入API认证密钥" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit name="submit" value="api">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
<div class="layui-tab-item">
<form action="{url./admin/Config/index}" method="post" class="layui-form">
<input type="hidden" name="formcheck" value="{$formcheck}" >
<div class="layui-form-item">
<label class="layui-form-label">状态</label>
<div class="layui-input-block">
<input type="radio" name="watermark_open" value="1" {if(@[$configs.watermark_open.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="watermark_open" value="0" {if(@[$configs.watermark_open.value]==0)} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">水印文字</label>
<div class="layui-input-inline">
<input type="text" name="watermark_text" value="{$configs.watermark_text.value}" placeholder="请输入水印文字PbootCMS" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">文字字体</label>
<div class="layui-input-inline">
<input type="text" name="watermark_text_font" id="watermark_text_font" value="{$configs.watermark_text_font.value}" placeholder="请上传水印文字字体" class="layui-input">
</div>
<button type="button" class="layui-btn file" data-des="watermark_text_font">
<i class="layui-icon">&#xe67c;</i>上传字体
</button>
</div>
<div class="layui-form-item">
<label class="layui-form-label">文字大小</label>
<div class="layui-input-inline">
<input type="text" name="watermark_text_size" value="{$configs.watermark_text_size.value}" placeholder="请输入水印文字大小20" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">文字颜色</label>
<div class="layui-input-inline">
<input type="text" name="watermark_text_color" value="{$configs.watermark_text_color.value}" placeholder="请输入水印文字颜色100,100,100" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">水印图片</label>
<div class="layui-input-inline">
<input type="text" name="watermark_pic" id="watermark_pic" value="{$configs.watermark_pic.value}" placeholder="请上传水印图片,优先文字水印" class="layui-input">
</div>
<button type="button" class="layui-btn upload" data-des="watermark_pic">
<i class="layui-icon">&#xe67c;</i>上传图片
</button>
<div id="watermark_pic_box" class="pic"><dl><dt>{if(@[$configs.watermark_pic.value])}<img src="{SITE_DIR}{$configs.watermark_pic.value}" data-url="{$configs.watermark_pic.value}"></dt><dd>删除</dd></dl>{/if}</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">水印位置</label>
<div class="layui-input-block">
<input type="radio" name="watermark_position" value="1" {if(@[$configs.watermark_position.value]==1)} checked="checked" {/if} title="左上">
<input type="radio" name="watermark_position" value="2" {if(@[$configs.watermark_position.value]==2)} checked="checked" {/if} title="右上">
<input type="radio" name="watermark_position" value="3" {if(@[$configs.watermark_position.value]==3)} checked="checked" {/if} title="左下">
<input type="radio" name="watermark_position" value="4" {if(@[$configs.watermark_position.value]==4)} checked="checked" {/if} title="右下">
<input type="radio" name="watermark_position" value="5" {if(@[$configs.watermark_position.value]==5)} checked="checked" {/if} title="中间">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit name="submit" value="watermark">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
<div class="layui-tab-item">
<form action="{url./admin/Config/index}" method="post" class="layui-form">
<input type="hidden" name="formcheck" value="{$formcheck}" >
<div class="layui-form-item">
<label class="layui-form-label">留言功能</label>
<div class="layui-input-block">
<input type="radio" name="message_status" value="1" {if([$configs.message_status.value]=='1'||[$configs.message_status.value]=='')} checked="checked" {/if} title="启用">
<input type="radio" name="message_status" value="0" {if([$configs.message_status.value]=='0')} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">留言验证码</label>
<div class="layui-input-block">
<input type="radio" name="message_check_code" value="1" {if([$configs.message_check_code.value]=='1'||[$configs.message_check_code.value]=='')} checked="checked" {/if} title="启用">
<input type="radio" name="message_check_code" value="0" {if([$configs.message_check_code.value]=='0')} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">留言审核</label>
<div class="layui-input-block">
<input type="radio" name="message_verify" value="1" {if([$configs.message_verify.value]=='1'||[$configs.message_verify.value]=='')} checked="checked" {/if} title="启用">
<input type="radio" name="message_verify" value="0" {if([$configs.message_verify.value]=='0')} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">留言需登录</label>
<div class="layui-input-block">
<input type="radio" name="message_rqlogin" value="1" {if([$configs.message_rqlogin.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="message_rqlogin" value="0" {if([$configs.message_rqlogin.value]==0)} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">表单功能</label>
<div class="layui-input-block">
<input type="radio" name="form_status" value="1" {if([$configs.form_status.value]=='1'||[$configs.form_status.value]=='')} checked="checked" {/if} title="启用">
<input type="radio" name="form_status" value="0" {if([$configs.form_status.value]=='0')} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">表单验证码</label>
<div class="layui-input-block">
<input type="radio" name="form_check_code" value="1" {if([$configs.form_check_code.value]=='1'||[$configs.form_check_code.value]=='')} checked="checked" {/if} title="启用">
<input type="radio" name="form_check_code" value="0" {if([$configs.form_check_code.value]=='0')} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">模板子目录</label>
<div class="layui-input-inline">
<input type="text" name="tpl_html_dir" value="{$configs.tpl_html_dir.value}" placeholder="首次请手动移动模板文件到填写的目录!" class="layui-input">
</div>
<span class="layui-icon layui-icon-about tips" data-content="一定程度上防盗,如填 html则默认模板情况下路径为 default/html 目录!"></span>
</div>
<div class="layui-form-item">
<label class="layui-form-label">IP黑名单</label>
<div class="layui-input-inline">
<textarea name="ip_deny" placeholder="请输入需要禁止访问的IP多个之间逗号隔开IP地址支持使用/掩码位数模式192.168.1.0/24, 192.168.2.100" class="layui-textarea">{$configs.ip_deny.value}</textarea>
</div>
<span class="layui-icon layui-icon-about tips" data-content="请输入需要禁止访问的IP多个之间逗号隔开IP地址支持使用/掩码位数模式192.168.1.0/24, 192.168.2.100"></span>
</div>
<div class="layui-form-item">
<label class="layui-form-label">IP白名单</label>
<div class="layui-input-inline">
<textarea name="ip_allow" placeholder="请输入需要允许访问的IP多个之间逗号隔开IP地址支持使用/掩码位数模式192.168.1.0/24, 192.168.2.100" class="layui-textarea">{$configs.ip_allow.value}</textarea>
</div>
<span class="layui-icon layui-icon-about tips" data-content="请输入需要允许访问的IP多个之间逗号隔开IP地址支持使用/掩码位数模式192.168.1.0/24,192.168.2.100"></span>
</div>
<hr>
<div class="layui-form-item">
<label class="layui-form-label">后台验证码</label>
<div class="layui-input-block">
<input type="radio" name="admin_check_code" value="1" {if([$configs.admin_check_code.value]=='1'||[$configs.admin_check_code.value]=='')} checked="checked" {/if} title="启用">
<input type="radio" name="admin_check_code" value="0" {if([$configs.admin_check_code.value]=='0')} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">后台登录阀值</label>
<div class="layui-input-inline">
<input type="text" name="lock_count" value="{$configs.lock_count.value}" placeholder="请输入后台登录失败几次后锁定IP默认5次" class="layui-input">
</div>
<div class="layui-form-mid layui-word-aux"></div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">失败锁定时间</label>
<div class="layui-input-inline">
<input type="text" name="lock_time" value="{$configs.lock_time.value}" placeholder="请输入后台登录异常锁定时间默认为900秒" class="layui-input">
</div>
<div class="layui-form-mid layui-word-aux"></div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit name="submit" value="security">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
<div class="layui-tab-item">
<form action="{url./admin/Config/index}" method="post" class="layui-form">
<input type="hidden" name="formcheck" value="{$formcheck}" >
<div class="layui-form-item">
<label class="layui-form-label">地址模式</label>
<div class="layui-input-block">
<P>
<input type="radio" name="url_rule_type" value="1" {if([$configs.url_rule_type.value]==1)} checked="checked" {/if} title="普通模式,类似:/index.php/product/1.html">
<span class="layui-icon layui-icon-about tips" data-content="基本模式需要服务器支持pathinfo,特别是nginx下pathinfo要手动配置"></span>
</P>
<P>
<input type="radio" name="url_rule_type" value="2" {if([$configs.url_rule_type.value]==2)} checked="checked" {/if} title="伪静态模式,类似:/product/1.html">
<span class="layui-icon layui-icon-about tips" data-content="伪静态时需要服务器环境的支持,并需要添加伪静态规则!"></span>
</P>
<P>
<input type="radio" name="url_rule_type" value="3" {if([$configs.url_rule_type.value]==3||![$configs.url_rule_type.value])} checked="checked" {/if} title="兼容模式,类似:/?product/1.html">
</P>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">栏目显示后缀</label>
<div class="layui-input-block">
<input type="radio" name="url_rule_sort_suffix" value="1" {if([$configs.url_rule_sort_suffix.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="url_rule_sort_suffix" value="0" {if([$configs.url_rule_sort_suffix.value]==0)} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit name="submit" value="urlrule">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
<div class="layui-tab-item">
<form action="{url./admin/Config/index}" method="post" class="layui-form">
<input type="hidden" name="formcheck" value="{$formcheck}" >
<div class="layui-form-item">
<label class="layui-form-label">常用组合标签: </label>
<div class="layui-input-block" style="line-height:36px;">
<p>全局标签:{pboot:sitetitle}站点标题、{pboot:sitesubtitle}站点副标题</p>
<p>列表或内容页:{sort:name}栏目名称、{sort:title}栏目标题</p>
<p>内容页:{content:title}内容标题</p>
<p>搜索结果页:{pboot:keyword}搜索关键字</p>
<p>个人中心:{user:nickname}会员昵称</p>
<p>例如定义内容页样式:{content:title}-{sort:name}-{pboot:sitetitle}-{pboot:sitesubtitle}</p>
<p>以下配置参数不设置时将使用系统默认规则。</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">首页</label>
<div class="layui-input-block">
<input type="text" name="index_title" value="{$configs.index_title.value}" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">专题页</label>
<div class="layui-input-block">
<input type="text" name="about_title" value="{$configs.about_title.value}" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">列表页</label>
<div class="layui-input-block">
<input type="text" name="list_title" value="{$configs.list_title.value}" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">内容页</label>
<div class="layui-input-block">
<input type="text" name="content_title" value="{$configs.content_title.value}" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">搜索结果页</label>
<div class="layui-input-block">
<input type="text" name="search_title" value="{$configs.search_title.value}" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">会员注册页</label>
<div class="layui-input-block">
<input type="text" name="register_title" value="{$configs.register_title.value}" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">会员登录页</label>
<div class="layui-input-block">
<input type="text" name="login_title" value="{$configs.login_title.value}" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">个人中心页</label>
<div class="layui-input-block">
<input type="text" name="ucenter_title" value="{$configs.ucenter_title.value}" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">资料修改页</label>
<div class="layui-input-block">
<input type="text" name="umodify_title" value="{$configs.umodify_title.value}" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">其它页</label>
<div class="layui-input-block">
<input type="text" name="other_title" value="{$configs.other_title.value}" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit name="submit" value="pagetitle">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
<div class="layui-tab-item">
<form action="{url./admin/Config/index}" method="post" class="layui-form">
<input type="hidden" name="formcheck" value="{$formcheck}" >
<div class="layui-form-item">
<label class="layui-form-label">会员注册</label>
<div class="layui-input-block">
<input type="radio" name="register_status" value="1" {if([$configs.register_status.value]=='1'||[$configs.register_status.value]=='')} checked="checked" {/if} title="启用">
<input type="radio" name="register_status" value="0" {if([$configs.register_status.value]=='0')} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">会员注册类型</label>
<div class="layui-input-block">
<input type="radio" name="register_type" value="1" {if([$configs.register_type.value]=='1'||[$configs.register_type.value]=='')} checked="checked" {/if} title="用户名">
<input type="radio" name="register_type" value="2" {if([$configs.register_type.value]=='2')} checked="checked" {/if} title="邮箱账号">
<input type="radio" name="register_type" value="3" {if([$configs.register_type.value]=='3')} checked="checked" {/if} title="手机号码">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">会员注册验证码</label>
<div class="layui-input-block">
<input type="radio" name="register_check_code" value="0" {if([$configs.register_check_code.value]=='0')} checked="checked" {/if} title="禁用">
<input type="radio" name="register_check_code" value="1" {if([$configs.register_check_code.value]=='1'||[$configs.register_check_code.value]=='')} checked="checked" {/if} title="普通验证码">
<input type="radio" name="register_check_code" value="2" {if([$configs.register_check_code.value]=='2')} checked="checked" {/if} title="邮箱验证码">
<!-- <input type="radio" name="register_check_code" value="3" {if([$configs.register_check_code.value]=='3')} checked="checked" {/if} title="短信验证码"> -->
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">会员注册审核</label>
<div class="layui-input-block">
<input type="radio" name="register_verify" value="1" {if([$configs.register_verify.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="register_verify" value="0" {if([$configs.register_verify.value]==0)} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">会员登录</label>
<div class="layui-input-block">
<input type="radio" name="login_status" value="1" {if([$configs.login_status.value]=='1'||[$configs.login_status.value]=='')} checked="checked" {/if} title="启用">
<input type="radio" name="login_status" value="0" {if([$configs.login_status.value]=='0')} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">会员登录验证码</label>
<div class="layui-input-block">
<input type="radio" name="login_check_code" value="1" {if([$configs.login_check_code.value]=='1'||[$configs.login_check_code.value]=='')} checked="checked" {/if} title="启用">
<input type="radio" name="login_check_code" value="0" {if([$configs.login_check_code.value]=='0')} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">不等待跳登录</label>
<div class="layui-input-block">
<input type="radio" name="login_no_wait" value="1" {if([$configs.login_no_wait.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="login_no_wait" value="0" {if([$configs.login_no_wait.value]==0)} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">评论功能</label>
<div class="layui-input-block">
<input type="radio" name="comment_status" value="1" {if([$configs.comment_status.value]=='1'||[$configs.comment_status.value]=='')} checked="checked" {/if} title="启用">
<input type="radio" name="comment_status" value="0" {if([$configs.comment_status.value]=='0')} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">匿名评论</label>
<div class="layui-input-block">
<input type="radio" name="comment_anonymous" value="1" {if([$configs.comment_anonymous.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="comment_anonymous" value="0" {if([$configs.comment_anonymous.value]==0)} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">评论验证码</label>
<div class="layui-input-block">
<input type="radio" name="comment_check_code" value="1" {if([$configs.comment_check_code.value]=='1'||[$configs.comment_check_code.value]=='')} checked="checked" {/if} title="启用">
<input type="radio" name="comment_check_code" value="0" {if([$configs.comment_check_code.value]=='0')} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">评论审核</label>
<div class="layui-input-block">
<input type="radio" name="comment_verify" value="1" {if([$configs.comment_verify.value]=='1'||[$configs.comment_verify.value]=='')} checked="checked" {/if} title="启用">
<input type="radio" name="comment_verify" value="0" {if([$configs.comment_verify.value]=='0')} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">会员注册积分</label>
<div class="layui-input-inline">
<input type="text" name="register_score" value="{$configs.register_score.value}" placeholder="请输入会员注册初始积分" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">会员登录积分</label>
<div class="layui-input-inline">
<input type="text" name="login_score" value="{$configs.login_score.value}" placeholder="请输入会员每次登录积分" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">会员默认等级</label>
<div class="layui-input-inline">
<select name="register_gcode">
<option value="">请选择</option>
{foreach $groups(key,value)}
<option value="[value->gcode]" {if([$configs.register_gcode.value]==$value->gcode)}selected{/if}>[value->gname]</option>
{/foreach}
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">允许上传格式</label>
<div class="layui-input-inline">
<input type="text" name="home_upload_ext" value="{$configs.home_upload_ext.value}" placeholder="以英文逗号隔开!" class="layui-input">
</div>
<span class="layui-icon layui-icon-about tips" data-content="以英文逗号隔开默认jpg, jpeg, png, gif, xls, xlsx, doc, docx, ppt, pptx, rar, zip, pdf, txt"></span>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit name="submit" value="member">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
{include file='common/foot.html'}

View File

@@ -0,0 +1,12 @@
<?php
return array(
// 应用版本
'app_version' => '3.0.7',
// 发布时间
'release_time' => '20211009',
// 修订版本
'revise_version' => '2'
);

View File

@@ -0,0 +1,306 @@
<?php
/**
* @copyright (C)2016-2099 Hnaoyun Inc.
* @author XingMeng
* @email hnxsh@foxmail.com
* @date 2018年2月14日
* 首页控制器
*/
namespace app\home\controller;
use core\basic\Controller;
use app\home\model\ParserModel;
use core\basic\Config;
use core\basic\Url;
class IndexController extends Controller
{
protected $parser;
protected $model;
protected $htmldir;
public function __construct()
{
$this->parser = new ParserController();
$this->model = new ParserModel();
$this->htmldir = $this->config('tpl_html_dir') ? $this->config('tpl_html_dir') . '/' : '';
}
// 空拦截器, 实现文章路由转发
public function _empty()
{
// 地址类型
$url_rule_type = $this->config('url_rule_type') ?: 3;
if (P) { // 采用pathinfo模式及p参数伪静态模式
if ($url_rule_type == 2 && stripos(URL, $_SERVER['SCRIPT_NAME']) !== false) { // 禁止伪静态时带index.php访问
_404('您访问的内容不存在,请核对后重试!');
}
$path = explode('/', P);
if (! defined('URL_BIND')) {
array_shift($path); // 去除模块部分
}
} elseif ($url_rule_type == 3 && isset($_SERVER["QUERY_STRING"]) && $qs = $_SERVER["QUERY_STRING"]) { // 采用简短传参模式
parse_str($qs, $output);
unset($output['page']); // 去除分页
if ($output && ! current($output)) { // 第一个路径参数不能有值,否则非标准路径参数
$path = key($output); // 第一个参数为路径信息注意PHP数组会自动将key点符号转换下划线
$path = trim($path, '/'); // 去除两端斜杠
$url_rule_suffix = substr($this->config('url_rule_suffix'), 1);
if (preg_match('/_' . $url_rule_suffix . '$/', $path) && (! ! $pos = strripos($path, '_' . $url_rule_suffix))) {
$path = substr($path, 0, $pos); // 去扩展
}
$path = explode('/', $path);
} elseif (get('tag')) { // 对于兼容模式tag需要自动跳转tag独立页面
$tag = new TagController();
$tag->index();
} elseif (get('keyword')) { // 兼容模式搜索处理
$search = new SearchController();
$search->index();
}
}
if (isset($path) && is_array($path)) {
switch ($path[0]) {
case 'search':
case 'keyword':
$search = new SearchController();
$search->index();
break;
case 'message':
$msg = new MessageController();
$msg->index();
break;
case 'form':
$_GET['fcode'] = $path[1];
$form = new FormController();
$form->index();
break;
case 'sitemap':
case 'Sitemap':
$sitemap = new SitemapController();
$sitemap->index();
break;
case 'tag':
$tag = new TagController();
$tag->index();
break;
case 'member':
$member = new MemberController();
$member->{$path[1]}();
break;
case 'comment':
$comment = new CommentController();
$comment->{$path[1]}();
break;
default:
if (get($path[0])) {
$this->getIndex();
} else {
// 优先判断全路径
$fullurl = implode('/', $path);
// 详情页匹配前段栏目路径
$sorturl = $path;
$contenturl = array_pop($sorturl);
$sorturl = implode('/', $sorturl);
$url_break_char = $this->config('url_break_char') ?: '_';
// 开始进行匹配
if (! ! $fullurl && ! ! $sort = $this->model->getSort($fullurl)) { // 栏目名称
$iscontent = false;
} elseif (! ! $sorturl && ! ! $sorts = $this->model->getSort($sorturl)) { // 栏目名称/内容名称或ID
$data = $this->model->getContent($contenturl);
$iscontent = true;
} elseif (preg_match('/^list_[0-9]+|about_[0-9]+$/', $sorturl)) { // 模型默认名称_栏目ID/内容名称或ID
$data = $this->model->getContent($contenturl);
$iscontent = true;
} else {
preg_match('/^([a-zA-Z0-9\-\/]+)(' . $url_break_char . '([0-9]+))?' . $url_break_char . '([0-9]+)$/i', $fullurl, $matchs);
if ($matchs[2] && $model = $this->model->checkModelUrlname($matchs[1])) { // 模型名称_栏目ID_分页
define('CMS_PAGE_CUSTOM', false);
$scode = $matchs[3]; // 分类
$sort = $this->model->getSort($scode);
$_GET['page'] = $matchs[4]; // 分页
} elseif ((! ! $model = $this->model->checkModelUrlname($matchs[1])) && ! ! $sort = $this->model->getSort($matchs[4])) { // 模型名称_栏目ID
$scode = $matchs[4]; // 分类
} elseif (! ! $sort = $this->model->getSort($matchs[1])) { // 栏目名称_分页
define('CMS_PAGE_CUSTOM', true);
$scode = $matchs[1]; // 分类
$_GET['page'] = $matchs[4]; // 分页
}
}
if ($iscontent) {
define('CMS_PAGE', false); // 使用普通分页处理模型
if (! ! $data) {
if ($data->acode != get_lg() && Config::get('lgautosw') !== '0') {
cookie('lg', $data->acode); // 调用内容语言与当前语言不一致时,自动切换语言
}
$this->getContent($data);
} else {
_404('您访问的内容不存在,请核对后重试!');
}
} else {
define('CMS_PAGE', true); // 使用cms分页处理模型
if (! ! $sort) {
if ($sort->acode != get_lg() && Config::get('lgautosw') !== '0') {
cookie('lg', $sort->acode); // 调用栏目语言与当前语言不一致时,自动切换语言
}
if ($sort->type == 1) {
$this->getAbout($sort);
} else {
$this->getList($sort);
}
} else {
_404('您访问的页面不存在,请核对后重试!');
}
}
}
}
} else {
$this->getIndex();
}
}
// 首页
private function getIndex()
{
$content = parent::parser($this->htmldir . 'index.html'); // 框架标签解析
$content = $this->parser->parserBefore($content); // CMS公共标签前置解析
$content = str_replace('{pboot:pagetitle}', $this->config('index_title') ?: '{pboot:sitetitle}-{pboot:sitesubtitle}', $content);
$content = $this->parser->parserPositionLabel($content, - 1, '首页', SITE_INDEX_DIR . '/'); // CMS当前位置标签解析
$content = $this->parser->parserSpecialPageSortLabel($content, 0, '', SITE_INDEX_DIR . '/'); // 解析分类标签
$content = $this->parser->parserAfter($content); // CMS公共标签后置解析
$this->cache($content, true);
}
// 列表
private function getList($sort)
{
if ($sort->listtpl) {
$this->checkPageLevel($sort->gcode, $sort->gtype, $sort->gnote);
$content = parent::parser($this->htmldir . $sort->listtpl); // 框架标签解析
$content = $this->parser->parserBefore($content); // CMS公共标签前置解析
$pagetitle = $sort->title ? "{sort:title}" : "{sort:name}"; // 页面标题
$content = str_replace('{pboot:pagetitle}', $this->config('list_title') ?: ($pagetitle . '-{pboot:sitetitle}-{pboot:sitesubtitle}'), $content);
$content = str_replace('{pboot:pagekeywords}', '{sort:keywords}', $content);
$content = str_replace('{pboot:pagedescription}', '{sort:description}', $content);
$content = $this->parser->parserPositionLabel($content, $sort->scode); // CMS当前位置标签解析
$content = $this->parser->parserSortLabel($content, $sort); // CMS分类信息标签解析
$content = $this->parser->parserListLabel($content, $sort->scode); // CMS分类列表标签解析
$content = $this->parser->parserAfter($content); // CMS公共标签后置解析
} else {
error('请到后台设置分类栏目列表页模板!');
}
$this->cache($content, true);
}
// 详情页
private function getContent($data)
{
// 读取模板
if (! ! $sort = $this->model->getSort($data->scode)) {
if ($sort->contenttpl) {
$this->checkPageLevel($sort->gcode, $sort->gtype, $sort->gnote); // 检查栏目权限
$this->checkPageLevel($data->gcode, $data->gtype, $data->gnote); // 检查内容权限
$content = parent::parser($this->htmldir . $sort->contenttpl); // 框架标签解析
$content = $this->parser->parserBefore($content); // CMS公共标签前置解析
$content = str_replace('{pboot:pagetitle}', $this->config('content_title') ?: '{content:title}-{sort:name}-{pboot:sitetitle}-{pboot:sitesubtitle}', $content);
$content = str_replace('{pboot:pagekeywords}', '{content:keywords}', $content);
$content = str_replace('{pboot:pagedescription}', '{content:description}', $content);
$content = $this->parser->parserPositionLabel($content, $sort->scode); // CMS当前位置标签解析
$content = $this->parser->parserSortLabel($content, $sort); // CMS分类信息标签解析
$content = $this->parser->parserCurrentContentLabel($content, $sort, $data); // CMS内容标签解析
$content = $this->parser->parserCommentLabel($content); // 文章评论
$content = $this->parser->parserAfter($content); // CMS公共标签后置解析
} else {
error('请到后台设置分类栏目内容页模板!');
}
} else {
_404('您访问内容的分类已经不存在,请核对后再试!');
}
$this->cache($content, true);
}
// 单页
private function getAbout($sort)
{
// 读取数据
if (! $data = $this->model->getAbout($sort->scode)) {
_404('您访问的内容不存在,请核对后重试!');
}
if ($sort->contenttpl) {
$this->checkPageLevel($sort->gcode, $sort->gtype, $sort->gnote);
$content = parent::parser($this->htmldir . $sort->contenttpl); // 框架标签解析
$content = $this->parser->parserBefore($content); // CMS公共标签前置解析
$pagetitle = $sort->title ? "{sort:title}" : "{content:title}"; // 页面标题
$content = str_replace('{pboot:pagetitle}', $this->config('about_title') ?: ($pagetitle . '-{pboot:sitetitle}-{pboot:sitesubtitle}'), $content);
$content = str_replace('{pboot:pagekeywords}', '{content:keywords}', $content);
$content = str_replace('{pboot:pagedescription}', '{content:description}', $content);
$content = $this->parser->parserPositionLabel($content, $sort->scode); // CMS当前位置标签解析
$content = $this->parser->parserSortLabel($content, $sort); // CMS分类信息标签解析
$content = $this->parser->parserCurrentContentLabel($content, $sort, $data); // CMS内容标签解析
$content = $this->parser->parserCommentLabel($content); // 文章评论
$content = $this->parser->parserAfter($content); // CMS公共标签后置解析
} else {
error('请到后台设置分类栏目内容页模板!');
}
$this->cache($content, true);
}
// 检查页面权限
private function checkPageLevel($gcode, $gtype, $gnote)
{
if ($gcode) {
$deny = false;
$gtype = $gtype ?: 4;
switch ($gtype) {
case 1:
if ($gcode <= session('pboot_gcode')) {
$deny = true;
}
break;
case 2:
if ($gcode < session('pboot_gcode')) {
$deny = true;
}
break;
case 3:
if ($gcode != session('pboot_gcode')) {
$deny = true;
}
break;
case 4:
if ($gcode > session('pboot_gcode')) {
$deny = true;
}
break;
case 5:
if ($gcode >= session('pboot_gcode')) {
$deny = true;
}
break;
}
if ($deny) {
$gnote = $gnote ?: '您的权限不足,无法浏览本页面!';
if (session('pboot_uid')) { // 已经登录
error($gnote);
} else {
if ($this->config('login_no_wait')) {
location(Url::home('member/login', null, "backurl=" . urlencode(get_current_url())));
} else {
error($gnote, Url::home('member/login', null, "backurl=" . urlencode(get_current_url())));
}
}
}
}
}
}

View File

@@ -0,0 +1,551 @@
<?php
/**
* @copyright (C)2016-2099 Hnaoyun Inc.
* @author XingMeng
* @email hnxsh@foxmail.com
* @date 2017年12月15日
* 文章控制器
*/
namespace app\admin\controller\content;
use core\basic\Controller;
use app\admin\model\content\ContentModel;
class ContentController extends Controller
{
private $model;
private $blank;
public function __construct()
{
$this->model = new ContentModel();
}
// 文章列表
public function index()
{
if ((! ! $id = get('id', 'int')) && $result = $this->model->getContent($id)) {
$this->assign('more', true);
$this->assign('content', $result);
} else {
$this->assign('list', true);
if (! $mcode = get('mcode', 'var')) {
error('传递的模型编码参数有误,请核对后重试!');
}
if (isset($_GET['keyword'])) {
if (! ! $scode = get('scode', 'var')) {
$result = $this->model->findContent($mcode, $scode, get('keyword', 'vars'));
} else {
$result = $this->model->findContentAll($mcode, get('keyword', 'vars'));
}
} else {
$result = $this->model->getList($mcode);
}
$this->assign('contents', $result);
// 文章分类下拉列表
$sort_model = model('admin.content.ContentSort');
$sort_select = $sort_model->getListSelect($mcode);
$this->assign('search_select', $this->makeSortSelect($sort_select, get('scode')));
$this->assign('sort_select', $this->makeSortSelect($sort_select, session('addscode')));
$this->assign('subsort_select', $this->makeSortSelect($sort_select));
// 模型名称
$this->assign('model_name', model('admin.content.Model')->getName($mcode));
// 扩展字段
$this->assign('extfield', model('admin.content.ExtField')->getModelField($mcode));
$this->assign('baidu_zz_token', $this->config('baidu_zz_token'));
$this->assign('baidu_ks_token', $this->config('baidu_ks_token'));
// 前端地址连接符判断
$url_break_char = $this->config('url_break_char') ?: '_';
$this->assign('url_break_char', $url_break_char);
// 获取会员分组
$this->assign('groups', model('admin.member.MemberGroup')->getSelect());
}
$this->display('content/content.html');
}
// 文章增加
public function add()
{
if ($_POST) {
// 获取数据
$scode = post('scode');
$subscode = post('subscode');
$title = post('title');
$titlecolor = post('titlecolor');
$subtitle = post('subtitle');
$filename = post('filename');
$author = post('author');
$source = post('source');
$outlink = post('outlink');
$date = post('date');
$ico = post('ico');
$pics = post('pics');
// 获取多图标题
$picstitle = post('picstitle');
if ($picstitle) {
$picstitle = implode(',', $picstitle);
}
$content = post('content');
$tags = str_replace('', ',', post('tags'));
$enclosure = post('enclosure');
$keywords = post('keywords');
$description = post('description');
$status = post('status', 'int');
$istop = post('istop', 'int', '', '', 0);
$isrecommend = post('isrecommend', 'int', '', '', 0);
$isheadline = post('isheadline', 'int', '', '', 0);
$gid = post('gid', 'int') ?: 0;
$gtype = post('gtype', 'int') ?: 4;
$gnote = post('gnote');
if (! $scode) {
alert_back('内容分类不能为空!');
}
if (! $title) {
alert_back('文章标题不能为空!');
}
if ($filename && ! preg_match('/^[a-zA-Z0-9\-]+$/', $filename)) {
alert_back('内容URL名称只允许字母、数字、横线组成!');
}
// 自动提起前一百个字符为描述
if (! $description && isset($_POST['content'])) {
$description = escape_string(clear_html_blank(substr_both(strip_tags($_POST['content']), 0, 150)));
}
// 缩放缩略图
if ($ico) {
resize_img(ROOT_PATH . $ico, '', $this->config('ico.max_width'), $this->config('ico.max_height'));
}
// 检查自定义URL名称
if ($filename) {
while ($this->model->checkFilename($filename)) {
$filename = $filename . '-' . mt_rand(1, 20);
}
}
// 记住新增栏目
session('addscode', $scode);
// 构建数据
$data = array(
'acode' => session('acode'),
'scode' => $scode,
'subscode' => $subscode,
'title' => $title,
'titlecolor' => $titlecolor,
'subtitle' => $subtitle,
'filename' => $filename,
'author' => $author,
'source' => $source,
'outlink' => $outlink,
'date' => $date,
'ico' => $ico,
'pics' => $pics,
'picstitle' => $picstitle,
'content' => $content,
'tags' => $tags,
'enclosure' => $enclosure,
'keywords' => $keywords,
'description' => clear_html_blank($description),
'sorting' => 255,
'status' => $status,
'istop' => $istop,
'isrecommend' => $isrecommend,
'isheadline' => $isheadline,
'gid' => $gid,
'gtype' => $gtype,
'gnote' => $gnote,
'visits' => 0,
'likes' => 0,
'oppose' => 0,
'create_user' => session('username'),
'update_user' => session('username')
);
// 执行添加
if (! ! $id = $this->model->addContent($data)) {
// 扩展内容添加
foreach ($_POST as $key => $value) {
if (preg_match('/^ext_[\w\-]+$/', $key)) {
if (! isset($data2['contentid'])) {
$data2['contentid'] = $id;
}
$temp = post($key);
if (is_array($temp)) {
$data2[$key] = implode(',', $temp);
} else {
$data2[$key] = str_replace("\r\n", '<br>', $temp);
}
}
}
if (isset($data2)) {
if (! $this->model->addContentExt($data2)) {
$this->model->delContent($id);
$this->log('新增文章失败!');
error('新增失败!', - 1);
}
}
$this->log('新增文章成功!');
if (! ! $backurl = get('backurl')) {
success('新增成功!', base64_decode($backurl));
} else {
success('新增成功!', url('/admin/Content/index/mcode/' . get('mcode')));
}
} else {
$this->log('新增文章失败!');
error('新增失败!', - 1);
}
}
}
// 生成分类选择
private function makeSortSelect($tree, $selectid = null)
{
$list_html = '';
foreach ($tree as $value) {
// 默认选择项
if ($selectid == $value->scode) {
$select = "selected='selected'";
} else {
$select = '';
}
$list_html .= "<option value='{$value->scode}' $select>{$this->blank}{$value->name}";
// 子菜单处理
if ($value->son) {
$this->blank .= '  ';
$list_html .= $this->makeSortSelect($value->son, $selectid);
}
}
// 循环完后回归位置
$this->blank = substr($this->blank, 0, - 6);
return $list_html;
}
// 文章删除
public function del()
{
// 执行批量删除
if ($_POST) {
if (! ! $list = post('list')) {
if ($this->model->delContentList($list)) {
$this->model->delContentExtList($list);
$this->log('批量删除文章成功!');
success('批量删除成功!', - 1);
} else {
$this->log('批量删除文章失败!');
error('批量删除失败!', - 1);
}
} else {
alert_back('请选择要删除的内容!');
}
}
if (! $id = get('id', 'int')) {
error('传递的参数值错误!', - 1);
}
if ($this->model->delContent($id)) {
$this->model->delContentExt($id);
$this->log('删除文章' . $id . '成功!');
success('删除成功!', - 1);
} else {
$this->log('删除文章' . $id . '失败!');
error('删除失败!', - 1);
}
}
// 文章修改
public function mod()
{
if (! ! $submit = post('submit')) {
switch ($submit) {
case 'sorting': // 修改列表排序
$listall = post('listall');
if ($listall) {
$sorting = post('sorting');
foreach ($listall as $key => $value) {
if ($sorting[$key] === '' || ! is_numeric($sorting[$key]))
$sorting[$key] = 255;
$this->model->modContent($value, "sorting=" . $sorting[$key]);
}
$this->log('修改内容排序成功!');
success('修改成功!', - 1);
} else {
alert_back('排序失败,无任何内容!');
}
break;
case 'copy':
$list = post('list');
$scode = post('scode');
if (! $list) {
alert_back('请选择要复制的内容!');
}
if (! $scode) {
alert_back('请选择目标栏目!');
}
if ($this->model->copyContent($list, $scode)) {
$this->log('复制内容成功!');
success('复制内容成功!', - 1);
} else {
alert_back('复制内容失败!');
}
break;
case 'move':
$list = post('list');
$scode = post('scode');
if (! $list) {
alert_back('请选择要移动的内容!');
}
if (! $scode) {
alert_back('请选择目标栏目!');
}
if ($this->model->modContent($list, "scode='" . $scode . "'")) {
$this->log('移动内容成功!');
success('移动内容成功!', - 1);
} else {
alert_back('移动内容失败!');
}
break;
case 'baiduzz':
$list = post('list');
$urls = post('urls');
if (! $list) {
alert_back('请选择要推送的内容!');
}
// 依次推送
$domain = get_http_url();
if (! $token = $this->config('baidu_zz_token')) {
alert_back('请先到系统配置中填写百度普通收录推送token值');
}
$api = "http://data.zz.baidu.com/urls?site=$domain&token=$token";
foreach ($list as $key => $value) {
$url = $domain . $urls[$value];
$this->log('百度普通收录推送:' . $url);
$post_urls[] = $url;
}
$result = post_baidu($api, $post_urls);
if (isset($result->error)) {
alert_back('百度普通收录推送发生错误:' . $result->message);
} elseif (isset($result->success)) {
alert_back('成功推送' . $result->success . '条,今天剩余可推送' . $result->remain . '条数!');
} else {
alert_back('发生未知错误!');
}
case 'baiduks':
$list = post('list');
$urls = post('urls');
if (! $list) {
alert_back('请选择要推送的内容!');
}
// 依次推送
$domain = get_http_url();
if (! $token = $this->config('baidu_ks_token')) {
alert_back('请先到系统配置中填写百度快速收录推送token值');
}
$api = "http://data.zz.baidu.com/urls?site=$domain&token=$token&type=daily";
foreach ($list as $key => $value) {
$url = $domain . $urls[$value];
$this->log('百度快速收录推送:' . $url);
$post_urls[] = $url;
}
$result = post_baidu($api, $post_urls);
if (isset($result->error)) {
alert_back('百度快速收录推送发生错误:' . $result->message);
} elseif (isset($result->success_daily)) {
alert_back('成功推送' . $result->success_daily . '条,今天剩余可推送' . $result->remain_daily . '条数!');
} else {
alert_back('发生未知错误!');
}
}
}
if (! $id = get('id', 'int')) {
error('传递的参数值错误!', - 1);
}
// 单独修改状态
if (($field = get('field', 'var')) && ! is_null($value = get('value', 'var'))) {
if ($this->model->modContent($id, "$field='$value',update_user='" . session('username') . "'")) {
location(- 1);
} else {
alert_back('修改失败!');
}
}
// 修改操作
if ($_POST) {
// 获取数据
$scode = post('scode');
$subscode = post('subscode');
$title = post('title');
$titlecolor = post('titlecolor');
$subtitle = post('subtitle');
$filename = post('filename');
$author = post('author');
$source = post('source');
$outlink = post('outlink');
$date = post('date');
$ico = post('ico');
$pics = post('pics');
// 获取多图标题
$picstitle = post('picstitle');
if ($picstitle) {
$picstitle = implode(',', $picstitle);
}
$content = post('content');
$tags = str_replace('', ',', post('tags'));
$enclosure = post('enclosure');
$keywords = post('keywords');
$description = post('description');
$status = post('status', 'int');
$istop = post('istop', 'int', '', '', 0);
$isrecommend = post('isrecommend', 'int', '', '', 0);
$isheadline = post('isheadline', 'int', '', '', 0);
$gid = post('gid', 'int') ?: 0;
$gtype = post('gtype', 'int') ?: 4;
$gnote = post('gnote');
if (! $scode) {
alert_back('内容分类不能为空!');
}
if (! $title) {
alert_back('文章标题不能为空!');
}
if ($filename && ! preg_match('/^[a-zA-Z0-9\-]+$/', $filename)) {
alert_back('内容URL名称只允许字母、数字、横线组成!');
}
// 自动提起前一百个字符为描述
if (! $description && isset($_POST['content'])) {
$description = escape_string(clear_html_blank(substr_both(strip_tags($_POST['content']), 0, 150)));
}
// 缩放缩略图
if ($ico) {
resize_img(ROOT_PATH . $ico, '', $this->config('ico.max_width'), $this->config('ico.max_height'));
}
if ($filename) {
while ($this->model->checkFilename($filename, "id<>$id")) {
$filename = $filename . '-' . mt_rand(1, 20);
}
}
// 构建数据
$data = array(
'scode' => $scode,
'subscode' => $subscode,
'title' => $title,
'titlecolor' => $titlecolor,
'subtitle' => $subtitle,
'filename' => $filename,
'author' => $author,
'source' => $source,
'outlink' => $outlink,
'date' => $date,
'ico' => $ico,
'pics' => $pics,
'picstitle' => $picstitle,
'content' => $content,
'tags' => $tags,
'enclosure' => $enclosure,
'keywords' => $keywords,
'description' => clear_html_blank($description),
'status' => $status,
'istop' => $istop,
'isrecommend' => $isrecommend,
'isheadline' => $isheadline,
'gid' => $gid,
'gtype' => $gtype,
'gnote' => $gnote,
'update_user' => session('username')
);
// 执行添加
if ($this->model->modContent($id, $data)) {
// 扩展内容修改
foreach ($_POST as $key => $value) {
if (preg_match('/^ext_[\w\-]+$/', $key)) {
$temp = post($key);
if (is_array($temp)) {
$data2[$key] = implode(',', $temp);
} else {
$data2[$key] = str_replace("\r\n", '<br>', $temp);
}
}
}
if (isset($data2)) {
if ($this->model->findContentExt($id)) {
$this->model->modContentExt($id, $data2);
} else {
$data2['contentid'] = $id;
$this->model->addContentExt($data2);
}
}
$this->log('修改文章' . $id . '成功!');
if (! ! $backurl = get('backurl')) {
success('修改成功!', base64_decode($backurl));
} else {
success('修改成功!', url('/admin/Content/index/mcode/2'));
}
} else {
location(- 1);
}
} else {
// 调取修改内容
$this->assign('mod', true);
if (! $result = $this->model->getContent($id)) {
error('编辑的内容已经不存在!', - 1);
}
$this->assign('content', $result);
if (! $mcode = get('mcode', 'var')) {
error('传递的模型编码参数有误,请核对后重试!');
}
// 文章分类
$sort_model = model('admin.content.ContentSort');
$sort_select = $sort_model->getListSelect($mcode);
$this->assign('sort_select', $this->makeSortSelect($sort_select, $result->scode));
$this->assign('subsort_select', $this->makeSortSelect($sort_select, $result->subscode));
// 模型名称
$this->assign('model_name', model('admin.content.Model')->getName($mcode));
// 扩展字段
$this->assign('extfield', model('admin.content.ExtField')->getModelField($mcode));
// 获取会员分组
$this->assign('groups', model('admin.member.MemberGroup')->getSelect());
$this->display('content/content.html');
}
}
}

View File

@@ -0,0 +1,557 @@
<?php
/**
* @copyright (C)2016-2099 Hnaoyun Inc.
* @author XingMeng
* @email hnxsh@foxmail.com
* @date 2017年12月26日
* 内容栏目控制器
*/
namespace app\admin\controller\content;
use core\basic\Controller;
use app\admin\model\content\ContentSortModel;
class ContentSortController extends Controller
{
private $count;
private $blank;
private $outData = array();
private $model;
public function __construct()
{
$this->model = new ContentSortModel();
}
// 内容栏目列表
public function index()
{
$this->assign('list', true);
$tree = $this->model->getList();
$sorts = $this->makeSortList($tree);
$this->assign('sorts', $sorts);
// 内容模型
$models = model('admin.content.Model');
$this->assign('allmodels', $models->getSelectAll());
$this->assign('models', $models->getSelect());
// 内容栏目下拉表
$sort_tree = $this->model->getSelect();
$sort_select = $this->makeSortSelect($sort_tree);
$this->assign('sort_select', $sort_select);
// 模板文件
$htmldir = $this->config('tpl_html_dir') ? '/' . $this->config('tpl_html_dir') : '';
$this->assign('tpls', file_list(ROOT_PATH . current($this->config('tpl_dir')) . '/' . $this->model->getTheme() . $htmldir));
// 前端地址连接符判断
$url_break_char = $this->config('url_break_char') ?: '_';
$this->assign('url_break_char', $url_break_char);
// 获取会员分组
$this->assign('groups', model('admin.member.MemberGroup')->getSelect());
$this->display('content/contentsort.html');
}
// 生成无限级内容栏目列表
private function makeSortList($tree)
{
// 循环生成
foreach ($tree as $value) {
$this->count ++;
$this->outData[$this->count] = new \stdClass();
$this->outData[$this->count]->id = $value->id;
$this->outData[$this->count]->blank = $this->blank;
$this->outData[$this->count]->name = $value->name;
$this->outData[$this->count]->subname = $value->subname;
$this->outData[$this->count]->scode = $value->scode;
$this->outData[$this->count]->pcode = $value->pcode;
$this->outData[$this->count]->mcode = $value->mcode;
$this->outData[$this->count]->listtpl = $value->listtpl;
$this->outData[$this->count]->contenttpl = $value->contenttpl;
$this->outData[$this->count]->ico = $value->ico;
$this->outData[$this->count]->pic = $value->pic;
$this->outData[$this->count]->keywords = $value->keywords;
$this->outData[$this->count]->description = $value->description;
$this->outData[$this->count]->outlink = $value->outlink;
$this->outData[$this->count]->sorting = $value->sorting;
$this->outData[$this->count]->status = $value->status;
$this->outData[$this->count]->filename = $value->filename;
$this->outData[$this->count]->type = $value->type;
$this->outData[$this->count]->urlname = $value->urlname;
$this->outData[$this->count]->create_user = $value->create_user;
$this->outData[$this->count]->update_user = $value->update_user;
$this->outData[$this->count]->create_time = $value->create_time;
$this->outData[$this->count]->update_time = $value->update_time;
if ($value->son) {
$this->outData[$this->count]->son = true;
} else {
$this->outData[$this->count]->son = false;
}
// 子菜单处理
if ($value->son) {
$this->blank .= '  ';
$this->makeSortList($value->son);
}
}
// 循环完后回归缩进位置
$this->blank = substr($this->blank, 6);
return $this->outData;
}
// 内容栏目增加
public function add()
{
if ($_POST) {
if (! ! $multiplename = post('multiplename')) {
$multiplename = str_replace('', ',', $multiplename);
$pcode = post('pcode', 'var');
$type = post('type');
$mcode = post('mcode');
$listtpl = basename(post('listtpl'));
$contenttpl = basename(post('contenttpl'));
$status = post('status');
if (! $pcode) { // 父编码默认为0
$pcode = 0;
}
if (! $mcode) {
alert_back('栏目模型必须选择!');
}
if (! $type) {
alert_back('栏目类型不能为空!');
}
$names = explode(',', $multiplename);
$lastcode = $this->model->getLastCode();
$scode = get_auto_code($lastcode);
foreach ($names as $key => $value) {
$data[] = array(
'acode' => session('acode'),
'pcode' => $pcode,
'scode' => $scode,
'name' => $value,
'mcode' => $mcode,
'listtpl' => $listtpl,
'contenttpl' => $contenttpl,
'status' => $status,
'gid' => 0,
'gtype' => 4,
'subname' => '',
'filename' => '',
'outlink' => '',
'ico' => '',
'pic' => '',
'title' => '',
'keywords' => '',
'description' => '',
'sorting' => 255,
'create_user' => session('username'),
'update_user' => session('username')
);
$scode = get_auto_code($scode);
}
} else {
// 获取数据
$scode = get_auto_code($this->model->getLastCode()); // 自动编码;
$pcode = post('pcode', 'var');
$name = post('name');
$type = post('type');
$mcode = post('mcode');
$listtpl = basename(post('listtpl'));
$contenttpl = basename(post('contenttpl'));
$status = post('status');
$subname = post('subname');
$filename = post('filename');
$outlink = post('outlink');
$ico = post('ico');
$pic = post('pic');
$title = post('title');
$keywords = post('keywords');
$description = post('description');
$gid = post('gid', 'int') ?: 0;
$gtype = post('gtype', 'int') ?: 4;
$gnote = post('gnote');
$def1 = post('def1');
$def2 = post('def2');
$def3 = post('def3');
if (! $scode) {
alert_back('编码不能为空!');
}
if (! $pcode) { // 父编码默认为0
$pcode = 0;
}
if (! $name) {
alert_back('栏目名不能为空!');
}
if (! $mcode) {
alert_back('栏目模型必须选择!');
}
if (! $type) {
alert_back('栏目类型不能为空!');
}
if ($filename && ! preg_match('/^[a-zA-Z0-9\-\/]+$/', $filename)) {
alert_back('URL名称只允许字母、数字、横线、斜线组成!');
}
if ($filename && $this->model->checkUrlname($filename)) {
alert_back('URL名称与模型URL名称冲突请换一个名称');
}
// 缩放缩略图
if ($ico) {
resize_img(ROOT_PATH . $ico, '', $this->config('ico.max_width'), $this->config('ico.max_height'));
}
// 检查编码
if ($this->model->checkSort("scode='$scode'")) {
alert_back('该内容栏目编号已经存在,不能再使用!');
}
// 检查自定义URL名称
if ($filename) {
while ($this->model->checkFilename($filename)) {
$filename = $filename . '_' . mt_rand(1, 20);
}
}
// 构建数据
$data = array(
'acode' => session('acode'),
'pcode' => $pcode,
'scode' => $scode,
'name' => $name,
'mcode' => $mcode,
'listtpl' => $listtpl,
'contenttpl' => $contenttpl,
'status' => $status,
'gid' => $gid,
'gtype' => $gtype,
'gnote' => $gnote,
'subname' => $subname,
'def1' => $def1,
'def2' => $def2,
'def3' => $def3,
'filename' => $filename,
'outlink' => $outlink,
'ico' => $ico,
'pic' => $pic,
'title' => $title,
'keywords' => $keywords,
'description' => $description,
'sorting' => 255,
'create_user' => session('username'),
'update_user' => session('username')
);
}
// 执行添加
if ($this->model->addSort($data)) {
if ($type == 1 && ! $outlink) { // 在填写了外链时不生成单页
if ($multiplename) {
foreach ($data as $key => $value) {
$this->addSingle($value['scode'], $value['name']);
}
} else {
$this->addSingle($scode, $name);
}
}
$this->log('新增数据内容栏目' . $scode . '成功!');
success('新增成功!', url('/admin/ContentSort/index'));
} else {
$this->log('新增数据内容栏目' . $scode . '失败!');
error('新增失败!', - 1);
}
}
}
// 生成内容栏目下拉选择
private function makeSortSelect($tree, $selectid = null)
{
$list_html = '';
foreach ($tree as $value) {
// 默认选择项
if ($selectid == $value->scode) {
$select = "selected='selected'";
} else {
$select = '';
}
if (get('scode') != $value->scode) { // 不显示本身,避免出现自身为自己的父节点
$list_html .= "<option value='{$value->scode}' $select>{$this->blank}{$value->name}</option>";
}
// 子菜单处理
if ($value->son) {
$this->blank .= '  ';
$list_html .= $this->makeSortSelect($value->son, $selectid);
}
}
// 循环完后回归位置
$this->blank = substr($this->blank, 0, - 6);
return $list_html;
}
// 内容栏目删除
public function del()
{
// 执行批量删除
if ($_POST) {
if (! ! $list = post('list')) {
if ($this->model->delSortList($list)) {
$this->log('批量删除栏目成功!');
success('批量删除成功!', - 1);
} else {
$this->log('批量删除栏目失败!');
error('批量删除失败!', - 1);
}
} else {
alert_back('请选择要删除的栏目!');
}
}
if (! $scode = get('scode', 'var')) {
error('传递的参数值错误!', - 1);
}
if ($this->model->delSort($scode)) {
$this->log('删除数据内容栏目' . $scode . '成功!');
success('删除成功!', - 1);
} else {
$this->log('删除数据内容栏目' . $scode . '失败!');
error('删除失败!', - 1);
}
}
// 内容栏目修改
public function mod()
{
if (! ! $submit = post('submit')) {
switch ($submit) {
case 'sorting': // 修改列表排序
$listall = post('listall');
if ($listall) {
$sorting = post('sorting');
foreach ($listall as $key => $value) {
if ($sorting[$key] === '' || ! is_numeric($sorting[$key]))
$sorting[$key] = 255;
$this->model->modSortSorting($value, "sorting=" . $sorting[$key]);
}
$this->log('批量修改栏目排序成功!');
success('修改成功!', - 1);
} else {
alert_back('排序失败,无任何内容!');
}
break;
}
}
if (! $scode = get('scode', 'var')) {
error('传递的参数值错误!', - 1);
}
// 单独修改状态
if (($field = get('field', 'var')) && ! is_null($value = get('value', 'var'))) {
if ($this->model->modSort($scode, "$field='$value',update_user='" . session('username') . "'")) {
$this->log('修改数据内容栏目' . $scode . '状态' . $value . '成功!');
location(- 1);
} else {
$this->log('修改数据内容栏目' . $scode . '状态' . $value . '失败!');
alert_back('修改失败!');
}
}
// 修改操作
if ($_POST) {
// 获取数据
$pcode = post('pcode', 'var');
$name = post('name');
$mcode = post('mcode');
$type = post('type');
$listtpl = basename(post('listtpl'));
$contenttpl = basename(post('contenttpl'));
$status = post('status');
$subname = post('subname');
$filename = post('filename');
$outlink = post('outlink');
$ico = post('ico');
$pic = post('pic');
$title = post('title');
$keywords = post('keywords');
$description = post('description');
$modsub = post('modsub', 'int');
$gid = post('gid', 'int') ?: 0;
$gtype = post('gtype', 'int') ?: 4;
$gnote = post('gnote');
$def1 = post('def1');
$def2 = post('def2');
$def3 = post('def3');
if (! $pcode) { // 父编码默认为0
$pcode = 0;
}
if (! $name) {
alert_back('栏目名不能为空!');
}
if (! $mcode) {
alert_back('栏目模型必须选择!');
}
if (! $type) {
alert_back('栏目类型不能为空!');
}
if ($filename && ! preg_match('/^[a-zA-Z0-9\-\/]+$/', $filename)) {
alert_back('URL名称只允许字母、数字、横线、斜线组成!');
}
if ($filename && $this->model->checkUrlname($filename)) {
alert_back('URL名称与模型URL名称冲突请换一个名称');
}
// 缩放缩略图
if ($ico) {
resize_img(ROOT_PATH . $ico, '', $this->config('ico.max_width'), $this->config('ico.max_height'));
}
if ($filename) {
while ($this->model->checkFilename($filename, "scode<>'$scode'")) {
$filename = $filename . '-' . mt_rand(1, 20);
}
}
// 构建数据
$data = array(
'pcode' => $pcode,
'name' => $name,
'mcode' => $mcode,
'listtpl' => $listtpl,
'contenttpl' => $contenttpl,
'status' => $status,
'gid' => $gid,
'gtype' => $gtype,
'gnote' => $gnote,
'subname' => $subname,
'def1' => $def1,
'def2' => $def2,
'def3' => $def3,
'filename' => $filename,
'outlink' => $outlink,
'ico' => $ico,
'pic' => $pic,
'title' => $title,
'keywords' => $keywords,
'description' => $description,
'update_user' => session('username')
);
// 执行添加
if ($this->model->modSort($scode, $data, $modsub)) {
// 如果修改为单页并且跳转,则删除单页内容,否则判断是否存在内容,不存在则添加
if ($type == 1 && $outlink) {
$this->model->delContent($scode);
} elseif ($type == 1 && ! $this->model->findContent($scode)) {
$this->addSingle($scode, $name);
}
$this->log('修改数据内容栏目' . $scode . '成功!');
success('修改成功!', url('/admin/ContentSort/index'));
} else {
location(- 1);
}
} else { // 调取修改内容
$this->assign('mod', true);
$sort = $this->model->getSort($scode);
if (! $sort) {
error('编辑的内容已经不存在!', - 1);
}
$this->assign('sort', $sort);
// 父编码下拉选择
$sort_tree = $this->model->getSelect();
$sort_select = $this->makeSortSelect($sort_tree, $sort->pcode);
$this->assign('sort_select', $sort_select);
// 模板文件
$htmldir = $this->config('tpl_html_dir') ? '/' . $this->config('tpl_html_dir') : '';
$this->assign('tpls', file_list(ROOT_PATH . current($this->config('tpl_dir')) . '/' . $this->model->getTheme() . $htmldir));
// 内容模型
$models = model('admin.content.Model');
$this->assign('models', $models->getSelect());
// 获取会员分组
$this->assign('groups', model('admin.member.MemberGroup')->getSelect());
$this->display('content/contentsort.html');
}
}
// 添加栏目时执行单页内容增加
public function addSingle($scode, $title)
{
// 构建数据
$data = array(
'acode' => session('acode'),
'scode' => $scode,
'subscode' => '',
'title' => $title,
'titlecolor' => '#333333',
'subtitle' => '',
'filename' => '',
'author' => session('realname'),
'source' => '本站',
'outlink' => '',
'date' => date('Y-m-d H:i:s'),
'ico' => '',
'pics' => '',
'content' => '',
'tags' => '',
'enclosure' => '',
'keywords' => '',
'description' => '',
'sorting' => 255,
'status' => 1,
'istop' => 0,
'isrecommend' => 0,
'isheadline' => 0,
'gid' => 0,
'gtype' => 4,
'gnote' => '',
'visits' => 0,
'likes' => 0,
'oppose' => 0,
'create_user' => session('username'),
'update_user' => session('username')
);
// 执行添加
if ($this->model->addSingle($data)) {
return true;
} else {
return false;
}
}
}

View File

@@ -0,0 +1,134 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="renderer" content="webkit">
<title>{CMSNAME}管理中心-V{APP_VERSION}-{RELEASE_TIME}</title>
<link rel="shortcut icon" href="{SITE_DIR}/favicon.ico" type="image/x-icon">
<link rel="stylesheet" href="{APP_THEME_DIR}/layui/css/layui.css?v=v2.5.4">
<link rel="stylesheet" href="{APP_THEME_DIR}/font-awesome/css/font-awesome.min.css?v=v4.7.0" type="text/css">
<link rel="stylesheet" href="{APP_THEME_DIR}/css/comm.css?v=v3.0.6">
<link href="{APP_THEME_DIR}/css/jquery.treetable.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="{APP_THEME_DIR}/js/jquery-1.12.4.min.js"></script>
<script type="text/javascript" src="{APP_THEME_DIR}/js/jquery.treetable.js"></script>
</head>
<body class="layui-layout-body">
<!--定义部分地址方便JS调用-->
<div style="display: none">
<span id="controller" data-controller="{C}"></span>
<span id="url" data-url="{URL}"></span>
<span id="preurl" data-preurl="{fun=url('/admin',false)}"></span>
<span id="sitedir" data-sitedir="{SITE_DIR}"></span>
<span id="mcode" data-mcode="{$get.mcode}"></span>
</div>
<div class="layui-layout layui-layout-admin">
<div class="layui-header">
<div class="layui-logo">
<a href="{url./admin/Index/home}">
后台管理
{if(LICENSE==3)}
<span class="layui-badge">SVIP</span>
{else}
<span class="layui-badge layui-bg-gray">V{APP_VERSION}</span>
{/if}
</a>
</div>
<ul class="menu">
<li class="menu-ico" title="显示或隐藏侧边栏"><i class="fa fa-bars" aria-hidden="true"></i></li>
</ul>
{if(![$one_area])}
<form method="post" action="{url./admin/Index/area}" class="area-select">
<input type="hidden" name="formcheck" value="{$formcheck}" >
<div class="layui-col-xs8">
<select name="acode">
{$area_html}
</select>
</div>
<div class="layui-col-xs4">
<button type="submit" class="layui-btn layui-btn-sm">切换</button>
</div>
</form>
{/if}
<ul class="layui-nav layui-layout-right">
<li class="layui-nav-item layui-hide-xs">
<a href="{SITE_DIR}/" target="_blank"><i class="fa fa-home" aria-hidden="true"></i> 网站主页</a>
</li>
<li class="layui-nav-item layui-hide-xs">
<a href="{url./admin/Index/clearCache}"><i class="fa fa-trash-o" aria-hidden="true"></i> 清理缓存</a>
</li>
<li class="layui-nav-item layui-hide-xs">
<a href="javascript:;">
<i class="fa fa-user-circle-o" aria-hidden="true"></i> {$session.realname}
</a>
<dl class="layui-nav-child">
<dd><a href="{url./admin/Index/ucenter}"><i class="fa fa-address-card-o" aria-hidden="true"></i> 密码修改</a></dd>
<dd><a href="{url./admin/Index/loginOut}"><i class="fa fa-sign-out" aria-hidden="true"></i> 退出登录</a></dd>
<dd><a href="{url./admin/Upgrade/index}"><i class="fa fa-cloud-upload" aria-hidden="true"></i> 在线更新</a></dd>
<dd><a href="{url./admin/Index/clearSession}"><i class="fa fa-trash-o" aria-hidden="true"></i> 清理会话</a></dd>
</dl>
</li>
</ul>
</div>
<div class="layui-side layui-bg-black">
<div class="layui-side-scroll">
<!-- 左侧导航区域可配合layui已有的垂直导航 -->
<ul class="layui-nav layui-nav-tree" id="nav" lay-shrink="all">
{foreach $menu_tree(key,value)}
<li class="layui-nav-item nav-item {if([$primary_menu_url]==$value->url)}layui-nav-itemed{/if}">
<a class="" href="javascript:;"><i class="fa [value->ico]" aria-hidden="true"></i>[value->name]</a>
<dl class="layui-nav-child">
{if($value->mcode=='M130')}
{foreach $menu_models(key3,value3,num3)}
{if($value3->type==1)}
<dd><a href="{url./admin/Single/index/mcode/'.$value3->mcode.'}"><i class="fa fa-file-text-o" aria-hidden="true"></i>[value3->name]内容</a></dd>
{/if}
{if($value3->type==2)}
<dd><a href="{url./admin/Content/index/mcode/'.$value3->mcode.'}"><i class="fa fa-file-text-o" aria-hidden="true"></i>[value3->name]内容</a></dd>
{/if}
{/foreach}
{else}
{foreach $value->son(key2,value2,num2)}
{if(!isset($value2->status)|| $value2->status==1)}
<dd><a href="{url.'.$value2->url.'}"><i class="fa [value2->ico]" aria-hidden="true"></i>[value2->name]</a></dd>
{/if}
{/foreach}
{if($value->mcode=='M101' && session('ucode')==10001)}
<dd><a href="{url./admin/Upgrade/index}"><i class="fa fa-cloud-upload" aria-hidden="true"></i>在线更新</a></dd>
{/if}
{/if}
</dl>
</li>
{/foreach}
<li style="height:1px;background:#666" class="layui-hide-sm"></li>
<li class="layui-nav-item layui-hide-sm">
<a href="{SITE_DIR}/" target="_blank"><i class="fa fa-home" aria-hidden="true"></i> 网站主页</a>
</li>
<li class="layui-nav-item layui-hide-sm">
<a href="{url./admin/Index/ucenter}"><i class="fa fa-address-card-o" aria-hidden="true"></i> 资料修改</a>
</li>
<li class="layui-nav-item layui-hide-sm">
<a href="{url./admin/Index/clearCache}"><i class="fa fa-trash-o" aria-hidden="true"></i> 清理缓存</a>
</li>
<li class="layui-nav-item layui-hide-sm">
<a href="{url./admin/Index/loginOut}"><i class="fa fa-sign-out" aria-hidden="true"></i> 退出登录</a>
</li>
</ul>
</div>
</div>

View File

@@ -0,0 +1,113 @@
{include file='common/head.html'}
<div class="layui-body">
<div class="layui-tab layui-tab-brief" lay-filter="tab">
<ul class="layui-tab-title">
<li class="layui-this">公司信息</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
<form action="{url./admin/Company/mod}" method="post">
<input type="hidden" name="formcheck" value="{$formcheck}" >
<div class="layui-form-item">
<label class="layui-form-label">公司名称</label>
<div class="layui-input-block">
<input type="text" name="name" value="{$companys->name}" placeholder="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">公司地址</label>
<div class="layui-input-block">
<input type="text" name="address" value="{$companys->address}" placeholder="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">邮政编码</label>
<div class="layui-input-block">
<input type="text" name="postcode" value="{$companys->postcode}" placeholder="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">联系人</label>
<div class="layui-input-block">
<input type="text" name="contact" value="{$companys->contact}" placeholder="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">手机号码</label>
<div class="layui-input-block">
<input type="text" name="mobile" value="{$companys->mobile}" placeholder="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">电话号码</label>
<div class="layui-input-block">
<input type="text" name="phone" value="{$companys->phone}" placeholder="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">传真号码</label>
<div class="layui-input-block">
<input type="text" name="fax" value="{$companys->fax}" placeholder="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">电子邮箱</label>
<div class="layui-input-block">
<input type="text" name="email" value="{$companys->email}" placeholder="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">QQ号码</label>
<div class="layui-input-block">
<input type="text" name="qq" value="{$companys->qq}" placeholder="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">微信二维码</label>
<div class="layui-input-inline">
<input type="text" name="weixin" id="weixin" value="{$companys->weixin}" placeholder="" class="layui-input">
</div>
<button type="button" class="layui-btn upload" data-des="weixin">
<i class="layui-icon">&#xe67c;</i>上传图片
</button>
<div id="weixin_box" class="pic"><dl><dt>{if(@[$companys->weixin])}<img src="{SITE_DIR}{$companys->weixin}" data-url="{$companys->weixin}"></dt><dd>删除</dd></dl>{/if}</div>
</div>
<!--<div class="layui-form-item">
<label class="layui-form-label">营业执照代码</label>
<div class="layui-input-block">
<input type="text" name="blicense" value="{$companys->blicense}" placeholder="" class="layui-input">
</div>
</div>-->
<div class="layui-form-item">
<label class="layui-form-label">其它信息</label>
<div class="layui-input-block">
<input type="text" name="other" value="{$companys->other}" placeholder="" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit>立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
{include file='common/foot.html'}

View File

@@ -0,0 +1,615 @@
{include file='common/head.html'}
<div class="layui-body">
{if([$list])}
<div class="layui-tab layui-tab-brief" lay-filter="tab">
<ul class="layui-tab-title">
<li class="layui-this" lay-id="t1">栏目列表</li>
<li lay-id="t2">栏目新增</li>
<li lay-id="t3">批量新增</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
<form action="{url./admin/ContentSort/mod}" method="post" id="sortForm" name="sortForm">
<input type="hidden" name="formcheck" value="{$formcheck}" >
<table class="layui-table" id="sortTable">
<thead>
<tr>
<th><input type="checkbox" lay-ignore id="checkall" title="全选"></th>
<th>栏目名称</th>
<th>编码</th>
<th>URL名称</th>
<th>模型</th>
<th>列表页模板</th>
<th>详情页模板</th>
<th>排序</th>
<th>状态</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{foreach $sorts(key,value)}
<tr data-tt-id='[value->scode]' data-tt-parent-id="[value->pcode]">
<td>
<input type="checkbox" class="checkitem" lay-ignore name="list[]" value="[value->scode]">
<input type="hidden" name="listall[]" value="[value->id]">
</td>
<td>
{if($value->son)}
<i class="fa fa-folder-o" aria-hidden="true"></i>
{else}
<i class="fa fa-folder-open-o" aria-hidden="true"></i>
{/if}
[value->name]
{if($value->outlink)}
<span class="layui-badge layui-bg-black"></span>
{/if}
</td>
<td>[value->scode]</td>
<td>[value->filename]</td>
<td>
{foreach $allmodels(key2,value2)}
{if($value2->mcode==$value->mcode)}
[value2->name]
{/if}
{/foreach}
</td>
<td>[value->listtpl]</td>
<td>[value->contenttpl]</td>
<td class="table-input"><input type="text" name="sorting[]" value="[value->sorting]" class="layui-input"></td>
<td>
{if($value->status)}
<a href="{url./admin/'.C.'/mod/scode/'.$value->scode.'/field/status/value/0}"><i class='fa fa-toggle-on' title="点击禁用"></i></a>
{else}
<a href="{url./admin/'.C.'/mod/scode/'.$value->scode.'/field/status/value/1}"><i class='fa fa-toggle-off' title="点击启用"></i></a>
{/if}
</td>
<td>
{if(!$value->outlink)}
{if($value->type==1)}
{php}$value->urlname=$value->urlname?:'about';{/php}
{else}
{php}$value->urlname=$value->urlname?:'list';{/php}
{/if}
{php} $url_rule_sort_suffix = \core\basic\Config::get('url_rule_sort_suffix') ? true : false;{/php}
{if($value->filename)}
<a href="{fun=homeurl('/home/Index/'.$value->filename,$url_rule_sort_suffix)}" class="layui-btn layui-btn-xs layui-btn-primary" target="_blank">查看</a>
{else}
<a href="{fun=homeurl('/home/Index/'.$value->urlname.[$url_break_char].$value->scode,$url_rule_sort_suffix)}" class="layui-btn layui-btn-xs layui-btn-primary" target="_blank">查看</a>
{/if}
{/if}
{fun=get_btn_del($value->scode,'scode')}
{fun=get_btn_mod($value->scode,'scode')}
</td>
</tr>
{/foreach}
</tbody>
</table>
<button type="submit" name="submit" value="sorting" class="layui-btn">保存排序</button>
<button type="submit" name="submit" onclick="return setDelAction();" class="layui-btn">批量删除</button>
<script>
function setDelAction(){
document.sortForm.action = "{url./admin/ContentSort/del}";
return confirm("您确定要删除选中的栏目么?");
}
$("#sortTable").treetable({ expandable: true,column: 1,indent:20,stringCollapse:'收缩',stringExpand:'展开' });
</script>
</form>
</div>
<div class="layui-tab-item">
<form action="{url./admin/ContentSort/add}" method="post" class="layui-form" lay-filter="sort">
<input type="hidden" name="formcheck" value="{$formcheck}" >
<div class="layui-tab">
<ul class="layui-tab-title">
<li class="layui-this">基本选项</li>
<li>高级选项</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
<div class="layui-form-item">
<label class="layui-form-label">父栏目</label>
<div class="layui-input-block">
<select name="pcode">
<option value="0" >顶级栏目</option>
{$sort_select}
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">栏目名称 <span class="layui-text-red">*</span></label>
<div class="layui-input-block">
<input type="text" name="name" required lay-verify="required" placeholder="请输入栏目名称" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">URL名称 </label>
<div class="layui-input-block">
<input type="text" name="filename" placeholder="请输入URL名称如:test" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">内容模型 <span class="layui-text-red">*</span></label>
<div class="layui-input-block">
<select name="mcode" lay-filter="model" lay-verify="required" >
<option value="">请选择内容模型</option>
{foreach $models(key,value)}
<option value="[value->mcode]" data-type="[value->type]" data-listtpl="[value->listtpl]" data-contenttpl="[value->contenttpl]" >[value->name]</option>
{/foreach}
</select>
</div>
</div>
<input type="hidden" value="1" name="type" id="type">
<div class="layui-form-item">
<label class="layui-form-label">列表页模板</label>
<div class="layui-input-block">
<select name="listtpl" id="listtpl">
<option value=""></option>
{foreach $tpls(key,value)}
<option value="[value]">[value]</option>
{/foreach}
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">详情页模板</label>
<div class="layui-input-block">
<select name="contenttpl" id="contenttpl" >
<option value=""></option>
{foreach $tpls(key,value)}
<option value="[value]">[value]</option>
{/foreach}
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">状态</label>
<div class="layui-input-block">
<input type="radio" name="status" value="1" title="显示" checked>
<input type="radio" name="status" value="0" title="隐藏">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">浏览权限</label>
<div class="layui-input-block">
<select name="gid">
<option value="">不限制</option>
{foreach $groups(key,value)}
<option value="[value->id]">[value->gname]</option>
{/foreach}
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">权限类型</label>
<div class="layui-input-block">
<select name="gtype" id="gtype" >
<option value="1">小于</option>
<option value="2">小于等于</option>
<option value="3">等于</option>
<option value="4" selected>大于等于</option>
<option value="5">大于</option>
</select>
</div>
</div>
</div>
<div class="layui-tab-item">
<div class="layui-form-item">
<label class="layui-form-label">栏目副名称</label>
<div class="layui-input-block">
<input type="text" name="subname" placeholder="请输入栏目副名称" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">栏目描述1</label>
<div class="layui-input-block">
<input type="text" name="def1" placeholder="请输入栏目描述1内容" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">栏目描述2</label>
<div class="layui-input-block">
<input type="text" name="def2" placeholder="请输入栏目描述2内容" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">栏目描述3</label>
<div class="layui-input-block">
<input type="text" name="def3" placeholder="请输入栏目描述3内容" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">跳转链接</label>
<div class="layui-input-block">
<input type="text" name="outlink" placeholder="请输入跳转链接" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">权限不足提示</label>
<div class="layui-input-block">
<input type="text" name="gnote" placeholder="请输入权限不足时提示文本" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">栏目缩略图</label>
<div class="layui-input-inline">
<input type="text" name="ico" id="ico" placeholder="请上传栏目缩略图" class="layui-input">
</div>
<button type="button" class="layui-btn upload" data-des="ico">
<i class="layui-icon">&#xe67c;</i>上传图片
</button>
<div id="ico_box" class="pic"></div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">栏目大图</label>
<div class="layui-input-inline">
<input type="text" name="pic" id="pic" placeholder="请上传栏目大图" class="layui-input">
</div>
<button type="button" class="layui-btn upload" data-des="pic">
<i class="layui-icon">&#xe67c;</i>上传图片
</button>
<div id="pic_box" class="pic"></div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">SEO标题</label>
<div class="layui-input-block">
<input type="text" name="title" placeholder="请输入栏目SEO标题需前端调用" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">SEO关键字</label>
<div class="layui-input-block">
<input type="text" name="keywords" placeholder="请输入栏目SEO关键字需前端调用" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">SEO描述</label>
<div class="layui-input-block">
<textarea name="description" placeholder="请输入栏目SEO描述需前端调用" class="layui-textarea"></textarea>
</div>
</div>
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit>立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
<!-- 批量新增 -->
<div class="layui-tab-item">
<form action="{url./admin/ContentSort/add}" method="post" class="layui-form" lay-filter="sort">
<input type="hidden" name="formcheck" value="{$formcheck}" >
<div class="layui-form-item">
<label class="layui-form-label">父栏目</label>
<div class="layui-input-block">
<select name="pcode">
<option value="0" >顶级栏目</option>
{$sort_select}
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">栏目名称</label>
<div class="layui-input-block">
<input type="text" name="multiplename" required lay-verify="required" placeholder="请输入栏目名称,多个栏目用逗号隔开" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">内容模型</label>
<div class="layui-input-block">
<select name="mcode" lay-filter="model" lay-verify="required" >
<option value="">请选择内容模型</option>
{foreach $models(key,value)}
<option value="[value->mcode]" data-type="[value->type]" data-listtpl="[value->listtpl]" data-contenttpl="[value->contenttpl]" >[value->name]</option>
{/foreach}
</select>
</div>
</div>
<input type="hidden" value="1" name="type" id="type">
<div class="layui-form-item">
<label class="layui-form-label">列表页模板</label>
<div class="layui-input-block">
<select name="listtpl" id="listtpl">
<option value=""></option>
{foreach $tpls(key,value)}
<option value="[value]">[value]</option>
{/foreach}
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">详情页模板</label>
<div class="layui-input-block">
<select name="contenttpl" id="contenttpl" >
<option value=""></option>
{foreach $tpls(key,value)}
<option value="[value]">[value]</option>
{/foreach}
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">状态</label>
<div class="layui-input-block">
<input type="radio" name="status" value="1" title="显示" checked>
<input type="radio" name="status" value="0" title="隐藏">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit>立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
</div>
</div>
{/if}
{if([$mod])}
<div class="layui-tab layui-tab-brief" lay-filter="tab">
<ul class="layui-tab-title">
<li class="layui-this">栏目修改</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
<form action="{url./admin/ContentSort/mod/scode/'.[$get.scode].'}{$backurl}" method="post" class="layui-form" lay-filter="sort">
<input type="hidden" name="formcheck" value="{$formcheck}" >
<div class="layui-tab">
<ul class="layui-tab-title">
<li class="layui-this">基本选项</li>
<li>高级选项</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
<div class="layui-form-item">
<label class="layui-form-label">父栏目</label>
<div class="layui-input-block">
<select name="pcode" id="pcode">
<option value="0" >顶级栏目</option>
{$sort_select}
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">栏目名称 <span class="layui-text-red">*</span></label>
<div class="layui-input-block">
<input type="text" name="name" required lay-verify="required" value="{$sort->name}" placeholder="请输入栏目名称" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">URL名称 </label>
<div class="layui-input-block">
<input type="text" name="filename" value="{$sort->filename}" placeholder="请输入URL名称如:test" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">内容模型 <span class="layui-text-red">*</span></label>
<div class="layui-input-block">
<select name="mcode" lay-filter="model" lay-verify="required" >
<option value="">请选择内容模型</option>
{foreach $models(key,value)}
<option value="[value->mcode]" {if($value->mcode==[$sort->mcode])}selected{/if} data-type="[value->type]" data-listtpl="[value->listtpl]" data-contenttpl="[value->contenttpl]" >[value->name]</option>
{/foreach}
</select>
</div>
</div>
<input type="hidden" name="type" id="type" value="{$sort->type}">
<div class="layui-form-item">
<label class="layui-form-label">列表页模板</label>
<div class="layui-input-block">
<select name="listtpl" id="listtpl">
<option value="{$sort->listtpl}">{$sort->listtpl}</option>
<option value=""></option>
{foreach $tpls(key,value)}
{if($value!=[$sort->listtpl])}
<option value="[value]">[value]</option>
{/if}
{/foreach}
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">详情页模板</label>
<div class="layui-input-block">
<select name="contenttpl" id="contenttpl" >
<option value="{$sort->contenttpl}">{$sort->contenttpl}</option>
<option value=""></option>
{foreach $tpls(key,value)}
{if($value!=[$sort->contenttpl])}
<option value="[value]">[value]</option>
{/if}
{/foreach}
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">同步子栏目模板</label>
<div class="layui-input-block">
<input type="radio" name="modsub" value="1" title="是">
<input type="radio" name="modsub" value="0" title="否" checked>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">状态</label>
<div class="layui-input-block">
<input type="radio" name="status" value="1" title="显示" {if([$sort->status]==1)}checked="checked"{/if}>
<input type="radio" name="status" value="0" title="隐藏" {if([$sort->status]==0)}checked="checked"{/if}>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">浏览权限</label>
<div class="layui-input-block">
<select name="gid">
<option value="">不限制</option>
{foreach $groups(key,value)}
<option value="[value->id]" {if([$sort->gid]==$value->id)}selected="selected"{/if}>[value->gname]</option>
{/foreach}
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">权限类型</label>
<div class="layui-input-block">
<select name="gtype" id="gtype" >
<option value="1" {if([$sort->gtype]==1)}selected="selected"{/if}>小于</option>
<option value="2" {if([$sort->gtype]==2)}selected="selected"{/if}>小于等于</option>
<option value="3" {if([$sort->gtype]==3)}selected="selected"{/if}>等于</option>
<option value="4" {if([$sort->gtype]==4||(![$sort->gtype]))}selected="selected"{/if}>大于等于</option>
<option value="5" {if([$sort->gtype]==5)}selected="selected"{/if}>大于</option>
</select>
</div>
</div>
</div>
<div class="layui-tab-item">
<div class="layui-form-item">
<label class="layui-form-label">栏目副名称</label>
<div class="layui-input-block">
<input type="text" name="subname" value="{$sort->subname}" placeholder="请输入栏目副名称" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">栏目描述1</label>
<div class="layui-input-block">
<input type="text" name="def1" value="{$sort->def1}" placeholder="请输入栏目描述1内容" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">栏目描述2</label>
<div class="layui-input-block">
<input type="text" name="def2" value="{$sort->def2}" placeholder="请输入栏目描述2内容" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">栏目描述3</label>
<div class="layui-input-block">
<input type="text" name="def3" value="{$sort->def3}" placeholder="请输入栏目描述3内容" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">跳转链接</label>
<div class="layui-input-block">
<input type="text" name="outlink" value="{$sort->outlink}" placeholder="请输入跳转链接" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">权限不足提示</label>
<div class="layui-input-block">
<input type="text" name="gnote" value="{$sort->gnote}" placeholder="请输入权限不足时提示文本" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">栏目缩略图</label>
<div class="layui-input-inline">
<input type="text" name="ico" id="ico" value="{$sort->ico}" placeholder="请上传栏目缩略图" class="layui-input">
</div>
<button type="button" class="layui-btn upload" data-des="ico">
<i class="layui-icon">&#xe67c;</i>上传图片
</button>
<div id="ico_box" class="pic"><dl><dt>{if([$sort->ico])}<img src='{SITE_DIR}{$sort->ico}' data-url="{$sort->ico}"></dt><dd>删除</dd></dl>{/if}</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">栏目大图</label>
<div class="layui-input-inline">
<input type="text" name="pic" id="pic" value="{$sort->pic}" placeholder="请上传栏目大图" class="layui-input">
</div>
<button type="button" class="layui-btn upload" data-des="pic">
<i class="layui-icon">&#xe67c;</i>上传图片
</button>
<div id="pic_box" class="pic"><dl><dt>{if([$sort->pic])}<img src='{SITE_DIR}{$sort->pic}' data-url="{$sort->pic}"></dt><dd>删除</dd></dl>{/if}</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">SEO标题</label>
<div class="layui-input-block">
<input type="text" name="title" value="{$sort->title}" placeholder="请输入栏目SEO标题需前端调用" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">SEO关键字</label>
<div class="layui-input-block">
<input type="text" name="keywords" value="{$sort->keywords}" placeholder="请输入栏目SEO关键字需前端调用" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">SEO描述</label>
<div class="layui-input-block">
<textarea name="description" placeholder="请输入栏目SEO描述需前端调用" class="layui-textarea">{$sort->description}</textarea>
</div>
</div>
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit>立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
{fun=get_btn_back()}
</div>
</div>
</form>
</div>
</div>
</div>
{/if}
</div>
{include file='common/foot.html'}

View File

@@ -0,0 +1,431 @@
{include file='common/head.html'}
<div class="layui-body">
{if([$list])}
<div class="layui-tab layui-tab-brief" lay-filter="tab">
<ul class="layui-tab-title">
<li class="layui-this" lay-id="t1">{$model_name}内容</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
<form action="{url./admin/Single/index/mcode/'.get('mcode').'}" method="get" class="layui-form">
<div class="layui-form-item nospace">
<div class="layui-input-inline">
{$pathinfo}
<select name="field" class="form-control input-sm" style="width:auto;">
<option value="b.name" {if(get('field')=='b.name')}selected="selected" {/if}>栏目名称</option>
<option value="a.title" {if(get('field')=='a.title')}selected="selected" {/if} >文章标题</option>
<option value="a.content" {if(get('field')=='a.content')}selected="selected" {/if}>文章内容</option>
</select>
</div>
<div class="layui-input-inline">
<input type="text" name="keyword" value="{$get.keyword}" placeholder="请输入搜索关键字" class="layui-input">
</div>
<div class="layui-input-inline">
<button class="layui-btn" lay-submit>搜索</button>
<a class="layui-btn layui-btn-primary" href="{url./admin/Single/index/mcode/'.get('mcode').'}">清除搜索</a>
</div>
</div>
</form>
<table class="layui-table">
<thead>
<tr>
<th>ID</th>
<th>栏目</th>
<th>标题</th>
<th>时间</th>
<th>状态</th>
<th>访问量</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{foreach $contents(key,value)}
<tr>
<td>[value->id]</td>
<td title="[value->scode]">[value->sortname]</td>
<td title="[value->title]">
{fun=substr_both($value->title,0,15)}
{if($value->ico)}
<span class="layui-badge layui-bg-orange"></span>
{/if}
{if($value->pics)}
<span class="layui-badge"></span>
{/if}
{if($value->outlink)}
<span class="layui-badge layui-bg-black"></span>
{/if}
</td>
<td>[value->date]</td>
<td>
{if($value->status)}
<a href="{url./admin/'.C.'/mod/id/'.$value->id.'/field/status/value/0}"><i class='fa fa-toggle-on' title="点击关闭"></i></a>
{else}
<a href="{url./admin/'.C.'/mod/id/'.$value->id.'/field/status/value/1}"><i class='fa fa-toggle-off' title="点击开启"></i></a>
{/if}
</td>
<td>[value->visits]</td>
<td>
{if(!$value->outlink)}
{php}
$value->urlname=$value->urlname?:'about';
$url_rule_sort_suffix = \core\basic\Config::get('url_rule_sort_suffix') ? true : false;
{/php}
{if($value->filename)}
<a href="{fun=homeurl('/home/Index/'.$value->filename,$url_rule_sort_suffix)}" class="layui-btn layui-btn-xs layui-btn-primary" target="_blank">查看</a>
{else}
<a href="{fun=homeurl('/home/Index/'.$value->urlname.[$url_break_char].$value->scode,$url_rule_sort_suffix)}" class="layui-btn layui-btn-xs layui-btn-primary" target="_blank">查看</a>
{/if}
{/if}
{if(check_level('mod'))}
<a href="{url./admin/Single/mod/mcode/'.$value->mcode.'/id/'.$value->id.'}{$btnqs}" class="layui-btn layui-btn-xs" >修改</a>
{if([$baidu_zz_token] && !$value->outlink)}
<a href="{url./admin/'.C.'/mod/baiduzz/'.$value->id.'}" class="layui-btn layui-btn-xs layui-btn-primary" >百度普通推送</a>
{/if}
{if([$baidu_ks_token] && !$value->outlink)}
<a href="{url./admin/'.C.'/mod/baiduks/'.$value->id.'}" class="layui-btn layui-btn-xs layui-btn-primary" >百度快速推送</a>
{/if}
{/if}
</td>
</tr>
{/foreach}
</tbody>
</table>
</div>
</div>
</div>
{/if}
{if([$mod])}
<div class="layui-tab layui-tab-brief" lay-filter="tab">
<ul class="layui-tab-title">
<li class="layui-this">单页修改</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
<form action="{url./admin/Single/mod/id/'.[$get.id].'}{$backurl}" method="post" class="layui-form" id="edit">
<input type="hidden" name="formcheck" value="{$formcheck}" >
<div class="layui-tab">
<ul class="layui-tab-title">
<li class="layui-this">基本内容</li>
<li>高级内容</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
<div class="layui-form-item">
<label class="layui-form-label">内容标题 <span class="layui-text-red">*</span></label>
<div class="layui-input-block">
<input type="text" name="title" required lay-verify="required" value="{$content->title}" placeholder="请输入内容标题" class="layui-input">
</div>
</div>
{foreach $extfield(key,value)}
{if($value->type==1)} <!-- 单行文本 -->
<div class="layui-form-item">
<label class="layui-form-label">[value->description]</label>
<div class="layui-input-block">
<input type="text" name="[value->name]" value="{$content->{$value->name}}" placeholder="请输入[value->description]" class="layui-input">
</div>
</div>
{/if}
{if($value->type==2)}<!-- 多行文本 -->
<div class="layui-form-item">
<label class="layui-form-label">[value->description]</label>
<div class="layui-input-block">
<textarea name="[value->name]" class="layui-textarea" placeholder="请输入[value->description]">{php}$name=$value->name;echo str_replace('<br>', "\r\n",$this->vars['content']->$name);{/php}</textarea>
</div>
</div>
{/if}
{if($value->type==3)}<!-- 单选 -->
<div class="layui-form-item">
<label class="layui-form-label">[value->description]</label>
<div class="layui-input-block">
<div>
{php}
$radios=explode(',',$value->value);
$name=$value->name;
foreach ($radios as $value2) {
if($this->vars['content']->$name==$value2){
echo '<input type="radio" name="'.$value->name.'" value="'.$value2.'" title="'.$value2.'" checked>';
}else{
echo '<input type="radio" name="'.$value->name.'" value="'.$value2.'" title="'.$value2.'">';
}
}
{/php}
</div>
</div>
</div>
{/if}
{if($value->type==4)}<!-- 多选 -->
<div class="layui-form-item">
<label class="layui-form-label">[value->description]</label>
<div class="layui-input-block">
<div>
{php}
$checkboxs=explode(',',$value->value);
$name=$value->name;
echo '<input name="'.$value->name.'" type="hidden">';//占位清空
$values=explode(',',$this->vars['content']->$name);
foreach ($checkboxs as $value2) {
if(in_array($value2,$values)){
echo '<input type="checkbox" name="'.$value->name.'[]" value="'.$value2.'" title="'.$value2.'" checked>';
}else{
echo '<input type="checkbox" name="'.$value->name.'[]" value="'.$value2.'" title="'.$value2.'">';
}
}
{/php}
</div>
</div>
</div>
{/if}
{if($value->type==5)}<!-- 图片 -->
<div class="layui-form-item">
<label class="layui-form-label">[value->description]</label>
<div class="layui-input-inline">
<input type="text" name="[value->name]" id="[value->name]" value="{$content->{$value->name}}" placeholder="请上传[value->description]" class="layui-input">
</div>
<button type="button" class="layui-btn upload watermark" data-des="[value->name]">
<i class="layui-icon">&#xe67c;</i>上传图片
</button>
{php}$name=$value->name; {/php}
<div id="[value->name]_box" class="pic"><dl><dt>{if([$content]->$name)}<img src='{SITE_DIR}{$content->{$value->name}}' data-url="{$content->{$value->name}}"></dt><dd>删除</dd></dl>{/if}</div>
</div>
{/if}
{if($value->type==6)}<!-- 文件 -->
<div class="layui-form-item">
<label class="layui-form-label">[value->description]</label>
<div class="layui-input-inline">
<input type="text" name="[value->name]" id="[value->name]" value="{$content->{$value->name}}" placeholder="请上传[value->description]" class="layui-input">
</div>
<button type="button" class="layui-btn file" data-des="[value->name]">
<i class="layui-icon">&#xe67c;</i>上传文件
</button>
</div>
{/if}
{if($value->type==7)}<!-- 日期 -->
<div class="layui-form-item">
<label class="layui-form-label">[value->description]</label>
<div class="layui-input-block">
<input type="text" name="[value->name]" value="{$content->{$value->name}}" readonly placeholder="请选择[value->description]" class="layui-input datetime">
</div>
</div>
{/if}
{if($value->type==8)}<!-- 编辑器 -->
<div class="layui-form-item">
<label class="layui-form-label">[value->description]</label>
<div class="layui-input-block">
{php}
$name=@$value->name;
{/php}
<script type="text/plain" id="editor_[value->name]" name="[value->name]" style="width:100%;height:240px;">{fun=decode_string([$content->$name])}</script>
<script>
//初始化编辑器
$(document).ready(function (e) {
var ue = UE.getEditor('editor_[value->name]',{
maximumWords:10000
});
})
</script>
</div>
</div>
{/if}
{if($value->type==9)}<!-- 下拉 -->
<div class="layui-form-item">
<label class="layui-form-label">[value->description]</label>
<div class="layui-input-block">
<select name="[value->name]">
{php}
$selects=explode(',',$value->value);
$name=$value->name;
foreach ($selects as $value2) {
if($this->vars['content']->$name==$value2){
echo '<option value="'.$value2.'" selected>'.$value2.'</option>';
}else{
echo '<option value="'.$value2.'">'.$value2.'</option>';
}
}
{/php}
</select>
</div>
</div>
{/if}
{/foreach}
<div class="layui-form-item">
<label class="layui-form-label">内容</label>
<div class="layui-input-block">
<script type="text/plain" id="editor" name="content" style="width:100%;height:240px;">{fun=decode_string([$content->content])}</script>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">tags</label>
<div class="layui-input-block">
<input type="text" name="tags" placeholder="请输入文章tag英文逗号隔开" value="{$content->tags}" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">作者</label>
<div class="layui-input-block">
<input type="text" name="author" placeholder="请输入作者" value="{$content->author}" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">来源</label>
<div class="layui-input-block">
<input type="text" name="source" placeholder="请输入来源" value="{$content->source}" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">缩略图</label>
<div class="layui-input-inline">
<input type="text" name="ico" id="ico" value="{$content->ico}" placeholder="请上传缩略图" class="layui-input">
</div>
<button type="button" class="layui-btn upload watermark" data-des="ico">
<i class="layui-icon">&#xe67c;</i>上传图片
</button>
<div id="ico_box" class="pic addedit">{if([$content->ico])}<dl><dt><img src="{SITE_DIR}{$content->ico}" data-url="{$content->ico}"></dt><dd>删除</dd></dl>{/if}</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">轮播多图</label>
<div class="layui-input-inline">
<input type="text" name="pics" id="pics" value="{$content->pics}" placeholder="请上传轮播多图" class="layui-input">
</div>
<button type="button" class="layui-btn uploads watermark" data-des="pics">
<i class="layui-icon">&#xe67c;</i>上传多图
</button>
<div id="pics_box" class="pic addedit">
<dl></dl> <!-- 规避空内容拖动bug -->
{php}
if([$content->pics]){
$pics=explode(',',[$content->pics]);
}else{
$pics = array();
}
if([$content->picstitle]){
$picstitle=explode(',',[$content->picstitle]);
}else{
$picstitle = array();
}
foreach ($pics as $key=>$value) {
//需要留一个空,不然被解析为标签了
echo "<dl><dt><img src='".SITE_DIR.$value."' data-url='".$value."'></dt><dd>删除</dd><dt><input type='text' value='".$picstitle[$key ]."' name='picstitle[]' style='width:95%' /></dt></dl>";
}
{/php}
</div>
</div>
</div>
<div class="layui-tab-item ">
<div class="layui-form-item">
<label class="layui-form-label">标题颜色</label>
<div class="layui-input-inline">
<input type="text" name="titlecolor" value="{$content->titlecolor}" placeholder="请选择标题颜色" class="layui-input jscolor {hash:true}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">副标题</label>
<div class="layui-input-block">
<input type="text" name="subtitle" value="{$content->subtitle}" placeholder="请输入副标题" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">时间</label>
<div class="layui-input-inline">
<input type="text" name="date" value="{$content->date}" readonly placeholder="请选择发布时间" class="layui-input datetime">
</div>
<div class="layui-form-mid layui-word-aux">温馨提示:单页不支持定时发布!</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">附件</label>
<div class="layui-input-inline">
<input type="text" name="enclosure" id="enclosure" value="{$content->enclosure}" placeholder="请上传附件" class="layui-input">
</div>
<button type="button" class="layui-btn file" data-des="enclosure">
<i class="layui-icon">&#xe67c;</i>上传附件
</button>
</div>
<div class="layui-form-item">
<label class="layui-form-label">SEO关键字</label>
<div class="layui-input-block">
<input type="text" name="keywords" value="{$content->keywords}" placeholder="请输入详情页SEO关键字" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">SEO描述</label>
<div class="layui-input-block">
<textarea name="description" placeholder="请输入详情页SEO描述" class="layui-textarea">{$content->description}</textarea>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">状态</label>
<div class="layui-input-block">
<input type="radio" name="status" value="1" title="显示" {if([$content->status]==1)} checked="checked"{/if}>
<input type="radio" name="status" value="0" title="隐藏" {if([$content->status]==0)} checked="checked"{/if}>
</div>
</div>
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit>立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
{fun=get_btn_back()}
</div>
</div>
</form>
</div>
</div>
</div>
{/if}
</div>
<style>.placeHolder {border:dashed 2px gray; }</style>
<script type="text/javascript" src="{APP_THEME_DIR}/js/jquery.dragsort-0.5.2.min.js"></script>
<script type="text/javascript">
$("#pics_box").dragsort({
dragSelector: "dl",
dragSelectorExclude: "input,textarea,dd",
dragBetween: false,
dragEnd: saveOrder,
placeHolderTemplate: "<dl class='placeHolder'><dt></dt></dl>"
});
function saveOrder() {
var data = $("#pics_box dl dt img").map(function() {
return $(this).data("url");
}).get();
$("input[name=pics]").val(data.join(","))
};
</script>
<script type="text/javascript" src="{APP_THEME_DIR}/js/jscolor.js"></script>
{include file='common/ueditor.html'}
{include file='common/foot.html'}

View File

@@ -0,0 +1,107 @@
{include file='common/head.html'}
<div class="layui-body">
<div class="layui-tab layui-tab-brief" lay-filter="tab">
<ul class="layui-tab-title">
<li class="layui-this">站点信息</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
<form action="{url./admin/Site/mod}" method="post" class="layui-form">
<input type="hidden" name="formcheck" value="{$formcheck}" >
<div class="layui-form-item">
<label class="layui-form-label">站点标题</label>
<div class="layui-input-block">
<input type="text" name="title" value="{$sites->title}" placeholder="请输入站点标题" class="layui-input">
</div>
</div>
<!-- <div class="layui-form-item">
<label class="layui-form-label">站点副标题</label>
<div class="layui-input-block">
<input type="text" name="subtitle" value="{$sites->subtitle}" placeholder="请输入站点副标题" class="layui-input">
</div>
</div>-->
<div class="layui-form-item">
<label class="layui-form-label">站点域名</label>
<div class="layui-input-block">
<input type="text" name="domain" value="{$sites->domain}" placeholder="请输入站点域名" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">站点LOGO</label>
<div class="layui-input-inline">
<input type="text" name="logo" id="logo" value="{$sites->logo}" placeholder="请上传站点LOGO图" class="layui-input">
</div>
<button type="button" class="layui-btn upload" data-des="logo">
<i class="layui-icon">&#xe67c;</i>上传图片
</button>
<div id="logo_box" class="pic"><dl><dt>{if(@[$sites->logo])}<img src="{SITE_DIR}{$sites->logo}" data-url="{$sites->logo}"></dt><dd>删除</dd></dl>{/if}</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">站点关键字</label>
<div class="layui-input-block">
<input type="text" name="keywords" value="{$sites->keywords}" placeholder="请输入站点关键字" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">站点描述</label>
<div class="layui-input-block">
<textarea name="description" placeholder="请输入站点描述" class="layui-textarea">{$sites->description}</textarea>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">站点备案</label>
<div class="layui-input-block">
<input type="text" name="icp" value="{$sites->icp}" placeholder="请输入站点备案" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">站点模板</label>
<div class="layui-input-block">
<select name="theme">
{foreach $themes(key,value)}
{if($value == [$sites->theme])}
<option value="[value]" selected='selected'>[value]</option>
{else}
<option value="[value]">[value]</option>
{/if}
{/foreach}
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">统计代码</label>
<div class="layui-input-block">
<textarea name="statistical" placeholder="请输入统计代码" class="layui-textarea">{$sites->statistical}</textarea>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">尾部信息</label>
<div class="layui-input-block">
<textarea name="copyright" placeholder="请输入尾部信息" class="layui-textarea">{$sites->copyright}</textarea>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit>立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
{include file='common/foot.html'}

View File

@@ -0,0 +1,78 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="renderer" content="webkit">
<title>{CMSNAME}管理中心-V{APP_VERSION}-{RELEASE_TIME}</title>
<link rel="shortcut icon" href="{SITE_DIR}/favicon.ico" type="image/x-icon">
<link rel="stylesheet" href="{APP_THEME_DIR}/layui/css/layui.css?v=v2.5.4">
<link rel="stylesheet" href="{APP_THEME_DIR}/font-awesome/css/font-awesome.min.css?v=v4.7.0" type="text/css">
<link rel="stylesheet" href="{APP_THEME_DIR}/css/login.css?v=v1.1.6">
<script type="text/javascript" src="{APP_THEME_DIR}/js/jquery-1.12.4.min.js"></script>
</head>
<body>
<div class="user-login" >
<div class="user-login-main">
<div class="user-login-header">
<h2>
网站管理中心
</h2>
<p>高效、简洁、强悍的PHP企业网站管理系统</p>
</div>
<form action="{url./admin/Index/login}" onsubmit="return false" class="layui-form" id="dologin">
<input type="hidden" name="formcheck" id="formcheck" value="{$formcheck}" >
<div class="user-login-box">
<div class="layui-form-item">
<label class="user-login-icon layui-icon layui-icon-username"></label>
<input name="username" id="username" type="text" lay-verify="required" placeholder="用户名" autocomplete="off" class="layui-input">
</div>
<div class="layui-form-item">
<label class="user-login-icon layui-icon layui-icon-password"></label>
<input name="password" id="password" type="password" lay-verify="required" placeholder="密码" autocomplete="off" class="layui-input">
</div>
{if([$config.admin_check_code])}
<div class="layui-form-item">
<div class="layui-row">
<div class="layui-col-xs7 layui-col-sm8">
<label class="user-login-icon layui-icon layui-icon-vercode" ></label>
<input name="checkcode" id="checkcode" type="text" lay-verify="required" placeholder="验证码" autocomplete="off" class="layui-input">
</div>
<div class="layui-col-xs5 layui-col-sm4">
<div style="margin-left: 10px;">
<img title="点击刷新" src="{CORE_DIR}/code.php" class="user-login-codeimg" id="codeimg" onclick="this.src='{CORE_DIR}/code.php?'+Math.round(Math.random()*10);" />
</div>
</div>
</div>
</div>
{/if}
<div class="layui-form-item">
<button class="layui-btn layui-btn-fluid" lay-submit lay-filter="login-submit" >登 录</button>
</div>
<div style="color:red;" id="note"></div>
</div>
</form>
</div>
<div class="layui-trans user-login-footer">
<p>© 2018-{fun=date('Y')}</p>
</div>
</div>
<script type="text/javascript" src="{APP_THEME_DIR}/layui/layui.all.js?v=v2.5.4"></script>
<script type="text/javascript" src="{APP_THEME_DIR}/js/mylayui.js?v=v1.1.6"></script>
<!-- 让IE8/9支持媒体查询从而兼容栅格 -->
<!--[if lt IE 9]>
<script src="https://cdn.staticfile.org/html5shiv/r29/html5.min.js"></script>
<script src="https://cdn.staticfile.org/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
</body>
</html>

View File

@@ -0,0 +1,806 @@
{include file='common/head.html'}
<div class="layui-body">
<div class="layui-tab layui-tab-brief" lay-filter="tab">
<ul class="layui-tab-title">
<li class="layui-this" lay-id="t1">基本配置</li>
<li lay-id="t2">邮件通知</li>
<li lay-id="t3">百度接口</li>
<li lay-id="t4">WebAPI</li>
<li lay-id="t5">图片水印</li>
<li lay-id="t6">安全配置</li>
<li lay-id="t7">URL规则</li>
<li lay-id="t8">标题样式</li>
<li lay-id="t9">会员配置</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
<form action="{url./admin/Config/index}" method="post" class="layui-form">
<input type="hidden" name="formcheck" value="{$formcheck}" >
<div class="layui-form-item">
<label class="layui-form-label">网站状态</label>
<div class="layui-input-block">
<input type="radio" name="close_site" value="1" {if([$configs.close_site.value]==1)} checked="checked" {/if} title="关闭">
<input type="radio" name="close_site" value="0" {if([$configs.close_site.value]==0)} checked="checked" {/if} title="开启">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">关站提示</label>
<div class="layui-input-inline">
<textarea name="close_site_note" placeholder="" class="layui-textarea">{$configs.close_site_note.value}</textarea>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">独立手机版</label>
<div class="layui-input-block">
<input type="radio" name="open_wap" value="1" {if([$configs.open_wap.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="open_wap" value="0" {if([$configs.open_wap.value]==0)} checked="checked" {/if} title="禁用">
<span class="layui-icon layui-icon-about tips" data-content="使用响应式模板的用户请不要开启!"></span>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">手机版域名绑定</label>
<div class="layui-input-inline">
<input type="text" name="wap_domain" value="{$configs.wap_domain.value}" placeholder="如m.baidu.com" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">动态缓存</label>
<div class="layui-input-block">
<input type="radio" name="tpl_html_cache" value="1" {if([$configs.tpl_html_cache.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="tpl_html_cache" value="0" {if([$configs.tpl_html_cache.value]==0)} checked="checked" {/if} title="禁用">
<span class="layui-icon layui-icon-about tips" data-content="本功能效果接近生成静态,开启后将提高前端访问速度及并发能力!"></span>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">缓存有效期(秒)</label>
<div class="layui-input-inline">
<input type="text" name="tpl_html_cache_time" value="{$configs.tpl_html_cache_time.value}" placeholder="请输入缓存有效期(秒)" class="layui-input">
</div>
<div class="layui-form-mid layui-word-aux"></div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">Gzip页面压缩</label>
<div class="layui-input-block">
<input type="radio" name="gzip" value="1" {if([$configs.gzip.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="gzip" value="0" {if([$configs.gzip.value]==0)} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">会话文件路径</label>
<div class="layui-input-block">
<input type="radio" name="session_in_sitepath" value="1" {if([$configs.session_in_sitepath.value]==1)} checked="checked" {/if} title="站内">
<input type="radio" name="session_in_sitepath" value="0" {if([$configs.session_in_sitepath.value]==0)} checked="checked" {/if} title="系统">
<span class="layui-icon layui-icon-about tips" data-content="站内则使用站点下runtime路径系统则使用操作系统的缓存路径"></span>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">跨语言自动切换</label>
<div class="layui-input-block">
<input type="radio" name="lgautosw" value="1" {if([$configs.lgautosw.value]=='1'||[$configs.lgautosw.value]=='')} checked="checked" {/if} title="启用">
<input type="radio" name="lgautosw" value="0" {if([$configs.lgautosw.value]=='0')} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">自动转HTTPS</label>
<div class="layui-input-block">
<input type="radio" name="to_https" value="1" {if([$configs.to_https.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="to_https" value="0" {if([$configs.to_https.value]==0)} checked="checked" {/if} title="禁用">
<span class="layui-icon layui-icon-about tips" data-content="访问非HTPPS地址时自动跳转"></span>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">自动转主域名</label>
<div class="layui-input-block">
<input type="radio" name="to_main_domain" value="1" {if([$configs.to_main_domain.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="to_main_domain" value="0" {if([$configs.to_main_domain.value]==0)} checked="checked" {/if} title="禁用">
<span class="layui-icon layui-icon-about tips" data-content="访问非主域名地址时自动跳转!"></span>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">网站主域名</label>
<div class="layui-input-inline">
<input type="text" name="main_domain" value="{$configs.main_domain.value}" placeholder="如www.baidu.com" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">分页数字条数量</label>
<div class="layui-input-inline">
<input type="text" name="pagenum" value="{$configs.pagenum.value}" placeholder="请输入前端分页数字条显示数量" class="layui-input">
</div>
<div class="layui-form-mid layui-word-aux"></div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">内链替换次数</label>
<div class="layui-input-inline">
<input type="text" name="content_tags_replace_num" value="{$configs.content_tags_replace_num.value}" placeholder="请输入文章内链替换次数默认3次" class="layui-input">
</div>
<div class="layui-form-mid layui-word-aux"></div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">敏感词过滤</label>
<div class="layui-input-inline">
<textarea name="content_keyword_replace" placeholder="请输入需要过滤的关键词,多个之间逗号隔开" class="layui-textarea">{$configs.content_keyword_replace.value}</textarea>
<div class="layui-form-mid layui-word-aux">注:多个敏感词之间用逗号隔开!</div>
</div>
</div>
{if(LICENSE<2)}
<div class="layui-form-item">
<label class="layui-form-label">系统授权码</label>
<div class="layui-input-inline">
<input type="text" name="sn" value="{$configs.sn.value}" placeholder="请输入授权码,多个授权码用逗号隔开" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">授权码手机</label>
<div class="layui-input-inline">
<input type="text" name="sn_user" value="{$configs.sn_user.value}" placeholder="请购买了万能授权码的用户填写" class="layui-input">
</div>
</div>
{/if}
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit name="submit" value="basic">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
<div class="layui-tab-item">
<form action="{url./admin/Config/index}" method="post" class="layui-form">
<input type="hidden" name="formcheck" value="{$formcheck}" >
<div class="layui-form-item">
<label class="layui-form-label">服务器状态 </label>
<div class="layui-input-block" style="line-height:36px;">
stream_socket_client函数<i class="layui-icon layui-icon-ok-circle" style="color: {php}echo function_exists('stream_socket_client')?'#5FB878':'#f2f2f2';{/php}"></i>&nbsp;&nbsp;&nbsp;
fsockopen函数 <i class="layui-icon layui-icon-ok-circle" style="color: {php}echo function_exists('fsockopen')?'#5FB878':'#f2f2f2';{/php}"></i>
<span class="layui-icon layui-icon-about tips" data-content="至少需要支持其中一个函数才能正常使用!"></span>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">SMTP服务器</label>
<div class="layui-input-inline">
<input type="text" name="smtp_server" value="{$configs.smtp_server.value}" placeholder="请输入SMTP服务器" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">SMTP端口</label>
<div class="layui-input-inline">
<input type="text" name="smtp_port" value="{$configs.smtp_port.value}" placeholder="请输入SMTP端口,一般SSL为465普通为25" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">是否为SSL</label>
<div class="layui-input-block">
<input type="radio" name="smtp_ssl" value="1" {if([$configs.smtp_ssl.value]==1)} checked="checked" {/if} title="是">
<input type="radio" name="smtp_ssl" value="0" {if([$configs.smtp_ssl.value]==0)} checked="checked" {/if} title="否">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">邮箱账号</label>
<div class="layui-input-inline">
<input type="text" name="smtp_username" value="{$configs.smtp_username.value}" placeholder="请输入邮箱账号" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">邮箱密码</label>
<div class="layui-input-inline">
<input type="password" name="smtp_password" value="{$configs.smtp_password.value}" placeholder="请输入邮箱密码或邮箱授权码" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">测试账号</label>
<div class="layui-input-inline">
<input type="text" name="smtp_username_test" id="smtp_username_test" value="{$configs.smtp_username_test.value}" placeholder="请输入用于接受测试邮件的账号" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">留言发送邮件</label>
<div class="layui-input-block">
<input type="radio" name="message_send_mail" value="1" {if([$configs.message_send_mail.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="message_send_mail" value="0" {if([$configs.message_send_mail.value]==0)} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">表单发送邮件</label>
<div class="layui-input-block">
<input type="radio" name="form_send_mail" value="1" {if([$configs.form_send_mail.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="form_send_mail" value="0" {if([$configs.form_send_mail.value]==0)} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">评论发送邮件</label>
<div class="layui-input-block">
<input type="radio" name="comment_send_mail" value="1" {if([$configs.comment_send_mail.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="comment_send_mail" value="0" {if([$configs.comment_send_mail.value]==0)} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">信息接收邮箱</label>
<div class="layui-input-inline">
<input type="text" name="message_send_to" value="{$configs.message_send_to.value}" placeholder="请输入信息接收邮箱" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit name="submit" value="email">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
<a href="{url./admin/Config/index/action/sendemail}" onclick="return sendtest(this,'#smtp_username_test')" class="layui-btn layui-btn-primary">发送测试邮件</a>
</div>
</div>
<script>
function sendtest(obj,to){
$(obj).attr('href',$(obj).attr('href')+'&to='+$(to).val());
return true;
}
</script>
</form>
</div>
<div class="layui-tab-item">
<form action="{url./admin/Config/index}" method="post" class="layui-form">
<input type="hidden" name="formcheck" value="{$formcheck}" >
<div class="layui-form-item">
<label class="layui-form-label">普通收录token</label>
<div class="layui-input-inline">
<input type="text" name="baidu_zz_token" value="{$configs.baidu_zz_token.value}" placeholder="请输入普通收录token" class="layui-input">
</div>
<span class="layui-icon layui-icon-about tips" data-content="请到百度站长中心获取!"></span>
</div>
<div class="layui-form-item">
<label class="layui-form-label">快速收录token</label>
<div class="layui-input-inline">
<input type="text" name="baidu_ks_token" value="{$configs.baidu_ks_token.value}" placeholder="请输入快速收录token" class="layui-input">
</div>
<span class="layui-icon layui-icon-about tips" data-content="请到百度站长中心获取!"></span>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit name="submit" value="baidu">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
<div class="layui-tab-item">
<form action="{url./admin/Config/index}" method="post" class="layui-form">
<input type="hidden" name="formcheck" value="{$formcheck}" >
<div class="layui-form-item">
<label class="layui-form-label">API状态</label>
<div class="layui-input-block">
<input type="radio" name="api_open" value="1" {if(@[$configs.api_open.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="api_open" value="0" {if(@[$configs.api_open.value]==0)} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">API强制认证</label>
<div class="layui-input-block">
<input type="radio" name="api_auth" value="1" {if(@[$configs.api_auth.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="api_auth" value="0" {if(@[$configs.api_auth.value]==0)} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">API认证用户</label>
<div class="layui-input-inline">
<input type="text" name="api_appid" value="{$configs.api_appid.value}" placeholder="请输入API认证用户名" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">API认证密钥</label>
<div class="layui-input-inline">
<input type="password" name="api_secret" value="{$configs.api_secret.value}" placeholder="请输入API认证密钥" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit name="submit" value="api">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
<div class="layui-tab-item">
<form action="{url./admin/Config/index}" method="post" class="layui-form">
<input type="hidden" name="formcheck" value="{$formcheck}" >
<div class="layui-form-item">
<label class="layui-form-label">状态</label>
<div class="layui-input-block">
<input type="radio" name="watermark_open" value="1" {if(@[$configs.watermark_open.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="watermark_open" value="0" {if(@[$configs.watermark_open.value]==0)} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">水印文字</label>
<div class="layui-input-inline">
<input type="text" name="watermark_text" value="{$configs.watermark_text.value}" placeholder="请输入水印文字PbootCMS" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">文字字体</label>
<div class="layui-input-inline">
<input type="text" name="watermark_text_font" id="watermark_text_font" value="{$configs.watermark_text_font.value}" placeholder="请上传水印文字字体" class="layui-input">
</div>
<button type="button" class="layui-btn file" data-des="watermark_text_font">
<i class="layui-icon">&#xe67c;</i>上传字体
</button>
</div>
<div class="layui-form-item">
<label class="layui-form-label">文字大小</label>
<div class="layui-input-inline">
<input type="text" name="watermark_text_size" value="{$configs.watermark_text_size.value}" placeholder="请输入水印文字大小20" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">文字颜色</label>
<div class="layui-input-inline">
<input type="text" name="watermark_text_color" value="{$configs.watermark_text_color.value}" placeholder="请输入水印文字颜色100,100,100" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">水印图片</label>
<div class="layui-input-inline">
<input type="text" name="watermark_pic" id="watermark_pic" value="{$configs.watermark_pic.value}" placeholder="请上传水印图片,优先文字水印" class="layui-input">
</div>
<button type="button" class="layui-btn upload" data-des="watermark_pic">
<i class="layui-icon">&#xe67c;</i>上传图片
</button>
<div id="watermark_pic_box" class="pic"><dl><dt>{if(@[$configs.watermark_pic.value])}<img src="{SITE_DIR}{$configs.watermark_pic.value}" data-url="{$configs.watermark_pic.value}"></dt><dd>删除</dd></dl>{/if}</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">水印位置</label>
<div class="layui-input-block">
<input type="radio" name="watermark_position" value="1" {if(@[$configs.watermark_position.value]==1)} checked="checked" {/if} title="左上">
<input type="radio" name="watermark_position" value="2" {if(@[$configs.watermark_position.value]==2)} checked="checked" {/if} title="右上">
<input type="radio" name="watermark_position" value="3" {if(@[$configs.watermark_position.value]==3)} checked="checked" {/if} title="左下">
<input type="radio" name="watermark_position" value="4" {if(@[$configs.watermark_position.value]==4)} checked="checked" {/if} title="右下">
<input type="radio" name="watermark_position" value="5" {if(@[$configs.watermark_position.value]==5)} checked="checked" {/if} title="中间">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit name="submit" value="watermark">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
<div class="layui-tab-item">
<form action="{url./admin/Config/index}" method="post" class="layui-form">
<input type="hidden" name="formcheck" value="{$formcheck}" >
<div class="layui-form-item">
<label class="layui-form-label">留言功能</label>
<div class="layui-input-block">
<input type="radio" name="message_status" value="1" {if([$configs.message_status.value]=='1'||[$configs.message_status.value]=='')} checked="checked" {/if} title="启用">
<input type="radio" name="message_status" value="0" {if([$configs.message_status.value]=='0')} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">留言验证码</label>
<div class="layui-input-block">
<input type="radio" name="message_check_code" value="1" {if([$configs.message_check_code.value]=='1'||[$configs.message_check_code.value]=='')} checked="checked" {/if} title="启用">
<input type="radio" name="message_check_code" value="0" {if([$configs.message_check_code.value]=='0')} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">留言审核</label>
<div class="layui-input-block">
<input type="radio" name="message_verify" value="1" {if([$configs.message_verify.value]=='1'||[$configs.message_verify.value]=='')} checked="checked" {/if} title="启用">
<input type="radio" name="message_verify" value="0" {if([$configs.message_verify.value]=='0')} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">留言需登录</label>
<div class="layui-input-block">
<input type="radio" name="message_rqlogin" value="1" {if([$configs.message_rqlogin.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="message_rqlogin" value="0" {if([$configs.message_rqlogin.value]==0)} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">表单功能</label>
<div class="layui-input-block">
<input type="radio" name="form_status" value="1" {if([$configs.form_status.value]=='1'||[$configs.form_status.value]=='')} checked="checked" {/if} title="启用">
<input type="radio" name="form_status" value="0" {if([$configs.form_status.value]=='0')} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">表单验证码</label>
<div class="layui-input-block">
<input type="radio" name="form_check_code" value="1" {if([$configs.form_check_code.value]=='1'||[$configs.form_check_code.value]=='')} checked="checked" {/if} title="启用">
<input type="radio" name="form_check_code" value="0" {if([$configs.form_check_code.value]=='0')} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">模板子目录</label>
<div class="layui-input-inline">
<input type="text" name="tpl_html_dir" value="{$configs.tpl_html_dir.value}" placeholder="首次请手动移动模板文件到填写的目录!" class="layui-input">
</div>
<span class="layui-icon layui-icon-about tips" data-content="一定程度上防盗,如填 html则默认模板情况下路径为 default/html 目录!"></span>
</div>
<div class="layui-form-item">
<label class="layui-form-label">IP黑名单</label>
<div class="layui-input-inline">
<textarea name="ip_deny" placeholder="请输入需要禁止访问的IP多个之间逗号隔开IP地址支持使用/掩码位数模式192.168.1.0/24, 192.168.2.100" class="layui-textarea">{$configs.ip_deny.value}</textarea>
</div>
<span class="layui-icon layui-icon-about tips" data-content="请输入需要禁止访问的IP多个之间逗号隔开IP地址支持使用/掩码位数模式192.168.1.0/24, 192.168.2.100"></span>
</div>
<div class="layui-form-item">
<label class="layui-form-label">IP白名单</label>
<div class="layui-input-inline">
<textarea name="ip_allow" placeholder="请输入需要允许访问的IP多个之间逗号隔开IP地址支持使用/掩码位数模式192.168.1.0/24, 192.168.2.100" class="layui-textarea">{$configs.ip_allow.value}</textarea>
</div>
<span class="layui-icon layui-icon-about tips" data-content="请输入需要允许访问的IP多个之间逗号隔开IP地址支持使用/掩码位数模式192.168.1.0/24,192.168.2.100"></span>
</div>
<hr>
<div class="layui-form-item">
<label class="layui-form-label">后台验证码</label>
<div class="layui-input-block">
<input type="radio" name="admin_check_code" value="1" {if([$configs.admin_check_code.value]=='1'||[$configs.admin_check_code.value]=='')} checked="checked" {/if} title="启用">
<input type="radio" name="admin_check_code" value="0" {if([$configs.admin_check_code.value]=='0')} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">后台登录阀值</label>
<div class="layui-input-inline">
<input type="text" name="lock_count" value="{$configs.lock_count.value}" placeholder="请输入后台登录失败几次后锁定IP默认5次" class="layui-input">
</div>
<div class="layui-form-mid layui-word-aux"></div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">失败锁定时间</label>
<div class="layui-input-inline">
<input type="text" name="lock_time" value="{$configs.lock_time.value}" placeholder="请输入后台登录异常锁定时间默认为900秒" class="layui-input">
</div>
<div class="layui-form-mid layui-word-aux"></div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit name="submit" value="security">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
<div class="layui-tab-item">
<form action="{url./admin/Config/index}" method="post" class="layui-form">
<input type="hidden" name="formcheck" value="{$formcheck}" >
<div class="layui-form-item">
<label class="layui-form-label">地址模式</label>
<div class="layui-input-block">
<P>
<input type="radio" name="url_rule_type" value="1" {if([$configs.url_rule_type.value]==1)} checked="checked" {/if} title="普通模式,类似:/index.php/product/1.html">
<span class="layui-icon layui-icon-about tips" data-content="基本模式需要服务器支持pathinfo,特别是nginx下pathinfo要手动配置"></span>
</P>
<P>
<input type="radio" name="url_rule_type" value="2" {if([$configs.url_rule_type.value]==2)} checked="checked" {/if} title="伪静态模式,类似:/product/1.html">
<span class="layui-icon layui-icon-about tips" data-content="伪静态时需要服务器环境的支持,并需要添加伪静态规则!"></span>
</P>
<P>
<input type="radio" name="url_rule_type" value="3" {if([$configs.url_rule_type.value]==3||![$configs.url_rule_type.value])} checked="checked" {/if} title="兼容模式,类似:/?product/1.html">
</P>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">栏目显示后缀</label>
<div class="layui-input-block">
<input type="radio" name="url_rule_sort_suffix" value="1" {if([$configs.url_rule_sort_suffix.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="url_rule_sort_suffix" value="0" {if([$configs.url_rule_sort_suffix.value]==0)} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit name="submit" value="urlrule">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
<div class="layui-tab-item">
<form action="{url./admin/Config/index}" method="post" class="layui-form">
<input type="hidden" name="formcheck" value="{$formcheck}" >
<div class="layui-form-item">
<label class="layui-form-label">常用组合标签: </label>
<div class="layui-input-block" style="line-height:36px;">
<p>全局标签:{pboot:sitetitle}站点标题、{pboot:sitesubtitle}站点副标题</p>
<p>列表或内容页:{sort:name}栏目名称、{sort:title}栏目标题</p>
<p>内容页:{content:title}内容标题</p>
<p>搜索结果页:{pboot:keyword}搜索关键字</p>
<p>个人中心:{user:nickname}会员昵称</p>
<p>例如定义内容页样式:{content:title}-{sort:name}-{pboot:sitetitle}-{pboot:sitesubtitle}</p>
<p>以下配置参数不设置时将使用系统默认规则。</p>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">首页</label>
<div class="layui-input-block">
<input type="text" name="index_title" value="{$configs.index_title.value}" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">专题页</label>
<div class="layui-input-block">
<input type="text" name="about_title" value="{$configs.about_title.value}" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">列表页</label>
<div class="layui-input-block">
<input type="text" name="list_title" value="{$configs.list_title.value}" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">内容页</label>
<div class="layui-input-block">
<input type="text" name="content_title" value="{$configs.content_title.value}" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">搜索结果页</label>
<div class="layui-input-block">
<input type="text" name="search_title" value="{$configs.search_title.value}" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">会员注册页</label>
<div class="layui-input-block">
<input type="text" name="register_title" value="{$configs.register_title.value}" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">会员登录页</label>
<div class="layui-input-block">
<input type="text" name="login_title" value="{$configs.login_title.value}" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">个人中心页</label>
<div class="layui-input-block">
<input type="text" name="ucenter_title" value="{$configs.ucenter_title.value}" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">资料修改页</label>
<div class="layui-input-block">
<input type="text" name="umodify_title" value="{$configs.umodify_title.value}" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">其它页</label>
<div class="layui-input-block">
<input type="text" name="other_title" value="{$configs.other_title.value}" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit name="submit" value="pagetitle">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
<div class="layui-tab-item">
<form action="{url./admin/Config/index}" method="post" class="layui-form">
<input type="hidden" name="formcheck" value="{$formcheck}" >
<div class="layui-form-item">
<label class="layui-form-label">会员注册</label>
<div class="layui-input-block">
<input type="radio" name="register_status" value="1" {if([$configs.register_status.value]=='1'||[$configs.register_status.value]=='')} checked="checked" {/if} title="启用">
<input type="radio" name="register_status" value="0" {if([$configs.register_status.value]=='0')} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">会员注册类型</label>
<div class="layui-input-block">
<input type="radio" name="register_type" value="1" {if([$configs.register_type.value]=='1'||[$configs.register_type.value]=='')} checked="checked" {/if} title="用户名">
<input type="radio" name="register_type" value="2" {if([$configs.register_type.value]=='2')} checked="checked" {/if} title="邮箱账号">
<input type="radio" name="register_type" value="3" {if([$configs.register_type.value]=='3')} checked="checked" {/if} title="手机号码">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">会员注册验证码</label>
<div class="layui-input-block">
<input type="radio" name="register_check_code" value="0" {if([$configs.register_check_code.value]=='0')} checked="checked" {/if} title="禁用">
<input type="radio" name="register_check_code" value="1" {if([$configs.register_check_code.value]=='1'||[$configs.register_check_code.value]=='')} checked="checked" {/if} title="普通验证码">
<input type="radio" name="register_check_code" value="2" {if([$configs.register_check_code.value]=='2')} checked="checked" {/if} title="邮箱验证码">
<!-- <input type="radio" name="register_check_code" value="3" {if([$configs.register_check_code.value]=='3')} checked="checked" {/if} title="短信验证码"> -->
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">会员注册审核</label>
<div class="layui-input-block">
<input type="radio" name="register_verify" value="1" {if([$configs.register_verify.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="register_verify" value="0" {if([$configs.register_verify.value]==0)} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">会员登录</label>
<div class="layui-input-block">
<input type="radio" name="login_status" value="1" {if([$configs.login_status.value]=='1'||[$configs.login_status.value]=='')} checked="checked" {/if} title="启用">
<input type="radio" name="login_status" value="0" {if([$configs.login_status.value]=='0')} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">会员登录验证码</label>
<div class="layui-input-block">
<input type="radio" name="login_check_code" value="1" {if([$configs.login_check_code.value]=='1'||[$configs.login_check_code.value]=='')} checked="checked" {/if} title="启用">
<input type="radio" name="login_check_code" value="0" {if([$configs.login_check_code.value]=='0')} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">不等待跳登录</label>
<div class="layui-input-block">
<input type="radio" name="login_no_wait" value="1" {if([$configs.login_no_wait.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="login_no_wait" value="0" {if([$configs.login_no_wait.value]==0)} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">评论功能</label>
<div class="layui-input-block">
<input type="radio" name="comment_status" value="1" {if([$configs.comment_status.value]=='1'||[$configs.comment_status.value]=='')} checked="checked" {/if} title="启用">
<input type="radio" name="comment_status" value="0" {if([$configs.comment_status.value]=='0')} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">匿名评论</label>
<div class="layui-input-block">
<input type="radio" name="comment_anonymous" value="1" {if([$configs.comment_anonymous.value]==1)} checked="checked" {/if} title="启用">
<input type="radio" name="comment_anonymous" value="0" {if([$configs.comment_anonymous.value]==0)} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">评论验证码</label>
<div class="layui-input-block">
<input type="radio" name="comment_check_code" value="1" {if([$configs.comment_check_code.value]=='1'||[$configs.comment_check_code.value]=='')} checked="checked" {/if} title="启用">
<input type="radio" name="comment_check_code" value="0" {if([$configs.comment_check_code.value]=='0')} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">评论审核</label>
<div class="layui-input-block">
<input type="radio" name="comment_verify" value="1" {if([$configs.comment_verify.value]=='1'||[$configs.comment_verify.value]=='')} checked="checked" {/if} title="启用">
<input type="radio" name="comment_verify" value="0" {if([$configs.comment_verify.value]=='0')} checked="checked" {/if} title="禁用">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">会员注册积分</label>
<div class="layui-input-inline">
<input type="text" name="register_score" value="{$configs.register_score.value}" placeholder="请输入会员注册初始积分" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">会员登录积分</label>
<div class="layui-input-inline">
<input type="text" name="login_score" value="{$configs.login_score.value}" placeholder="请输入会员每次登录积分" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">会员默认等级</label>
<div class="layui-input-inline">
<select name="register_gcode">
<option value="">请选择</option>
{foreach $groups(key,value)}
<option value="[value->gcode]" {if([$configs.register_gcode.value]==$value->gcode)}selected{/if}>[value->gname]</option>
{/foreach}
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">允许上传格式</label>
<div class="layui-input-inline">
<input type="text" name="home_upload_ext" value="{$configs.home_upload_ext.value}" placeholder="以英文逗号隔开!" class="layui-input">
</div>
<span class="layui-icon layui-icon-about tips" data-content="以英文逗号隔开默认jpg, jpeg, png, gif, xls, xlsx, doc, docx, ppt, pptx, rar, zip, pdf, txt"></span>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit name="submit" value="member">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
{include file='common/foot.html'}

View File

@@ -0,0 +1,173 @@
{include file='common/head.html'}
<div class="layui-body">
{if(![$dbsecurity]||![$session.pwsecurity])}
<blockquote class="layui-elem-quote layui-text-red" id="note">
{if(![$dbsecurity])}
<p>
<i class="fa fa-info-circle" aria-hidden="true"></i>
您的数据库文件存在安全隐患,可能被下载,请尽快修改数据库路径!<a class="layui-btn layui-btn-sm" href="{url./admin/Index/home}&action=moddb">自动修改</a>
</p>
{/if}
{if(![$session.pwsecurity])}
<p>
<i class="fa fa-info-circle" aria-hidden="true"></i>
您的账号密码为初始密码,存在安全隐患,请尽快修改密码!<a class="layui-btn layui-btn-sm" href="{url./admin/Index/ucenter}">立即修改</a>
</p>
{/if}
</blockquote>
{/if}
<blockquote class="layui-elem-quote">
当前登录用户:{$user_info->username} {$user_info->realname},登录时间:{$user_info->update_time}登录IP{fun=long2ip([$user_info->last_login_ip])},累计登录次数:{$user_info->login_count}
</blockquote>
<fieldset class="layui-elem-field">
<legend>快捷操作</legend>
<div class="layui-field-box">
<div class="layui-row">
{foreach $model_msg(key,value)}
<div class="layui-col-xs6 layui-col-sm4 layui-col-md3 layui-col-lg2">
{if($value->type==1)}
<a href="{url./admin/Single/index/mcode/'.$value->mcode.'}">
{else}
<a href="{url./admin/Content/index/mcode/'.$value->mcode.'}">
{/if}
<dl class="deskbox center-block">
<dt>[value->name]</dt>
<dd>[value->count]</dd>
</dl>
</a>
</div>
{/foreach}
<div class="layui-col-xs6 layui-col-sm4 layui-col-md3 layui-col-lg2">
<a href="{url./admin/Message/index}">
<dl class="deskbox center-block">
<dt>留言</dt>
<dd>{$sum_msg}</dd>
</dl>
</a>
</div>
</div>
</div>
</fieldset>
{if(CMSNAME=='PbootCMS')}
<div class="layui-row layui-col-space10">
<div class="layui-col-xs12 layui-col-md6">
<table class="layui-table table-two">
<thead>
<tr>
<th colspan="2">系统信息</th>
</tr>
</thead>
<tbody>
<tr>
<th width="100">应用版本</th>
<td>PbootCMS V{APP_VERSION}-{RELEASE_TIME}
{if(session('ucode')==10001)}
<a href="{url./admin/Upgrade/index}" class="layui-btn layui-btn-xs" id="check">在线更新</a>
{/if}
</td>
</tr>
<tr>
<th>主机系统</th>
<td>{$server->php_os}</td>
</tr>
<tr>
<th>主机地址</th>
<td>{$server->server_name}{$server->server_addr}:{$server->server_port}</td>
</tr>
<tr>
<th>WEB软件</th>
<td>{$server->server_software}</td>
</tr>
<tr>
<th>PHP版</th>
<td>{$server->php_version}</td>
</tr>
<tr>
<th>数据库驱动</th>
<td>{$server->db_driver}</td>
</tr>
<tr>
<th>文件上传限制</th>
<td>{$server->upload_max_filesize}</td>
</tr>
<tr>
<th>表单提交限制</th>
<td>{$server->post_max_size}</td>
</tr>
</tbody>
</table>
</div>
<div class="layui-col-xs12 layui-col-md6">
<table class="layui-table table-two">
<thead>
<tr>
<th colspan="2">开发信息</th>
</tr>
</thead>
<tbody>
<tr>
<th>系统名称</th>
<td>{CMSNAME}企业网站开发建设管理系统</td>
</tr>
<tr>
<th>官方网站</th>
<td><a href="http://www.pbootcms.com" target="_blank" style="color:#666">www.pbootcms.com</a></td>
</tr>
<tr>
<th>模板下载</th>
<td>
<a href="http://www.adminbuy.cn/" style="color:#666" target="_blank">AB模板网</a>
</td>
</tr>
<tr>
<th>图标下载</th>
<td><a href="http://sc.adminbuy.cn" style="color:#666" target="_blank">图标库</a></td>
</tr>
<tr>
<th>系统开发</th>
<td>星梦</td>
</tr>
<tr>
<th>友情贡献者</th>
<td>
感谢交流群各网友对PbootCMS发展的大力支持
感谢LayUI提供的前端框架
感谢百度提供的富文本编辑器;
感谢星梦开发团队的日夜奋斗。
</td>
</tr>
</tbody>
</table>
</div>
</div>
{/if}
</div>
<script>
$.ajax({
type: 'GET',
url: 'https://www.pbootcms.com/index.php?p=/upgrade/check&version={APP_VERSION}.{RELEASE_TIME}.{$revise}&branch={$branch}&snuser={$snuser}&site={$site}',
dataType: 'json',
success: function (response, status) {
if(response.code==1){
$("#check").html($("#check").html()+'<span class="layui-badge-dot"></span>');
}
}
});
</script>
{include file='common/foot.html'}

View File

@@ -0,0 +1,118 @@
{include file='common/head.html'}
<div class="layui-body">
<div class="layui-tab layui-tab-brief" lay-filter="tab">
<ul class="layui-tab-title">
<li class="layui-this" lay-id="t1">服务器基本信息</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
<table class="layui-table table-two">
<thead>
<tr>
<th colspan=2>服务器基本信息</th>
</tr>
</thead>
<tbody>
<tr>
<th>应用版本</th>
<td>PbootCMS V{APP_VERSION}-{RELEASE_TIME}</td>
</tr>
<tr>
<th>框架版本</th>
<td>Pboot V{CORE_VERSION}</td>
</tr>
<tr>
<th>主机系统</th>
<td>{$server->php_os}</td>
</tr>
<tr>
<th>访问地址</th>
<td>{$server->http_host}</td>
</tr>
<tr>
<th>主机名称</th>
<td>{$server->server_name}</td>
</tr>
<tr>
<th>主机地址</th>
<td>{$server->server_addr}</td>
</tr>
<tr>
<th>主机端口</th>
<td>{$server->server_port}</td>
</tr>
<tr>
<th>WEB软件</th>
<td>{$server->server_software}</td>
</tr>
<tr>
<th>PHP版</th>
<td>{$server->php_version}</td>
</tr>
<tr>
<th>数据库驱动</th>
<td>{$server->db_driver}</td>
</tr>
<tr>
<th>文件上传限制</th>
<td>{$server->upload_max_filesize}</td>
</tr>
<tr>
<th>表单提交限制</th>
<td>{$server->post_max_size}</td>
</tr>
<tr>
<th>最大提交数量</th>
<td>{$server->max_file_uploads}</td>
</tr>
<tr>
<th>分配内存限制</th>
<td>{$server->memory_limit}</td>
</tr>
<tr>
<th>GD库支持</th>
<td>{$server->gd}</td>
</tr>
<tr>
<th>Curl支持</th>
<td>{$server->curl}</td>
</tr>
<tr>
<th>加速模块支持</th>
<td>
pthreads{$server->pthreads}
XCache{$server->xcache}
APC{$server->apc}
eAccelerator{$server->eaccelerator}
WinCache{$server->wincache}
ZendOPcache{$server->zendopcache}
Memcache{$server->memcache}
Memcached{$server->memcached}
</td>
</tr>
<tr>
<th>已加载模块</th>
<td>{$server->extensions}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
{include file='common/foot.html'}

View File

@@ -0,0 +1,62 @@
<?php
/**
* @copyright (C)2016-2099 Hnaoyun Inc.
* @author XingMeng
* @email hnxsh@foxmail.com
* @date 2018年11月11日
* 单页内容通过分类编码调用接口控制器
*/
namespace app\api\controller;
use core\basic\Controller;
use app\api\model\CmsModel;
use core\basic\Url;
class AboutController extends Controller
{
protected $model;
public function __construct()
{
$this->model = new CmsModel();
}
public function index()
{
if (! ! $scode = request('scode', 'var')) {
// 区域获取
$acode = request('acode', 'var') ?: get_default_lg();
// 读取数据
if (! ! $data = $this->model->getAbout($acode, $scode)) {
if ($data->outlink) {
$data->apilink = $data->outlink;
} else {
$data->apilink = url('/api/content/index/id/' . $data->id, false);
}
$data->likeslink = url('/home/Do/likes/id/' . $data->id, false);
$data->opposelink = url('/home/Do/oppose/id/' . $data->id, false);
$urlname = $data->urlname ?: 'about';
$url_break_char = $this->config('url_break_char') ?: '_';
$url_rule_sort_suffix = $this->config('url_rule_sort_suffix') ? true : null;
if ($data->sortfilename) {
$data->contentlink = Url::home($data->sortfilename, $url_rule_sort_suffix);
} else {
$data->contentlink = Url::home($urlname . $url_break_char . $data->scode, $url_rule_sort_suffix);
}
$data->content = str_replace(STATIC_DIR . '/upload/', get_http_url() . STATIC_DIR . '/upload/', $data->content);
json(1, $data);
} else {
json(0, '分类编码为' . $scode . '的内容已经不存在了!');
}
} else {
json(1, '请求错误传递的内容scode有误');
}
}
}

View File

@@ -0,0 +1,197 @@
<?php
/**
* @copyright (C)2016-2099 Hnaoyun Inc.
* @author XingMeng
* @email hnxsh@foxmail.com
* @date 2016年12月25日
* 应用公共控制类
*/
namespace app\common;
use core\basic\Controller;
class AdminController extends Controller
{
public function __construct()
{
// 自动缓存基础信息
cache_config();
// 从配置文件读取cmsname参数来设置系统名称
define("CMSNAME", $this->config("cmsname") ?: 'PbootCMS');
// 检测登录,未登录跳转登录页面,已登录执行数据处理
if ($this->checkLogin()) {
// 权限检测
$this->checkLevel();
$this->getSecondMenu(); // 获取同级菜单
$this->assign('menu_tree', session('menu_tree')); // 注入菜单树
if (session('area_tree')) {
$area_html = make_area_Select(session('area_tree'), session('acode'));
$this->assign('area_html', $area_html);
if (count(session('area_tree')) == 1) {
$this->assign('one_area', true);
}
} else {
session_unset();
error('您账号的区域权限设置有误,无法正常登录!', url('/admin/Index/index'), 10);
}
// 内容模型菜单注入
$models = model('admin.content.Model');
$this->assign('menu_models', $models->getModelMenu());
// 注入编码后的回跳地址
$this->assign('btnqs', get_btn_qs());
$this->assign('backurl', get_backurl());
// 兼容模式form使用get搜索时注入pathinfo隐藏域
if ($_GET['p'] && $this->config('app_url_type') == 3) {
$this->assign('pathinfo', '<input name="p" type="hidden" value="' . get('p') . '">');
}
}
// 不进行表单检验的控制器
$nocheck = array(
'Upgrade'
);
// POST表单提交校验
if ($_POST && ! in_array(C, $nocheck) && session('formcheck') != post('formcheck')) {
// 检查会话目录权限问题
if (session_save_path()) {
preg_match('/^((\s+)?([0-9]+)(\s+)?;)?(.*)/', session_save_path(), $matches);
// 自动创建会话主目录
if (! check_dir($matches[5], true)) {
error('会话目录创建失败!' . $matches[5]);
}
// 检查会话目录写入权限
if (! is_writable($matches[5])) {
error('会话目录权限不足!' . $matches[5]);
}
// 自动创建层级会话目录
if ($matches[3]) {
create_session_dir($matches[5], $matches[3]);
}
} elseif (isset($_SERVER['TMP']) && ! file_exists($_SERVER['TMP'] . '/sess_' . session_id())) {
error(' 操作系统缓存目录写入权限不足!' . $_SERVER['TMP']);
}
alert_back('表单提交校验失败,请刷新后重试!');
}
// 首次加载时,生成页面验证码
if (! issetSession('formcheck')) {
session('formcheck', get_uniqid());
}
$this->assign('formcheck', session('formcheck')); // 注入formcheck模板变量
}
// 后台用户登录状态检查
private function checkLogin()
{
// 免登录可访问页面
$public_path = array(
'/admin/Index/index', // 登录页面
'/admin/Index/login' // 执行登录
);
if (session('sid') && $this->checkSid()) { // 如果已经登录直接true
return true;
} elseif (in_array('/' . M . '/' . C . '/' . F, $public_path)) { // 免登录可访问页面
return false;
} else { // 未登录跳转到登录页面
location(url('/admin/Index/index'));
}
}
// 检查会话id
private function checkSid()
{
$sid = encrypt_string(session_id() . session('id'));
if ($sid != session('sid') || session('M') != M) {
session_destroy();
return false;
} else {
return true;
}
}
// 访问权限检查
private function checkLevel()
{
// 免权限等级认证页面,即所有登录用户都可以访问
$public_path = array(
'/admin/Index/index', // 登录页
'/admin/Index/home', // 主页
'/admin/Index/loginOut', // 退出登录
'/admin/Index/ucenter', // 用户中心
'/admin/Index/area', // 区域选择
'/admin/Index/clearCache', // 清理缓存
'/admin/Index/upload', // 上传文件
'/admin/Index/clearSession' // 清理会话
);
$levals = session('levels');
$path1 = '/' . M . '/' . C;
$path2 = '/' . M . '/' . C . '/' . F;
if (session('id') == 1 || in_array(URL, $levals) || in_array($path2, $levals) || in_array($path1, $public_path) || in_array($path2, $public_path)) {
return true;
} else {
error('您的账号权限不足,您无法执行该操作!');
}
}
// 当前菜单的父类的子菜单,即同级菜单二级菜单
private function getSecondMenu()
{
$menu_tree = session('menu_tree');
$url = '/' . M . '/' . C . '/' . F;
$len = 0;
$primary_menu_url = '';
$second_menu = array();
// 直接比对找出最长匹配URL
foreach ($menu_tree as $key => $value) {
if (is_array($value->son)) {
foreach ($value->son as $key2 => $value2) {
if (! $value2->url) // 如果为空,则跳过
continue;
$pos = strpos($url, $value2->url);
if ($pos !== false) {
$templen = strlen($value2->url);
if ($templen > $len) {
$len = $templen;
$primary_menu_url = $value->url;
$second_menu = $value->son;
}
break; // 如果匹配到已经找到父类,则结束
}
}
}
}
// 前面第一种无法匹配,则选择子菜单匹配,只需控制器通过即可,如翻页、增、改、删操作
if (! $second_menu) {
foreach ($menu_tree as $key => $value) {
if (is_array($value->son)) {
foreach ($value->son as $key2 => $value2) {
if (strpos($value2->url, '/' . M . '/' . C . '/') === 0) {
$primary_menu_url = $value->url;
$second_menu = $value->son;
break;
}
}
}
if ($second_menu) { // 已经获取二级菜单到后退出
break;
}
}
}
$this->assign('primary_menu_url', $primary_menu_url);
$this->assign('second_menu', $second_menu);
}
}

View File

@@ -0,0 +1,12 @@
<?php
return array(
// 应用版本
'app_version' => '3.0.7',
// 发布时间
'release_time' => '20211009',
// 修订版本
'revise_version' => '3'
);

View File

@@ -0,0 +1,317 @@
<?php
/**
* @copyright (C)2016-2099 Hnaoyun Inc.
* @author XingMeng
* @email hnxsh@foxmail.com
* @date 2018年2月14日
* 首页控制器
*/
namespace app\home\controller;
use core\basic\Controller;
use app\home\model\ParserModel;
use core\basic\Config;
use core\basic\Url;
class IndexController extends Controller
{
protected $parser;
protected $model;
protected $htmldir;
public function __construct()
{
$this->parser = new ParserController();
$this->model = new ParserModel();
$this->htmldir = $this->config('tpl_html_dir') ? $this->config('tpl_html_dir') . '/' : '';
}
// 空拦截器, 实现文章路由转发
public function _empty()
{
// 地址类型
$url_rule_type = $this->config('url_rule_type') ?: 3;
if (P) { // 采用pathinfo模式及p参数伪静态模式
if ($url_rule_type == 2 && stripos(URL, $_SERVER['SCRIPT_NAME']) !== false) { // 禁止伪静态时带index.php访问
_404('您访问的内容不存在,请核对后重试!');
}
$path = explode('/', P);
if (! defined('URL_BIND')) {
array_shift($path); // 去除模块部分
}
} elseif ($url_rule_type == 3 && isset($_SERVER["QUERY_STRING"]) && $qs = $_SERVER["QUERY_STRING"]) { // 采用简短传参模式
parse_str($qs, $output);
unset($output['page']); // 去除分页
if ($output && ! current($output)) { // 第一个路径参数不能有值,否则非标准路径参数
$path = key($output); // 第一个参数为路径信息注意PHP数组会自动将key点符号转换下划线
$path = trim($path, '/'); // 去除两端斜杠
$url_rule_suffix = substr($this->config('url_rule_suffix'), 1);
if (preg_match('/_' . $url_rule_suffix . '$/', $path) && (! ! $pos = strripos($path, '_' . $url_rule_suffix))) {
$path = substr($path, 0, $pos); // 去扩展
}
$path = explode('/', $path);
} elseif (get('tag')) { // 对于兼容模式tag需要自动跳转tag独立页面
$tag = new TagController();
$tag->index();
} elseif (get('keyword')) { // 兼容模式搜索处理
$search = new SearchController();
$search->index();
}
}
if (isset($path) && is_array($path)) {
switch ($path[0]) {
case 'search':
case 'keyword':
$search = new SearchController();
$search->index();
break;
case 'message':
$msg = new MessageController();
$msg->index();
break;
case 'form':
$_GET['fcode'] = $path[1];
$form = new FormController();
$form->index();
break;
case 'sitemap':
case 'Sitemap':
$sitemap = new SitemapController();
$sitemap->index();
break;
case 'tag':
$tag = new TagController();
$tag->index();
break;
case 'member':
$member = new MemberController();
$member->{$path[1]}();
break;
case 'comment':
$comment = new CommentController();
$comment->{$path[1]}();
break;
default:
if (get($path[0])) {
$this->getIndex();
} else {
// 优先判断全路径
$fullurl = implode('/', $path);
// 详情页匹配前段栏目路径
$sorturl = $path;
$contenturl = array_pop($sorturl);
$sorturl = implode('/', $sorturl);
$url_break_char = $this->config('url_break_char') ?: '_';
// 开始进行匹配
if (! ! $sort = $this->model->getSort($fullurl)) {
// 栏目名称
$iscontent = false;
} elseif (preg_match('/^([a-zA-Z0-9\-\/]+)' . $url_break_char . '([0-9]+)$/i', $fullurl, $matchs) && ! ! $sort = $this->model->getSort($matchs[1])) {
// 栏目名称_分页
$iscontent = false;
define('CMS_PAGE_CUSTOM', true);
$_GET['page'] = $matchs[2]; // 分页
} elseif (! ! $sorturl && ! ! $sort = $this->model->getSort($sorturl)) {
// 栏目名称/内容名称或ID要在第2个判断【栏目名称_分页】后
$data = $this->model->getContent($contenturl);
$iscontent = true;
} elseif (preg_match('/^list' . $url_break_char . '[0-9]+|about' . $url_break_char . '[0-9]+$/', $sorturl)) {
// 模型默认名称_栏目ID/内容名称或ID
$data = $this->model->getContent($contenturl);
$iscontent = true;
} else {
preg_match('/^([a-zA-Z0-9\-\/]+)(' . $url_break_char . '([0-9]+))?' . $url_break_char . '([0-9]+)$/i', $fullurl, $matchs);
if ($matchs[2] && $model = $this->model->checkModelUrlname($matchs[1])) {
// 模型名称_栏目ID_分页
define('CMS_PAGE_CUSTOM', false);
$sort = $this->model->getSort($matchs[3]);
$_GET['page'] = $matchs[4]; // 分页
} elseif (! ! $model = $this->model->checkModelUrlname($matchs[1])) {
// 模型名称_栏目ID
$sort = $this->model->getSort($matchs[4]);
} elseif (preg_match('/^([a-zA-Z0-9\-\/]+)' . $url_break_char . '([0-9]+)$/i', $sorturl, $matchs)) {
// 模型名称_栏目ID/内容名称或ID
if (! ! $model = $this->model->checkModelUrlname($matchs[1])) {
$data = $this->model->getContent($contenturl);
$iscontent = true;
}
}
}
if ($iscontent) {
define('CMS_PAGE', false); // 使用普通分页处理模型
if (! ! $data) {
if ($data->acode != get_lg() && Config::get('lgautosw') !== '0') {
cookie('lg', $data->acode); // 调用内容语言与当前语言不一致时,自动切换语言
}
$this->getContent($data);
} else {
_404('您访问的内容不存在,请核对后重试!');
}
} else {
define('CMS_PAGE', true); // 使用cms分页处理模型
if (! ! $sort) {
if ($sort->acode != get_lg() && Config::get('lgautosw') !== '0') {
cookie('lg', $sort->acode); // 调用栏目语言与当前语言不一致时,自动切换语言
}
if ($sort->type == 1) {
$this->getAbout($sort);
} else {
$this->getList($sort);
}
} else {
_404('您访问的页面不存在,请核对后重试!');
}
}
}
}
} else {
$this->getIndex();
}
}
// 首页
private function getIndex()
{
$content = parent::parser($this->htmldir . 'index.html'); // 框架标签解析
$content = $this->parser->parserBefore($content); // CMS公共标签前置解析
$content = str_replace('{pboot:pagetitle}', $this->config('index_title') ?: '{pboot:sitetitle}-{pboot:sitesubtitle}', $content);
$content = $this->parser->parserPositionLabel($content, - 1, '首页', SITE_INDEX_DIR . '/'); // CMS当前位置标签解析
$content = $this->parser->parserSpecialPageSortLabel($content, 0, '', SITE_INDEX_DIR . '/'); // 解析分类标签
$content = $this->parser->parserAfter($content); // CMS公共标签后置解析
$this->cache($content, true);
}
// 列表
private function getList($sort)
{
if ($sort->listtpl) {
$this->checkPageLevel($sort->gcode, $sort->gtype, $sort->gnote);
$content = parent::parser($this->htmldir . $sort->listtpl); // 框架标签解析
$content = $this->parser->parserBefore($content); // CMS公共标签前置解析
$pagetitle = $sort->title ? "{sort:title}" : "{sort:name}"; // 页面标题
$content = str_replace('{pboot:pagetitle}', $this->config('list_title') ?: ($pagetitle . '-{pboot:sitetitle}-{pboot:sitesubtitle}'), $content);
$content = str_replace('{pboot:pagekeywords}', '{sort:keywords}', $content);
$content = str_replace('{pboot:pagedescription}', '{sort:description}', $content);
$content = $this->parser->parserPositionLabel($content, $sort->scode); // CMS当前位置标签解析
$content = $this->parser->parserSortLabel($content, $sort); // CMS分类信息标签解析
$content = $this->parser->parserListLabel($content, $sort->scode); // CMS分类列表标签解析
$content = $this->parser->parserAfter($content); // CMS公共标签后置解析
} else {
error('请到后台设置分类栏目列表页模板!');
}
$this->cache($content, true);
}
// 详情页
private function getContent($data)
{
// 读取模板
if (! ! $sort = $this->model->getSort($data->scode)) {
if ($sort->contenttpl) {
$this->checkPageLevel($sort->gcode, $sort->gtype, $sort->gnote); // 检查栏目权限
$this->checkPageLevel($data->gcode, $data->gtype, $data->gnote); // 检查内容权限
$content = parent::parser($this->htmldir . $sort->contenttpl); // 框架标签解析
$content = $this->parser->parserBefore($content); // CMS公共标签前置解析
$content = str_replace('{pboot:pagetitle}', $this->config('content_title') ?: '{content:title}-{sort:name}-{pboot:sitetitle}-{pboot:sitesubtitle}', $content);
$content = str_replace('{pboot:pagekeywords}', '{content:keywords}', $content);
$content = str_replace('{pboot:pagedescription}', '{content:description}', $content);
$content = $this->parser->parserPositionLabel($content, $sort->scode); // CMS当前位置标签解析
$content = $this->parser->parserSortLabel($content, $sort); // CMS分类信息标签解析
$content = $this->parser->parserCurrentContentLabel($content, $sort, $data); // CMS内容标签解析
$content = $this->parser->parserCommentLabel($content); // 文章评论
$content = $this->parser->parserAfter($content); // CMS公共标签后置解析
} else {
error('请到后台设置分类栏目内容页模板!');
}
} else {
_404('您访问内容的分类已经不存在,请核对后再试!');
}
$this->cache($content, true);
}
// 单页
private function getAbout($sort)
{
// 读取数据
if (! $data = $this->model->getAbout($sort->scode)) {
_404('您访问的内容不存在,请核对后重试!');
}
if ($sort->contenttpl) {
$this->checkPageLevel($sort->gcode, $sort->gtype, $sort->gnote);
$content = parent::parser($this->htmldir . $sort->contenttpl); // 框架标签解析
$content = $this->parser->parserBefore($content); // CMS公共标签前置解析
$pagetitle = $sort->title ? "{sort:title}" : "{content:title}"; // 页面标题
$content = str_replace('{pboot:pagetitle}', $this->config('about_title') ?: ($pagetitle . '-{pboot:sitetitle}-{pboot:sitesubtitle}'), $content);
$content = str_replace('{pboot:pagekeywords}', '{content:keywords}', $content);
$content = str_replace('{pboot:pagedescription}', '{content:description}', $content);
$content = $this->parser->parserPositionLabel($content, $sort->scode); // CMS当前位置标签解析
$content = $this->parser->parserSortLabel($content, $sort); // CMS分类信息标签解析
$content = $this->parser->parserCurrentContentLabel($content, $sort, $data); // CMS内容标签解析
$content = $this->parser->parserCommentLabel($content); // 文章评论
$content = $this->parser->parserAfter($content); // CMS公共标签后置解析
} else {
error('请到后台设置分类栏目内容页模板!');
}
$this->cache($content, true);
}
// 检查页面权限
private function checkPageLevel($gcode, $gtype, $gnote)
{
if ($gcode) {
$deny = false;
$gtype = $gtype ?: 4;
switch ($gtype) {
case 1:
if ($gcode <= session('pboot_gcode')) {
$deny = true;
}
break;
case 2:
if ($gcode < session('pboot_gcode')) {
$deny = true;
}
break;
case 3:
if ($gcode != session('pboot_gcode')) {
$deny = true;
}
break;
case 4:
if ($gcode > session('pboot_gcode')) {
$deny = true;
}
break;
case 5:
if ($gcode >= session('pboot_gcode')) {
$deny = true;
}
break;
}
if ($deny) {
$gnote = $gnote ?: '您的权限不足,无法浏览本页面!';
if (session('pboot_uid')) { // 已经登录
error($gnote);
} else {
if ($this->config('login_no_wait')) {
location(Url::home('member/login', null, "backurl=" . urlencode(get_current_url())));
} else {
error($gnote, Url::home('member/login', null, "backurl=" . urlencode(get_current_url())));
}
}
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,90 @@
<?php
/**
* @copyright (C)2016-2099 Hnaoyun Inc.
* @author XingMeng
* @email hnxsh@foxmail.com
* @date 2018年7月15日
* 生成sitemap文件
*/
namespace app\home\controller;
use core\basic\Controller;
use app\home\model\SitemapModel;
use core\basic\Url;
class SitemapController extends Controller
{
protected $model;
public function __construct()
{
$this->model = new SitemapModel();
}
public function index()
{
header("Content-type:text/xml;charset=utf-8");
$str = '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
$str .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:mobile="http://www.baidu.com/schemas/sitemap-mobile/1/">' . "\n";
$str .= $this->makeNode('', date('Y-m-d'), '1.00'); // 根目录
$url_break_char = $this->config('url_break_char') ?: '_';
$sorts = $this->model->getSorts();
foreach ($sorts as $value) {
if ($value->outlink) {
continue;
} elseif ($value->type == 1) {
$value->urlname = $value->urlname ?: 'list';
if ($value->filename) {
$link = Url::home('/home/Index/' . $value->filename);
} else {
$link = Url::home('/home/Index/' . $value->urlname . $url_break_char . $value->scode);
}
$str .= $this->makeNode($link, date('Y-m-d'), '0.80');
} else {
$value->urlname = $value->urlname ?: 'list';
if ($value->filename) {
$link = Url::home('home/Index/' . $value->filename);
} else {
$link = Url::home('home/Index/' . $value->urlname . $url_break_char . $value->scode);
}
$str .= $this->makeNode($link, date('Y-m-d'), '0.80');
$contents = $this->model->getSortContent($value->scode);
foreach ($contents as $value2) {
if ($value2->outlink) { // 外链
continue;
} else {
$value2->urlname = $value2->urlname ?: 'list';
if ($value2->filename && $value2->sortfilename) {
$link = Url::home('home/Index/' . $value2->sortfilename . '/' . $value2->filename, true);
} elseif ($value2->sortfilename) {
$link = Url::home('home/Index/' . $value2->sortfilename . '/' . $value2->id, true);
} elseif ($value2->contentfilename) {
$link = Url::home('home/Index/' . $value2->urlname . $url_break_char . $value2->scode . '/' . $value2->filename, true);
} else {
$link = Url::home('home/Index/' . $value2->urlname . $url_break_char . $value2->scode . '/' . $value2->id, true);
}
}
$str .= $this->makeNode($link, date('Y-m-d'), '0.60');
}
}
}
echo $str . "\n</urlset>";
}
// 生成结点信息
private function makeNode($link, $date, $priority = 0.60)
{
$node = '
<url>
<mobile:mobile type="pc,mobile"/>
<loc>' . get_http_url() . $link . '</loc>
<priority>' . $priority . '</priority>
<lastmod>' . $date . '</lastmod>
<changefreq>Always</changefreq>
</url>';
return $node;
}
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,157 @@
<?php
/**
* @copyright (C)2016-2099 Hnaoyun Inc.
* @author XingMeng
* @email hnxsh@foxmail.com
* @date 2017年11月6日
* 生成指定模块下控制器方法的跳转路径
*/
namespace core\basic;
class Url
{
// 存储已经生成过的地址信息
private static $urls = array();
// 接收控制器方法完整访问路径,如:/home/Index/index /模块/控制器/方法/.. 路径,生成可访问地址
public static function get($path, $suffix = null)
{
if (strpos($path, 'http') === 0 || ! $path) {
return $path;
}
$path = trim_slash($path); // 去除两端斜线
if (! isset(self::$urls[$path])) {
$path_arr = explode('/', $path); // 地址数组
if ($suffix && Config::get('app_url_type') == 2 && strrpos(strtolower($_SERVER["SCRIPT_NAME"]), 'index.php') !== false) {
$url_ext = Config::get('url_rule_suffix'); // 伪静态文件形式
} elseif (Config::get('app_url_type') == 1 || Config::get('app_url_type') == 2) {
$url_ext = '/'; // pathinfo目录形式
} else {
$url_ext = '';
}
// 路由处理
if (! ! $routes = Config::get('url_route')) {
foreach ($routes as $key => $value) {
// 去除两端斜线
$value = trim_slash($value);
$key = trim_slash($key);
// 替换原来正则为替换内容
if (preg_match_all('/\(.*?\)/', $key, $source)) {
foreach ($source[0] as $kk => $vk) {
$key = str_replace($vk, '$' . ($kk + 1), $key);
}
}
// 替换原来替换内容为正则
if (preg_match_all('/\$([0-9]+)/', $value, $destination)) {
foreach ($destination[1] as $kv => $vv) {
$value = str_replace($destination[0][$kv], $source[0][$vv - 1], $value);
}
}
// 执行匹配替换
if (preg_match('{' . $value . '$}i', $path)) {
$path = preg_replace('{' . $value . '$}i', $key, $path);
} elseif (preg_match('{' . $value . '\/}i', $path)) {
$path = preg_replace('{' . $value . '\/}i', $key . '/', $path);
}
}
}
// 域名绑定处理匹配
$cut_str = '';
if (! ! $domains = Config::get('app_domain_bind')) {
foreach ($domains as $key => $value) {
$value = trim_slash($value); // 去除两端斜线
if (strpos($path, $value . '/') === 0) {
$cut_str = $value;
$server_name = get_http_host();
if ($server_name != $key) { // 绑定的域名与当前域名不一致时,添加主机地址
$host = is_https() ? 'https://' . $key : 'http://' . $key;
} else {
$host = '';
}
break;
}
}
}
// 入口文件绑定匹配
if (defined('URL_BIND') && $path_arr[0] == M) {
$cut_str = trim_slash(URL_BIND);
}
// 执行URL简化
if ($cut_str) {
$path = substr($path, strlen($cut_str) + 1);
}
// 保存处理过的地址
if ($path) {
self::$urls[$path] = $host . url_index_path() . '/' . $path . $url_ext;
} else {
self::$urls[$path] = $host . url_index_path(); // 获取根路径前置地址
}
}
return self::$urls[$path];
}
// 生成前端地址
public static function home($path, $suffix = null, $qs = null)
{
if (! isset(self::$urls[md5($path . $suffix . $qs)])) {
$url_rule_type = Config::get('url_rule_type') ?: 3;
$url_rule_suffix = Config::get('url_rule_suffix') ?: '.html';
$url_rule_sort_suffix = Config::get('url_rule_sort_suffix');
if (($suffix === null && $url_rule_sort_suffix) || $suffix) {
$suffix = $url_rule_suffix;
} elseif ($suffix === false) {
$suffix = '';
} else {
$suffix = '/';
}
$path = ltrim($path, '/');
// 去除默认模块及控制器部分
$path = str_replace('home/Index/', '', $path);
if (! $path) {
if ($url_rule_type == 1) {
$link = SITE_INDEX_DIR . '/index.php';
} elseif ($url_rule_type == 2) {
$link = SITE_INDEX_DIR;
} else {
$link = SITE_INDEX_DIR . '/?';
}
} else {
switch ($url_rule_type) {
case '1': // 普通模式
$qs = $qs ? "?" . $qs : '';
$link = SITE_INDEX_DIR . '/index.php' . '/' . $path . $suffix . $qs;
break;
case '2': // 伪静态模式
$qs = $qs ? "?" . $qs : '';
$link = SITE_INDEX_DIR . '/' . $path . $suffix . $qs;
break;
case '3': // 兼容模式
$qs = $qs ? "&" . $qs : '';
$link = SITE_INDEX_DIR . '/?' . $path . $suffix . $qs;
break;
default:
error('地址模式设置错误,请登录后台重新设置!');
}
}
self::$urls[md5($path . $suffix . $qs)] = $link;
}
return self::$urls[md5($path . $suffix . $qs)];
}
}

View File

@@ -0,0 +1,626 @@
<?php
/**
* @copyright (C)2016-2099 Hnaoyun Inc.
* @author XingMeng
* @email hnxsh@foxmail.com
* @date 2017年8月3日
* 数据处理函数库
*/
use core\basic\Config;
// 检测目录是否存在
function check_dir($path, $create = false)
{
if (is_dir($path)) {
return true;
} elseif ($create) {
return create_dir($path);
}
}
// 创建目录
function create_dir($path)
{
if (! file_exists($path)) {
if (mkdir($path, 0777, true)) {
return true;
}
}
return false;
}
// 检查文件是否存在
function check_file($path, $create = false, $content = null)
{
if (file_exists($path)) {
return true;
} elseif ($create) {
return create_file($path, $content);
}
}
// 创建文件
function create_file($path, $content = null, $over = false)
{
if (file_exists($path) && ! $over) {
return false;
} elseif (file_exists($path)) {
@unlink($path);
}
check_dir(dirname($path), true);
$handle = fopen($path, 'w') or error('创建文件失败,请检查目录权限!');
fwrite($handle, $content);
return fclose($handle);
}
// 目录文件夹列表
function dir_list($path)
{
$list = array();
if (! is_dir($path) || ! $filename = scandir($path)) {
return $list;
}
$files = count($filename);
for ($i = 0; $i < $files; $i ++) {
$dir = $path . '/' . $filename[$i];
if (is_dir($dir) && $filename[$i] != '.' && $filename[$i] != '..') {
$list[] = $filename[$i];
}
}
return $list;
}
// 目录文件列表
function file_list($path)
{
$list = array();
if (! is_dir($path) || ! $filename = scandir($path)) {
return $list;
}
$files = count($filename);
for ($i = 0; $i < $files; $i ++) {
$dir = $path . '/' . $filename[$i];
if (is_file($dir)) {
$list[] = $filename[$i];
}
}
return $list;
}
// 目录下文件及文件夹列表
function path_list($path)
{
$list = array();
if (! is_dir($path) || ! $filename = scandir($path)) {
return $list;
}
$files = count($filename);
for ($i = 0; $i < $files; $i ++) {
$dir = $path . '/' . $filename[$i];
if (is_file($dir) || (is_dir($dir) && $filename[$i] != '.' && $filename[$i] != '..')) {
$list[] = $filename[$i];
}
}
return $list;
}
/**
* 删除目录及目录下所有文件或删除指定文件
*
* @param str $path
* 待删除目录路径
* @param int $delDir
* 是否删除目录true删除目录false则只删除文件保留目录
* @return bool 返回删除状态
*/
function path_delete($path, $delDir = false)
{
$result = true; // 对于空目录直接返回true状态
if (! file_exists($path)) {
return $result;
}
if (is_dir($path)) {
if (! ! $dirs = scandir($path)) {
foreach ($dirs as $value) {
if ($value != "." && $value != "..") {
$dir = $path . '/' . $value;
$result = is_dir($dir) ? path_delete($dir, $delDir) : unlink($dir);
}
}
if ($result && $delDir) {
return rmdir($path);
} else {
return $result;
}
} else {
return false;
}
} else {
return unlink($path);
}
}
// 拷贝文件夹
function dir_copy($src, $des, $son = 1)
{
if (! is_dir($src)) {
return false;
}
if (! is_dir($des)) {
create_dir($des);
}
$handle = dir($src);
while (! ! $path = $handle->read()) {
if (($path != ".") && ($path != "..")) {
if (is_dir($src . "/" . $path)) {
if ($son)
dir_copy($src . "/" . $path, $des . "/" . $path, $son);
} else {
copy($src . "/" . $path, $des . "/" . $path);
}
}
}
return true;
}
// 判断文件是否是图片
function is_image($path)
{
$types = '.gif|.jpeg|.png|.bmp'; // 定义检查的图片类型
if (file_exists($path)) {
$info = getimagesize($path);
$ext = image_type_to_extension($info['2']);
if (stripos($types, $ext) !== false)
return true;
}
return false;
}
/**
* 文件上传
*
* @param string $input_name表单名称
* @param string $file_ext允许的扩展名
* @param number $max_width最大宽度
* @param number $max_height最大高度
* @return string 返回成功上传文件的路径数组
*/
function upload($input_name, $file_ext = null, $max_width = null, $max_height = null, $watermark = false)
{
// 未选择文件返回空
if (! isset($_FILES[$input_name])) {
return '文件超过PHP环境允许的大小';
} else {
$files = $_FILES[$input_name];
}
// 定义允许上传的扩展
if (! $file_ext) {
$array_ext_allow = Config::get('upload.format', true);
} else {
$array_ext_allow = explode(',', $file_ext);
}
// 未直接传递函数参数,且具有地址参数,则打水印
if (! $watermark && get('watermark', 'int')) {
$watermark = true;
}
$array_save_file = array();
if (is_array($files['tmp_name'])) { // 多文件情况
$file_count = count($files['tmp_name']);
for ($i = 0; $i < $file_count; $i ++) {
if (! $files['error'][$i]) {
$upfile = handle_upload($files['name'][$i], $files['tmp_name'][$i], $array_ext_allow, $max_width, $max_height, $watermark);
if (strrpos($upfile, '/') > 0) {
$array_save_file[] = $upfile;
} else {
$err = $upfile;
}
} else {
$err = '错误代码' . $files['error'][$i];
}
}
} else { // 单文件情况
if (! $files['error']) {
$upfile = handle_upload($files['name'], $files['tmp_name'], $array_ext_allow, $max_width, $max_height, $watermark);
if (strrpos($upfile, '/') > 0) {
$array_save_file[] = $upfile;
} else {
$err = $upfile;
}
} else {
$err = '错误代码' . $files['error'];
}
}
if (isset($err)) {
return $err;
} else {
return $array_save_file;
}
}
// 处理并移动上传文件
function handle_upload($file, $temp, $array_ext_allow, $max_width, $max_height, $watermark)
{
// 定义主存储路径
$save_path = DOC_PATH . STATIC_DIR . '/upload';
$file = explode('.', $file); // 分离文件名及扩展
$file_ext = strtolower(end($file)); // 获取扩展
if (! in_array($file_ext, $array_ext_allow)) {
return $file_ext . '格式的文件不允许上传!';
}
$image = array(
'png',
'jpg',
'gif',
'bmp'
);
$file = array(
'ppt',
'pptx',
'xls',
'xlsx',
'doc',
'docx',
'pdf',
'txt'
);
if (in_array($file_ext, $image)) {
$file_type = 'image';
} elseif (in_array($file_ext, $file)) {
$file_type = 'file';
} else {
$file_type = 'other';
}
// 检查文件存储路径
if (! check_dir($save_path . '/' . $file_type . '/' . date('Ymd'), true)) {
return '存储目录创建失败!';
}
$file_path = $save_path . '/' . $file_type . '/' . date('Ymd') . '/' . time() . mt_rand(100000, 999999) . '.' . $file_ext;
if (! move_uploaded_file($temp, $file_path)) { // 从缓存中转存
return '从缓存中转存失败!';
}
$save_file = str_replace(ROOT_PATH, '', $file_path); // 获取文件站点路径
// 如果是图片
if (is_image($file_path)) {
// 进行等比例缩放
if (($reset = resize_img($file_path, $file_path, $max_width, $max_height)) !== true) {
return $reset;
}
// 图片打水印
if ($watermark) {
watermark_img($file_path);
}
}
return $save_file;
}
/**
* *
* 等比缩放图片
*
* @param string $src_image源图片路径
* @param string $out_image输出图像路径
* @param number $max_width最大宽
* @param number $max_height最大高
* @param number $img_quality图片质量
* @return boolean 返回是否成功
*/
function resize_img($src_image, $out_image = null, $max_width = null, $max_height = null, $img_quality = 90)
{
// 输出地址
if (! $out_image)
$out_image = $src_image;
// 读取配置文件设置
if (! $max_width)
$max_width = Config::get('upload.max_width') ?: 999999999;
if (! $max_height)
$max_height = Config::get('upload.max_height') ?: 999999999;
// 获取图片属性
list ($width, $height, $type, $attr) = getimagesize($src_image);
// 检查输出目录
check_dir(dirname($out_image), true);
// 无需缩放的图片
if ($width <= $max_width && $height <= $max_height) {
if ($src_image != $out_image) { // 存储地址不一致时进行拷贝
if (! copy($src_image, $out_image)) {
return '缩放图片时拷贝到目的地址失败!';
}
}
return true;
}
// 求缩放比例
if ($max_width && $max_height) {
$scale = min($max_width / $width, $max_height / $height);
} elseif ($max_width) {
$scale = $max_width / $width;
} elseif ($max_height) {
$scale = $max_height / $height;
}
if ($scale < 1) {
switch ($type) {
case 1:
$img = imagecreatefromgif($src_image);
break;
case 2:
$img = imagecreatefromjpeg($src_image);
break;
case 3:
$img = imagecreatefrompng($src_image);
break;
}
$new_width = floor($scale * $width);
$new_height = floor($scale * $height);
$new_img = imagecreatetruecolor($new_width, $new_height); // 创建画布
// 创建透明画布,避免黑色
if ($type == 1 || $type == 3) {
$color = imagecolorallocate($new_img, 255, 255, 255);
imagefill($new_img, 0, 0, $color);
imagecolortransparent($new_img, $color);
}
imagecopyresized($new_img, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
switch ($type) {
case 1:
imagegif($new_img, $out_image, $img_quality);
break;
case 2:
imagejpeg($new_img, $out_image, $img_quality);
break;
case 3:
imagepng($new_img, $out_image, $img_quality / 10); // $quality参数取值范围0-99 在php 5.1.2之后变更为0-9
break;
default:
imagejpeg($new_img, $out_image, $img_quality);
}
imagedestroy($new_img);
imagedestroy($img);
}
return true;
}
// 剪切图片
function cut_img($src_image, $out_image = null, $new_width = null, $new_height = null, $img_quality = 90)
{
// 输出地址
if (! $out_image)
$out_image = $src_image;
// 读取配置文件设置
if (! $new_width && ! $new_height)
return;
// 获取图片属性
list ($width, $height, $type, $attr) = getimagesize($src_image);
switch ($type) {
case 1:
$img = imagecreatefromgif($src_image);
break;
case 2:
$img = imagecreatefromjpeg($src_image);
break;
case 3:
$img = imagecreatefrompng($src_image);
break;
}
// 不限定是等比例缩放
if (! $new_width) {
$new_width = floor($width * ($new_height / $height));
}
if (! $new_height) {
$new_height = floor($height * ($new_width / $width));
}
// 计算裁剪是变大缩小方式
if ($width >= $new_width && $height >= $new_height) { // 长宽均满足
$cut_width = $new_width;
$cut_height = $new_height;
} else { // 有一边不满足
$scale1 = $width / $new_width;
$scale2 = $height / $new_height;
if ($scale1 < $scale2) { // 变化越多的一边取全值,其余一边等比例缩放
$cut_width = $width;
$cut_height = floor($height * ($width / $new_width));
} else {
$cut_width = floor($new_width * ($height / $new_height));
$cut_height = $height;
}
}
// 创建画布
$new_img = imagecreatetruecolor($new_width, $new_height);
// 创建透明画布,避免黑色
if ($type == 1 || $type == 3) {
$color = imagecolorallocate($new_img, 255, 255, 255);
imagefill($new_img, 0, 0, $color);
imagecolortransparent($new_img, $color);
}
imagecopyresized($new_img, $img, 0, 0, 0, 0, $new_width, $new_height, $cut_width, $cut_height);
check_dir(dirname($out_image), true); // 检查输出目录
switch ($type) {
case 1:
imagegif($new_img, $out_image, $img_quality);
break;
case 2:
imagejpeg($new_img, $out_image, $img_quality);
break;
case 3:
imagepng($new_img, $out_image, $img_quality / 10); // $quality参数取值范围0-99 在php 5.1.2之后变更为0-9
break;
default:
imagejpeg($new_img, $out_image, $img_quality);
}
imagedestroy($new_img);
imagedestroy($img);
return true;
}
// 图片水印
function watermark_img($src_image, $out_image = null, $position = null, $watermark_image = null, $watermark_text = '', $watermark_text_size = null, $watermark_text_color = null)
{
if (! Config::get('watermark_open')) {
return;
}
// 输出地址
if (! $out_image)
$out_image = $src_image;
// 如果不存在文字及图片则直接返回
if (! $watermark_text) {
$watermark_text = Config::get('watermark_text') ?: 'PbootCMS';
}
$watermark_image = $watermark_image ?: Config::get('watermark_pic');
if (! $watermark_text && ! $watermark_image) {
return;
}
// 获取图片属性
list ($width1, $height1, $type1, $attr1) = getimagesize($src_image);
switch ($type1) {
case 1:
$img1 = imagecreatefromgif($src_image);
break;
case 2:
$img1 = imagecreatefromjpeg($src_image);
break;
case 3:
$img1 = imagecreatefrompng($src_image);
break;
}
if ($watermark_image) {
$watermark_image = ROOT_PATH . $watermark_image;
// 获取水印图片
list ($width2, $height2, $type2, $attr2) = getimagesize($watermark_image);
switch ($type2) {
case 1:
$img2 = imagecreatefromgif($watermark_image);
break;
case 2:
$img2 = imagecreatefromjpeg($watermark_image);
break;
case 3:
$img2 = imagecreatefrompng($watermark_image);
break;
}
} else {
if (! $watermark_text_size) {
$watermark_text_size = Config::get('watermark_text_size') ?: 16;
}
if (! $watermark_text_color) {
$watermark_text_color = Config::get('watermark_text_color') ?: '100,100,100';
}
$colors = explode(',', $watermark_text_color);
if (Config::get('watermark_text_font')) {
$font = ROOT_PATH . Config::get('watermark_text_font');
} else {
return;
}
// 手动创建水印图像
$fontsize = $watermark_text_size;
$width2 = mb_strlen($watermark_text, 'UTF-8') * ($fontsize + 10) + 20;
$height2 = $fontsize + 10;
$img2 = imagecreatetruecolor($width2, $height2);
$color = imagecolorallocate($img2, 255, 255, 255);
imagefill($img2, 0, 0, $color);
imagecolortransparent($img2, $color); // 创建透明图
$textcolor = imagecolorallocate($img2, $colors[0], $colors[1], $colors[2]);
imagettftext($img2, $fontsize, 0, 5, $fontsize + 5, $textcolor, $font, $watermark_text);
}
// 现对图片太大时,自动缩放水印
if ($width1 < $width2 * 3 || $height1 < $height2) {
$scale = min(($width1 / 3) / $width2, ($height1 / 2) / $height2); // 求缩放比例
$new_width = floor($scale * $width2);
$new_height = floor($scale * $height2);
} else {
$new_width = $width2;
$new_height = $height2;
}
// 水印位置
if (! $position) {
$position = Config::get('watermark_position') ?: 4;
}
switch ($position) {
case '1':
$x = 15;
$y = 15;
break;
case '2':
$x = $width1 - $new_width - 15;
$y = 20;
break;
case '3':
$x = 20;
$y = $height1 - $new_height - 15;
break;
case '5':
$x = ($width1 - $new_width) / 2;
$y = ($height1 - $new_height) / 2;
break;
default:
$x = $width1 - $new_width - 15;
$y = $height1 - $new_height - 15;
break;
}
// 创建透明画布,避免黑色
if ($type1 == 1 || $type1 == 3) {
$out = imagecreatetruecolor($width1, $height1);
$color = imagecolorallocate($out, 255, 255, 255);
imagefill($out, 0, 0, $color);
imagecolortransparent($out, $color);
imagecopy($out, $img1, 0, 0, 0, 0, $width1, $height1);
} else {
$out = $img1;
}
// 打上水印
imagecopyresized($out, $img2, $x, $y - 10, 0, 0, $new_width, $new_height, $width2, $height2);
check_dir(dirname($out_image), true); // 检查输出目录
// 输出图片
switch ($type1) {
case 1:
imagegif($out, $out_image, 90);
break;
case 2:
imagejpeg($out, $out_image, 90);
break;
case 3:
imagepng($out, $out_image, 90 / 10); // $quality参数取值范围0-99 在php 5.1.2之后变更为0-9
break;
default:
imagejpeg($out, $out_image, 90);
}
imagedestroy($img1);
imagedestroy($img2);
return true;
}

View File

@@ -0,0 +1,976 @@
<?php
/**
* @copyright (C)2016-2099 Hnaoyun Inc.
* @author XingMeng
* @email hnxsh@foxmail.com
* @date 2017年11月5日
*
*/
use core\basic\Config;
// 获取用户浏览器类型
function get_user_bs($bs = null)
{
if (isset($_SERVER["HTTP_USER_AGENT"])) {
$user_agent = strtolower($_SERVER["HTTP_USER_AGENT"]);
} else {
return null;
}
// 直接检测传递的值
if ($bs) {
if (strpos($user_agent, strtolower($bs))) {
return true;
} else {
return false;
}
}
// 固定检测
if (strpos($user_agent, 'micromessenger')) {
$user_bs = 'Weixin';
} elseif (strpos($user_agent, 'qq')) {
$user_bs = 'QQ';
} elseif (strpos($user_agent, 'weibo')) {
$user_bs = 'Weibo';
} elseif (strpos($user_agent, 'alipayclient')) {
$user_bs = 'Alipay';
} elseif (strpos($user_agent, 'trident/7.0')) {
$user_bs = 'IE11'; // 新版本IE优先避免360等浏览器的兼容模式检测错误
} elseif (strpos($user_agent, 'trident/6.0')) {
$user_bs = 'IE10';
} elseif (strpos($user_agent, 'trident/5.0')) {
$user_bs = 'IE9';
} elseif (strpos($user_agent, 'trident/4.0')) {
$user_bs = 'IE8';
} elseif (strpos($user_agent, 'msie 7.0')) {
$user_bs = 'IE7';
} elseif (strpos($user_agent, 'msie 6.0')) {
$user_bs = 'IE6';
} elseif (strpos($user_agent, 'edge')) {
$user_bs = 'Edge';
} elseif (strpos($user_agent, 'firefox')) {
$user_bs = 'Firefox';
} elseif (strpos($user_agent, 'chrome') || strpos($user_agent, 'android')) {
$user_bs = 'Chrome';
} elseif (strpos($user_agent, 'safari')) {
$user_bs = 'Safari';
} elseif (strpos($user_agent, 'mj12bot')) {
$user_bs = 'MJ12bot';
} else {
$user_bs = 'Other';
}
return $user_bs;
}
// 获取用户操作系统类型
function get_user_os($osstr = null)
{
if (isset($_SERVER["HTTP_USER_AGENT"])) {
$user_agent = strtolower($_SERVER["HTTP_USER_AGENT"]);
} else {
return null;
}
// 直接检测传递的值
if ($osstr) {
if (strpos($user_agent, strtolower($osstr))) {
return true;
} else {
return false;
}
}
if (strpos($user_agent, 'windows nt 5.0')) {
$user_os = 'Windows 2000';
} elseif (strpos($user_agent, 'windows nt 9')) {
$user_os = 'Windows 9X';
} elseif (strpos($user_agent, 'windows nt 5.1')) {
$user_os = 'Windows XP';
} elseif (strpos($user_agent, 'windows nt 5.2')) {
$user_os = 'Windows 2003';
} elseif (strpos($user_agent, 'windows nt 6.0')) {
$user_os = 'Windows Vista';
} elseif (strpos($user_agent, 'windows nt 6.1')) {
$user_os = 'Windows 7';
} elseif (strpos($user_agent, 'windows nt 6.2')) {
$user_os = 'Windows 8';
} elseif (strpos($user_agent, 'windows nt 6.3')) {
$user_os = 'Windows 8.1';
} elseif (strpos($user_agent, 'windows nt 10')) {
$user_os = 'Windows 10';
} elseif (strpos($user_agent, 'windows phone')) {
$user_os = 'Windows Phone';
} elseif (strpos($user_agent, 'android')) {
$user_os = 'Android';
} elseif (strpos($user_agent, 'iphone')) {
$user_os = 'iPhone';
} elseif (strpos($user_agent, 'ipad')) {
$user_os = 'iPad';
} elseif (strpos($user_agent, 'mac')) {
$user_os = 'Mac';
} elseif (strpos($user_agent, 'sunos')) {
$user_os = 'Sun OS';
} elseif (strpos($user_agent, 'bsd')) {
$user_os = 'BSD';
} elseif (strpos($user_agent, 'ubuntu')) {
$user_os = 'Ubuntu';
} elseif (strpos($user_agent, 'linux')) {
$user_os = 'Linux';
} elseif (strpos($user_agent, 'unix')) {
$user_os = 'Unix';
} else {
$user_os = 'Other';
}
return $user_os;
}
// 获取用户IP
function get_user_ip()
{
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$cip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
$cip = $_SERVER['HTTP_CLIENT_IP'];
} else {
$cip = $_SERVER['REMOTE_ADDR'];
}
if ($cip == '::1') { // 使用localhost时
$cip = '127.0.0.1';
}
if (! preg_match('/^[0-9\.]+$/', $cip)) { // 非标准的IP
$cip = '0.0.0.0';
}
return htmlspecialchars($cip);
}
// 执行URL请求并返回数据
function get_url($url, $fields = array(), $UserAgent = null, $vfSSL = false)
{
$SSL = substr($url, 0, 8) == "https://" ? true : false;
$ch = curl_init();
if ($UserAgent) { // 在HTTP请求中包含一个"User-Agent: "头的字符串。
curl_setopt($ch, CURLOPT_USERAGENT, $UserAgent);
} else {
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER["HTTP_USER_AGENT"]);
}
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60); // 在发起连接前等待的时间如果设置为0则无限等待
curl_setopt($ch, CURLOPT_TIMEOUT, 90); // 设置cURL允许执行的最长秒数
curl_setopt($ch, CURLOPT_URL, $url); // 设置请求地址
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // 设置cURL 参数,要求结果保存到字符串中还是输出到屏幕上。
// SSL验证
if ($SSL) {
if ($vfSSL) {
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_CAINFO, CORE_PATH . '/cacert.pem');
} else {
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 信任任何证书
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); // 不检查证书中是否设置域名
}
}
// 数据字段
if ($fields) {
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
}
$output = curl_exec($ch);
if (curl_errno($ch)) {
error('请求远程地址错误:' . curl_error($ch));
}
curl_close($ch);
return $output;
}
// 返回时间戳格式化日期时间,默认当前
function get_datetime($timestamp = null)
{
if (! $timestamp)
$timestamp = time();
return date('Y-m-d H:i:s', $timestamp);
}
// 返回时间戳格式化日期,默认当前
function get_date($timestamp = null)
{
if (! $timestamp)
$timestamp = time();
return date('Y-m-d', $timestamp);
}
// 返回时间戳差值部分,年、月、日
function get_date_diff($startstamp, $endstamp, $return = 'm')
{
$y = date('Y', $endstamp) - date('Y', $startstamp);
$m = date('m', $endstamp) - date('m', $startstamp);
switch ($return) {
case 'y':
if ($y <= 1) {
$y = $m / 12;
}
$string = $y;
break;
case 'm':
$string = $y * 12 + $m;
break;
case 'd':
$string = ($endstamp - $startstamp) / 86400;
break;
}
return $string;
}
// 生成无限极树,$data为二维数组数据
function get_tree($data, $tid, $idField, $pidField, $sonName = 'son')
{
$tree = array();
foreach ($data as $key => $value) {
if (is_array($value)) {
if ($value[$pidField] == "$tid") { // 父亲找到儿子
$value[$sonName] = get_tree($data, $value[$idField], $idField, $pidField, $sonName);
$tree[] = $value;
}
} else {
if ($value->$pidField == "$tid") { // 父亲找到儿子
$temp = clone $value;
$temp->$sonName = get_tree($data, $value->$idField, $idField, $pidField, $sonName);
$tree[] = $temp;
}
}
}
return $tree;
}
// 获取数据数组的映射数组
function get_mapping($array, $vValue, $vKey = null)
{
if (! $array)
return array();
foreach ($array as $key => $value) {
if (is_array($value)) {
if ($vKey) {
$result[$value[$vKey]] = $value[$vValue];
} else {
$result[] = $value[$vValue];
}
} elseif (is_object($value)) {
if ($vKey) {
$result[$value->$vKey] = $value->$vValue;
} else {
$result[] = $value->$vValue;
}
} else {
return $array;
}
}
return $result;
}
// 页码赋值异常返回1
function get_page()
{
if (isset($_GET['page'])) {
$value = trim($_GET['page']);
if (preg_match('/^[0-9]+$/', $value)) {
return $value;
}
}
return 1;
}
// 返回请求类型
function get_request_method()
{
return $_SERVER['REQUEST_METHOD'];
}
// 获取当前完整URL地址
function get_current_url()
{
$http_type = is_https() ? 'https://' : 'http://';
return $http_type . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
}
// 获取字符串第N次出现位置
function get_strpos($string, $find, $n)
{
$pos = strpos($string, $find);
for ($i = 2; $i <= $n; $i ++) {
$pos = strpos($string, $find, $pos + 1);
}
return $pos;
}
// array_column向下兼容低版本PHP
if (! function_exists('array_column')) {
function array_column($input, $columnKey, $indexKey = null)
{
$columnKeyIsNumber = (is_numeric($columnKey)) ? true : false;
$indexKeyIsNull = (is_null($indexKey)) ? true : false;
$indexKeyIsNumber = (is_numeric($indexKey)) ? true : false;
$result = array();
foreach ((array) $input as $key => $row) {
if ($columnKeyIsNumber) {
$tmp = array_slice($row, $columnKey, 1);
$tmp = (is_array($tmp) && ! empty($tmp)) ? current($tmp) : null;
} else {
$tmp = isset($row[$columnKey]) ? $row[$columnKey] : null;
}
if (! $indexKeyIsNull) {
if ($indexKeyIsNumber) {
$key = array_slice($row, $indexKey, 1);
$key = (is_array($key) && ! empty($key)) ? current($key) : null;
$key = is_null($key) ? 0 : $key;
} else {
$key = isset($row[$indexKey]) ? $row[$indexKey] : 0;
}
}
$result[$key] = $tmp;
}
return $result;
}
}
/**
* 系统信息弹出解析函数
*
* @param string $info_tpl模板
* @param string $string内容
* @param string $jump_url跳转地址
* @param number $time时间
*/
function parse_info_tpl($info_tpl, $string, $jump_url = null, $time = 0)
{
if (file_exists($info_tpl)) {
$tpl_content = file_get_contents($info_tpl);
if ($jump_url) {
$timeout_js = "<script>var timeout = {time};var showbox = document.getElementById('time');show();function show(){showbox.innerHTML = timeout+ ' 秒后自动跳转';timeout--;if (timeout == 0) {window.location.href = '{url}';}else {setTimeout(function(){show();}, 1000);}}</script>";
} else {
$timeout_js = '';
}
$tpl_content = str_replace('{js}', $timeout_js, $tpl_content);
$tpl_content = str_replace('{info}', $string, $tpl_content);
$tpl_content = str_replace('{url}', $jump_url, $tpl_content);
$tpl_content = str_replace('{time}', $time, $tpl_content);
$tpl_content = str_replace('{sitedir}', SITE_DIR, $tpl_content);
$tpl_content = str_replace('{coredir}', CORE_DIR, $tpl_content);
$tpl_content = str_replace('{appversion}', APP_VERSION . '-' . RELEASE_TIME, $tpl_content);
$tpl_content = str_replace('{serveros}', PHP_OS, $tpl_content);
$tpl_content = str_replace('{serversoft}', $_SERVER['SERVER_SOFTWARE'], $tpl_content);
return $tpl_content;
} else {
exit('<div style="font-size:50px;">:(</div>提示信息的模板文件不存在!');
}
}
// 获取转义数据,支持字符串、数组、对象
function escape_string($string)
{
if (! $string)
return $string;
if (is_array($string)) { // 数组处理
foreach ($string as $key => $value) {
$string[$key] = escape_string($value);
}
} elseif (is_object($string)) { // 对象处理
foreach ($string as $key => $value) {
$string->$key = escape_string($value);
}
} else { // 字符串处理
$string = htmlspecialchars(trim($string), ENT_QUOTES, 'UTF-8');
$string = addslashes($string);
}
return $string;
}
// 字符反转义html实体及斜杠支持字符串、数组、对象
function decode_string($string)
{
if (! $string)
return $string;
if (is_array($string)) { // 数组处理
foreach ($string as $key => $value) {
$string[$key] = decode_string($value);
}
} elseif (is_object($string)) { // 对象处理
foreach ($string as $key => $value) {
$string->$key = decode_string($value);
}
} else { // 字符串处理
$string = stripcslashes($string);
$string = htmlspecialchars_decode($string, ENT_QUOTES);
}
$string = preg_replace_r('/pboot:if/i', 'pboot@if', $string); // 避免解码绕过问题
return $string;
}
// 字符反转义斜杠,支持字符串、数组、对象
function decode_slashes($string)
{
if (! $string)
return $string;
if (is_array($string)) { // 数组处理
foreach ($string as $key => $value) {
$string[$key] = decode_slashes($value);
}
} elseif (is_object($string)) { // 对象处理
foreach ($string as $key => $value) {
$string->$key = decode_slashes($value);
}
} else { // 字符串处理
$string = stripcslashes($string);
}
return $string;
}
// 字符串双层MD5加密
function encrypt_string($string)
{
return md5(md5($string));
}
// 生成唯一标识符
function get_uniqid()
{
return encrypt_string(uniqid(mt_rand(), true));
}
// 清洗html代码的空白符号
function clear_html_blank($string)
{
$string = str_replace("\r\n", '', $string); // 清除换行符
$string = str_replace("\n", '', $string); // 清除换行符
$string = str_replace("\t", '', $string); // 清除制表符
$string = str_replace(' ', '', $string); // 清除大空格
$string = str_replace('&nbsp;', '', $string); // 清除 &nbsp;
$string = preg_replace('/\s+/', ' ', $string); // 清除空格
return $string;
}
// 去除字符串两端斜线
function trim_slash($string)
{
return trim($string, '/');
}
// 驼峰转换下划线加小写字母
function hump_to_underline($string)
{
return strtolower(preg_replace('/(?<=[a-z])([A-Z])/', '_$1', $string));
}
// 转换对象为数组
function object_to_array($object)
{
return json_decode(json_encode($object), true);
}
// 转换数组为对象
function array_to_object($array)
{
return json_decode(json_encode($array));
}
// 值是否在对象中
function in_object($needle, $object)
{
foreach ($object as $value) {
if ($needle == $value)
return true;
}
}
// 结果集中查找指定字段父节点是否存在
function result_value_search($needle, $result, $skey)
{
foreach ($result as $key => $value) {
if ($value->$skey == $needle) {
return $key;
}
}
return false;
}
// 多维数组合并
function mult_array_merge($array1, $array2)
{
if (is_array($array2)) {
foreach ($array2 as $key => $value) {
if (is_array($value)) {
if (array_key_exists($key, $array1)) {
$array1[$key] = mult_array_merge($array1[$key], $value);
} else {
$array1[$key] = $value;
}
} else {
$array1[$key] = $value;
}
}
}
return $array1;
}
// 数组转换为带引号字符串
function implode_quot($glue, array $pieces, $diffnum = false)
{
if (! $pieces)
return "''";
foreach ($pieces as $key => $value) {
if ($diffnum && ! is_numeric($value)) {
$value = "'$value'";
} elseif (! $diffnum) {
$value = "'$value'";
}
if (isset($string)) {
$string .= $glue . $value;
} else {
$string = $value;
}
}
return $string;
}
// 是否为多维数组,是返回true
function is_multi_array($array)
{
if (is_array($array)) {
return (count($array) != count($array, 1));
} else {
return false;
}
}
// 是否为移动设备
function is_mobile()
{
$os = get_user_os();
if ($os == 'Android' || $os == 'iPhone' || $os == 'Windows Phone' || $os == 'iPad') {
return true;
}
}
// 是否为POST请求
function is_post()
{
if ($_POST) {
return true;
} else {
return false;
}
}
// 是否为GET请求
function is_get()
{
if ($_GET) {
return true;
} else {
return false;
}
}
// 是否为PUT请求
function is_put()
{
if ($_SERVER['REQUEST_METHOD'] == 'PUT') {
return true;
} else {
return false;
}
}
// 是否为PATCH请求
function is_patch()
{
if ($_SERVER['REQUEST_METHOD'] == 'PATCH') {
return true;
} else {
return false;
}
}
// 是否为DELETE请求
function is_delete()
{
if ($_SERVER['REQUEST_METHOD'] == 'DELETE') {
return true;
} else {
return false;
}
}
// 是否为AJAX请求
function is_ajax()
{
if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
return true;
} else {
return false;
}
}
// 判断当前是否为https
function is_https()
{
if ((isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on')) {
return true;
} elseif (isset($_SERVER['REQUEST_SCHEME']) && strtolower($_SERVER['REQUEST_SCHEME']) == 'https') {
return true;
} elseif (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) == 'https') {
return true;
} elseif (isset($_SERVER['HTTP_X_CLIENT_SCHEME']) && strtolower($_SERVER['HTTP_X_CLIENT_SCHEME']) == 'https') {
return true;
} else {
return false;
}
}
// 获取当前访问地址
function get_http_url($noport = false)
{
if (is_https()) {
$url = 'https://' . $_SERVER['HTTP_HOST'];
} else {
$url = 'http://' . $_SERVER['HTTP_HOST'];
}
if ($noport) {
$url = str_replace(':' . $_SERVER['SERVER_PORT'], '', $url);
}
return $url;
}
// 获取当前访问域名
function get_http_host($noport = true)
{
if ($noport) {
return str_replace(':' . $_SERVER['SERVER_PORT'], '', $_SERVER['HTTP_HOST']);
} else {
return $_SERVER['HTTP_HOST'];
}
}
// 服务器信息
function get_server_info()
{
// 定义输出常量
define('YES', 'Yes');
define('NO', '<span style="color:red">No</span>');
// 服务器系统
$data['php_os'] = PHP_OS;
// 服务器访问地址
$data['http_host'] = $_SERVER['HTTP_HOST'];
// 服务器名称
$data['server_name'] = $_SERVER['SERVER_NAME'];
// 服务器端口
$data['server_port'] = $_SERVER['SERVER_PORT'];
// 服务器地址
$data['server_addr'] = isset($_SERVER['LOCAL_ADDR']) ? $_SERVER['LOCAL_ADDR'] : $_SERVER['SERVER_ADDR'];
// 服务器软件
$data['server_software'] = $_SERVER['SERVER_SOFTWARE'];
// 站点目录
$data['document_root'] = isset($_SERVER['DOCUMENT_ROOT']) ? $_SERVER['DOCUMENT_ROOT'] : DOC_PATH;
// PHP版本
$data['php_version'] = PHP_VERSION;
// 数据库驱动
$data['db_driver'] = Config::get('database.type');
// php配置文件
$data['php_ini'] = @php_ini_loaded_file();
// 最大上传
$data['upload_max_filesize'] = ini_get('upload_max_filesize');
// 最大提交
$data['post_max_size'] = ini_get('post_max_size');
// 最大提交文件数
$data['max_file_uploads'] = ini_get('max_file_uploads');
// 内存限制
$data['memory_limit'] = ini_get('memory_limit');
// 检测gd扩展
$data['gd'] = extension_loaded('gd') ? YES : NO;
// 检测imap扩展
$data['imap'] = extension_loaded('imap') ? YES : NO;
// 检测socket扩展
$data['sockets'] = extension_loaded('sockets') ? YES : NO;
// 检测curl扩展
$data['curl'] = extension_loaded('curl') ? YES : NO;
// 会话保存路径
$data['session_save_path'] = session_save_path() ?: $_SERVER['TMP'];
// 检测standard库是否存在
$data['standard'] = extension_loaded('standard') ? YES : NO;
// 检测多线程支持
$data['pthreads'] = extension_loaded('pthreads') ? YES : NO;
// 检测XCache支持
$data['xcache'] = extension_loaded('XCache') ? YES : NO;
// 检测APC支持
$data['apc'] = extension_loaded('APC') ? YES : NO;
// 检测eAccelerator支持
$data['eaccelerator'] = extension_loaded('eAccelerator') ? YES : NO;
// 检测wincache支持
$data['wincache'] = extension_loaded('wincache') ? YES : NO;
// 检测ZendOPcache支持
$data['zendopcache'] = extension_loaded('Zend OPcache') ? YES : NO;
// 检测memcache支持
$data['memcache'] = extension_loaded('memcache') ? YES : NO;
// 检测memcached支持
$data['memcached'] = extension_loaded('memcached') ? YES : NO;
// 已经安装模块
$loaded_extensions = get_loaded_extensions();
$extensions = '';
foreach ($loaded_extensions as $key => $value) {
$extensions .= $value . ', ';
}
$data['extensions'] = $extensions;
return json_decode(json_encode($data));
}
// 获取数据库类型
function get_db_type()
{
switch (Config::get('database.type')) {
case 'mysqli':
case 'pdo_mysql':
$db = 'mysql';
break;
case 'sqlite':
case 'pdo_sqlite':
$db = 'sqlite';
break;
case 'pdo_pgsql':
$db = 'pgsql';
break;
default:
$db = null;
}
return $db;
}
// 获取间隔的月份的起始及结束日期
function get_month_days($date, $start = 0, $interval = 1, $retamp = false)
{
$timestamp = strtotime($date) ?: $date;
$first_day = strtotime(date('Y', $timestamp) . '-' . date('m', $timestamp) . '-01 +' . $start . ' month');
$last_day = strtotime(date('Y-m-d', $first_day) . ' +' . $interval . ' month -1 day');
if ($retamp) {
$return = array(
'first' => $first_day,
'last' => $last_day
);
} else {
$return = array(
'first' => date('Y-m-d', $first_day),
'last' => date('Y-m-d', $last_day)
);
}
return $return;
}
// 框架地址地址前缀
function url_index_path($indexfile = null)
{
$indexfile = $indexfile ?: $_SERVER["SCRIPT_NAME"];
if (Config::get('app_url_type') == 2 && strripos($indexfile, 'index.php') !== false) {
return SITE_DIR;
} elseif (Config::get('app_url_type') == 3 && strripos($indexfile, 'index.php') !== false) {
return SITE_DIR . '/?p=';
} elseif (Config::get('app_url_type') == 3 && strripos($indexfile, 'index.php') === false) {
return $indexfile . '?p=';
} else {
return $indexfile;
}
}
// 获取服务端web软件
function get_server_soft()
{
$soft = strtolower($_SERVER["SERVER_SOFTWARE"]);
if (strpos($soft, 'iis')) {
return 'iis';
} elseif (strpos($soft, 'apache')) {
return 'apache';
} elseif (strpos($soft, 'nginx')) {
return 'nginx';
} else {
return 'other';
}
}
// 创建会话层级目录
function create_session_dir($path, $depth)
{
if ($depth < 1) {
return;
} else {
$depth --;
}
$char = array(
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
'j',
'k',
'l',
'm',
'n',
'o',
'p',
'q',
'r',
's',
't',
'u',
'v'
);
foreach ($char as $value) {
if (! check_dir($path . '/' . $value, true)) {
error('会话目录写入权限不足!');
}
create_session_dir($path . '/' . $value, $depth);
}
}
// 中英混合的字符串截取,以一个汉字为一个单位长度,英文为半个
function substr_both($string, $strat, $length)
{
$s = 0; // 起始位置
$i = 0; // 实际Byte计数
$n = 0; // 字符串长度计数
$str_length = strlen($string); // 字符串的字节长度
while (($n < $length) and ($i < $str_length)) {
$ascnum = Ord(substr($string, $i, 1)); // 得到字符串中第$i位字符的ascii码
if ($ascnum >= 224) { // 根据UTF-8编码规范将3个连续的字符计为单个字符
$i += 3;
$n ++;
} elseif ($ascnum >= 192) { // 根据UTF-8编码规范将2个连续的字符计为单个字符
$i += 2;
$n ++;
} else {
$i += 1;
$n += 0.5;
}
if ($s == 0 && $strat > 0 && $n >= $strat) {
$s = $i; // 记录起始位置
}
}
if ($n < $strat) { // 起始位置大于字符串长度
return;
}
return substr($string, $s, $i);
}
// 中英混合的字符串长度,以一个汉字为一个单位长度,英文为半个
function strlen_both($string)
{
$i = 0; // 实际Byte计数
$n = 0; // 字符串长度计数
$str_length = strlen($string); // 字符串的字节长度
while ($i < $str_length) {
$ascnum = Ord(substr($string, $i, 1)); // 得到字符串中第$i位字符的ascii码
if ($ascnum >= 224) { // 根据UTF-8编码规范将3个连续的字符计为单个字符
$i += 3;
$n ++;
} elseif ($ascnum >= 192) { // 根据UTF-8编码规范将2个连续的字符计为单个字符
$i += 2;
$n ++;
} else {
$i += 1;
$n += 0.5;
}
}
return $n;
}
// 获取地址参数
function query_string($unset = null)
{
if (isset($_SERVER["QUERY_STRING"]) && ! ! $qs = $_SERVER["QUERY_STRING"]) {
parse_str($qs, $output);
unset($output['page']);
$unset = strpos($unset, ',') ? explode(',', $unset) : $unset;
if (is_array($unset)) {
foreach ($unset as $value) {
if (isset($output[$value])) {
unset($output[$value]);
}
}
} else {
if (isset($output[$unset])) {
unset($output[$unset]);
}
}
// 避免路径参数编码
if (isset($output['p'])) {
$p = 'p=' . $output['p'];
unset($output['p']);
$qs = $output ? $p . '&' . http_build_query($output) : $p;
} else {
$qs = http_build_query($output);
}
}
return $qs ? '?' . $qs : '';
}
// 判断是否在子网
function network_match($ip, $network)
{
if (strpos($network, '/') > 0) {
$network = explode('/', $network);
$move = 32 - $network[1];
if ($network[1] == 0) {
return true;
}
return ((ip2long($ip) >> $move) === (ip2long($network[0]) >> $move)) ? true : false;
} elseif ($network == $ip) {
return true;
} else {
return false;
}
}
// 递归替换
function preg_replace_r($search, $replace, $subject)
{
while (preg_match($search, $subject)) {
$subject = preg_replace($search, $replace, $subject);
}
return $subject;
}
// 生成随机验证码
function create_code($len = 4)
{
$charset = 'ABCDEFGHKMNPRTUVWXY23456789';
$charset = str_shuffle($charset);
$charlen = strlen($charset) - 1;
$code = '';
for ($i = 0; $i < $len; $i ++) {
$code .= $charset[mt_rand(0, $charlen)];
}
return $code;
}

View File

@@ -0,0 +1,733 @@
<?php
/**
* @copyright (C)2016-2099 Hnaoyun Inc.
* @author XingMeng
* @email hnxsh@foxmail.com
* @date 2017年11月5日
* 助手函数
*/
use core\basic\Config;
use core\basic\Json;
use core\view\View;
use core\view\Paging;
use core\basic\Response;
use core\basic\Url;
use core\basic\Basic;
use core\basic\Smtp;
/**
* 生成实际跳转路径
*
* @param string $url
* 接收控制器方法访问完整路径,如:/home/index/index
* @return mixed
*/
function url($url, $suffix = false)
{
return Url::get($url, $suffix);
}
/**
* 生成前端路径
*
* @param string $url
* 前端地址参数
* @return mixed
*/
function homeurl($url, $suffix = null, $qs = null)
{
return Url::home($url, $suffix, $qs);
}
/**
* 自定义错误页面
*
* @param string $_string内容
* @param string $_url跳转地址
* @param number $_time时间
*/
function error($string, $jump_url = null, $time = 2)
{
@ob_clean();
if (! $string)
$string = '未知错误!';
if ($jump_url == '-1' && isset($_SERVER['HTTP_REFERER'])) {
$jump_url = $_SERVER['HTTP_REFERER'];
if (strpos($jump_url, get_http_url()) !== 0) {
$jump_url = '/';
}
} elseif ($jump_url == '-1') {
$jump_url = null;
}
if (Config::get('return_data_type') == 'json' || is_ajax()) { // 接口模型返回格式数据
Response::json(0, strip_tags($string), $jump_url);
} else {
$err_tpl = CORE_PATH . '/template/error.html';
echo parse_info_tpl($err_tpl, $string, $jump_url, $time);
}
exit();
}
/**
* 自定义错误页面
*
* @param string $_string内容
* @param string $_url跳转地址
* @param number $_time时间
*/
function success($string, $jump_url = null, $time = 2)
{
if ($jump_url == '-1' && isset($_SERVER['HTTP_REFERER'])) {
$jump_url = $_SERVER['HTTP_REFERER'];
if (strpos($jump_url, get_http_url()) !== 0) {
$jump_url = '/';
}
} elseif ($jump_url == '-1') {
$jump_url = null;
}
if (Config::get('return_data_type') == 'json' || is_ajax()) { // 接口模型返回格式数据
Response::json(1, strip_tags($string), $jump_url);
} else {
$err_tpl = CORE_PATH . '/template/success.html';
echo parse_info_tpl($err_tpl, $string, $jump_url, $time);
}
exit();
}
/**
* 弹窗
*
* @param string $info信息
*/
function alert($info, $status = 0)
{
if (Config::get('return_data_type') == 'json' || is_ajax()) { // 接口模型返回格式数据
Response::json($status, strip_tags($info));
} else {
echo '<script type="text/javascript">alert("' . clear_html_blank($info) . '");</script>';
}
}
/**
* 弹窗并返回前页
*
* @param string $info信息
*/
function alert_back($info, $status = 0)
{
if (Config::get('return_data_type') == 'json' || is_ajax()) { // 接口模型返回格式数据
Response::json($status, strip_tags($info));
} else {
echo '<script type="text/javascript">alert("' . clear_html_blank($info) . '");window.history.go(-1);</script>';
exit();
}
}
/**
* 跳转
*
* @param string $url跳转地址
*/
function location($url)
{
if ($url == '-1' && isset($_SERVER['HTTP_REFERER'])) {
$url = $_SERVER['HTTP_REFERER'];
if (strpos($url, get_http_url()) !== 0) {
$url = '/';
}
}
header('Location:' . $url);
exit();
}
/**
* 弹窗并跳转
*
* @param string $info信息
* @param string $url跳转地址
*/
function alert_location($info, $url, $status = 0)
{
if ($url == '-1' && isset($_SERVER['HTTP_REFERER'])) {
$url = $_SERVER['HTTP_REFERER'];
if (strpos($url, get_http_url()) !== 0) {
$url = '/';
}
}
if (Config::get('return_data_type') == 'json' || is_ajax()) { // 接口模型返回格式数据
Response::json($status, strip_tags($info), $url);
} else {
echo '<script type="text/javascript">alert("' . clear_html_blank($info) . '");location.href="' . $url . '";</script>';
exit();
}
}
/**
* 弹窗并关闭
*
* @param string $info信息
*/
function alert_close($info, $status = 0)
{
if (Config::get('return_data_type') == 'json' || is_ajax()) { // 接口模型返回格式数据
Response::json($status, strip_tags($info));
} else {
echo '<script type="text/javascript">alert("' . clear_html_blank($info) . '");window.close();</script>';
exit();
}
}
/**
* 实例化模型对象助手
*
* @param string $name
* 需要实力化的模型名称
* @param string $new
* 是否强制新建对象
* @return mixed
*/
function model($name = null, $new = false)
{
return Basic::createModel($name, $new);
}
/**
* api读取数据
*
* @param string $name
* 接口名称add或 admin.user.addd
* @param array $param
* 参数
* @param string $rsOriginal
* 结果不处理直接返回
* @param string $jsonRsArray
* 返回Json数组方式
* @return mixed
*/
function api($args = null)
{
return Basic::createApi(func_get_args());
}
// 输出模板内容
function display($tpl)
{
$view = View::getInstance();
echo $view->parser($tpl);
}
// 解析模板内容
function parser($tpl)
{
$view = View::getInstance();
return $view->parser($tpl);
}
// 设置模板
function set_theme($theme_name)
{
$view = View::getInstance();
$view->assign('theme', $theme_name);
}
// 注入模板变量
function assign($var, $value)
{
$view = View::getInstance();
$view->assign($var, $value);
}
// 变量获取接口
function get_var($var)
{
$view = View::getInstance();
return $view->getVar($var);
}
// 手动生成分页信息,返回限制语句
function page($tatal, $morePageStr = false)
{
$page = Paging::getInstance();
return $page->limit($tatal, $morePageStr);
}
// 内容输出助手函数
function response($data)
{
return core\basic\Response::handle($data);
}
// Json内容输出助手函数
function json($code, $data, $tourl = null)
{
return core\basic\Response::json($code, $data, $tourl);
}
/**
* 数据过滤
*
* @param mixed $varname
* 字符串或参数名称
* @param array $condition
* array('d_source'=>'post','d_none'=>true,'d_require'=>true,'d_type'=>'int','d_max'=>5,'d_min'=2,'d_default'=>'')
* 字段名称:$varname,用字段名称做key传递文本
* 数据源:d_source[post、get、cookie、session、both、string]
* 是否允许空d_none[true、false],如果为false接受的收据为空则直接报错
* 是否必须d_require[true、false],如果为true意味着如果数据不满足要求直接报错否则返回null
* 数据类型d_type[int、float、num、letter、var、bool、date、array、object]
* 正则表达d_regular接受正则表达式
* 最大值|最大长度d_max
* 最小值|最小长度d_min
* 默认值d_default
* @return mixed
*/
function filter($varname, $condition)
{
// 变量名称文本
if (array_key_exists($varname, $condition) && $condition[$varname]) {
$vartext = $condition[$varname];
} else {
$vartext = $varname;
}
// 数据源
if (array_key_exists('d_source', $condition)) {
switch ($condition['d_source']) {
case 'post':
$data = @$_POST[$varname];
break;
case 'get':
$data = @$_GET[$varname];
break;
case 'cookie':
$data = @$_COOKIE[$varname];
break;
case 'session':
$data = session($varname);
break;
case 'both':
$data = @$_POST[$varname] ?: @$_GET[$varname];
break;
case 'string':
$data = $varname;
default:
error($vartext . '数据获取方式设置错误!');
}
// 去空格
if (is_string($data))
$data = trim($data);
} else {
$data = $varname; // 没有数据源指定时直接按照字符串过滤处理
}
// 数据为空时,进行是否允许空检测
if (! $data && array_key_exists('d_none', $condition) && $condition['d_none'] === false) {
error($vartext . '不能为空!');
}
// 判断是否强制检测为true时意味着如果数据不满足要求直接报错否则返回null
if (array_key_exists('d_require', $condition) && $condition['d_require'] == true) {
$require = true;
} else {
$require = false;
}
// 数据类型检测
if (array_key_exists('d_type', $condition)) {
switch ($condition['d_type']) {
case 'int':
if (! preg_match('/^[0-9]+$/', $data)) {
$err = '必须为整数!';
}
break;
case 'float':
if (! is_float($data)) {
$err = '必须为浮点数!';
}
break;
case 'num':
if (! is_numeric($data)) {
$err = '必须为数字!';
}
break;
case 'letter':
if (! preg_match('/^[a-zA-Z]+$/', $data)) {
$err = '只能包含字母!';
}
break;
case 'var':
if (! preg_match('/^[\w\-\.]+$/', $data)) {
$err = '只能包含字母、数字、划线、点!';
}
break;
case 'bool':
if (! is_bool($data)) {
$err = '必须为布尔类型!';
}
break;
case 'date':
if (! strtotime($data)) {
$err = '必须为日期类型!';
}
break;
case 'array':
if (! is_array($data)) {
$err = '必须为数组类型!';
}
break;
case 'object':
if (! is_object($data)) {
$err = '必须为对象类型!';
}
break;
case 'vars':
if (! preg_match('/^[\x{4e00}-\x{9fa5}\w\-\.,\s]+$/u', $data)) {
$err = '只能包含中文、字母、数字、横线、点、逗号、空格!';
}
break;
default:
if ($condition['d_type'])
error($vartext . '数据类型设置错误!');
}
}
// 非必须或必须但无错误时执行
if ((! $require || ($require && ! isset($err)))) {
// 正则匹配
if (array_key_exists('d_regular', $condition)) {
if (! preg_match($condition['d_regular'], $data)) {
$err = '不符合正则表达式规则!';
}
}
// 最大值匹配
if (array_key_exists('d_max', $condition)) {
if (is_numeric($data)) {
if ($data > $condition['d_max']) {
$err = '不能大于' . $condition['d_max'];
}
} else {
if (mb_strlen($data) > $condition['d_max']) {
$err = '长度不能大于' . $condition['d_max'];
}
}
}
// 最小值匹配
if (array_key_exists('d_min', $condition)) {
if (is_numeric($data)) {
if ($data < $condition['d_min']) {
$err = '不能小于' . $condition['d_min'];
}
} else {
if (mb_strlen($data) < $condition['d_min']) {
$err = '长度不能小于' . $condition['d_min'];
}
}
}
}
// 如果为必须且有错误,则显示错误,如果非必须但有错误则设置数据为null
if ($require && isset($err)) {
error($vartext . $err);
} elseif (isset($err)) {
$data = null;
}
// 如果设置有默认值,默认值
if (array_key_exists('d_default', $condition)) {
$data = (! is_null($data)) ? $data : $condition['d_default'];
}
if (is_string($data)) {
$data = trim($data); // 去空格
$data = preg_replace_r('/(x3c)|(x3e)/', '', $data); // 去十六进制括号
$data = preg_replace_r('/pboot:if/i', 'pboot@if', $data); // 过滤插入cms条件语句
$data = preg_replace_r('/pboot:sql/i', 'pboot@sql', $data); // 过滤插入cms条件语句
$data = preg_replace_r('/GET\[/i', 'GET@[', $data);
$data = preg_replace_r('/POST\[/i', 'POST@[', $data);
}
// 销毁错误
unset($err);
// 返回收据
return escape_string($data);
}
/**
* 获取GET参数
*
* @param string $name
* 参数名称
* @param mixed $type
* 数据类型
* @param string $require
* 是否为必须为true是如果不满足条件直接错误
* @param string $vartext
* 变量描述文本
* @param string $default
* 在非必需情况下默认值
* @return mixed
*/
function get($name, $type = null, $require = false, $vartext = null, $default = null)
{
$condition = array(
'd_source' => 'get',
'd_type' => $type,
'd_require' => $require,
$name => $vartext,
'd_default' => $default
);
return filter($name, $condition);
}
/**
* * 获取POST参数
*
* @param string $name
* 参数名称
* @param mixed $type
* 数据类型
* @param string $require
* 是否为必须为true是如果不满足条件直接错误
* @param string $vartext
* 变量描述文本
* @param string $default
* 在非必需情况下默认值
* @return mixed
*/
function post($name, $type = null, $require = false, $vartext = null, $default = null)
{
$condition = array(
'd_source' => 'post',
'd_type' => $type,
'd_require' => $require,
$name => $vartext,
'd_default' => $default
);
return filter($name, $condition);
}
/**
* * 获取参数post或get
*
* @param string $name
* 参数名称
* @param mixed $type
* 数据类型
* @param string $require
* 是否为必须为true是如果不满足条件直接错误
* @param string $vartext
* 变量描述文本
* @param string $default
* 在非必需情况下默认值
* @return mixed
*/
function request($name, $type = null, $require = false, $vartext = null, $default = null)
{
if (isset($_POST[$name])) {
$d_source = 'post';
} else {
$d_source = 'get';
}
$condition = array(
'd_source' => $d_source,
'd_type' => $type,
'd_require' => $require,
$name => $vartext,
'd_default' => $default
);
return filter($name, $condition);
}
/**
* 读取或写入Cookie信息
*
* @param string $name
* 名称
* @param string $value
* 值
* @param int $expire
* 秒数
* @param string $path
* 路径,默认站点目录
*/
function cookie($name, $value = null, $expire = null, $path = null, $domain = null, $secure = null, $httponly = true)
{
if (! is_null($value)) {
$path = SITE_DIR . '/';
if (is_string($value))
$value = trim($value);
$_COOKIE[$name] = $value; // 让cookie立即生效
if (! is_null($expire)) {
return setcookie($name, $value, time() + $expire, $path, $domain, $secure, $httponly);
} else {
return setcookie($name, $value, 0, $path, $domain, $secure, $httponly);
}
} else {
if (isset($_COOKIE[$name])) {
return escape_string($_COOKIE[$name]);
} else {
return null;
}
}
}
/**
* 读取或写入session信息
*
* @param string $name
* 支持点分多级获取
* @param mixed $value
* 设置值
* @return string|NULL|unknown
*/
function session($name, $value = null)
{
if (! isset($_SESSION)) {
session_start(); // 自动启动会话
}
if (! is_null($value)) {
if (isset($_SESSION[$name])) {
if ($_SESSION[$name] != $value) {
$_SESSION[$name] = $value;
}
} else {
$_SESSION[$name] = $value;
}
return $value;
} else {
if (strpos($name, '.')) {
if (isset($_SESSION[$name])) {
return $_SESSION[$name];
}
$names = explode('.', $name);
if (! isset($_SESSION[$names[0]])) {
return null;
}
$var = $_SESSION[$names[0]];
$len = count($names);
for ($i = 1; $i < $len; $i ++) {
if (is_array($var)) {
if (isset($var[$names[$i]])) {
$var = $var[$names[$i]];
} else {
return null;
}
} elseif (is_object($var)) {
if (isset($var->{$names[$i]})) {
$var = $var->{$names[$i]};
} else {
return null;
}
} else {
break;
}
}
return $var;
} else {
if (isset($_SESSION[$name])) {
return $_SESSION[$name];
} else {
return null;
}
}
}
}
// 检查会话参数是否存在
function issetSession($name)
{
if (! isset($_SESSION)) {
session_start(); // 自动启动会话
}
return isset($_SESSION[$name]);
}
/**
* 快速发送邮件函数
*
* @param array $config
* 邮件服务器连接数组,需包含 smtp_server、smtp_username、smtp_password、smtp_port、smtp_port
* @param string $to
* 邮件接收人
* @param string $subject
* 邮件主题
* @param string $body
* 邮件正文
*/
function sendmail(array $config, $to, $subject, $body)
{
$smtp = new Smtp($config['smtp_server'], $config['smtp_username'], $config['smtp_password'], $config['smtp_port'], $config['smtp_ssl']);
if ($smtp->sendMail($to, $subject, $body)) {
return true;
} else {
return $smtp->error();
}
}
// 发送短信
function sendsms(array $config, $to, $content)
{
if (! $to || ! $content) {
return false;
}
if (! isset($config['sms_account']) || ! isset($config['sms_pwd']) || ! isset($config['sms_signid'])) {
alert_back('短信发送参数配置有误');
}
$data['Account'] = $config['sms_account'];
$data['Pwd'] = $config['sms_pwd'];
$data['SignId'] = $config['sms_signid'];
$data['Content'] = $content;
$to = str_replace("\r\n", ",", $to); // 替换回车
$to = str_replace("", ",", $to); // 替换中文逗号分割符
$data['Mobile'] = str_replace(" ", "", $to); // 替换空格
$url = "http://api.feige.ee/SmsService/Send";
if (! ! $res = get_url($url, $data)) {
$result = json_decode($res);
if (! ($result->Code === 0)) {
error('短信发送失败,' . $result->Message);
} else {
return true;
}
}
}
// 查询短信余额
function get_sms_balance(array $config)
{
$data['Account'] = $config['sms_account'];
$data['Pwd'] = $config['sms_pwd'];
$url = "http://api.feige.ee/Account/Balance";
if (! ! $res = get_url($url, $data)) {
$result = json_decode($res);
if (! ($result->Code === 0)) {
error('查询失败,' . $result->Message);
} else {
return $result->Balance;
}
}
}
// 返回404页面,文件中可使用{info}替换提示信息
function _404($string, $jump_url = null, $time = 2)
{
header('HTTP/1.1 404 Not Found');
header('status: 404 Not Found');
$file_404 = ROOT_PATH . '/404.html';
if (file_exists($file_404)) {
echo parse_info_tpl($file_404, $string, $jump_url, $time);
exit();
} else {
error($string, $jump_url, $time);
}
}

View File

@@ -0,0 +1,396 @@
<?php
/**
* @copyright (C)2016-2099 Hnaoyun Inc.
* @author XingMeng
* @email hnxsh@foxmail.com
* @date 2016年11月6日
* 分页控制类
*/
namespace core\view;
use core\basic\Config;
class Paging
{
// 每页数量
public $pageSize;
// 当前页码
public $page;
// 数字条数量
public $num = 5;
// 调整数量
public $start = 1;
// 总记录
private $rowTotal = 0;
// 页面数量
private $pageCount;
// 存储前置URL
private $preUrl;
// 分页实例
private static $paging;
private function __construct()
{
// 禁用类new实例化
}
// 获取单一实例
public static function getInstance()
{
if (! self::$paging) {
self::$paging = new self();
}
return self::$paging;
}
// 限制语句
public function limit($total = null, $morePageStr = false)
{
// 起始数据调整
if (! is_numeric($this->start) || $this->start < 1) {
$this->start = 1;
}
if ($this->start > $total) {
$this->start = $total + 1;
}
// 设置总数
if ($total) {
$this->rowTotal = $total - ($this->start - 1);
}
// 设置分页大小
if (! isset($this->pageSize)) {
$this->pageSize = get('pagesize') ?: Config::get('pagesize') ?: 15;
}
// 分页数字条数量
$this->num = Config::get('pagenum') ?: 5;
// 计算页数
$this->pageCount = @ceil($this->rowTotal / $this->pageSize);
// 获取当前页面
$this->page = $this->page();
// 定义相关常量,用于方便模板引擎解析序号等计算和调用
define('ROWTOTAL', $this->rowTotal);
define('PAGECOUNT', $this->pageCount);
define('PAGE', $this->page);
define('PAGESIZE', $this->pageSize);
// 注入分页模板变量
$this->assign($morePageStr);
// 返回限制语句
return ($this->page - 1) * $this->pageSize + ($this->start - 1) . ",$this->pageSize";
}
// 快速分页字符代码
public function quikLimit()
{
$page = get('page', 'int') ?: 1;
if ($page < 1) {
$page = 0;
}
$pagesize = config::get('pagesize') ?: 15;
return ($page - 1) * $pagesize . ",$pagesize";
}
// 注入页面相关信息,用于模板调用,如:{$pagebar}调用分页条
private function assign($morePageStr = false)
{
assign('pagebar', $this->pageBar());
if ($morePageStr) {
assign('pagecurrent', $this->page()); // 注入当前页
assign('pagecount', $this->pageCount); // 注入总页数
assign('pagerows', $this->rowTotal); // 注入总数据
assign('pageindex', $this->pageIndex()); // 注入首页链接
assign('pagepre', $this->pagePre()); // 注入前一页链接
assign('pagenext', $this->pageNext()); // 注入后一页链接
assign('pagelast', $this->pageLast()); // 注入最后一页链接
assign('pagestatus', $this->pageStatus()); // 注入分页状态
assign('pagenumbar', $this->pageNumBar()); // 注入数字
assign('pageselectbar', $this->pageSelectBar()); // 注入选择栏
}
}
// 当前页码容错处理
private function page()
{
$page = get('page', 'int') ?: $this->page;
if (is_numeric($page) && $page > 1) {
if ($page > $this->pageCount && $this->pageCount) {
return $this->pageCount;
} else {
return $page;
}
} else {
return 1;
}
}
// 过滤pathinfo中分页参数
private function getPreUrl()
{
if (! isset($this->preUrl) && URL) {
$url = parse_url(URL);
$path = preg_replace('/\/page\/[0-9]+/i', '', $url['path']);
if (defined('CMS_PAGE') && CMS_PAGE == true) { // 使用CMS分页时去除扩展
$url_rule_suffix = Config::get('url_rule_suffix');
if (! ! $pos = strripos($path, $url_rule_suffix)) {
$path = substr($path, 0, $pos);
}
}
$this->preUrl = $path;
}
return $this->preUrl;
}
// 构建链接地址
private function buildPath($page)
{
if ($page) {
if (defined('CMS_PAGE') && CMS_PAGE == true) {
$url_rule_type = Config::get('url_rule_type') ?: 3;
$url_rule_suffix = Config::get('url_rule_suffix') ?: '.html';
$url_break_char = Config::get('url_break_char') ?: '_';
$url_rule_sort_suffix = Config::get('url_rule_sort_suffix') ? $url_rule_suffix : '/';
if ($url_rule_type == 1 || $url_rule_type == 2) {
if (defined('CMS_PAGE_CUSTOM')) { // 去分页参数
$prepath = preg_replace('/(.*)' . $url_break_char . '[0-9]+$/', '$1', rtrim($this->getPreUrl(), '/'));
} else {
$prepath = preg_replace('/(.*)(' . $url_break_char . '[0-9]+)' . $url_break_char . '[0-9]+$/', '$1$2', rtrim($this->getPreUrl(), '/'));
}
if ($prepath) { // 非首页分页
if ($page == 1) { // 第一页处理
$path = $prepath . $url_rule_sort_suffix . query_string('p,s');
} else {
$path = $prepath . $url_break_char . $page . $url_rule_sort_suffix . query_string('p,s');
}
} else { // 首页分页
$path = ($page == 1) ? SITE_INDEX_DIR . '/' : '?page=' . $page;
}
} else {
if ($url_rule_type == 3 && isset($_SERVER["QUERY_STRING"]) && $qs = $_SERVER["QUERY_STRING"]) {
parse_str($qs, $output);
unset($output['page']);
if ($output && ! current($output)) {
$path_qs = key($output); // 第一个参数为路径信息注意PHP数组会自动将点转换下划线
unset($output[$path_qs]); // 去除路径参数
// 去后缀扩展
$temp_suffix = substr($url_rule_suffix, 1);
if (! ! $pos = strripos($path_qs, '_' . $temp_suffix)) {
$path = substr($path_qs, 0, $pos); // 去扩展
} else {
$path = $path_qs;
}
// 去除原分页参数
if (defined('CMS_PAGE_CUSTOM')) {
$path = preg_replace('/(.*)' . $url_break_char . '[0-9]+$/', "$1", rtrim($path, '/'));
} else {
$path = preg_replace('/(.*)(' . $url_break_char . '[0-9]+)' . $url_break_char . '[0-9]+$/', "$1$2", rtrim($path, '/'));
}
// 第一页链接处理
if ($page == 1) {
$path = SITE_INDEX_DIR . '/?' . $path . $url_rule_sort_suffix;
} else {
$path = SITE_INDEX_DIR . '/?' . $path . $url_break_char . $page . $url_rule_sort_suffix;
}
// 附加参数
if (! ! $qs = http_build_query($output)) {
$path = rtrim($path, '/') . '&' . $qs;
}
}
}
if (! $path) { // 转基本分页模式
return $this->buildBasicPage($page);
}
}
return $path;
} else {
return $this->buildBasicPage($page);
}
} else {
return 'javascript:;';
}
}
// 构建基本分页
private function buildBasicPage($page)
{
// 对于路径保留变量给予去除
$qs = $_SERVER["QUERY_STRING"];
if ((M == 'home' && Config::get('url_rule_type') == 2) || (M != 'home' && Config::get('app_url_type') == 2)) {
$qs = preg_replace('/[&\?]?p=([\w\/\.]+)?/i', '', $qs);
$qs = preg_replace('/[&\?]?s=([\w\/\.]+)?/i', '', $qs);
}
$qs = preg_replace('/[&\?]?page=([0-9]+)?/i', '', $qs);
if ($page == 1) {
if ($qs) {
return $this->getPreUrl() . '?' . $qs;
} else {
return $this->getPreUrl();
}
} else {
if ($qs) {
return $this->getPreUrl() . '?' . $qs . '&page=' . $page;
} else {
return $this->getPreUrl() . '?page=' . $page;
}
}
}
// 分页条
private function pageBar()
{
if (! $this->pageCount)
return "<span class='page-none' style='color:#999'>未查询到任何数据!</span>";
$string = "<span class='page-status'>{$this->pageStatus()}</span>";
$string .= "<span class='page-index'><a href='" . $this->pageIndex() . "'>首页</a></span>";
$string .= "<span class='page-pre'><a href='" . $this->pagePre() . "'>前一页</a></span>";
$string .= "<span class='page-numbar'>{$this->pageNumBar()}</span>";
$string .= "<span class='page-next'><a href='" . $this->pageNext() . "'>后一页</a></span>";
$string .= "<span class='page-last'><a href='" . $this->pageLast() . "'>尾页</a></span>";
// $string .= "<span class='page-select'>{$this->pageSelectBar()}</span>";
return $string;
}
// 当前页面情况
private function pageStatus()
{
if (! $this->pageCount)
return;
return "" . $this->rowTotal . "条 当前" . $this->page . "/" . $this->pageCount . "";
}
// 首页链接
private function pageIndex()
{
if (! $this->pageCount)
return $this->buildPath('');
return $this->buildPath(1);
}
// 上一页链接
private function pagePre()
{
if (! $this->pageCount)
return $this->buildPath('');
if ($this->page > 1) {
$pre_page = $this->buildPath($this->page - 1);
} else {
$pre_page = $this->buildPath('');
}
return $pre_page;
}
// 下一页链接
private function pageNext()
{
if (! $this->pageCount)
return $this->buildPath('');
if ($this->page < $this->pageCount) {
$next_page = $this->buildPath($this->page + 1);
} else {
$next_page = $this->buildPath('');
}
return $next_page;
}
// 尾页
private function pageLast()
{
if (! $this->pageCount)
return $this->buildPath('');
return $this->buildPath($this->pageCount);
}
// 数字分页,要修改数字显示的条数请修改类头部num属性值
private function pageNumBar()
{
if (! $this->pageCount)
return;
if (M == 'admin') {
$total = 5;
} else {
$total = $this->num;
}
$halfl = intval($total / 2);
$halfu = ceil($total / 2);
$num_html = '';
if ($this->page > $halfu) {
$num_html .= '<span class="page-num">···</span>';
}
if ($this->page <= $halfl || $this->pageCount < $total) { // 当前页小于一半或页数小于总数
for ($i = 1; $i <= $total; $i ++) {
if ($i > $this->pageCount)
break;
if ($this->page == $i) {
$num_html .= '<a href="' . $this->buildPath($i) . '" class="page-num page-num-current">' . $i . '</a>';
} else {
$num_html .= '<a href="' . $this->buildPath($i) . '" class="page-num">' . $i . '</a>';
}
}
} elseif ($this->page + $halfl >= $this->pageCount) { // 当前页为倒数页以内
for ($i = $this->pageCount - $total + 1; $i <= $this->pageCount; $i ++) {
if ($this->page == $i) {
$num_html .= '<a href="' . $this->buildPath($i) . '" class="page-num page-num-current">' . $i . '</a>';
} else {
$num_html .= '<a href="' . $this->buildPath($i) . '" class="page-num">' . $i . '</a>';
}
}
} else { // 正常的前后各5页
for ($i = $this->page - $halfl; $i <= $this->page + $halfl; $i ++) {
if ($this->page == $i) {
$num_html .= '<a href="' . $this->buildPath($i) . '" class="page-num page-num-current">' . $i . '</a>';
} else {
$num_html .= '<a href="' . $this->buildPath($i) . '" class="page-num">' . $i . '</a>';
}
}
}
if ($this->pageCount > $total && $this->page < $this->pageCount - $halfl) {
$num_html .= '<span class="page-num">···</span>';
}
return $num_html;
}
// 跳转分页
private function pageSelectBar()
{
if (! $this->pageCount)
return;
$select_html = '<select onchange="changepage(this)" lay-ignore>';
for ($i = 1; $i <= $this->pageCount; $i ++) {
if ($i == $this->page) {
$select_html .= '<option value="' . $i . '" selected="selected">跳到' . $i . '页</option>';
} else {
$select_html .= '<option value="' . $i . '">跳到' . $i . '页</option>';
}
}
$select_html .= '</select><script>function changepage(tag){window.location.href="' . $this->buildPath('"+tag.value+"') . '";}</script>';
return $select_html;
}
}

View File

@@ -0,0 +1,159 @@
<?php
/**
* @copyright (C)2016-2099 Hnaoyun Inc.
* @author XingMeng
* @email hnxsh@foxmail.com
* @date 2016年11月6日
* 模板显示类
*/
namespace core\view;
use core\basic\Config;
class View
{
// 模板路径
protected $tplPath;
// 编译路径
protected $tplcPath;
// 缓存路径
protected $cachePath;
// 存储注入变量
protected $vars = array();
// 存储包含文件
protected $incFile = array();
// 实例
protected static $view;
// 获取单一实例
public static function getInstance()
{
if (! self::$view) {
self::$view = new self();
}
return self::$view;
}
// 禁止通过new实例化类
private function __construct()
{
$this->tplPath = APP_VIEW_PATH;
$this->tplcPath = RUN_PATH . '/complile';
$this->cachePath = RUN_PATH . '/cache';
check_dir($this->tplcPath, true);
check_dir($this->cachePath, true);
}
private function __clone()
{
die('不允许克隆对象请使用getInstance获取实例');
}
// 变量注入
public function assign($var, $value)
{
if (! empty($var)) {
if (isset($this->vars[$var])) {
error('模板变量$' . $var . '出现重复注入!');
}
$this->vars[$var] = $value;
return true;
} else {
error('传递的设置模板变量有误');
}
}
// 变量获取
public function getVar($var)
{
if (! empty($var)) {
if (isset($this->vars[$var])) {
return $this->vars[$var];
} else {
return null;
}
} else {
error('传递的获取模板变量有误');
}
}
// 解析模板文件
public function parser($file)
{
// 设置主题
$theme = isset($this->vars['theme']) ? $this->vars['theme'] : 'default';
$theme = preg_replace_r('{\.\.(\/|\\\\)}', '', $theme); // 过滤掉相对路径
$file = preg_replace_r('{\.\.(\/|\\\\)}', '', $file); // 过滤掉相对路径
if (strpos($file, '/') === 0) { // 绝对路径模板
$tpl_file = ROOT_PATH . $file;
} elseif (! ! $pos = strpos($file, '@')) { // 跨模块调用
$path = APP_PATH . '/' . substr($file, 0, $pos) . '/view/' . $theme;
define('APP_THEME_DIR', str_replace(DOC_PATH, '', $path));
if (! is_dir($path)) { // 检查主题是否存在
error('模板主题目录不存在!主题路径:' . $path);
} else {
$this->tplPath = $path;
}
$tpl_file = $path . '/' . substr($file, $pos + 1);
} else {
// 定义当前应用主题目录
define('APP_THEME_DIR', str_replace(DOC_PATH, '', APP_VIEW_PATH) . '/' . $theme);
if (! is_dir($this->tplPath .= '/' . $theme)) { // 检查主题是否存在
error('模板主题目录不存在!主题路径:' . APP_THEME_DIR);
}
$tpl_file = $this->tplPath . '/' . $file; // 模板文件
}
$note = Config::get('tpl_html_dir') ? '<br>同时检测到您系统中启用了模板子目录' . Config::get('tpl_html_dir') . ',请核对是否是此原因导致!' : '';
file_exists($tpl_file) ?: error('模板文件' . APP_THEME_DIR . '/' . $file . '不存在!' . $note);
$tpl_c_file = $this->tplcPath . '/' . md5($tpl_file) . '.php'; // 编译文件
// 当编译文件不存在,或者模板文件修改过,则重新生成编译文件
if (! file_exists($tpl_c_file) || filemtime($tpl_c_file) < filemtime($tpl_file) || ! Config::get('tpl_parser_cache')) {
$content = Parser::compile($this->tplPath, $tpl_file); // 解析模板
file_put_contents($tpl_c_file, $content) ?: error('编译文件' . $tpl_c_file . '生成出错!请检查目录是否有可写权限!'); // 写入编译文件
$compile = true;
}
ob_start(); // 开启缓冲区,引入编译文件
$rs = include $tpl_c_file;
if (! isset($compile)) {
foreach ($rs as $value) { // 检查包含文件是否更新,其中一个包含文件不存在或修改则重新解析模板
if (! file_exists($value) || filemtime($tpl_c_file) < filemtime($value) || ! Config::get('tpl_parser_cache')) {
$content = Parser::compile($this->tplPath, $tpl_file); // 解析模板
file_put_contents($tpl_c_file, $content) ?: error('编译文件' . $tpl_c_file . '生成出错!请检查目录是否有可写权限!'); // 写入编译文件
ob_clean();
include $tpl_c_file;
break;
}
}
}
$content = ob_get_contents();
ob_end_clean();
return $content;
}
// 缓存页面, 开启缓存开关时有效
public function cache($content)
{
if (Config::get('tpl_html_cache') && ! query_string('p,s')) {
$lg = cookie('lg');
if (Config::get('open_wap') && (is_mobile() || Config::get('wap_domain') == get_http_host())) {
$wap = 'wap';
} else {
$wap = '';
}
$cacheFile = $this->cachePath . '/' . md5(get_http_url() . $_SERVER["REQUEST_URI"] . $lg . $wap) . '.html'; // 缓存文件
file_put_contents($cacheFile, $content) ?: error('缓存文件' . $cacheFile . '生成出错!请检查目录是否有可写权限!'); // 写入缓存文件
return true;
}
return false;
}
}

View File

@@ -0,0 +1,675 @@
##########################################
官方网站https://www.pbootcms.com
标签手册https://www.pbootcms.com/docs.html
##########################################
PbootCMS V3.0.7 build 2021-10-09
1、新增列表页自定义多层级路径的支持
2、新增专题单页多图的标题支持
3、新增后台清理站点内会话目录的功能(右上角)
4、去除错误页面显示的服务器信息
PbootCMS V3.0.6 build 2021-09-29
1、新增文章多图标题功能,前台标签:[pics:title]
2、新增在config中定义cmsname变量修改系统显示名称
3、去除后台底部版权区域扩大操作范围
4、支持修改CMS名称后自动隐藏官方信息
5、栏目新增def1-def3三个备用描述字段
PbootCMS V3.0.5 build 2021-06-18
1、修复系统存在的安全漏洞重要
PbootCMS V3.0.4 build 2021-02-14
1、新增{pboot:sql sql="语句"}[sql:字段]{/pboot:sql}万能循环标签;
2、新增自动跳转HTTPS功能参数
3、新增自动跳转主域名功能参数
4、修复地址栏扩展后可附带任意字符问题;
5、修复部分主机CDN后台跳转异常
6、升级layui为最新版本
7、修复系统存在的安全问题
8、优化内容含有标签的处理
PbootCMS V3.0.3 build 2020-10-07
1、修复上版本出现的地址后缀不一致问题
2、修复搜索功能多语言混乱问题
3、新增{pboot:isregister}用于js检查用户名是否已经注册
4、修复已经注册的邮箱仍然发送验证码问题
5、修复系统存在的安全问题
PbootCMS V3.0.2 build 2020-08-04
1、修复会员评论无昵称时不解析标签问题
2、修复默认模板留言页面判断错误问题
3、修复两处存在安全隐患的漏洞
4、修复首页筛选兼容模式错误
5、修复tag标签地址错误问题
6、修复扩展类文件地址错误问题
7、修复文章关闭后tag依然调用问题
8、修复后台设置搜索词标题不解析问题
9、修复内置附件标签不支持截取问题
10、其他问题修复与优化
PbootCMS V3.0.1 build 2020-07-09
1、修复会员权限不足报错页面被404覆盖掉问题
2、新增对循环体标签整体进行访问权限控制如list,nav等
3、新增内容权限不足时调整登录界面“不等待跳登录”参数控制
PbootCMS V3.0.0 build 2020-07-06
1、新增会员功能支持注册、登录、资料、积分等操作;
2、支持对会员相关功能进行后台配置;
3、支持对栏目设置会员权限、权限类型、权限提示
4、支持对内容设置会员权限、权限类型、权限提示
5、支持模板中设置指定页面必须登录
6、支持模板中设置标签指定权限可见或隐藏
7、支持内容评论功能(参考默认模板)
8、支持会员注册邮件验证码功能
9、支持留言关联登录用户新增标签nickname、username、headpic
//相关表单字段
username、password、checkcode //登录必填
username、nickname、password、rpassword、checkcode //注册必填
comment、checkcode //评论必填
//会员页面标签
{pboot:ucenter} 个人中心地址
{pboot:login} 登录地址
{pboot:register} 注册地址
{pboot:umodify} 资料修改地址
{pboot:logout} 退出登录地址
{pboot:upload} 文件上传AJAX接口
{pboot:islogin} 是否登录状态
{pboot:mustlogin} 设置页面必须登录
{pboot:sendemail} 发送邮件验证码接口,参数to
{pboot:registercodestatus} 会员注册验证码状态0、1、2
{pboot:logincodestatus} 会员登录验证码状态
{pboot:registerstatus} 是否开启注册
{pboot:loginstatus} 是否开启登录
{pboot:commentstatus} 是否开启评论
//会员模板控制标签,如:{content:title showgcode=1}
showgcode=* 指定等级显示,支持多个逗号隔开
showucode=* 指定用户显示,支持多个逗号隔开
hidegcode=* 指定等级隐藏,支持多个逗号隔开
hideucode=* 指定用户隐藏,支持多个逗号隔开
showgcodelt=* 等级小于显示
showgcodegt=* 等级大于显示
showgcodele=* 等级小于等于显示
showgcodege=* 等级大于等于显示
hidegcodelt=* 等级小于隐藏
hidegcodegt=* 等级大于隐藏
hidegcodele=* 等级小于等于隐藏
hidegcodege=* 等级大于等于隐藏
showlogin=1 登录后显示
hidelogin=1 登录后隐藏
对于内容及栏目,也支持在后台直接控制
//会员资料标签,全局可用
{user:ucode} 会员编码
{user:username} 会员用户名
{user:useremail} 会员邮箱
{user:usermobile} 会员手机
{user:gcode} 等级编码
{user:gname} 等级名称
{user:registertime} 注册时间
{user:logincount} 登录次数
{user:lastloginip} 最后登录IP
{user:lastlogintime} 最后登录时间
{user:headpic} 头像URL
{user:***} 自定义会员字段,如果{user:sex}
//文章评论
{pboot:commentcodestatus} 验证码是否开启
{pboot:commentaction} 评论提交地址
{pboot:comment contentid={content:id}}
[comment:i] 序号0开始
[comment:n] 序号1开始
[comment:pid] 父评论ID
[comment:contentid] 评论文章ID
[comment:comment] 评论内容
[comment:ip] IP地址
[comment:os] 操作系统
[comment:bs] 浏览器
[comment:date] 日期
[comment:uid] 评论人ID
[comment:username] 评论人账号
[comment:nickname] 评论人昵称
[comment:headpic] 评论人头像
[comment:pid] 父评论人ID
[comment:pusername] 父评论人账号
[comment:pnickname] 父评论人昵称
[comment:pheadpic] 父评论人头像
[comment:likes] 点赞数量
[comment:oppose] 反对数量
[comment:replyaction] 评论回复提交地址
{pboot:commentsub} 子评论输出
[commentsub:***] 子评论调用字段同上
{/pboot:commentsub}
{/pboot:comment}
//我的评论
{pboot:mycommentpage} 我的评论页面地址
{pboot:mycomment}
[mycomment:i] 序号0开始
[mycomment:n] 序号1开始
[mycomment:pid] 父评论ID
[mycomment:contentid] 评论文章ID
[mycomment:comment] 评论内容
[mycomment:title] 文章标题
[mycomment:ip] IP地址
[mycomment:os] 操作系统
[mycomment:bs] 浏览器
[mycomment:date] 日期
[mycomment:uid] 评论人ID
[mycomment:username] 评论人账号
[mycomment:nickname] 评论人昵称
[mycomment:headpic] 评论人头像
[mycomment:pid] 父评论人ID
[mycomment:pusername] 父评论人账号
[mycomment:pnickname] 父评论人昵称
[mycomment:pheadpic] 父评论人头像
[mycomment:likes] 点赞数量
[mycomment:oppose] 反对数量
[mycomment:status] 评论状态1审核2待审核
[mycomment:replyaction] 评论回复提交地址
[mycomment:delaction] 评论删除地址
{/pboot:mycomment}
PbootCMS V2.0.9 build 2020-06-18
1、新增多语言分享链接自动切换功能并新增后台开关;
2、新增后台设置网站页面标题样式功能;
3、修复列表序号翻页不连续问题;
4、修复地址生成函数特殊情况后缀判断不准问题
5、新增百度快速推送功能
6、系统安全问题修复
PbootCMS V2.0.8 build 2020-04-26
1、修复兼容模式分享链接导致打不开页面问题
2、修复几处可能影响系统安全的漏洞
3、修改使用IP访问不再需要域名授权码
4、修复个别空间的兼容性问题。
PbootCMS V2.0.7 build 2020-04-06
1、修复后台被登录成功后系统更新处可能造成的安全漏洞
2、修复dropblank不支持全角空格过滤问题;
3、新增万能码用户后台SVIP尊贵标识
4、修复模板子目录在目标文件夹存在时失败问题
5、修复后台内容编辑页面切换语言导致无限循环问题
6、新增后台切换多语言时同步切换前台语言
PbootCMS V2.0.6 build 2020-03-18
1、修复搜索结果关键字标红无法正常匹配大小写问题
2、新增后台“安全配置”中配置模板文件子目录功能
3、修复operate参数无法使用小数问题
4、新增tags列表支持指定参数target=tag跳转到tag.html模板参考默认模板
5、新增home下ExtLabelController控制器文件扩展个人标签升级不覆盖
6、优化调整前台代码结构
7、新增后台内容列表每页显示数量选择
8、修复tags重复显示问题
9、新增config/route.php文件自定义二开路由支持
10、新增API内容列表返回自适应的内容网页链接地址contentlink
11、修复API内容API链接错误并修改参数为apilink
12、修复API留言及表单无法关闭功能问题
PbootCMS V2.0.5 build 2020-01-31
1、优化前台404.html并支持内容内{info}自适应提示文字;
2、优化内容列表排序方式,并修复api使用随机排序无效问题
3、修复后台入口文件修改名字后在线升级无法自适应问题
4、新增lfield="a,b,*"限制列表查询字段,提高大数据时速度;
5、新增系统自适应入口文件子目录的能力
6、新增留言及表单数据清空功能(管理员)
7、新增留言及表单数据导出功能
8、新增mark=1标签参数对搜索结果关键字进行标红[search:title mark=1]
9、其他问题修复与优化。
PbootCMS V2.0.4 build 2020-01-21
1、修复部分循环体控制参数无效问题
2、修复一处安全漏洞并全局加强系统安全过滤
3、修复面包屑参数中不能使用html的问题
4、修复API接口中post方式page无效问题
5、新增程序全自动修改数据库名
6、新增operate参数对标签进行加减乘除等运算[list:i operate=+100]
7、新增站点关闭功能
8、新增站点访问IP黑白名单功能
9、升级layui到最新版本。
PbootCMS V2.0.3 build 2019-10-25
1、修复一处PHP7环境下的安全漏洞
2、新增关闭留言、表单功能的开关
3、新增缩略图未上传时自动获取文章图片
4、其他问题修复与优化。
PbootCMS V2.0.2 build 2019-09-15
1、伪静态时不再允许访问普通模式地址
2、新增xx:ispics判断是否有多图
3、新增页面内容关键词过滤功能
4、升级layui到最新版本
5、其他问题修复与优化。
PbootCMS V2.0.1 build 2019-08-15
1、优化编辑器工具栏浮动功能
2、优化数据库备份文件名称;
3、优化基础环境组件检查功能
4、修复默认模板一处链接错误
5、修复API一处提示文字错误
6、修复内链替换alt、title内容的问题;
7、去除内置测试账号避免被恶意利用
PbootCMS V2.0.0 build 2019-08-12
1、全新多种URL地址模式上线模型、栏目、内容自由后台设置
2、后台不再依赖pathinfo提高环境兼容性
3、新增模型下面有栏目时不允许直接删除
4、调整跨语言区域调用内容不再自动切换区域;
5、新增上下篇preico标签调用缩略图
6、优化在线更新文件过多时下载问题
7、优化sitamap生成格式
8、其他大量系统框架优化及调整;
9、修复个别空间商的兼容性问题
PbootCMS V1.4.3 build 2019-08-10
1、修复调用指定内容单页链接指向错误问题
2、优化调整模板引擎链接生成过程
3、优化在线更新功能
4、新增升级到2.X分支版本的通道
5、其他问题修复与优化
PbootCMS V1.4.2 build 2019-07-22
1、修复内容tags为空时也有代码输出问题
2、新增文章内链替换次数系统配置参数
3、新增修改栏目时可选同步修改子栏目模板的功能
4、新增批量添加栏目功能
5、新增自定义表单添加到左侧导航菜单功能
6、修复角色修改时区域数量显示不全问题
7、修复IE浏览器翻页兼容性问题
8、优化调整内链替换为长关键字优先
9、新增连续多次登录失败后锁定IP功能
10、新增自动记住上次添加内容栏目功能
11、修复一处可能被利用的安全漏洞感谢stick.wang@Zionlab
12、新增表单提交验证码独立开关并优化邮箱提醒标题
13、其他问题修复与优化
PbootCMS V1.4.1 build 2019-07-12
1、扩大自定义字段默认长度
2、升级layui为最新版本
3、修复后台IE浏览器部分兼容性问题
4、修复新增区域无法绑定域名问题
5、修复图片无法拖动排序问题
6、修复单独修改用户角色不成功问题
7、修复微信分享参数导致安全拦截提示问题
8、修复登录失败时验证码不刷新问题
9、修复编辑器未能按设置大小缩放图片问题
10、优化合并邮箱配置功能到系统配置
11、增加会话文件路径后台切换功能
12、新增单页模型也在左侧导航中显示
13、新增文章图片水印功能
14、新增文章内容内链功能
15、其他问题修复与优化
PbootCMS V1.4.0 build 2019-06-07
1、修复部分浏览器多图无法删除的问题
2、新增万能授权码填写后自动后台隐藏功能
3、修复QQ中打开搜索页面附加参数导致错误问题
4、修复后台密码泄露后系统配置可能构成的安全问题
PbootCMS V1.3.9 build 2019-05-15
1、优化相关目录权限不足报错机制
2、修复PHP56有时后台更新无法使用问题
3、优化后台在线升级功能
4、新增中文路径部署检测
5、优化升级系统框架模板引擎
6、新增自定义路由正则匹配的支持
7、新增后台配置数字分页条数量
8、其他问题修复与优化
PbootCMS V1.3.8 build 2019-04-12
1、新增同时支持fsockopen及stream_socket_client发送邮件
2、优化邮件发送失败错误提示信息
3、新增手机版绑定域名后自动跳转到对应域名地址上
4、修改会话文件默认为使用系统环境缓存路径
5、修复mysqli配置文件读取端口不一致问题
6、修复tags为空时仍然会输出代码字符问题
7、修复开启缓存功能后异样地址会导致文件产生问题
8、修复编辑器在PHP7下多图上传名字重复问题
9、修复编辑器多图上传位置错乱问题
PbootCMS V1.3.7 build 2019-03-12
1、修复部分情况数据库语句执行发生的错误不能正常显示的问题
2、修复搜索时表单传递字段控制被过滤掉的问题
3、新增多个搜索通过传递searchtpl字段自定义不同搜索结果页模板
4、修复分享非默认语言链接后无法直接访问问题
5、新增跨语言调用内容及列表的支持
6、新增留言使用lg=*调取指定语言留言记录功能;
7、新增order=random调取随机排序内容列表
8、修复上传图片字段使用网络图片时地址错误问题
9、修复栏目seo标题使用自动标题时不显示问题
PbootCMS V1.3.6 build 2019-01-12
1、框架问题修复与优化;
2、优化后台在线升级功能;
3、修复api内容列表无法传递自定义排序问题;
4、去除后台执行sql语句功能;
5、新增超级管理员清空日志功能
6、修复测试邮件发送失败返回中文乱码的问题;
PbootCMS V1.3.5 build 2018-12-24
1、修复邮件测试功能被误拦截问题;
2、修复使用首页分页与筛选时出现两种链接类型问题;
3、修复编辑器工具栏不能正常浮动到顶部及视频插入问题;
4、修复gif不能正常缩放及png透明图片缩放后背景变黑问题;
5、新增内容截取时使用more='*'设置省略号内容;
6、新增调节参数maxwidth、maxheight、height、width对图片进行处理;
7、进一步加强系统入侵防御能力;
8、后台主页、验证码、上传、默认模板等的改进与优化;
9、其他问题修复与优化;
PbootCMS V1.3.3 build 2018-11-29
1、新增sort指定栏目输出支持后台排序规则;
2、修复PHP7.3环境下的一些兼容性问题;
3、修改自定义表单数据调用列表为formlist标签避免标签冲突问题;
4、修复多个列表的页面筛选对非筛选列表干扰问题;
5、修复if判断详情内容是否为空无效问题;
6、修复自定义字段英文单词之间空格被过滤掉的问题;
7、修复一处可能导致恶意利用的漏洞重要;
8、进一步增强系统框架安全防御策略;
9、验证码加入英文字母增强复杂度;
PbootCMS V1.3.2 build 2018-11-22
1、修复用户名验证规则不统一导致修改特殊字符后无法登录问题;
2、修复js无法获取到点赞及反对cookie的问题;
3、修复content标签无法使用scode调取单页问题;
4、新增start=*设置数据列表起始数据;
5、加强后台执行数据库脚本功能的安全性;
6、新增默认正文内容不再对PB标签进行解析;
7、修复上版本API搜索接口无法正常实现功能的问题;
8、新增lencn=* 截取长度,解决中英文显示长度不同问题;
9、其他问题修复与优化。
PbootCMS V1.3.1 build 2018-11-14
1、优化在线升级功能;
2、修复表单Ajax提交返回状态码不正确问题;
3、优化会话层级目录创建避免会话目录缺失导致登录失败的情况;
PbootCMS V1.3.0 build 2018-11-12
1、优化会话创建机制,避免会话文件过多问题;
2、修复一些可能导致注入的安全问题(感谢topsec(zhan_ran)及CNVD的反馈);
3、修复搜索结果无法按预期显示的的问题;
4、新增内容页、列表页404自动匹配的支持;
5、新增支持在根目录定义sn.html文件自定义免费授权码填写提示;
6、新增API通过scode来调用单篇内容;
7、新增[nav:rows]输出该菜单下内容数量;
8、新增[sort:rows]输出该栏目下内容数量;
9、新增[sort:toprows]输出顶级栏目下内容数量;
10、新增[sort:parentrows]输出父栏目下内容数量;
11、新增内置tags功能不再需要扩展字段实现;
12、新增输出指定内容或栏目tags标签功能;
13、新增列表使用参数tags='*,*'过滤列表;
14、新增列表使用参数scode=*匹配全部栏目;
15、新增指定内容输出单页时支持scode来指定内容;
16、新增栏目独立seo标题设置字段[nav:title];
17、新增开启iis\apache伪静态时自动拷贝伪静态规则;
18、新增后台内容列表百度站长推送及熊掌号推送;
19、新增多语言\区域绑定域名功能(站群系统);
20、新增留言及表单记录调用时使用page=0关闭分页;
21、其他问题修复与优化。
PbootCMS V1.2.2 build 2018-10-12
1、修复自定义表单多选类型提交数据错误问题;
2、修复发送邮件设置完成不立即生效问题;
3、修复发送测试邮件不能正确返回状态的问题;
4、修复分页代码数字条省略号不准问题;
5、修复后台编辑器的一些问题;
6、修复自定义标签的图片不自适应多级目录问题;
7、修复使用mysql数据库时可能导致的安全问题;
8、修复列表筛选与指定分类列表冲突问题;
9、修复多次调用内容标签导致重复计算访问量问题;
10、大幅提高Sqlite数据库数据写入速度;
11、优化后台登录错误处理机制;
12、优化数据列表排序方式;
13、新增模板嵌套引用的支持;
14、新增在线更新涉及数据库时自动备份数据库;
15、新增在线更新分支选择功能;
16、新增对指定代码块不做标签解析的标签;
17、新增列表多条件排序自定义任意组合的支持,如:order='istop desc,id asc'
18、新增MySQL数据库事务的支持;
19、新增自定义标签多行文本类型;
20、新增文章定时发布的支持;
21、其它问题修复与优化。
PbootCMS V1.2.1 build 2018-09-12
1、新增在线升级新版本红点提示;
2、新增程序部署到非根目录时虚拟目录大小写不区分;
3、新增表单提交频率安全检测;
4、调整程序非伪静态时不再显示html后缀;
5、调整程序留言表单外的自定义表单不再要求验证码;
6、修复上版本首页分页不正常问题;
7、优化完善默认模板;
PbootCMS V1.2.0 build 2018-09-04
1、系统优化及安全修复;
2、修复API搜索与页面实现不统一;
3、优化后台内容页栏目显示逻辑;
4、新增后台轮播、链接页面批量排序;
5、升级layui到最新版本;
6、新增列表标签isico、ispics、istop、isrecommend、isheadline调节参数;
7、新增面包屑连接符separatoriconc及indexicon参数设置字体图标class;
8、优化分页条代码;
9、新增内容截取时自动添加省略号;
10、基于bootstrap v4的全新默认模板正式上线;
11、修复在线更新浏览器兼容性问题;
PbootCMS V1.1.9 build 2018-08-17
1、系统优化及安全修复(重要);
2、修复自定义表单Mysql时添加失败问题;
3、修复后台模板一些小错误;
4、修复影响缓存效果的一些问题;
5、新增后台在线更新功能;
6、新增附件大小标签;
PbootCMS V1.1.8 build 2018-08-07
1、修复提交表单多选字段接收数据问题;
2、修复登录过程中二次登录在页面不刷新时验证失败问题;
3、新增搜索结果fuzzy参数来控制是否模糊匹配;
4、新增父分类、顶级分类名称及链接独立标签具体见手册;
5、新增内容多图拖动排序功能;
PbootCMS V1.1.7 build 2018-08-01
1、修复测试邮件不发送到填写的测试邮箱问题;
2、修复友情链接添加时排序报错问题;
3、修复API幻灯片及友情链接排序无效;
4、修复站内Ajax调用API数据时间戳过期问题;
5、新增自定义标签开关类型;
6、新增自定义表单数据调取标签;
7、新增单页设置跳转后内容不再出现管理列表中;
8、新增搜索支持多字段同时匹配;
9、新增点击上传的图片自动添加到编辑器;
10、优化表单提交验证;
11、其它问题修复与优化;
PbootCMS V1.1.6 build 2018-07-21
1、优化编辑器配置及安全加固;
2、优化内容管理列表布局;
3、增强系统后台及标签解析引擎安全性;
4、调整runtime标签展示方式;
5、新增Gzip页面压缩功能及后台开关;
6、新增支持根目录定义404.html匹配错误URL访问;
7、新增缩略图自动缩放更小图功能;
8、新增config/route.php文件里定义路由规则的支持;
9、新增调用指定栏目 标签scode支持多个分类;
10、新增如果栏目及内容关键字标签为空时自动使用全局关键字;
11、新增如果栏目及内容描述标签为空时自动使用全局描述;
12、新增全局自动页面标题标签{pboot:pagetitle};
13、新增全局自动页面关键字标签{pboot:pagekeywords};
14、新增全局自动页面描述标签{pboot:pagedescription}
15、新增留言表单添加更多字段的支持;
16、新增幻灯片、友情链接、扩展字段排序的支持;
17、新增sitemap生成读取地址/index.php/sitemap;
18、新增URL路径支持中文;
19、新增中文用户名登录的支持;
20、新增API正文内容返回图片路径自动添加网址路径;
21、新增邮件配置中发送测试邮件功能;
22、新增API调用自定义表单数据接口;
23、其它问题修复与优化;
注意:升级到此版本需要同时升级数据库,脚本见升级包中。
PbootCMS V1.1.5 build 2018-07-10
1、修复开启静态缓存后无法切换语言问题;
2、修复开启静态缓存后无法自动切换手机版;
3、修复数据库安全检查不准问题;
4、修复后台多选字段无法取消问题;
5、新增调试模式后台开关;
6、新增访问地址不存在时404状态信息;
7、新增运行时间标签{pboot:runtime};
8、新增留言验证码判断标签{pboot:checkcodestatus};
9、新增筛选全部按钮的class和active分别设置;
10、新增类似filter=title|php,asp多条件过滤支持;
11、新增搜索列表scode、field调节控制参数支持;
12、新增任意字段搜索及综合搜索支持;
13、新增列表零开头序号标签[list:n];
14、新增loop循环语句标签;
15、新增模型字段下拉选择类型;
16、优化内容页访问量代码插入方式;
17、优化会话文件处理方式;
18、优化框架模板解析引擎;
19、优化后台单页数据读取方式;
20、优化系统配置载入方式;
21、优化API数据读取;
PbootCMS V1.1.4 build 2018-06-25
1、修复自定义表单表名重复仍然添加成功问题;
2、修复分享到微信导致页面错误的问题;
3、修复静态缓存失效问题并提高缓存效果;
4、新增多条件筛选时多选类型支持;
5、新增全站多条件筛选的支持;
6、新增登录时数据库目录写入权限判断提示;
7、新增后台开启高速静态缓存功能;
8、新增后台填写授权码功能;
9、新增指定列表scode使用逗号调用多个分类功能;
10、新增{pboot:keyword}标签;
11、新增数据库安全提示及修改功能;
PbootCMS V1.1.3 build 2018-06-15
1、优化Sqlite查询过程高并发锁死问题;
2、优化编辑器配置;
3、优化标签参数获取方法;
4、修复部分环境截取描述文本出现乱码问题;
5、修复API搜索数据获取方式错误;
6、新增API获取指定分类子类接口;
7、新增多条件筛选功能;
8、新增无缩略图时自动调用默认图功能;
9、新增上下篇标签参数notext定义"没有了"文本;
10、新增内容管理复制和移动功能;
PbootCMS V1.1.2 build 2018-06-12
1、修复httpurl非标准端口时解析错误;
2、修复内容为空时提取描述报警告问题;
3、修复非根目录情况下图片路径使用IF判断不准问题;
4、修复授权码带空格时导致无法正常匹配问题;
5、修复数据库中存在乱码时读取异常问题;
6、修复面包屑不显示当前分类的问题;
7、修复API中数据调用的一些错误;
8、新增表单数据删除功能;
9、新增栏目自定义路径名称功能;
10、新增留言和自定义表单提交API;
PbootCMS V1.1.1 build 2018-06-03
1、更新Layui到最新版本;
2、修复表备份无数据时处理错误;
3、优化添加自定义字段数据库处理方式;
4、修复修改模型时类型默认不选中问题;
5、修复在单页面多次调用面包屑数据重复问题;
6、修复访客留言不显示问题;
7、新增删除栏目时彻底删除本类及子类内容;
8、修复单页预览按钮地址错误;
9、新增自定义表单功能,调用方法见手册;
10、新增二维码生成标签及当前域名获取标签;
11、新增添加内容时自动提取内容描述文字;
12、新增文件上传过程提示图标;
13、新增数据库管理执行Sql脚本功能;
注意:升级到此版本需要同时升级数据库,脚本见升级包中。
PbootCMS V1.1.0 build 2018-05-24
1、修复新增语言后站点和公司信息图片首次出现警告问题;
2、优化文章访问量计数方式;
3、新增扩展字段编辑器类型;
4、新增后台文章列表有图的标注;
5、修复模板部分手误错误;
6、增强搜索时字段安全性;
7、新增PHP环境自动转义判断;
8、新增总页数、总行数分页标签;
9、调整独立分页标签为不带文字的链接;
10、修复多图多次输出num干扰问题;
11、修复新增语言后未做保存导致手机版切换错误;
PbootCMS V1.0.9 build 2018-05-14
1、新增图片上传直接显示及删除功能;
2、修复内容过滤参数及状态失效问题;
3、优化后台菜单显示视觉流畅性;
4、框架入口文件安全加强;
5、面包屑新增indextext参数配置"首页"文字;
6、新增API认证签名生成标签方便进行Ajax加载具体见手册示例;
7、新增上一篇及下一篇链接及标题独立标签并支持len截取;
PbootCMS V1.0.8 build 2018-05-07
1、修复后台菜单高亮错误;
2、修改编辑器为不替换div和不自动拉高;
3、修复删除栏目时子类未全部删除问题;
4、新增后台栏目管理折叠功能;
5、新增手机版绑定独立域名功能;
6、修复多语言切换时栏目编码导致报错;
7、修复副栏目内容无法正常调取问题;
8、新增指定内容扩展字段多选输出标签;
PbootCMS V1.0.7 build 2018-05-02
1、采用LayUI新版管理后台;
2、修复后台单页无法显示更多问题;
3、调整默认分页数字条长度为5;
4、修复API调用全部自定义标签错误;
5、新增内容批量删除功能;
6、新增栏目批量删除功能;
7、修复面包屑对外链跳转问题;
8、修复栏目修改直接保存类型错误;
9、其它问题修复和优化;
PbootCMS V1.0.6 build 2018-04-24
1、修复无任何内容执行排序报错;
2、修复可能存在的跨站请求伪造漏洞;
PbootCMS V1.0.5 build 2018-04-23
1、新增后台配置项自动新增功能;
2、修复logo不自适应多级目录路径;
3、新增十类API调用方便小程序、APP、Ajax等数据获取;
4、修复个别虚拟主机分页代码报警告问题;
5、新增服务器未开启sockets导致非加密发送邮件错误提示;
PbootCMS V1.0.4 build 2018-04-19
1、优化框架配置文件载入方式;
2、修复当前分类列表页过滤参数无效;
3、新增首页分页功能大家可以做博客了;
4、新增模型类菜单桌面同步显示;
5、新增当前栏目位置标签;
PbootCMS V1.0.3 build 2018-04-16
1、修复多图输出只输出一张问题;
2、修复PHP7.1中合并多维数组警告;
3、修复登录地址末尾带有斜杠时错误;
4、新增配置文件自动去除Bom,避免空白;
PbootCMS V1.0.2 build 2018-04-14
1、新增自动去除模板的Bom信息避免空白;
2、优化编辑器可见按钮;
3、修复编辑器无法插入动态地图问题;
4、修复文章排序无法按预期排列问题;
PbootCMS V1.0.1 build 2018-04-13
1、修复数据库导出未正常解码问题;
2、修复系统栏目出现多个新闻内容问题;
3、新增默认及内置区域不允许删除;
4、新增删除区域后强制重新登录;
5、修复前端多语言无法正常切换问题;
6、修复新增语言无法匹配默认模板问题;
7、Mysql脚本默认内容解码有问题大家重新导入sql;
8、修复友情链接图片无法自适应多级目录;
PbootCMS V1.0.0 build 2018-04-12
1、正式发布第一个版本。

View File

@@ -0,0 +1,23 @@
<?php
/**
* @copyright (C)2016-2099 Hnaoyun Inc.
* @author XingMeng
* @email hnxsh@foxmail.com
* @date 2016年11月5日
* 用户前端入口文件
*/
// 定义为入口文件
define('IS_INDEX', true);
// 入口文件地址绑定
define('URL_BIND', 'home');
// PHP版本检测
if (PHP_VERSION < '5.3') {
header('Content-Type:text/html; charset=utf-8');
exit('您服务器PHP的版本太低程序要求PHP版本不小于5.3');
}
// 引用内核启动文件
require dirname(__FILE__) . '/core/start.php';