初始化官网代码

This commit is contained in:
wojiaoxiaomage
2025-12-30 10:26:47 +08:00
commit 00f55e8b83
232 changed files with 49856 additions and 0 deletions

View File

@@ -0,0 +1,227 @@
{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>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
<table class="layui-table">
<thead>
<tr>
<th>序号</th>
<th>内容模型</th>
<th>字段描述</th>
<th>字段名称</th>
<th>字段类型</th>
<th>排序</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{foreach $extfields(key,value)}
<tr>
<td>[num]</td>
<td>
{foreach $models(key2,value2,num2)}
{if($value2->mcode==$value->mcode)}
[value2->name]
{/if}
{/foreach}
</td>
<td>[value->description]</td>
<td>[value->name]</td>
<td>
{if($value->type==1)}单行文本{/if}
{if($value->type==2)}多行文本{/if}
{if($value->type==3)}单选按钮{/if}
{if($value->type==4)}多选按钮{/if}
{if($value->type==5)}单图上传{/if}
{if($value->type==10)}多图上传{/if}
{if($value->type==6)}附件上传{/if}
{if($value->type==7)}日期选择{/if}
{if($value->type==8)}编辑器{/if}
{if($value->type==9)}下拉选择{/if}
</td>
<td>[value->sorting]</td>
<td>
{fun=get_btn_del($value->id)}
{fun=get_btn_mod($value->id)}
</td>
</tr>
{/foreach}
</tbody>
</table>
<div class="page">{$pagebar}</div>
</div>
<div class="layui-tab-item">
<form action="{url./admin/ExtField/add}" 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">
<select name="mcode" lay-verify="required">
<option value="">请选择内容模型</option>
{foreach $models(key,value)}
<option value="[value->mcode]">[value->name]</option>
{/foreach}
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">字段描述</label>
<div class="layui-input-block">
<input type="text" name="description" 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">
<input type="text" name="name" required maxlength="20" lay-verify="required" placeholder="请输入字段名称,字母、数组、下划线price" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">字段类型</label>
<div class="layui-input-block">
<select name="type" lay-verify="required">
<option value="1">单行文本</option>
<option value="2">多行文本</option>
<option value="3">单选按钮</option>
<option value="4">多选按钮</option>
<option value="5">单图上传</option>
<option value="10">多图上传</option>
<option value="6">附件上传</option>
<option value="7">日期选择</option>
<option value="8">编辑器</option>
<option value="9">下拉选择</option>
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">选择按钮值</label>
<div class="layui-input-block">
<textarea name="value" placeholder="多个选项用逗号隔开或者回车" class="layui-textarea"></textarea>
<div class="layui-form-mid layui-word-aux">只在类型为单选或多选时填写有效。</div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">排序</label>
<div class="layui-input-block">
<input type="text" name="sorting" required lay-verify="required" value="255" 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>
{/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/ExtField/mod/id/'.[$get.id].'}{$backurl}" 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">
<select name="mcode" lay-verify="required">
<option value="">请选择内容模型</option>
{foreach $models(key,value)}
<option value="[value->mcode]" {if($value->mcode==[$extfield->mcode])}selected{/if}>[value->name]</option>
{/foreach}
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">字段描述</label>
<div class="layui-input-block">
<input type="text" name="description" value="{$extfield->description}" 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="name" readonly value="{$extfield->name}" maxlength="20" placeholder="请输入字段名称字母、数组、下划线price" class="layui-input readonly">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">字段类型</label>
<div class="layui-input-block">
<select name="type" lay-verify="required">
{if([$extfield->type]==2)}
<option value="2" selected>多行文本</option>
{/if}
{if([$extfield->type]==7)}
<option value="7" selected>日期选择</option>
{/if}
{if([$extfield->type]==8)}
<option value="8" selected>编辑器</option>
{/if}
{if([$extfield->type]!=2 && [$extfield->type]!=7 && [$extfield->type]!=8)}
<option value="1" {if([$extfield->type]==1)}selected{/if}>单行文本</option>
<option value="3" {if([$extfield->type]==3)}selected{/if}>单选按钮</option>
<option value="4" {if([$extfield->type]==4)}selected{/if}>多选按钮</option>
<option value="5" {if([$extfield->type]==5)}selected{/if}>单图上传</option>
<option value="10" {if([$extfield->type]==10)}selected{/if}>多图上传</option>
<option value="6" {if([$extfield->type]==6)}selected{/if}>附件上传</option>
<option value="9" {if([$extfield->type]==9)}selected{/if}>下拉选择</option>
{/if}
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">选择按钮值</label>
<div class="layui-input-block">
<textarea name="value" placeholder="多个选项用逗号或回车隔开" class="layui-textarea">{$extfield->value}</textarea>
<div class="layui-form-mid layui-word-aux">只在类型为单选或多选时填写有效,多个选项用逗号或回车隔开。</div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">排序</label>
<div class="layui-input-block">
<input type="text" name="sorting" required lay-verify="required" value="{$extfield->sorting}" 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>
{fun=get_btn_back()}
</div>
</div>
</form>
</div>
</div>
</div>
{/if}
</div>
{include file='common/foot.html'}

View File

@@ -0,0 +1,523 @@
<?php
/**
* @copyright (C)2016-2099 Hnaoyun Inc.
* @author XingMeng
* @email hnxsh@foxmail.com
* @date 2018年4月20日
* CMS通用接口控制器
*/
namespace app\api\controller;
use core\basic\Controller;
use app\api\model\CmsModel;
use core\basic\Url;
use app\home\controller\ParserController;
class CmsController extends Controller
{
protected $model;
protected $lg;
public function __construct()
{
$this->model = new CmsModel();
$this->lg = get_default_lg();
}
// 站点基础信息
public function site()
{
// 获取参数
$acode = request('acode', 'var') ?: $this->lg;
// 读取数据
if (! $name = request('name', 'var')) {
$data = $this->model->getSiteAll($acode);
} else {
$data = $this->model->getSite($acode, $name);
}
// 输出数据
json(1, $data);
}
// 公司信息
public function company()
{
// 获取参数
$acode = request('acode', 'var') ?: $this->lg;
// 读取数据
if (! $name = request('name', 'var')) {
$data = $this->model->getCompanyAll($acode);
} else {
$data = $this->model->getCompany($acode, $name);
}
// 输出数据
json(1, $data);
}
// 自定义标签信息
public function label()
{
// 获取全部或指定自定义标签
if (! $name = request('name', 'var')) {
$data = $this->model->getLabelAll();
} else {
$data = $this->model->getLabel($name);
}
// 输出数据
json(1, $data);
}
// 获取菜单栏目树
public function nav()
{
// 获取参数
$acode = request('acode', 'var') ?: $this->lg;
// 获取栏目树
if (! $scode = request('scode', 'var')) {
$data = $this->model->getSorts($acode);
} else { // 获取子类
$data = $this->model->getSortsSon($acode, $scode);
}
// 输出数据
json(1, $data);
}
// 当前栏目位置
public function position()
{
// 获取参数
$acode = request('acode', 'var') ?: $this->lg;
if (! ! $scode = request('scode', 'var')) {
$data = $this->model->getPosition($acode, $scode);
json(1, $data);
} else {
json(0, '必须传递当前分类scode参数');
}
}
// 分类信息
public function sort()
{
// 获取参数
$acode = request('acode', 'var') ?: $this->lg;
if (! ! $scode = request('scode', 'var')) {
$data = $this->model->getSort($acode, $scode);
json(1, $data);
} else {
json(0, '必须传递分类scode参数');
}
}
// 内容多图
public function pics()
{
if (! ! $id = request('id', 'int')) {
$acode = request('acode', 'var') ?: $this->lg;
if (! ! $pics = $this->model->getContentPics($acode, $id)) {
$pics = explode(',', $pics);
} else {
$pics = array();
}
json(1, $pics);
} else {
json(0, '必须传递内容id参数');
}
}
// 幻灯片
public function slide()
{
if (! ! $gid = request('gid', 'var')) {
$acode = request('acode', 'var') ?: $this->lg;
$num = request('num', 'int') ?: 10;
$data = $this->model->getSlides($acode, $gid, $num);
json(1, $data);
} else {
json(0, '必须传递幻灯片分组gid参数');
}
}
// 友情链接
public function link()
{
if (! ! $gid = request('gid', 'var')) {
$acode = request('acode', 'var') ?: $this->lg;
$num = request('num', 'int') ?: 20;
$data = $this->model->getLinks($acode, $gid, $num);
json(1, $data);
} else {
json(0, '必须传递友情链接分组gid参数');
}
}
// 搜索
public function search()
{
if (! $_POST) {
json(0, '请使用POST提交');
}
$acode = request('acode', 'var') ?: $this->lg;
// 获取主要参数
$field = request('field');
if (! preg_match('/^[\w\|\s]+$/', $field)) {
$field = '';
}
$keyword = request('keyword', 'vars');
$scode = request('scode'); // 支持多个分类逗号隔开
if (! preg_match('/^[\w,\s]+$/', $scode)) {
$scode = '';
}
if ($scode == '*') { // 星号意味任意栏目
$scode = '';
}
$num = request('num', 'int') ?: $this->config('pagesize');
$rorder = request('order');
$tags = request('tags', 'vars');
$fuzzy = request('fuzzy', 'int') ?: true;
if (! preg_match('/^[\w\-,\s]+$/', $rorder)) {
$order = 'a.istop DESC,a.isrecommend DESC,a.isheadline DESC,a.sorting ASC,a.date DESC,a.id DESC';
} else {
switch ($rorder) {
case 'id':
$order = 'a.id DESC,a.istop DESC,a.isrecommend DESC,a.isheadline DESC,a.sorting ASC,a.date DESC';
break;
case 'date':
$order = 'a.date DESC,a.istop DESC,a.isrecommend DESC,a.isheadline DESC,a.sorting ASC,a.id DESC';
break;
case 'sorting':
$order = 'a.sorting ASC,a.istop DESC,a.isrecommend DESC,a.isheadline DESC,a.date DESC,a.id DESC';
break;
case 'istop':
$order = 'a.istop DESC,a.isrecommend DESC,a.isheadline DESC,a.sorting ASC,a.date DESC,a.id DESC';
break;
case 'isrecommend':
$order = 'a.isrecommend DESC,a.istop DESC,a.isheadline DESC,a.sorting ASC,a.date DESC,a.id DESC';
break;
case 'isheadline':
$order = 'a.isrecommend DESC,a.istop DESC,a.isheadline DESC,a.sorting ASC,a.date DESC,a.id DESC';
break;
case 'visits':
case 'likes':
case 'oppose':
$order = $rorder . ' DESC,a.istop DESC,a.isrecommend DESC,a.isheadline DESC,a.sorting ASC,a.date DESC,a.id DESC';
break;
case 'random': // 随机取数
$db_type = get_db_type();
if ($db_type == 'mysql') {
$order = "RAND()";
} elseif ($db_type == 'sqlite') {
$order = "RANDOM()";
}
break;
default:
if ($rorder) {
$orders = explode(',', $rorder);
foreach ($orders as $k => $v) {
if (strpos($v, 'ext_') === 0) {
$orders[$k] = 'e.' . $v;
} else {
$orders[$k] = 'a.' . $v;
}
}
$order = implode(',', $orders);
$order .= ',a.istop DESC,a.isrecommend DESC,a.isheadline DESC,a.sorting ASC,a.date DESC,a.id DESC';
}
}
}
$where1 = array();
// tags数据筛选
$where2 = array();
if ($tags) {
$tags_arr = explode(',', $tags);
foreach ($tags_arr as $value) {
if ($value) {
if ($fuzzy) {
$where2[] = "a.tags like '%" . escape_string($value) . "%'";
} else {
$where2[] = "a.tags='" . escape_string($value) . "'";
}
}
}
}
// 存储搜索条件,条件为“并列”关系,由于为模糊匹配,条件为空时意味着“任意”
$where3 = array();
// 采取keyword方式
if ($keyword) {
if (strpos($field, '|')) { // 匹配多字段的关键字搜索
$field = explode('|', $field);
foreach ($field as $value) {
if ($value == 'title') {
$value = 'a.title';
}
if ($fuzzy) {
$like = " like '%" . $keyword . "%'"; // 前面已经转义过
} else {
$like = " like '" . $keyword . "'"; // 前面已经转义过
}
if (isset($where3[0])) {
$where3[0] .= ' OR ' . $value . $like;
} else {
$where3[0] = $value . $like;
}
}
if (count($field) > 1) {
$where3[0] = '(' . $where3[0] . ')';
}
} else { // 匹配单一字段的关键字搜索
if ($field) {
if ($field == 'title') {
$field = 'a.title';
}
$where3[$field] = $keyword;
} else {
$where3['a.title'] = $keyword;
}
}
}
// 数据接收
if ($_POST) {
$receive = $_POST;
} else {
$receive = $_GET;
}
foreach ($receive as $key => $value) {
if (! ! $value = request($key, 'vars')) {
if ($key == 'title') {
$key = 'a.title';
}
if (preg_match('/^[\w\-\.]+$/', $key)) { // 带有违规字符时不带入查询
$where3[$key] = $value;
}
}
}
// 去除特殊键值
unset($where3['appid']);
unset($where3['timestamp']);
unset($where3['signature']);
unset($where3['keyword']);
unset($where3['field']);
unset($where3['scode']);
unset($where3['page']);
unset($where3['from']);
unset($where3['isappinstalled']);
unset($where3['tdsourcetag']);
unset($where3['x']);
unset($where3['y']);
unset($where3['searchtpl']);
unset($where3['p']);
unset($where3['s']);
// 读取数据
$data = $this->model->getLists($acode, $scode, $num, $order, $where1, $where2, $where3, $fuzzy);
$Parser = new ParserController();
foreach ($data as $key => $value) {
if ($value->outlink) {
$data[$key]->apilink = $value->outlink;
} else {
$data[$key]->apilink = url('/api/content/index/scode/' . $value->id, false);
}
$data[$key]->likeslink = url('/home/Do/likes/id/' . $value->id, false);
$data[$key]->opposelink = url('/home/Do/oppose/id/' . $value->id, false);
$data[$key]->content = str_replace(STATIC_DIR . '/upload/', get_http_url() . STATIC_DIR . '/upload/', $value->content);
// 返回网页链接地址便于AJAX调用内容
$data[$key]->contentlink = $Parser->parserLink(2, $value->urlname, 'content', $value->scode, $value->sortfilename, $value->id, $value->filename);
}
// 输出数据
if (request('page') <= PAGECOUNT) {
json(1, $data);
} else {
return json(0, '已经到底了!');
}
}
// 读取留言记录
public function msg()
{
// 获取参数
$acode = request('acode', 'var') ?: $this->lg;
$num = request('num', 'int') ?: $this->config('pagesize');
// 获取栏目数
$data = $this->model->getMessage($acode, $num);
if (request('page') <= PAGECOUNT) {
json(1, $data);
} else {
return json(0, '已经到底了!');
}
}
// 新增留言
public function addmsg()
{
if ($_POST) {
if ($this->config('message_status') === '0') {
json(0, '系统已经关闭留言功能,请到后台开启再试!');
}
// 读取字段
if (! $form = $this->model->getFormField(1)) {
json(0, '接收表单不存在任何字段,请核对后重试!');
}
// 接收数据
$mail_body = '';
foreach ($form as $value) {
$field_data = post($value->name);
if (is_array($field_data)) { // 如果是多选等情况时转换
$field_data = implode(',', $field_data);
}
$field_data = str_replace('pboot:if', '', $field_data);
if ($value->required && ! $field_data) {
json(0, $value->description . '不能为空!');
} else {
$data[$value->name] = $field_data;
$mail_body .= $value->description . '' . $field_data . '<br>';
}
}
$status = $this->config('message_verify') == '0' ? 1 : 0;
// 设置其他字段
if ($data) {
$data['acode'] = request('acode', 'var') ?: $this->lg;
$data['user_ip'] = ip2long(get_user_ip());
$data['user_os'] = get_user_os();
$data['user_bs'] = get_user_bs();
$data['recontent'] = '';
$data['status'] = $status;
$data['create_user'] = 'api';
$data['update_user'] = 'api';
}
// 写入数据
if ($this->model->addMessage($value->table_name, $data)) {
$this->log('API提交留言数据成功');
if ($this->config('message_send_mail') && $this->config('message_send_to')) {
$mail_subject = "【'.CMSNAME.'】您有新的" . $value->form_name . "信息,请注意查收!";
$mail_body .= '<br>来自网站' . get_http_url() . '' . date('Y-m-d H:i:s') . '';
sendmail($this->config(), $this->config('message_send_to'), $mail_subject, $mail_body);
}
json(1, '留言提交成功!');
} else {
$this->log('API提交留言数据失败');
json(0, '留言提交失败!');
}
} else {
json(0, '留言提交失败请使用POST方式提交');
}
}
// 表单记录
public function form()
{
// 获取参数
$num = request('num', 'int') ?: $this->config('pagesize');
// 获取表单编码
if (! $fcode = request('fcode', 'var'))
json(0, '必须传递表单编码fcode');
// 获取表名称
if (! $table = $this->model->getFormTable($fcode)) {
json(0, '传递的fcode有误');
}
// 获取表数据
$data = $this->model->getForm($table, $num);
if (request('page') <= PAGECOUNT) {
json(1, $data);
} else {
return json(0, '已经到底了!');
}
}
// 表单提交
public function addform()
{
if ($_POST) {
if (! $fcode = request('fcode', 'var')) {
json(0, '传递的表单编码fcode有误');
}
if ($this->config('form_status') === '0') {
json(0, '系统已经关闭表单功能,请到后台开启再试!');
}
// 读取字段
if (! $form = $this->model->getFormField($fcode)) {
json(0, '接收表单不存在任何字段,请核对后重试!');
}
// 接收数据
$mail_body = '';
foreach ($form as $value) {
$field_data = post($value->name);
if (is_array($field_data)) { // 如果是多选等情况时转换
$field_data = implode(',', $field_data);
}
$field_data = str_replace('pboot:if', '', $field_data);
if ($value->required && ! $field_data) {
json(0, $value->description . '不能为空!');
} else {
$data[$value->name] = $field_data;
$mail_body .= $value->description . '' . $field_data . '<br>';
}
}
// 设置创建时间
if ($data) {
$data['create_time'] = get_datetime();
}
// 写入数据
if ($this->model->addForm($value->table_name, $data)) {
$this->log('API提交表单数据成功');
if ($this->config('form_send_mail') && $this->config('message_send_to')) {
$mail_subject = "【'.CMSNAME.'】您有新的" . $value->form_name . "信息,请注意查收!";
$mail_body .= '<br>来自网站' . get_http_url() . '' . date('Y-m-d H:i:s') . '';
sendmail($this->config(), $this->config('message_send_to'), $mail_subject, $mail_body);
}
json(1, '表单提交成功!');
} else {
$this->log('API提交表单数据失败');
json(0, '表单提交失败!');
}
} else {
json(0, '表单提交失败请使用POST方式提交');
}
}
// 空拦截
public function _empty()
{
json(0, '您调用的接口不存在,请核对后重试!');
}
}

View File

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

View File

@@ -0,0 +1,151 @@
<?php
/**
* @copyright (C)2020-2099 Hnaoyun Inc.
* @author XingMeng
* @email hnxsh@foxmail.com
* @date 2020年06月27日
* 评论控制器
*/
namespace app\home\controller;
use core\basic\Controller;
use app\home\model\ParserModel;
use core\basic\Url;
class CommentController extends Controller
{
protected $parser;
protected $model;
protected $htmldir;
public function __construct()
{
$this->model = new ParserModel();
$this->parser = new ParserController();
$this->htmldir = $this->config('tpl_html_dir') ? $this->config('tpl_html_dir') . '/' : '';
}
// 评论新增
public function add()
{
if ($_POST) {
if ($this->config('comment_status') === '0') {
error('系统已经关闭评论功能,请到后台开启再试!');
}
if (time() - session('lastsub') < 10) {
alert_back('您提交太频繁了,请稍后再试!');
}
if (! session('pboot_uid') && ! $this->config('comment_anonymous')) {
if (! ! $backurl = $_SERVER['HTTP_REFERER']) {
alert_location("请先注册登录后再评论!", Url::home('member/login', null, "backurl=" . urlencode($backurl)));
} else {
alert_location("请先注册登录后再评论!", Url::home('member/login'));
}
}
// 验证码验证
$checkcode = strtolower(post('checkcode', 'var'));
if ($this->config('comment_check_code') !== '0') {
if (! $checkcode) {
alert_back('验证码不能为空!');
}
if ($checkcode != session('checkcode')) {
alert_back('验证码错误!');
}
}
// 接收数据
$status = $this->config('comment_verify') === '0' ? 1 : 0;
if (! $contentid = request('contentid', 'int')) {
alert_back('文章ID未能正常获取请使用POST或URL参数传递');
}
$comment = post('comment');
$data = array(
'pid' => request('pid', 'int') ?: 0,
'contentid' => $contentid,
'comment' => $comment,
'uid' => session('pboot_uid'),
'puid' => request('puid', 'int'),
'likes' => 0,
'oppose' => 0,
'status' => $status,
'user_ip' => ip2long(get_user_ip()),
'user_os' => get_user_os(),
'user_bs' => get_user_bs(),
'create_time' => get_datetime(),
'update_user' => '',
'update_time' => ''
);
if ($this->model->addComment($data)) {
session('lastsub', time()); // 记录最后提交时间
$this->log('文章' . $contentid . '评论提交成功!');
if ($this->config('comment_send_mail') && $this->config('message_send_to')) {
$mail_subject = "【'.CMSNAME.'】您有新的文章评论信息,请注意查收!";
$mail_body = '评论内容:' . $comment . '<br>';
$mail_body .= '<br>来自网站 ' . get_http_url() . ' ' . date('Y-m-d H:i:s') . '';
sendmail($this->config(), $this->config('message_send_to'), $mail_subject, $mail_body);
}
if ($status) {
alert_location('评论提交成功!', '-1', 1);
} else {
alert_location('评论提交成功,请等待管理员审核!', '-1', 1);
}
} else {
$this->log('文章评论提交失败!');
alert_back('提交失败!');
}
} else {
alert_back('提交失败请使用POST方式提交');
}
}
// 我的评论
public function my()
{
// 未登录时跳转到用户登录
if (! session('pboot_uid')) {
location(Url::home('member/login'));
}
$content = parent::parser($this->htmldir . 'member/mycomment.html'); // 框架标签解析
$content = $this->parser->parserBefore($content); // CMS公共标签前置解析
$content = str_replace('{pboot:pagetitle}', '我的评论-{pboot:sitetitle}-{pboot:sitesubtitle}', $content);
$content = $this->parser->parserPositionLabel($content, 0, '我的评论', Url::home('comment/my')); // CMS当前位置标签解析
$content = $this->parser->parserSpecialPageSortLabel($content, - 3, '我的评论', Url::home('comment/my')); // 解析分类标签
$content = $this->parser->parserMyCommentLabel($content); // 我的评论
$content = $this->parser->parserAfter($content); // CMS公共标签后置解析
echo $content;
exit();
}
// 评论删除
public function del()
{
// 未登录时跳转到用户登录
if (! session('pboot_uid')) {
location(Url::home('member/login'));
}
// 执行删除
if (! ! $id = get('id', 'int')) {
if ($this->model->delComment($id)) {
alert_back('删除成功!', 1);
} else {
alert_back('删除失败!');
}
} else {
alert_back('传递参数有误!');
}
}
}

View File

@@ -0,0 +1,105 @@
<?php
/**
* @copyright (C)2020-2099 Hnaoyun Inc.
* @author XingMeng
* @email hnxsh@foxmail.com
* @date 2020年3月8日
* 表单控制器
*/
namespace app\home\controller;
use core\basic\Controller;
use app\home\model\ParserModel;
class FormController extends Controller
{
protected $model;
public function __construct()
{
$this->model = new ParserModel();
}
// 表单提交
public function index()
{
// 在非兼容模式接受地址第二参数值
if (defined('RVAR')) {
$_GET['fcode'] = RVAR;
}
if ($_POST) {
if ($this->config('form_status') === '0') {
error('系统已经关闭表单功能,请到后台开启再试!');
}
if (time() - session('lastsub') < 10) {
alert_back('您提交太频繁了,请稍后再试!');
}
if (! $fcode = get('fcode', 'var')) {
alert_back('传递的表单编码有误!');
}
if ($fcode == 1) {
alert_back('表单提交地址有误,留言提交请使用留言专用地址!');
}
// 验证码验证
$checkcode = strtolower(post('checkcode', 'var'));
if ($this->config('form_check_code') !== '0') {
if (! $checkcode) {
alert_back('验证码不能为空!');
}
if ($checkcode != session('checkcode')) {
alert_back('验证码错误!');
}
}
// 读取字段
if (! $form = $this->model->getFormField($fcode)) {
alert_back('接收表单不存在任何字段,请核对后重试!');
}
// 接收数据
$mail_body = '';
foreach ($form as $value) {
$field_data = post($value->name);
if (is_array($field_data)) { // 如果是多选等情况时转换
$field_data = implode(',', $field_data);
}
$field_data = preg_replace_r('/pboot:if/i', '', $field_data);
if ($value->required && ! $field_data) {
alert_back($value->description . '不能为空!');
} else {
$data[$value->name] = $field_data;
$mail_body .= $value->description . '' . $field_data . '<br>';
}
}
// 设置创建时间
if ($data) {
$data['create_time'] = get_datetime();
}
// 写入数据
if ($this->model->addForm($value->table_name, $data)) {
session('lastsub', time()); // 记录最后提交时间
$this->log('提交表单数据成功!');
if ($this->config('form_send_mail') && $this->config('message_send_to')) {
$mail_subject = "【'.CMSNAME.'】您有新的" . $value->form_name . "信息,请注意查收!";
$mail_body .= '<br>来自网站 ' . get_http_url() . ' ' . date('Y-m-d H:i:s') . '';
sendmail($this->config(), $this->config('message_send_to'), $mail_subject, $mail_body);
}
alert_location('提交成功!', '-1', 1);
} else {
$this->log('提交表单数据失败!');
alert_back('提交失败!');
}
} else {
alert_back('提交失败请使用POST方式提交');
}
}
}

View File

@@ -0,0 +1,363 @@
<?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 = P;
} 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点符号转换下划线
} elseif (get('tag')) { // 对于兼容模式tag需要自动跳转tag独立页面
$tag = new TagController();
$tag->index();
} elseif (get('keyword')) { // 兼容模式搜索处理
$search = new SearchController();
$search->index();
}
}
// 判断是否存在后缀
$url_rule_suffix = substr($this->config('url_rule_suffix'), 1);
$suffix = false;
$slash = false;
if (preg_match('/(.*)(_|\.)' . $url_rule_suffix . '$/', $path, $matchs)) {
$path = $matchs[1];
$suffix = true;
} elseif (preg_match('/^[\w\-\/]+\/$/', $path)) {
$slash = true;
$path = trim($path, '/');
}
$path_arr = $path ? explode('/', $path) : array();
// 开始路由
if (isset($path_arr) && count($path_arr) > 0) {
switch (strtolower($path_arr[0])) {
case 'search':
case 'keyword':
$search = new SearchController();
$search->index();
break;
case 'message':
$msg = new MessageController();
$msg->index();
break;
case 'form':
$_GET['fcode'] = $path_arr[1];
$form = new FormController();
$form->index();
break;
case 'sitemap':
case 'sitemap_xml':
$sitemap = new SitemapController();
$sitemap->index();
break;
case 'sitemap_txt':
$sitemap = new SitemapController();
$sitemap->linkTxt();
break;
case 'tag':
$tag = new TagController();
$tag->index();
break;
case 'member':
$member = new MemberController();
$member->{$path_arr[1]}();
break;
case 'comment':
$comment = new CommentController();
$comment->{$path_arr[1]}();
break;
default:
$url_break_char = $this->config('url_break_char') ?: '_';
$url_rule_content_path = $this->config('url_rule_content_path') ? true : false;
$err = '';
$iscontent = false;
// 开始进行地址匹配
if (! $suffix && ! ! $sort = $this->model->getSort($path)) {
// 栏目名称,即栏目全路径匹配
} elseif (preg_match('/^([a-zA-Z0-9\-\/]+)' . $url_break_char . '([0-9]+)$/i', $path, $matchs) && ! ! $sort = $this->model->getSort($matchs[1])) {
// 栏目名称_分页栏目分页的情况
define('CMS_PAGE_CUSTOM', true); // 设置走自定义CMS分页
$_GET['page'] = $matchs[2]; // 设置分页参数
} else {
if ($url_rule_content_path && ! ! $data = $this->model->getContent($path)) {
$iscontent = true; // 短路径情况
} elseif (! $url_rule_content_path) {
// 详情页至少是2级对地址进行栏目和内容路径拆分访问详情页
$part1 = dirname($path);
$part2 = basename($path);
while ($part1 != '.') {
if ((! ! $sort = $this->model->getSort($part1)) && ! ! $data = $this->model->getContent($part2)) {
// 栏目名称/内容名称或ID
$iscontent = true;
$scode = $sort->scode;
break;
} elseif (preg_match('/^([a-zA-Z0-9\-\/]+)' . $url_break_char . '([0-9]+)$/i', $part1, $matchs) && ! ! $model = $this->model->checkModelUrlname($matchs[1])) {
// 模型名称_栏目ID/内容名称或ID
$data = $this->model->getContent($part2);
$iscontent = true;
$scode = $matchs[2];
// 限制串模型多路径
if (! ! $data->urlname && $matchs[1] != $data->urlname) {
$err = true;
}
break;
} else {
$part2 = basename($part1) . '/' . $part2;
$part1 = dirname($part1);
}
}
// 限制串栏目多路径
if ($scode != $data->scode) {
$err = true;
}
// 限制串内容ID及名称多路径
if (! ! $data->filename && $part2 != $data->filename) {
$err = true;
}
}
// 执行未配置栏目名称但是配置了模型路径的情况路径匹配
if (! $iscontent) {
preg_match('/^([a-zA-Z0-9\-\/]+)(' . $url_break_char . '([0-9]+))?' . $url_break_char . '([0-9]+)$/i', $path, $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]);
}
// 限制串模型和栏目名称多路径,当栏目名称不为空时不允许使用模型路径
if ($sort->filename != '') {
$err = true;
}
// 限制串模型多路径
if (! ! $sort->urlname && $matchs[1] != $sort->urlname) {
$err = true;
}
}
}
if ($iscontent) {
define('CMS_PAGE', false); // 使用普通分页处理模型
if (! ! $data && $suffix && ! $err) {
$this->getContentPage($data);
} else {
_404('您访问的内容不存在,请核对后重试!');
}
} else {
define('CMS_PAGE', true); // 使用cms分页处理模型
if (! ! $sort && ! $suffix && ! $err) {
if ($sort->type == 1) {
$this->getAboutPage($sort);
} else {
$this->getListPage($sort);
}
} else {
_404('您访问的页面不存在,请核对后重试!');
}
}
}
} else {
$this->getIndexPage();
}
}
// 首页
private function getIndexPage()
{
$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 getListPage($sort)
{
// 调用栏目语言与当前语言不一致时,自动切换语言
if ($sort->acode != get_lg() && Config::get('lgautosw') !== '0') {
cookie('lg', $sort->acode);
}
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 getContentPage($data)
{
// 调用内容语言与当前语言不一致时,自动切换语言
if ($data->acode != get_lg() && Config::get('lgautosw') !== '0') {
cookie('lg', $data->acode);
}
// 读取模板
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 getAboutPage($sort)
{
// 调用栏目语言与当前语言不一致时,自动切换语言
if ($sort->acode != get_lg() && Config::get('lgautosw') !== '0') {
cookie('lg', $sort->acode);
}
// 读取数据
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,509 @@
<?php
/**
* @copyright (C)2016-2099 Hnaoyun Inc.
* @author XingMeng
* @email hnxsh@foxmail.com
* @date 2020年06月26日
* 会员前台控制器
*/
namespace app\home\controller;
use core\basic\Controller;
use app\home\model\MemberModel;
use core\basic\Url;
class MemberController extends Controller
{
protected $parser;
protected $model;
protected $htmldir;
public function __construct()
{
$this->model = new MemberModel();
$this->parser = new ParserController();
$this->htmldir = $this->config('tpl_html_dir') ? $this->config('tpl_html_dir') . '/' : '';
}
// 会员登录页面
public function login()
{
// 已经登录时跳转到用户中心
if (session('pboot_uid')) {
location(Url::home('member/ucenter'));
}
// 执行登录验证
if ($_POST) {
if ($this->config('login_status') === '0') {
error('系统已经关闭登录功能,请到后台开启再试!');
}
// 验证码验证
$checkcode = strtolower(post('checkcode', 'var'));
if ($this->config('login_check_code') !== '0') {
if (! $checkcode) {
alert_back('验证码不能为空!');
}
if ($checkcode != session('checkcode')) {
alert_back('验证码错误!');
}
}
$username = post('username');
$password = post('password');
if (! $username) {
alert_back('用户账号不能为空!');
}
// 检查用户名
if (! $this->model->checkUsername("username='$username' or useremail='$username' or usermobile='$username'")) {
alert_back('用户账号不存在!');
}
// 检查密码
if (! $password) {
alert_back('用户密码不能为空!');
} else {
$password = md5(md5($password));
}
// 登录验证
if (! ! $login = $this->model->login("(username='$username' or useremail='$username' or usermobile='$username') AND password='$password'")) {
if (! $login->status) {
alert_back('您的账号待审核,请联系管理员!');
}
session('pboot_uid', $login->id);
session('pboot_ucode', $login->ucode);
session('pboot_username', $login->username);
session('pboot_useremail', $login->seremail);
session('pboot_usermobile', $login->usermobile);
session('pboot_gid', $login->gid);
session('pboot_gcode', $login->gcode);
session('pboot_gname', $login->gname);
if (! ! $backurl = get('backurl')) {
alert_location('登录成功!', $backurl, 1);
} else {
alert_location('登录成功!', Url::home('member/ucenter'), 1);
}
} else {
alert_back('账号密码错误,请核对后重试!', 0);
}
} else {
$content = parent::parser($this->htmldir . 'member/login.html'); // 框架标签解析
$content = $this->parser->parserBefore($content); // CMS公共标签前置解析
$content = str_replace('{pboot:pagetitle}', $this->config('login_title') ?: '会员登录-{pboot:sitetitle}-{pboot:sitesubtitle}', $content);
$content = $this->parser->parserPositionLabel($content, 0, '会员登录', Url::home('member/login')); // CMS当前位置标签解析
$content = $this->parser->parserSpecialPageSortLabel($content, - 2, '会员登录', Url::home('member/login')); // 解析分类标签
$content = $this->parser->parserAfter($content); // CMS公共标签后置解析
echo $content;
exit();
}
}
// 会员注册页面
public function register()
{
// 已经登录时跳转到用户中心
if (session('pboot_uid')) {
location(Url::home('member/ucenter'));
}
// 执行注册
if ($_POST) {
if ($this->config('register_status') === '0') {
error('系统已经关闭注册功能,请到后台开启再试!');
}
if (time() - session('lastreg') < 10) {
alert_back('您注册太频繁了,请稍后再试!');
}
// 验证码验证
$checkcode = strtolower(post('checkcode', 'var'));
if ($this->config('register_check_code') !== '0') {
if (! $checkcode) {
alert_back('验证码不能为空!');
}
if ($checkcode != session('checkcode')) {
alert_back('验证码错误!');
}
}
$ucode = get_auto_code($this->model->getLastUcode(), 1);
$username = post('username'); // 接受用户名、邮箱、手机三种方式
$nickname = post('nickname');
$password = post('password');
$rpassword = post('rpassword');
$useremail = '';
$usermobile = '';
// 注册类型判断
if ($this->config('register_type') == 2) { // 邮箱注册
$useremail = $username;
if (! $useremail) {
alert_back('账号不能为空,请输入注册的邮箱账号!');
}
if (! preg_match('/^[\w]+@[\w\.]+\.[a-zA-Z]+$/', $useremail)) {
alert_back('账号格式不正确,请输入正确的邮箱账号!');
}
if ($this->model->checkUsername("useremail='$useremail' OR username='$useremail'")) {
alert_back('您输入的邮箱已被注册!');
}
} elseif ($this->config('register_type') == 3) { // 手机注册
$usermobile = $username;
if (! $usermobile) {
alert_back('账号不能为空,请输入注册的手机号码!');
}
if (! preg_match('/^1[0-9]{10}$/', $usermobile)) {
alert_back('账号格式不正确,请输入正确的手机号码!');
}
if ($this->model->checkUsername("usermobile='$usermobile' OR username='$usermobile'")) {
alert_back('您输入的手机号码已被注册!');
}
} else { // 账号注册
if (! $username) {
alert_back('用户名不能为空!');
}
if (! preg_match('/^[\w\@\.]+$/', $username)) {
alert_back('用户账号含有不允许的特殊字符!');
}
// 检查用户名
if ($this->model->checkUsername("username='$username' OR useremail='$username' OR usermobile='$username'")) {
alert_back('您输入的账号已被注册!');
}
}
if ($password != $rpassword) {
alert_back('确认密码不正确!');
}
if (! $password) {
alert_back('密码不能为空!');
} else {
$password = md5(md5($password));
}
// 默认值设置
$status = $this->config('register_verify') ? 0 : 1; // 默认不需要审核
$score = $this->config('register_score') ?: 0;
$group = $this->model->getFirstGroup();
$gid = $this->model->getGroupID($this->config('register_gcode')) ?: $group->id;
// 构建数据
$data = array(
'ucode' => $ucode,
'username' => $username,
'useremail' => $useremail,
'usermobile' => $usermobile,
'nickname' => $nickname,
'password' => $password,
'headpic' => '',
'status' => $status,
'gid' => $gid,
'wxid' => '',
'qqid' => '',
'wbid' => '',
'activation' => 1,
'score' => $score,
'register_time' => get_datetime(),
'login_count' => 0,
'last_login_ip' => 0,
'last_login_time' => 0
);
// 读取字段
if (! ! $field = $this->model->getField()) {
foreach ($field as $value) {
$field_data = post($value->name);
if (is_array($field_data)) { // 如果是多选等情况时转换
$field_data = implode(',', $field_data);
}
$field_data = preg_replace_r('pboot:if', '', $field_data);
if ($value->required && ! $field_data) {
alert_back($value->description . '不能为空!');
} else {
$data[$value->name] = $field_data;
}
}
}
// 执行注册
if ($this->model->register($data)) {
session('lastreg', time()); // 记录最后提交时间
if ($status) {
alert_location('注册成功!', Url::home('member/login'), 1);
} else {
alert_location('注册成功,请等待管理员审核!', Url::home('member/login'), 1);
}
} else {
error('会员注册失败!', - 1);
}
} else {
$content = parent::parser($this->htmldir . 'member/register.html'); // 框架标签解析
$content = $this->parser->parserBefore($content); // CMS公共标签前置解析
$content = str_replace('{pboot:pagetitle}', $this->config('register_title') ?: '会员注册-{pboot:sitetitle}-{pboot:sitesubtitle}', $content);
$content = $this->parser->parserPositionLabel($content, 0, '会员注册', Url::home('member/register')); // CMS当前位置标签解析
$content = $this->parser->parserSpecialPageSortLabel($content, - 3, '会员注册', Url::home('member/register')); // 解析分类标签
$content = $this->parser->parserAfter($content); // CMS公共标签后置解析
echo $content;
exit();
}
}
// 用户中心
public function ucenter()
{
// 未登录时跳转到用户登录
if (! session('pboot_uid')) {
location(Url::home('member/login'));
}
$content = parent::parser($this->htmldir . 'member/ucenter.html'); // 框架标签解析
$content = $this->parser->parserBefore($content); // CMS公共标签前置解析
$content = str_replace('{pboot:pagetitle}', $this->config('ucenter_title') ?: '个人中心-{pboot:sitetitle}-{pboot:sitesubtitle}', $content);
$content = $this->parser->parserPositionLabel($content, 0, '个人中心', Url::home('member/ucenter')); // CMS当前位置标签解析
$content = $this->parser->parserSpecialPageSortLabel($content, - 4, '个人中心', Url::home('member/ucenter')); // 解析分类标签
$content = $this->parser->parserAfter($content); // CMS公共标签后置解析
echo $content;
exit();
}
// 用户修改
public function umodify()
{
// 未登录时跳转到用户登录
if (! session('pboot_uid')) {
location(Url::home('member/login'));
}
// 执行资料修改
if ($_POST && session('pboot_uid')) {
$nickname = post('nickname');
$useremail = post('useremail');
$usermobile = post('usermobile');
$password = post('password');
$rpassword = post('rpassword');
$headpic = str_replace(SITE_DIR, '', post('headpic'));
if ($useremail) { // 邮箱校验
if (! preg_match('/^[\w]+@[\w\.]+\.[a-zA-Z]+$/', $useremail)) {
alert_back('邮箱格式不正确,请输入正确的邮箱账号!');
}
if ($this->model->checkUsername("(useremail='$useremail' OR username='$useremail') AND id<>'" . session('pboot_uid') . "'")) {
alert_back('您输入的邮箱已被注册!');
}
}
if ($usermobile) { // 手机检验
if (! preg_match('/^1[0-9]{10}$/', $usermobile)) {
alert_back('手机格式不正确,请输入正确的手机号码!');
}
if ($this->model->checkUsername("(usermobile='$usermobile' OR username='$usermobile') AND id<>'" . session('pboot_uid') . "'")) {
alert_back('您输入的手机号码已被注册!');
}
}
// 构建数据
$data = array(
'nickname' => $nickname,
'useremail' => $useremail,
'usermobile' => $usermobile,
'headpic' => $headpic
);
// 密码修改
if ($password) {
if ($password != $rpassword) {
alert_back('确认密码不正确!');
} else {
$data['password'] = md5(md5($password));
}
}
// 读取字段
if (! ! $field = $this->model->getField()) {
foreach ($field as $value) {
$field_data = post($value->name);
if (is_array($field_data)) { // 如果是多选等情况时转换
$field_data = implode(',', $field_data);
}
$field_data = preg_replace_r('pboot:if', '', $field_data);
if ($value->required && ! $field_data) {
alert_back($value->description . '不能为空!');
} else {
$data[$value->name] = $field_data;
}
}
}
// 不允许修改的字段
unset($data['id']);
unset($data['ucode']);
unset($data['username']);
unset($data['status']);
unset($data['gid']);
unset($data['wxid']);
unset($data['qqid']);
unset($data['wbid']);
unset($data['score']);
unset($data['register_time']);
unset($data['login_count']);
unset($data['last_login_ip']);
unset($data['last_login_time']);
// 执行修改
if ($this->model->modUser($data)) {
alert_location('修改成功!', Url::home('member/umodify'), 1);
} else {
error('资料修改失败!', - 1);
}
} else {
$content = parent::parser($this->htmldir . 'member/umodify.html'); // 框架标签解析
$content = $this->parser->parserBefore($content); // CMS公共标签前置解析
$content = str_replace('{pboot:pagetitle}', $this->config('umodify_title') ?: '资料修改-{pboot:sitetitle}-{pboot:sitesubtitle}', $content);
$content = $this->parser->parserPositionLabel($content, 0, '资料修改', Url::home('member/umodify')); // CMS当前位置标签解析
$content = $this->parser->parserSpecialPageSortLabel($content, - 5, '资料修改', Url::home('member/umodify')); // 解析分类标签
$content = $this->parser->parserAfter($content); // CMS公共标签后置解析
echo $content;
exit();
}
}
// 退出登录
public function logout()
{
session('pboot_uid', '');
session('pboot_ucode', '');
session('pboot_username', '');
session('pboot_useremail', '');
session('pboot_usermobile', '');
session('pboot_gid', '');
session('pboot_gcode', '');
session('pboot_gname', '');
location(Url::home('member/login'));
}
// 文件上传方法(Ajax)
public function upload()
{
// 必须登录
if (! session('pboot_uid')) {
json(0, '请先登录!');
}
$ext = $this->config('home_upload_ext') ?: "jpg,jpeg,png,gif,xls,xlsx,doc,docx,ppt,pptx,rar,zip,pdf,txt";
$upload = upload('upload', $ext);
if (is_array($upload)) {
json(1, $upload);
} else {
json(0, $upload);
}
}
// 发送邮件
public function sendEmail()
{
if ($this->config('register_check_code') != 2) {
json(0, '发送失败,后台配置非邮箱验证码模式!');
}
if (time() - session('lastsend') < 10) {
json(0, '您提交太频繁了,请稍后再试!');
}
if (! session('sendemail')) {
json(0, '非法提交发送邮件!');
}
// 发送邮箱参数
if (! ! $to = post('to')) {
if (! preg_match('/^[\w]+@[\w]+\.[a-zA-Z]+$/', $to)) {
json(0, '邮箱格式不正确,请输入正确的邮箱账号!');
}
} else {
json(0, '发送失败缺少发送对象参数to');
}
// 检查邮箱注册
if ($this->model->checkUsername("useremail='$to' OR username='$to'")) {
alert_back('您输入的邮箱已被注册!');
}
$rs = false;
if ($to) {
session('lastsend', time()); // 记录最后提交时间
$mail_subject = "【'.CMSNAME.'】您有新的验证码信息,请注意查收!";
$code = create_code(4);
session('checkcode', strtolower($code));
$mail_body = "您的验证码为:" . $code;
$mail_body .= '<br>来自网站 ' . get_http_url() . ' ' . date('Y-m-d H:i:s') . '';
$rs = sendmail($this->config(), $to, $mail_subject, $mail_body);
}
if ($rs === true) {
json(1, '发送成功!');
} else {
json(0, '发送失败,' . $rs);
}
}
// 检查用户是否注册
public function isRegister()
{
// 接受用户名、邮箱、手机三种方式
$info = '';
if (! $username = post('username')) {
$err = '账号不能为空!';
}
// 注册类型判断
if ($this->config('register_type') == 2) { // 邮箱注册
if (! preg_match('/^[\w]+@[\w\.]+\.[a-zA-Z]+$/', $username)) {
$err = '账号格式不正确,请输入正确的邮箱账号!';
}
if ($this->model->checkUsername("useremail='$username' OR username='$username'")) {
$err = '您输入的邮箱已被注册!';
} else {
$suc = '您输入的邮箱可以使用!';
}
} elseif ($this->config('register_type') == 3) { // 手机注册
if (! preg_match('/^1[0-9]{10}$/', $username)) {
$err = '账号格式不正确,请输入正确的手机号码!';
}
if ($this->model->checkUsername("usermobile='$username' OR username='$username'")) {
$err = '您输入的手机号码已被注册!';
} else {
$suc = '您输入的手机号码可以使用!';
}
} else { // 账号注册
if (! preg_match('/^[\w\@\.]+$/', $username)) {
$err = '用户账号含有不允许的特殊字符!';
}
// 检查用户名
if ($this->model->checkUsername("username='$username' OR useremail='$username' OR usermobile='$username'")) {
$err = '您输入的账号已被注册!';
} else {
$suc = '您输入的账号可以使用!';
}
}
if ($err) {
json(1, $err);
} else {
json(0, $suc);
}
}
public function _empty()
{
_404('您访问的地址不存在,请核对再试!');
}
}

View File

@@ -0,0 +1,112 @@
<?php
/**
* @copyright (C)2020-2099 Hnaoyun Inc.
* @author XingMeng
* @email hnxsh@foxmail.com
* @date 2020年3月8日
* 留言控制器
*/
namespace app\home\controller;
use core\basic\Controller;
use app\home\model\ParserModel;
use core\basic\Url;
class MessageController extends Controller
{
protected $model;
public function __construct()
{
$this->model = new ParserModel();
}
// 留言新增
public function index()
{
if ($_POST) {
if ($this->config('message_status') === '0') {
error('系统已经关闭留言功能,请到后台开启再试!');
}
if (time() - session('lastsub') < 10) {
alert_back('您提交太频繁了,请稍后再试!');
}
// 需登录
if ($this->config('message_rqlogin') && ! session('pboot_uid')) {
if (! ! $backurl = $_SERVER['HTTP_REFERER']) {
alert_location("请先注册登录后再留言!", Url::home('member/login', null, "backurl=" . urlencode($backurl)));
} else {
alert_location("请先注册登录后再留言!", Url::home('member/login'));
}
}
// 验证码验证
$checkcode = strtolower(post('checkcode', 'var'));
if ($this->config('message_check_code') !== '0') {
if (! $checkcode) {
alert_back('验证码不能为空!');
}
if ($checkcode != session('checkcode')) {
alert_back('验证码错误!');
}
}
// 读取字段
if (! $form = $this->model->getFormField(1)) {
alert_back('留言表单不存在任何字段,请核对后重试!');
}
// 接收数据
$mail_body = '';
foreach ($form as $value) {
$field_data = post($value->name);
if (is_array($field_data)) { // 如果是多选等情况时转换
$field_data = implode(',', $field_data);
}
$field_data = preg_replace_r('/pboot:if/i', '', $field_data);
if ($value->required && ! $field_data) {
alert_back($value->description . '不能为空!');
} else {
$data[$value->name] = $field_data;
$mail_body .= $value->description . '' . $field_data . '<br>';
}
}
$status = $this->config('message_verify') === '0' ? 1 : 0;
// 设置额外数据
if ($data) {
$data['acode'] = get_lg();
$data['user_ip'] = ip2long(get_user_ip());
$data['user_os'] = get_user_os();
$data['user_bs'] = get_user_bs();
$data['recontent'] = '';
$data['status'] = $status;
$data['create_user'] = 'guest';
$data['update_user'] = 'guest';
$data['uid'] = session('pboot_uid');
}
if ($this->model->addMessage($data)) {
session('lastsub', time()); // 记录最后提交时间
$this->log('留言提交成功!');
if ($this->config('message_send_mail') && $this->config('message_send_to')) {
$mail_subject = "【'.CMSNAME.'】您有新的" . $value->form_name . "信息,请注意查收!";
$mail_body .= '<br>来自网站 ' . get_http_url() . ' ' . date('Y-m-d H:i:s') . '';
sendmail($this->config(), $this->config('message_send_to'), $mail_subject, $mail_body);
}
alert_location('提交成功!', '-1', 1);
} else {
$this->log('留言提交失败!');
alert_back('提交失败!');
}
} else {
alert_back('提交失败请使用POST方式提交');
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,97 @@
<?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>' . "\n";
$str .= $this->makeNode('', date('Y-m-d'), '1.00'); // 根目录
$sorts = $this->model->getSorts();
$Parser = new ParserController();
foreach ($sorts as $value) {
if ($value->outlink) {
continue;
} elseif ($value->type == 1) {
$link = $Parser->parserLink(1, $value->urlname, 'about', $value->scode, $value->filename);
$str .= $this->makeNode($link, date('Y-m-d'), '0.80');
} else {
$link = $Parser->parserLink(2, $value->urlname, 'list', $value->scode, $value->filename);
$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 {
$link = $Parser->parserLink(2, $value2->urlname, 'content', $value2->scode, $value2->sortfilename, $value2->id, $value2->filename);
}
$str .= $this->makeNode($link, date('Y-m-d'), '0.60');
}
}
}
echo $str . "\n</urlset>";
}
// 生成结点信息
private function makeNode($link, $date, $priority = 0.60)
{
$node = '
<url>
<loc>' . get_http_url() . $link . '</loc>
<priority>' . $priority . '</priority>
<lastmod>' . $date . '</lastmod>
<changefreq>Always</changefreq>
</url>';
return $node;
}
// 文本格式
public function linkTxt()
{
$sorts = $this->model->getSorts();
$Parser = new ParserController();
$str = get_http_url() . "\n";
foreach ($sorts as $value) {
if ($value->outlink) {
continue;
} elseif ($value->type == 1) {
$link = $Parser->parserLink(1, $value->urlname, 'about', $value->scode, $value->filename);
} else {
$link = $Parser->parserLink(2, $value->urlname, 'list', $value->scode, $value->filename);
$str .= get_http_url() . $link . "\n";
$contents = $this->model->getSortContent($value->scode);
foreach ($contents as $value2) {
if ($value2->outlink) { // 外链
continue;
} else {
$link = $Parser->parserLink(2, $value2->urlname, 'content', $value2->scode, $value2->sortfilename, $value2->id, $value2->filename);
}
$str .= get_http_url() . $link . "\n";
}
}
}
echo $str;
}
}

View File

@@ -0,0 +1,991 @@
<?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)
{
if ($urlname == 'list' || $urlname == 'about') {
return true;
}
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, $field)
{
$join = array(
'ay_content_ext b',
'a.id=b.contentid',
'LEFT'
);
$result = parent::table('ay_content a')->field($field . ',picstitle')
->join($join)
->where("a.id='$id'")
->where('a.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,79 @@
<?php
/**
* @copyright (C)2016-2099 Hnaoyun Inc.
* @author XingMeng
* @email hnxsh@foxmail.com
* @date 2018年2月14日
* Sitemap模型
*/
namespace app\home\model;
use core\basic\Model;
class SitemapModel extends Model
{
// 分类栏目列表
public function getSorts()
{
$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'
);
$result = parent::table('ay_content_sort a')->field($fields)
->where('a.status=1')
->where("a.acode='" . get_lg() . "'")
->join($join)
->order('a.pcode,a.sorting,a.id')
->select();
return $result;
}
// 指定列表内容
public function getSortContent($scode)
{
$fields = array(
'a.id',
'a.filename',
'a.date',
'c.type',
'c.urlname',
'b.scode',
'b.filename as sortfilename'
);
$join = array(
array(
'ay_content_sort b',
'a.scode=b.scode',
'LEFT'
),
array(
'ay_model c',
'b.mcode=c.mcode',
'LEFT'
)
);
$where = array(
'a.status=1',
'c.type=2'
);
return parent::table('ay_content a')->field($fields)
->where("a.scode='$scode'")
->where($where)
->join($join)
->select();
}
}

View File

@@ -0,0 +1,708 @@
##########################################
官方网站https://www.pbootcms.com
标签手册https://www.pbootcms.com/docs.html
##########################################
PbootCMS V3.1.1 build 2021-10-26
1、修复上版本sitemap短路径模式不统一问题
2、修复栏目名称必填导致外链跳转栏目无法添加
3、修复数据库备份引号未转义问题
4、优化栏目管理跳转内容支持跳转指定子栏目
5、优化会话清理功能
6、优化更彻底的OEM定义
7、优化轮播及友链支持修改分组
8、新增sitemap.txt格式的支持
PbootCMS V3.1.0 build 2021-10-24
1、修复地址串栏目及模型可访问问题
2、优化if语句执行性能提高系统速度
3、新增详情页URL路径支持层级路径定义
4、新增后台栏目及内容开关无刷新操作
5、新增文章新增时自动提取缩略图
6、新增后台栏目管理跳转文章链接
7、新增文章扩展字段多图类型的支持
8、配合多图扩展新增多图标签{pboot:pics}指定field字段参数
9、新增详情页URL是否带目录路径控制参数
10、修复自适应标题标签无站点副标题时横线问题
11、其他问题修复与优化
PbootCMS V3.0.9 build 2021-10-13
1、修复上版本栏目分享到微信出现打不开问题
2、修复pboot:sql循环标签无法传带引号参数问题
3、增强系统安全性;
PbootCMS V3.0.8 build 2021-10-11
1、修复部分环境错误页面状态码不对问题
2、启用访问地址严格模式避免多地址指向问题
3、其他问题修复与优化
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、正式发布第一个版本。