'), '', $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']) : ''; } /** * 上传文件处理函数,如果需要实现自己的文件哈希或者特殊的文件系统,请在options表里把uploadHandle改成自己的函数 * * @access public * @param array $file 上传的文件 * @return mixed */ public static function uploadHandle($file) { if (empty($file['name'])) { return false; } $result = Typecho_Plugin::factory('Widget_Upload')->trigger($hasUploaded)->uploadHandle($file); if ($hasUploaded) { return $result; } $ext = self::getSafeName($file['name']); if (!self::checkFileType($ext) || Typecho_Common::isAppEngine()) { return false; } $options = Typecho_Widget::widget('Widget_Options'); $date = new Typecho_Date($options->gmtTime); $path = 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__) . '/' . $date->year . '/' . $date->month; //创建上传目录 if (!is_dir($path)) { if (!self::makeUploadDir($path)) { return false; } } //获取文件名 $fileName = sprintf('%u', crc32(uniqid())) . '.' . $ext; $path = $path . '/' . $fileName; if (isset($file['tmp_name'])) { //移动上传文件 if (!@move_uploaded_file($file['tmp_name'], $path)) { return false; } } else if (isset($file['bytes'])) { //直接写入文件 if (!file_put_contents($path, $file['bytes'])) { return false; } } else { return false; } if (!isset($file['size'])) { $file['size'] = filesize($path); } //返回相对存储路径 return array( 'name' => $file['name'], 'path' => (defined('__TYPECHO_UPLOAD_DIR__') ? __TYPECHO_UPLOAD_DIR__ : self::UPLOAD_DIR) . '/' . $date->year . '/' . $date->month . '/' . $fileName, 'size' => $file['size'], 'type' => $ext, 'mime' => Typecho_Common::mimeContentType($path) ); } /** * 修改文件处理函数,如果需要实现自己的文件哈希或者特殊的文件系统,请在options表里把modifyHandle改成自己的函数 * * @access public * @param array $content 老文件 * @param array $file 新上传的文件 * @return mixed */ public static function modifyHandle($content, $file) { if (empty($file['name'])) { return false; } $result = Typecho_Plugin::factory('Widget_Upload')->trigger($hasModified)->modifyHandle($content, $file); if ($hasModified) { return $result; } $ext = self::getSafeName($file['name']); if ($content['attachment']->type != $ext || Typecho_Common::isAppEngine()) { return false; } $path = Typecho_Common::url($content['attachment']->path, defined('__TYPECHO_UPLOAD_ROOT_DIR__') ? __TYPECHO_UPLOAD_ROOT_DIR__ : __TYPECHO_ROOT_DIR__); $dir = dirname($path); //创建上传目录 if (!is_dir($dir)) { if (!self::makeUploadDir($dir)) { return false; } } if (isset($file['tmp_name'])) { @unlink($path); //移动上传文件 if (!@move_uploaded_file($file['tmp_name'], $path)) { return false; } } else if (isset($file['bytes'])) { @unlink($path); //直接写入文件 if (!file_put_contents($path, $file['bytes'])) { return false; } } else { return false; } if (!isset($file['size'])) { $file['size'] = filesize($path); } //返回相对存储路径 return array( 'name' => $content['attachment']->name, 'path' => $content['attachment']->path, 'size' => $file['size'], 'type' => $content['attachment']->type, 'mime' => $content['attachment']->mime ); } /** * 删除文件 * * @access public * @param array $content 文件相关信息 * @return string */ public static function deleteHandle(array $content) { $result = Typecho_Plugin::factory('Widget_Upload')->trigger($hasDeleted)->deleteHandle($content); if ($hasDeleted) { return $result; } return !Typecho_Common::isAppEngine() && @unlink(__TYPECHO_ROOT_DIR__ . '/' . $content['attachment']->path); } /** * 获取实际文件绝对访问路径 * * @access public * @param array $content 文件相关信息 * @return string */ public static function attachmentHandle(array $content) { $result = Typecho_Plugin::factory('Widget_Upload')->trigger($hasPlugged)->attachmentHandle($content); if ($hasPlugged) { return $result; } $options = Typecho_Widget::widget('Widget_Options'); return Typecho_Common::url($content['attachment']->path, defined('__TYPECHO_UPLOAD_URL__') ? __TYPECHO_UPLOAD_URL__ : $options->siteUrl); } /** * 获取实际文件数据 * * @access public * @param array $content * @return string */ public static function attachmentDataHandle(array $content) { $result = Typecho_Plugin::factory('Widget_Upload')->trigger($hasPlugged)->attachmentDataHandle($content); if ($hasPlugged) { return $result; } return file_get_contents(Typecho_Common::url($content['attachment']->path, defined('__TYPECHO_UPLOAD_ROOT_DIR__') ? __TYPECHO_UPLOAD_ROOT_DIR__ : __TYPECHO_ROOT_DIR__)); } /** * 检查文件名 * * @access private * @param string $ext 扩展名 * @return boolean */ public static function checkFileType($ext) { $options = Typecho_Widget::widget('Widget_Options'); return in_array($ext, $options->allowedAttachmentTypes); } /** * 执行升级程序 * * @access public * @return void */ public function upload() { if (!empty($_FILES)) { $file = array_pop($_FILES); if (0 == $file['error'] && is_uploaded_file($file['tmp_name'])) { // xhr的send无法支持utf8 if ($this->request->isAjax()) { $file['name'] = urldecode($file['name']); } $result = self::uploadHandle($file); if (false !== $result) { $this->pluginHandle()->beforeUpload($result); $struct = array( 'title' => $result['name'], 'slug' => $result['name'], 'type' => 'attachment', 'status' => 'publish', 'text' => serialize($result), 'allowComment' => 1, 'allowPing' => 0, 'allowFeed' => 1 ); if (isset($this->request->cid)) { $cid = $this->request->filter('int')->cid; if ($this->isWriteable($this->db->sql()->where('cid = ?', $cid))) { $struct['parent'] = $cid; } } $insertId = $this->insert($struct); $this->db->fetchRow($this->select()->where('table.contents.cid = ?', $insertId) ->where('table.contents.type = ?', 'attachment'), array($this, 'push')); /** 增加插件接口 */ $this->pluginHandle()->upload($this); $this->response->throwJson(array($this->attachment->url, array( 'cid' => $insertId, 'title' => $this->attachment->name, 'type' => $this->attachment->type, 'size' => $this->attachment->size, 'bytes' => number_format(ceil($this->attachment->size / 1024)) . ' Kb', 'isImage' => $this->attachment->isImage, 'url' => $this->attachment->url, 'permalink' => $this->permalink ))); } } } $this->response->throwJson(false); } /** * 执行升级程序 * * @access public * @return void */ public function modify() { if (!empty($_FILES)) { $file = array_pop($_FILES); if (0 == $file['error'] && is_uploaded_file($file['tmp_name'])) { $this->db->fetchRow($this->select()->where('table.contents.cid = ?', $this->request->filter('int')->cid) ->where('table.contents.type = ?', 'attachment'), array($this, 'push')); if (!$this->have()) { $this->response->setStatus(404); exit; } if (!$this->allow('edit')) { $this->response->setStatus(403); exit; } // xhr的send无法支持utf8 if ($this->request->isAjax()) { $file['name'] = urldecode($file['name']); } $result = self::modifyHandle($this->row, $file); if (false !== $result) { $this->pluginHandle()->beforeModify($result); $this->update(array( 'text' => serialize($result) ), $this->db->sql()->where('cid = ?', $this->cid)); $this->db->fetchRow($this->select()->where('table.contents.cid = ?', $this->cid) ->where('table.contents.type = ?', 'attachment'), array($this, 'push')); /** 增加插件接口 */ $this->pluginHandle()->modify($this); $this->response->throwJson(array($this->attachment->url, array( 'cid' => $this->cid, 'title' => $this->attachment->name, 'type' => $this->attachment->type, 'size' => $this->attachment->size, 'bytes' => number_format(ceil($this->attachment->size / 1024)) . ' Kb', 'isImage' => $this->attachment->isImage, 'url' => $this->attachment->url, 'permalink' => $this->permalink ))); } } } $this->response->throwJson(false); } /** * 初始化函数 * * @access public * @return void */ public function action() { if ($this->user->pass('contributor', true) && $this->request->isPost()) { $this->security->protect(); if ($this->request->is('do=modify&cid')) { $this->modify(); } else { $this->upload(); } } else { $this->response->setStatus(403); } } }