通知设置 新通知
关于表单及表格功能的征集帖
功能建议 • echo 回复了问题 • 13 人关注 • 15 个回复 • 3109 次浏览 • 2019-10-09 14:51
关于音频 /上传 方法
提问交流 • MrTao 回复了问题 • 4 人关注 • 4 个回复 • 2349 次浏览 • 2019-07-25 16:49
自定义分片上传字段
经验分享 • yangweijie 发表了文章 • 1 个评论 • 2263 次浏览 • 2019-03-23 16:26
还有官方手册,终于把他搞出来了。
思路,第一自己扩展sendFile 事件第二,改变分片上传参数,包括上传地址
第三 实现分片上传的方法。
WebUploader.Uploader.register({
"name": "cutfile_uploader",
"before-send": "beforeSend" // 整个文件上传前
}, {
beforeSend:function(block){
var deferred = WebUploader.Deferred();
if(is_upload)//跳过到开始上传的哪一个分片时
{
deferred.resolve();
}else if(totalFiles) {
//已经获取过文件数量则直接判断是否跳过
//当前分片下标小于等于目录下的文件数量就认为分块存在,因为分块上传下标是由小到大
// console.log(block.chunk);
// console.log(totalFiles);
// console.log(!totalFiles.in_array(block.chunk));
if (!totalFiles.in_array(block.chunk - 1)) {
deferred.resolve();
} else {
//分块存在,跳过
deferred.reject();
}
} else {
$.post(cutfile_conf.check_upload_url, {md5: fileMd5}, function (data) {
console.log(data);
if (data.code) {
totalFiles = data.data;
//当前分片下标小于等于目录下的文件数量就认为分块存在,因为分块上传下标是由小到大
if (!data.data.in_array(block.chunk-1)) {
deferred.resolve();
} else {
//分块存在,跳过
deferred.reject();
}
} else {
is_upload = true;
deferred.resolve();
}
}, 'json');
}
}
});注册send-file事件
// 当有文件添加进来的时候
uploader.on( 'fileQueued', function( file ) {
console.log(new Date());
// 设置当前上传对象
curr_uploader = uploader;
uploader.md5File( file )
// 完成
.then(function(val) {
fileMd5 = val;
var formData = uploader.option('formData');
// console.log('md5 result:', val);
formData.md5 = fileMd5;
// console.log(formData);
uploader.option('formData',formData);
// console.log(uploader.option('formData'));
});
var $li = '<li id="' + file.id + '" class="list-group-item file-item">' +
'<span class="pull-right file-state"><span class="text-info"><i class="fa fa-sun-o fa-spin"></i> 正在读取文件信息...</span></span>' +
'<i class="fa fa-file"></i> ' +
file.name +
' [<a href="javascript:void(0);" class="download-file">下载</a>] [<a href="javascript:void(0);" class="remove-file">删除</a>]' +
'<div class="progress progress-mini remove-margin active" style="display: none"><div class="progress-bar progress-bar-primary progress-bar-striped" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%"></div></div>'+
'</li>';
if ($multiple) {
$file_list.append($li);
} else {
$file_list.html($li);
// 清空原来的数据
$input_file.val('');
}
});
修改file-queueshi事件,主要是每次上传时不光传file 对象还将原始md5传过去用于组成分片的文件用,方便最终检测是否存在已传过的分片。这里面有一个大坑,curr_uploader = uploader; 这个设置的在form.js里
WebUploader.Uploader.register({
"before-send-file": "beforeSendFile" // 整个文件上传前
}, {
beforeSendFile:function(file){
var $li = $( '#'+file.id );
var deferred = WebUploader.Deferred();
var owner = this.owner;
owner.md5File(file).then(function(val){
$.ajax({
type: "POST",
url: dolphin.upload_check_url,
data: {
md5: val
},
cache: false,
timeout: 10000, // 超时的话,只能认为该文件不曾上传过
dataType: "json"
}).then(function(res, textStatus, jqXHR){
if(res.code){
// 已上传,触发上传完成事件,实现秒传
deferred.reject();
curr_uploader.trigger('uploadSuccess', file, res);
curr_uploader.trigger('uploadComplete', file);
}else{
// 文件不存在,触发上传
deferred.resolve();
$li.find('.file-state').html('<span class="text-info">正在上传...</span>');
$li.find('.img-state').html('<div class="bg-info">正在上传...</div>');
$li.find('.progress').show();
}
}, function(jqXHR, textStatus, errorThrown){
// 任何形式的验证失败,都触发重新上传
deferred.resolve();
$li.find('.file-state').html('<span class="text-info">正在上传...</span>');
$li.find('.img-state').html('<div class="bg-info">正在上传...</div>');
$li.find('.progress').show();
});
});
return deferred.promise();
}
});
里面的 妙传实现时 出发已有的webload uploadSuccess 会报为定义的方法,必须修改 form.js
将var curr_uploader = {}; 这个定义提到$(function(){ 外,变为全局变量。前端我也不太懂,
总之官方的实现 不管表单里有没有webupload 都跑去注册了一下事件,然后才加载init.js 自定义表单项的js 并且我试了用官方的 unregistered webupload 都无效。官方要考虑一下扩展性,或者官方支持分片最好。对应的上传和检测 方法我已经更改了admin里的ajax 实现了。
所以官方的自定义字段的后端实现 也不知道如何去扩展一个控制器方法。
大家把我的附件解压放到项目里,只支持1.1.0 以上。 然后修改一行form.js 就可以了。
参考页面:
public function index(){
return ZBuilder::make('form')
->setPageTitle('分片上传')
->addCutfile('file', '上传')
->fetch();
}有个疑惑,看了很多文章,chunk 发现upload都是1开始 而webupload里是从0开始的。
还有感觉获取本地信息检查妙传总感觉卡,还有断电续传的进度 不想现象的 自动晚上长,但是请求数确实会比重新传的分片数要少。希望官方参考本文章增加一个分片上传的字段体验完整的功能
查看全部
有用户说要断点续传,然后自己没研究过,但是发现webupload里支持分片上传的,就研究实现了下,本来试了一个stream js 但是在海豚里各种ui没调通。
还有官方手册,终于把他搞出来了。
思路,第一自己扩展sendFile 事件第二,改变分片上传参数,包括上传地址
第三 实现分片上传的方法。
WebUploader.Uploader.register({注册send-file事件
"name": "cutfile_uploader",
"before-send": "beforeSend" // 整个文件上传前
}, {
beforeSend:function(block){
var deferred = WebUploader.Deferred();
if(is_upload)//跳过到开始上传的哪一个分片时
{
deferred.resolve();
}else if(totalFiles) {
//已经获取过文件数量则直接判断是否跳过
//当前分片下标小于等于目录下的文件数量就认为分块存在,因为分块上传下标是由小到大
// console.log(block.chunk);
// console.log(totalFiles);
// console.log(!totalFiles.in_array(block.chunk));
if (!totalFiles.in_array(block.chunk - 1)) {
deferred.resolve();
} else {
//分块存在,跳过
deferred.reject();
}
} else {
$.post(cutfile_conf.check_upload_url, {md5: fileMd5}, function (data) {
console.log(data);
if (data.code) {
totalFiles = data.data;
//当前分片下标小于等于目录下的文件数量就认为分块存在,因为分块上传下标是由小到大
if (!data.data.in_array(block.chunk-1)) {
deferred.resolve();
} else {
//分块存在,跳过
deferred.reject();
}
} else {
is_upload = true;
deferred.resolve();
}
}, 'json');
}
}
});
// 当有文件添加进来的时候修改file-queueshi事件,主要是每次上传时不光传file 对象还将原始md5传过去用于组成分片的文件用,方便最终检测是否存在已传过的分片。这里面有一个大坑,
uploader.on( 'fileQueued', function( file ) {
console.log(new Date());
// 设置当前上传对象
curr_uploader = uploader;
uploader.md5File( file )
// 完成
.then(function(val) {
fileMd5 = val;
var formData = uploader.option('formData');
// console.log('md5 result:', val);
formData.md5 = fileMd5;
// console.log(formData);
uploader.option('formData',formData);
// console.log(uploader.option('formData'));
});
var $li = '<li id="' + file.id + '" class="list-group-item file-item">' +
'<span class="pull-right file-state"><span class="text-info"><i class="fa fa-sun-o fa-spin"></i> 正在读取文件信息...</span></span>' +
'<i class="fa fa-file"></i> ' +
file.name +
' [<a href="javascript:void(0);" class="download-file">下载</a>] [<a href="javascript:void(0);" class="remove-file">删除</a>]' +
'<div class="progress progress-mini remove-margin active" style="display: none"><div class="progress-bar progress-bar-primary progress-bar-striped" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%"></div></div>'+
'</li>';
if ($multiple) {
$file_list.append($li);
} else {
$file_list.html($li);
// 清空原来的数据
$input_file.val('');
}
});
curr_uploader = uploader; 这个设置的在form.js里
WebUploader.Uploader.register({
"before-send-file": "beforeSendFile" // 整个文件上传前
}, {
beforeSendFile:function(file){
var $li = $( '#'+file.id );
var deferred = WebUploader.Deferred();
var owner = this.owner;
owner.md5File(file).then(function(val){
$.ajax({
type: "POST",
url: dolphin.upload_check_url,
data: {
md5: val
},
cache: false,
timeout: 10000, // 超时的话,只能认为该文件不曾上传过
dataType: "json"
}).then(function(res, textStatus, jqXHR){
if(res.code){
// 已上传,触发上传完成事件,实现秒传
deferred.reject();
curr_uploader.trigger('uploadSuccess', file, res);
curr_uploader.trigger('uploadComplete', file);
}else{
// 文件不存在,触发上传
deferred.resolve();
$li.find('.file-state').html('<span class="text-info">正在上传...</span>');
$li.find('.img-state').html('<div class="bg-info">正在上传...</div>');
$li.find('.progress').show();
}
}, function(jqXHR, textStatus, errorThrown){
// 任何形式的验证失败,都触发重新上传
deferred.resolve();
$li.find('.file-state').html('<span class="text-info">正在上传...</span>');
$li.find('.img-state').html('<div class="bg-info">正在上传...</div>');
$li.find('.progress').show();
});
});
return deferred.promise();
}
});
里面的 妙传实现时 出发已有的webload uploadSuccess 会报为定义的方法,必须修改 form.js
将var curr_uploader = {}; 这个定义提到$(function(){ 外,变为全局变量。前端我也不太懂,
总之官方的实现 不管表单里有没有webupload 都跑去注册了一下事件,然后才加载init.js 自定义表单项的js 并且我试了用官方的 unregistered webupload 都无效。官方要考虑一下扩展性,或者官方支持分片最好。对应的上传和检测 方法我已经更改了admin里的ajax 实现了。
所以官方的自定义字段的后端实现 也不知道如何去扩展一个控制器方法。
大家把我的附件解压放到项目里,只支持1.1.0 以上。 然后修改一行form.js 就可以了。
参考页面:
public function index(){有个疑惑,看了很多文章,chunk 发现upload都是1开始 而webupload里是从0开始的。
return ZBuilder::make('form')
->setPageTitle('分片上传')
->addCutfile('file', '上传')
->fetch();
}
还有感觉获取本地信息检查妙传总感觉卡,还有断电续传的进度 不想现象的 自动晚上长,但是请求数确实会比重新传的分片数要少。希望官方参考本文章增加一个分片上传的字段体验完整的功能
阿里云oss对象存储插件
经验分享 • wangchunfu 发表了文章 • 4 个评论 • 5534 次浏览 • 2018-08-17 15:42
Tp5中api开发中异常输出为html的问题
经验分享 • dragonlhp 发表了文章 • 0 个评论 • 1904 次浏览 • 2018-02-05 20:06
1:按照TP扩展异常的方式引用这个文件
看云 /manual/thinkphp5_1/354092
2:判断一下配置文件的默认输出类型
配置文件:
// 判断默认输出类型
if ($app['default_return_type'] == 'json') {
// 异常处理handle类 留空使用 \think\exception\Handle
$app['exception_handle'] = '\\app\\common\\exception\\JsonException';
}
return $app;
查看全部
1:按照TP扩展异常的方式引用这个文件
看云 /manual/thinkphp5_1/354092
2:判断一下配置文件的默认输出类型
配置文件:
// 判断默认输出类型
if ($app['default_return_type'] == 'json') {
// 异常处理handle类 留空使用 \think\exception\Handle
$app['exception_handle'] = '\\app\\common\\exception\\JsonException';
}
return $app;
阿里短信
模块&插件 • simone 发表了文章 • 3 个评论 • 3477 次浏览 • 2017-10-27 10:08
AccessKeyId 与 AccessKeySecret 在阿里云Access Key管理页面获取。
短信签名及短信模板 短信服务内申请
阿里短信系统升级 现更新源码。
使用:
plugin_action('AliyunSms','AliyunSms','sendSms',['phoneNumbers'=>18888888888,'templateParam'=>array('name'=>'test')]);
查看全部
AccessKeyId 与 AccessKeySecret 在阿里云Access Key管理页面获取。
短信签名及短信模板 短信服务内申请
阿里短信系统升级 现更新源码。
使用:
plugin_action('AliyunSms','AliyunSms','sendSms',['phoneNumbers'=>18888888888,'templateParam'=>array('name'=>'test')]);
关于linkages标签 三个选项框不能对应三层结构数据的问题
经验分享 • chhnang 发表了文章 • 0 个评论 • 1715 次浏览 • 2017-10-23 16:13
后台【两步验证】插件
模块&插件 • 流风回雪 发表了文章 • 10 个评论 • 4522 次浏览 • 2017-10-20 14:39
一、安装
解压附件中的插件到 /plugins 目录修改 application/admin/controller/Admin.php 在 protected function _initialize() 方法的第一行添加代码 /** * 初始化 * @author 蔡伟明 <314013107@qq.com> */ protected function _initialize() { // 两步验证钩子 $hook_result = \think\Hook::listen('two_step'); if (!empty($hook_result) && true !== $hook_result[0]) { $current_url = request()->url(); // 当前 url if ( // 下面三个 URL 不跳转到两步验证页 strpos ( $current_url , plugin_url('TwoStep/Admin/verification') ) === false && // 两步验证页 strpos ( $current_url , plugin_url('TwoStep/Admin/signin') ) === false && // 验证两步验证码 strpos ( $current_url , url('user/publics/signout') ) === false // 登出账号 ){ $this->redirect(plugin_url('TwoStep/Admin/verification')); } } . . . . . }修改 application/admin/controller/Index.php 用下面代码覆盖 public function profile() 方法 /** * 个人设置 * @author 蔡伟明 <314013107@qq.com> */ public function profile() { // 保存数据 if ($this->request->isPost()) { $data = $this->request->post(); $data['nickname'] == '' && $this->error('昵称不能为空'); $data['id'] = UID; // 如果没有填写密码,则不更新密码 if ($data['password'] == '') { unset($data['password']); } $UserModel = new UserModel(); if ($user = $UserModel->allowField(['nickname', 'email', 'password', 'mobile', 'avatar'])->update($data)) { // 记录行为 action_log('user_edit', 'admin_user', UID, UID, get_nickname(UID)); $this->success('编辑成功'); } else { $this->error('编辑失败'); } } // 获取数据 $info = UserModel::where('id', UID)->field('password', true)->find(); // 开启两步验证功能 $generate_secret_url = plugin_url('TwoStep/Admin/generateSecret'); $js = <<<EOF <script type="text/javascript"> $(function(){ $("#is_two_step").change(function() { if($('#is_two_step').is(':checked')) { $.get("{$generate_secret_url}", function(res){ if(res.code == 0){ Dolphin.notify(res.msg, 'danger'); $("#is_two_step").removeAttr("checked"); } else { $("#two_step_secret").val(res.secret); $("#form_group_is_two_step > .col-sm-12").after("<img src='"+res.QRCode+"' id='QRCode' alt='QRCode'>"); } }); } else { $("#two_step_secret").val(''); $("#QRCode").remove(); } }); }); </script>EOF; $items = [ // 批量添加表单项 ['static', 'username', '用户名', '不可更改'], ['text', 'nickname', '昵称', '可以是中文'], ['text', 'email', '邮箱', ''], ['password', 'password', '密码', '必填,6-20位'], ['text', 'mobile', '手机号'], ['image', 'avatar', '头像'] ]; if (isset($info['two_step_secret'])){ // 两步验证插件已安装 if ($info['two_step_secret']){ array_push ( $items , ['switch', 'is_two_step', '两步验证', '关闭后再开启可重新生成二维码', 1] ); }else{ array_push ( $items , ['switch', 'is_two_step', '两步验证', '开启后用 <code>Google Authenticator</code> 扫描二维码', 0] ); } array_push ( $items , ['hidden', 'two_step_secret'] ); }else{ $js = ''; } // 使用ZBuilder快速创建表单 return ZBuilder::make('form') ->addFormItems($items) ->setFormData($info) // 设置表单数据 ->setExtraJs($js) ->fetch(); }到后台“扩展中心”安装“两步验证”插件安装后再“设置插件”,把主机名改成自己的
开启非“超级管理员”的插件运行权限
PS: 如果插件设置和权限设置没生效,请清空缓存!二、使用打开“个人设置”页
拖到页面底部,开启两步验证
开启后立即用 Google Authenticator 扫描二维码(不过我还是推荐使用 Authy 这款APP,即使刷机也不怕验证码丢失)
确定扫描成功后再提交保存!退出后台重新登录,在系统验证完账号密码后,如果要登录的用户开启了两步验证,则会再要求输入验证码,验证成功后方可进入后台
三、关闭两步验证若要关闭两步验证只需要在“个人设置”页关闭并保存即可
本插件基于 DolphinPHP 1.0.7 开发
目前测试下来支持 DolphinPHP 1.1.0 !但如果你从低版本升级到 1.1.0 后发现无法登录后台,请先删除 runtime 目录;如果还使用了Redis缓存,需要清空下Redis缓存数据的内容!
TwoStep.zip 查看全部
一、安装
- 解压附件中的插件到 /plugins 目录
- 修改 application/admin/controller/Admin.php 在 protected function _initialize() 方法的第一行添加代码
/** * 初始化 * @author 蔡伟明 <314013107@qq.com> */ protected function _initialize() { // 两步验证钩子 $hook_result = \think\Hook::listen('two_step'); if (!empty($hook_result) && true !== $hook_result[0]) { $current_url = request()->url(); // 当前 url if ( // 下面三个 URL 不跳转到两步验证页 strpos ( $current_url , plugin_url('TwoStep/Admin/verification') ) === false && // 两步验证页 strpos ( $current_url , plugin_url('TwoStep/Admin/signin') ) === false && // 验证两步验证码 strpos ( $current_url , url('user/publics/signout') ) === false // 登出账号 ){ $this->redirect(plugin_url('TwoStep/Admin/verification')); } } . . . . . }
- 修改 application/admin/controller/Index.php 用下面代码覆盖 public function profile() 方法
/** * 个人设置 * @author 蔡伟明 <314013107@qq.com> */ public function profile() { // 保存数据 if ($this->request->isPost()) { $data = $this->request->post(); $data['nickname'] == '' && $this->error('昵称不能为空'); $data['id'] = UID; // 如果没有填写密码,则不更新密码 if ($data['password'] == '') { unset($data['password']); } $UserModel = new UserModel(); if ($user = $UserModel->allowField(['nickname', 'email', 'password', 'mobile', 'avatar'])->update($data)) { // 记录行为 action_log('user_edit', 'admin_user', UID, UID, get_nickname(UID)); $this->success('编辑成功'); } else { $this->error('编辑失败'); } } // 获取数据 $info = UserModel::where('id', UID)->field('password', true)->find(); // 开启两步验证功能 $generate_secret_url = plugin_url('TwoStep/Admin/generateSecret'); $js = <<<EOF <script type="text/javascript"> $(function(){ $("#is_two_step").change(function() { if($('#is_two_step').is(':checked')) { $.get("{$generate_secret_url}", function(res){ if(res.code == 0){ Dolphin.notify(res.msg, 'danger'); $("#is_two_step").removeAttr("checked"); } else { $("#two_step_secret").val(res.secret); $("#form_group_is_two_step > .col-sm-12").after("<img src='"+res.QRCode+"' id='QRCode' alt='QRCode'>"); } }); } else { $("#two_step_secret").val(''); $("#QRCode").remove(); } }); }); </script>EOF; $items = [ // 批量添加表单项 ['static', 'username', '用户名', '不可更改'], ['text', 'nickname', '昵称', '可以是中文'], ['text', 'email', '邮箱', ''], ['password', 'password', '密码', '必填,6-20位'], ['text', 'mobile', '手机号'], ['image', 'avatar', '头像'] ]; if (isset($info['two_step_secret'])){ // 两步验证插件已安装 if ($info['two_step_secret']){ array_push ( $items , ['switch', 'is_two_step', '两步验证', '关闭后再开启可重新生成二维码', 1] ); }else{ array_push ( $items , ['switch', 'is_two_step', '两步验证', '开启后用 <code>Google Authenticator</code> 扫描二维码', 0] ); } array_push ( $items , ['hidden', 'two_step_secret'] ); }else{ $js = ''; } // 使用ZBuilder快速创建表单 return ZBuilder::make('form') ->addFormItems($items) ->setFormData($info) // 设置表单数据 ->setExtraJs($js) ->fetch(); }
- 到后台“扩展中心”安装“两步验证”插件
- 安装后再“设置插件”,把主机名改成自己的
- 开启非“超级管理员”的插件运行权限
- 打开“个人设置”页
- 拖到页面底部,开启两步验证
- 开启后立即用 Google Authenticator 扫描二维码(不过我还是推荐使用 Authy 这款APP,即使刷机也不怕验证码丢失)
- 确定扫描成功后再提交保存!
- 退出后台重新登录,在系统验证完账号密码后,如果要登录的用户开启了两步验证,则会再要求输入验证码,验证成功后方可进入后台
- 若要关闭两步验证只需要在“个人设置”页关闭并保存即可
本插件基于 DolphinPHP 1.0.7 开发
目前测试下来支持 DolphinPHP 1.1.0 !但如果你从低版本升级到 1.1.0 后发现无法登录后台,请先删除 runtime 目录;如果还使用了Redis缓存,需要清空下Redis缓存数据的内容!
Multifield多维数组字段-扩展form单序列化字段
模块&插件 • yangweijie 发表了文章 • 6 个评论 • 2796 次浏览 • 2017-10-04 08:47
form
addMultifield($name = '', $title = '', $tips = '', $options = [], $default = [],$extra_class='') 添加多维字段序列化存储,每一行记录由options控制,field_name=>field_title
存储时 如 input('no') 获取出来是 [['name'=>'', 'value'=>'']]这样的结构;
测试代码
public function test(){
if(request()->isAjax()){
$mult_attribute = I('mult_attribute/a', []);
$this->checkPackagePrice($mult_attribute);
}else{
return ZBuilder::make('form')
->setPageTitle('新增商品-选择店铺')
->addMultifield('mult_attribute', '商品', '', ['name'=>'名称','value'=>'值'], '')
->fetch();
}
}
public function checkPackagePrice($mult_attribute){
$empty_num = 0;
foreach ($mult_attribute as $key => $row) {
if (empty($row['attribute_value']) || empty($row['attribute_name'])) {
$empty_num++;
}
}
if ($empty_num > 0) {
$this->error('每个子项的属性名或属性值必填');
}
}效果图:
查看全部
form
addMultifield($name = '', $title = '', $tips = '', $options = [], $default = [],$extra_class='') 添加多维字段序列化存储,每一行记录由options控制,field_name=>field_title
存储时 如 input('no') 获取出来是 [['name'=>'', 'value'=>'']]这样的结构;
测试代码
public function test(){效果图:
if(request()->isAjax()){
$mult_attribute = I('mult_attribute/a', []);
$this->checkPackagePrice($mult_attribute);
}else{
return ZBuilder::make('form')
->setPageTitle('新增商品-选择店铺')
->addMultifield('mult_attribute', '商品', '', ['name'=>'名称','value'=>'值'], '')
->fetch();
}
}
public function checkPackagePrice($mult_attribute){
$empty_num = 0;
foreach ($mult_attribute as $key => $row) {
if (empty($row['attribute_value']) || empty($row['attribute_name'])) {
$empty_num++;
}
}
if ($empty_num > 0) {
$this->error('每个子项的属性名或属性值必填');
}
}
扩展表格按树状显示
经验分享 • freebirdy 发表了文章 • 2 个评论 • 4879 次浏览 • 2017-08-24 21:05
具体修改方法:
第一步:在table的Builder.php里面增加一个方法 setTreeMode/**
* 设置树状表格,此模式建议设置为无分页模式
* @param string $key 唯一标识字段
* @param string $pkey 父结点字段
* @param int $pos 可控制列位置,默认为0,即第一列
* @param int $expand 默认展开层级,默认为1
*/
public function setTreeMode($key = "id", $pkey = "pid", $pos = 0, $expand = 1)
{
if (!empty($key) && !empty($pkey)) {
$this->_vars['tree_mode'] = [
'key' => $key,
'pkey' => $pkey,
'pos' => $pos,
'expand' => $expand,
];
}
return $this;
}第二步:修改table的layout.html
找到 tbody元素,加入属性<tbody{present name='tree_mode'} id="tree_table" expand="{$tree_mode.expand|default=1}" pos="{$tree_mode.pos|default=0}"{/present}</tbody>在tbody的循环体的tr里面,加入属性<tr class="{$row['_tr_class']|default=''}"{present name='tree_mode'} id="{$row[$tree_mode['key']]}" pid="{$row[$tree_mode['pkey']]}"{/present}></tr>
第三步:下载附件 treeTable.zip,解压后放至 __LIBS__ 目录,并利用dolphinPHP引入css和js的方法,将相应的JS和CSS文件引入,即可
第四步:加入树特效的执行代码,可以放到layout.html,也可以引入自定义的js文件$('#tree_table').treeTable({
expandLevel:$('#tree_table').attr("expand"),
column:$('#tree_table').attr("pos")
});
第五步:在控制器输出表格之前调用 setTreeMode 方法return ZBuilder::make('table')
....
->setTreeMode("id", "pid", 1, 99)
->noPages() //建议使用无分页模式,取数据的时候,一次性将数据取出来
->fetch();
记↓得↓不↓要↓忘↓了↓下↓载↓附↓件!
查看全部
具体修改方法:
第一步:在table的Builder.php里面增加一个方法 setTreeMode
/**第二步:修改table的layout.html
* 设置树状表格,此模式建议设置为无分页模式
* @param string $key 唯一标识字段
* @param string $pkey 父结点字段
* @param int $pos 可控制列位置,默认为0,即第一列
* @param int $expand 默认展开层级,默认为1
*/
public function setTreeMode($key = "id", $pkey = "pid", $pos = 0, $expand = 1)
{
if (!empty($key) && !empty($pkey)) {
$this->_vars['tree_mode'] = [
'key' => $key,
'pkey' => $pkey,
'pos' => $pos,
'expand' => $expand,
];
}
return $this;
}
找到 tbody元素,加入属性
<tbody{present name='tree_mode'} id="tree_table" expand="{$tree_mode.expand|default=1}" pos="{$tree_mode.pos|default=0}"{/present}</tbody>在tbody的循环体的tr里面,加入属性
<tr class="{$row['_tr_class']|default=''}"{present name='tree_mode'} id="{$row[$tree_mode['key']]}" pid="{$row[$tree_mode['pkey']]}"{/present}></tr>
第三步:下载附件 treeTable.zip,解压后放至 __LIBS__ 目录,并利用dolphinPHP引入css和js的方法,将相应的JS和CSS文件引入,即可
第四步:加入树特效的执行代码,可以放到layout.html,也可以引入自定义的js文件
$('#tree_table').treeTable({
expandLevel:$('#tree_table').attr("expand"),
column:$('#tree_table').attr("pos")
});
第五步:在控制器输出表格之前调用 setTreeMode 方法
return ZBuilder::make('table')
....
->setTreeMode("id", "pid", 1, 99)
->noPages() //建议使用无分页模式,取数据的时候,一次性将数据取出来
->fetch();
记↓得↓不↓要↓忘↓了↓下↓载↓附↓件!
【定时/计划任务】模块发布
模块&插件 • 流风回雪 发表了文章 • 31 个评论 • 14393 次浏览 • 2017-07-14 09:11
此模块可以在网站系统的后台管理定时任务,让系统自动的定时的执行SQL,Shell或者请求指定的URL。
任务计划使用与 linux 一致的的 cron 表达式进行配置,所以非常灵活。例如:0 23 ? * MON-FRI 这样配置就可以设置任务在 每周一至周五晚上11点30分 执行计划任务。至于 cron 表达式请自行百度查询!
模块大量抄袭了 FastAdmin 的设计,但 FastAdmin 不能后台查看任务的执行结果,只能在服务器上查看日志文件,而且日志记录还不完整。不过我们还是要感谢FastAdmin作者!
FastAdmin项目地址: git.oschina.net/karson/fastadmin
应用场景举例:
定时执行SQL,比如定时清理某些日志表;定时访问某个本地路径或者远程的URL,让其做某些工作;定时执行Shell命令,比如定时更新网站搜索引擎的索引。
安装流程:
1. 安装这两个依赖包composer require mtdowling/cron-expression
composer require guzzlehttp/guzzle
说明:
mtdowling/cron-expression 是用来解析、计算 cron 表达式的关键组件;
guzzlehttp/guzzle 用来请求远程 url 的。
2. 安装模块
把模块包解压后放到 application 目录,然后进系统后台安装本模块。
3. 把系统入口文件 index.php 改为下面代码
DolphinPHP V1.0.8 版本使用下面代码// 定义应用目录
define('APP_PATH', __DIR__ . '/application/');
// 定义后台入口文件
define('ADMIN_FILE', 'admin.php');
// 检查是否安装
if(!is_file(__DIR__ . '/data/install.lock')){
define('BIND_MODULE', 'install');
}
// 加载框架基础文件
require __DIR__ . '/thinkphp/base.php';
// cli 模式关闭路由
if (PHP_SAPI == 'cli'){
\think\App::route(false);
}
// 执行应用
\think\App::run()->send();
DolphinPHP V1.1.0 以上版本使用下面代码// 定义应用目录
define('APP_PATH', __DIR__ . '/../application/');
// 定义后台入口文件
define('ADMIN_FILE', 'admin.php');
// 检查是否安装
if(!is_file(__DIR__ . '/../data/install.lock')){
define('BIND_MODULE', 'install');
}
// 加载框架基础文件
require __DIR__ . '/../thinkphp/base.php';
// cli 模式关闭路由
if (PHP_SAPI == 'cli'){
\think\App::route(false);
}
// 执行应用
\think\App::run()->send();
说明:
把相对路径改成绝对路径的目的是为了使定时任务可以在命令行下的任意位置执行;cli模式下必须关闭系统的路由功能,否则 ThinkPHP 在检查路由的时候会报错,这貌似是 ThinkPHP 的BUG;
4. 开启PHP的 shell_exec() 函数
打开 php.ini ,在里面搜索 disable_functions ,然后把等号后面的 shell_exec 删掉执行 /etc/init.d/httpd restart 重启 Apache ,如果是 Nginx 的话执行 /etc/init.d/php-fpm restart 重启 PHP
5. 添加一个Linux上的crontab定时任务
执行 crontab -e ,在里面添加一条定时任务,让服务器每1分钟访问一次我们的任务执行接口* * * * * /usr/bin/php /你网站的完整根路径(绝对路径)/index.php /crontab/autotask(1、注意空格;2、注意 DolphinPHP V1.1.0 以上版本入口文件是在 public 目录)
6. 到网站后台添加任务即可
截图:
任务列表
请求本地路径配置
配置定时执行SQL
请求远程URL,这里故意把url写错,用来测试请求失败的效果
执行的任务日志列表
可以看到,上面请求远程URL的任务内容配置错了,这里执行失败后便记录下了错误内容
执行Shell命令后记录返回的结果
模块包:
适用于 DolphinPHP V1.0.8
crontab_v1_0_8.zip
适用于 DolphinPHP V1.1.0 以上版本
crontab_v1_1_0.zip
从 DolphinPHP 1.0.8 升级到 1.1.0
1、升级时如果用升级包里的 vendor 替换了原系统的 vendor,请检查模块需要的那两个依赖包是否存在,如果被替换或删除了,请重新安装;
2、升级后如果覆盖了 index.php 入口文件,请照文中方法修改;
3、重新下载文中适用于 DolphinPHP V1.1.0 以上版本的模块包进行覆盖(实际上是需要覆盖 /crontab/view/admin/index/add.html 文件和 /crontab/home/Autotask.php 即可)
4、执行 crontab -e 命令,修改 Linux 定时任务中网站系统入口文件的绝对路径,因为 1.1.0 把入口调整到了 public 目录,这里也需要在 index.php 前面加上 public
更新日志:
2018-02-21:
1. 修复升级到 Dolphinphp v1.1.0 后本地 URL 任务执行错误问题;
2018-01-24:
1. 修改模板文件以支持 DolphinPHP V1.1.0 以上版本;
2. 上文中的安装说明新增 DolphinPHP V1.1.0 以上版本注意事项;
2017-10-27:
1. 支持 DolphinPHP V1.0.8(V1.0.8以下版本需要删除表格构建器的raw()方法,V1.0.7系统有BUG,所以不支持);
2. 把 rmccue/requests 组件换成 guzzlehttp/guzzle;
2017-07-15:
1. 更换掉后台任务管理模板的那种蛋疼的写法;
2. 修改任务执行接口上的一个小bug;
注意:
不支持windows环境 查看全部
此模块可以在网站系统的后台管理定时任务,让系统自动的定时的执行SQL,Shell或者请求指定的URL。
任务计划使用与 linux 一致的的 cron 表达式进行配置,所以非常灵活。例如:0 23 ? * MON-FRI 这样配置就可以设置任务在 每周一至周五晚上11点30分 执行计划任务。至于 cron 表达式请自行百度查询!
模块大量抄袭了 FastAdmin 的设计,但 FastAdmin 不能后台查看任务的执行结果,只能在服务器上查看日志文件,而且日志记录还不完整。不过我们还是要感谢FastAdmin作者!
FastAdmin项目地址: git.oschina.net/karson/fastadmin
应用场景举例:
- 定时执行SQL,比如定时清理某些日志表;
- 定时访问某个本地路径或者远程的URL,让其做某些工作;
- 定时执行Shell命令,比如定时更新网站搜索引擎的索引。
安装流程:
1. 安装这两个依赖包
composer require mtdowling/cron-expression
composer require guzzlehttp/guzzle
说明:
mtdowling/cron-expression 是用来解析、计算 cron 表达式的关键组件;
guzzlehttp/guzzle 用来请求远程 url 的。
2. 安装模块
把模块包解压后放到 application 目录,然后进系统后台安装本模块。
3. 把系统入口文件 index.php 改为下面代码
DolphinPHP V1.0.8 版本使用下面代码
// 定义应用目录
define('APP_PATH', __DIR__ . '/application/');
// 定义后台入口文件
define('ADMIN_FILE', 'admin.php');
// 检查是否安装
if(!is_file(__DIR__ . '/data/install.lock')){
define('BIND_MODULE', 'install');
}
// 加载框架基础文件
require __DIR__ . '/thinkphp/base.php';
// cli 模式关闭路由
if (PHP_SAPI == 'cli'){
\think\App::route(false);
}
// 执行应用
\think\App::run()->send();
DolphinPHP V1.1.0 以上版本使用下面代码
// 定义应用目录
define('APP_PATH', __DIR__ . '/../application/');
// 定义后台入口文件
define('ADMIN_FILE', 'admin.php');
// 检查是否安装
if(!is_file(__DIR__ . '/../data/install.lock')){
define('BIND_MODULE', 'install');
}
// 加载框架基础文件
require __DIR__ . '/../thinkphp/base.php';
// cli 模式关闭路由
if (PHP_SAPI == 'cli'){
\think\App::route(false);
}
// 执行应用
\think\App::run()->send();
说明:
- 把相对路径改成绝对路径的目的是为了使定时任务可以在命令行下的任意位置执行;
- cli模式下必须关闭系统的路由功能,否则 ThinkPHP 在检查路由的时候会报错,这貌似是 ThinkPHP 的BUG;
4. 开启PHP的 shell_exec() 函数
- 打开 php.ini ,在里面搜索 disable_functions ,然后把等号后面的 shell_exec 删掉
- 执行 /etc/init.d/httpd restart 重启 Apache ,如果是 Nginx 的话执行 /etc/init.d/php-fpm restart 重启 PHP
5. 添加一个Linux上的crontab定时任务
执行 crontab -e ,在里面添加一条定时任务,让服务器每1分钟访问一次我们的任务执行接口
* * * * * /usr/bin/php /你网站的完整根路径(绝对路径)/index.php /crontab/autotask(1、注意空格;2、注意 DolphinPHP V1.1.0 以上版本入口文件是在 public 目录)
6. 到网站后台添加任务即可
截图:
任务列表
请求本地路径配置
配置定时执行SQL
请求远程URL,这里故意把url写错,用来测试请求失败的效果
执行的任务日志列表
可以看到,上面请求远程URL的任务内容配置错了,这里执行失败后便记录下了错误内容
执行Shell命令后记录返回的结果
模块包:
适用于 DolphinPHP V1.0.8
适用于 DolphinPHP V1.1.0 以上版本
从 DolphinPHP 1.0.8 升级到 1.1.0
1、升级时如果用升级包里的 vendor 替换了原系统的 vendor,请检查模块需要的那两个依赖包是否存在,如果被替换或删除了,请重新安装;
2、升级后如果覆盖了 index.php 入口文件,请照文中方法修改;
3、重新下载文中适用于 DolphinPHP V1.1.0 以上版本的模块包进行覆盖(实际上是需要覆盖 /crontab/view/admin/index/add.html 文件和 /crontab/home/Autotask.php 即可)
4、执行 crontab -e 命令,修改 Linux 定时任务中网站系统入口文件的绝对路径,因为 1.1.0 把入口调整到了 public 目录,这里也需要在 index.php 前面加上 public
更新日志:
2018-02-21:
1. 修复升级到 Dolphinphp v1.1.0 后本地 URL 任务执行错误问题;
2018-01-24:
1. 修改模板文件以支持 DolphinPHP V1.1.0 以上版本;
2. 上文中的安装说明新增 DolphinPHP V1.1.0 以上版本注意事项;
2017-10-27:
1. 支持 DolphinPHP V1.0.8(V1.0.8以下版本需要删除表格构建器的raw()方法,V1.0.7系统有BUG,所以不支持);
2. 把 rmccue/requests 组件换成 guzzlehttp/guzzle;
2017-07-15:
1. 更换掉后台任务管理模板的那种蛋疼的写法;
2. 修改任务执行接口上的一个小bug;
注意:
不支持windows环境
环迅支付插件
模块&插件 • cklnk 发表了文章 • 0 个评论 • 2932 次浏览 • 2017-06-30 14:18
$payment_data = [
'GoodsName' => '充值',
'MerBillNo' => '订单号',
'Amount' => '金额',
'Attach' => '备注',
'Merchanturl' => '',
'ServerUrl' => '',
'UserRealName' => '',//自动注册
'UserId' => '',//自动注册
];
plugin_action('Ipspay/Ipspay/payment', [$payment_data, 'h5']);
解压到plugins文件夹下即可 查看全部
IIS 7.下面URL Rewrite的路由配置
经验分享 • 小兔言言 发表了文章 • 0 个评论 • 3168 次浏览 • 2017-06-28 22:17
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="thinkPhp" enabled="true" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="index.php/{R:0}" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration> 查看全部
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="thinkPhp" enabled="true" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="index.php/{R:0}" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
PHPMailer邮件类插件
模块&插件 • july 发表了文章 • 2 个评论 • 3348 次浏览 • 2017-06-27 13:49
安装此插件前,请先使用命令composer require phpmailer/phpmailer 安装PHPMailer
public function send_phpmailer(){
$res = PHPMailer::send_email('测试宝宝','测试内容','to_user_emial','alias');
dump($res);
}
查看全部
SwiftMailer邮件类插件
模块&插件 • july 发表了文章 • 2 个评论 • 2519 次浏览 • 2017-06-27 13:11
安装此插件前,请先使用命令composer require swiftmailer/swiftmailer 安装SwiftMailer
测试方法public function send_email(){
$res = SwiftMailer::send_email('测试宝宝','测试内容',to_user_emial);
dump($res);
} 查看全部
百度合成语音插件,初学初试,请各位指教
模块&插件 • july 发表了文章 • 0 个评论 • 2833 次浏览 • 2017-06-20 17:52
根据百度合成语音的文档把基本能用的参数作为配置
因为是根据api测试的,所以报错直接$this->result();
下面是测试方法,请先引入use plugins\BaiduTTS\controller\BaiduTTS;测试方法public function test_tts(Request $request){
$msg = $request->param('msg');
$tts = new BaiduTTS();
$file = $tts->send($msg);
if (empty($file) || $file === false){
$this->result(null,400,'error','json');
}
$this->result(['audio'=>$file],200,'success','json');
}
在浏览器输入中文正常,postman中输入中文pathinfo接收到的参数似乎转码了,以 ? 的get参数能正常
还请各位多指教啦
查看全部
根据百度合成语音的文档把基本能用的参数作为配置
因为是根据api测试的,所以报错直接$this->result();
下面是测试方法,请先引入
use plugins\BaiduTTS\controller\BaiduTTS;测试方法
public function test_tts(Request $request){
$msg = $request->param('msg');
$tts = new BaiduTTS();
$file = $tts->send($msg);
if (empty($file) || $file === false){
$this->result(null,400,'error','json');
}
$this->result(['audio'=>$file],200,'success','json');
}
在浏览器输入中文正常,postman中输入中文pathinfo接收到的参数似乎转码了,以 ? 的get参数能正常
还请各位多指教啦
thinkphp+TCPDF生成PDF文件,最新版TCPDF6.2.13,熟肉!即拿即用
经验分享 • xin5288 发表了文章 • 1 个评论 • 4244 次浏览 • 2017-06-07 17:33
新建文件夹 / extend / Tcpdf
将附件压缩包内的东西解压到/ extend / Tcpdf
使用方法
use tcpdf\Tcpdf;
class PDF extends Common
{
public function index()
{
// create new PDF document
$pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
// set document information
$pdf->SetCreator(PDF_CREATOR);
$pdf->SetAuthor('Nicola Asuni');
$pdf->SetTitle('TCPDF Example 001');
$pdf->SetSubject('TCPDF Tutorial');
$pdf->SetKeywords('TCPDF, PDF, example, test, guide');
// set default header data
$pdf->SetHeaderData(PDF_HEADER_LOGO, PDF_HEADER_LOGO_WIDTH, PDF_HEADER_TITLE.' 001', PDF_HEADER_STRING, array(0,64,255), array(0,64,128));
$pdf->setFooterData(array(0,64,0), array(0,64,128));
// set header and footer fonts
$pdf->setHeaderFont(Array(PDF_FONT_NAME_MAIN, '', PDF_FONT_SIZE_MAIN));
$pdf->setFooterFont(Array(PDF_FONT_NAME_DATA, '', PDF_FONT_SIZE_DATA));
// set default monospaced font
$pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
// set margins
$pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT);
$pdf->SetHeaderMargin(PDF_MARGIN_HEADER);
$pdf->SetFooterMargin(PDF_MARGIN_FOOTER);
// set auto page breaks
$pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM);
// set image scale factor
$pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
// set some language-dependent strings (optional)
if (@file_exists(dirname(__FILE__).'/lang/eng.php')) {
require_once(dirname(__FILE__).'/lang/eng.php');
$pdf->setLanguageArray($l);
}
// ---------------------------------------------------------
// set default font subsetting mode
$pdf->setFontSubsetting(true);
// Set font
// dejavusans is a UTF-8 Unicode font, if you only need to
// print standard ASCII chars, you can use core fonts like
// helvetica or times to reduce file size.
$pdf->SetFont('dejavusans', '', 14, '', true);
// Add a page
// This method has several options, check the source code documentation for more information.
$pdf->AddPage();
// set text shadow effect
$pdf->setTextShadow(array('enabled'=>true, 'depth_w'=>0.2, 'depth_h'=>0.2, 'color'=>array(196,196,196), 'opacity'=>1, 'blend_mode'=>'Normal'));
// Set some content to print
$html = <<<EOD
<h1>Welcome to <a href="h提提p://www点tcpdf点org" style="text-decoration:none;background-color:#CC0000;color:black;"> <span style="color:black;">TC</span><span style="color:white;">PDF</span> </a>!</h1>
<i>This is the first example of TCPDF library.</i>
<p>This text is printed using the <i>writeHTMLCell()</i> method but you can also use: <i>Multicell(), writeHTML(), Write(), Cell() and Text()</i>.</p>
<p>Please check the source code documentation and other examples for further information.</p>
<p style="color:#CC0000;">TO IMPROVE AND EXPAND TCPDF I NEED YOUR SUPPORT, PLEASE <a href="h提提p://sourceforge点net/donate/index
点
php?group_id=128076">MAKE A DONATION!</a></p>
EOD;
// Print text using writeHTMLCell()
$pdf->writeHTMLCell(0, 0, '', '', $html, 0, 1, 0, true, '', true);
// ---------------------------------------------------------
// Close and output PDF document
// This method has several options, check the source code documentation for more information.
$pdf->Output('example_001.pdf', 'I');
//============================================================+
// END OF FILE
//============================================================+
}
} 查看全部
新建文件夹 / extend / Tcpdf
将附件压缩包内的东西解压到/ extend / Tcpdf
使用方法
use tcpdf\Tcpdf;
class PDF extends Common
{
public function index()
{
// create new PDF document
$pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
// set document information
$pdf->SetCreator(PDF_CREATOR);
$pdf->SetAuthor('Nicola Asuni');
$pdf->SetTitle('TCPDF Example 001');
$pdf->SetSubject('TCPDF Tutorial');
$pdf->SetKeywords('TCPDF, PDF, example, test, guide');
// set default header data
$pdf->SetHeaderData(PDF_HEADER_LOGO, PDF_HEADER_LOGO_WIDTH, PDF_HEADER_TITLE.' 001', PDF_HEADER_STRING, array(0,64,255), array(0,64,128));
$pdf->setFooterData(array(0,64,0), array(0,64,128));
// set header and footer fonts
$pdf->setHeaderFont(Array(PDF_FONT_NAME_MAIN, '', PDF_FONT_SIZE_MAIN));
$pdf->setFooterFont(Array(PDF_FONT_NAME_DATA, '', PDF_FONT_SIZE_DATA));
// set default monospaced font
$pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
// set margins
$pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT);
$pdf->SetHeaderMargin(PDF_MARGIN_HEADER);
$pdf->SetFooterMargin(PDF_MARGIN_FOOTER);
// set auto page breaks
$pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM);
// set image scale factor
$pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
// set some language-dependent strings (optional)
if (@file_exists(dirname(__FILE__).'/lang/eng.php')) {
require_once(dirname(__FILE__).'/lang/eng.php');
$pdf->setLanguageArray($l);
}
// ---------------------------------------------------------
// set default font subsetting mode
$pdf->setFontSubsetting(true);
// Set font
// dejavusans is a UTF-8 Unicode font, if you only need to
// print standard ASCII chars, you can use core fonts like
// helvetica or times to reduce file size.
$pdf->SetFont('dejavusans', '', 14, '', true);
// Add a page
// This method has several options, check the source code documentation for more information.
$pdf->AddPage();
// set text shadow effect
$pdf->setTextShadow(array('enabled'=>true, 'depth_w'=>0.2, 'depth_h'=>0.2, 'color'=>array(196,196,196), 'opacity'=>1, 'blend_mode'=>'Normal'));
// Set some content to print
$html = <<<EOD
<h1>Welcome to <a href="h提提p://www点tcpdf点org" style="text-decoration:none;background-color:#CC0000;color:black;"> <span style="color:black;">TC</span><span style="color:white;">PDF</span> </a>!</h1>
<i>This is the first example of TCPDF library.</i>
<p>This text is printed using the <i>writeHTMLCell()</i> method but you can also use: <i>Multicell(), writeHTML(), Write(), Cell() and Text()</i>.</p>
<p>Please check the source code documentation and other examples for further information.</p>
<p style="color:#CC0000;">TO IMPROVE AND EXPAND TCPDF I NEED YOUR SUPPORT, PLEASE <a href="h提提p://sourceforge点net/donate/index
点
php?group_id=128076">MAKE A DONATION!</a></p>
EOD;
// Print text using writeHTMLCell()
$pdf->writeHTMLCell(0, 0, '', '', $html, 0, 1, 0, true, '', true);
// ---------------------------------------------------------
// Close and output PDF document
// This method has several options, check the source code documentation for more information.
$pdf->Output('example_001.pdf', 'I');
//============================================================+
// END OF FILE
//============================================================+
}
}
开发模块
模块&插件 • yangweijie 发表了文章 • 5 个评论 • 3191 次浏览 • 2017-05-29 12:06
同时移植了laravel-admin 的 脚手架里的 database 。目前只支持一个数据库。
使用方法,将附件dev 压缩包 解压到dev 目录,然后放入application模块目录里去,将dev目录里的public 覆盖根目录public里去。其实就是用了codemirror插件。
装好后,在cmd 切换到应用根目录,里 执行 composer 安装 symfony/console, symfony/var-dumper 这两个组件,最后在 应用的函数库里 添加以下代码use Symfony\Component\VarDumper\VarDumper;
if (!function_exists('vardump')) {
/**
* @author Nicolas Grekas <p@tchwork.com>
*/
function vardump($var)
{
foreach (func_get_args() as $var) {
VarDumper::dump($var);
}
}
}然后装好模块就可以使用该模块的功能了。如果有使用问题,请论坛@我
查看全部
同时移植了laravel-admin 的 脚手架里的 database 。目前只支持一个数据库。
使用方法,将附件dev 压缩包 解压到dev 目录,然后放入application模块目录里去,将dev目录里的public 覆盖根目录public里去。其实就是用了codemirror插件。
装好后,在cmd 切换到应用根目录,里 执行 composer 安装 symfony/console, symfony/var-dumper 这两个组件,最后在 应用的函数库里 添加以下代码
use Symfony\Component\VarDumper\VarDumper;然后装好模块就可以使用该模块的功能了。如果有使用问题,请论坛@我
if (!function_exists('vardump')) {
/**
* @author Nicolas Grekas <p@tchwork.com>
*/
function vardump($var)
{
foreach (func_get_args() as $var) {
VarDumper::dump($var);
}
}
}