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)) { if (!file_exists($log_file_name)) { self::makeUploadDir($upload_root . self::LOG_SUFFIX); fopen($log_file_name, 'w'); } $log_content = '恭喜!暂无错误日志产生,请继续保持维护~'; $log_color = '#009900'; if (file_exists($log_file_name)) { $content = file_get_contents($log_file_name); if ($content) { $log_content = $content; $log_color = '#dd0000'; } } } else { $log_content = '!!!注意!!! 当前网站上传目录无写入权限,无法记录日志! 请给路径 '.$upload_root.' 赋予写入权限'; $log_color = '#f00000'; } ?>

插件使用说明

  1. 插件基于aliyun-oss-php-sdk Release 2.3.1开发, 若以后SDK开发包更新导致插件不可用,请到 我的博客^-^获取新版本插件,如果我还用typecho、阿里云OSS就会更新。
  2. 为保证正确记录日志,请赋予以下目录写权限:,并定期查阅日志处理事件错误。
  3. 当文件成功上传到OSS,但保存到服务器失败时,总体进度会显示失败。在OSS中的文件不会自动删除,请根据错误日志自行处理。
  4. 运行在云应用引擎上的站点“在服务器保留备份”选项无效,且无法记录日志。
  5. 旧版本Typecho存在无法上传大写扩展名文件的bug,请更新Typecho程序。
  6. 如有问题或建议请到 我的博客https://www.droomo.top/AliOssForTypecho.html 留言

以下是本插件产生的错误日志,请定期查看并处理:

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); $form->addInput(new Typecho_Widget_Helper_Form_Element_Radio('ifLoaclSave', array( "1" => '保留', "0" => '不保留' ), "1", _t('在服务器保留备份'), _t('是否在服务器保留备份'))); // The following line is used to fix bugs left in history. $form->addInput(new Typecho_Widget_Helper_Form_Element_Text('des', NULL, '', '', '')); ?> 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上的文件' . "\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' => $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 = '错误:修改文件失败,旧文件无写权限' . "\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; 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; } else { return $cdnUrl . $userDir . $content['attachment']->path; } } /** * 获取实际文件数据 * * @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']) : ''; } }