最近一个用来娱乐的小站由于考虑到速度问题,图片需要采用七牛云存储。由于老九发文章的时候还是比较熟悉PHPCMS,考虑尽可能不影响后台体验,采用了深度接入的方式。另外,大部分上传功能都抛弃swfupload,毕竟flash是各平台报警大户,对SEO不利。
添加七牛PHP和JS sdk
具体的可以参考七牛的官方SDK文档。这里可以选择通过composer和npm分别加载,根据个人喜好自行选择吧。
修改form.class.php
从这里开始一系列的调整。
首先,增加js引入,如果要兼容以前的swfupload,就在所有swf2ckeditor.js引入后面增加qn2ckeditor.js的引入。如果不需要,直接将swf2全页替换为qn2即可。修改的地方比较多,请注意检查。
qn2ckeditor.js文件从swf2ckeditor修改而来,具体可参考下文。
然后修改 images方法下的flashupload为qnupload即可。
修改caches_form.class.php
这个细节比较难找到。修改该文件中的image方法,同样增加qn2ckeditor.js的引入,并修改flashupload为qnupload。
配置qn2ckeditor.js
目的是让phpcms自带的CKeditor接入云存储。
拷贝/statics/js/swfupload目录下的swf2ckeditor.js为qn2ckeditor.js,将flashupload函数修改为:
function qnupload(uploadid, name, textareaid, funcName, args, module, catid, authkey) {
var args = args ? '&args='+args : '';
var setting = '&module='+module+'&catid='+catid+'&authkey='+authkey;
window.top.art.dialog({
title:name,id:uploadid,iframe:'index.php?m=attachment&c=attachments&a=qnupload'+args+setting,width:'500',height:'420'},
function(){
if(funcName) {
funcName.apply(this,[uploadid,textareaid]);
}else {
submit_ckeditor(uploadid,textareaid);
}
},
function(){
window.top.art.dialog({id:uploadid}).close()
}
);
}
其他函数不需要修改。很多参数是不影响的,这里就没修改了
修改attachments.php,增加两个控制器函数
这一块的修改主要为了保证各个上传界面接入正常。注意,修改之前请先引入Qiniu。
use Qiniu\Auth;
use Qiniu\Storage\UploadManager;
1. 增加upload76() 该函数为普通上传调用
/**
* 常规上传七牛版本
*/
public function upload76() {
//加载七牛SDK
$bucket = 'deadnine.com';
$accessKey = '你的KEY';
$secretKey = '你的KEY';
$auth = new Auth($accessKey, $secretKey);
$upToken = $auth->uploadToken($bucket);
$upDomain= 'http://www.deadnine.com/';
$filePath=$_FILES['upload']['tmp_name'];
$fileName=$_FILES['upload']['name'];
list($msec, $sec) = explode(' ', microtime());
$msectime = (float)sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000);
$key=$msectime.'_'.$fileName;
$uploadMgr = new UploadManager();
list($ret, $err) = $uploadMgr->putFile($upToken, $key, $filePath);
echo "上传结果:";
if ($err !== null) {
var_dump($err);
} else {
$fn = intval($_GET['CKEditorFuncNum']);
$fileurl = $upDomain.$key;
$str='<script type="text/javascript">window.parent.CKEDITOR.tools.callFunction('.$fn.', \''.$fileurl.'\', \''.'\');</script>';
exit($str);
}
}
2. 增加qnupload() 该函数用于打开窗口采用JS方法上传。不需要的可以省略该函数
/**
* qnupload上传附件
*/
public function qnupload(){
//加载七牛SDK
$bucket = 'www.deadnine.com';
$accessKey = '你的KEY';
$secretKey = '你的KEY';
$auth = new Auth($accessKey, $secretKey);
$upToken = $auth->uploadToken($bucket);
$upDomain= 'http://www.deadnine.com/';
$grouplist = getcache('grouplist','member');
if(isset($_POST['dosubmit'])){
} else {
if($this->isadmin==0 && !$grouplist[$this->groupid]['allowattachment']) showmessage(L('att_no_permission'));
include $this->admin_tpl('qnupload');
}
}
对应的,你需要编写模板文件qnupload.tpl.php,对照swfupload做简要修改即可。这里略过。如果有需要可以联系老九。
修改attachment.class.php
修改该文件目的主要是为了让图片本地化自动上传。
同样,先引入
use Qiniu\Auth;
use Qiniu\Storage\BucketManager;
修改download方法
function download($field, $value,$watermark = '0',$ext = 'gif|jpg|jpeg|bmp|png', $absurl = '', $basehref = '')
{
//加载七牛SDK
$upload_domain = 'www.deadnine.com';
$domain = 'http://www.deadnine.com/';
$accessKey = '你的KEY';
$secretKey = '你的KEY';
$auth = new Auth($accessKey, $secretKey);
$bucketMgr = new BucketManager($auth);
$bucket = 'deadnine.com';
global $image_d;
$this->att_db = pc_base::load_model('attachment_model');
$upload_url = pc_base::load_config('system','upload_url');
$this->field = $field;
$dir = date('Y/md/');
$uploadpath = $upload_url.$dir;
$uploaddir = $this->upload_root.$dir;
$string = new_stripslashes($value);
if(!preg_match_all("/(href|src)=([\"|']?)([^ \"'>]+\.($ext))\\2/i", $string, $matches)) return $value;
$remotefileurls = array();
foreach($matches[3] as $matche)
{
if(strpos($matche, '://') === false) continue;
dir_create($uploaddir);
$remotefileurls[$matche] = $this->fillurl($matche, $absurl, $basehref);
}
unset($matches, $string);
$remotefileurls = array_unique($remotefileurls);
$oldpath = $newpath = array();
foreach($remotefileurls as $k=>$file) {
//增加七牛的默认过滤路径
if(strpos($file, '://') === false || strpos($file, $upload_url) !== false || strpos($file, $upload_domain) !== false) continue;
list($msec, $sec) = explode(' ', microtime());
$msectime = (float)sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000);
$filename = fileext($file);
if(!preg_match("/($ext)/is",$filename) || in_array($filename, array('php','phtml','php3','php4','jsp','dll','asp','cer','asa','shtml','shtm','aspx','asax','cgi','fcgi','pl'))){
continue;
}
$file_name = basename($file);
$filename = $this->getname($filename);
$key=$msectime.'_'.$filename;
$items = $bucketMgr->fetch($file,$bucket,$key);
$oldpath[] = $k;
$newpath[] = $domain.$key;
}
return str_replace($oldpath, $newpath, $value);
}
这种方式可以兼容本地存储和云存储,解决冲突问题。
到此基本需要修改的地方就完成了。其中细节很多,有需要的请主要参考本案例的逻辑。如果实践中有问题可以联系老九。