TF社区维护版】
*
* @package QNUpload
* @author rakiy
* @version 1.3.1
* @link https://del.pub/post/qnupload.html
* @date 2016-12-09
*/
class QNUpload_Plugin implements Typecho_Plugin_Interface
{
/**
* 激活插件方法,如果激活失败,直接抛出异常
*
* @access public
* @return void
* @throws Typecho_Plugin_Exception
*/
public static function activate(){
//上传
Typecho_Plugin::factory('Widget_Upload')->uploadHandle = array('QNUpload_Plugin', 'uploadHandle');
//修改
Typecho_Plugin::factory('Widget_Upload')->modifyHandle = array('QNUpload_Plugin', 'modifyHandle');
//删除
Typecho_Plugin::factory('Widget_Upload')->deleteHandle = array('QNUpload_Plugin', 'deleteHandle');
//路径参数处理
Typecho_Plugin::factory('Widget_Upload')->attachmentHandle = array('QNUpload_Plugin', 'attachmentHandle');
//文件内容数据
Typecho_Plugin::factory('Widget_Upload')->attachmentDataHandle = array('QNUpload_Plugin', 'attachmentDataHandle');
}
/**
* 禁用插件方法,如果禁用失败,直接抛出异常
*
* @static
* @access public
* @return void
* @throws Typecho_Plugin_Exception
*/
public static function deactivate(){}
/**
* 获取插件配置面板
*
* @access public
* @param Typecho_Widget_Helper_Form $form 配置面板
* @return void
*/
public static function config(Typecho_Widget_Helper_Form $form){
$ak = new Typecho_Widget_Helper_Form_Element_Text('ak',
NULL, '',
_t('Access Key'),
_t('获取Access Key'));
$form->addInput($ak);
$sk = new Typecho_Widget_Helper_Form_Element_Text('sk',
NULL, '',
_t('Secure Key'),
_t('获取Secure Key'));
$form->addInput($sk);
$bucketName = new Typecho_Widget_Helper_Form_Element_Text('bucket',
NULL, 'bucketName',
_t('Bucket名称'),
_t(''));
$form->addInput($bucketName);
$server = new Typecho_Widget_Helper_Form_Element_Radio('server',
array('0'=>_t('华东'), '1'=>_t('华北'), '2'=>_t('华南'), '3'=>_t('北美')),
'0',
_t('选择bucket节点'),
_t('一般在七牛面板右下角显示')
);
$form->addInput($server);
$domain = new Typecho_Widget_Helper_Form_Element_Text('domain',
NULL, 'http://',
_t('使用的域名,必填,请带上http://'),
_t('一般在七牛存储面板右上角,形如 xxx.bkt.clouddn.com/xxx.u.qiniu.com'));
$form->addInput($domain);
}
/**
* 个人用户的配置面板
*
* @access public
* @param Typecho_Widget_Helper_Form $form
* @return void
*/
public static function personalConfig(Typecho_Widget_Helper_Form $form){}
/**
* 上传文件处理函数
*
* @access public
* @param array $file 上传的文件
* @return mixed
*/
public static function uploadHandle($file){
if (empty($file['name'])) return false;
//获取扩展名
$ext = self::getSafeName($file['name']);
//判定是否是允许的文件类型
if (!Widget_Upload::checkFileType($ext)) return false;
//获取文件名
$filePath = date('Y') . '/' . date('m') . '/';
$fileName = sprintf('%u', crc32(uniqid())) . '.' . $ext;
//如果没有临时文件,则退出
if(!isset($file['tmp_name'])) return false;
//获取插件参数
$options = Typecho_Widget::widget('Widget_Options')->plugin('QNUpload');
//初始化七牛
self::__qninit__($options);
$putPolicy = new Qiniu_RS_PutPolicy($options->bucket);
$upToken = $putPolicy->Token(null);
$putExtra = new Qiniu_PutExtra();
list($ret, $err) = Qiniu_PutFile($upToken, $filePath . $fileName, $file['tmp_name'], $putExtra);
if($err !== null) return false;
return array(
'name' => $file['name'],
'path' => $filePath . $fileName,
'size' => $file['size'],
'type' => $ext,
'mime' => @Typecho_Common::mimeContentType(rtrim($options->domain,'/') . '/' . $filePath . $fileName),
);
}
/**
* 文件修改处理函数
*
* @access public
* @param array $content 当前文件信息
* @param array $file 新上传文件信息
* @return mixed
*/
public static function modifyHandle($content, $file){
if (empty($file['name'])) return false;
//获取扩展名
$ext = self::getSafeName($file['name']);
if ($content['attachment']->type != $ext) return false;
//获取文件名
$fileName = $content['attachment']->path;
//获取插件参数
$options = Typecho_Widget::widget('Widget_Options')->plugin('QNUpload');
$bucket = $options->bucket;
//初始化七牛
self::__qninit__($options);
//如果没有临时文件,则退出
if(!isset($file['tmp_name'])) return false;
//上传前删除旧文件
$client = new Qiniu_MacHttpClient(null);
$err = Qiniu_RS_Delete($client, $bucket, $fileName);
//重新上传
$putPolicy = new Qiniu_RS_PutPolicy($options->bucket);
$upToken = $putPolicy->Token(null);
$putExtra = new Qiniu_PutExtra();
list($ret, $err) = Qiniu_PutFile($upToken, $fileName, $file['tmp_name'], $putExtra);
if($err !== null) return false;
return array(
'name' => $file['name'],
'path' => $fileName,
'size' => $file['size'],
'type' => $ext,
'mime' => @Typecho_Common::mimeContentType(rtrim($options->domain,'/') . '/' . $fileName),
);
}
/**
* 文件删除
*
* @access public
* @param array $content 当前文件信息
* @return mixed
*/
public static function deleteHandle($content){
$options = Typecho_Widget::widget('Widget_Options')->plugin('QNUpload');
self::__qninit__($options);
$client = new Qiniu_MacHttpClient(null);
$err = Qiniu_RS_Delete($client, $options->bucket, $content['attachment']->path);
return !$err;
}
/**
* 获取实际文件数据
*
* @access public
* @param array $content
* @return string
*/
public static function attachmentDataHandle($content){
$options = Typecho_Widget::widget('Widget_Options')->plugin('QNUpload');
self::__qninit__($options);
list($ret, $err) = Qiniu_RS_Stat($client, $options->bucket, $fileName);
return $err === null ? $ret : false;
}
/**
* 获取实际文件绝对访问路径
*
* @access public
* @param array $content 文件相关信息
* @return string
*/
public static function attachmentHandle(array $content){
$domain = Typecho_Widget::widget('Widget_Options')->plugin('QNUpload')->domain;
//因为七牛放弃了默认的 xxx.u.qiniudn.com,且api中并无域名返回,所以域名为必填
$tmp = preg_match('/http(s)?:\/\/[\w\d\.\-\/]+$/is', $domain); //粗略验证域名
if(!$tmp) return false;
return Typecho_Common::url($content['attachment']->path, $domain);
}
/**
* 七牛初始化
*
* @access public
* @return object
*/
private static function __qninit__($options){
$server = intval($options->server);
require_once("Qiniu/rs.php");
require_once("Qiniu/io.php");
$accessKey = $options->ak;
$secretKey = $options->sk;
Qiniu_SetKeys($accessKey, $secretKey);
}
/**
* 获取安全的文件名
*
* @param string $name
* @static
* @access private
* @return string
*/
private static function getSafeName(&$name){
$name = str_replace(array('"', '<', '>'), '', $name);
$name = str_replace('\\', '/', $name);
$name = false === strpos($name, '/') ? ('a' . $name) : str_replace('/', '/a', $name);
$info = pathinfo($name);
$name = substr($info['basename'], 1);
return isset($info['extension']) ? strtolower($info['extension']) : '';
}
/**
* 创建上传路径
*
* @access private
* @param string $path 路径
* @return boolean
*/
private static function makeUploadDir($path){
$path = preg_replace("/\\\+/", '/', $path);
$current = rtrim($path, '/');
$last = $current;
while (!is_dir($current) && false !== strpos($path, '/')) {
$last = $current;
$current = dirname($current);
}
if ($last == $current) {
return true;
}
if (!@mkdir($last)) {
return false;
}
$stat = @stat($last);
$perms = $stat['mode'] & 0007777;
@chmod($last, $perms);
return self::makeUploadDir($path);
}
}