1.新增插件。2.升级各依赖组件

This commit is contained in:
taoser 2021-11-02 15:40:58 +08:00
parent afada3a373
commit 184eb4ce30
80 changed files with 2815 additions and 900 deletions

View File

@ -2,13 +2,13 @@
> TaoLer是一个简单迅捷的轻论坛系统适用于个人或组织区域型信息交流发布平台。 > TaoLer是一个简单迅捷的轻论坛系统适用于个人或组织区域型信息交流发布平台。
* 官网https://www.aieok.com * 官网https://www.aieok.com:8443
* 前台http://bbs.aieok.com:888 * 前台http://bbs.aieok.com:888
* 后台http://adm.aieok.com:888 * 后台http://adm.aieok.com:888
* 账号test * 账号test
* 密码test123 * 密码test123
* 版本TaoLer 1.8.8 * 版本TaoLer 1.8.10
* 日期2021.10.12 * 日期2021.11.2
#### 项目地址 #### 项目地址
@ -97,6 +97,15 @@
#### 前后台独立域名的绑定 #### 前后台独立域名的绑定
1. 手动修改`config/app.php`文件内的`'domain_bind'`对应的应用。 1. 手动修改`config/app.php`文件内的`'domain_bind'`对应的应用。
```html
// 域名绑定(自动多应用模式有效)
'domain_bind' => [
'bbs' => 'index', //bbs.xxx.com 访问的是Index应用
'adm' => 'admin', //adm.xxx.com 访问的是Admin应用
'api' => 'api' //api.xxx.com 访问的是Admin应用
'www.test.com' => 'test' //www.test.com 访问的是Test应用
],
```
2. 后面会针对动态的设置绑定域名功能开发...此处待完成 2. 后面会针对动态的设置绑定域名功能开发...此处待完成

57
app/404.html Normal file
View File

@ -0,0 +1,57 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>404 - TaoLer社区</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="keywords" content="fly,layui,前端社区">
<meta name="description" content="Fly社区是模块化前端UI框架Layui的官网社区致力于为web开发提供强劲动力">
<link rel="stylesheet" href="/static/layui/css/layui.css">
<link rel="stylesheet" href="/static/res/css/global.css" charset="utf-8">
</head>
<body>
<include file="/view/taoler/index/public/header" />
<include file="./taoler/index/public/column" />
<div class="layui-container fly-marginTop">
<div class="fly-panel">
<div class="fly-none">
<h2><i class="iconfont icon-404"></i></h2>
<p>页面或者数据被<a href="/" target="_blank"> 纸飞机app </a>运到火星了,啥都看不到了…<a href="/">请返回首页</a></p>
</div>
</div>
</div>
<include file="./footer" />
<script src="/static/layui/jquery.min.js" charset="utf-8"></script>
<script src="/static/layui/layui.js" charset="utf-8"></script>
<script>
layui.cache.user = {
username: '{$user.name??'游客'}'
,uid: {$user.id ? 168*$user.id : -1}
,avatar: '{if condition="$user['user_img'] neq ''"}/uploads/{$user['user_img']}{else /}/static/res/images/avatar/00.jpg{/if}'
,experience: 83
,sex: '{if condition="$user['sex'] eq 0"}男{else/}女{/if}'
};
layui.config({
version: "3.0.0"
,base: '/static/res/mods/'
}).extend({
fly: 'index'
}).use('fly');
</script>
</body>
</html>

View File

@ -9,24 +9,42 @@ use think\facade\Config;
use app\admin\model\Addons as AddonsModel; use app\admin\model\Addons as AddonsModel;
use taoler\com\Files; use taoler\com\Files;
use taoler\com\Api; use taoler\com\Api;
use app\common\lib\SetConf;
use think\App;
use app\common\lib\ZipFile;
class Addons extends AdminController class Addons extends AdminController
{ {
/** /**
* 显示资源列表 * @return string
*
* @return \think\Response
*/ */
public function index() public function index()
{ {
//$conf = new \addons\social\model\Conf;
//$arr = $conf->getConf();
//dump($arr);
//dump($arr[0]['value']['app_key']);
return View::fetch();
}
public function addonsList()
{
$type = input('type'); $type = input('type');
//$filter = input('filter') ? input('filter') : 'public-list'; $res = [];
//动态field
switch($type){ switch($type){
//已安装 //已安装
case 'installed': case 'installed':
$col = [ $addons = Files::getDirName('../addons/');
['type' => 'numbers', 'fixed'=> 'left'], if($addons){
$res = ['code'=>0,'msg'=>'','count'=>5];
foreach($addons as $v){
$info_file = '../addons/'.$v.'/info.ini';
$info = parse_ini_file($info_file);
$res['data'][] = $info;
}
$res['col'] = [
['type' => 'numbers'],
['field' => 'name','title'=> '插件', 'width'=> 150], ['field' => 'name','title'=> '插件', 'width'=> 150],
['field'=> 'title','title'=> '标题', 'width'=> 100], ['field'=> 'title','title'=> '标题', 'width'=> 100],
['field'=> 'version','title'=> '版本', 'width'=> 100], ['field'=> 'version','title'=> '版本', 'width'=> 100],
@ -37,11 +55,20 @@ class Addons extends AdminController
['field' => 'ctime','title'=> '到期时间', 'width'=> 150], ['field' => 'ctime','title'=> '到期时间', 'width'=> 150],
['title' => '操作', 'width'=> 220, 'align'=>'center', 'toolbar'=> '#addons-installed-tool'] ['title' => '操作', 'width'=> 220, 'align'=>'center', 'toolbar'=> '#addons-installed-tool']
]; ];
} else {
$res = ['code'=>-1,'msg'=>'没有安装任何插件'];
}
break; break;
//在线 //在线
case 'onlineAddons': case 'onlineAddons':
$col = [ $url = $this->getSystem()['api_url'].'/v1/addons';
['type' => 'numbers', 'fixed'=> 'left'], $addons = Api::urlPost($url,[]);
if( $addons->code !== -1){
$res['code'] = 0;
$res['msg'] = '';
$res['data'] = $addons->data;
$res['col'] = [
['type' => 'numbers'],
['field' => 'name','title'=> '插件', 'width'=> 150], ['field' => 'name','title'=> '插件', 'width'=> 150],
['field'=> 'title','title'=> '标题', 'width'=> 100], ['field'=> 'title','title'=> '标题', 'width'=> 100],
['field'=> 'version','title'=> '版本', 'width'=> 100], ['field'=> 'version','title'=> '版本', 'width'=> 100],
@ -53,89 +80,60 @@ class Addons extends AdminController
['field' => 'ctime','title'=> '时间', 'width'=> 150], ['field' => 'ctime','title'=> '时间', 'width'=> 150],
['title' => '操作', 'width'=> 150, 'align'=>'center', 'toolbar'=> '#addons-tool'] ['title' => '操作', 'width'=> 150, 'align'=>'center', 'toolbar'=> '#addons-tool']
]; ];
break; } else {
default: $res = ['code'=>-1,'msg'=>''];
$col = [
['type' => 'numbers', 'fixed'=> 'left'],
['field' => 'name','title'=> '插件', 'width'=> 150],
['field'=> 'title','title'=> '标题', 'width'=> 100],
['field'=> 'version','title'=> '版本', 'width'=> 100],
['field' => 'author','title'=> '作者', 'width'=> 100],
['field' => 'description','title'=> '简介', 'minWidth'=> 200],
['field' => 'status','title'=> '状态', 'width'=> 100],
['field' => 'install','title'=> '安装', 'width'=> 100],
['field' => 'ctime','title'=> '到期时间', 'width'=> 150],
['title' => '操作', 'width'=> 220, 'align'=>'center', 'toolbar'=> '#addons-installed-tool']
];
}
View::assign('col',$col);
return View::fetch();
}
public function addonsList()
{
$type = input('type') ? input('type') : 'installed';
$res = [];
switch($type){
//已安装
case 'installed':
$addons = Files::getDirName('../addons/');
if($addons){
$res = ['code'=>0,'msg'=>'','count'=>5];
foreach($addons as $v){
$info_file = '../addons/'.$v.'/info.ini';
$info = parse_ini_file($info_file);
$res['data'][] = $info;
}
}
break;
//在线
case 'onlineAddons':
$url = $this->getSystem()['api_url'].'/v1/addons';
$addons = Api::urlPost($url,[]);
if( $addons->code !== -1){
$res['code'] = 0;
$res['msg'] = '';
$res['data'] = $addons->data;
}
break;
//已安装
default:
$addons = Files::getDirName('../addons/');
if($addons){
$res = ['code'=>0,'msg'=>'','count'=>5];
foreach($addons as $v){
$info_file = '../addons/'.$v.'/info.ini';
$info = parse_ini_file($info_file);
$res['data'][] = $info;
}
} }
break; break;
} }
return json($res); return json($res);
} }
/** /**
* 显示创建资源表单页. * 显示创建资源表单页.
* *
* @return \think\Response * @return \think\Response
*/ */
public function install() public function add()
{ {
// //添加版本
if(Request::isAjax()){
$data = Request::param();
$result = AddonsModel::create($data);
if($result){
$res = ['code'=>0,'msg'=>'添加成功'];
}else{
$res = ['code'=>-1,'msg'=>'添加失败'];
}
return json($res);
}
return View::fetch();
} }
/**
* 编辑版本
*
* @param int $id
* @return \think\Response
*/
public function edit($id)
{
$addons = AddonsModel::find($id);
if(Request::isAjax()){
$data = Request::only(['id','addons_name','addons_version','addons_auther','addons_resume','addons_price','addons_src']);
$result = $addons->where('id',$id)->save($data);
if($result){
$res = ['code'=>0,'msg'=>'编辑成功'];
}else{
$res = ['code'=>-1,'msg'=>'编辑失败'];
}
return json($res);
}
View::assign('addons',$addons);
return View::fetch();
}
/** /**
* 上传版本的zip资源 * 上传版本的zip资源
@ -146,23 +144,193 @@ class Addons extends AdminController
*/ */
public function uploadZip() public function uploadZip()
{ {
// $id = Request::param();
$file = request()->file('file');
try {
validate(['file'=>'filesize:2048|fileExt:zip,rar,7z'])
->check(array($file));
$savename = \think\facade\Filesystem::disk('public')->putFile('addons',$file);
} catch (think\exception\ValidateException $e) {
echo $e->getMessage();
}
$upload = Config::get('filesystem.disks.public.url');
if($savename){
$name_path =str_replace('\\',"/",$upload.'/'.$savename);
$res = ['code'=>0,'msg'=>'插件上传成功','src'=>$name_path];
} else {
$res = ['code'=>-1,'msg'=>'上传错误'];
}
return json($res);
} }
/** //安装插件
* 删除指定资源 public function install()
*
* @param int $id
* @return \think\Response
*/
public function delete($id)
{ {
$version = AddonsModel::find($id); $data = Request::param();
$res = $version->delete(); $url = $this->getSystem()['api_url'].'/v1/getaddons';
if($res){ $addons = Api::urlPost($url,['name'=>$data['name'],'version'=>$data['version']]);
return json(['code'=>0,'msg'=>'删除成功']); if( $addons->code == -1) {
} else { return json(['code'=>$addons->code,'msg'=>$addons->msg]);
return json(['code'=>-1,'msg'=>'删除失败']);
} }
//是否安装?
$addInstalledVersion = get_addons_info($data['name']);
if(!empty($addInstalledVersion)){
$verRes = version_compare($data['version'],$addInstalledVersion['version'],'>');
if(!$verRes){
return json(['code'=>-1,'msg'=>'不能降级,请选择正确版本']);
}
}
$file_url = $addons->addons_src;
//判断远程文件是否可用存在
$header = get_headers($file_url, true);
if(!isset($header[0]) && (strpos($header[0], '200') || strpos($header[0], '304'))){
return json(['code'=>-1,'msg'=>'获取远程文件失败']);
}
//把远程文件放入本地
//拼接路径
$addons_dir = Files::getDirPath('../runtime/addons/');
Files::mkdirs($addons_dir);
$package_file = $addons_dir . $data['name'] .'.zip'; //升级的压缩包文件
// halt($package_file);
$cpfile = copy($file_url,$package_file);
if(!$cpfile)
{
return json(['code'=>-1,'msg'=>'下载升级文件失败']);
}
$uzip = new ZipFile();
$zipDir = strstr($package_file, '.zip',true); //返回文件名后缀前的字符串
$zipPath = Files::getDirPath($zipDir); //转换为带/的路径 压缩文件解压到的路径
$unzip_res = $uzip->unzip($package_file,$zipPath,true);
if(!$unzip_res)
{
return json(['code'=>-1,'msg'=>'解压失败']);
}
//升级插件
if(is_dir($zipPath))
{
//升级前的写入文件权限检查
$allUpdateFiles = Files::getAllFile($zipPath);
if (empty($allUpdateFiles)) return json(['code' => -1, 'msg' => '无可更新文件。']);
$checkString = '';
foreach ($allUpdateFiles as $updateFile) {
$coverFile = ltrim(str_replace($zipPath, '', $updateFile), DIRECTORY_SEPARATOR);
$dirPath = dirname('../'.$coverFile);
if (file_exists('../'.$coverFile)) {
if (!is_writable('../'.$coverFile)) $checkString .= $coverFile . '&nbsp;[<span class="text-red">' . '无写入权限' . '</span>]<br>';
} else {
if (!is_dir($dirPath)) @mkdir($dirPath, 0777, true);
if (!is_writable($dirPath)) $checkString .= $dirPath . '&nbsp;[<span class="text-red">' . '无写入权限' . '</span>]<br>';
}
}
if (!empty($checkString)) return json(['code' => -1, 'msg' => $checkString]);
$addonsPath = '../';
$cpRes = Files::copyDirs($zipPath,$addonsPath);
$cpData = $cpRes->getData();
//更新失败
if($cpData['code'] == -1)
{
return json(['code'=>-1,'msg'=>$cpData['msg']]);
}
//清除
Files::delDirAndFile('../runtime/addons/');
}
return json(['code'=>0,'msg'=>'插件安装成功!']);
}
/**
* 卸载插件
*/
public function delete()
{
$name = input('name');
$addonsPath = '../addons/'.$name;
$staticPath = 'addons/'.$name;
if (is_dir($staticPath)) {
Files::delDir($staticPath);
}
$res = Files::delDir($addonsPath);
if($res){
return json(['code'=>0,'msg'=>'卸载成功']);
} else {
return json(['code'=>-1,'msg'=>'卸载失败']);
}
}
//启用插件
public function start()
{
$name = input('name');
$arr = ['status' => 1];
//$res = get_addons_info($name);
//$res = get_addons_instance($name);
$res = set_addons_info($name,$arr);
return json(['code'=>0,'msg'=>$name.'插件已启用']);
}
//暂停插件
public function shutDown()
{
$name = input('name');
$arr = ['status' => 0];
$res = set_addons_info($name,$arr);
var_dump($res);
return json(['code'=>-1,'msg'=>$name.'插件已禁用']);
}
//配置插件
public function config($name)
{
$name = input('name');
//var_dump($name);
$config = get_addons_config($name);
if(empty($config)) return json(['code'=>-1,'msg'=>'无配置项!']);
if(Request::isAjax()){
$params = Request::param('params/a');
if ($params) {
foreach ($config as $k => &$v) {
if (isset($params[$k])) {
if ($v['type'] == 'array') {
$arr = [];
$params[$k] = is_array($params[$k]) ? $params[$k] :[];
foreach ($params[$k]['key'] as $kk=>$vv){
$arr[$vv] = $params[$k]['value'][$kk];
}
$params[$k] = $arr;
$value = $params[$k];
$v['content'] = $value;
$v['value'] = $value;
} else {
$value = $params[$k];
}
$v['value'] = $value;
}
}
unset($v);
set_addons_config($name,$config);
}
return json(['code'=>0,'msg'=>'配置成功!']);
}
//模板引擎初始化
$view = ['formData'=>$config,'title'=>'title'];
View::assign($view);
return View::fetch();
} }
} }

View File

@ -78,6 +78,8 @@ class Admin extends Model
//用户名密码正确返回1 //用户名密码正确返回1
return 1; return 1;
} else {
return "用户名或密码错误!";
} }
} }
} }

View File

@ -0,0 +1,93 @@
{extend name="public/base" /}
{block name="body"}
<div class="layui-form" lay-filter="layuiadmin-form-addons" id="layuiadmin-form-addons" style="padding: 20px 40px 0 0;">
<div class="layui-form-item">
<label class="layui-form-label">名称</label>
<div class="layui-input-inline">
<input type="text" name="addons_name" lay-verify="required" placeholder="请输入名称" autocomplete="off" 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="addons_version" lay-verify="required" placeholder="请输入版本" autocomplete="off" 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="addons_auther" lay-verify="required" placeholder="请输入作者名" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">简介</label>
<div class="layui-input-inline">
<textarea name="addons_resume" placeholder="请输入简介" lay-verify="required" class="layui-textarea"></textarea>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">价格</label>
<div class="layui-input-inline">
<input type="text" name="addons_price" lay-verify="required" placeholder="请输入价格" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item layui-form-text">
<label class="layui-form-label">压缩包</label>
<div class="layui-input-inline">
<input type="text" name="addons_src" lay-verify="required" placeholder="请上传zip包" autocomplete="off" class="layui-input" >
</div>
</div>
<div class="layui-form-item layui-form-text">
<label class="layui-form-label"></label>
<div class="layui-input-inline">
<button style="float: left;" type="button" class="layui-btn " id="layuiadmin-upload-addons">上传插件</button>
</div>
</div>
<div class="layui-form-item layui-hide">
<input type="button" lay-submit lay-filter="LAY-addons-submit" id="LAY-addons-submit" value="确认">
</div>
</div>
{/block}
{block name="js"}
<script>
layui.config({
base: '/static/admin/' //静态资源所在路径
}).extend({
index: 'lib/index' //主入口模块
}).use(['index', 'form', 'upload'], function(){
var $ = layui.$
,form = layui.form
,upload = layui.upload ;
upload.render({
elem: '#layuiadmin-upload-addons'
,url: 'uploadZip'
,accept: 'file'
,field: 'file'
,method: 'get'
,exts: 'zip|rar|7z'
,done: function(res){
//console.log(res)
$(this.item).prev("div").children("input").val(res.src)
if(res.code == 0){
layer.msg(res.msg,{
icon:6,
tiye:2000
});
} else {
layer.open({
title:"上传失败",
content:res.msg,
icon:5,
anim:6
});
}
}
});
})
</script>
{/block}

View File

@ -0,0 +1,51 @@
{extend name="public/base" /}
{block name="body"}
<div class="layui-form" lay-filter="layuiadmin-form-addons" id="layuiadmin-form-addons" style="padding: 20px 30px 0 0;">
{foreach name="formData" item="vo" key="k"}
{php}$name = "params[".$k."]";{/php}
{switch name="$vo.type"}
{case value="text"}
{:form_input($name,'text',['label'=>$vo.title,'tip'=>$vo.tip],$vo.value)}
{/case}
{case value="textarea"}
{:form_textarea($name,['label'=>$vo.title,'tip'=>$vo.tip],$vo.value)}
{/case}
{case value="password"}
{:form_input($name,'password',['label'=>$vo.title,'tip'=>$vo.tip],$vo.value)}
{/case}
{case value="radio"}
{:form_radio($name,$vo.content,['label'=>$vo.title,'tip'=>$vo.tip],$vo.value)}
{/case}
{case value="select"}
{:form_select($name,$vo.content,['label'=>$vo.title,'verify'=>$vo.rule,'tip'=>$vo.tip,'search'=>1] ,[],$vo.value)}
{/case}
{case value="image"}
{:form_upload($name,$vo.value,['label'=>$vo.title,'tip'=>$vo.tip,'verify'=>$vo.rule,'type'=>'radio','num'=>'1','mime'=>'image'])}
{/case}
{case value="images"}
{:form_upload($name,$vo.value,['label'=>$vo.title,'tip'=>$vo.tip,'verify'=>$vo.rule,'type'=>'checkbox','num'=>$vo.num,'mime'=>'image'])}
{/case}
{case value="file"}
{:form_upload($name,$vo.value,['label'=>$vo.title,'tip'=>$vo.tip,'verify'=>$vo.rule,'type'=>'radio','num'=>$vo.num,'mime'=>'*'])}
{/case}
{case value="files"}
{:form_upload($name,$vo.value,['label'=>$vo.title,'tip'=>$vo.tip,'verify'=>$vo.rule,'type'=>'checkbox','num'=>$vo.num,'mime'=>'*'])}
{/case}
{case value="editor"}
{:form_editor($name,$name,2,['label'=>$vo.title,'tip'=>$vo.tip,'verify'=>$vo.rule])}
{/case}
{case value="array"}
{:form_arrays($name,['label'=>$vo.title,'tip'=>$vo.tip,'verify'=>$vo.rule],$vo.value?$vo.value:$vo.content)}
{/case}
{/switch}
{/foreach}
<div class="layui-form-item layui-hide">
<input type="hidden" name="name" value="{:input('name')}">
<input type="button" lay-submit lay-filter="LAY-addons-config-submit" id="LAY-addons-config-submit" value="确认">
</div>
</div>
{/block}
{block name="js"}
{/block}

View File

@ -0,0 +1,93 @@
{extend name="public/base" /}
{block name="body"}
<div class="layui-form" lay-filter="layuiadmin-form-addons" id="layuiadmin-form-addons" style="padding: 20px 30px 0 0;">
<div class="layui-form-item layui-hide">
<input type="text" name="id" value="{$addons.id}">
</div>
<div class="layui-form-item">
<label class="layui-form-label">名称</label>
<div class="layui-input-inline">
<input type="text" name="addons_name" lay-verify="required" placeholder="请输入名称" autocomplete="off" class="layui-input" value="{$addons.addons_name}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">版本</label>
<div class="layui-input-inline">
<input type="text" name="addons_version" lay-verify="required" placeholder="请输入版本" autocomplete="off" class="layui-input" value="{$addons.addons_version}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">作者</label>
<div class="layui-input-inline">
<input type="text" name="addons_auther" lay-verify="required" placeholder="请输入作者名" autocomplete="off" class="layui-input" value="{$addons.addons_auther}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">简介</label>
<div class="layui-input-inline">
<textarea name="addons_resume" placeholder="请输入简介" lay-verify="required" class="layui-textarea">{$addons.addons_resume}</textarea>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">价格</label>
<div class="layui-input-inline">
<input type="text" name="addons_price" lay-verify="required" placeholder="请输入价格" autocomplete="off" class="layui-input" value="{$addons.addons_price}">
</div>
</div>
<div class="layui-form-item layui-form-text">
<label class="layui-form-label">压缩包</label>
<div class="layui-input-inline">
<input type="text" name="addons_src" lay-verify="required" placeholder="请上传zip包" autocomplete="off" class="layui-input" value="{$addons.addons_src}">
</div>
<button style="float: left;" type="button" class="layui-btn " id="layuiadmin-upload-addons">上传插件</button>
</div>
<div class="layui-form-item layui-hide">
<input type="button" lay-submit lay-filter="LAY-addons-submit" id="LAY-addons-submit" value="确认">
</div>
</div>
{/block}
{block name="js"}
<script>
layui.config({
base: '/static/admin/' //静态资源所在路径
}).extend({
index: 'lib/index' //主入口模块
}).use(['index', 'form', 'upload'], function(){
var $ = layui.$
,form = layui.form
,upload = layui.upload ;
upload.render({
elem: '#layuiadmin-upload-addons'
,url: 'uploadZip'
,accept: 'file'
,field: 'file'
,method: 'get'
,exts: 'zip|rar|7z'
,done: function(res){
$(this.item).prev("div").children("input").val(res.src);
if(res.code == 0){
layer.msg(res.msg,{
icon:6,
tiye:2000
});
} else {
layer.open({
title:"上传失败",
content:res.msg,
icon:5,
anim:6
});
}
}
});
})
</script>
{/block}

View File

@ -2,7 +2,8 @@
{block name="body"} {block name="body"}
<div class="layui-fluid"> <div class="layui-fluid">
<div class="layui-card">
<div class="layui-card-body">
<div class="layui-form layui-card-header layuiadmin-card-header-auto"> <div class="layui-form layui-card-header layuiadmin-card-header-auto">
<div class="layui-form-item"> <div class="layui-form-item">
<div class="layui-inline"> <div class="layui-inline">
@ -13,7 +14,6 @@
<option value="">全部插件</option> <option value="">全部插件</option>
<option value="">支付</option> <option value="">支付</option>
<option value="">第三方登陆</option> <option value="">第三方登陆</option>
</select> </select>
</div> </div>
</div> </div>
@ -22,41 +22,47 @@
<script type="text/html" id="toolbar"> <script type="text/html" id="toolbar">
<div class="layui-btn-group" style="padding-bottom: 10px;"> <div class="layui-btn-group" style="padding-bottom: 10px;">
<button class="layui-btn layuiadmin-btn-admin" data-type="batchdel">刷新</button> <button class="layui-btn layui-btn-sm layuiadmin-btn-admin" data-type="batchdel">刷新</button>
<button class="layui-btn layuiadmin-btn-admin" data-type="add1">离线安装</button> <button class="layui-btn layui-btn-sm layuiadmin-btn-admin" data-type="add">离线安装</button>
</div> </div>
<div class="layui-btn-group" style="padding-bottom: 10px;"> <div class="layui-btn-group" style="padding-bottom: 10px;">
<button type="button" class="layui-btn layui-btn-sm" lay-event="installed">已安装</button> <button type="button" class="layui-btn layui-btn-sm" lay-event="installed">已安装</button>
<button type="button" class="layui-btn layui-btn-sm" lay-event="onlineAddons">在线</button> <button type="button" class="layui-btn layui-btn-sm" lay-event="onlineAddons">在线</button>
<button type="button" class="layui-btn layui-btn-sm" lay-event="freeAddons">免费</button> <button type="button" class="layui-btn layui-btn-sm" lay-event="freeAddons">免费</button>
<button type="button" class="layui-btn layui-btn-sm" lay-event="payAddons">付费</button> <button type="button" class="layui-btn layui-btn-sm" lay-event="payAddons">付费</button>
</div> </div>
</script> </script>
<script type="text/html" id="addons-installed-tool"> <script type="text/html" id="addons-installed-tool">
<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="install"><i class="layui-icon layui-icon-edit"></i>安装</a> {{# if(d.status == 1){ }}
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="set"><i class="layui-icon layui-icon-edit"></i>设置</a> <a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="shutdown"><i class="layui-icon layui-icon-pause"></i>禁用</a>
<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="del"><i class="layui-icon layui-icon-delete"></i>卸载</a> {{# } else { }}
</script> <a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="start"><i class="layui-icon layui-icon-play"></i>启动</a>
<script type="text/html" id="addons-tool"> {{# } }}
<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="install"><i class="layui-icon layui-icon-edit"></i>安装</a> <a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="config"><i class="layui-icon layui-icon-set"></i>设置</a>
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="set"><i class="layui-icon layui-icon-edit"></i>设置</a> <a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del"><i class="layui-icon layui-icon-delete"></i>卸载</a>
</script> </script>
<script type="text/html" id="addons-tool">
<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="install"><i class="layui-icon layui-icon-edit"></i>安装</a>
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="config"><i class="layui-icon layui-icon-set"></i>设置</a>
</script>
</div>
</div>
</div> </div>
{/block} {/block}
{block name="js"} {block name="js"}
<script> <script>
var filter = "{:url('Addons')}";
//console.log(filter);
var addonsIndex = "{:url('Addons/index')}", var addonsIndex = "{:url('Addons/index')}",
addonsList = "{:url('Addons/addonsList')}", addonsList = "{:url('Addons/addonsList')}",
pluginsList = "{:url('Addons/pluginsList')}",
addonsDelete = "{:url('Addons/delete')}", addonsDelete = "{:url('Addons/delete')}",
addonsEdit = "{:url('Addons/edit')}"; addonsEdit = "{:url('Addons/edit')}";
var col = new Array(); var addonsStart = "{:url('Addons/start')}";
col = {:json_encode($col)}; var addonsShut = "{:url('Addons/shutDown')}";
var addonsInstall = "{:url('Addons/install')}";
var addonsConfig = "{:url('Addons/config')}";
layui.config({ layui.config({
base: '/static/admin/' //静态资源所在路径 base: '/static/admin/' //静态资源所在路径
@ -68,7 +74,6 @@
,form = layui.form ,form = layui.form
,upload = layui.upload; ,upload = layui.upload;
//事件 //事件
var active = { var active = {
add: function(){ add: function(){

Binary file not shown.

View File

@ -39,14 +39,14 @@
<input type="hidden" class="layui-hide" name="__token__" value="{:token()}" /> <input type="hidden" class="layui-hide" name="__token__" value="{:token()}" />
<button class="layui-btn layui-btn-fluid" lay-submit lay-filter="LAY-user-login-submit" id="LAY-user-login-submit">登 入</button> <button class="layui-btn layui-btn-fluid" lay-submit lay-filter="LAY-user-login-submit" id="LAY-user-login-submit">登 入</button>
</div> </div>
<div class="layui-trans layui-form-item layadmin-user-login-other"> <!--div class="layui-trans layui-form-item layadmin-user-login-other">
<label>社交账号登入</label> <label>社交账号登入</label>
<a href="javascript:;"><i class="layui-icon layui-icon-login-qq"></i></a> <a href="javascript:;"><i class="layui-icon layui-icon-login-qq"></i></a>
<a href="javascript:;"><i class="layui-icon layui-icon-login-wechat"></i></a> <a href="javascript:;"><i class="layui-icon layui-icon-login-wechat"></i></a>
<a href="javascript:;"><i class="layui-icon layui-icon-login-weibo"></i></a> <a href="javascript:;"><i class="layui-icon layui-icon-login-weibo"></i></a>
<a href="{:url('admin/login/reg')}" class="layadmin-user-jump-change layadmin-link">注册帐号</a> <a href="{:url('admin/login/reg')}" class="layadmin-user-jump-change layadmin-link">注册帐号</a>
</div> </div-->
{:hook('socialhook')}
</div> </div>
</div> </div>
@ -77,6 +77,7 @@
{/block} {/block}
{block name="js"} {block name="js"}
{:hook('bacimghook')}
<script> <script>
layui.config({ layui.config({
base: '/static/admin/' //静态资源所在路径 base: '/static/admin/' //静态资源所在路径
@ -92,6 +93,8 @@
form.render(); form.render();
//回车登陆 //回车登陆
$(document).keydown(function(e){ $(document).keydown(function(e){
if(e.keyCode == 13){ if(e.keyCode == 13){
@ -142,4 +145,5 @@
}); });
</script> </script>
{/block} {/block}

View File

@ -9,14 +9,15 @@
<div class="layui-tab layui-tab-brief" lay-filter="server-tabs-brief"> <div class="layui-tab layui-tab-brief" lay-filter="server-tabs-brief">
<ul class="layui-tab-title"> <ul class="layui-tab-title">
<li class="layui-this" lay-id="score">积分设置</li> {if hook('signstatushook') == 1}
<li lay-id="vip">用户等级</li> <li class="layui-this" lay-id="score">签到规则</li>
{/if}
<li lay-id="vip" {if hook('signstatushook') == 0}class="layui-this"{/if}>用户等级</li>
</ul> </ul>
<div class="layui-tab-content"> <div class="layui-tab-content">
<div class="layui-tab-item layui-show"> {:hook('signadminhook')}
<!--div class="layui-tab-item layui-show">
<div class="layui-tab-content" style="padding: 20px 0;"> <div class="layui-tab-content" style="padding: 20px 0;">
<div class="layui-form layui-card-header layuiadmin-card-header-auto">
<div class="layui-form-item"> <div class="layui-form-item">
<div class="layui-inline"> <div class="layui-inline">
<label class="layui-form-label">连续签到</label> <label class="layui-form-label">连续签到</label>
@ -55,12 +56,10 @@
</script> </script>
</div> </div>
</div> </div>
</div> </div-->
</div> <div class="layui-tab-item {if hook('signstatushook') == 0}layui-show{/if}">
<div class="layui-tab-item">
<div class="layui-tab-content" style="padding: 20px 0;"> <div class="layui-tab-content" style="padding: 20px 0;">
<div class="layui-form layui-card-header layuiadmin-card-header-auto"> <div class="layui-form">
<div class="layui-form-item"> <div class="layui-form-item">
<div class="layui-inline"> <div class="layui-inline">
<label class="layui-form-label">用户积分</label> <label class="layui-form-label">用户积分</label>
@ -85,22 +84,22 @@
</div> </div>
</div> </div>
</div> </div>
</div>
<div class="layui-form-item"> <div class="layui-form-item">
<table id="vip-rule" lay-filter="vip-rule"></table> <table id="vip-rule" lay-filter="vip-rule"></table>
<script type="text/html" id="vip-rule-button"> <script type="text/html" id="vip-rule-button">
{if condition="checkRuleButton('admin/Vip/vipEdit')"} {if condition="checkRuleButton('admin/Vip/vipEdit')"}
<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="edit"><i class="layui-icon layui-icon-edit"></i>编辑</a> <a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="edit"><i class="layui-icon layui-icon-edit"></i></a>
{else /}<a class="layui-btn layui-btn-normal layui-btn-xs layui-btn-disabled"><i class="layui-icon layui-icon-edit"></i>编辑</a>{/if} {else /}<a class="layui-btn layui-btn-normal layui-btn-xs layui-btn-disabled"><i class="layui-icon layui-icon-edit"></i></a>{/if}
{if condition="checkRuleButton('admin/Vip/delete')"} {if condition="checkRuleButton('admin/Vip/delete')"}
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del"><i class="layui-icon layui-icon-delete"></i>删除</a> <a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del"><i class="layui-icon layui-icon-delete"></i></a>
{else /}<a class="layui-btn layui-btn-danger layui-btn-xs layui-btn-disabled"><i class="layui-icon layui-icon-delete"></i>删除</a>{/if} {else /}<a class="layui-btn layui-btn-danger layui-btn-xs layui-btn-disabled"><i class="layui-icon layui-icon-delete"></i></a>{/if}
</script> </script>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div>
</div> </div>
</div> </div>
@ -132,7 +131,7 @@
var field = data.field; var field = data.field;
$.ajax({ $.ajax({
type:"post", type:"post",
url:"{:url('admin/Sign/add')}", url: signAddAddons,
data:field, data:field,
daType:"json", daType:"json",
success:function (data){ success:function (data){

View File

@ -164,7 +164,7 @@ CREATE TABLE `tao_auth_rule` (
`pid` smallint(5) NOT NULL DEFAULT '0' COMMENT '父级ID', `pid` smallint(5) NOT NULL DEFAULT '0' COMMENT '父级ID',
`level` tinyint(1) NOT NULL DEFAULT '1' COMMENT '菜单层级', `level` tinyint(1) NOT NULL DEFAULT '1' COMMENT '菜单层级',
`icon` varchar(50) NOT NULL DEFAULT '' COMMENT '图标', `icon` varchar(50) NOT NULL DEFAULT '' COMMENT '图标',
`ishidden` enum('1','0') NOT NULL DEFAULT '1' COMMENT '0隐藏,1显示', `ishidden` enum('1','0','-1') NOT NULL DEFAULT '1' COMMENT '0隐藏,1显示-1其它',
`sort` tinyint(4) NOT NULL DEFAULT '50' COMMENT '排序', `sort` tinyint(4) NOT NULL DEFAULT '50' COMMENT '排序',
`condition` char(100) NOT NULL DEFAULT '', `condition` char(100) NOT NULL DEFAULT '',
`create_time` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间', `create_time` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间',
@ -177,11 +177,11 @@ CREATE TABLE `tao_auth_rule` (
-- ---------------------------- -- ----------------------------
-- Records of tao_auth_rule -- Records of tao_auth_rule
-- ---------------------------- -- ----------------------------
INSERT INTO `tao_auth_rule` VALUES ('1', 'admin', '管理', '', '1', '1', '0', '0', 'layui-icon-user', '1', '3', '', '0', '0', '0'); INSERT INTO `tao_auth_rule` VALUES ('1', 'admin', '管理', '', '1', '1', '0', '0', 'layui-icon-user', '1', '5', '', '0', '1635757559', '0');
INSERT INTO `tao_auth_rule` VALUES ('2', 'set', '设置', '', '1', '1', '0', '0', 'layui-icon-set', '1', '4', '', '0', '0', '0'); INSERT INTO `tao_auth_rule` VALUES ('2', 'set', '设置', '', '1', '1', '0', '0', 'layui-icon-set', '1', '6', '', '0', '1635757571', '0');
INSERT INTO `tao_auth_rule` VALUES ('3', 'administrator', '账户', '', '1', '1', '0', '0', 'layui-icon-username', '1', '5', '', '0', '1578980034', '0'); INSERT INTO `tao_auth_rule` VALUES ('3', 'administrator', '账户', '', '1', '1', '0', '0', 'layui-icon-username', '1', '7', '', '0', '1635757594', '0');
INSERT INTO `tao_auth_rule` VALUES ('4', 'app', '应用', '', '1', '1', '0', '0', 'layui-icon-app', '1', '2', '', '0', '0', '0'); INSERT INTO `tao_auth_rule` VALUES ('4', 'app', '应用', '', '1', '1', '0', '0', 'layui-icon-app', '1', '4', '', '0', '1635757536', '0');
INSERT INTO `tao_auth_rule` VALUES ('5', 'article', '内容', '', '1', '1', '0', '0', 'layui-icon-read', '1', '0', '', '0', '1578902321', '0'); INSERT INTO `tao_auth_rule` VALUES ('5', 'article', '内容', '', '1', '1', '0', '0', 'layui-icon-read', '1', '1', '', '0', '1635757294', '0');
INSERT INTO `tao_auth_rule` VALUES ('6', 'admin/User/list', '用户管理', '', '1', '1', '1', '1', '', '1', '1', '', '0', '1578901015', '0'); INSERT INTO `tao_auth_rule` VALUES ('6', 'admin/User/list', '用户管理', '', '1', '1', '1', '1', '', '1', '1', '', '0', '1578901015', '0');
INSERT INTO `tao_auth_rule` VALUES ('7', 'admin/Admin/index', '管理员', '', '1', '1', '1', '1', '', '1', '6', '', '0', '1578901133', '0'); INSERT INTO `tao_auth_rule` VALUES ('7', 'admin/Admin/index', '管理员', '', '1', '1', '1', '1', '', '1', '6', '', '0', '1578901133', '0');
INSERT INTO `tao_auth_rule` VALUES ('8', 'admin/AuthGroup/list', '角色管理', '', '1', '1', '1', '1', '', '1', '11', '', '0', '1578901282', '0'); INSERT INTO `tao_auth_rule` VALUES ('8', 'admin/AuthGroup/list', '角色管理', '', '1', '1', '1', '1', '', '1', '11', '', '0', '1578901282', '0');
@ -257,10 +257,13 @@ INSERT INTO `tao_auth_rule` VALUES ('89', 'admin/User/auth', '设置超级用户
INSERT INTO `tao_auth_rule` VALUES ('90', 'admin/Forum/tagshot', '开启热点', '', '1', '1', '16', '2', '', '0', '15', '', '1585841826', '1611997546', '0'); INSERT INTO `tao_auth_rule` VALUES ('90', 'admin/Forum/tagshot', '开启热点', '', '1', '1', '16', '2', '', '0', '15', '', '1585841826', '1611997546', '0');
INSERT INTO `tao_auth_rule` VALUES ('91', 'admin/Admin/infoSet', '资料设置', '', '1', '1', '12', '2', '', '0', '62', '', '1586245669', '1611998517', '0'); INSERT INTO `tao_auth_rule` VALUES ('91', 'admin/Admin/infoSet', '资料设置', '', '1', '1', '12', '2', '', '0', '62', '', '1586245669', '1611998517', '0');
INSERT INTO `tao_auth_rule` VALUES ('92', 'admin/Admin/repassSet', '密码设置', '', '1', '1', '13', '2', '', '0', '64', '', '1586245727', '1611998534', '0'); INSERT INTO `tao_auth_rule` VALUES ('92', 'admin/Admin/repassSet', '密码设置', '', '1', '1', '13', '2', '', '0', '64', '', '1586245727', '1611998534', '0');
INSERT INTO `tao_auth_rule` VALUES ('93', 'servers', '服务', '', '1', '1', '0', '0', 'layui-icon-cols', '1', '2', '', '1611286515', '1611997619', '0'); INSERT INTO `tao_auth_rule` VALUES ('93', 'servers', '服务', '', '1', '1', '0', '0', 'layui-icon-cols', '1', '3', '', '1611286515', '1635757525', '0');
INSERT INTO `tao_auth_rule` VALUES ('94', 'admin/Database/index', '数据备份', '', '1', '1', '93', '1', '', '1', '9', '', '1611897141', '1611902589', '0'); INSERT INTO `tao_auth_rule` VALUES ('94', 'admin/Database/index', '数据备份', '', '1', '1', '93', '1', '', '1', '9', '', '1611897141', '1611902589', '0');
INSERT INTO `tao_auth_rule` VALUES ('95', 'admin/Database/backup', '进行备份', '', '1', '1', '94', '2', '', '0', '10', '', '1611897285', '1611902610', '0'); INSERT INTO `tao_auth_rule` VALUES ('95', 'admin/Database/backup', '进行备份', '', '1', '1', '94', '2', '', '0', '10', '', '1611897285', '1611902610', '0');
INSERT INTO `tao_auth_rule` VALUES ('96', 'admin/Database/delete', '备份删除', '', '1', '1', '94', '2', '', '0', '0', '', '1611902429', '0', '0'); INSERT INTO `tao_auth_rule` VALUES ('96', 'admin/Database/delete', '备份删除', '', '1', '1', '94', '2', '', '0', '0', '', '1611902429', '0', '0');
INSERT INTO `tao_auth_rule` VALUES ('97', 'addons', '插件', '', '1', '1', '0', '0', 'layui-icon-flag', '1', '2', '', '1635757328', '1635757632', '0');
INSERT INTO `tao_auth_rule` VALUES ('98', 'admin/Addons/index', '插件市场', '', '1', '1', '97', '1', '', '1', '0', '', '1635757426', '0', '0');
INSERT INTO `tao_auth_rule` VALUES ('99', 'admin/Addons/addonsList', '插件列表', '', '1', '1', '98', '2', '', '', '0', '', '1635758251', '0', '0');
-- ---------------------------- -- ----------------------------
-- Table structure for tao_cate -- Table structure for tao_cate
@ -471,7 +474,7 @@ CREATE TABLE `tao_system` (
`cache` tinyint(5) NOT NULL DEFAULT '0' COMMENT '缓存时间分钟', `cache` tinyint(5) NOT NULL DEFAULT '0' COMMENT '缓存时间分钟',
`upsize` int(5) NOT NULL DEFAULT '0' COMMENT '上传文件大小KB', `upsize` int(5) NOT NULL DEFAULT '0' COMMENT '上传文件大小KB',
`uptype` varchar(255) NOT NULL DEFAULT '0' COMMENT '上传文件类型', `uptype` varchar(255) NOT NULL DEFAULT '0' COMMENT '上传文件类型',
`copyright` varchar(80) NOT NULL DEFAULT '' COMMENT '版权', `copyright` varchar(100) NOT NULL DEFAULT '' COMMENT '版权',
`keywords` tinytext NOT NULL COMMENT '网站关键字', `keywords` tinytext NOT NULL COMMENT '网站关键字',
`descript` tinytext NOT NULL COMMENT '网站描述', `descript` tinytext NOT NULL COMMENT '网站描述',
`is_open` enum('0','1') NOT NULL DEFAULT '1' COMMENT '是否开启站点1开启0关闭', `is_open` enum('0','1') NOT NULL DEFAULT '1' COMMENT '是否开启站点1开启0关闭',

View File

@ -0,0 +1,18 @@
<?php
namespace app\middleware;
use think\facade\Request;
use think\facade\Lang;
class AddonsLang
{
public function handle($request, \Closure $next)
{
Lang::load([
//$this->app->getRootPath() . '/vendor/zzstudio/think-addons/src/lang/zh-cn.php',
app()->getRootPath().'addons/sign/lang/zh-cn.php',
]);
return $next($request);
}
}

View File

@ -18,7 +18,7 @@ class Auth
public function handle($request, \Closure $next) public function handle($request, \Closure $next)
{ {
$path = app('http')->getName().'/'.stristr($request->pathinfo(),".html",true); $path = app('http')->getName().'/'.stristr($request->pathinfo(),".html",true);
//var_dump($path);
//没有登录及当前非登录页重定向登录页 //没有登录及当前非登录页重定向登录页
if(!Session::has('admin_id') && $path !== 'admin/login/index' && !stristr($request->pathinfo(),"captcha.html") ) if(!Session::has('admin_id') && $path !== 'admin/login/index' && !stristr($request->pathinfo(),"captcha.html") )
{ {
@ -31,14 +31,16 @@ class Auth
} }
// 排除公共权限 // 排除公共权限
$not_check = ['admin/','admin/login/index','admin/index/index','admin/index/home','admin/Admin/info','admin/Admin/repass','admin/Admin/logout','admin/Index/news','admin/Index/cunsult','admin/Index/replys','admin/Index/reply','admin/captcha']; $not_check = ['admin/','admin/login/index','admin/index/index','admin/index/home','admin/Admin/info','admin/Admin/repass','admin/Admin/logout','admin/Index/news','admin/Index/cunsult','admin/Index/replys','admin/Index/reply','admin/captcha','addons/socail/'];
if (!in_array($path, $not_check)) { if (!in_array($path, $not_check)) {
$auth = new UserAuth(); $auth = new UserAuth();
$admin_id = Session::get('admin_id'); //登录用户的id $admin_id = Session::get('admin_id'); //登录用户的id
if (!$auth->check($path, $admin_id) && $admin_id != 1) { if (!$auth->check($path, $admin_id) && $admin_id != 1) {
return view('public/auth'); //return view('public/auth');
//return response("<script>alert('没有操作权限')</script>");
return json(['code'=>-1,'msg'=>'无权限']);
} }
} }
return $next($request); return $next($request);

View File

@ -8,13 +8,14 @@ class CheckRegister
{ {
public function handle($request, \Closure $next) public function handle($request, \Closure $next)
{ {
//排除特殊注册用户名 //排除禁止注册用户名的字段
if($request->action(true)=='reg'){ if($request->action(true)=='reg'){
$name = $request->param('name');
$disname = Db::name('system')->where('id',1)->value('blackname'); $disname = Db::name('system')->where('id',1)->value('blackname');
$data = explode("|",$disname); $data = explode("|",$disname);
foreach($data as $v){ foreach($data as $v){
if ($request->param('name') == $v) { if(stripos($name,$v) !== false){
return json(['msg'=>'该用户名禁止注册,请更换名称']); return json(['msg'=>'非法字段或该用户名禁止注册,请更换']);
} }
} }
} }

View File

@ -24,10 +24,10 @@
"topthink/think-view": "^1.0", "topthink/think-view": "^1.0",
"topthink/think-captcha": "^3.0", "topthink/think-captcha": "^3.0",
"phpmailer/phpmailer": "^6.1", "phpmailer/phpmailer": "^6.1",
"zzstudio/think-addons": "^2.0",
"firebase/php-jwt": "^5.2", "firebase/php-jwt": "^5.2",
"lotofbadcode/phpspirit_databackup": "^1.1", "lotofbadcode/phpspirit_databackup": "^1.1",
"wamkj/thinkphp6.0-databackup": "^1.0" "wamkj/thinkphp6.0-databackup": "^1.0",
"taoser/think-addons": "^1.0"
}, },
"require-dev": { "require-dev": {
"symfony/var-dumper": "^4.2", "symfony/var-dumper": "^4.2",
@ -39,7 +39,10 @@
}, },
"psr-0": { "psr-0": {
"": "extend/" "": "extend/"
} },
"files": [
"extend/taoler/com/form.php"
]
}, },
"config": { "config": {
"preferred-install": "dist" "preferred-install": "dist"

180
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "c6dc1dcd45b2b2cd2e7bd36c0e76eb04", "content-hash": "3ef61427e5d1c98f5ca1e197d25ef688",
"packages": [ "packages": [
{ {
"name": "firebase/php-jwt", "name": "firebase/php-jwt",
@ -71,16 +71,16 @@
}, },
{ {
"name": "league/flysystem", "name": "league/flysystem",
"version": "1.1.4", "version": "1.1.5",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/thephpleague/flysystem.git", "url": "https://github.com/thephpleague/flysystem.git",
"reference": "f3ad69181b8afed2c9edf7be5a2918144ff4ea32" "reference": "18634df356bfd4119fe3d6156bdb990c414c14ea"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/f3ad69181b8afed2c9edf7be5a2918144ff4ea32", "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/18634df356bfd4119fe3d6156bdb990c414c14ea",
"reference": "f3ad69181b8afed2c9edf7be5a2918144ff4ea32", "reference": "18634df356bfd4119fe3d6156bdb990c414c14ea",
"shasum": "", "shasum": "",
"mirrors": [ "mirrors": [
{ {
@ -159,7 +159,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/thephpleague/flysystem/issues", "issues": "https://github.com/thephpleague/flysystem/issues",
"source": "https://github.com/thephpleague/flysystem/tree/1.1.4" "source": "https://github.com/thephpleague/flysystem/tree/1.1.5"
}, },
"funding": [ "funding": [
{ {
@ -167,7 +167,7 @@
"type": "other" "type": "other"
} }
], ],
"time": "2021-06-23T21:56:05+00:00" "time": "2021-08-17T13:49:42+00:00"
}, },
{ {
"name": "league/flysystem-cached-adapter", "name": "league/flysystem-cached-adapter",
@ -228,16 +228,16 @@
}, },
{ {
"name": "league/mime-type-detection", "name": "league/mime-type-detection",
"version": "1.7.0", "version": "1.8.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/thephpleague/mime-type-detection.git", "url": "https://github.com/thephpleague/mime-type-detection.git",
"reference": "3b9dff8aaf7323590c1d2e443db701eb1f9aa0d3" "reference": "b38b25d7b372e9fddb00335400467b223349fd7e"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/3b9dff8aaf7323590c1d2e443db701eb1f9aa0d3", "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/b38b25d7b372e9fddb00335400467b223349fd7e",
"reference": "3b9dff8aaf7323590c1d2e443db701eb1f9aa0d3", "reference": "b38b25d7b372e9fddb00335400467b223349fd7e",
"shasum": "", "shasum": "",
"mirrors": [ "mirrors": [
{ {
@ -274,7 +274,7 @@
"description": "Mime-type detection for Flysystem", "description": "Mime-type detection for Flysystem",
"support": { "support": {
"issues": "https://github.com/thephpleague/mime-type-detection/issues", "issues": "https://github.com/thephpleague/mime-type-detection/issues",
"source": "https://github.com/thephpleague/mime-type-detection/tree/1.7.0" "source": "https://github.com/thephpleague/mime-type-detection/tree/1.8.0"
}, },
"funding": [ "funding": [
{ {
@ -286,7 +286,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2021-01-18T20:58:21+00:00" "time": "2021-09-25T08:23:19+00:00"
}, },
{ {
"name": "lotofbadcode/phpspirit_databackup", "name": "lotofbadcode/phpspirit_databackup",
@ -340,16 +340,16 @@
}, },
{ {
"name": "phpmailer/phpmailer", "name": "phpmailer/phpmailer",
"version": "v6.5.0", "version": "v6.5.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/PHPMailer/PHPMailer.git", "url": "https://github.com/PHPMailer/PHPMailer.git",
"reference": "a5b5c43e50b7fba655f793ad27303cd74c57363c" "reference": "dd803df5ad7492e1b40637f7ebd258fee5ca7355"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/a5b5c43e50b7fba655f793ad27303cd74c57363c", "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/dd803df5ad7492e1b40637f7ebd258fee5ca7355",
"reference": "a5b5c43e50b7fba655f793ad27303cd74c57363c", "reference": "dd803df5ad7492e1b40637f7ebd258fee5ca7355",
"shasum": "", "shasum": "",
"mirrors": [ "mirrors": [
{ {
@ -367,10 +367,12 @@
"require-dev": { "require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0",
"doctrine/annotations": "^1.2", "doctrine/annotations": "^1.2",
"php-parallel-lint/php-console-highlighter": "^0.5.0",
"php-parallel-lint/php-parallel-lint": "^1.3",
"phpcompatibility/php-compatibility": "^9.3.5", "phpcompatibility/php-compatibility": "^9.3.5",
"roave/security-advisories": "dev-latest", "roave/security-advisories": "dev-latest",
"squizlabs/php_codesniffer": "^3.5.6", "squizlabs/php_codesniffer": "^3.6.0",
"yoast/phpunit-polyfills": "^0.2.0" "yoast/phpunit-polyfills": "^1.0.0"
}, },
"suggest": { "suggest": {
"ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses", "ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses",
@ -410,7 +412,7 @@
"description": "PHPMailer is a full-featured email creation and transfer class for PHP", "description": "PHPMailer is a full-featured email creation and transfer class for PHP",
"support": { "support": {
"issues": "https://github.com/PHPMailer/PHPMailer/issues", "issues": "https://github.com/PHPMailer/PHPMailer/issues",
"source": "https://github.com/PHPMailer/PHPMailer/tree/v6.5.0" "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.5.1"
}, },
"funding": [ "funding": [
{ {
@ -418,7 +420,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2021-06-16T14:33:43+00:00" "time": "2021-08-18T09:14:16+00:00"
}, },
{ {
"name": "psr/cache", "name": "psr/cache",
@ -642,6 +644,68 @@
}, },
"time": "2017-10-23T01:57:42+00:00" "time": "2017-10-23T01:57:42+00:00"
}, },
{
"name": "taoser/think-addons",
"version": "v1.0.1",
"source": {
"type": "git",
"url": "https://github.com/taoser/think-addons.git",
"reference": "bd8b0bfa4543fe8d2da65355c134250f78c0d457"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/taoser/think-addons/zipball/bd8b0bfa4543fe8d2da65355c134250f78c0d457",
"reference": "bd8b0bfa4543fe8d2da65355c134250f78c0d457",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"php": ">=7.1.0",
"topthink/framework": "^6.0",
"topthink/think-helper": "^3.0.0",
"topthink/think-view": "^1.0"
},
"type": "library",
"extra": {
"think": {
"services": [
"taoser\\addons\\Service"
],
"config": {
"addons": "src/config.php"
}
}
},
"autoload": {
"psr-4": {
"taoser\\": "src/"
},
"files": [
"src/helper.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"mit"
],
"authors": [
{
"name": "taoler",
"email": "changlin_zhao@qq.com"
}
],
"description": "The ThinkPHP6 Addons Package",
"support": {
"issues": "https://github.com/taoser/think-addons/issues",
"source": "https://github.com/taoser/think-addons/tree/v1.0.1"
},
"time": "2021-09-18T08:41:10+00:00"
},
{ {
"name": "taoser/think-auth", "name": "taoser/think-auth",
"version": "v1.0.0", "version": "v1.0.0",
@ -1139,68 +1203,6 @@
"source": "https://github.com/wamkj/thinkphp6.0-databackup/tree/v1.0" "source": "https://github.com/wamkj/thinkphp6.0-databackup/tree/v1.0"
}, },
"time": "2020-02-15T13:04:16+00:00" "time": "2020-02-15T13:04:16+00:00"
},
{
"name": "zzstudio/think-addons",
"version": "2.0.5",
"source": {
"type": "git",
"url": "https://github.com/zz-studio/think-addons.git",
"reference": "7eb740cb219a111d593a05ad88248a74f640fe5c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/zz-studio/think-addons/zipball/7eb740cb219a111d593a05ad88248a74f640fe5c",
"reference": "7eb740cb219a111d593a05ad88248a74f640fe5c",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"php": ">=7.1.0",
"topthink/framework": "^6.0",
"topthink/think-helper": "^3.0.0",
"topthink/think-view": "^1.0"
},
"type": "library",
"extra": {
"think": {
"services": [
"think\\addons\\Service"
],
"config": {
"addons": "src/config.php"
}
}
},
"autoload": {
"psr-4": {
"think\\": "src/"
},
"files": [
"src/helper.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"Apache-2.0"
],
"authors": [
{
"name": "byron",
"email": "xiaobo.sun@qq.com"
}
],
"description": "The ThinkPHP6 Addons Package",
"support": {
"issues": "https://github.com/zz-studio/think-addons/issues",
"source": "https://github.com/zz-studio/think-addons/tree/2.0.5"
},
"time": "2020-01-06T06:42:39+00:00"
} }
], ],
"packages-dev": [ "packages-dev": [
@ -1463,16 +1465,16 @@
}, },
{ {
"name": "symfony/var-dumper", "name": "symfony/var-dumper",
"version": "v4.4.27", "version": "v4.4.33",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/var-dumper.git", "url": "https://github.com/symfony/var-dumper.git",
"reference": "391d6d0e7a06ab54eb7c38fab29b8d174471b3ba" "reference": "50286e2b7189bfb4f419c0731e86632cddf7c5ee"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/391d6d0e7a06ab54eb7c38fab29b8d174471b3ba", "url": "https://api.github.com/repos/symfony/var-dumper/zipball/50286e2b7189bfb4f419c0731e86632cddf7c5ee",
"reference": "391d6d0e7a06ab54eb7c38fab29b8d174471b3ba", "reference": "50286e2b7189bfb4f419c0731e86632cddf7c5ee",
"shasum": "", "shasum": "",
"mirrors": [ "mirrors": [
{ {
@ -1538,7 +1540,7 @@
"dump" "dump"
], ],
"support": { "support": {
"source": "https://github.com/symfony/var-dumper/tree/v4.4.27" "source": "https://github.com/symfony/var-dumper/tree/v4.4.33"
}, },
"funding": [ "funding": [
{ {
@ -1554,7 +1556,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2021-07-23T15:41:52+00:00" "time": "2021-10-25T20:24:58+00:00"
}, },
{ {
"name": "topthink/think-trace", "name": "topthink/think-trace",

View File

@ -21,7 +21,7 @@ return [
'app_map' => [], 'app_map' => [],
// 域名绑定(自动多应用模式有效) // 域名绑定(自动多应用模式有效)
'domain_bind' => [ 'domain_bind' => [
//'www' => 'index', //'bbs' => 'index',
//'adm' => 'admin', //'adm' => 'admin',
//'api' => 'api' //'api' => 'api'
], ],
@ -29,15 +29,16 @@ return [
'deny_app_list' => [], 'deny_app_list' => [],
// 异常页面的模板文件 // 异常页面的模板文件
'exception_tmpl' => app()->getThinkPath() . 'tpl/think_exception.tpl', //'exception_tmpl' => app()->getThinkPath() . 'tpl/think_exception.tpl',
'exception_tmpl' => app()->getAppPath() . '404.html',
// 错误显示信息,非调试模式有效 // 错误显示信息,非调试模式有效
'error_message' => '页面错误!请稍后再试~', 'error_message' => '页面错误!请稍后再试~',
// 显示错误信息 // 显示错误信息
'show_error_msg' => true, 'show_error_msg' => false,
//异常页面模板 //异常页面模板
'http_exception_template' => [ 'http_exception_template' => [
404 => '404.html', 404 => \think\facade\App::getAppPath() . '404.html',
500 => '404.html' 500 => \think\facade\App::getAppPath() . '404.html',
] ]
]; ];

View File

@ -7,7 +7,7 @@ return [
//应用名,此项不可更改 //应用名,此项不可更改
'appname' => 'TaoLer', 'appname' => 'TaoLer',
//版本配置 //版本配置
'version' => '1.8.9', 'version' => '1.8.10',
//加盐 //加盐
'salt' => 'taoler', 'salt' => 'taoler',
//数据库备份目录 //数据库备份目录

223
extend/taoler/com/form.php Normal file
View File

@ -0,0 +1,223 @@
<?php
use taoler\com\FormHelper;
if (!function_exists('form_input')) {
/**
* @param $type
* @param $name
* @return string
*/
function form_input($name='',$type='text',$options=[],$value=null)
{
return FormHelper::input($name,$type,$options,$value);
}
}
if (!function_exists('form_radio')) {
/**
* @param $id
* @param $name
* @return string
*/
function form_radio($name=null, $radiolist = null, $options = [],$value='')
{
return FormHelper::radio($name,$radiolist,$options,$value);
}
}
if (!function_exists('form_switch')) {
/**
* @param $id
* @param $name
* @param $switch
* @param $option
* @param $value
* @return string
*/
function form_switch($name,$switch=[] , $option=[],$value='')
{
return FormHelper::switchs($name,$switch , $option,$value);
}
}
if (!function_exists('form_checkbox')) {
/**
* @param $id
* @param $name
* @return string
*/
function form_checkbox($name,$list, $option, $value)
{
return FormHelper::checkbox($name,$list, $option, $value);
}
}
if (!function_exists('form_arrays')) {
/**
* @param $id
* @param $name
* @return string
*/
function form_arrays($name, $option, $list=[])
{
return FormHelper::arrays($name, $option, $list);
}
}
if (!function_exists('form_textarea')) {
/**
* @param $id
* @param $name
* @return string
*/
function form_textarea($name=null, $option=[], $value=null)
{
return FormHelper::textarea($name, $option,$value);
}
}
if (!function_exists('form_select')) {
/**
* @param null $name
* @param array $options
* @return string
*/
function form_select($name = null,$select=[], $options = [],$attr='',$value=null)
{
if(!empty($attr) and !is_array($attr)) $attr = explode(',',$attr);
return FormHelper::multiselect($name,$select,$options,$attr,$value);
}
}
if (!function_exists('form_multiselect')) {
/**
* @param null $name
* @param array $options
* @return string
*/
function form_multiselect($name = null,$select=[], $options = [],$attr='',$value='')
{
if(!empty($attr) and !is_array($attr))$attr = explode(',',$attr);
return FormHelper::multiselect($name,$select,$options,$attr,$value);
}
}
if (!function_exists('form_xmselect')) {
/**
* @param null $name
* @param array $options
* @return string
*/
function form_xmselect($name = null,$select=[], $options = [],$attr='',$value='')
{
if(!empty($attr) and !is_array($attr))$attr = explode(',',$attr);
return FormHelper::xmselect($name,$select,$options,$attr,$value);
}
}
if (!function_exists('form_icon')) {
/**
* @param array $options
* @return string
*/
function form_icon($name=null,$options = [],$value=null)
{
return FormHelper::icon($name, $options,$value);
}
}
if (!function_exists('form_date')) {
/**
* @param array $options
* @return string
*/
function form_date($name=null,$options = [],$value='')
{
return FormHelper::date($name, $options,$value);
}
}
if (!function_exists('form_city')) {
/**
* @param array $options
* @return string
*/
function form_city($name='cityPicker',$id='cityPicker',$options = [])
{
return FormHelper::city($name,$id,$options);
}
}
if (!function_exists('form_region')) {
/**
* @param array $options
* @return string
*/
function form_region($name='regionCheck',$id='regionCheck',$options = [])
{
return FormHelper::region($name,$id,$options);
}
}
if (!function_exists('form_tags')) {
/**
* @param array $options
* @return string
*/
function form_tags($id='tags',$name='',$options = [],$value='')
{
return FormHelper::tags($id,$name,$options,$value);
}
}
if (!function_exists('form_color')) {
/**
* @param array $options
* @return string
*/
function form_color($id='iconPicker',$name=null,$options = [],$value='')
{
return FormHelper::color($id,$name,$options,$value);
}
}
if (!function_exists('form_submitbtn')) {
/**
* @param bool $reset
* @param array $options
* @return string
*/
function form_submitbtn($reset = true, $options=[])
{
return FormHelper::submitbtn($reset, $options);
}
}
if (!function_exists('form_closebtn')) {
/**
* @param bool $reset
* @param array $options
* @return string
*/
function form_closebtn($reset = true, $options=[])
{
return FormHelper::closebtn($reset,$options);
}
}
if (!function_exists('form_upload')) {
/**
* @param $name
* @param null $formdata
* @return string
*/
function form_upload($name=null,$formdata=[],$options=[])
{
return FormHelper::upload($name,$formdata,$options);
}
}
if (!function_exists('form_editor')) {
/**
* @param $id
* @param $name
* @return string
*/
function form_editor($name='container',$id='container',$type=1,$options=[])
{
return FormHelper::editor($name,$id,$type,$options);
}
}

View File

@ -1,55 +0,0 @@
/**
@NamelayuiAdmin 登入注册页
@Author贤心
@Sitehttp://www.layui.com/admin/
@LicenseGPL-2
*/
html,body,#LAY_app{height:100%; background: url(res/bg1.jpg) no-repeat center; background-size: cover;}
.layui-layout-body{overflow: auto;}
#LAY-user-login,
.layadmin-user-display-show{display: block !important;}
.layadmin-user-login{position: relative; left: 0; top: 0; padding: 110px 0; min-height: 100%; box-sizing: border-box;}
.layadmin-user-login-main{width: 375px; margin: 0 auto; box-sizing: border-box; background-color:rgba(0,0,0,.6); border:1px solid; border-radius:15px}
.layadmin-user-login-box{padding: 20px;}
.layadmin-user-login-header{text-align: center;}
.layadmin-user-login-header h2{margin-bottom: 10px; font-weight: 300; font-size: 30px; color: #000;}
.layadmin-user-login-header p{font-weight: 300; color: #999;}
.layadmin-user-login-body .layui-form-item{position: relative;}
.layadmin-user-login-icon{position: absolute; left: 1px; top: 1px; width: 38px; line-height: 36px; text-align: center; color: #d2d2d2;}
.layadmin-user-login-body .layui-form-item .layui-input{padding-left: 38px;}
.layadmin-user-login-codeimg{max-height: 38px; width: 100%; cursor: pointer; box-sizing: border-box;}
.layadmin-user-login-other{position: relative; font-size: 0; line-height: 38px; padding-top: 20px;}
.layadmin-user-login-other>*{display: inline-block; vertical-align: middle; margin-right: 10px; font-size: 14px;}
.layadmin-user-login-other .layui-icon{position: relative; top: 2px; font-size: 26px;}
.layadmin-user-login-other a:hover{opacity: 0.8;}
.layadmin-user-jump-change{float: right;}
.layadmin-user-login-footer{position: absolute; left: 0; bottom: 0; width: 100%; line-height: 30px; padding: 20px; text-align: center; box-sizing: border-box; color: rgba(0,0,0,.5)}
.layadmin-user-login-footer span{padding: 0 5px;}
.layadmin-user-login-footer a{padding: 0 5px; color: rgba(0,0,0,.5);}
.layadmin-user-login-footer a:hover{color: rgba(0,0,0,1);}
/* 有背景图时 */
.layadmin-user-login-main[bgimg]{background-color: #fff; box-shadow: 0 0 5px rgba(0,0,0,0.05);}
/* 主题背景 */
.ladmin-user-login-theme{position: fixed; bottom: 0; left: 0; width: 100%; text-align: center;}
.ladmin-user-login-theme ul{display: inline-block; padding: 5px; background-color: #fff;}
.ladmin-user-login-theme ul li{display: inline-block; vertical-align: top; width: 64px; height: 43px; cursor: pointer; transition: all .3s; -webkit-transition: all .3s; background-color: #f2f2f2;}
.ladmin-user-login-theme ul li:hover{opacity: 0.9}
@media screen and (max-width: 768px) {
.layadmin-user-login{padding-top: 60px;}
.layadmin-user-login-main{width: 300px;}
.layadmin-user-login-box{padding: 10px;}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 310 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 314 KiB

View File

@ -6,86 +6,66 @@ layui.define(['table', 'form','upload'], function(exports){
,form = layui.form ,form = layui.form
,upload = layui.upload; ,upload = layui.upload;
//安装插件 function addList(type)
{
$.ajax({
type: 'post',
url: addonsList ,
data: {type:type},
dataType: 'json',
success: function (res) {
//渲染表格
table.render({ table.render({
elem: '#addons-list', elem: '#addons-list',
toolbar: '#toolbar', toolbar: '#toolbar',
url: addonsList, defaultToolbar: [],
cols:[ url: addonsList + '?type='+ type,
col cols: [
res['col']
] ]
,page: true , page: true
,limit: 10 , limit: 10
,height: 'full-220' , height: 'full-220'
,text: '对不起,加载出现异常!' , text: '对不起,加载出现异常!'
}); });
}
});
}
addList('installed');
//头工具栏事件 //头工具栏事件
table.on('toolbar(addons-list)', function(obj){ table.on('toolbar(addons-list)', function(obj){
var checkStatus = table.checkStatus(obj.config.id); var checkStatus = table.checkStatus(obj.config.id);
switch(obj.event){ switch(obj.event){
case 'installed': case 'installed':
$.post(addonsIndex + '?type=installed',function(){ addList("installed");
location.href = addonsIndex + '?type=installed';
});
$.post(addonsList + '?type=installed',{"type":"installed"});
table.reload('addons-list', {
where: {"type":"installed"}
}); //数据刷新
break; break;
case 'onlineAddons': case 'onlineAddons':
$.post(addonsIndex + '?type=onlineAddons',function(){ addList("onlineAddons");
location.href = addonsIndex + '?type=onlineAddons';
});
$.post(addonsList + '?type=onlineAddons',{"type":"onlineAddons"});
table.reload('addons-list', {
where: {"type":"onlineAddons"}
}); //数据刷新
break; break;
case 'isAll': }
layer.msg(checkStatus.isAll ? '全选': '未全选');
break;
//自定义头工具栏右侧图标 - 提示
case 'LAYTABLE_TIPS':
layer.alert('这是工具栏右侧自定义的一个图标按钮');
break;
};
}); });
//监听工具条 //监听工具条
table.on('tool(addons-list)', function(obj){ table.on('tool(addons-list)', function(obj){
var data = obj.data; var data = obj.data;
if(obj.event === 'del'){ if(obj.event === 'del'){
layer.prompt({ layer.prompt({
formType: 1 formType: 1
,title: '敏感操作,请验证口令' ,title: '敏感操作,请验证口令'
}, function(value, index){ }, function(value, index){
layer.close(index); layer.close(index);
layer.confirm('真的删除行么', function(index){ layer.confirm('真的删除行么', function(index){
//obj.del(); $.post(addonsDelete,{name:data.name},function (res) {
$.ajax({ if (res.code == 0) {
type:'post', layer.msg(res.msg,{icon:6,time:2000});
url:addonsDelete,
data:{id:data.id},
dataType:'json',
success:function(data){
if(data.code == 0){
layer.msg(data.msg,{
icon:6,
time:2000
});
} else { } else {
layer.open({ layer.open({tiele:'修改失败',content:res.msg,icon:5,anim:6});
title:'删除失败',
content:data.msg,
icon:5,
adim:6
})
}
} }
}); });
table.reload('addons-list'); table.reload('addons-list');
layer.close(index); layer.close(index);
}); });
@ -100,7 +80,6 @@ layui.define(['table', 'form','upload'], function(exports){
,area: ['400px', '620px'] ,area: ['400px', '620px']
,btn: ['确定', '取消'] ,btn: ['确定', '取消']
,yes: function(index, layero){ ,yes: function(index, layero){
var iframeWindow = window['layui-layer-iframe'+ index] var iframeWindow = window['layui-layer-iframe'+ index]
,submitID = 'LAY-addons-submit' ,submitID = 'LAY-addons-submit'
,submit = layero.find('iframe').contents().find('#'+ submitID); ,submit = layero.find('iframe').contents().find('#'+ submitID);
@ -117,17 +96,9 @@ layui.define(['table', 'form','upload'], function(exports){
daType:"json", daType:"json",
success:function (res){ success:function (res){
if (res.code == 0) { if (res.code == 0) {
layer.msg(res.msg,{ layer.msg(res.msg,{icon:6,time:2000});
icon:6,
time:2000
});
} else { } else {
layer.open({ layer.open({tiele:'修改失败',content:res.msg,icon:5,anim:6});
tiele:'修改失败',
content:res.msg,
icon:5,
anim:6
});
} }
} }
}); });
@ -142,7 +113,106 @@ layui.define(['table', 'form','upload'], function(exports){
} }
}); });
} else if (obj.event === 'start'){
//提交 Ajax 成功后,静态更新表格中的数据
$.ajax({
type:"post",
url:addonsStart,
data:{name:data.name},
daType:"json",
success:function (res){
if (res.code == 0) {
layer.msg(res.msg,{icon:6,time:2000});
} else {
layer.open({tiele:'修改失败',content:res.msg,icon:5,anim:6});
} }
}
});
} else if(obj.event === 'shutdown'){
//提交 Ajax 成功后,静态更新表格中的数据
$.ajax({
type:"post",
url:addonsShut,
data:{name:data.name},
daType:"json",
success:function (res){
if (res.code == 0) {
layer.msg(res.msg,{icon:6,time:2000});
} else {
layer.open({tiele:'修改失败',content:res.msg,icon:5,anim:6});
}
}
});
} else if(obj.event === 'install'){
//安装插件
$.post(addonsInstall,{name:data.name,version:data.version},function (res) {
if (res.code == 0) {
layer.msg(res.msg,{icon:6,time:2000});
} else {
layer.open({tiele:'修改失败',content:res.msg,icon:5,anim:6});
}
});
} else if(obj.event === 'config'){
layer.open({
type: 2
,title: '配置插件'
,content: addonsConfig + '?name='+ data.name
,maxmin: true
,area: ['780px', '90%']
,btn: ['确定', '取消']
,yes: function(index, layero){
var iframeWindow = window['layui-layer-iframe'+ index]
,submitID = 'LAY-addons-config-submit'
,submit = layero.find('iframe').contents().find('#'+ submitID);
//监听提交
iframeWindow.layui.form.on('submit('+ submitID +')', function(data){
var field = data.field; //获取提交的字段
$.ajax({
type:"post",
url:addonsConfig,
data:field,
daType:"json",
success:function (res){
if (res.code == 0) {
layer.msg(res.msg,{icon:6,time:2000});
} else {
layer.open({tiele:'修改失败',content:res.msg,icon:5,anim:6});
}
}
});
layer.close(index); //关闭弹层
});
submit.trigger('click');
}
,success: function(layero, index){
var forms = layero.find('iframe').contents().find('.layui-form');
var button = forms.find('button');
//事件委托
forms.on('click','button',function (data) {
var even = this.getAttribute('lay-event');
var names = this.dataset.name;
if(even == 'addInput'){
var html = '<div class="layui-form-item"><label class="layui-form-label"></label><div class="layui-input-inline">\n' +
' <input type="text" name="'+ names +'[key][]" value="" placeholder="key" autocomplete="off" class="layui-input input-double-width">\n' +
' </div><div class="layui-input-inline">\n' +
' <input type="text" name="'+ names +'[value][]" value="" placeholder="value" autocomplete="off" class="layui-input input-double-width">\n' +
' </div>\n' +
' <button data-name="'+ names +'" type="button" class="layui-btn layui-btn-danger layui-btn-sm removeInupt" lay-event="removeInupt">\n' +
' <i class="layui-icon"></i>\n' +
' </button>\n' +
' </div>';
$(this).parent().parent().append(html);
} else {
$(this).parent().remove();
}
});
}
});
}
table.reload('addons-list'); //数据刷新
}); });
exports('addons', {}) exports('addons', {})

View File

@ -13,7 +13,7 @@ html,body,#LAY_app{height:100%;}
#LAY-user-login, #LAY-user-login,
.layadmin-user-display-show{display: block !important;} .layadmin-user-display-show{display: block !important;}
.layadmin-user-login{position: relative; left: 0; top: 0; padding: 110px 0; min-height: 100%; box-sizing: border-box;} .layadmin-user-login{position: relative; left: 0; top: 0; padding: 110px 0; min-height: 100%; box-sizing: border-box;}
.layadmin-user-login-main{width: 375px; margin: 0 auto; box-sizing: border-box;} .layadmin-user-login-main{width: 375px; margin-top: 0px; margin-left: 5%; box-sizing: border-box; background-color:rgba(0,0,0,.3); border:1px solid; border-radius:15px}
.layadmin-user-login-box{padding: 20px;} .layadmin-user-login-box{padding: 20px;}
.layadmin-user-login-header{text-align: center;} .layadmin-user-login-header{text-align: center;}
.layadmin-user-login-header h2{margin-bottom: 10px; font-weight: 300; font-size: 30px; color: #000;} .layadmin-user-login-header h2{margin-bottom: 10px; font-weight: 300; font-size: 30px; color: #000;}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -35,12 +35,12 @@ private static $installed = array (
), ),
'league/flysystem' => 'league/flysystem' =>
array ( array (
'pretty_version' => '1.1.4', 'pretty_version' => '1.1.5',
'version' => '1.1.4.0', 'version' => '1.1.5.0',
'aliases' => 'aliases' =>
array ( array (
), ),
'reference' => 'f3ad69181b8afed2c9edf7be5a2918144ff4ea32', 'reference' => '18634df356bfd4119fe3d6156bdb990c414c14ea',
), ),
'league/flysystem-cached-adapter' => 'league/flysystem-cached-adapter' =>
array ( array (
@ -53,12 +53,12 @@ private static $installed = array (
), ),
'league/mime-type-detection' => 'league/mime-type-detection' =>
array ( array (
'pretty_version' => '1.7.0', 'pretty_version' => '1.8.0',
'version' => '1.7.0.0', 'version' => '1.8.0.0',
'aliases' => 'aliases' =>
array ( array (
), ),
'reference' => '3b9dff8aaf7323590c1d2e443db701eb1f9aa0d3', 'reference' => 'b38b25d7b372e9fddb00335400467b223349fd7e',
), ),
'lotofbadcode/phpspirit_databackup' => 'lotofbadcode/phpspirit_databackup' =>
array ( array (
@ -71,12 +71,12 @@ private static $installed = array (
), ),
'phpmailer/phpmailer' => 'phpmailer/phpmailer' =>
array ( array (
'pretty_version' => 'v6.5.0', 'pretty_version' => 'v6.5.1',
'version' => '6.5.0.0', 'version' => '6.5.1.0',
'aliases' => 'aliases' =>
array ( array (
), ),
'reference' => 'a5b5c43e50b7fba655f793ad27303cd74c57363c', 'reference' => 'dd803df5ad7492e1b40637f7ebd258fee5ca7355',
), ),
'psr/cache' => 'psr/cache' =>
array ( array (
@ -143,12 +143,12 @@ private static $installed = array (
), ),
'symfony/var-dumper' => 'symfony/var-dumper' =>
array ( array (
'pretty_version' => 'v4.4.27', 'pretty_version' => 'v4.4.33',
'version' => '4.4.27.0', 'version' => '4.4.33.0',
'aliases' => 'aliases' =>
array ( array (
), ),
'reference' => '391d6d0e7a06ab54eb7c38fab29b8d174471b3ba', 'reference' => '50286e2b7189bfb4f419c0731e86632cddf7c5ee',
), ),
'taoser/taoler' => 'taoser/taoler' =>
array ( array (
@ -159,6 +159,15 @@ private static $installed = array (
), ),
'reference' => NULL, 'reference' => NULL,
), ),
'taoser/think-addons' =>
array (
'pretty_version' => 'v1.0.1',
'version' => '1.0.1.0',
'aliases' =>
array (
),
'reference' => 'bd8b0bfa4543fe8d2da65355c134250f78c0d457',
),
'taoser/think-auth' => 'taoser/think-auth' =>
array ( array (
'pretty_version' => 'v1.0.0', 'pretty_version' => 'v1.0.0',
@ -249,15 +258,6 @@ private static $installed = array (
), ),
'reference' => '28a0e406d827132942723a3c9f69bb20c98e652f', 'reference' => '28a0e406d827132942723a3c9f69bb20c98e652f',
), ),
'zzstudio/think-addons' =>
array (
'pretty_version' => '2.0.5',
'version' => '2.0.5.0',
'aliases' =>
array (
),
'reference' => '7eb740cb219a111d593a05ad88248a74f640fe5c',
),
), ),
); );

View File

@ -11,7 +11,8 @@ return array(
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php', '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
'25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php', '25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php',
'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php', 'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
'667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php', '223fa6f9b46fbe5d6b44c5ff847bfceb' => $vendorDir . '/taoser/think-addons/src/helper.php',
'1cfd2761b63b0a29ed23657ea394cb2d' => $vendorDir . '/topthink/think-captcha/src/helper.php', '1cfd2761b63b0a29ed23657ea394cb2d' => $vendorDir . '/topthink/think-captcha/src/helper.php',
'39594db8502267d6df2fe2dca5f3914d' => $vendorDir . '/zzstudio/think-addons/src/helper.php', '667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php',
'd421242fd42b2ea6cd13f802bcf18a6e' => $baseDir . '/extend/taoler/com/form.php',
); );

View File

@ -11,8 +11,9 @@ return array(
'think\\trace\\' => array($vendorDir . '/topthink/think-trace/src'), 'think\\trace\\' => array($vendorDir . '/topthink/think-trace/src'),
'think\\captcha\\' => array($vendorDir . '/topthink/think-captcha/src'), 'think\\captcha\\' => array($vendorDir . '/topthink/think-captcha/src'),
'think\\app\\' => array($vendorDir . '/topthink/think-multi-app/src'), 'think\\app\\' => array($vendorDir . '/topthink/think-multi-app/src'),
'think\\' => array($vendorDir . '/topthink/framework/src/think', $vendorDir . '/topthink/think-helper/src', $vendorDir . '/topthink/think-orm/src', $vendorDir . '/topthink/think-template/src', $vendorDir . '/zzstudio/think-addons/src'), 'think\\' => array($vendorDir . '/topthink/framework/src/think', $vendorDir . '/topthink/think-helper/src', $vendorDir . '/topthink/think-orm/src', $vendorDir . '/topthink/think-template/src'),
'taoser\\think\\' => array($vendorDir . '/taoser/think-auth/src'), 'taoser\\think\\' => array($vendorDir . '/taoser/think-auth/src'),
'taoser\\' => array($vendorDir . '/taoser/think-addons/src'),
'phpspirit\\databackup\\' => array($vendorDir . '/lotofbadcode/phpspirit_databackup/src'), 'phpspirit\\databackup\\' => array($vendorDir . '/lotofbadcode/phpspirit_databackup/src'),
'app\\' => array($baseDir . '/app'), 'app\\' => array($baseDir . '/app'),
'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'), 'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'),

View File

@ -12,9 +12,10 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php', '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
'25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php', '25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php',
'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php', 'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
'667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php', '223fa6f9b46fbe5d6b44c5ff847bfceb' => __DIR__ . '/..' . '/taoser/think-addons/src/helper.php',
'1cfd2761b63b0a29ed23657ea394cb2d' => __DIR__ . '/..' . '/topthink/think-captcha/src/helper.php', '1cfd2761b63b0a29ed23657ea394cb2d' => __DIR__ . '/..' . '/topthink/think-captcha/src/helper.php',
'39594db8502267d6df2fe2dca5f3914d' => __DIR__ . '/..' . '/zzstudio/think-addons/src/helper.php', '667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php',
'd421242fd42b2ea6cd13f802bcf18a6e' => __DIR__ . '/../..' . '/extend/taoler/com/form.php',
); );
public static $prefixLengthsPsr4 = array ( public static $prefixLengthsPsr4 = array (
@ -30,6 +31,7 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2
'think\\app\\' => 10, 'think\\app\\' => 10,
'think\\' => 6, 'think\\' => 6,
'taoser\\think\\' => 13, 'taoser\\think\\' => 13,
'taoser\\' => 7,
), ),
'p' => 'p' =>
array ( array (
@ -93,12 +95,15 @@ class ComposerStaticInit1b32198725235c8d6500c87262ef30c2
1 => __DIR__ . '/..' . '/topthink/think-helper/src', 1 => __DIR__ . '/..' . '/topthink/think-helper/src',
2 => __DIR__ . '/..' . '/topthink/think-orm/src', 2 => __DIR__ . '/..' . '/topthink/think-orm/src',
3 => __DIR__ . '/..' . '/topthink/think-template/src', 3 => __DIR__ . '/..' . '/topthink/think-template/src',
4 => __DIR__ . '/..' . '/zzstudio/think-addons/src',
), ),
'taoser\\think\\' => 'taoser\\think\\' =>
array ( array (
0 => __DIR__ . '/..' . '/taoser/think-auth/src', 0 => __DIR__ . '/..' . '/taoser/think-auth/src',
), ),
'taoser\\' =>
array (
0 => __DIR__ . '/..' . '/taoser/think-addons/src',
),
'phpspirit\\databackup\\' => 'phpspirit\\databackup\\' =>
array ( array (
0 => __DIR__ . '/..' . '/lotofbadcode/phpspirit_databackup/src', 0 => __DIR__ . '/..' . '/lotofbadcode/phpspirit_databackup/src',

View File

@ -68,17 +68,17 @@
}, },
{ {
"name": "league/flysystem", "name": "league/flysystem",
"version": "1.1.4", "version": "1.1.5",
"version_normalized": "1.1.4.0", "version_normalized": "1.1.5.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/thephpleague/flysystem.git", "url": "https://github.com/thephpleague/flysystem.git",
"reference": "f3ad69181b8afed2c9edf7be5a2918144ff4ea32" "reference": "18634df356bfd4119fe3d6156bdb990c414c14ea"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/f3ad69181b8afed2c9edf7be5a2918144ff4ea32", "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/18634df356bfd4119fe3d6156bdb990c414c14ea",
"reference": "f3ad69181b8afed2c9edf7be5a2918144ff4ea32", "reference": "18634df356bfd4119fe3d6156bdb990c414c14ea",
"shasum": "", "shasum": "",
"mirrors": [ "mirrors": [
{ {
@ -114,7 +114,7 @@
"spatie/flysystem-dropbox": "Allows you to use Dropbox storage", "spatie/flysystem-dropbox": "Allows you to use Dropbox storage",
"srmklive/flysystem-dropbox-v2": "Allows you to use Dropbox storage for PHP 5 applications" "srmklive/flysystem-dropbox-v2": "Allows you to use Dropbox storage for PHP 5 applications"
}, },
"time": "2021-06-23T21:56:05+00:00", "time": "2021-08-17T13:49:42+00:00",
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
@ -159,7 +159,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/thephpleague/flysystem/issues", "issues": "https://github.com/thephpleague/flysystem/issues",
"source": "https://github.com/thephpleague/flysystem/tree/1.1.4" "source": "https://github.com/thephpleague/flysystem/tree/1.1.5"
}, },
"funding": [ "funding": [
{ {
@ -227,17 +227,17 @@
}, },
{ {
"name": "league/mime-type-detection", "name": "league/mime-type-detection",
"version": "1.7.0", "version": "1.8.0",
"version_normalized": "1.7.0.0", "version_normalized": "1.8.0.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/thephpleague/mime-type-detection.git", "url": "https://github.com/thephpleague/mime-type-detection.git",
"reference": "3b9dff8aaf7323590c1d2e443db701eb1f9aa0d3" "reference": "b38b25d7b372e9fddb00335400467b223349fd7e"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/3b9dff8aaf7323590c1d2e443db701eb1f9aa0d3", "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/b38b25d7b372e9fddb00335400467b223349fd7e",
"reference": "3b9dff8aaf7323590c1d2e443db701eb1f9aa0d3", "reference": "b38b25d7b372e9fddb00335400467b223349fd7e",
"shasum": "", "shasum": "",
"mirrors": [ "mirrors": [
{ {
@ -255,7 +255,7 @@
"phpstan/phpstan": "^0.12.68", "phpstan/phpstan": "^0.12.68",
"phpunit/phpunit": "^8.5.8 || ^9.3" "phpunit/phpunit": "^8.5.8 || ^9.3"
}, },
"time": "2021-01-18T20:58:21+00:00", "time": "2021-09-25T08:23:19+00:00",
"type": "library", "type": "library",
"installation-source": "dist", "installation-source": "dist",
"autoload": { "autoload": {
@ -276,7 +276,7 @@
"description": "Mime-type detection for Flysystem", "description": "Mime-type detection for Flysystem",
"support": { "support": {
"issues": "https://github.com/thephpleague/mime-type-detection/issues", "issues": "https://github.com/thephpleague/mime-type-detection/issues",
"source": "https://github.com/thephpleague/mime-type-detection/tree/1.7.0" "source": "https://github.com/thephpleague/mime-type-detection/tree/1.8.0"
}, },
"funding": [ "funding": [
{ {
@ -345,17 +345,17 @@
}, },
{ {
"name": "phpmailer/phpmailer", "name": "phpmailer/phpmailer",
"version": "v6.5.0", "version": "v6.5.1",
"version_normalized": "6.5.0.0", "version_normalized": "6.5.1.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/PHPMailer/PHPMailer.git", "url": "https://github.com/PHPMailer/PHPMailer.git",
"reference": "a5b5c43e50b7fba655f793ad27303cd74c57363c" "reference": "dd803df5ad7492e1b40637f7ebd258fee5ca7355"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/a5b5c43e50b7fba655f793ad27303cd74c57363c", "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/dd803df5ad7492e1b40637f7ebd258fee5ca7355",
"reference": "a5b5c43e50b7fba655f793ad27303cd74c57363c", "reference": "dd803df5ad7492e1b40637f7ebd258fee5ca7355",
"shasum": "", "shasum": "",
"mirrors": [ "mirrors": [
{ {
@ -373,10 +373,12 @@
"require-dev": { "require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0",
"doctrine/annotations": "^1.2", "doctrine/annotations": "^1.2",
"php-parallel-lint/php-console-highlighter": "^0.5.0",
"php-parallel-lint/php-parallel-lint": "^1.3",
"phpcompatibility/php-compatibility": "^9.3.5", "phpcompatibility/php-compatibility": "^9.3.5",
"roave/security-advisories": "dev-latest", "roave/security-advisories": "dev-latest",
"squizlabs/php_codesniffer": "^3.5.6", "squizlabs/php_codesniffer": "^3.6.0",
"yoast/phpunit-polyfills": "^0.2.0" "yoast/phpunit-polyfills": "^1.0.0"
}, },
"suggest": { "suggest": {
"ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses", "ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses",
@ -386,7 +388,7 @@
"stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication", "stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication",
"symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)" "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)"
}, },
"time": "2021-06-16T14:33:43+00:00", "time": "2021-08-18T09:14:16+00:00",
"type": "library", "type": "library",
"installation-source": "dist", "installation-source": "dist",
"autoload": { "autoload": {
@ -418,7 +420,7 @@
"description": "PHPMailer is a full-featured email creation and transfer class for PHP", "description": "PHPMailer is a full-featured email creation and transfer class for PHP",
"support": { "support": {
"issues": "https://github.com/PHPMailer/PHPMailer/issues", "issues": "https://github.com/PHPMailer/PHPMailer/issues",
"source": "https://github.com/PHPMailer/PHPMailer/tree/v6.5.0" "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.5.1"
}, },
"funding": [ "funding": [
{ {
@ -924,17 +926,17 @@
}, },
{ {
"name": "symfony/var-dumper", "name": "symfony/var-dumper",
"version": "v4.4.27", "version": "v4.4.33",
"version_normalized": "4.4.27.0", "version_normalized": "4.4.33.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/var-dumper.git", "url": "https://github.com/symfony/var-dumper.git",
"reference": "391d6d0e7a06ab54eb7c38fab29b8d174471b3ba" "reference": "50286e2b7189bfb4f419c0731e86632cddf7c5ee"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/391d6d0e7a06ab54eb7c38fab29b8d174471b3ba", "url": "https://api.github.com/repos/symfony/var-dumper/zipball/50286e2b7189bfb4f419c0731e86632cddf7c5ee",
"reference": "391d6d0e7a06ab54eb7c38fab29b8d174471b3ba", "reference": "50286e2b7189bfb4f419c0731e86632cddf7c5ee",
"shasum": "", "shasum": "",
"mirrors": [ "mirrors": [
{ {
@ -964,7 +966,7 @@
"ext-intl": "To show region name in time zone dump", "ext-intl": "To show region name in time zone dump",
"symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script" "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script"
}, },
"time": "2021-07-23T15:41:52+00:00", "time": "2021-10-25T20:24:58+00:00",
"bin": [ "bin": [
"Resources/bin/var-dump-server" "Resources/bin/var-dump-server"
], ],
@ -1002,7 +1004,7 @@
"dump" "dump"
], ],
"support": { "support": {
"source": "https://github.com/symfony/var-dumper/tree/v4.4.27" "source": "https://github.com/symfony/var-dumper/tree/v4.4.33"
}, },
"funding": [ "funding": [
{ {
@ -1020,6 +1022,71 @@
], ],
"install-path": "../symfony/var-dumper" "install-path": "../symfony/var-dumper"
}, },
{
"name": "taoser/think-addons",
"version": "v1.0.1",
"version_normalized": "1.0.1.0",
"source": {
"type": "git",
"url": "https://github.com/taoser/think-addons.git",
"reference": "bd8b0bfa4543fe8d2da65355c134250f78c0d457"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/taoser/think-addons/zipball/bd8b0bfa4543fe8d2da65355c134250f78c0d457",
"reference": "bd8b0bfa4543fe8d2da65355c134250f78c0d457",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"php": ">=7.1.0",
"topthink/framework": "^6.0",
"topthink/think-helper": "^3.0.0",
"topthink/think-view": "^1.0"
},
"time": "2021-09-18T08:41:10+00:00",
"type": "library",
"extra": {
"think": {
"services": [
"taoser\\addons\\Service"
],
"config": {
"addons": "src/config.php"
}
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"taoser\\": "src/"
},
"files": [
"src/helper.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"mit"
],
"authors": [
{
"name": "taoler",
"email": "changlin_zhao@qq.com"
}
],
"description": "The ThinkPHP6 Addons Package",
"support": {
"issues": "https://github.com/taoser/think-addons/issues",
"source": "https://github.com/taoser/think-addons/tree/v1.0.1"
},
"install-path": "../taoser/think-addons"
},
{ {
"name": "taoser/think-auth", "name": "taoser/think-auth",
"version": "v1.0.0", "version": "v1.0.0",
@ -1584,67 +1651,6 @@
"source": "https://github.com/wamkj/thinkphp6.0-databackup/tree/v1.0" "source": "https://github.com/wamkj/thinkphp6.0-databackup/tree/v1.0"
}, },
"install-path": "../wamkj/thinkphp6.0-databackup" "install-path": "../wamkj/thinkphp6.0-databackup"
},
{
"name": "zzstudio/think-addons",
"version": "2.0.5",
"version_normalized": "2.0.5.0",
"source": {
"type": "git",
"url": "https://github.com/zz-studio/think-addons.git",
"reference": "7eb740cb219a111d593a05ad88248a74f640fe5c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/zz-studio/think-addons/zipball/7eb740cb219a111d593a05ad88248a74f640fe5c",
"reference": "7eb740cb219a111d593a05ad88248a74f640fe5c",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"php": ">=7.1.0",
"topthink/framework": "^6.0",
"topthink/think-helper": "^3.0.0",
"topthink/think-view": "^1.0"
},
"time": "2020-01-06T06:42:39+00:00",
"type": "library",
"extra": {
"think": {
"services": [
"think\\addons\\Service"
],
"config": {
"addons": "src/config.php"
}
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"think\\": "src/"
},
"files": [
"src/helper.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"Apache-2.0"
],
"authors": [
{
"name": "byron",
"email": "xiaobo.sun@qq.com"
}
],
"description": "The ThinkPHP6 Addons Package",
"install-path": "../zzstudio/think-addons"
} }
], ],
"dev": true "dev": true

View File

@ -22,12 +22,12 @@
), ),
'league/flysystem' => 'league/flysystem' =>
array ( array (
'pretty_version' => '1.1.4', 'pretty_version' => '1.1.5',
'version' => '1.1.4.0', 'version' => '1.1.5.0',
'aliases' => 'aliases' =>
array ( array (
), ),
'reference' => 'f3ad69181b8afed2c9edf7be5a2918144ff4ea32', 'reference' => '18634df356bfd4119fe3d6156bdb990c414c14ea',
), ),
'league/flysystem-cached-adapter' => 'league/flysystem-cached-adapter' =>
array ( array (
@ -40,12 +40,12 @@
), ),
'league/mime-type-detection' => 'league/mime-type-detection' =>
array ( array (
'pretty_version' => '1.7.0', 'pretty_version' => '1.8.0',
'version' => '1.7.0.0', 'version' => '1.8.0.0',
'aliases' => 'aliases' =>
array ( array (
), ),
'reference' => '3b9dff8aaf7323590c1d2e443db701eb1f9aa0d3', 'reference' => 'b38b25d7b372e9fddb00335400467b223349fd7e',
), ),
'lotofbadcode/phpspirit_databackup' => 'lotofbadcode/phpspirit_databackup' =>
array ( array (
@ -58,12 +58,12 @@
), ),
'phpmailer/phpmailer' => 'phpmailer/phpmailer' =>
array ( array (
'pretty_version' => 'v6.5.0', 'pretty_version' => 'v6.5.1',
'version' => '6.5.0.0', 'version' => '6.5.1.0',
'aliases' => 'aliases' =>
array ( array (
), ),
'reference' => 'a5b5c43e50b7fba655f793ad27303cd74c57363c', 'reference' => 'dd803df5ad7492e1b40637f7ebd258fee5ca7355',
), ),
'psr/cache' => 'psr/cache' =>
array ( array (
@ -130,12 +130,12 @@
), ),
'symfony/var-dumper' => 'symfony/var-dumper' =>
array ( array (
'pretty_version' => 'v4.4.27', 'pretty_version' => 'v4.4.33',
'version' => '4.4.27.0', 'version' => '4.4.33.0',
'aliases' => 'aliases' =>
array ( array (
), ),
'reference' => '391d6d0e7a06ab54eb7c38fab29b8d174471b3ba', 'reference' => '50286e2b7189bfb4f419c0731e86632cddf7c5ee',
), ),
'taoser/taoler' => 'taoser/taoler' =>
array ( array (
@ -146,6 +146,15 @@
), ),
'reference' => NULL, 'reference' => NULL,
), ),
'taoser/think-addons' =>
array (
'pretty_version' => 'v1.0.1',
'version' => '1.0.1.0',
'aliases' =>
array (
),
'reference' => 'bd8b0bfa4543fe8d2da65355c134250f78c0d457',
),
'taoser/think-auth' => 'taoser/think-auth' =>
array ( array (
'pretty_version' => 'v1.0.0', 'pretty_version' => 'v1.0.0',
@ -236,14 +245,5 @@
), ),
'reference' => '28a0e406d827132942723a3c9f69bb20c98e652f', 'reference' => '28a0e406d827132942723a3c9f69bb20c98e652f',
), ),
'zzstudio/think-addons' =>
array (
'pretty_version' => '2.0.5',
'version' => '2.0.5.0',
'aliases' =>
array (
),
'reference' => '7eb740cb219a111d593a05ad88248a74f640fe5c',
),
), ),
); );

View File

@ -160,7 +160,7 @@ class Ftp extends AbstractFtpAdapter
{ {
if ($this->utf8) { if ($this->utf8) {
$response = ftp_raw($this->connection, "OPTS UTF8 ON"); $response = ftp_raw($this->connection, "OPTS UTF8 ON");
if (substr($response[0], 0, 3) !== '200') { if (!in_array(substr($response[0], 0, 3), ['200', '202'])) {
throw new ConnectionRuntimeException( throw new ConnectionRuntimeException(
'Could not set UTF-8 mode for connection: ' . $this->getHost() . '::' . $this->getPort() 'Could not set UTF-8 mode for connection: ' . $this->getHost() . '::' . $this->getPort()
); );

View File

@ -1,5 +1,11 @@
# Changelog # Changelog
## 1.8.0 - 2021-09-25
### Added
- Added the decorator `OverridingExtensionToMimeTypeMap` which allows you to override values.
## 1.7.0 - 2021-01-18 ## 1.7.0 - 2021-01-18
### Added ### Added

View File

@ -45,6 +45,7 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap
'air' => 'application/vnd.adobe.air-application-installer-package+zip', 'air' => 'application/vnd.adobe.air-application-installer-package+zip',
'ait' => 'application/vnd.dvb.ait', 'ait' => 'application/vnd.dvb.ait',
'ami' => 'application/vnd.amiga.ami', 'ami' => 'application/vnd.amiga.ami',
'amr' => 'audio/amr',
'apk' => 'application/vnd.android.package-archive', 'apk' => 'application/vnd.android.package-archive',
'apng' => 'image/apng', 'apng' => 'image/apng',
'appcache' => 'text/cache-manifest', 'appcache' => 'text/cache-manifest',
@ -265,6 +266,7 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap
'evy' => 'application/x-envoy', 'evy' => 'application/x-envoy',
'exe' => 'application/octet-stream', 'exe' => 'application/octet-stream',
'exi' => 'application/exi', 'exi' => 'application/exi',
'exp' => 'application/express',
'exr' => 'image/aces', 'exr' => 'image/aces',
'ext' => 'application/vnd.novadigm.ext', 'ext' => 'application/vnd.novadigm.ext',
'ez' => 'application/andrew-inset', 'ez' => 'application/andrew-inset',
@ -351,8 +353,8 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap
'gv' => 'text/vnd.graphviz', 'gv' => 'text/vnd.graphviz',
'gxf' => 'application/gxf', 'gxf' => 'application/gxf',
'gxt' => 'application/vnd.geonext', 'gxt' => 'application/vnd.geonext',
'gz' => 'application/x-gzip', 'gz' => 'application/gzip',
'gzip' => 'application/x-gzip', 'gzip' => 'application/gzip',
'h' => 'text/x-c', 'h' => 'text/x-c',
'h261' => 'video/h261', 'h261' => 'video/h261',
'h263' => 'video/h263', 'h263' => 'video/h263',
@ -457,7 +459,7 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap
'karbon' => 'application/vnd.kde.karbon', 'karbon' => 'application/vnd.kde.karbon',
'kdb' => 'application/octet-stream', 'kdb' => 'application/octet-stream',
'kdbx' => 'application/x-keepass2', 'kdbx' => 'application/x-keepass2',
'key' => 'application/vnd.apple.keynote', 'key' => 'application/x-iwork-keynote-sffkey',
'kfo' => 'application/vnd.kde.kformula', 'kfo' => 'application/vnd.kde.kformula',
'kia' => 'application/vnd.kidspiration', 'kia' => 'application/vnd.kidspiration',
'kml' => 'application/vnd.google-earth.kml+xml', 'kml' => 'application/vnd.google-earth.kml+xml',
@ -507,6 +509,7 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap
'm3u8' => 'application/vnd.apple.mpegurl', 'm3u8' => 'application/vnd.apple.mpegurl',
'm4a' => 'audio/x-m4a', 'm4a' => 'audio/x-m4a',
'm4p' => 'application/mp4', 'm4p' => 'application/mp4',
'm4s' => 'video/iso.segment',
'm4u' => 'application/vnd.mpegurl', 'm4u' => 'application/vnd.mpegurl',
'm4v' => 'video/x-m4v', 'm4v' => 'video/x-m4v',
'm13' => 'application/x-msmediaview', 'm13' => 'application/x-msmediaview',
@ -608,6 +611,7 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap
'musd' => 'application/mmt-usd+xml', 'musd' => 'application/mmt-usd+xml',
'musicxml' => 'application/vnd.recordare.musicxml+xml', 'musicxml' => 'application/vnd.recordare.musicxml+xml',
'mvb' => 'application/x-msmediaview', 'mvb' => 'application/x-msmediaview',
'mvt' => 'application/vnd.mapbox-vector-tile',
'mwf' => 'application/vnd.mfer', 'mwf' => 'application/vnd.mfer',
'mxf' => 'application/mxf', 'mxf' => 'application/mxf',
'mxl' => 'application/vnd.recordare.musicxml', 'mxl' => 'application/vnd.recordare.musicxml',
@ -635,7 +639,7 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap
'nsf' => 'application/vnd.lotus-notes', 'nsf' => 'application/vnd.lotus-notes',
'nt' => 'application/n-triples', 'nt' => 'application/n-triples',
'ntf' => 'application/vnd.nitf', 'ntf' => 'application/vnd.nitf',
'numbers' => 'application/vnd.apple.numbers', 'numbers' => 'application/x-iwork-numbers-sffnumbers',
'nzb' => 'application/x-nzb', 'nzb' => 'application/x-nzb',
'oa2' => 'application/vnd.fujitsu.oasys2', 'oa2' => 'application/vnd.fujitsu.oasys2',
'oa3' => 'application/vnd.fujitsu.oasys3', 'oa3' => 'application/vnd.fujitsu.oasys3',
@ -696,7 +700,7 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap
'p10' => 'application/x-pkcs10', 'p10' => 'application/x-pkcs10',
'p12' => 'application/x-pkcs12', 'p12' => 'application/x-pkcs12',
'pac' => 'application/x-ns-proxy-autoconfig', 'pac' => 'application/x-ns-proxy-autoconfig',
'pages' => 'application/vnd.apple.pages', 'pages' => 'application/x-iwork-pages-sffpages',
'pas' => 'text/x-pascal', 'pas' => 'text/x-pascal',
'paw' => 'application/vnd.pawaafile', 'paw' => 'application/vnd.pawaafile',
'pbd' => 'application/vnd.powerbuilder6', 'pbd' => 'application/vnd.powerbuilder6',
@ -921,6 +925,9 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap
'sti' => 'application/vnd.sun.xml.impress.template', 'sti' => 'application/vnd.sun.xml.impress.template',
'stk' => 'application/hyperstudio', 'stk' => 'application/hyperstudio',
'stl' => 'model/stl', 'stl' => 'model/stl',
'stpx' => 'model/step+xml',
'stpxz' => 'model/step-xml+zip',
'stpz' => 'model/step+zip',
'str' => 'application/vnd.pg.format', 'str' => 'application/vnd.pg.format',
'stw' => 'application/vnd.sun.xml.writer.template', 'stw' => 'application/vnd.sun.xml.writer.template',
'styl' => 'text/stylus', 'styl' => 'text/stylus',
@ -977,6 +984,7 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap
'tpt' => 'application/vnd.trid.tpt', 'tpt' => 'application/vnd.trid.tpt',
'tr' => 'text/troff', 'tr' => 'text/troff',
'tra' => 'application/vnd.trueapp', 'tra' => 'application/vnd.trueapp',
'trig' => 'application/trig',
'trm' => 'application/x-msterminal', 'trm' => 'application/x-msterminal',
'ts' => 'video/mp2t', 'ts' => 'video/mp2t',
'tsd' => 'application/timestamped-data', 'tsd' => 'application/timestamped-data',
@ -1047,6 +1055,7 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap
'vcs' => 'text/x-vcalendar', 'vcs' => 'text/x-vcalendar',
'vcx' => 'application/vnd.vcx', 'vcx' => 'application/vnd.vcx',
'vdi' => 'application/x-virtualbox-vdi', 'vdi' => 'application/x-virtualbox-vdi',
'vds' => 'model/vnd.sap.vds',
'vhd' => 'application/x-virtualbox-vhd', 'vhd' => 'application/x-virtualbox-vhd',
'vis' => 'application/vnd.visionary', 'vis' => 'application/vnd.visionary',
'viv' => 'video/vnd.vivo', 'viv' => 'video/vnd.vivo',
@ -1136,7 +1145,7 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap
'xdw' => 'application/vnd.fujixerox.docuworks', 'xdw' => 'application/vnd.fujixerox.docuworks',
'xel' => 'application/xcap-el+xml', 'xel' => 'application/xcap-el+xml',
'xenc' => 'application/xenc+xml', 'xenc' => 'application/xenc+xml',
'xer' => 'application/xcap-error+xml', 'xer' => 'application/patch-ops-error+xml',
'xfdf' => 'application/vnd.adobe.xfdf', 'xfdf' => 'application/vnd.adobe.xfdf',
'xfdl' => 'application/vnd.xfdl', 'xfdl' => 'application/vnd.xfdl',
'xht' => 'application/xhtml+xml', 'xht' => 'application/xhtml+xml',
@ -1195,7 +1204,7 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap
'z7' => 'application/x-zmachine', 'z7' => 'application/x-zmachine',
'z8' => 'application/x-zmachine', 'z8' => 'application/x-zmachine',
'zaz' => 'application/vnd.zzazz.deck+xml', 'zaz' => 'application/vnd.zzazz.deck+xml',
'zip' => 'application/x-zip', 'zip' => 'application/zip',
'zir' => 'application/vnd.zul', 'zir' => 'application/vnd.zul',
'zirz' => 'application/vnd.zul', 'zirz' => 'application/vnd.zul',
'zmm' => 'application/vnd.handheld-entertainment+xml', 'zmm' => 'application/vnd.handheld-entertainment+xml',

View File

@ -0,0 +1,30 @@
<?php
namespace League\MimeTypeDetection;
class OverridingExtensionToMimeTypeMap implements ExtensionToMimeTypeMap
{
/**
* @var ExtensionToMimeTypeMap
*/
private $innerMap;
/**
* @var string[]
*/
private $overrides;
/**
* @param array<string, string> $overrides
*/
public function __construct(ExtensionToMimeTypeMap $innerMap, array $overrides)
{
$this->innerMap = $innerMap;
$this->overrides = $overrides;
}
public function lookupMimeType(string $extension): ?string
{
return $this->overrides[$extension] ?? $this->innerMap->lookupMimeType($extension);
}
}

View File

@ -2,7 +2,12 @@
# PHPMailer A full-featured email creation and transfer class for PHP # PHPMailer A full-featured email creation and transfer class for PHP
[![Test status](https://github.com/PHPMailer/PHPMailer/workflows/Tests/badge.svg)](https://github.com/PHPMailer/PHPMailer/actions) [![Latest Stable Version](https://poser.pugx.org/phpmailer/phpmailer/v/stable.svg)](https://packagist.org/packages/phpmailer/phpmailer) [![Total Downloads](https://poser.pugx.org/phpmailer/phpmailer/downloads)](https://packagist.org/packages/phpmailer/phpmailer) [![License](https://poser.pugx.org/phpmailer/phpmailer/license.svg)](https://packagist.org/packages/phpmailer/phpmailer) [![API Docs](https://github.com/phpmailer/phpmailer/workflows/Docs/badge.svg)](https://phpmailer.github.io/PHPMailer/) [![Test status](https://github.com/PHPMailer/PHPMailer/workflows/Tests/badge.svg)](https://github.com/PHPMailer/PHPMailer/actions)
[![codecov.io](https://codecov.io/gh/PHPMailer/PHPMailer/branch/master/graph/badge.svg?token=iORZpwmYmM)](https://codecov.io/gh/PHPMailer/PHPMailer)
[![Latest Stable Version](https://poser.pugx.org/phpmailer/phpmailer/v/stable.svg)](https://packagist.org/packages/phpmailer/phpmailer)
[![Total Downloads](https://poser.pugx.org/phpmailer/phpmailer/downloads)](https://packagist.org/packages/phpmailer/phpmailer)
[![License](https://poser.pugx.org/phpmailer/phpmailer/license.svg)](https://packagist.org/packages/phpmailer/phpmailer)
[![API Docs](https://github.com/phpmailer/phpmailer/workflows/Docs/badge.svg)](https://phpmailer.github.io/PHPMailer/)
## Features ## Features
- Probably the world's most popular code for sending email from PHP! - Probably the world's most popular code for sending email from PHP!
@ -17,7 +22,7 @@
- Protects against header injection attacks - Protects against header injection attacks
- Error messages in over 50 languages! - Error messages in over 50 languages!
- DKIM and S/MIME signing support - DKIM and S/MIME signing support
- Compatible with PHP 5.5 and later, including PHP 8.0 - Compatible with PHP 5.5 and later, including PHP 8.1
- Namespaced to prevent name clashes - Namespaced to prevent name clashes
- Much more! - Much more!
@ -39,7 +44,7 @@ This software is distributed under the [LGPL 2.1](http://www.gnu.org/licenses/lg
PHPMailer is available on [Packagist](https://packagist.org/packages/phpmailer/phpmailer) (using semantic versioning), and installation via [Composer](https://getcomposer.org) is the recommended way to install PHPMailer. Just add this line to your `composer.json` file: PHPMailer is available on [Packagist](https://packagist.org/packages/phpmailer/phpmailer) (using semantic versioning), and installation via [Composer](https://getcomposer.org) is the recommended way to install PHPMailer. Just add this line to your `composer.json` file:
```json ```json
"phpmailer/phpmailer": "^6.2" "phpmailer/phpmailer": "^6.5"
``` ```
or run or run
@ -89,7 +94,7 @@ use PHPMailer\PHPMailer\Exception;
//Load Composer's autoloader //Load Composer's autoloader
require 'vendor/autoload.php'; require 'vendor/autoload.php';
//Instantiation and passing `true` enables exceptions //Create an instance; passing `true` enables exceptions
$mail = new PHPMailer(true); $mail = new PHPMailer(true);
try { try {
@ -100,8 +105,8 @@ try {
$mail->SMTPAuth = true; //Enable SMTP authentication $mail->SMTPAuth = true; //Enable SMTP authentication
$mail->Username = 'user@example.com'; //SMTP username $mail->Username = 'user@example.com'; //SMTP username
$mail->Password = 'secret'; //SMTP password $mail->Password = 'secret'; //SMTP password
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; //Enable TLS encryption; `PHPMailer::ENCRYPTION_SMTPS` encouraged $mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS; //Enable implicit TLS encryption
$mail->Port = 587; //TCP port to connect to, use 465 for `PHPMailer::ENCRYPTION_SMTPS` above $mail->Port = 465; //TCP port to connect to; use 587 if you have set `SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS`
//Recipients //Recipients
$mail->setFrom('from@example.com', 'Mailer'); $mail->setFrom('from@example.com', 'Mailer');

View File

@ -1 +1 @@
6.5.0 6.5.1

View File

@ -34,10 +34,12 @@
"require-dev": { "require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0",
"doctrine/annotations": "^1.2", "doctrine/annotations": "^1.2",
"php-parallel-lint/php-console-highlighter": "^0.5.0",
"php-parallel-lint/php-parallel-lint": "^1.3",
"phpcompatibility/php-compatibility": "^9.3.5", "phpcompatibility/php-compatibility": "^9.3.5",
"roave/security-advisories": "dev-latest", "roave/security-advisories": "dev-latest",
"squizlabs/php_codesniffer": "^3.5.6", "squizlabs/php_codesniffer": "^3.6.0",
"yoast/phpunit-polyfills": "^0.2.0" "yoast/phpunit-polyfills": "^1.0.0"
}, },
"suggest": { "suggest": {
"ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses", "ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses",
@ -60,6 +62,10 @@
"license": "LGPL-2.1-only", "license": "LGPL-2.1-only",
"scripts": { "scripts": {
"check": "./vendor/bin/phpcs", "check": "./vendor/bin/phpcs",
"test": "./vendor/bin/phpunit" "test": "./vendor/bin/phpunit --no-coverage",
"coverage": "./vendor/bin/phpunit",
"lint": [
"@php ./vendor/php-parallel-lint/php-parallel-lint/parallel-lint . -e php,phps --exclude vendor --exclude .git --exclude build"
]
} }
} }

View File

@ -5,24 +5,25 @@
* @package PHPMailer * @package PHPMailer
* @author Mitsuhiro Yoshida <http://mitstek.com/> * @author Mitsuhiro Yoshida <http://mitstek.com/>
* @author Yoshi Sakai <http://bluemooninc.jp/> * @author Yoshi Sakai <http://bluemooninc.jp/>
* @author Arisophy <https://github.com/arisophy/>
*/ */
$PHPMAILER_LANG['authenticate'] = 'SMTPエラー: 認証できませんでした。'; $PHPMAILER_LANG['authenticate'] = 'SMTPエラー: 認証できませんでした。';
$PHPMAILER_LANG['connect_host'] = 'SMTPエラー: SMTPホストに接続できませんでした。'; $PHPMAILER_LANG['connect_host'] = 'SMTPエラー: SMTPホストに接続できませんでした。';
$PHPMAILER_LANG['data_not_accepted'] = 'SMTPエラー: データが受け付けられませんでした。'; $PHPMAILER_LANG['data_not_accepted'] = 'SMTPエラー: データが受け付けられませんでした。';
//$PHPMAILER_LANG['empty_message'] = 'Message body empty'; $PHPMAILER_LANG['empty_message'] = 'メール本文が空です。';
$PHPMAILER_LANG['encoding'] = '不明なエンコーディング: '; $PHPMAILER_LANG['encoding'] = '不明なエンコーディング: ';
$PHPMAILER_LANG['execute'] = '実行できませんでした: '; $PHPMAILER_LANG['execute'] = '実行できませんでした: ';
$PHPMAILER_LANG['file_access'] = 'ファイルにアクセスできません: '; $PHPMAILER_LANG['file_access'] = 'ファイルにアクセスできません: ';
$PHPMAILER_LANG['file_open'] = 'ファイルエラー: ファイルを開けません: '; $PHPMAILER_LANG['file_open'] = 'ファイルエラー: ファイルを開けません: ';
$PHPMAILER_LANG['from_failed'] = 'Fromアドレスを登録する際にエラーが発生しました: '; $PHPMAILER_LANG['from_failed'] = 'Fromアドレスを登録する際にエラーが発生しました: ';
$PHPMAILER_LANG['instantiate'] = 'メール関数が正常に動作しませんでした。'; $PHPMAILER_LANG['instantiate'] = 'メール関数が正常に動作しませんでした。';
//$PHPMAILER_LANG['invalid_address'] = 'Invalid address: '; $PHPMAILER_LANG['invalid_address'] = '不正なメールアドレス: ';
$PHPMAILER_LANG['provide_address'] = '少なくとも1つメールアドレスを 指定する必要があります。'; $PHPMAILER_LANG['provide_address'] = '少なくとも1つメールアドレスを 指定する必要があります。';
$PHPMAILER_LANG['mailer_not_supported'] = ' メーラーがサポートされていません。'; $PHPMAILER_LANG['mailer_not_supported'] = ' メーラーがサポートされていません。';
$PHPMAILER_LANG['recipients_failed'] = 'SMTPエラー: 次の受信者アドレスに 間違いがあります: '; $PHPMAILER_LANG['recipients_failed'] = 'SMTPエラー: 次の受信者アドレスに 間違いがあります: ';
//$PHPMAILER_LANG['signing'] = 'Signing Error: '; $PHPMAILER_LANG['signing'] = '署名エラー: ';
//$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.'; $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP接続に失敗しました。';
//$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; $PHPMAILER_LANG['smtp_error'] = 'SMTPサーバーエラー: ';
//$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: '; $PHPMAILER_LANG['variable_set'] = '変数が存在しません: ';
//$PHPMAILER_LANG['extension_missing'] = 'Extension missing: '; $PHPMAILER_LANG['extension_missing'] = '拡張機能が見つかりません: ';

View File

@ -7,23 +7,28 @@
*/ */
$PHPMAILER_LANG['authenticate'] = 'SMTP-fout: authenticatie mislukt.'; $PHPMAILER_LANG['authenticate'] = 'SMTP-fout: authenticatie mislukt.';
$PHPMAILER_LANG['buggy_php'] = 'PHP versie gededecteerd die onderhavig is aan een bug die kan resulteren in gecorrumpeerde berichten. Om dit te voorkomen, gebruik SMTP voor het verzenden van berichten, zet de mail.add_x_header optie in uw php.ini file uit, gebruik MacOS of Linux, of pas de gebruikte PHP versie aan naar versie 7.0.17+ or 7.1.3+.';
$PHPMAILER_LANG['connect_host'] = 'SMTP-fout: kon niet verbinden met SMTP-host.'; $PHPMAILER_LANG['connect_host'] = 'SMTP-fout: kon niet verbinden met SMTP-host.';
$PHPMAILER_LANG['data_not_accepted'] = 'SMTP-fout: data niet geaccepteerd.'; $PHPMAILER_LANG['data_not_accepted'] = 'SMTP-fout: data niet geaccepteerd.';
$PHPMAILER_LANG['empty_message'] = 'Berichttekst is leeg'; $PHPMAILER_LANG['empty_message'] = 'Berichttekst is leeg';
$PHPMAILER_LANG['encoding'] = 'Onbekende codering: '; $PHPMAILER_LANG['encoding'] = 'Onbekende codering: ';
$PHPMAILER_LANG['execute'] = 'Kon niet uitvoeren: '; $PHPMAILER_LANG['execute'] = 'Kon niet uitvoeren: ';
$PHPMAILER_LANG['extension_missing'] = 'Extensie afwezig: ';
$PHPMAILER_LANG['file_access'] = 'Kreeg geen toegang tot bestand: '; $PHPMAILER_LANG['file_access'] = 'Kreeg geen toegang tot bestand: ';
$PHPMAILER_LANG['file_open'] = 'Bestandsfout: kon bestand niet openen: '; $PHPMAILER_LANG['file_open'] = 'Bestandsfout: kon bestand niet openen: ';
$PHPMAILER_LANG['from_failed'] = 'Het volgende afzendersadres is mislukt: '; $PHPMAILER_LANG['from_failed'] = 'Het volgende afzendersadres is mislukt: ';
$PHPMAILER_LANG['instantiate'] = 'Kon mailfunctie niet initialiseren.'; $PHPMAILER_LANG['instantiate'] = 'Kon mailfunctie niet initialiseren.';
$PHPMAILER_LANG['invalid_address'] = 'Ongeldig adres: '; $PHPMAILER_LANG['invalid_address'] = 'Ongeldig adres: ';
$PHPMAILER_LANG['invalid_header'] = 'Ongeldige header naam of waarde';
$PHPMAILER_LANG['invalid_hostentry'] = 'Ongeldige hostentry: '; $PHPMAILER_LANG['invalid_hostentry'] = 'Ongeldige hostentry: ';
$PHPMAILER_LANG['invalid_host'] = 'Ongeldige host: '; $PHPMAILER_LANG['invalid_host'] = 'Ongeldige host: ';
$PHPMAILER_LANG['mailer_not_supported'] = ' mailer wordt niet ondersteund.'; $PHPMAILER_LANG['mailer_not_supported'] = ' mailer wordt niet ondersteund.';
$PHPMAILER_LANG['provide_address'] = 'Er moet minstens één ontvanger worden opgegeven.'; $PHPMAILER_LANG['provide_address'] = 'Er moet minstens één ontvanger worden opgegeven.';
$PHPMAILER_LANG['recipients_failed'] = 'SMTP-fout: de volgende ontvangers zijn mislukt: '; $PHPMAILER_LANG['recipients_failed'] = 'SMTP-fout: de volgende ontvangers zijn mislukt: ';
$PHPMAILER_LANG['signing'] = 'Signeerfout: '; $PHPMAILER_LANG['signing'] = 'Signeerfout: ';
$PHPMAILER_LANG['smtp_code'] = 'SMTP code: ';
$PHPMAILER_LANG['smtp_code_ex'] = 'Aanvullende SMTP informatie: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Verbinding mislukt.'; $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Verbinding mislukt.';
$PHPMAILER_LANG['smtp_detail'] = 'Detail: ';
$PHPMAILER_LANG['smtp_error'] = 'SMTP-serverfout: '; $PHPMAILER_LANG['smtp_error'] = 'SMTP-serverfout: ';
$PHPMAILER_LANG['variable_set'] = 'Kan de volgende variabele niet instellen of resetten: '; $PHPMAILER_LANG['variable_set'] = 'Kan de volgende variabele niet instellen of resetten: ';
$PHPMAILER_LANG['extension_missing'] = 'Extensie afwezig: ';

View File

@ -1,35 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/8.5/phpunit.xsd"
backupGlobals="true"
bootstrap="vendor/autoload.php"
verbose="true"
colors="true"
forceCoversAnnotation="false"
>
<testsuites>
<testsuite name="PHPMailerTests">
<directory>./test/</directory>
</testsuite>
</testsuites>
<listeners>
<listener class="PHPMailer\Test\DebugLogTestListener" />
</listeners>
<groups>
<exclude>
<group>languages</group>
<group>pop3</group>
</exclude>
</groups>
<filter>
<whitelist addUncoveredFilesFromWhitelist="true">
<directory suffix=".php">./src</directory>
</whitelist>
</filter>
<logging>
<log type="coverage-text" target="php://stdout" showUncoveredFiles="true"/>
<log type="coverage-clover" target="build/logs/clover.xml"/>
<log type="junit" target="build/logs/junit.xml"/>
</logging>
</phpunit>

View File

@ -35,6 +35,6 @@ class Exception extends \Exception
*/ */
public function errorMessage() public function errorMessage()
{ {
return '<strong>' . htmlspecialchars($this->getMessage()) . "</strong><br />\n"; return '<strong>' . htmlspecialchars($this->getMessage(), ENT_COMPAT | ENT_HTML401) . "</strong><br />\n";
} }
} }

View File

@ -103,14 +103,14 @@ class PHPMailer
* *
* @var string * @var string
*/ */
public $From = 'root@localhost'; public $From = '';
/** /**
* The From name of the message. * The From name of the message.
* *
* @var string * @var string
*/ */
public $FromName = 'Root User'; public $FromName = '';
/** /**
* The envelope sender of the message. * The envelope sender of the message.
@ -689,7 +689,7 @@ class PHPMailer
protected $boundary = []; protected $boundary = [];
/** /**
* The array of available languages. * The array of available text strings for the current language.
* *
* @var array * @var array
*/ */
@ -750,7 +750,7 @@ class PHPMailer
* *
* @var string * @var string
*/ */
const VERSION = '6.5.0'; const VERSION = '6.5.1';
/** /**
* Error severity: message only, continue processing. * Error severity: message only, continue processing.
@ -1188,25 +1188,33 @@ class PHPMailer
* *
* @return array * @return array
*/ */
public static function parseAddresses($addrstr, $useimap = true) public static function parseAddresses($addrstr, $useimap = true, $charset = self::CHARSET_ISO88591)
{ {
$addresses = []; $addresses = [];
if ($useimap && function_exists('imap_rfc822_parse_adrlist')) { if ($useimap && function_exists('imap_rfc822_parse_adrlist')) {
//Use this built-in parser if it's available //Use this built-in parser if it's available
$list = imap_rfc822_parse_adrlist($addrstr, ''); $list = imap_rfc822_parse_adrlist($addrstr, '');
// Clear any potential IMAP errors to get rid of notices being thrown at end of script.
imap_errors();
foreach ($list as $address) { foreach ($list as $address) {
if ( if (
('.SYNTAX-ERROR.' !== $address->host) && static::validateAddress( '.SYNTAX-ERROR.' !== $address->host &&
$address->mailbox . '@' . $address->host static::validateAddress($address->mailbox . '@' . $address->host)
)
) { ) {
//Decode the name part if it's present and encoded //Decode the name part if it's present and encoded
if ( if (
property_exists($address, 'personal') && property_exists($address, 'personal') &&
extension_loaded('mbstring') && //Check for a Mbstring constant rather than using extension_loaded, which is sometimes disabled
preg_match('/^=\?.*\?=$/', $address->personal) defined('MB_CASE_UPPER') &&
preg_match('/^=\?.*\?=$/s', $address->personal)
) { ) {
$origCharset = mb_internal_encoding();
mb_internal_encoding($charset);
//Undo any RFC2047-encoded spaces-as-underscores
$address->personal = str_replace('_', '=20', $address->personal);
//Decode the name
$address->personal = mb_decode_mimeheader($address->personal); $address->personal = mb_decode_mimeheader($address->personal);
mb_internal_encoding($origCharset);
} }
$addresses[] = [ $addresses[] = [
@ -1234,9 +1242,16 @@ class PHPMailer
$email = trim(str_replace('>', '', $email)); $email = trim(str_replace('>', '', $email));
$name = trim($name); $name = trim($name);
if (static::validateAddress($email)) { if (static::validateAddress($email)) {
//Check for a Mbstring constant rather than using extension_loaded, which is sometimes disabled
//If this name is encoded, decode it //If this name is encoded, decode it
if (preg_match('/^=\?.*\?=$/', $name)) { if (defined('MB_CASE_UPPER') && preg_match('/^=\?.*\?=$/s', $name)) {
$origCharset = mb_internal_encoding();
mb_internal_encoding($charset);
//Undo any RFC2047-encoded spaces-as-underscores
$name = str_replace('_', '=20', $name);
//Decode the name
$name = mb_decode_mimeheader($name); $name = mb_decode_mimeheader($name);
mb_internal_encoding($origCharset);
} }
$addresses[] = [ $addresses[] = [
//Remove any surrounding quotes and spaces from the name //Remove any surrounding quotes and spaces from the name
@ -1508,12 +1523,7 @@ class PHPMailer
&& ini_get('mail.add_x_header') === '1' && ini_get('mail.add_x_header') === '1'
&& stripos(PHP_OS, 'WIN') === 0 && stripos(PHP_OS, 'WIN') === 0
) { ) {
trigger_error( trigger_error($this->lang('buggy_php'), E_USER_WARNING);
'Your version of PHP is affected by a bug that may result in corrupted messages.' .
' To fix it, switch to sending using SMTP, disable the mail.add_x_header option in' .
' your php.ini, switch to MacOS or Linux, or upgrade your PHP to version 7.0.17+ or 7.1.3+.',
E_USER_WARNING
);
} }
try { try {
@ -1724,7 +1734,7 @@ class PHPMailer
fwrite($mail, $header); fwrite($mail, $header);
fwrite($mail, $body); fwrite($mail, $body);
$result = pclose($mail); $result = pclose($mail);
$addrinfo = static::parseAddresses($toAddr); $addrinfo = static::parseAddresses($toAddr, true, $this->charSet);
$this->doCallback( $this->doCallback(
($result === 0), ($result === 0),
[[$addrinfo['address'], $addrinfo['name']]], [[$addrinfo['address'], $addrinfo['name']]],
@ -1884,7 +1894,7 @@ class PHPMailer
if ($this->SingleTo && count($toArr) > 1) { if ($this->SingleTo && count($toArr) > 1) {
foreach ($toArr as $toAddr) { foreach ($toArr as $toAddr) {
$result = $this->mailPassthru($toAddr, $this->Subject, $body, $header, $params); $result = $this->mailPassthru($toAddr, $this->Subject, $body, $header, $params);
$addrinfo = static::parseAddresses($toAddr); $addrinfo = static::parseAddresses($toAddr, true, $this->charSet);
$this->doCallback( $this->doCallback(
$result, $result,
[[$addrinfo['address'], $addrinfo['name']]], [[$addrinfo['address'], $addrinfo['name']]],
@ -2181,14 +2191,15 @@ class PHPMailer
/** /**
* Set the language for error messages. * Set the language for error messages.
* Returns false if it cannot load the language file.
* The default language is English. * The default language is English.
* *
* @param string $langcode ISO 639-1 2-character language code (e.g. French is "fr") * @param string $langcode ISO 639-1 2-character language code (e.g. French is "fr")
* Optionally, the language code can be enhanced with a 4-character
* script annotation and/or a 2-character country annotation.
* @param string $lang_path Path to the language file directory, with trailing separator (slash).D * @param string $lang_path Path to the language file directory, with trailing separator (slash).D
* Do not set this from user input! * Do not set this from user input!
* *
* @return bool * @return bool Returns true if the requested language was loaded, false otherwise.
*/ */
public function setLanguage($langcode = 'en', $lang_path = '') public function setLanguage($langcode = 'en', $lang_path = '')
{ {
@ -2211,44 +2222,77 @@ class PHPMailer
//Define full set of translatable strings in English //Define full set of translatable strings in English
$PHPMAILER_LANG = [ $PHPMAILER_LANG = [
'authenticate' => 'SMTP Error: Could not authenticate.', 'authenticate' => 'SMTP Error: Could not authenticate.',
'buggy_php' => 'Your version of PHP is affected by a bug that may result in corrupted messages.' .
' To fix it, switch to sending using SMTP, disable the mail.add_x_header option in' .
' your php.ini, switch to MacOS or Linux, or upgrade your PHP to version 7.0.17+ or 7.1.3+.',
'connect_host' => 'SMTP Error: Could not connect to SMTP host.', 'connect_host' => 'SMTP Error: Could not connect to SMTP host.',
'data_not_accepted' => 'SMTP Error: data not accepted.', 'data_not_accepted' => 'SMTP Error: data not accepted.',
'empty_message' => 'Message body empty', 'empty_message' => 'Message body empty',
'encoding' => 'Unknown encoding: ', 'encoding' => 'Unknown encoding: ',
'execute' => 'Could not execute: ', 'execute' => 'Could not execute: ',
'extension_missing' => 'Extension missing: ',
'file_access' => 'Could not access file: ', 'file_access' => 'Could not access file: ',
'file_open' => 'File Error: Could not open file: ', 'file_open' => 'File Error: Could not open file: ',
'from_failed' => 'The following From address failed: ', 'from_failed' => 'The following From address failed: ',
'instantiate' => 'Could not instantiate mail function.', 'instantiate' => 'Could not instantiate mail function.',
'invalid_address' => 'Invalid address: ', 'invalid_address' => 'Invalid address: ',
'invalid_header' => 'Invalid header name or value',
'invalid_hostentry' => 'Invalid hostentry: ', 'invalid_hostentry' => 'Invalid hostentry: ',
'invalid_host' => 'Invalid host: ', 'invalid_host' => 'Invalid host: ',
'mailer_not_supported' => ' mailer is not supported.', 'mailer_not_supported' => ' mailer is not supported.',
'provide_address' => 'You must provide at least one recipient email address.', 'provide_address' => 'You must provide at least one recipient email address.',
'recipients_failed' => 'SMTP Error: The following recipients failed: ', 'recipients_failed' => 'SMTP Error: The following recipients failed: ',
'signing' => 'Signing Error: ', 'signing' => 'Signing Error: ',
'smtp_code' => 'SMTP code: ',
'smtp_code_ex' => 'Additional SMTP info: ',
'smtp_connect_failed' => 'SMTP connect() failed.', 'smtp_connect_failed' => 'SMTP connect() failed.',
'smtp_detail' => 'Detail: ',
'smtp_error' => 'SMTP server error: ', 'smtp_error' => 'SMTP server error: ',
'variable_set' => 'Cannot set or reset variable: ', 'variable_set' => 'Cannot set or reset variable: ',
'extension_missing' => 'Extension missing: ',
]; ];
if (empty($lang_path)) { if (empty($lang_path)) {
//Calculate an absolute path so it can work if CWD is not here //Calculate an absolute path so it can work if CWD is not here
$lang_path = dirname(__DIR__) . DIRECTORY_SEPARATOR . 'language' . DIRECTORY_SEPARATOR; $lang_path = dirname(__DIR__) . DIRECTORY_SEPARATOR . 'language' . DIRECTORY_SEPARATOR;
} }
//Validate $langcode //Validate $langcode
if (!preg_match('/^[a-z]{2}(?:_[a-zA-Z]{2})?$/', $langcode)) { $foundlang = true;
$langcode = strtolower($langcode);
if (
!preg_match('/^(?P<lang>[a-z]{2})(?P<script>_[a-z]{4})?(?P<country>_[a-z]{2})?$/', $langcode, $matches)
&& $langcode !== 'en'
) {
$foundlang = false;
$langcode = 'en'; $langcode = 'en';
} }
$foundlang = true;
$lang_file = $lang_path . 'phpmailer.lang-' . $langcode . '.php';
//There is no English translation file //There is no English translation file
if ('en' !== $langcode) { if ('en' !== $langcode) {
//Make sure language file path is readable $langcodes = [];
if (!static::fileIsAccessible($lang_file)) { if (!empty($matches['script']) && !empty($matches['country'])) {
$langcodes[] = $matches['lang'] . $matches['script'] . $matches['country'];
}
if (!empty($matches['country'])) {
$langcodes[] = $matches['lang'] . $matches['country'];
}
if (!empty($matches['script'])) {
$langcodes[] = $matches['lang'] . $matches['script'];
}
$langcodes[] = $matches['lang'];
//Try and find a readable language file for the requested language.
$foundFile = false;
foreach ($langcodes as $code) {
$lang_file = $lang_path . 'phpmailer.lang-' . $code . '.php';
if (static::fileIsAccessible($lang_file)) {
$foundFile = true;
break;
}
}
if ($foundFile === false) {
$foundlang = false; $foundlang = false;
} else { } else {
//$foundlang = include $lang_file;
$lines = file($lang_file); $lines = file($lang_file);
foreach ($lines as $line) { foreach ($lines as $line) {
//Translation file lines look like this: //Translation file lines look like this:
@ -2283,6 +2327,10 @@ class PHPMailer
*/ */
public function getTranslations() public function getTranslations()
{ {
if (empty($this->language)) {
$this->setLanguage(); // Set the default language.
}
return $this->language; return $this->language;
} }
@ -2551,7 +2599,17 @@ class PHPMailer
//Only allow a custom message ID if it conforms to RFC 5322 section 3.6.4 //Only allow a custom message ID if it conforms to RFC 5322 section 3.6.4
//https://tools.ietf.org/html/rfc5322#section-3.6.4 //https://tools.ietf.org/html/rfc5322#section-3.6.4
if ('' !== $this->MessageID && preg_match('/^<.*@.*>$/', $this->MessageID)) { if (
'' !== $this->MessageID &&
preg_match(
'/^<((([a-z\d!#$%&\'*+\/=?^_`{|}~-]+(\.[a-z\d!#$%&\'*+\/=?^_`{|}~-]+)*)' .
'|("(([\x01-\x08\x0B\x0C\x0E-\x1F\x7F]|[\x21\x23-\x5B\x5D-\x7E])' .
'|(\\[\x01-\x09\x0B\x0C\x0E-\x7F]))*"))@(([a-z\d!#$%&\'*+\/=?^_`{|}~-]+' .
'(\.[a-z\d!#$%&\'*+\/=?^_`{|}~-]+)*)|(\[(([\x01-\x08\x0B\x0C\x0E-\x1F\x7F]' .
'|[\x21-\x5A\x5E-\x7E])|(\\[\x01-\x09\x0B\x0C\x0E-\x7F]))*\])))>$/Di',
$this->MessageID
)
) {
$this->lastMessageID = $this->MessageID; $this->lastMessageID = $this->MessageID;
} else { } else {
$this->lastMessageID = sprintf('<%s@%s>', $this->uniqueid, $this->serverHostname()); $this->lastMessageID = sprintf('<%s@%s>', $this->uniqueid, $this->serverHostname());
@ -3935,13 +3993,13 @@ class PHPMailer
if (!empty($lasterror['error'])) { if (!empty($lasterror['error'])) {
$msg .= $this->lang('smtp_error') . $lasterror['error']; $msg .= $this->lang('smtp_error') . $lasterror['error'];
if (!empty($lasterror['detail'])) { if (!empty($lasterror['detail'])) {
$msg .= ' Detail: ' . $lasterror['detail']; $msg .= ' ' . $this->lang('smtp_detail') . $lasterror['detail'];
} }
if (!empty($lasterror['smtp_code'])) { if (!empty($lasterror['smtp_code'])) {
$msg .= ' SMTP code: ' . $lasterror['smtp_code']; $msg .= ' ' . $this->lang('smtp_code') . $lasterror['smtp_code'];
} }
if (!empty($lasterror['smtp_code_ex'])) { if (!empty($lasterror['smtp_code_ex'])) {
$msg .= ' Additional SMTP info: ' . $lasterror['smtp_code_ex']; $msg .= ' ' . $this->lang('smtp_code_ex') . $lasterror['smtp_code_ex'];
} }
} }
} }
@ -4002,7 +4060,7 @@ class PHPMailer
empty($host) empty($host)
|| !is_string($host) || !is_string($host)
|| strlen($host) > 256 || strlen($host) > 256
|| !preg_match('/^([a-zA-Z\d.-]*|\[[a-fA-F\d:]+])$/', $host) || !preg_match('/^([a-zA-Z\d.-]*|\[[a-fA-F\d:]+\])$/', $host)
) { ) {
return false; return false;
} }
@ -4079,11 +4137,11 @@ class PHPMailer
list($name, $value) = explode(':', $name, 2); list($name, $value) = explode(':', $name, 2);
} }
$name = trim($name); $name = trim($name);
$value = trim($value); $value = (null === $value) ? '' : trim($value);
//Ensure name is not empty, and that neither name nor value contain line breaks //Ensure name is not empty, and that neither name nor value contain line breaks
if (empty($name) || strpbrk($name . $value, "\r\n") !== false) { if (empty($name) || strpbrk($name . $value, "\r\n") !== false) {
if ($this->exceptions) { if ($this->exceptions) {
throw new Exception('Invalid header name or value'); throw new Exception($this->lang('invalid_header'));
} }
return false; return false;
@ -4237,7 +4295,8 @@ class PHPMailer
* *
* @param string $html The HTML text to convert * @param string $html The HTML text to convert
* @param bool|callable $advanced Any boolean value to use the internal converter, * @param bool|callable $advanced Any boolean value to use the internal converter,
* or provide your own callable for custom conversion * or provide your own callable for custom conversion.
* *Never* pass user-supplied data into this parameter
* *
* @return string * @return string
*/ */

View File

@ -46,7 +46,7 @@ class POP3
* *
* @var string * @var string
*/ */
const VERSION = '6.5.0'; const VERSION = '6.5.1';
/** /**
* Default POP3 port number. * Default POP3 port number.

View File

@ -35,7 +35,7 @@ class SMTP
* *
* @var string * @var string
*/ */
const VERSION = '6.5.0'; const VERSION = '6.5.1';
/** /**
* SMTP line break constant. * SMTP line break constant.

10
vendor/services.php vendored
View File

@ -1,9 +1,9 @@
<?php <?php
// This file is automatically generated at:2021-08-04 18:41:10 // This file is automatically generated at:2021-11-02 14:10:33
declare (strict_types = 1); declare (strict_types = 1);
return array ( return array (
0 => 'think\\captcha\\CaptchaService', 0 => 'taoser\\addons\\Service',
1 => 'think\\app\\Service', 1 => 'think\\captcha\\CaptchaService',
2 => 'think\\trace\\Service', 2 => 'think\\app\\Service',
3 => 'think\\addons\\Service', 3 => 'think\\trace\\Service',
); );

View File

@ -214,8 +214,13 @@ class ExceptionCaster
if (file_exists($f['file']) && 0 <= self::$srcContext) { if (file_exists($f['file']) && 0 <= self::$srcContext) {
if (!empty($f['class']) && (is_subclass_of($f['class'], 'Twig\Template') || is_subclass_of($f['class'], 'Twig_Template')) && method_exists($f['class'], 'getDebugInfo')) { if (!empty($f['class']) && (is_subclass_of($f['class'], 'Twig\Template') || is_subclass_of($f['class'], 'Twig_Template')) && method_exists($f['class'], 'getDebugInfo')) {
$template = $f['object'] ?? unserialize(sprintf('O:%d:"%s":0:{}', \strlen($f['class']), $f['class'])); $template = null;
if (isset($f['object'])) {
$template = $f['object'];
} elseif ((new \ReflectionClass($f['class']))->isInstantiable()) {
$template = unserialize(sprintf('O:%d:"%s":0:{}', \strlen($f['class']), $f['class']));
}
if (null !== $template) {
$ellipsis = 0; $ellipsis = 0;
$templateSrc = method_exists($template, 'getSourceContext') ? $template->getSourceContext()->getCode() : (method_exists($template, 'getSource') ? $template->getSource() : ''); $templateSrc = method_exists($template, 'getSourceContext') ? $template->getSourceContext()->getCode() : (method_exists($template, 'getSource') ? $template->getSource() : '');
$templateInfo = $template->getDebugInfo(); $templateInfo = $template->getDebugInfo();
@ -229,6 +234,7 @@ class ExceptionCaster
} }
} }
} }
}
if ($srcKey == $f['file']) { if ($srcKey == $f['file']) {
$src = self::extractSource(file_get_contents($f['file']), $f['line'], self::$srcContext, 'php', $f['file'], $f); $src = self::extractSource(file_get_contents($f['file']), $f['line'], self::$srcContext, 'php', $f['file'], $f);
$srcKey .= ':'.$f['line']; $srcKey .= ':'.$f['line'];

View File

@ -356,6 +356,8 @@ class ReflectionCaster
$signature .= 10 > \strlen($v) && !str_contains($v, '\\') ? "'{$v}'" : "'…".\strlen($v)."'"; $signature .= 10 > \strlen($v) && !str_contains($v, '\\') ? "'{$v}'" : "'…".\strlen($v)."'";
} elseif (\is_bool($v)) { } elseif (\is_bool($v)) {
$signature .= $v ? 'true' : 'false'; $signature .= $v ? 'true' : 'false';
} elseif (\is_object($v)) {
$signature .= 'new '.substr(strrchr('\\'.get_debug_type($v), '\\'), 1);
} else { } else {
$signature .= $v; $signature .= $v;
} }

View File

@ -44,6 +44,22 @@ class XmlReaderCaster
public static function castXmlReader(\XMLReader $reader, array $a, Stub $stub, $isNested) public static function castXmlReader(\XMLReader $reader, array $a, Stub $stub, $isNested)
{ {
try {
$properties = [
'LOADDTD' => @$reader->getParserProperty(\XMLReader::LOADDTD),
'DEFAULTATTRS' => @$reader->getParserProperty(\XMLReader::DEFAULTATTRS),
'VALIDATE' => @$reader->getParserProperty(\XMLReader::VALIDATE),
'SUBST_ENTITIES' => @$reader->getParserProperty(\XMLReader::SUBST_ENTITIES),
];
} catch (\Error $e) {
$properties = [
'LOADDTD' => false,
'DEFAULTATTRS' => false,
'VALIDATE' => false,
'SUBST_ENTITIES' => false,
];
}
$props = Caster::PREFIX_VIRTUAL.'parserProperties'; $props = Caster::PREFIX_VIRTUAL.'parserProperties';
$info = [ $info = [
'localName' => $reader->localName, 'localName' => $reader->localName,
@ -57,12 +73,7 @@ class XmlReaderCaster
'value' => $reader->value, 'value' => $reader->value,
'namespaceURI' => $reader->namespaceURI, 'namespaceURI' => $reader->namespaceURI,
'baseURI' => $reader->baseURI ? new LinkStub($reader->baseURI) : $reader->baseURI, 'baseURI' => $reader->baseURI ? new LinkStub($reader->baseURI) : $reader->baseURI,
$props => [ $props => $properties,
'LOADDTD' => $reader->getParserProperty(\XMLReader::LOADDTD),
'DEFAULTATTRS' => $reader->getParserProperty(\XMLReader::DEFAULTATTRS),
'VALIDATE' => $reader->getParserProperty(\XMLReader::VALIDATE),
'SUBST_ENTITIES' => $reader->getParserProperty(\XMLReader::SUBST_ENTITIES),
],
]; ];
if ($info[$props] = Caster::filter($info[$props], Caster::EXCLUDE_EMPTY, [], $count)) { if ($info[$props] = Caster::filter($info[$props], Caster::EXCLUDE_EMPTY, [], $count)) {

View File

@ -111,6 +111,7 @@ class Data implements \ArrayAccess, \Countable, \IteratorAggregate
/** /**
* @return int * @return int
*/ */
#[\ReturnTypeWillChange]
public function count() public function count()
{ {
return \count($this->getValue()); return \count($this->getValue());
@ -119,6 +120,7 @@ class Data implements \ArrayAccess, \Countable, \IteratorAggregate
/** /**
* @return \Traversable * @return \Traversable
*/ */
#[\ReturnTypeWillChange]
public function getIterator() public function getIterator()
{ {
if (!\is_array($value = $this->getValue())) { if (!\is_array($value = $this->getValue())) {
@ -150,6 +152,7 @@ class Data implements \ArrayAccess, \Countable, \IteratorAggregate
/** /**
* @return bool * @return bool
*/ */
#[\ReturnTypeWillChange]
public function offsetExists($key) public function offsetExists($key)
{ {
return $this->__isset($key); return $this->__isset($key);
@ -158,6 +161,7 @@ class Data implements \ArrayAccess, \Countable, \IteratorAggregate
/** /**
* @return mixed * @return mixed
*/ */
#[\ReturnTypeWillChange]
public function offsetGet($key) public function offsetGet($key)
{ {
return $this->__get($key); return $this->__get($key);
@ -166,6 +170,7 @@ class Data implements \ArrayAccess, \Countable, \IteratorAggregate
/** /**
* @return void * @return void
*/ */
#[\ReturnTypeWillChange]
public function offsetSet($key, $value) public function offsetSet($key, $value)
{ {
throw new \BadMethodCallException(self::class.' objects are immutable.'); throw new \BadMethodCallException(self::class.' objects are immutable.');
@ -174,6 +179,7 @@ class Data implements \ArrayAccess, \Countable, \IteratorAggregate
/** /**
* @return void * @return void
*/ */
#[\ReturnTypeWillChange]
public function offsetUnset($key) public function offsetUnset($key)
{ {
throw new \BadMethodCallException(self::class.' objects are immutable.'); throw new \BadMethodCallException(self::class.' objects are immutable.');

View File

@ -82,29 +82,39 @@ class VarCloner extends AbstractCloner
// $v is the original value or a stub object in case of hard references // $v is the original value or a stub object in case of hard references
if (\PHP_VERSION_ID >= 70400) { if (\PHP_VERSION_ID >= 70400) {
$zvalIsRef = null !== \ReflectionReference::fromArrayElement($vals, $k); $zvalRef = ($r = \ReflectionReference::fromArrayElement($vals, $k)) ? $r->getId() : null;
} else { } else {
$refs[$k] = $cookie; $refs[$k] = $cookie;
$zvalIsRef = $vals[$k] === $cookie; $zvalRef = $vals[$k] === $cookie;
} }
if ($zvalIsRef) { if ($zvalRef) {
$vals[$k] = &$stub; // Break hard references to make $queue completely $vals[$k] = &$stub; // Break hard references to make $queue completely
unset($stub); // independent from the original structure unset($stub); // independent from the original structure
if ($v instanceof Stub && isset($hardRefs[spl_object_id($v)])) { if (\PHP_VERSION_ID >= 70400 ? null !== $vals[$k] = $hardRefs[$zvalRef] ?? null : $v instanceof Stub && isset($hardRefs[spl_object_id($v)])) {
$vals[$k] = $refs[$k] = $v; if (\PHP_VERSION_ID >= 70400) {
$v = $vals[$k];
} else {
$refs[$k] = $vals[$k] = $v;
}
if ($v->value instanceof Stub && (Stub::TYPE_OBJECT === $v->value->type || Stub::TYPE_RESOURCE === $v->value->type)) { if ($v->value instanceof Stub && (Stub::TYPE_OBJECT === $v->value->type || Stub::TYPE_RESOURCE === $v->value->type)) {
++$v->value->refCount; ++$v->value->refCount;
} }
++$v->refCount; ++$v->refCount;
continue; continue;
} }
$refs[$k] = $vals[$k] = new Stub(); $vals[$k] = new Stub();
$refs[$k]->value = $v; $vals[$k]->value = $v;
$vals[$k]->handle = ++$refsCounter;
if (\PHP_VERSION_ID >= 70400) {
$hardRefs[$zvalRef] = $vals[$k];
} else {
$refs[$k] = $vals[$k];
$h = spl_object_id($refs[$k]); $h = spl_object_id($refs[$k]);
$hardRefs[$h] = &$refs[$k]; $hardRefs[$h] = &$refs[$k];
$values[$h] = $v; $values[$h] = $v;
$vals[$k]->handle = ++$refsCounter; }
} }
// Create $stub when the original value $v can not be used directly // Create $stub when the original value $v can not be used directly
// If $v is a nested structure, put that structure in array $a // If $v is a nested structure, put that structure in array $a
@ -163,12 +173,17 @@ class VarCloner extends AbstractCloner
unset($v[$gid]); unset($v[$gid]);
$a = []; $a = [];
foreach ($v as $gk => &$gv) { foreach ($v as $gk => &$gv) {
if ($v === $gv) { if ($v === $gv && (\PHP_VERSION_ID < 70400 || !isset($hardRefs[\ReflectionReference::fromArrayElement($v, $gk)->getId()]))) {
unset($v); unset($v);
$v = new Stub(); $v = new Stub();
$v->value = [$v->cut = \count($gv), Stub::TYPE_ARRAY => 0]; $v->value = [$v->cut = \count($gv), Stub::TYPE_ARRAY => 0];
$v->handle = -1; $v->handle = -1;
if (\PHP_VERSION_ID >= 70400) {
$gv = &$a[$gk];
$hardRefs[\ReflectionReference::fromArrayElement($a, $gk)->getId()] = &$gv;
} else {
$gv = &$hardRefs[spl_object_id($v)]; $gv = &$hardRefs[spl_object_id($v)];
}
$gv = $v; $gv = $v;
} }
@ -270,10 +285,12 @@ class VarCloner extends AbstractCloner
} }
} }
if ($zvalIsRef) { if (!$zvalRef) {
$refs[$k]->value = $stub;
} else {
$vals[$k] = $stub; $vals[$k] = $stub;
} elseif (\PHP_VERSION_ID >= 70400) {
$hardRefs[$zvalRef]->value = $stub;
} else {
$refs[$k]->value = $stub;
} }
} }

View File

@ -3,7 +3,7 @@ VarDumper Component
The VarDumper component provides mechanisms for walking through any arbitrary The VarDumper component provides mechanisms for walking through any arbitrary
PHP variable. It provides a better `dump()` function that you can use instead PHP variable. It provides a better `dump()` function that you can use instead
of `var_dump`. of `var_dump()`.
Resources Resources
--------- ---------

View File

@ -2,7 +2,7 @@
The ThinkPHP 6 Addons Package The ThinkPHP 6 Addons Package
## 安装 ## 安装
> composer require zzstudio/think-addons > composer require taoser/think-addons
## 配置 ## 配置
@ -272,3 +272,8 @@ www WEB部署目录或者子目录
├─README.md README 文件 ├─README.md README 文件
├─think 命令行入口文件 ├─think 命令行入口文件
``` ```
基于zzstudio修改版think-addons
The ThinkPHP 6 Addons Package
感谢 zzstudio/think-addons

View File

@ -1,11 +1,11 @@
{ {
"name": "zz-studio/think-addons", "name": "taoser/think-addons",
"description": "The ThinkPHP6 Addons Package", "description": "The ThinkPHP6 Addons Package",
"license": "Apache-2.0", "license": "mit",
"authors": [ "authors": [
{ {
"name": "byron", "name": "taoler",
"email": "xiaobo.sun@qq.com" "email": "changlin_zhao@qq.com"
} }
], ],
"require": { "require": {
@ -16,7 +16,7 @@
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {
"think\\": "src/" "taoser\\": "src/"
}, },
"files": [ "files": [
"src/helper.php" "src/helper.php"
@ -25,7 +25,7 @@
"extra": { "extra": {
"think": { "think": {
"services": [ "services": [
"think\\addons\\Service" "taoser\\addons\\Service"
], ],
"config":{ "config":{
"addons": "src/config.php" "addons": "src/config.php"

View File

@ -1,26 +1,8 @@
<?php <?php
/**
* +----------------------------------------------------------------------
* | think-addons [thinkphp6]
* +----------------------------------------------------------------------
* .--, .--, | FILE: Addons.php
* ( ( \.---./ ) ) | AUTHOR: byron
* '.__/o o\__.' | EMAIL: xiaobo.sun@qq.com
* {= ^ =} | QQ: 150093589
* / \ | DATETIME: 2019/11/5 14:47
* // \\ |
* //| . |\\ |
* "'\ /'"_.-~^`'-. |
* \ _ /--' ` |
* ___)( )(___ |-----------------------------------------
* (((__) (__))) | 高山仰止,景行行止.虽不能至,心向往之。
* +----------------------------------------------------------------------
* | Copyright (c) 2019 http://www.zzstudio.net All rights reserved.
* +----------------------------------------------------------------------
*/
declare(strict_types=1); declare(strict_types=1);
namespace think; namespace taoser;
use think\App; use think\App;
use think\helper\Str; use think\helper\Str;
@ -186,6 +168,23 @@ abstract class Addons
return $config; return $config;
} }
/**
* 设置插件信息数据
* @param $name
* @param array $value
* @return array
*/
final public function setInfo($name = '', $value = [])
{
if (empty($name)) {
$name = $this->getName();
}
$info = $this->getInfo($name);
$info = array_merge($info, $value);
Config::set($info,$name);
return $info;
}
//必须实现安装 //必须实现安装
abstract public function install(); abstract public function install();

View File

@ -1,26 +1,8 @@
<?php <?php
/**
* +----------------------------------------------------------------------
* | think-addons [thinkphp6]
* +----------------------------------------------------------------------
* .--, .--, | FILE: Route.php
* ( ( \.---./ ) ) | AUTHOR: byron
* '.__/o o\__.' | EMAIL: xiaobo.sun@qq.com
* {= ^ =} | QQ: 150093589
* / \ | DATETIME: 2019/11/5 09:57
* // \\ |
* //| . |\\ |
* "'\ /'"_.-~^`'-. |
* \ _ /--' ` |
* ___)( )(___ |-----------------------------------------
* (((__) (__))) | 高山仰止,景行行止.虽不能至,心向往之。
* +----------------------------------------------------------------------
* | Copyright (c) 2019 http://www.zzstudio.net All rights reserved.
* +----------------------------------------------------------------------
*/
declare(strict_types=1); declare(strict_types=1);
namespace think\addons; namespace taoser\addons;
use think\helper\Str; use think\helper\Str;
use think\facade\Event; use think\facade\Event;

View File

@ -1,7 +1,7 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
namespace think\addons; namespace taoser\addons;
use think\Route; use think\Route;
use think\helper\Str; use think\helper\Str;
@ -9,7 +9,7 @@ use think\facade\Config;
use think\facade\Lang; use think\facade\Lang;
use think\facade\Cache; use think\facade\Cache;
use think\facade\Event; use think\facade\Event;
use think\addons\middleware\Addons; use taoser\addons\middleware\Addons;
/** /**
* 插件服务 * 插件服务
@ -25,7 +25,7 @@ class Service extends \think\Service
$this->addons_path = $this->getAddonsPath(); $this->addons_path = $this->getAddonsPath();
// 加载系统语言包 // 加载系统语言包
Lang::load([ Lang::load([
$this->app->getRootPath() . '/vendor/zzstudio/think-addons/src/lang/zh-cn.php' $this->app->getRootPath() . '/vendor/taoser/think-addons/src/lang/zh-cn.php'
]); ]);
// 自动载入插件 // 自动载入插件
$this->autoload(); $this->autoload();
@ -41,7 +41,7 @@ class Service extends \think\Service
{ {
$this->registerRoutes(function (Route $route) { $this->registerRoutes(function (Route $route) {
// 路由脚本 // 路由脚本
$execute = '\\think\\addons\\Route::execute'; $execute = '\\taoser\\addons\\Route::execute';
// 注册插件公共中间件 // 注册插件公共中间件
if (is_file($this->app->addons->getAddonsPath() . 'middleware.php')) { if (is_file($this->app->addons->getAddonsPath() . 'middleware.php')) {
@ -167,7 +167,7 @@ class Service extends \think\Service
} }
$config = Config::get('addons'); $config = Config::get('addons');
// 读取插件目录及钩子列表 // 读取插件目录及钩子列表
$base = get_class_methods("\\think\\Addons"); $base = get_class_methods("\\taoser\\Addons");
// 读取插件目录中的php文件 // 读取插件目录中的php文件
foreach (glob($this->getAddonsPath() . '*/*.php') as $addons_file) { foreach (glob($this->getAddonsPath() . '*/*.php') as $addons_file) {
// 格式化路径信息 // 格式化路径信息

View File

@ -0,0 +1,47 @@
<?php
namespace taoser\addons\command;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
use think\facade\Env;
class SendConfig extends Command
{
public function configure()
{
$this->setName('addons:config')
->setDescription('send config to config folder');
}
public function execute(Input $input, Output $output)
{
//获取默认配置文件
$content = file_get_contents(root_path() . 'vendor/taoser/think-addons/src/config.php');
$configPath = config_path() . '/';
$configFile = $configPath . 'addons.php';
//判断目录是否存在
if (!file_exists($configPath)) {
mkdir($configPath, 0755, true);
}
//判断文件是否存在
if (is_file($configFile)) {
throw new \InvalidArgumentException(sprintf('The config file "%s" already exists', $configFile));
}
if (false === file_put_contents($configFile, $content)) {
throw new \RuntimeException(sprintf('The config file "%s" could not be written to "%s"', $configFile,$configPath));
}
$output->writeln('create addons config ok');
}
}

View File

@ -0,0 +1,30 @@
<?php
declare(strict_types=1);
namespace taoser\addons\middleware;
use think\App;
class Addons
{
protected $app;
public function __construct(App $app)
{
$this->app = $app;
}
/**
* 插件中间件
* @param $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, \Closure $next)
{
hook('addon_middleware', $request);
return $next($request);
}
}

View File

@ -3,13 +3,17 @@ declare(strict_types=1);
use think\facade\Event; use think\facade\Event;
use think\facade\Route; use think\facade\Route;
use taoser\addons\Service;
use think\facade\App;
use think\facade\Config;
use think\facade\Cache;
use think\helper\{ use think\helper\{
Str, Arr Str, Arr
}; };
\think\Console::starting(function (\think\Console $console) { \think\Console::starting(function (\think\Console $console) {
$console->addCommands([ $console->addCommands([
'addons:config' => '\\think\\addons\\command\\SendConfig' 'addons:config' => '\\taoser\\addons\\command\\SendConfig'
]); ]);
}); });
@ -76,6 +80,50 @@ if (!function_exists('get_addons_info')) {
} }
} }
/**
* 设置基础配置信息
* @param string $name 插件名
* @param array $array 配置数据
* @return boolean
* @throws Exception
*/
if (!function_exists('set_addons_info')) {
function set_addons_info($name, $array)
{
$service = new Service(App::instance()); // 获取service 服务
$addons_path = $service->getAddonsPath();
// 插件列表
$file = $addons_path . $name . DIRECTORY_SEPARATOR . 'info.ini';
$addon = get_addons_instance($name);
$array = $addon->setInfo($name, $array);
$array['status'] ? $addon->enabled() : $addon->disabled();
if (!isset($array['name']) || !isset($array['title']) || !isset($array['version'])) {
throw new Exception("Failed to write plugin config");
}
$res = array();
foreach ($array as $key => $val) {
if (is_array($val)) {
$res[] = "[$key]";
foreach ($val as $k => $v)
$res[] = "$k = " . (is_numeric($v) ? $v : $v);
} else
$res[] = "$key = " . (is_numeric($val) ? $val : $val);
}
if ($handle = fopen($file, 'w')) {
fwrite($handle, implode("\n", $res) . "\n");
fclose($handle);
//清空当前配置缓存
Config::set($array, "addon_{$name}_info");
Cache::delete('addonslist');
} else {
throw new Exception("File does not have write permission");
}
return true;
}
}
if (!function_exists('get_addons_instance')) { if (!function_exists('get_addons_instance')) {
/** /**
* 获取插件的单例 * 获取插件的单例
@ -131,6 +179,45 @@ if (!function_exists('get_addons_class')) {
} }
} }
if (!function_exists('get_addons_config')) {
/**
* 获取插件的配置
* @param string $name 插件名
* @return mixed|null
*/
function get_addons_config($name)
{
$addon = get_addons_instance($name);
if (!$addon) {
return [];
}
return $addon->getConfig($name);
}
}
if (!function_exists('set_addons_config')) {
function set_addons_config($name, $array)
{
$service = new Service(App::instance()); // 获取service 服务
$addons_path = $service->getAddonsPath();
// 插件列表
$file = $addons_path . $name . DIRECTORY_SEPARATOR . 'config.php';
if (!is_writable($file)) {
throw new \Exception(lang("addons.php File does not have write permission"));
}
if ($handle = fopen($file, 'w')) {
fwrite($handle, "<?php\n\n" . "return " . var_export($array, TRUE) . ";");
fclose($handle);
} else {
throw new Exception(lang("File does not have write permission"));
}
return true;
}
}
if (!function_exists('addons_url')) { if (!function_exists('addons_url')) {
/** /**
* 插件显示内容里生成访问插件的url * 插件显示内容里生成访问插件的url

View File

@ -1,67 +0,0 @@
<?php
/**
* +----------------------------------------------------------------------
* | think-addons [基于 thinkphp6]
* +----------------------------------------------------------------------
* .--, .--, | FILE: config.php
* ( ( \.---./ ) ) | AUTHOR: byron sampson
* '.__/o o\__.' | EMAIL: xiaobo.sun@qq.com
* {= ^ =} | QQ: 150093589
* > - < | WECHAT: wx5ini99
* / \ | DATETIME: 2019/10/29
* // \\ |
* //| . |\\ |
* "'\ /'"_.-~^`'-. |
* \ _ /--' ` |
* ___)( )(___ |-----------------------------------------
* (((__) (__))) | 高山仰止,景行行止.虽不能至,心向往之。
* +----------------------------------------------------------------------
* | Copyright (c) 2019 http://www.zzstudio.net All rights reserved.
* +----------------------------------------------------------------------
*/
namespace think\addons\command;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
use think\facade\Env;
class SendConfig extends Command
{
public function configure()
{
$this->setName('addons:config')
->setDescription('send config to config folder');
}
public function execute(Input $input, Output $output)
{
//获取默认配置文件
$content = file_get_contents(root_path() . 'vendor/zzstudio/think-addons/src/config.php');
$configPath = config_path() . '/';
$configFile = $configPath . 'addons.php';
//判断目录是否存在
if (!file_exists($configPath)) {
mkdir($configPath, 0755, true);
}
//判断文件是否存在
if (is_file($configFile)) {
throw new \InvalidArgumentException(sprintf('The config file "%s" already exists', $configFile));
}
if (false === file_put_contents($configFile, $content)) {
throw new \RuntimeException(sprintf('The config file "%s" could not be written to "%s"', $configFile,$configPath));
}
$output->writeln('create addons config ok');
}
}

View File

@ -1,48 +0,0 @@
<?php
/**
* +----------------------------------------------------------------------
* | think-addons [thinkphp6]
* +----------------------------------------------------------------------
* .--, .--, | FILE: Addons.php
* ( ( \.---./ ) ) | AUTHOR: byron
* '.__/o o\__.' | EMAIL: xiaobo.sun@qq.com
* {= ^ =} | QQ: 150093589
* / \ | DATETIME: 2019/11/5 09:55
* // \\ |
* //| . |\\ |
* "'\ /'"_.-~^`'-. |
* \ _ /--' ` |
* ___)( )(___ |-----------------------------------------
* (((__) (__))) | 高山仰止,景行行止.虽不能至,心向往之。
* +----------------------------------------------------------------------
* | Copyright (c) 2019 http://www.zzstudio.net All rights reserved.
* +----------------------------------------------------------------------
*/
declare(strict_types=1);
namespace think\addons\middleware;
use think\App;
class Addons
{
protected $app;
public function __construct(App $app)
{
$this->app = $app;
}
/**
* 插件中间件
* @param $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, \Closure $next)
{
hook('addon_middleware', $request);
return $next($request);
}
}

View File

@ -20,7 +20,7 @@
{/if} {/if}
<span id="LAY_jieAdmin" data-id="{$article['id']}"></span> <span id="LAY_jieAdmin" data-id="{$article['id']}"></span>
</div> </div>
<div onclick="PhoneDown();" style="" class="detail_qrcode" id="mobile"></div> <div class="detail_qrcode layui-hide-xs" onclick="PhoneDown();" id="mobile"></div>
{//图标} {//图标}
<div class="user-questions"> <div class="user-questions">
@ -294,10 +294,10 @@ layui.use(['fly', 'face','colorpicker','plyr'], function(){
}); });
//如果你是采用模版自带的编辑器,你需要开启以下语句来解析。 //如果你是采用模版自带的编辑器,你需要开启以下语句来解析。
// $('.detail-body-wenda').each(function(){ $('.detail-body-wenda').each(function(){
// var othis = $(this), html = othis.html(); var othis = $(this), html = othis.html();
// othis.html(fly.content(html)); othis.html(fly.content(html));
// }); });
$('.detail-body').each(function(){ $('.detail-body').each(function(){
var othis = $(this), html = othis.html(); var othis = $(this), html = othis.html();

View File

@ -0,0 +1,325 @@
{extend name="public/base" /}
{block name="title"}{$article.title}-{$sysInfo.webname}{/block}
{block name="keywords"}{$article.title},{$article.tags}{/block}
{block name="description"}{$article.title},{:getArtContent($article.content)}{/block}
{block name="link"}<link rel="stylesheet" href="/static/res/css/plyr.css" charset="utf-8">{/block}
{block name="column"}<div class="layui-hide-xs">{include file="/public/column" /}</div>{/block}
{block name="content"}
<div class="layui-container">
<div class="layui-row layui-col-space15">
<div class="layui-col-md8 content detail">
<div class="fly-panel detail-box">
{//标题}
<h1 style="color:{$article.title_color};">{$article.title}
<span class="layui-hide-xs"><div onclick="PhoneDown();" style="" class="detail_qrcode" id="mobile"></div></span>
</h1>
{//图标}
<div class="fly-detail-info">
<span class="layui-badge layui-bg-green fly-detail-column">{:cookie('think_lang') == 'en-us' ? $article.cate.ename : $article.cate.catename}</span>
{if ($article.jie == 0)}
<span class="layui-badge" style="background-color: #999;">{:lang('no finished')}</span>
{else /}
<span class="layui-badge" style="background-color: #5FB878;">{:lang('finished')}</span>
{/if}
{if ($article.is_top == 1)}<span class="layui-badge layui-bg-black">{:lang('top')}</span>{/if}
{if ($article.is_hot == 1)}<span class="layui-badge layui-bg-red">{:lang('hot')}</span>{/if}
<span id="LAY_jieAdmin" data-id="{$article['id']}"></span>
<span class="fly-list-nums">
<a href="#comment"><i class="iconfont" title="{:lang('reply')}">&#xe60c;</i>{$comments->count()}</a><i class="iconfont" title="浏览">&#xe60b;</i>{$pv}
</span>
</div>
{//作者}
<div class="detail-about">
<a class="fly-avatar" href="{:url('user/home',['id'=>$article.user.id])}">
<img src="{$article.user.user_img}" alt="{$article.user.name}">
<i class="iconfont icon-renzheng" title="认证信息"></i>
</a>
<div class="fly-detail-user">
<a href="{:url('user/home',['id'=>$article.user.id])}" class="fly-link">
{if config('taoler.config.area_show') == 1}<i class="layui-badge layui-bg-green " title="">{:getAsing($article.user.area_id) ?: '无'}</i>{/if}
<cite>{$article.user.nickname ?: $article.user.name}</cite>
</a>
<span class="layui-btn layui-btn-xs guanzhu" >关注</span>
</div>
<div class="detail-hits">
<!--span style="padding-right: 10px; color: #FF7200">悬赏60飞吻</span-->
<span class="post-time" data="{$article.create_time}" style="padding-top: 5px;"></span>
</div>
</div>
<div class="detail-body photos">{$article.content|raw}</div>
{//管理}
{if (($article.upzip !== '') || session('?user_name'))}
<div class="detail-assist">
{notempty name="$article.upzip"}
<button type="button" class="layui-btn layui-btn-xs" id="zip-download"><i class="layui-icon layui-icon-download-circle"></i>{:lang('download files')}: {$article.downloads}次</button>
{/notempty}
<div class="fly-admin-box" data-id="{$article.id}">
{if ($user.auth ?? '')}
<span class="layui-btn layui-btn-xs jie-admin" type="del"><i class="layui-icon layui-icon-delete"></i></span>
{if($article.is_top == 0)}<span class="layui-btn layui-btn-xs jie-admin" type="set" field="top" rank="1"><i class="layui-icon layui-icon-top"></i></span>
{else /}<span class="layui-btn layui-btn-xs jie-admin" type="set" field="top" rank="0" style="background-color:#ccc;">{:lang('cancel topping')}</span>{/if}
{if($article.is_hot == 0)}
<span class="layui-btn layui-btn-xs jie-admin" type="set" field="hot" rank="1"><i class="layui-icon layui-icon-fire"></i></span>
{else /}
<span class="layui-btn layui-btn-xs jie-admin" type="set" field="hot" rank="0" style="background-color:#ccc;">{:lang('cancel hoting')}</span>
{/if}
{if($article.is_reply == 1)}
<span class="layui-btn layui-btn-xs jie-admin" type="set" field="reply" rank="0"><i class="layui-icon layui-icon-face-cry"></i></span>
{else /}
<span class="layui-btn layui-btn-xs jie-admin" type="set" field="reply" rank="1" style="background-color:#ccc;">{:lang('enable reply')}</span>
{/if}
<span id="color">{:lang('title color')}</span>
{/if}
{if(session('user_name')==$article.user.name || ($user.auth ?? ''))}
<span class="layui-btn layui-btn-xs jie-admin" type="edit"><a href="{:url('article/edit',['id'=>$article.id])}">{:lang('edit')}</a></span>
{/if}
</div>
</div>
{/if}
</div>
{//评论}
<div class="fly-panel detail-box" id="flyReply">
<span style="font-size:18px;">评论 {$comments->count()}</span>
<ul class="jieda" id="jieda">
{volist name="comments" id="vo" empty= ""}
<li data-id="{$vo.id}" class="jieda-daan">
<a name="item-1111111111"></a>
<div class="detail-about detail-about-reply">
<a class="fly-avatar" href="{:url('user/home',['id'=>$vo.user.id])}">
<img src="{$vo.user.user_img}" alt=" "><i class="iconfont icon-renzheng" title="认证信息"></i>
</a>
<div class="fly-detail-user">
<a href="{:url('user/home',['id'=>$vo.user.id])}" class="fly-link">
{if config('taoler.config.area_show') == 1}<i class="layui-badge layui-bg-green " title="">{:getAsing($vo.user.area_id) ?: '无'}</i>{/if}
<cite>{$vo.user.nickname ?: $vo.user.name}</cite>
</a>
{if condition="$article.user.id eq $vo.user.id"}<span>({:lang('poster')})</span>{/if}
</div>
<div class="detail-hits"><span class="post-time" data="{$vo.create_time}"></span></div>
{if $vo.cai == 1}<i class="iconfont icon-caina" title="最佳答案"></i>{/if}
</div>
<div class="detail-body jieda-body photos">{$vo.content|raw}</div>
<div class="jieda-reply">
<span class="jieda-zan {if($vo.zan != 0)}zanok{/if}" type="zan">
<i class="iconfont icon-zan"></i><em>{$vo.zan}</em>
</span>
<span type="reply"><i class="iconfont icon-svgmoban53"></i>{:lang('reply')}</span>
{//评论编辑删除采纳权限}
<div class="jieda-admin">
{if ((session('user_id') == $vo.user.id) && (getLimtTime($vo.create_time) < 2)) OR ($user.auth ?? '')}
<span type="edit">{:lang('edit')}</span>
<span type="del">{:lang('delete')}</span>
{/if}
{if ($vo.cai == 0) && ((session('user_id') == $article.user_id) OR ($user.auth ?? '')) /}<span class="jieda-accept" type="accept">{:lang('accept')}</span>{/if}
</div>
</div>
</li>
{/volist}
</ul>
<div style="text-align: center">{$comments|raw}</div>
{if condition="$article.is_reply == 1"}
<div class="layui-form layui-form-pane">
<div class="layui-form-item layui-form-text">
<a name="comment"></a>
<div class="layui-input-block">
<textarea id="L_content" name="content" required lay-verify="required" placeholder="{:lang('please input the content')}" class="layui-textarea fly-editor" style="height: 150px;"></textarea>
</div>
</div>
<div class="layui-form-item">
<input type="hidden" name="article_id" value="{$article.id}">
<input type="hidden" name="user_id" value="{:session('user_id')}">
<button class="layui-btn" lay-filter="user-comment" lay-submit>{:lang('submit comments')}</button>
</div>
</div>
{else /}
<blockquote class="layui-elem-quote layui-quote-nm layui-disabled" style="margin: 100px 0 20px; padding: 50px 20px; text-align: center; color: #999!important;">本帖已设置禁止回复</blockquote>
{/if}
</div>
</div>
<div class="layui-col-md4">
<div class="fly-panel">
<div class="fly-panel-title">{:lang('sponsor')}<span style="padding: 0 3px;">-</span>
<a href="" class="fly-link fly-joinad">{:lang('i want to join')}</a>
</div>
<div class="fly-panel-main">
{volist name="ad_comm" id="vo"}
<a href="{$vo.slid_href}" target="_blank" rel="nofollow" class="fly-zanzhu" style="background-color: {$vo.slid_color};">{$vo.slid_name}</a>
{/volist}
</div>
</div>
<dl class="fly-panel fly-list-one">
<dt class="fly-panel-title">{:lang('hot post list')}</dt>
{volist name="artHot" id="vo"}
<dd>
<a href="{:url('article/detail',['id' => $vo.id])}">{$vo.title}</a>
<span><i class="iconfont icon-pinglun1"></i> {$vo.comments_count}</span>
</dd>
{/volist}
</dl>
<div class="fly-panel" style="padding: 5px 0; text-align: center;">
{volist name="ad_art" id="vo"}
<a href="{$vo.slid_href}" target="_blank"><img src="{$vo.slid_img}" style="max-width: 100%;"></a>
{/volist}
</div>
</div>
</div>
<!--底部栏-->
<div class="site-tree-mobile-detail-bottom layui-hide-md">
<div id="LAY_jieAdmin1" data-id="{$article['id']}"></div>
</div>
</div>
{include file="public/menu" /}
{/block}
{block name="script"}
<script>
var collectionFind = "{:url('Collection/find')}",
articleJieset = "{:url('Article/jieset')}",
articleDelete = "{:url('Article/delete')}",
commentJiedaZan = "{:url('Comment/jiedaZan')}",
commentJiedaCai = "{:url('Comment/jiedaCai')}",
commentGetDa = "{:url('Comment/getDa')}",
commentUpdateDa = "{:url('Comment/updateDa')}",
commentJiedaDelete = "{:url('Comment/jiedaDelete')}",
langCollection = "{:lang('collection')}",
langCancelCollection = "{:lang('cancel collection')}";
var collection = "{:url('collection/')}";
layui.use(['fly', 'face','colorpicker','plyr'], function(){
var $ = layui.jquery
,form = layui.form
,fly = layui.fly
,colorpicker = layui.colorpicker
,plyr = layui.plyr;
var laytpl = layui.laytpl;
var uid = layui.cache.user.uid;
//tpl模板给发布时间赋值
$('div.detail-hits').children('span.post-time').each(function(){
var othis = $(this), html = othis.html();
var string = laytpl('{{ d.time }}').render({
//time: html
time: othis.attr('data')
});
var posttime = layui.util.timeAgo(string, 1);
othis.text(posttime);
//console.log(othis.attr('data'));
});
//预定义颜色项
colorpicker.render({
elem: '#color'
,color: '#393d49'
,predefine: true // 开启预定义颜色
,size: 'xs'
,done: function(color){
//改变标题颜色
$('h1').css("color", color);
var id = {$article.id};
$.ajax({
type:'post',
url:"{:url('Article/titleColor')}",
data:{id: id,title_color: color},
dataType:'json',
success:function(data){
if(data.code == 0){
layer.msg(data.msg,{icon:6,time:2000
});
} else {
layer.open({content:data.msg,icon:5,adim:6});
}
}
});
}
});
//评论需要登陆
form.on('submit(user-comment)',function (data){
var filed = data.field;
if (uid == -1) {
layer.msg('请先登陆',{icon:5,time:2000},function(){
location.href = "{:url('login/index')}";
});
} else {
$.ajax({
type: "post",
url: "{:url('article/comment')}",
data: filed,
dataType: "json",
success:function (data) {
if (data.code == 0) {
layer.msg(data.msg,{icon:6,time:2000},function () {
location.reload(true);
});
}else {
layer.open({title:'评论失败',content:data.msg,icon:5,anim:6});
}
}
});
}
return false;
});
//下载
$('#zip-download').click(function (){
var id = "{$article.id}";
$.ajax({
type:"post",
url:"{:url('article/download')}",
data:{id:id},
success:function (data) {
location.href = "{:url('article/download',['id'=>$article.id])}";
}
});
});
//如果你是采用模版自带的编辑器,你需要开启以下语句来解析。
$('.detail-body').each(function(){
var othis = $(this), html = othis.html();
othis.html(fly.content(html));
});
//加载播放器
plyr.setup();
});
//扫码阅读
$("#rdown").hover(function(){
$("#phonedl").show().stop();
},function(){
$("#phonedl").hide().stop();
});
$("#phonedl").hover(function(){
$("#phonedl").show().stop();
},function(){
$("#phonedl").hide().stop();
});
function PhoneDown(){
layer.open({
title: "扫码查阅",
skin: 'layui-layer',
content: "<img src='/qrcode/?text={$Request.domain}{:url('article/detail',['id' => $article.id])}&size=230'>"
});
}
//推送百度收录服务
(function(){
var bp = document.createElement('script');
var curProtocol = window.location.protocol.split(':')[0];
if (curProtocol === 'https') {
bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
}
else {
bp.src = 'http://push.zhanzhang.baidu.com/push.js';
}
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(bp, s);
})();
</script>
{/block}

View File

@ -0,0 +1,318 @@
{extend name="public/base" /}
{block name="title"}{$article.title}-{$sysInfo.webname}{/block}
{block name="keywords"}{$article.title},{$article.tags}{/block}
{block name="description"}{$article.title},{:getArtContent($article.content)}{/block}
{block name="link"}<link rel="stylesheet" href="/static/res/css/plyr.css" charset="utf-8">{/block}
{block name="column"}<div class="layui-hide-xs">{include file="/public/column" /}</div>{/block}
{block name="content"}
<div class="layui-container">
<div class="layui-row layui-col-space15">
<div class="layui-col-md8 content detail">
<div class="fly-panel detail-box">
{//标题}
<h1 style="color:{$article.title_color};">{$article.title}
<span class="layui-hide-xs"><div onclick="PhoneDown();" style="" class="detail_qrcode" id="mobile"></div></span>
</h1>
{//图标}
<div class="fly-detail-info">
<span class="layui-badge layui-bg-green fly-detail-column">{:cookie('think_lang') == 'en-us' ? $article.cate.ename : $article.cate.catename}</span>
{if ($article.is_top == 1)}<span class="layui-badge layui-bg-black">{:lang('top')}</span>{/if}
{if ($article.is_hot == 1)}<span class="layui-badge layui-bg-red">{:lang('hot')}</span>{/if}
<span id="LAY_jieAdmin" data-id="{$article['id']}"></span>
<span class="fly-list-nums">
<a href="#comment"><i class="iconfont" title="{:lang('reply')}">&#xe60c;</i>{$comments->count()}</a><i class="iconfont" title="浏览">&#xe60b;</i>{$pv}
</span>
</div>
{//作者}
<div class="detail-about">
<a class="fly-avatar" href="{:url('user/home',['id'=>$article.user.id])}">
<img src="{$article.user.user_img}" alt="{$article.user.name}">
<i class="iconfont icon-renzheng" title="认证信息"></i>
</a>
<div class="fly-detail-user">
<a href="{:url('user/home',['id'=>$article.user.id])}" class="fly-link">
{if config('taoler.config.area_show') == 1}<i class="layui-badge layui-bg-green " title="">{:getAsing($article.user.area_id) ?: '无'}</i>{/if}
<cite>{$article.user.nickname ?: $article.user.name}</cite>
</a>
<span class="layui-btn layui-btn-xs guanzhu" >关注</span>
</div>
<div class="detail-hits">
<!--span style="padding-right: 10px; color: #FF7200">悬赏60飞吻</span-->
<span class="post-time" data="{$article.create_time}" style="padding-top: 5px;"></span>
</div>
</div>
<div class="detail-body photos">{$article.content|raw}</div>
{//管理}
{if (($article.upzip !== '') || session('?user_name'))}
<div class="detail-assist">
{notempty name="$article.upzip"}
<button type="button" class="layui-btn layui-btn-xs" id="zip-download"><i class="layui-icon layui-icon-download-circle"></i>{:lang('download files')}: {$article.downloads}次</button>
{/notempty}
<div class="fly-admin-box" data-id="{$article.id}">
{if ($user.auth ?? '')}
<span class="layui-btn layui-btn-xs jie-admin" type="del"><i class="layui-icon layui-icon-delete"></i></span>
{if($article.is_top == 0)}<span class="layui-btn layui-btn-xs jie-admin" type="set" field="top" rank="1"><i class="layui-icon layui-icon-top"></i></span>
{else /}<span class="layui-btn layui-btn-xs jie-admin" type="set" field="top" rank="0" style="background-color:#ccc;">{:lang('cancel topping')}</span>{/if}
{if($article.is_hot == 0)}
<span class="layui-btn layui-btn-xs jie-admin" type="set" field="hot" rank="1"><i class="layui-icon layui-icon-fire"></i></span>
{else /}
<span class="layui-btn layui-btn-xs jie-admin" type="set" field="hot" rank="0" style="background-color:#ccc;">{:lang('cancel hoting')}</span>
{/if}
{if($article.is_reply == 1)}
<span class="layui-btn layui-btn-xs jie-admin" type="set" field="reply" rank="0"><i class="layui-icon layui-icon-face-cry"></i></span>
{else /}
<span class="layui-btn layui-btn-xs jie-admin" type="set" field="reply" rank="1" style="background-color:#ccc;">{:lang('enable reply')}</span>
{/if}
<span id="color">{:lang('title color')}</span>
{/if}
{if(session('user_name')==$article.user.name || ($user.auth ?? ''))}
<span class="layui-btn layui-btn-xs jie-admin" type="edit"><a href="{:url('article/edit',['id'=>$article.id])}">{:lang('edit')}</a></span>
{/if}
</div>
</div>
{/if}
</div>
{//评论}
<div class="fly-panel detail-box" id="flyReply">
<span style="font-size:18px;">评论 {$comments->count()}</span>
<ul class="jieda" id="jieda">
{volist name="comments" id="vo" empty= ""}
<li data-id="{$vo.id}" class="jieda-daan">
<a name="item-1111111111"></a>
<div class="detail-about detail-about-reply">
<a class="fly-avatar" href="{:url('user/home',['id'=>$vo.user.id])}">
<img src="{$vo.user.user_img}" alt=" "><i class="iconfont icon-renzheng" title="认证信息"></i>
</a>
<div class="fly-detail-user">
<a href="{:url('user/home',['id'=>$vo.user.id])}" class="fly-link">
{if config('taoler.config.area_show') == 1}<i class="layui-badge layui-bg-green " title="">{:getAsing($vo.user.area_id) ?: '无'}</i>{/if}
<cite>{$vo.user.nickname ?: $vo.user.name}</cite>
</a>
{if condition="$article.user.id eq $vo.user.id"}<span>({:lang('poster')})</span>{/if}
</div>
<div class="detail-hits"><span class="post-time" data="{$vo.create_time}"></span></div>
{if $vo.cai == 1}<i class="iconfont icon-caina" title="最佳答案"></i>{/if}
</div>
<div class="detail-body jieda-body photos">{$vo.content|raw}</div>
<div class="jieda-reply">
<span class="jieda-zan {if($vo.zan != 0)}zanok{/if}" type="zan">
<i class="iconfont icon-zan"></i><em>{$vo.zan}</em>
</span>
<span type="reply"><i class="iconfont icon-svgmoban53"></i>{:lang('reply')}</span>
{//评论编辑删除采纳权限}
<div class="jieda-admin">
{if ((session('user_id') == $vo.user.id) && (getLimtTime($vo.create_time) < 2)) OR ($user.auth ?? '')}
<span type="edit">{:lang('edit')}</span>
<span type="del">{:lang('delete')}</span>
{/if}
{if ($vo.cai == 0) && ((session('user_id') == $article.user_id) OR ($user.auth ?? '')) /}<span class="jieda-accept" type="accept">{:lang('accept')}</span>{/if}
</div>
</div>
</li>
{/volist}
</ul>
<div style="text-align: center">{$comments|raw}</div>
{if condition="$article.is_reply == 1"}
<div class="layui-form layui-form-pane">
<div class="layui-form-item layui-form-text">
<a name="comment"></a>
<div class="layui-input-block">
<textarea id="L_content" name="content" required lay-verify="required" placeholder="{:lang('please input the content')}" class="layui-textarea fly-editor" style="height: 150px;"></textarea>
</div>
</div>
<div class="layui-form-item">
<input type="hidden" name="article_id" value="{$article.id}">
<input type="hidden" name="user_id" value="{:session('user_id')}">
<button class="layui-btn" lay-filter="user-comment" lay-submit>{:lang('submit comments')}</button>
</div>
</div>
{else /}
<blockquote class="layui-elem-quote layui-quote-nm layui-disabled" style="margin: 100px 0 20px; padding: 50px 20px; text-align: center; color: #999!important;">本帖已设置禁止回复</blockquote>
{/if}
</div>
</div>
<div class="layui-col-md4">
<div class="fly-panel">
<div class="fly-panel-title">{:lang('sponsor')}<span style="padding: 0 3px;">-</span>
<a href="" class="fly-link fly-joinad">{:lang('i want to join')}</a>
</div>
<div class="fly-panel-main">
{volist name="ad_comm" id="vo"}
<a href="{$vo.slid_href}" target="_blank" rel="nofollow" class="fly-zanzhu" style="background-color: {$vo.slid_color};">{$vo.slid_name}</a>
{/volist}
</div>
</div>
<dl class="fly-panel fly-list-one">
<dt class="fly-panel-title">{:lang('hot post list')}</dt>
{volist name="artHot" id="vo"}
<dd>
<a href="{:url('article/detail',['id' => $vo.id])}">{$vo.title}</a>
<span><i class="iconfont icon-pinglun1"></i> {$vo.comments_count}</span>
</dd>
{/volist}
</dl>
<div class="fly-panel" style="padding: 5px 0; text-align: center;">
{volist name="ad_art" id="vo"}
<a href="{$vo.slid_href}" target="_blank"><img src="{$vo.slid_img}" style="max-width: 100%;"></a>
{/volist}
</div>
</div>
</div>
<!--底部栏-->
<div class="site-tree-mobile-detail-bottom layui-hide-md">
<div id="LAY_jieAdmin1" data-id="{$article['id']}"></div>
</div>
</div>
{include file="public/menu" /}
{/block}
{block name="script"}
<script>
var collectionFind = "{:url('Collection/find')}",
articleJieset = "{:url('Article/jieset')}",
articleDelete = "{:url('Article/delete')}",
commentJiedaZan = "{:url('Comment/jiedaZan')}",
commentJiedaCai = "{:url('Comment/jiedaCai')}",
commentGetDa = "{:url('Comment/getDa')}",
commentUpdateDa = "{:url('Comment/updateDa')}",
commentJiedaDelete = "{:url('Comment/jiedaDelete')}",
langCollection = "{:lang('collection')}",
langCancelCollection = "{:lang('cancel collection')}";
var collection = "{:url('collection/')}";
layui.use(['fly', 'face','colorpicker','plyr'], function(){
var $ = layui.jquery
,form = layui.form
,fly = layui.fly
,colorpicker = layui.colorpicker
,plyr = layui.plyr;
var laytpl = layui.laytpl;
var uid = layui.cache.user.uid;
//tpl模板给发布时间赋值
$('div.detail-hits').children('span.post-time').each(function(){
var othis = $(this), html = othis.html();
var string = laytpl('{{ d.time }}').render({
//time: html
time: othis.attr('data')
});
var posttime = layui.util.timeAgo(string, 1);
othis.text(posttime);
//console.log(othis.attr('data'));
});
//预定义颜色项
colorpicker.render({
elem: '#color'
,color: '#393d49'
,predefine: true // 开启预定义颜色
,size: 'xs'
,done: function(color){
//改变标题颜色
$('h1').css("color", color);
var id = {$article.id};
$.ajax({
type:'post',
url:"{:url('Article/titleColor')}",
data:{id: id,title_color: color},
dataType:'json',
success:function(data){
if(data.code == 0){
layer.msg(data.msg,{icon:6,time:2000
});
} else {
layer.open({content:data.msg,icon:5,adim:6});
}
}
});
}
});
//评论需要登陆
form.on('submit(user-comment)',function (data){
var filed = data.field;
if (uid == -1) {
layer.msg('请先登陆',{icon:5,time:2000},function(){
location.href = "{:url('login/index')}";
});
} else {
$.ajax({
type: "post",
url: "{:url('article/comment')}",
data: filed,
dataType: "json",
success:function (data) {
if (data.code == 0) {
layer.msg(data.msg,{icon:6,time:2000},function () {
location.reload(true);
});
}else {
layer.open({title:'评论失败',content:data.msg,icon:5,anim:6});
}
}
});
}
return false;
});
//下载
$('#zip-download').click(function (){
var id = "{$article.id}";
$.ajax({
type:"post",
url:"{:url('article/download')}",
data:{id:id},
success:function (data) {
location.href = "{:url('article/download',['id'=>$article.id])}";
}
});
});
//如果你是采用模版自带的编辑器,你需要开启以下语句来解析。
$('.detail-body').each(function(){
var othis = $(this), html = othis.html();
othis.html(fly.content(html));
});
//加载播放器
plyr.setup();
});
//扫码阅读
$("#rdown").hover(function(){
$("#phonedl").show().stop();
},function(){
$("#phonedl").hide().stop();
});
$("#phonedl").hover(function(){
$("#phonedl").show().stop();
},function(){
$("#phonedl").hide().stop();
});
function PhoneDown(){
layer.open({
title: "扫码查阅",
skin: 'layui-layer',
content: "<img src='/qrcode/?text={$Request.domain}{:url('article/detail',['id' => $article.id])}&size=230'>"
});
}
//推送百度收录服务
(function(){
var bp = document.createElement('script');
var curProtocol = window.location.protocol.split(':')[0];
if (curProtocol === 'https') {
bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
}
else {
bp.src = 'http://push.zhanzhang.baidu.com/push.js';
}
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(bp, s);
})();
</script>
{/block}

View File

@ -73,7 +73,7 @@
</div> </div>
<div class="layui-form-item layui-form-text"> <div class="layui-form-item layui-form-text">
<div class="layui-input-block"> <div class="layui-input-block">
<textarea id="L_content" name="content" required lay-verify="required" placeholder="详细描述" class="layui-textarea fly-editor" style="height: 260px;">{$article.content}</textarea> <textarea id="L_content" name="content" required lay-verify="required" placeholder="详细描述" class="layui-textarea fly-editor" style="height: 260px;">{$article.content|raw|htmlspecialchars_decode}</textarea>
</div> </div>
</div> </div>
<div class="layui-form-item"> <div class="layui-form-item">

View File

@ -11,9 +11,8 @@
<div class="layui-col-md8 content detail"> <div class="layui-col-md8 content detail">
<div class="fly-panel detail-box"> <div class="fly-panel detail-box">
{//标题} {//标题}
<h1 style="color:{$article.title_color};">{$article.title} <h1 style="color:{$article.title_color};">{$article.title}</h1>
<span class="layui-hide-xs"><div onclick="PhoneDown();" style="" class="detail_qrcode" id="mobile"></div></span> <div class="detail_qrcode layui-hide-xs" onclick="PhoneDown();" id="mobile"></div>
</h1>
{//图标} {//图标}
<div class="fly-detail-info"> <div class="fly-detail-info">
<span class="layui-badge layui-bg-green fly-detail-column">{:cookie('think_lang') == 'en-us' ? $article.cate.ename : $article.cate.catename}</span> <span class="layui-badge layui-bg-green fly-detail-column">{:cookie('think_lang') == 'en-us' ? $article.cate.ename : $article.cate.catename}</span>
@ -43,7 +42,7 @@
</div> </div>
</div> </div>
<div class="detail-body photos">{$article.content}</div> <div class="detail-body photos" id="content">{$article.content}</div>
{//管理} {//管理}
{if (($article.upzip !== '') || session('?user_name'))} {if (($article.upzip !== '') || session('?user_name'))}
<div class="detail-assist"> <div class="detail-assist">
@ -280,7 +279,11 @@ layui.use(['fly', 'face','colorpicker','plyr'], function(){
plyr.setup(); plyr.setup();
}); });
</script>
{:hook('markdownhook')}
<script>
//扫码阅读 //扫码阅读
$("#rdown").hover(function(){ $("#rdown").hover(function(){
$("#phonedl").show().stop(); $("#phonedl").show().stop();
@ -315,4 +318,5 @@ $("#rdown").hover(function(){
s.parentNode.insertBefore(bp, s); s.parentNode.insertBefore(bp, s);
})(); })();
</script> </script>
{/block} {/block}

View File

@ -0,0 +1,315 @@
{extend name="public/base" /}
{block name="title"}{$article.title}-{$sysInfo.webname}{/block}
{block name="keywords"}{$article.title},{$article.tags}{/block}
{block name="description"}{$article.title},{:getArtContent($article.content)}{/block}
{block name="link"}<link rel="stylesheet" href="/static/res/css/plyr.css" charset="utf-8">{/block}
{block name="column"}<div class="layui-hide-xs">{include file="/public/column" /}</div>{/block}
{block name="content"}
<div class="layui-container">
<div class="layui-row layui-col-space15">
<div class="layui-col-md8 content detail">
<div class="fly-panel detail-box">
{//标题}
<h1 style="color:{$article.title_color};">{$article.title}
<span class="layui-hide-xs"><div onclick="PhoneDown();" style="" class="detail_qrcode" id="mobile"></div></span>
</h1>
{//图标}
<div class="fly-detail-info">
<span class="layui-badge layui-bg-green fly-detail-column">{:cookie('think_lang') == 'en-us' ? $article.cate.ename : $article.cate.catename}</span>
{if ($article.is_top == 1)}<span class="layui-badge layui-bg-black">{:lang('top')}</span>{/if}
{if ($article.is_hot == 1)}<span class="layui-badge layui-bg-red">{:lang('hot')}</span>{/if}
<span id="LAY_jieAdmin" data-id="{$article['id']}"></span>
<span class="fly-list-nums">
<a href="#comment"><i class="iconfont" title="{:lang('reply')}">&#xe60c;</i>{$comments->count()}</a><i class="iconfont" title="浏览">&#xe60b;</i>{$pv}
</span>
</div>
{//作者}
<div class="detail-about">
<a class="fly-avatar" href="{:url('user/home',['id'=>$article.user.id])}">
<img src="{$article.user.user_img}" alt="{$article.user.name}">
<i class="iconfont icon-renzheng" title="认证信息"></i>
</a>
<div class="fly-detail-user">
<a href="{:url('user/home',['id'=>$article.user.id])}" class="fly-link">
{if config('taoler.config.area_show') == 1}<i class="layui-badge layui-bg-green " title="">{:getAsing($article.user.area_id) ?: '无'}</i>{/if}
<cite>{$article.user.nickname ?: $article.user.name}</cite>
</a>
<span class="layui-btn layui-btn-xs guanzhu" >关注</span>
</div>
<div class="detail-hits">
<!--span style="padding-right: 10px; color: #FF7200">悬赏60飞吻</span-->
<span class="post-time" data="{$article.create_time}" style="padding-top: 5px;"></span>
</div>
</div>
<div class="detail-body photos">{$article.content|raw}</div>
{//管理}
{if (($article.upzip !== '') || (session('user_id')==$article.user_id) OR ($user.auth ?? ''))}
<div class="detail-assist">
{notempty name="$article.upzip"}
<button type="button" class="layui-btn layui-btn-xs" id="zip-download"><i class="layui-icon layui-icon-download-circle"></i>{:lang('download files')}: {$article.downloads}次</button>
{/notempty}
<div class="fly-admin-box" data-id="{$article.id}">
{if ($user.auth ?? '')}
<span class="layui-btn layui-btn-xs jie-admin" type="del"><i class="layui-icon layui-icon-delete"></i></span>
{if($article.is_top == 0)}<span class="layui-btn layui-btn-xs jie-admin" type="set" field="top" rank="1"><i class="layui-icon layui-icon-top"></i></span>
{else /}<span class="layui-btn layui-btn-xs jie-admin" type="set" field="top" rank="0" style="background-color:#ccc;">{:lang('cancel topping')}</span>{/if}
{if($article.is_hot == 0)}
<span class="layui-btn layui-btn-xs jie-admin" type="set" field="hot" rank="1"><i class="layui-icon layui-icon-fire"></i></span>
{else /}
<span class="layui-btn layui-btn-xs jie-admin" type="set" field="hot" rank="0" style="background-color:#ccc;">{:lang('cancel hoting')}</span>
{/if}
{if($article.is_reply == 1)}
<span class="layui-btn layui-btn-xs jie-admin" type="set" field="reply" rank="0"><i class="layui-icon layui-icon-face-cry"></i></span>
{else /}
<span class="layui-btn layui-btn-xs jie-admin" type="set" field="reply" rank="1" style="background-color:#ccc;">{:lang('enable reply')}</span>
{/if}
<span id="color">{:lang('title color')}</span>
{/if}
{if(session('user_name')==$article.user.name || ($user.auth ?? ''))}
<span class="layui-btn layui-btn-xs jie-admin" type="edit"><a href="{:url('article/edit',['id'=>$article.id])}">{:lang('edit')}</a></span>
{/if}
</div>
</div>
{/if}
</div>
{//评论}
<div class="fly-panel detail-box" id="flyReply">
<span style="font-size:18px;">评论 {$comments->count()}</span>
<ul class="jieda" id="jieda">
{volist name="comments" id="vo" empty= ""}
<li data-id="{$vo.id}" class="jieda-daan">
<a name="item-1111111111"></a>
<div class="detail-about detail-about-reply">
<a class="fly-avatar" href="{:url('user/home',['id'=>$vo.user.id])}">
<img src="{$vo.user.user_img}" alt=" "><i class="iconfont icon-renzheng" title="认证信息"></i>
</a>
<div class="fly-detail-user">
<a href="{:url('user/home',['id'=>$vo.user.id])}" class="fly-link">
{if config('taoler.config.area_show') == 1}<i class="layui-badge layui-bg-green " title="">{:getAsing($vo.user.area_id) ?: '无'}</i>{/if}
<cite>{$vo.user.nickname ?: $vo.user.name}</cite>
</a>
{if condition="$article.user.id eq $vo.user.id"}<span>({:lang('poster')})</span>{/if}
</div>
<div class="detail-hits"><span class="post-time" data="{$vo.create_time}"></span></div>
</div>
<div class="detail-body jieda-body photos">{$vo.content|raw|htmlspecialchars_decode}</div>
<div class="jieda-reply">
<span class="jieda-zan {if($vo.zan != 0)}zanok{/if}" type="zan">
<i class="iconfont icon-zan"></i><em>{$vo.zan}</em>
</span>
<span type="reply"><i class="iconfont icon-svgmoban53"></i>{:lang('reply')}</span>
{//评论编辑删除采纳权限}
<div class="jieda-admin">
{if ((session('user_id') == $vo.user.id) && (getLimtTime($vo.create_time) < 2)) OR ($user.auth ?? '')}
<span type="edit">{:lang('edit')}</span>
<span type="del">{:lang('delete')}</span>
{/if}
</div>
</div>
</li>
{/volist}
</ul>
<div style="text-align: center">{$comments|raw}</div>
{if condition="$article.is_reply == 1"}
<div class="layui-form layui-form-pane">
<div class="layui-form-item layui-form-text">
<a name="comment"></a>
<div class="layui-input-block">
<textarea id="L_content" name="content" required lay-verify="required" placeholder="{:lang('please input the content')}" class="layui-textarea fly-editor" style="height: 150px;"></textarea>
</div>
</div>
<div class="layui-form-item">
<input type="hidden" name="article_id" value="{$article.id}">
<input type="hidden" name="user_id" value="{:session('user_id')}">
<button class="layui-btn" lay-filter="user-comment" lay-submit>{:lang('submit comments')}</button>
</div>
</div>
{else /}
<blockquote class="layui-elem-quote layui-quote-nm layui-disabled" style="margin: 100px 0 20px; padding: 50px 20px; text-align: center; color: #999!important;">本帖已设置禁止回复</blockquote>
{/if}
</div>
</div>
<div class="layui-col-md4">
<div class="fly-panel">
<div class="fly-panel-title">{:lang('sponsor')}<span style="padding: 0 3px;">-</span>
<a href="" class="fly-link fly-joinad">{:lang('i want to join')}</a>
</div>
<div class="fly-panel-main">
{volist name="ad_comm" id="vo"}
<a href="{$vo.slid_href}" target="_blank" rel="nofollow" class="fly-zanzhu" style="background-color: {$vo.slid_color};">{$vo.slid_name}</a>
{/volist}
</div>
</div>
<dl class="fly-panel fly-list-one">
<dt class="fly-panel-title">{:lang('hot post list')}</dt>
{volist name="artHot" id="vo"}
<dd>
<a href="{:url('article/detail',['id' => $vo.id])}">{$vo.title}</a>
<span><i class="iconfont icon-pinglun1"></i> {$vo.comments_count}</span>
</dd>
{/volist}
</dl>
<div class="fly-panel" style="padding: 5px 0; text-align: center;">
{volist name="ad_art" id="vo"}
<a href="{$vo.slid_href}" target="_blank"><img src="{$vo.slid_img}" style="max-width: 100%;"></a>
{/volist}
</div>
</div>
</div>
<!--底部栏-->
<div class="site-tree-mobile-detail-bottom layui-hide-md">
<div id="LAY_jieAdmin1" data-id="{$article['id']}"></div>
</div>
</div>
{include file="public/menu" /}
{/block}
{block name="script"}
<script>
var collectionFind = "{:url('Collection/find')}",
articleJieset = "{:url('Article/jieset')}",
articleDelete = "{:url('Article/delete')}",
commentJiedaZan = "{:url('Comment/jiedaZan')}",
commentJiedaCai = "{:url('Comment/jiedaCai')}",
commentGetDa = "{:url('Comment/getDa')}",
commentUpdateDa = "{:url('Comment/updateDa')}",
commentJiedaDelete = "{:url('Comment/jiedaDelete')}",
langCollection = "{:lang('collection')}",
langCancelCollection = "{:lang('cancel collection')}";
var collection = "{:url('collection/')}";
layui.use(['fly', 'face','colorpicker','plyr'], function(){
var $ = layui.jquery
,form = layui.form
,fly = layui.fly
,colorpicker = layui.colorpicker
,plyr = layui.plyr;
var laytpl = layui.laytpl;
var uid = layui.cache.user.uid;
//tpl模板给发布时间赋值
$('div.detail-hits').children('span.post-time').each(function(){
var othis = $(this), html = othis.html();
var string = laytpl('{{ d.time }}').render({
//time: html
time: othis.attr('data')
});
var posttime = layui.util.timeAgo(string, 1);
othis.text(posttime);
//console.log(othis.attr('data'));
});
//预定义颜色项
colorpicker.render({
elem: '#color'
,color: '#393d49'
,predefine: true // 开启预定义颜色
,size: 'xs'
,done: function(color){
//改变标题颜色
$('h1').css("color", color);
var id = {$article.id};
$.ajax({
type:'post',
url:"{:url('Article/titleColor')}",
data:{id: id,title_color: color},
dataType:'json',
success:function(data){
if(data.code == 0){
layer.msg(data.msg,{icon:6,time:2000
});
} else {
layer.open({content:data.msg,icon:5,adim:6});
}
}
});
}
});
//评论需要登陆
form.on('submit(user-comment)',function (data){
var filed = data.field;
if (uid == -1) {
layer.msg('请先登陆',{icon:5,time:2000},function(){
location.href = "{:url('login/index')}";
});
} else {
$.ajax({
type: "post",
url: "{:url('article/comment')}",
data: filed,
dataType: "json",
success:function (data) {
if (data.code == 0) {
layer.msg(data.msg,{icon:6,time:2000},function () {
location.reload(true);
});
}else {
layer.open({title:'评论失败',content:data.msg,icon:5,anim:6});
}
}
});
}
return false;
});
//下载
$('#zip-download').click(function (){
var id = "{$article.id}";
$.ajax({
type:"post",
url:"{:url('article/download')}",
data:{id:id},
success:function (data) {
location.href = "{:url('article/download',['id'=>$article.id])}";
}
});
});
//如果你是采用模版自带的编辑器,你需要开启以下语句来解析。
$('.detail-body').each(function(){
var othis = $(this), html = othis.html();
othis.html(fly.content(html));
});
//加载播放器
plyr.setup();
});
//扫码阅读
$("#rdown").hover(function(){
$("#phonedl").show().stop();
},function(){
$("#phonedl").hide().stop();
});
$("#phonedl").hover(function(){
$("#phonedl").show().stop();
},function(){
$("#phonedl").hide().stop();
});
function PhoneDown(){
layer.open({
title: "扫码查阅",
skin: 'layui-layer',
content: "<img src='/qrcode/?text={$Request.domain}{:url('article/detail',['id' => $article.id])}&size=230'>"
});
}
//推送百度收录服务
(function(){
var bp = document.createElement('script');
var curProtocol = window.location.protocol.split(':')[0];
if (curProtocol === 'https') {
bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
}
else {
bp.src = 'http://push.zhanzhang.baidu.com/push.js';
}
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(bp, s);
})();
</script>
{/block}

View File

@ -0,0 +1,46 @@
{extend name="public/base" /}
{block name="title"}404 - {$sysInfo.webname}{/block}
{block name="keywords"}{$sysInfo.keywords}{/block}
{block name="description"}{$sysInfo.descript}{/block}
{block name="column"}{include file="public/column" /}{/block}
{block name="content"}
<div class="layui-container fly-marginTop">
<div class="fly-panel">
<div class="fly-none">
<h2><i class="iconfont icon-404"></i></h2>
<p>页面或者数据被<a href="http://www.aieok.com"> 纸飞机 </a>运到火星了,啥都看不到了…</p>
</div>
</div>
</div>
{/block}
{block name="script"}
<script>
layui.cache.page = 'user';
layui.cache.user = {
username: '{$user.name??'游客'}'
,uid: '{$user.id ?? -1}'
,avatar: '{$user['user_img'] ?? '/static/res/images/avatar/00.jpg'}'
,experience: '{$user.point ?? ''}'
,sex: '{$user.sex ? '女':'男'}'
};
layui.config({
version: "3.0.0"
,base: '/static/res/mods/'
}).extend({
fly: 'index'
}).use('fly');
</script>
{/block}

View File

@ -41,11 +41,8 @@
</div> </div>
</div> </div>
<div class="layui-col-md4"> <div class="layui-col-md4">
<!--签到--> {:hook('signhook', ['id'=>1])}
<a name="signin"> </a>
<div class="fly-panel fly-signin layui-hide-xs">
{include file="public/sign" /}
</div>
<!--温馨通道--> <!--温馨通道-->
<div class="fly-panel layui-hide-xs"> <div class="fly-panel layui-hide-xs">
<h3 class="fly-panel-title">{:lang('links list')}</h3> <h3 class="fly-panel-title">{:lang('links list')}</h3>

View File

@ -44,11 +44,7 @@
<a href="{:url('login/forget')}">{:lang('forget password')}</a> <a href="{:url('login/forget')}">{:lang('forget password')}</a>
</span> </span>
</div> </div>
<!--div class="layui-form-item fly-form-app"> {:hook('socialhook')}
<span>或者使用社交账号登入</span>
<a href="" onclick="layer.msg('正在通过QQ登入', {icon:16, shade: 0.1, time:0})" class="iconfont icon-qq" title="QQ登入"></a>
<a href="" onclick="layer.msg('正在通过微博登入', {icon:16, shade: 0.1, time:0})" class="iconfont icon-weibo" title="微博登入"></a>
</div-->
</form> </form>
</div> </div>
</div> </div>

1
view/taoler/index/public/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
user-nav.html

View File

@ -1,5 +1,5 @@
<div class="fly-footer html5plus-hide layui-hide-xs"> <div class="fly-footer html5plus-hide">
<p> Copyright &copy; {:date('Y')}{$sysInfo.copyright|raw}</p> <p> Copyright &copy; {:date('Y')}{$sysInfo.copyright|raw}v{:config('taoler.version')}</p>
<p> <p>
{$sysInfo.showlist|raw} {$sysInfo.showlist|raw}
{volist name="footlinks" id="vo"} {volist name="footlinks" id="vo"}

View File

@ -1,13 +1,13 @@
<div class="fly-header layui-bg-black"> <div class="fly-header layui-bg-black">
<div class="layui-container"> <div class="layui-container">
<a class="fly-logo layui-hide-xs" href="/"><img src="{$sysInfo.logo}" alt="layui" width="135" height="37"></a> <a class="fly-logo layui-hide-xs" href="/"><img src="{$sysInfo.logo}" alt="taoler" width="135" height="37"></a>
<!--头部伸缩侧边栏--> <!--头部伸缩侧边栏-->
<div class="site-tree-mobile-top layui-hide"> <div class="site-tree-mobile-top layui-hide">
<i class="layui-icon layui-icon-spread-left"></i> <i class="layui-icon layui-icon-spread-left"></i>
</div> </div>
<div class="site-mobile-shade-top"></div> <div class="site-mobile-shade-top"></div>
{//移动端LOGO} {//移动端LOGO}
<a class="fly-logo layui-hide-md" href="/" style="padding-left:50%; margin-left:-65px;"><img src="{$sysInfo.logo}" alt="layui" width="135" height="37"></a> <a class="fly-logo layui-hide-md" href="/" style="padding-left:50%; margin-left:-60px;"><img src="/static/res/images/logo-m.png"></a>
<ul class="layui-nav fly-nav layui-hide-xs"> <ul class="layui-nav fly-nav layui-hide-xs">
{volist name="headlinks" id="vo"} {volist name="headlinks" id="vo"}
<li class="layui-nav-item"> <li class="layui-nav-item">

View File

@ -1,12 +0,0 @@
<script>
var messageNums = "{:url('Message/nums')}",
messageRead = "{:url('Message/read')}",
userMessage = "{:url('index/User/message')}",
login = "{:url('Login/index')}",
articleAdd = "{:url('Article/add')}",
websearch = "{:url('index/search')}",
textImgUpload = "{:url('article/textImgUpload')}",
searchUrl = "{:url('index/search')}";
</script>
<script src="/static/layui/jquery.min.js" charset="utf-8"></script>
<script src="/static/layui/layui.js" charset="utf-8"></script>

View File

@ -1,5 +1,4 @@
<div class="layui-hide-md"> <div class="layui-panel site-menu layui-hide-md">
<div class="layui-panel site-menu" style="width: auto;">
<ul class="layui-menu layui-menu-lg"> <ul class="layui-menu layui-menu-lg">
<li class="search" style="padding-left:5px;padding-top:2px;padding-right:5px;"> <li class="search" style="padding-left:5px;padding-top:2px;padding-right:5px;">
<form action="{:url('index/search',['keywords'=>$Request.param.keywords])}"> <form action="{:url('index/search',['keywords'=>$Request.param.keywords])}">
@ -68,8 +67,8 @@
</ul> </ul>
</li> </li>
</ul> </ul>
</div>
</div> </div>
<!-- <!--
<div class="site-tree-mobile layui-hide"> <div class="site-tree-mobile layui-hide">
<i class="layui-icon layui-icon-spread-left"></i> <i class="layui-icon layui-icon-spread-left"></i>

View File

@ -1,42 +1,43 @@
<ul class="layui-nav layui-nav-tree layui-inline" lay-filter="user"> <ul class="layui-nav layui-nav-tree layui-inline" lay-filter="user">
<li class="layui-nav-item {if($Request.action=='index')}layui-this{/if}"> <li class="layui-nav-item {if($Request.action=='index')}layui-this{/if}">
<a href="{:url('user/index')}"> <a href="{:url('user/index')}">
<i class="layui-icon">&#xe612;</i> <i class="layui-icon layui-icon-user"></i>
用户中心 {:lang('user center')}
</a> </a>
</li> </li>
<li class="layui-nav-item {if($Request.action=='set')}layui-this{/if}"> <li class="layui-nav-item {if($Request.action=='set')}layui-this{/if}">
<a href="{:url('user/set')}"> <a href="{:url('user/set')}">
<i class="layui-icon">&#xe620;</i> <i class="layui-icon layui-icon-set"></i>
基本设置 {:lang('set info')}
</a> </a>
</li> </li>
<li class="layui-nav-item {if($Request.action=='post')}layui-this{/if}"> <li class="layui-nav-item {if($Request.action=='post')}layui-this{/if}">
<a href="{:url('user/post')}"> <a href="{:url('user/post')}">
<i class="layui-icon">&#xe705;</i> <i class="layui-icon layui-icon-read"></i>
我的帖子 {:lang('my post')}
</a> </a>
</li> </li>
<li class="layui-nav-item {if($Request.action=='message')}layui-this{/if}"> <li class="layui-nav-item {if($Request.action=='message')}layui-this{/if}">
<a href="{:url('user/message')}"> <a href="{:url('user/message')}">
<i class="layui-icon">&#xe611;</i> <i class="layui-icon layui-icon-notice"></i>
我的消息 {:lang('my message')}
</a>
</li>
<li class="layui-nav-item {if($Request.action=='key')}layui-this{/if}" >
<a href="{:url('Api/key')}">
<i class="layui-icon layui-icon-vercode"></i>
{:lang('my auth')}
</a> </a>
</li> </li>
<li class="layui-nav-item " > <li class="layui-nav-item " >
<a href="{:url('user/home',['id'=>session('user_id')])}"> <a href="{:url('user/home',['id'=>session('user_id')])}">
<i class="layui-icon">&#xe609;</i> <i class="layui-icon layui-icon-home"></i>
我的主页 {:lang('my page')}
</a> </a>
</li> </li>
</ul> </ul>
<div class="site-tree-mobile-user layui-hide"> <div class="site-tree-mobile-user layui-hide">
<i class="layui-icon">&#xe602;</i> <i class="layui-icon layui-icon-right"></i>
</div>
<div class="site-mobile-shade-user"></div>
<div class="site-tree-mobile-user layui-hide">
<i class="layui-icon">&#xe602;</i>
</div> </div>
<div class="site-mobile-shade-user"></div> <div class="site-mobile-shade-user"></div>