diff --git a/.gitattributes b/.gitattributes
deleted file mode 100644
index bdb0cab..0000000
--- a/.gitattributes
+++ /dev/null
@@ -1,17 +0,0 @@
-# Auto detect text files and perform LF normalization
-* text=auto
-
-# Custom for Visual Studio
-*.cs diff=csharp
-
-# Standard to msysgit
-*.doc diff=astextplain
-*.DOC diff=astextplain
-*.docx diff=astextplain
-*.DOCX diff=astextplain
-*.dot diff=astextplain
-*.DOT diff=astextplain
-*.pdf diff=astextplain
-*.PDF diff=astextplain
-*.rtf diff=astextplain
-*.RTF diff=astextplain
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 96374c4..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,43 +0,0 @@
-# Windows image file caches
-Thumbs.db
-ehthumbs.db
-
-# Folder config file
-Desktop.ini
-
-# Recycle Bin used on file shares
-$RECYCLE.BIN/
-
-# Windows Installer files
-*.cab
-*.msi
-*.msm
-*.msp
-
-# Windows shortcuts
-*.lnk
-
-# =========================
-# Operating System Files
-# =========================
-
-# OSX
-# =========================
-
-.DS_Store
-.AppleDouble
-.LSOverride
-
-# Thumbnails
-._*
-
-# Files that might appear on external disk
-.Spotlight-V100
-.Trashes
-
-# Directories potentially created on remote AFP share
-.AppleDB
-.AppleDesktop
-Network Trash Folder
-Temporary Items
-.apdisk
diff --git a/Plugin.php b/Plugin.php
index 8efe068..9b885e9 100644
--- a/Plugin.php
+++ b/Plugin.php
@@ -1,770 +1,774 @@
-to($activatedPlugins);
- $activatedPlugins = json_decode(json_encode($activatedPlugins),true);
- $plugins_list = $activatedPlugins['stack'];
- $plugins_info = array();
- for ($i = 0; $i < count($plugins_list); $i++){
- if($plugins_list[$i]['title'] == 'AliOssForTypecho'){
- $plugins_info = $plugins_list[$i];
- break;
- }
- }
- if (count($plugins_info) < 1) {
- return false;
- }
- return $plugins_info;
- }
-
-
- /**
- * 激活插件方法,如果激活失败,直接抛出异常
- *
- * @access public
- * @return void
- * @throws Typecho_Plugin_Exception
- */
- public static function activate() {
- Typecho_Plugin::factory('Widget_Upload')->uploadHandle = array('AliOssForTypecho_Plugin', 'uploadHandle');
- Typecho_Plugin::factory('Widget_Upload')->modifyHandle = array('AliOssForTypecho_Plugin', 'modifyHandle');
- Typecho_Plugin::factory('Widget_Upload')->deleteHandle = array('AliOssForTypecho_Plugin', 'deleteHandle');
- Typecho_Plugin::factory('Widget_Upload')->attachmentHandle = array('AliOssForTypecho_Plugin', 'attachmentHandle');
- Typecho_Plugin::factory('Widget_Upload')->attachmentDataHandle = array('AliOssForTypecho_Plugin', 'attachmentDataHandle');
-
- Helper::addRoute('__alioss_for_tp_plugin_version__', '/__alioss_for_tp_plugin_api__/version', 'AliOssForTypecho_Plugin', 'api_version');
- Helper::addRoute('__alioss_for_tp_plugin_log__', '/__alioss_for_tp_plugin_api__/log', 'AliOssForTypecho_Plugin', 'api_log');
-
- return _t('启用成功,请进行相应设置!');
- }
-
- /**
- * 禁用插件方法,如果禁用失败,直接抛出异常
- *
- * @static
- * @access public
- * @return void
- * @throws Typecho_Plugin_Exception
- */
- public static function deactivate() {
- Helper::removeRoute('__alioss_for_tp_plugin_version__');
- Helper::removeRoute('__alioss_for_tp_plugin_log__');
- }
-
- /**
- * 获取插件配置面板
- *
- * @access public
- * @param Typecho_Widget_Helper_Form $form 配置面板
- * @return void
- */
- public static function config(Typecho_Widget_Helper_Form $form) {
- $upload_root = Typecho_Common::url(defined('__TYPECHO_UPLOAD_DIR__') ? __TYPECHO_UPLOAD_DIR__ : self::UPLOAD_DIR,
- defined('__TYPECHO_UPLOAD_ROOT_DIR__') ? __TYPECHO_UPLOAD_ROOT_DIR__ : __TYPECHO_ROOT_DIR__);
-
- $log_file_name = $upload_root . self::LOG_SUFFIX . 'error.log';
-
- if (is_writable($upload_root)) {
- $log_content = '恭喜!暂无错误日志产生,请继续保持维护~';
- $log_color = '#009900';
-
- if (!file_exists($log_file_name)) {
- self::makeUploadDir($upload_root . self::LOG_SUFFIX);
- fopen($log_file_name, 'w');
- if (!file_exists($log_file_name)) {
- $log_content = '无法创建日志文件,请检查权限设置!!!开启SELinux的用户注意合理配置权限!';
- $log_color = '#f00000';
- }
- } else {
- try {
- $content = file_get_contents($log_file_name);
- if ($content) {
- $log_content = $content;
- $log_color = '#dd0000';
- }
- } catch (Exception $e) {
- $log_content = '注意!无法读取日志文件,请检查文件状态!';
- $log_color = '#f00000';
- }
- }
- } else {
- $log_content = '!!!注意!!!
-当前网站上传目录无写入权限,无法记录日志!
-请给路径 '.$upload_root.' 赋予写入权限。开启SELinux的用户注意合理配置权限。';
- $log_color = '#f00000';
- }
-?>
-
-addInput($buketName->addRule('required', _t('必须填写Bucket名称')));
-
- $accessKeyId = new Typecho_Widget_Helper_Form_Element_Text('accessKeyId', NULL, null,
- _t('ACCESS KEY ID'), _t('请填写ACCESS KEY ID'));
- $form->addInput($accessKeyId->addRule('required', _t('必须填写ACCESS KEY ID')));
-
- $accessKeySecret = new Typecho_Widget_Helper_Form_Element_Text('accessKeySecret', NULL, null,
- _t('ACCESS KEY SECRET'), _t('请填写请填写ACCESS KEY SECRET'));
- $form->addInput($accessKeySecret->addRule('required', _t('必须填写ACCESS_KEY')));
-
- $endPoint = new Typecho_Widget_Helper_Form_Element_Select('endPoint',
- array(
- "oss-cn-hangzhou" => "华东1(杭州)oss-cn-hangzhou",
- "oss-cn-shanghai" => "华东2(上海)oss-cn-shanghai",
- "oss-cn-qingdao" => "华北1(青岛)oss-cn-qingdao",
- "oss-cn-beijing" => "华北2(北京)oss-cn-beijing",
- "oss-cn-zhangjiakou" => "华北3(张家口)oss-cn-zhangjiakou",
- "oss-cn-huhehaote" => "华北5(呼和浩特)oss-cn-huhehaote",
- "oss-cn-wulanchabu" => "华北6(乌兰察布)oss-cn-wulanchabu",
- "oss-cn-shenzhen" => "华南1(深圳)oss-cn-shenzhen",
- "oss-cn-heyuan" => "华南2(河源)oss-cn-heyuan",
- "oss-cn-chengdu" => "西南1(成都)oss-cn-chengdu",
- "oss-cn-hongkong" => "中国(香港)oss-cn-hongkong",
- "oss-us-west-1" => "美国西部1(硅谷)oss-us-west-1",
- "oss-us-east-1" => "美国东部1(弗吉尼亚)oss-us-east-1",
- "oss-ap-southeast-1" =>"亚太东南1(新加坡)oss-ap-southeast-1",
- "oss-ap-southeast-2" =>"亚太东南2(悉尼)oss-ap-southeast-2",
- "oss-ap-southeast-3" =>"亚太东南3(吉隆坡)oss-ap-southeast-3",
- "oss-ap-southeast-5" =>"亚太东南5(雅加达)oss-ap-southeast-5",
- "oss-ap-northeast-1" =>"亚太东北1(日本)oss-ap-northeast-1",
- "oss-ap-south-1" => "亚太南部1(孟买)oss-ap-south-1",
- "oss-eu-central-1" => "欧洲中部1(法兰克福)oss-eu-central-1",
- "oss-eu-west-1" => "英国(伦敦)oss-eu-west-1",
- "oss-me-east-1" => "中东东部1(迪拜)oss-me-east-1",
- "other" => '自定义'
- ),
- 'oss-cn-qingdao',
- _t('区域选择(若区域不在列表中则选择自定义,然后填写区域)'), '');
- $form->addInput($endPoint);
-
- $endPointType = new Typecho_Widget_Helper_Form_Element_Select('endPointType',
- array(
- ".aliyuncs.com" => '外网',
- "-internal.aliyuncs.com" => '内网',
- ),
- '.aliyuncs.com', '',
- '在你了解两种连接方式的不同作用的情况下修改此选项');
- $form->addInput($endPointType);
-
- $otherEndPoint = new Typecho_Widget_Helper_Form_Element_Text('otherEndPoint', NULL, '',
- '', '
- 填写全部Endpoint地址,通常以\'.aliyuncs.com\'或\'-internal.aliyuncs.com\'结尾。开头不包含http://,结尾不包含"/"。
例如"oss-cn-qingdao.aliyuncs.com"');
- $form->addInput($otherEndPoint);
-
- $userDir = new Typecho_Widget_Helper_Form_Element_Text('userDir', NULL, 'typecho/',
- _t('要储存的路径'), _t('请填写文件储存的路径(相对OSS根目录),以字母或数字开头,以"/"结尾。留空则上传到根目录。'));
- $form->addInput($userDir);
-
- $cdnUrl = new Typecho_Widget_Helper_Form_Element_Text('cdnUrl', NULL, '',
- _t('自定义(CDN)域名'), '请填写自定义域名,留空则使用外网Endpoint访问,以http://或https://开头,以"/"结尾');
- $form->addInput($cdnUrl);
-
- $diy_style = new Typecho_Widget_Helper_Form_Element_Text('des', NULL, '', _t('默认自定义样式'),
- _t('通过后缀的方式使用自定义样式,留空为不使用。使用详情见阿里云文档'));
- $form->addInput($diy_style);
-
- $form->addInput(new Typecho_Widget_Helper_Form_Element_Radio('ifLoaclSave', array( "1" => '保留', "0" => '不保留' ), "1",
- _t('在服务器保留备份'), _t('是否在服务器保留备份')));
-?>
-
-plugin('AliOssForTypecho')->userDir;
- $bucket_name = $options->plugin('AliOssForTypecho')->bucketName;
- $end_point = 'http://' . (($options->plugin('AliOssForTypecho')->endPoint === "other") ?
- $options->plugin('AliOssForTypecho')->otherEndPoint :
- $options->plugin('AliOssForTypecho')->endPoint . $options->plugin('AliOssForTypecho')->endPointType);
- $access_id = $options->plugin('AliOssForTypecho')->accessKeyId;
- $access_key = $options->plugin('AliOssForTypecho')->accessKeySecret;
-
- try {
- $oss_client = new OssClient($access_id, $access_key, $end_point);
- $oss_client->doesBucketExist($bucket_name);
- } catch (Exception $e) {
- $error = '错误:连接OSS Client实例失败' . "\r\n" .
- '错误描述:' . $e->getMessage() . "\r\n" .
- '时间:' . date('Y-m-d h:i:sa') . "\r\n\r\n";
- self::my_error_log($error);
- return false;
- }
-
- $save_on_server = $options->plugin('AliOssForTypecho')->ifLoaclSave;
-
- $file_origin_name = self::getSafeName($file['name']);
- $relative_path = date('Y/m/d/');
-
- $remote_file_name = $user_dir . $relative_path . $file_origin_name;
-
- if ($save_on_server === "1" && !Typecho_Common::isAppEngine()) {
-
- $upload_root = Typecho_Common::url(defined('__TYPECHO_UPLOAD_DIR__') ? __TYPECHO_UPLOAD_DIR__ : self::UPLOAD_DIR,
- defined('__TYPECHO_UPLOAD_ROOT_DIR__') ? __TYPECHO_UPLOAD_ROOT_DIR__ : __TYPECHO_ROOT_DIR__);
-
- $local_file_name = $upload_root . $relative_path . $file_origin_name;
- try{
- $exist_on_oss = $oss_client->doesObjectExist($bucket_name, $remote_file_name);
- $exist_on_server = file_exists($local_file_name);
- } catch(OssException $e) {
- $error = '错误:检查OSS或本地服务器中中是否存在同名文件时失败' . "\r\n" .
- '错误描述:' . $e->getMessage() . "\r\n" .
- '时间:' . date('Y-m-d h:i:sa') . "\r\n\r\n";
- self::my_error_log($error);
- return false;
- }
-
- if ($exist_on_oss || $exist_on_server) {
- // find a name neither exist on oss nor the server
- $pathinfo = pathinfo($file_origin_name);
- for ($i = 1;; $i++) {
- $file_origin_name = $pathinfo['filename'] . '(' . strval($i) . ').' . self::getExtentionName($file_origin_name);
- $remote_file_name = $user_dir . $relative_path . $file_origin_name;
- $local_file_name = $upload_root . $relative_path . $file_origin_name;
-
- try{
- $exist_on_oss = $oss_client->doesObjectExist($bucket_name, $remote_file_name);
- $exist_on_server = file_exists($local_file_name);
- } catch(OssException $e) {
- $error = '错误:检查OSS或本地服务器中中是否存在同名文件时失败' . "\r\n" .
- '错误描述:' . $e->getMessage() . "\r\n" .
- '时间:' . date('Y-m-d h:i:sa') . "\r\n\r\n";
- self::my_error_log($error);
- return false;
- }
-
- if ($exist_on_oss || $exist_on_server) {
- } else {
- break;
- }
- }
- }
- } else {
- try{
- $exist_on_oss = $oss_client->doesObjectExist($bucket_name, $remote_file_name);
- } catch(OssException $e) {
- $error = '错误:检查OSS中是否存在同名文件时失败' . "\r\n" .
- '错误描述:' . $e->getMessage() . "\r\n" .
- '时间:' . date('Y-m-d h:i:sa') . "\r\n\r\n";
- self::my_error_log($error);
- return false;
- }
- if ($exist_on_oss || $exist_on_server) {
- // find a name not exist on oss
- $pathinfo = pathinfo($file_origin_name);
- for ($i = 1;; $i++) {
- $file_origin_name = $pathinfo['filename'] . '(' . strval($i) . ').' . self::getExtentionName($file_origin_name);
- $remote_file_name = $user_dir . $relative_path . $file_origin_name;
-
- try{
- $exist_on_oss = $oss_client->doesObjectExist($bucket_name, $remote_file_name);
- } catch(OssException $e) {
- $error = '错误:检查OSS中是否存在同名文件时失败' . "\r\n" .
- '错误描述:' . $e->getMessage() . "\r\n" .
- '时间:' . date('Y-m-d h:i:sa') . "\r\n\r\n";
- self::my_error_log($error);
- return false;
- }
-
- if (!$exist_on_oss) {
- break;
- }
- }
- }
- }
-
- try{
- $ali_response = $oss_client->putObject($bucket_name, $remote_file_name, $content);
- } catch(OssException $e) {
- $error = '错误:将文件储存到OSS失败' . "\r\n" .
- '错误描述:' . $e->getMessage() . "\r\n" .
- '时间:' . date('Y-m-d h:i:sa') . "\r\n\r\n";
- self::my_error_log($error);
- return false;
- }
-
- if (200 != $ali_response['info']['http_code']) {
- $error = '错误:将文件储存到OSS时返回码不正常' . "\r\n" .
- '错误码:' . $ali_response['info']['http_code'] . "\r\n" .
- '远程文件:' . $remote_file_name . "\r\n" .
- '时间:' . date('Y-m-d h:i:sa') . "\r\n\r\n";
- self::my_error_log($error);
- return false;
- } else {
- if ($save_on_server === "1" && !Typecho_Common::isAppEngine()) {
- $file_dir_name = dirname($local_file_name);
- $dir_exist = true;
-
- if (!is_dir($file_dir_name) && !self::makeUploadDir($file_dir_name)) {
- $dir_exist = false;
- }
-
- if ($dir_exist) {
- if (!file_put_contents($local_file_name, $content)) {
- $error = '错误:文件已保存到OSS,将文件储存到本地服务器时失败,请手动删除OSS上的文件,开启SELinux的用户注意合理配置权限。' . "\r\n" .
- '文件路径:' . $local_file_name . "\r\n" .
- '远程文件:' . $remote_file_name . "\r\n" .
- '时间:' . date('Y-m-d h:i:sa') . "\r\n\r\n";
- self::my_error_log($error);
- return false;
- }
- } else {
- $error = '错误:文件已保存到OSS,将文件储存到本地服务器时创建目录失败,请检查服务器权限设置,开启SELinux的用户注意合理配置权限。' . "\r\n" .
- '无法创建路径:' . $file_dir_name . "\r\n" .
- '远程文件:' . $remote_file_name . "\r\n" .
- '时间:' . date('Y-m-d h:i:sa') . "\r\n\r\n";
- self::my_error_log($error);
- return false;
- }
- }
-
- return array(
- 'name' => $file_origin_name,
- 'path' => $relative_path . $file_origin_name,
- 'size' => intval($ali_response['oss-requestheaders']['Content-Length']),
- 'type' => $ext,
- 'mime' => $ali_response['oss-requestheaders']['Content-Type']
- );
-
- }
- }
-
- /**
- * 修改文件处理函数
- *
- * @access public
- * @param array $content 老文件
- * @param array $file 新上传的文件
- * @return mixed
- */
- public static function modifyHandle($content, $file)
- {
- if (empty($file['name'])) {
- return false;
- }
- $ext = self::getExtentionName($file['name']);
- if ($content['attachment']->type != $ext) {
- return false;
- }
- if (isset($file['tmp_name'])) {
- $new_file_content = file_get_contents($file['tmp_name']);
- } else if (isset($file['bytes'])) {
- $new_file_content = $file['bytes'];
- } else {
- return false;
- }
-
- $options = Typecho_Widget::widget('Widget_Options');
- $userDir = $options->plugin('AliOssForTypecho')->userDir;
- $bucket_name = $options->plugin('AliOssForTypecho')->bucketName;
- $end_point = 'http://' . (($options->plugin('AliOssForTypecho')->endPoint === "other") ?
- $options->plugin('AliOssForTypecho')->otherEndPoint :
- $options->plugin('AliOssForTypecho')->endPoint . $options->plugin('AliOssForTypecho')->endPointType);
- $access_id = $options->plugin('AliOssForTypecho')->accessKeyId;
- $access_key = $options->plugin('AliOssForTypecho')->accessKeySecret;
-
- $path = $content['attachment']->path;
-
- $remote_file_name = $userDir . $path;
-
- $ifLoaclSave = $options->plugin('AliOssForTypecho')->ifLoaclSave;
- $upload_root = Typecho_Common::url(defined('__TYPECHO_UPLOAD_DIR__') ? __TYPECHO_UPLOAD_DIR__ : self::UPLOAD_DIR,
- defined('__TYPECHO_UPLOAD_ROOT_DIR__') ? __TYPECHO_UPLOAD_ROOT_DIR__ : __TYPECHO_ROOT_DIR__);
- $local_file_name = $upload_root . $path;
-
- if ($ifLoaclSave && (!is_writable($upload_root) || !is_writable($local_file_name))) {
- $error = '错误:修改文件失败,旧文件无写权限,开启SELinux的用户注意合理配置权限。' . "\r\n" .
- '本地文件:' . $local_file_name . "\r\n" .
- '远程文件:' . $remote_file_name . "\r\n" .
- '时间:' . date('Y-m-d h:i:sa') . "\r\n\r\n";
- self::my_error_log($error);
- return false;
- }
-
- try {
- $oss_client = new OssClient($access_id, $access_key, $end_point);
- $oss_client->doesBucketExist($bucket_name);
- } catch (Exception $e) {
- $error = '错误:连接OSS Client实例失败' . "\r\n" .
- '错误描述:' . $e->getMessage() . "\r\n" .
- '时间:' . date('Y-m-d h:i:sa') . "\r\n\r\n";
- self::my_error_log($error);
- return false;
- }
-
- try{
- $ali_response = $oss_client->putObject($bucket_name, $remote_file_name, $new_file_content);
- } catch(OssException $e) {
- $error = '错误:将文件储存到OSS时失败' . "\r\n" .
- '错误描述:' . $e->getMessage() . "\r\n" .
- '时间:' . date('Y-m-d h:i:sa') . "\r\n\r\n";
- self::my_error_log($error);
- return false;
- }
-
- if (200 != $ali_response['info']['http_code']) {
- $error = '错误:将文件储存到OSS时返回码不正常' . "\r\n" .
- '错误码:' . $ali_response['info']['http_code'] . "\r\n" .
- '远程文件:' . $remote_file_name . "\r\n" .
- '时间:' . date('Y-m-d h:i:sa') . "\r\n\r\n";
- self::my_error_log($error);
- return false;
- } else {
- if ($ifLoaclSave === "1" && !Typecho_Common::isAppEngine()) {
- if (file_exists($local_file_name) && !unlink($local_file_name)) {
- $error = '错误:修改文件失败,无法删除旧文件' . "\r\n" .
- '本地文件:' . $local_file_name . "\r\n" .
- '远程文件:' . $remote_file_name . "\r\n" .
- '时间:' . date('Y-m-d h:i:sa') . "\r\n\r\n";
- self::my_error_log($error);
- return false;
- }
-
- $file_dir_name = dirname($local_file_name);
- $dir_exist = true;
-
- if (!is_dir($file_dir_name) && !self::makeUploadDir($file_dir_name)) {
- $dir_exist = false;
- }
-
- if ($dir_exist) {
- if (!file_put_contents($local_file_name, $new_file_content)) {
- $error = '错误:文件已保存到OSS,将文件储存到本地服务器时失败,请手动删除OSS上的文件' . "\r\n" .
- '文件路径:' . $local_file_name . "\r\n" .
- '远程文件:' . $remote_file_name . "\r\n" .
- '时间:' . date('Y-m-d h:i:sa') . "\r\n\r\n";
- self::my_error_log($error);
- return false;
- }
- } else {
- $error = '错误:文件已保存到OSS,将文件储存到本地服务器时创建目录失败,请检查服务器权限设置,请手动删除OSS上的文件' . "\r\n" .
- '无法创建路径:' . $file_dir_name . "\r\n" .
- '远程文件:' . $remote_file_name . "\r\n" .
- '时间:' . date('Y-m-d h:i:sa') . "\r\n\r\n";
- self::my_error_log($error);
- return false;
- }
- }
- }
-
- return array(
- 'name' => $content['attachment']->name,
- 'path' => $path,
- 'size' => intval($ali_response['oss-requestheaders']['Content-Length']),
- 'type' => $ext,
- 'mime' => $ali_response['oss-requestheaders']['Content-Type']
- );
- }
-
- /**
- * 删除文件
- *
- * @access public
- * @param array $content 文件相关信息
- * @return string
- */
- public static function deleteHandle(array $content)
- {
- $options = Typecho_Widget::widget('Widget_Options');
- $userDir = $options->plugin('AliOssForTypecho')->userDir;
- $bucket_name = $options->plugin('AliOssForTypecho')->bucketName;
- $end_point = 'http://' . (($options->plugin('AliOssForTypecho')->endPoint === "other") ?
- $options->plugin('AliOssForTypecho')->otherEndPoint :
- $options->plugin('AliOssForTypecho')->endPoint . $options->plugin('AliOssForTypecho')->endPointType);
- $access_id = $options->plugin('AliOssForTypecho')->accessKeyId;
- $access_key = $options->plugin('AliOssForTypecho')->accessKeySecret;
- $ifLoaclSave = $options->plugin('AliOssForTypecho')->ifLoaclSave;
-
- $path = $content['attachment']->path;
- $object_name = $userDir . $path;
- try {
- $oss_client = new OssClient($access_id, $access_key, $end_point);
- $oss_client->doesBucketExist($bucket_name);
- } catch (Exception $e) {
- $error = '错误:删除文件失败,无法连接OSS Client实例' . "\r\n" .
- '错误描述:' . $e->getMessage() . "\r\n" .
- 'OSS文件:' . $object_name . "\r\n" .
- '时间:' . date('Y-m-d h:i:sa') . "\r\n\r\n";
- self::my_error_log($error);
- return false;
- }
-
- try {
- $ali_response = $oss_client->deleteObject($bucket_name, $object_name);
- } catch (Exception $e) {
- $error = '错误:删除OSS文件失败' . "\r\n" .
- '错误描述:' . $e->getMessage() . "\r\n" .
- 'OSS文件: ' . $object_name . "\r\n" .
- '时间:' . date('Y-m-d h:i:sa') . "\r\n\r\n";
- self::my_error_log($error);
- }
-
- $delete_local_succeed = true;
- if ($ifLoaclSave === "1" && !Typecho_Common::isAppEngine()) {
- $upload_root = Typecho_Common::url(defined('__TYPECHO_UPLOAD_DIR__') ? __TYPECHO_UPLOAD_DIR__ : self::UPLOAD_DIR,
- defined('__TYPECHO_UPLOAD_ROOT_DIR__') ? __TYPECHO_UPLOAD_ROOT_DIR__ : __TYPECHO_ROOT_DIR__);
- $local_file_name = $upload_root . $path;
-
- $delete_local_succeed = false;
- if (file_exists($local_file_name)) {
- if (!is_writable($local_file_name)) {
- $error = '错误:删除本地文件失败,请检查权限设置' . "\r\n" .
- '文件路径:' . $local_file_name . "\r\n" .
- '时间:' . date('Y-m-d h:i:sa') . "\r\n\r\n";
- self::my_error_log($error);
- } else {
- try {
- $delete_local_succeed = unlink($local_file_name);
- } catch (Exception $e) {
- $error = '错误:删除本地文件失败' . "\r\n" .
- '错误描述:' . $e->getMessage() . "\r\n" .
- '文件路径:' . $local_file_name . "\r\n" .
- '时间:' . date('Y-m-d h:i:sa') . "\r\n\r\n";
- self::my_error_log($error);
- }
- }
- } else {
- $delete_local_succeed = true;
- }
- }
- return $delete_local_succeed && ($ali_response['info']['http_code'] === 204);
- }
-
- /**
- * 获取实际文件绝对访问路径
- *
- * @access public
- * @param array $content 文件相关信息
- * @return string
- */
- public static function attachmentHandle(array $content) {
- $options = Typecho_Widget::widget('Widget_Options');
-
- $cdnUrl = $options->plugin('AliOssForTypecho')->cdnUrl;
- $userDir = $options->plugin('AliOssForTypecho')->userDir;
- $diy_style = $options->plugin('AliOssForTypecho')->des;
- if (empty($cdnUrl)) {
- $bucket_name = $options->plugin('AliOssForTypecho')->bucketName;
- $end_point = ($options->plugin('AliOssForTypecho')->endPoint === "other") ?
- $options->plugin('AliOssForTypecho')->otherEndPoint :
- $options->plugin('AliOssForTypecho')->endPoint;
- return 'https://' . $bucket_name . '.' . $end_point . '.aliyuncs.com/' . $userDir . $content['attachment']->path . $diy_style;
- } else {
- return $cdnUrl . $userDir . $content['attachment']->path . $diy_style;
- }
- }
-
- /**
- * 获取实际文件数据
- *
- * @access public
- * @param array $content
- * @return string
- */
- public static function attachmentDataHandle(array $content)
- {
- return file_get_contents(self::attachmentHandle($content));
- }
-
- /**
- * 检查文件名
- *
- * @access private
- * @param string $ext 扩展名
- * @return boolean
- */
- private static function checkFileType($ext)
- {
- $options = Typecho_Widget::widget('Widget_Options');
- return in_array($ext, $options->allowedAttachmentTypes);
- }
-
- /**
- * 创建上传路径
- *
- * @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);
- }
-
- /**
- * 获取安全的文件名
- *
- * @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 $name;
- }
-
- private static function my_error_log(&$error) {
- if (!Typecho_Common::isAppEngine()) {
- $upload_root = Typecho_Common::url(defined('__TYPECHO_UPLOAD_DIR__') ? __TYPECHO_UPLOAD_DIR__ : self::UPLOAD_DIR,
- defined('__TYPECHO_UPLOAD_ROOT_DIR__') ? __TYPECHO_UPLOAD_ROOT_DIR__ : __TYPECHO_ROOT_DIR__);
- $error_log_file = $upload_root . self::LOG_SUFFIX . 'error.log';
-
- $log_dir = dirname($error_log_file);
- if (!is_dir($log_dir)) {
- if (is_writeable($upload_root)) {
- self::makeUploadDir($log_dir);
- }
- }
- if (is_writeable($log_dir)) {
- error_log($error, 3, $error_log_file);
- }
- }
- }
-
- private static function getExtentionName(&$name) {
- $info = pathinfo($name);
- return isset($info['extension']) ? strtolower($info['extension']) : '';
- }
-
-}
+to($activatedPlugins);
+ $activatedPlugins = json_decode(json_encode($activatedPlugins),true);
+ $plugins_list = $activatedPlugins['stack'];
+ $plugins_info = array();
+ for ($i = 0; $i < count($plugins_list); $i++){
+ if($plugins_list[$i]['title'] == 'AliOssForTypecho'){
+ $plugins_info = $plugins_list[$i];
+ break;
+ }
+ }
+ if (count($plugins_info) < 1) {
+ return false;
+ }
+ return $plugins_info;
+ }
+
+
+ /**
+ * 激活插件方法,如果激活失败,直接抛出异常
+ *
+ * @access public
+ * @return void
+ * @throws Typecho_Plugin_Exception
+ */
+ public static function activate() {
+ Typecho_Plugin::factory('Widget_Upload')->uploadHandle = array('AliOssForTypecho_Plugin', 'uploadHandle');
+ Typecho_Plugin::factory('Widget_Upload')->modifyHandle = array('AliOssForTypecho_Plugin', 'modifyHandle');
+ Typecho_Plugin::factory('Widget_Upload')->deleteHandle = array('AliOssForTypecho_Plugin', 'deleteHandle');
+ Typecho_Plugin::factory('Widget_Upload')->attachmentHandle = array('AliOssForTypecho_Plugin', 'attachmentHandle');
+ Typecho_Plugin::factory('Widget_Upload')->attachmentDataHandle = array('AliOssForTypecho_Plugin', 'attachmentDataHandle');
+
+ Helper::addRoute('__alioss_for_tp_plugin_version__', '/__alioss_for_tp_plugin_api__/version', 'AliOssForTypecho_Plugin', 'api_version');
+ Helper::addRoute('__alioss_for_tp_plugin_log__', '/__alioss_for_tp_plugin_api__/log', 'AliOssForTypecho_Plugin', 'api_log');
+
+ return _t('启用成功,请进行相应设置!');
+ }
+
+ /**
+ * 禁用插件方法,如果禁用失败,直接抛出异常
+ *
+ * @static
+ * @access public
+ * @return void
+ * @throws Typecho_Plugin_Exception
+ */
+ public static function deactivate() {
+ Helper::removeRoute('__alioss_for_tp_plugin_version__');
+ Helper::removeRoute('__alioss_for_tp_plugin_log__');
+ }
+
+ /**
+ * 获取插件配置面板
+ *
+ * @access public
+ * @param Typecho_Widget_Helper_Form $form 配置面板
+ * @return void
+ */
+ public static function config(Typecho_Widget_Helper_Form $form) {
+ $upload_root = Typecho_Common::url(defined('__TYPECHO_UPLOAD_DIR__') ? __TYPECHO_UPLOAD_DIR__ : self::UPLOAD_DIR,
+ defined('__TYPECHO_UPLOAD_ROOT_DIR__') ? __TYPECHO_UPLOAD_ROOT_DIR__ : __TYPECHO_ROOT_DIR__);
+
+ $log_file_name = $upload_root . self::LOG_SUFFIX . 'error.log';
+
+ if (is_writable($upload_root)) {
+ $log_content = '恭喜!暂无错误日志产生,请继续保持维护~';
+ $log_color = '#009900';
+
+ if (!file_exists($log_file_name)) {
+ self::makeUploadDir($upload_root . self::LOG_SUFFIX);
+ fopen($log_file_name, 'w');
+ if (!file_exists($log_file_name)) {
+ $log_content = '无法创建日志文件,请检查权限设置!!!开启SELinux的用户注意合理配置权限!';
+ $log_color = '#f00000';
+ }
+ } else {
+ try {
+ $content = file_get_contents($log_file_name);
+ if ($content) {
+ $log_content = $content;
+ $log_color = '#dd0000';
+ }
+ } catch (Exception $e) {
+ $log_content = '注意!无法读取日志文件,请检查文件状态!';
+ $log_color = '#f00000';
+ }
+ }
+ } else {
+ $log_content = '!!!注意!!!
+当前网站上传目录无写入权限,无法记录日志!
+请给路径 '.$upload_root.' 赋予写入权限。开启SELinux的用户注意合理配置权限。';
+ $log_color = '#f00000';
+ }
+?>
+
+addInput($buketName->addRule('required', _t('必须填写Bucket名称')));
+
+ $accessKeyId = new Typecho_Widget_Helper_Form_Element_Text('accessKeyId', NULL, null,
+ _t('ACCESS KEY ID'), _t('请填写ACCESS KEY ID'));
+ $form->addInput($accessKeyId->addRule('required', _t('必须填写ACCESS KEY ID')));
+
+ $accessKeySecret = new Typecho_Widget_Helper_Form_Element_Text('accessKeySecret', NULL, null,
+ _t('ACCESS KEY SECRET'), _t('请填写请填写ACCESS KEY SECRET'));
+ $form->addInput($accessKeySecret->addRule('required', _t('必须填写ACCESS_KEY')));
+
+ $endPoint = new Typecho_Widget_Helper_Form_Element_Select('endPoint',
+ array(
+ "oss-cn-hangzhou" => "华东1(杭州)oss-cn-hangzhou",
+ "oss-cn-shanghai" => "华东2(上海)oss-cn-shanghai",
+ "oss-cn-qingdao" => "华北1(青岛)oss-cn-qingdao",
+ "oss-cn-beijing" => "华北2(北京)oss-cn-beijing",
+ "oss-cn-zhangjiakou" => "华北3(张家口)oss-cn-zhangjiakou",
+ "oss-cn-huhehaote" => "华北5(呼和浩特)oss-cn-huhehaote",
+ "oss-cn-wulanchabu" => "华北6(乌兰察布)oss-cn-wulanchabu",
+ "oss-cn-shenzhen" => "华南1(深圳)oss-cn-shenzhen",
+ "oss-cn-heyuan" => "华南2(河源)oss-cn-heyuan",
+ "oss-cn-chengdu" => "西南1(成都)oss-cn-chengdu",
+ "oss-cn-hongkong" => "中国(香港)oss-cn-hongkong",
+ "oss-us-west-1" => "美国西部1(硅谷)oss-us-west-1",
+ "oss-us-east-1" => "美国东部1(弗吉尼亚)oss-us-east-1",
+ "oss-ap-southeast-1" =>"亚太东南1(新加坡)oss-ap-southeast-1",
+ "oss-ap-southeast-2" =>"亚太东南2(悉尼)oss-ap-southeast-2",
+ "oss-ap-southeast-3" =>"亚太东南3(吉隆坡)oss-ap-southeast-3",
+ "oss-ap-southeast-5" =>"亚太东南5(雅加达)oss-ap-southeast-5",
+ "oss-ap-northeast-1" =>"亚太东北1(日本)oss-ap-northeast-1",
+ "oss-ap-south-1" => "亚太南部1(孟买)oss-ap-south-1",
+ "oss-eu-central-1" => "欧洲中部1(法兰克福)oss-eu-central-1",
+ "oss-eu-west-1" => "英国(伦敦)oss-eu-west-1",
+ "oss-me-east-1" => "中东东部1(迪拜)oss-me-east-1",
+ "other" => '自定义'
+ ),
+ 'oss-cn-qingdao',
+ _t('区域选择(若区域不在列表中则选择自定义,然后填写区域)'), '');
+ $form->addInput($endPoint);
+
+ $endPointType = new Typecho_Widget_Helper_Form_Element_Select('endPointType',
+ array(
+ ".aliyuncs.com" => '外网',
+ "-internal.aliyuncs.com" => '内网',
+ ),
+ '.aliyuncs.com', '',
+ '在你了解两种连接方式的不同作用的情况下修改此选项');
+ $form->addInput($endPointType);
+
+ $otherEndPoint = new Typecho_Widget_Helper_Form_Element_Text('otherEndPoint', NULL, '',
+ '', '
+ 填写全部Endpoint地址,通常以\'.aliyuncs.com\'或\'-internal.aliyuncs.com\'结尾。开头不包含http://,结尾不包含"/"。
例如"oss-cn-qingdao.aliyuncs.com"');
+ $form->addInput($otherEndPoint);
+
+ $userDir = new Typecho_Widget_Helper_Form_Element_Text('userDir', NULL, 'typecho/',
+ _t('要储存的路径'), _t('请填写文件储存的路径(相对OSS根目录),以字母或数字开头,以"/"结尾。留空则上传到根目录。'));
+ $form->addInput($userDir);
+
+ $cdnUrl = new Typecho_Widget_Helper_Form_Element_Text('cdnUrl', NULL, '',
+ _t('自定义(CDN)域名'), '请填写自定义域名,留空则使用外网Endpoint访问,以http://或https://开头,以"/"结尾');
+ $form->addInput($cdnUrl);
+
+ $diy_style = new Typecho_Widget_Helper_Form_Element_Text('des', NULL, '', _t('默认自定义样式'),
+ _t('通过后缀的方式使用自定义样式,留空为不使用。使用详情见阿里云文档'));
+ $form->addInput($diy_style);
+
+ $form->addInput(new Typecho_Widget_Helper_Form_Element_Radio('ifLoaclSave', array( "1" => '保留', "0" => '不保留' ), "1",
+ _t('在服务器保留备份'), _t('是否在服务器保留备份')));
+?>
+
+plugin('AliOssForTypecho')->userDir;
+ $bucket_name = $options->plugin('AliOssForTypecho')->bucketName;
+ $end_point = 'http://' . (($options->plugin('AliOssForTypecho')->endPoint === "other") ?
+ $options->plugin('AliOssForTypecho')->otherEndPoint :
+ $options->plugin('AliOssForTypecho')->endPoint . $options->plugin('AliOssForTypecho')->endPointType);
+ $access_id = $options->plugin('AliOssForTypecho')->accessKeyId;
+ $access_key = $options->plugin('AliOssForTypecho')->accessKeySecret;
+
+ try {
+ $oss_client = new OssClient($access_id, $access_key, $end_point);
+ $oss_client->doesBucketExist($bucket_name);
+ } catch (Exception $e) {
+ $error = '错误:连接OSS Client实例失败' . "\r\n" .
+ '错误描述:' . $e->getMessage() . "\r\n" .
+ '时间:' . date('Y-m-d h:i:sa') . "\r\n\r\n";
+ self::my_error_log($error);
+ return false;
+ }
+
+ $save_on_server = $options->plugin('AliOssForTypecho')->ifLoaclSave;
+
+ $file_origin_name = self::getSafeName($file['name']);
+ $relative_path = date('Y/m/d/');
+
+ $remote_file_name = $user_dir . $relative_path . $file_origin_name;
+
+ if ($save_on_server === "1" && !Typecho_Common::isAppEngine()) {
+
+ $upload_root = Typecho_Common::url(defined('__TYPECHO_UPLOAD_DIR__') ? __TYPECHO_UPLOAD_DIR__ : self::UPLOAD_DIR,
+ defined('__TYPECHO_UPLOAD_ROOT_DIR__') ? __TYPECHO_UPLOAD_ROOT_DIR__ : __TYPECHO_ROOT_DIR__);
+
+ $local_file_name = $upload_root . $relative_path . $file_origin_name;
+ try{
+ $exist_on_oss = $oss_client->doesObjectExist($bucket_name, $remote_file_name);
+ $exist_on_server = file_exists($local_file_name);
+ } catch(OssException $e) {
+ $error = '错误:检查OSS或本地服务器中中是否存在同名文件时失败' . "\r\n" .
+ '错误描述:' . $e->getMessage() . "\r\n" .
+ '时间:' . date('Y-m-d h:i:sa') . "\r\n\r\n";
+ self::my_error_log($error);
+ return false;
+ }
+
+ if ($exist_on_oss || $exist_on_server) {
+ // find a name neither exist on oss nor the server
+ $pathinfo = pathinfo($file_origin_name);
+ for ($i = 1;; $i++) {
+ $file_origin_name = $pathinfo['filename'] . '(' . strval($i) . ').' . self::getExtentionName($file_origin_name);
+ $remote_file_name = $user_dir . $relative_path . $file_origin_name;
+ $local_file_name = $upload_root . $relative_path . $file_origin_name;
+
+ try{
+ $exist_on_oss = $oss_client->doesObjectExist($bucket_name, $remote_file_name);
+ $exist_on_server = file_exists($local_file_name);
+ } catch(OssException $e) {
+ $error = '错误:检查OSS或本地服务器中中是否存在同名文件时失败' . "\r\n" .
+ '错误描述:' . $e->getMessage() . "\r\n" .
+ '时间:' . date('Y-m-d h:i:sa') . "\r\n\r\n";
+ self::my_error_log($error);
+ return false;
+ }
+
+ if ($exist_on_oss || $exist_on_server) {
+ } else {
+ break;
+ }
+ }
+ }
+ } else {
+ try{
+ $exist_on_oss = $oss_client->doesObjectExist($bucket_name, $remote_file_name);
+ } catch(OssException $e) {
+ $error = '错误:检查OSS中是否存在同名文件时失败' . "\r\n" .
+ '错误描述:' . $e->getMessage() . "\r\n" .
+ '时间:' . date('Y-m-d h:i:sa') . "\r\n\r\n";
+ self::my_error_log($error);
+ return false;
+ }
+ if ($exist_on_oss || $exist_on_server) {
+ // find a name not exist on oss
+ $pathinfo = pathinfo($file_origin_name);
+ for ($i = 1;; $i++) {
+ $file_origin_name = $pathinfo['filename'] . '(' . strval($i) . ').' . self::getExtentionName($file_origin_name);
+ $remote_file_name = $user_dir . $relative_path . $file_origin_name;
+
+ try{
+ $exist_on_oss = $oss_client->doesObjectExist($bucket_name, $remote_file_name);
+ } catch(OssException $e) {
+ $error = '错误:检查OSS中是否存在同名文件时失败' . "\r\n" .
+ '错误描述:' . $e->getMessage() . "\r\n" .
+ '时间:' . date('Y-m-d h:i:sa') . "\r\n\r\n";
+ self::my_error_log($error);
+ return false;
+ }
+
+ if (!$exist_on_oss) {
+ break;
+ }
+ }
+ }
+ }
+
+ try{
+ $ali_response = $oss_client->putObject($bucket_name, $remote_file_name, $content);
+ } catch(OssException $e) {
+ $error = '错误:将文件储存到OSS失败' . "\r\n" .
+ '错误描述:' . $e->getMessage() . "\r\n" .
+ '时间:' . date('Y-m-d h:i:sa') . "\r\n\r\n";
+ self::my_error_log($error);
+ return false;
+ }
+
+ if (200 != $ali_response['info']['http_code']) {
+ $error = '错误:将文件储存到OSS时返回码不正常' . "\r\n" .
+ '错误码:' . $ali_response['info']['http_code'] . "\r\n" .
+ '远程文件:' . $remote_file_name . "\r\n" .
+ '时间:' . date('Y-m-d h:i:sa') . "\r\n\r\n";
+ self::my_error_log($error);
+ return false;
+ } else {
+ if ($save_on_server === "1" && !Typecho_Common::isAppEngine()) {
+ $file_dir_name = dirname($local_file_name);
+ $dir_exist = true;
+
+ if (!is_dir($file_dir_name) && !self::makeUploadDir($file_dir_name)) {
+ $dir_exist = false;
+ }
+
+ if ($dir_exist) {
+ if (!file_put_contents($local_file_name, $content)) {
+ $error = '错误:文件已保存到OSS,将文件储存到本地服务器时失败,请手动删除OSS上的文件,开启SELinux的用户注意合理配置权限。' . "\r\n" .
+ '文件路径:' . $local_file_name . "\r\n" .
+ '远程文件:' . $remote_file_name . "\r\n" .
+ '时间:' . date('Y-m-d h:i:sa') . "\r\n\r\n";
+ self::my_error_log($error);
+ return false;
+ }
+ } else {
+ $error = '错误:文件已保存到OSS,将文件储存到本地服务器时创建目录失败,请检查服务器权限设置,开启SELinux的用户注意合理配置权限。' . "\r\n" .
+ '无法创建路径:' . $file_dir_name . "\r\n" .
+ '远程文件:' . $remote_file_name . "\r\n" .
+ '时间:' . date('Y-m-d h:i:sa') . "\r\n\r\n";
+ self::my_error_log($error);
+ return false;
+ }
+ }
+
+ return array(
+ 'name' => $file_origin_name,
+ 'path' => $relative_path . $file_origin_name,
+ 'size' => intval($ali_response['oss-requestheaders']['Content-Length']),
+ 'type' => $ext,
+ 'mime' => $ali_response['oss-requestheaders']['Content-Type']
+ );
+
+ }
+ }
+
+ /**
+ * 修改文件处理函数
+ *
+ * @access public
+ * @param array $content 老文件
+ * @param array $file 新上传的文件
+ * @return mixed
+ */
+ public static function modifyHandle($content, $file)
+ {
+ if (empty($file['name'])) {
+ return false;
+ }
+ $ext = self::getExtentionName($file['name']);
+ if ($content['attachment']->type != $ext) {
+ return false;
+ }
+ if (isset($file['tmp_name'])) {
+ $new_file_content = file_get_contents($file['tmp_name']);
+ } else if (isset($file['bytes'])) {
+ $new_file_content = $file['bytes'];
+ } else {
+ return false;
+ }
+
+ $options = Typecho_Widget::widget('Widget_Options');
+ $userDir = $options->plugin('AliOssForTypecho')->userDir;
+ $bucket_name = $options->plugin('AliOssForTypecho')->bucketName;
+ $end_point = 'http://' . (($options->plugin('AliOssForTypecho')->endPoint === "other") ?
+ $options->plugin('AliOssForTypecho')->otherEndPoint :
+ $options->plugin('AliOssForTypecho')->endPoint . $options->plugin('AliOssForTypecho')->endPointType);
+ $access_id = $options->plugin('AliOssForTypecho')->accessKeyId;
+ $access_key = $options->plugin('AliOssForTypecho')->accessKeySecret;
+
+ $path = $content['attachment']->path;
+
+ $remote_file_name = $userDir . $path;
+
+ $ifLoaclSave = $options->plugin('AliOssForTypecho')->ifLoaclSave;
+ $upload_root = Typecho_Common::url(defined('__TYPECHO_UPLOAD_DIR__') ? __TYPECHO_UPLOAD_DIR__ : self::UPLOAD_DIR,
+ defined('__TYPECHO_UPLOAD_ROOT_DIR__') ? __TYPECHO_UPLOAD_ROOT_DIR__ : __TYPECHO_ROOT_DIR__);
+ $local_file_name = $upload_root . $path;
+
+ if ($ifLoaclSave && (!is_writable($upload_root) || !is_writable($local_file_name))) {
+ $error = '错误:修改文件失败,旧文件无写权限,开启SELinux的用户注意合理配置权限。' . "\r\n" .
+ '本地文件:' . $local_file_name . "\r\n" .
+ '远程文件:' . $remote_file_name . "\r\n" .
+ '时间:' . date('Y-m-d h:i:sa') . "\r\n\r\n";
+ self::my_error_log($error);
+ return false;
+ }
+
+ try {
+ $oss_client = new OssClient($access_id, $access_key, $end_point);
+ $oss_client->doesBucketExist($bucket_name);
+ } catch (Exception $e) {
+ $error = '错误:连接OSS Client实例失败' . "\r\n" .
+ '错误描述:' . $e->getMessage() . "\r\n" .
+ '时间:' . date('Y-m-d h:i:sa') . "\r\n\r\n";
+ self::my_error_log($error);
+ return false;
+ }
+
+ try{
+ $ali_response = $oss_client->putObject($bucket_name, $remote_file_name, $new_file_content);
+ } catch(OssException $e) {
+ $error = '错误:将文件储存到OSS时失败' . "\r\n" .
+ '错误描述:' . $e->getMessage() . "\r\n" .
+ '时间:' . date('Y-m-d h:i:sa') . "\r\n\r\n";
+ self::my_error_log($error);
+ return false;
+ }
+
+ if (200 != $ali_response['info']['http_code']) {
+ $error = '错误:将文件储存到OSS时返回码不正常' . "\r\n" .
+ '错误码:' . $ali_response['info']['http_code'] . "\r\n" .
+ '远程文件:' . $remote_file_name . "\r\n" .
+ '时间:' . date('Y-m-d h:i:sa') . "\r\n\r\n";
+ self::my_error_log($error);
+ return false;
+ } else {
+ if ($ifLoaclSave === "1" && !Typecho_Common::isAppEngine()) {
+ if (file_exists($local_file_name) && !unlink($local_file_name)) {
+ $error = '错误:修改文件失败,无法删除旧文件' . "\r\n" .
+ '本地文件:' . $local_file_name . "\r\n" .
+ '远程文件:' . $remote_file_name . "\r\n" .
+ '时间:' . date('Y-m-d h:i:sa') . "\r\n\r\n";
+ self::my_error_log($error);
+ return false;
+ }
+
+ $file_dir_name = dirname($local_file_name);
+ $dir_exist = true;
+
+ if (!is_dir($file_dir_name) && !self::makeUploadDir($file_dir_name)) {
+ $dir_exist = false;
+ }
+
+ if ($dir_exist) {
+ if (!file_put_contents($local_file_name, $new_file_content)) {
+ $error = '错误:文件已保存到OSS,将文件储存到本地服务器时失败,请手动删除OSS上的文件' . "\r\n" .
+ '文件路径:' . $local_file_name . "\r\n" .
+ '远程文件:' . $remote_file_name . "\r\n" .
+ '时间:' . date('Y-m-d h:i:sa') . "\r\n\r\n";
+ self::my_error_log($error);
+ return false;
+ }
+ } else {
+ $error = '错误:文件已保存到OSS,将文件储存到本地服务器时创建目录失败,请检查服务器权限设置,请手动删除OSS上的文件' . "\r\n" .
+ '无法创建路径:' . $file_dir_name . "\r\n" .
+ '远程文件:' . $remote_file_name . "\r\n" .
+ '时间:' . date('Y-m-d h:i:sa') . "\r\n\r\n";
+ self::my_error_log($error);
+ return false;
+ }
+ }
+ }
+
+ return array(
+ 'name' => $content['attachment']->name,
+ 'path' => $path,
+ 'size' => intval($ali_response['oss-requestheaders']['Content-Length']),
+ 'type' => $ext,
+ 'mime' => $ali_response['oss-requestheaders']['Content-Type']
+ );
+ }
+
+ /**
+ * 删除文件
+ *
+ * @access public
+ * @param array $content 文件相关信息
+ * @return string
+ */
+ public static function deleteHandle(array $content)
+ {
+ $options = Typecho_Widget::widget('Widget_Options');
+ $userDir = $options->plugin('AliOssForTypecho')->userDir;
+ $bucket_name = $options->plugin('AliOssForTypecho')->bucketName;
+ $end_point = 'http://' . (($options->plugin('AliOssForTypecho')->endPoint === "other") ?
+ $options->plugin('AliOssForTypecho')->otherEndPoint :
+ $options->plugin('AliOssForTypecho')->endPoint . $options->plugin('AliOssForTypecho')->endPointType);
+ $access_id = $options->plugin('AliOssForTypecho')->accessKeyId;
+ $access_key = $options->plugin('AliOssForTypecho')->accessKeySecret;
+ $ifLoaclSave = $options->plugin('AliOssForTypecho')->ifLoaclSave;
+
+ $path = $content['attachment']->path;
+ $object_name = $userDir . $path;
+ try {
+ $oss_client = new OssClient($access_id, $access_key, $end_point);
+ $oss_client->doesBucketExist($bucket_name);
+ } catch (Exception $e) {
+ $error = '错误:删除文件失败,无法连接OSS Client实例' . "\r\n" .
+ '错误描述:' . $e->getMessage() . "\r\n" .
+ 'OSS文件:' . $object_name . "\r\n" .
+ '时间:' . date('Y-m-d h:i:sa') . "\r\n\r\n";
+ self::my_error_log($error);
+ return false;
+ }
+
+ try {
+ $ali_response = $oss_client->deleteObject($bucket_name, $object_name);
+ } catch (Exception $e) {
+ $error = '错误:删除OSS文件失败' . "\r\n" .
+ '错误描述:' . $e->getMessage() . "\r\n" .
+ 'OSS文件: ' . $object_name . "\r\n" .
+ '时间:' . date('Y-m-d h:i:sa') . "\r\n\r\n";
+ self::my_error_log($error);
+ }
+
+ $delete_local_succeed = true;
+ if ($ifLoaclSave === "1" && !Typecho_Common::isAppEngine()) {
+ $upload_root = Typecho_Common::url(defined('__TYPECHO_UPLOAD_DIR__') ? __TYPECHO_UPLOAD_DIR__ : self::UPLOAD_DIR,
+ defined('__TYPECHO_UPLOAD_ROOT_DIR__') ? __TYPECHO_UPLOAD_ROOT_DIR__ : __TYPECHO_ROOT_DIR__);
+ $local_file_name = $upload_root . $path;
+
+ $delete_local_succeed = false;
+ if (file_exists($local_file_name)) {
+ if (!is_writable($local_file_name)) {
+ $error = '错误:删除本地文件失败,请检查权限设置' . "\r\n" .
+ '文件路径:' . $local_file_name . "\r\n" .
+ '时间:' . date('Y-m-d h:i:sa') . "\r\n\r\n";
+ self::my_error_log($error);
+ } else {
+ try {
+ $delete_local_succeed = unlink($local_file_name);
+ } catch (Exception $e) {
+ $error = '错误:删除本地文件失败' . "\r\n" .
+ '错误描述:' . $e->getMessage() . "\r\n" .
+ '文件路径:' . $local_file_name . "\r\n" .
+ '时间:' . date('Y-m-d h:i:sa') . "\r\n\r\n";
+ self::my_error_log($error);
+ }
+ }
+ } else {
+ $delete_local_succeed = true;
+ }
+ }
+ return $delete_local_succeed && ($ali_response['info']['http_code'] === 204);
+ }
+
+ /**
+ * 获取实际文件绝对访问路径
+ *
+ * @access public
+ * @param array $content 文件相关信息
+ * @return string
+ */
+ public static function attachmentHandle(array $content) {
+ $options = Typecho_Widget::widget('Widget_Options');
+ $cdnUrl = $options->plugin('AliOssForTypecho')->cdnUrl;
+ $userDir = $options->plugin('AliOssForTypecho')->userDir;
+ $diy_style = $options->plugin('AliOssForTypecho')->des;
+
+ $newPath = urlencode($content['attachment']->path);
+
+ if (empty($cdnUrl)) {
+ $bucket_name = $options->plugin('AliOssForTypecho')->bucketName;
+ $end_point = ($options->plugin('AliOssForTypecho')->endPoint === "other") ?
+ $options->plugin('AliOssForTypecho')->otherEndPoint :
+ $options->plugin('AliOssForTypecho')->endPoint;
+ // return 'https://' . $bucket_name . '.' . $end_point . '.aliyuncs.com/' . $userDir . $content['attachment']->path . $diy_style;
+ return 'https://' . $bucket_name . '.' . $end_point . '.aliyuncs.com/' . $userDir . $newPath . $diy_style;
+ } else {
+ // return $cdnUrl . $userDir . $content['attachment']->path . $diy_style;
+ return $cdnUrl . $userDir . $newPath . $diy_style;
+ }
+ }
+
+ /**
+ * 获取实际文件数据
+ *
+ * @access public
+ * @param array $content
+ * @return string
+ */
+ public static function attachmentDataHandle(array $content)
+ {
+ return file_get_contents(self::attachmentHandle($content));
+ }
+
+ /**
+ * 检查文件名
+ *
+ * @access private
+ * @param string $ext 扩展名
+ * @return boolean
+ */
+ private static function checkFileType($ext)
+ {
+ $options = Typecho_Widget::widget('Widget_Options');
+ return in_array($ext, $options->allowedAttachmentTypes);
+ }
+
+ /**
+ * 创建上传路径
+ *
+ * @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);
+ }
+
+ /**
+ * 获取安全的文件名
+ *
+ * @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 $name;
+ }
+
+ private static function my_error_log(&$error) {
+ if (!Typecho_Common::isAppEngine()) {
+ $upload_root = Typecho_Common::url(defined('__TYPECHO_UPLOAD_DIR__') ? __TYPECHO_UPLOAD_DIR__ : self::UPLOAD_DIR,
+ defined('__TYPECHO_UPLOAD_ROOT_DIR__') ? __TYPECHO_UPLOAD_ROOT_DIR__ : __TYPECHO_ROOT_DIR__);
+ $error_log_file = $upload_root . self::LOG_SUFFIX . 'error.log';
+
+ $log_dir = dirname($error_log_file);
+ if (!is_dir($log_dir)) {
+ if (is_writeable($upload_root)) {
+ self::makeUploadDir($log_dir);
+ }
+ }
+ if (is_writeable($log_dir)) {
+ error_log($error, 3, $error_log_file);
+ }
+ }
+ }
+
+ private static function getExtentionName(&$name) {
+ $info = pathinfo($name);
+ return isset($info['extension']) ? strtolower($info['extension']) : '';
+ }
+
+}
\ No newline at end of file
diff --git a/README.MD b/README.MD
index 02266a4..2db5b49 100644
--- a/README.MD
+++ b/README.MD
@@ -2,7 +2,7 @@
### 介绍
用于将Typecho上传的附件保存到阿里云的OSS。
-最后更新于2022年1月。
+最后更新于2023年2月。
### 特性
1. 可以选择只保存到OSS,或同时保存到OSS和服务器,方便维护;
@@ -11,3 +11,4 @@
4. 可以自定义CDN地址、OSS储存前缀、OSS连接方式(内网、外网);
5. 可以使用自定义样式。借鉴 [DefectingCat](https://github.com/DefectingCat/AliOssForTypecho-)
6. 感谢[Jump-Boy](https://github.com/Jump-Boy/AliOssForTypecho)提交PR更新OSS SDK以适配PHP8.
+7. 修复因为上传时阿里云将url中的字符集自动替换成ascill码,而服务器匹配url时出错