/** * 控制器执行主逻辑函数 * * @return mixed $value 返回最终需要执行完的结果 */ public function invoke() { Yii::trace(Yii::t('api', 'Begin to process {class}::{function}', array('{class}' => get_class($this), '{function}' => __FUNCTION__)), "miniyun.api"); // 调用父类初始化函数,注册自定义的异常和错误处理逻辑 parent::init(); // keys,是作为参数的键值,进行请求合法验证 $keys = array('Filename', 'key'); # 重新序列化参数 $post = array(); foreach ($_POST as $key => $value) { if ($key == "Filename") { $name = explode("_part_", $value); $post[$key] = $name[0]; } else { $post[$key] = $value; } } if (MSecurity::verification($keys, $post) == false) { Yii::log(Yii::t('api', "Request is Error, verification error"), CLogger::LEVEL_ERROR, "miniyun.api"); throw new MException(Yii::t('api', MConst::INVLID_REQUEST . "3"), MConst::UPLOAD_FILE_FAILS); } // 处理创建文件 if (!MUtils::create(DOCUMENT_CACHE, $_POST, $_FILES)) { throw new MException(Yii::t('api', MConst::INVLID_REQUEST . "4"), MConst::UPLOAD_FILE_FAILS); } }
/** * 处理下载文件逻辑 */ private function downloadFile() { $file_name = $_POST["Filename"]; $key = $_POST["key"]; $path = ''; // 参数检查 if (strlen(trim($file_name)) <= 0 || strlen(trim($key)) <= 0) { Yii::log(Yii::t('api', "Request is Error, file_name:'{$file_name}'"), CLogger::LEVEL_ERROR, "miniyun.api"); throw new MException(Yii::t('api', MConst::FILE_NOT_EXIST), MConst::DOWNLOAD_FILE_FAILS); } // 全路径 $path = str_replace("\${filename}", $file_name, $key); if (is_null($path) || strlen(trim($path)) <= 0) { Yii::log(Yii::t('api', "Request is Error, file_name:'{$file_name}'"), CLogger::LEVEL_ERROR, "miniyun.api"); throw new MException(Yii::t('api', MConst::FILE_NOT_EXIST), MConst::DOWNLOAD_FILE_FAILS); } $file_path = DOCUMENT_ROOT_BLOCK . $path; //文件不存在 if (file_exists($file_path) == false) { Yii::log(Yii::t('api', "File do not exist, path:'{$file_path}'"), CLogger::LEVEL_ERROR, "miniyun.api"); throw new MException(Yii::t('api', MConst::FILE_NOT_EXIST), MConst::DOWNLOAD_FILE_FAILS); } $content_type = 'application/force-download'; MUtils::download($file_path, $content_type, $file_name); }
/** * * 创建默认存储目录 */ public function createDefault() { $obj = new MFilesystemDirect(); if (!file_exists(DOCUMENT_TEMP)) { MUtils::MkDirsOject($obj, DOCUMENT_TEMP); } if (!file_exists(DOCUMENT_ROOT_BLOCK)) { MUtils::MkDirsOject($obj, DOCUMENT_ROOT_BLOCK); } if (!file_exists(THUMBNAIL_TEMP)) { MUtils::MkDirsOject($obj, THUMBNAIL_TEMP); } }
/** * 控制器执行主逻辑函数 * */ public function invoke($uri = null) { // 调用父类初始化函数,注册自定义的异常和错误处理逻辑 parent::init(); // 解析文件路径,若返回false,则错误处理 $urlManager = new MUrlManager(); $path = $urlManager->parsePathFromUrl($uri); $root = $urlManager->parseRootFromUrl($uri); if ($path == false || $root == false) { throw new MFilesException(Yii::t('api', MConst::PATH_ERROR), MConst::HTTP_CODE_411); } // 解析路径 $path = MUtils::convertStandardPath($path); MiniFile::getInstance()->download($path); }
/** * 控制器执行主逻辑函数 * * @return mixed $value 返回最终需要执行完的结果 */ public function invoke() { Yii::trace(Yii::t('api', 'Begin to process {class}::{function}', array('{class}' => get_class($this), '{function}' => __FUNCTION__)), "miniyun.api"); // 调用父类初始化函数,注册自定义的异常和错误处理逻辑 parent::init(); // keys,是作为参数的键值,进行请求合法验证 $keys = array('Filename', 'key'); if (MSecurity::verification($keys, $_POST) == false) { Yii::log(Yii::t('api', "Request is Error, keys:'{$keys}'"), CLogger::LEVEL_ERROR, "miniyun.api"); throw new MException(Yii::t('api', MConst::INVLID_REQUEST . "1"), MConst::UPLOAD_FILE_FAILS); } // 处理创建文件 if (!MUtils::create(DOCUMENT_ROOT_BLOCK, $_POST, $_FILES, true)) { throw new MException(Yii::t('api', MConst::INVLID_REQUEST . "2"), MConst::UPLOAD_FILE_FAILS); } Yii::trace(Yii::t('api', 'end to process {class}::{function}', array('{class}' => get_class($this), '{function}' => __FUNCTION__)), "miniyun.api"); }
/** * 从url请求解析对应的action名称 * 比如www.xx.cn/meta/service_upload_meta,返回的是service_upload_meta * @return string 返回的是对应action操作 */ public function parseActionFromUrl() { // // TODO: 针对不同的php server进行部署逻辑处理 // $uri = $_SERVER['REQUEST_URI']; // // iis服务器,处理编码 // if (isset($_SERVER['SERVER_SOFTWARE']) && strpos(strtolower($_SERVER['SERVER_SOFTWARE']), 'iis') !== false) { // iis urlencode() 或者 rawurlencode(),二者的区别是前者把空格编码为 '+',而后者把空格编码为 '%20' $uri = rawurldecode($uri); $uri = mb_convert_encoding($uri, "UTF-8", "gbk"); } else { $uri = urldecode($uri); } // // 姜松 20120419,前置假设用户不会将服务部署在/api.php/1/文件夹下 // 也就是不会存在这种请求:api.php/1/api.php/1/info // 查找对应api,便于取出控制器 // $index = strpos($uri, "api.php/1/"); if ($index != FALSE) { $uri = substr($uri, $index + strlen("api.php/1/")); self::$API_VERSION = 1; } // 转换为标准格式的路径 $uri = MUtils::convertStandardPath($uri); $parts = array_slice(explode('/', $uri), 1); // // 确保只有一个对应的方法 // if (count($parts) < 1) { return false; } $action = $parts[0]; if ($pos = strpos($action, '?')) { $action = substr($action, 0, $pos); } $array = array(); $array["action"] = $action; $array["uri"] = $uri; return $array; }
/** * (non-PHPdoc) * @see MFilesecController::invoke() */ public function invoke($uri = NULL) { $size = isset($_REQUEST['size']) ? $_REQUEST['size'] : NULL; if ($size === NULL || $size < 0) { throw new MFilesException(Yii::t('api', MConst::PARAMS_ERROR . 'Missing parameter'), MConst::HTTP_CODE_400); } $hash = $_REQUEST["hash"]; $this->size = $size; $url_manager = new MUrlManager(); $path = $url_manager->parsePathFromUrl($uri); $path_info = MUtils::pathinfo_utf($path); $file_name = $path_info["basename"]; $this->type = MiniUtil::getMimeType($file_name); //如果文件的block存在则直接创建meta,表示创建成功否则返回上传文件的参数 if ($this->handleCheckFileVersionSearch($hash)) { parent::invoke($uri); } else { //空间检查 $this->spaceFilter($size); echo json_encode(array("hash" => $hash, "filename" => $file_name)); } }
/** * 查找该路径下所有子文件:文件存入数组 * @param string $parent_file_id 父目录id * @return mixed $value 返回最终需要执行完的结果 */ public function findAllChildrenFiles($parent_file_id, $user_nick, $from_path, $to_path, $file_array, $device_name, $file_size) { $query_db_files = MFiles::queryChildrenFilesByParentFileID($parent_file_id); if ($query_db_files === false) { return false; } foreach ($query_db_files as $key => $db_file) { if ($db_file["file_type"] != MConst::OBJECT_TYPE_FILE) { $file_array = $this->findAllChildrenFiles($db_file["id"], $user_nick, $from_path, $to_path, $file_array, $device_name, $file_size); continue; } // // 转换路径 // $file_path = $db_file["file_path"]; // // 文件存入数组 // $file = new MFiles(); $file->file_path = $file_path; $file->version_id = $db_file["version_id"]; $meta_value = MUtils::getFileVersions($device_name, $db_file['file_size'], $file->version_id, MConst::CREATE_FILE, $db_file["user_id"], $user_nick); $file->meta_value = $meta_value; $file->is_add = true; // 记录是否需要添加 $file_array[$file_path] = $file; } return $file_array; }
/** * * 根据查询出的用户信息组装user对象 * @param int $user_id 用户id * @return mixed $value 返回最终需要执行完的结果 */ public function assembleUser($user_data) { $this->id = $user_data["id"]; $this->user_id = $user_data["id"]; $this->user_uuid = $user_data["user_uuid"]; $this->user_name = $user_data["user_name"]; $this->user_pass = $user_data["user_pass"]; $this->user_status = $user_data["user_status"]; $this->created_at = $user_data["created_at"]; $this->updated_at = $user_data["updated_at"]; //填充用户当前空间,与当前使用空间 $db = MDbManager::getInstance(); $sql = "select * from " . DB_PREFIX . "_user_metas where user_id={$this->user_id} and meta_key in('space','phone','email','nick')"; $items = $db->selectDb($sql); $this->nick = $this->user_name; //用户昵称 $this->phone = ""; //用户电话 $this->email = ""; //用户邮件 $this->space = FALSE; foreach ($items as $index => $item) { $value = $item["meta_value"]; if ($item["meta_key"] == "space") { $this->space = doubleval($value) * 1024 * 1024; } if ($item["meta_key"] == "nick" && strlen(trim($value)) > 0) { $this->nick = $value; } if ($item["meta_key"] == "phone") { $this->phone = $value; } if ($item["meta_key"] == "email") { $this->email = $value; } } //查询用户的默认空间 if ($this->space === FALSE) { $this->space = MUtils::defaultTotalSize(); } $this->usedSpace = $this->getUsedSpaceById($this->user_id); return $this; }
/** * 获取签名 * @param array $input 关联数组 * @param int $expire 过期时间 * @return mixed $value 执行成功返回签名,否则返回false */ public static function getRequesSignature($input, $expire = 21600) { if (is_array($input) == false) { return false; } //计算过期时间 $expiredDate = time() + $expire; // 对传入数组进行转换,将其key值转成小写,形成新的关联数组 $newInput = array(); foreach ($input as $key => $value) { // 转成小写 $key = strtolower($key); $newInput[$key] = $value; } // 获取新数组的key $keys = array_keys($newInput); // keys数组排序 natsort($keys); // input 的key不区分大小写 $str = ""; foreach ($keys as $key) { $str .= $key . $newInput[$key]; } $str .= MConst::EXPIRATION_DATE . $expiredDate; $signature = MUtils::getSha1Signature($str); // 在传入数组后添加两个新值: expiration_date digital_signature $input["expiration_date"] = $expiredDate; $input["digital_signature"] = $signature; return $input; }
/** * 处理组装请求元数据 * @param $response * @param $file * @param $mimeType * @return mixed */ private function assembleResponse($response, $file, $mimeType) { $filePath = $file["file_path"]; $result = LockBiz::getInstance()->status($filePath); $response['lock'] = $result["success"]; $response["size"] = MUtils::getSizeByLocale($this->locale, $file["file_size"]); $response["bytes"] = (int) $file["file_size"]; $response["path"] = $filePath; $response["file_name_pinyin"] = $file['file_name_pinyin']; $response["modified"] = MUtils::formatIntTime($file["file_update_time"]); $response["create_time"] = $file["file_create_time"]; $response["update_time"] = $file["file_update_time"]; $response["revision"] = intval($file["version_id"]); $response["rev"] = strval($file["version_id"]); $response["root"] = $this->root; $response["hash"] = !empty($file["signature"]) ? $file["signature"] : ""; $response["event"] = $file["event_uuid"]; $response["sort"] = (int) $file["sort"]; //外链Key $link = MiniLink::getInstance()->getByFileId($file['id']); if (empty($link['share_key'])) { $response["share_key"] = ''; } else { $response["share_key"] = $link['share_key']; } $response['is_dir'] = false; $permission = UserPermissionBiz::getInstance()->getPermission($filePath, $this->userId); if (!empty($permission)) { if (isset($permission['children_shared'])) { $response['children_shared'] = true; } else { $permission["share_model"] = $this->getShareModel($filePath); $response['share'] = $permission; } $filePermission = new MiniPermission($permission['permission']); $response['canDelete'] = $filePermission->canDeleteFile(); if (empty($permission['permission'])) { return null; } } if ($file["file_type"] == MConst::OBJECT_TYPE_FILE) { $mimeType = MiniUtil::getMimeType($file['file_path']); $response["thumb_exists"] = MUtils::isExistThumbnail($mimeType, (int) $file["file_size"]); } else { $response['is_dir'] = true; } if ($file["file_type"] > MConst::OBJECT_TYPE_FILE) { $response["type"] = (int) $file["file_type"]; } if (!empty($mimeType)) { $response["mime_type"] = $mimeType; } if ($file["is_deleted"] == true) { $response["is_deleted"] = true; } return $response; }
/** * 获取用户的权限 * * @since 1.0.7 */ public function getUserPermission($userIds, $userId) { $indexUser = 0; foreach ($userIds as $index => $id) { $indexUser = $index; if ($userId == $id) { break; } } return MUtils::getPermissionArray($this->_permissions[$indexUser]); }
/** * 打包下载 * @param $paths * @param $filePath * @throws MFileopsException */ public function downloadToPackage($paths, $filePath) { $userId = $this->user['id']; $parentPath = dirname($filePath); $isSharedPath = false; //主要用于判断是否为被共享文件 if (dirname(MiniUtil::getRelativePath($filePath)) == "/" . $userId) { $permission = MConst::SUPREME_PERMISSION; } else { $pathArr = explode('/', $filePath); $masterId = $pathArr[1]; if ($masterId != $userId) { $isSharedPath = true; } else { $model = new GeneralFolderPermissionBiz($parentPath); if ($model->isParentShared($parentPath)) { //如果是父目录被共享 $isSharedPath = true; } } if ($isSharedPath) { $permissionArr = UserPermissionBiz::getInstance()->getPermission($parentPath, $userId); if (!isset($permissionArr)) { $permission = MConst::SUPREME_PERMISSION; } else { $permission = $permissionArr['permission']; $privilegeModel = new PrivilegeBiz(); $this->share_filter->slaves = $privilegeModel->getSlaveIdsByPath($permissionArr['share_root_path']); $this->share_filter->is_shared = true; } } else { $permission = MConst::SUPREME_PERMISSION; } } $miniPermission = new MiniPermission($permission); $canDownload = $miniPermission->canDownload(); if (!$canDownload) { throw new MFileopsException(Yii::t('api', 'no permission'), MConst::HTTP_CODE_409); } $arr = explode('/', $filePath); $isRoot = false; $isMine = false; if (count($arr) == 3) { $isRoot = true; } $fileOwnerId = $arr[1]; $currentUser = $this->user; $currentUserId = $currentUser['user_id']; if ($fileOwnerId == $currentUserId) { $isMine = true; } if ($isRoot && !$isMine) { //如果是在根目录下且不是自己的目录 则后台控制不准取消共享 throw new MFileopsException(Yii::t('api', 'Internal Server Error'), MConst::HTTP_CODE_409); } //打包下载限制 header("Content-type: text/html; charset=utf-8"); $limit = new DownloadPackageLimit(); $limitCount = $limit->getLimitCount(); $limitSize = $limit->getLimitSize(); $code = ''; $fileNames = array(); $user = $this->user; $userId = $user['user_id']; $paths = explode(',', $paths); foreach ($paths as $path) { $file = MiniFile::getInstance()->getByPath($path); if (empty($file)) { echo "批量下载的文件存在不存在的文件"; exit; } $code = $code . ',' . $file['id']; array_push($fileNames, $file['file_name']); } if (count($fileNames) > 1) { $packageName = 'miniyun'; } else { $packageName = $fileNames[0]; } //创建临时文件夹 $fileSystem = new CFileSystem(); MUtils::MkDirsLocal(DOCUMENT_TEMP . $userId); $storePath = DOCUMENT_TEMP . $userId . "/" . $packageName; $array = array(); $ids = explode(",", $code); foreach ($ids as $id) { $file = MiniFile::getInstance()->getById($id); if (empty($file)) { continue; } if ($file["file_type"] == MConst::OBJECT_TYPE_FILE) { //属于自己的文件 $array[] = $file; } else { //不属于自己的文件 //查询共有多少个子目录 $array[] = $file; $files = MiniFile::getInstance()->getChildrenByPath($file["file_path"]); $array = array_merge($array, $files); } } if (count($array) > $limitCount) { echo "批量下载单次最大文件数不能超过:" . $limitCount; exit; } $size = $this->calculateSize($array); if ($size > $limitSize * 1024 * 1024) { echo "批量下载单次最大文件大小不能超过:" . $limitSize . "M"; exit; } $path = CUtils::removeUserFromPath($array[0]["file_path"]); $removeParent = pathinfo($path, PATHINFO_DIRNAME); if (strlen($removeParent) == 1) { $removeParent = ""; } //zip压缩 $zip = new ZipArchive(); $zipFile = $storePath . ".zip"; //删除上次存在的压缩文件 $fileSystem->delete($zipFile); try { $zipFile = mb_convert_encoding($zipFile, "gb2312", "UTF-8"); } catch (Exception $e) { $zipFile = $zipFile; } if ($zip->open($zipFile, ZIPARCHIVE::OVERWRITE) === TRUE) { //执行拷贝操作 foreach ($array as $file) { $fileType = $file["file_type"]; $filePath = $file["file_path"]; //获取存储文件的绝对路径 if (!empty($removeParent)) { $relativePath = CUtils::str_replace_once($removeParent, "", CUtils::removeUserFromPath($filePath)); } else { $relativePath = CUtils::removeUserFromPath($filePath); } //打包加上nick $relativePath = $packageName . $relativePath; //转换文件编码为中文编码 try { $store = mb_convert_encoding($relativePath, "gb2312", "UTF-8"); } catch (Exception $e) { $store = $relativePath; } $hasRead = true; if ($userId == $file["user_id"] && $fileType == MConst::OBJECT_TYPE_FILE) { //属于自己的文件 $this->addToFile($zip, $file, $store, $fileSystem); } elseif ($userId != $file["user_id"] && $fileType == MConst::OBJECT_TYPE_FILE) { //不属于自己的文件 if ($hasRead) { $this->addToFile($zip, $file, $store, $fileSystem); } } elseif ($userId == $file["user_id"] && $fileType == MConst::OBJECT_TYPE_DIRECTORY) { //属于自己的文件夹 $this->addToFolder($zip, $store); } else { //不属于自己的文件夹 if ($hasRead) { $this->addToFolder($zip, $store); } } } $zip->close(); //关闭 } if (!file_exists($zipFile)) { echo Yii::t('i18n', 'no_privilege'); Yii::app()->end(); } //进行下载 CUtils::output($zipFile, "application/octet-stream", $packageName . ".zip"); }
/** * 把db对象转换为array * @param object $item * @return array|null */ private function db2Item($item) { if (isset($item)) { $user = array(); $user["id"] = $item->id; $user["user_id"] = $item->id; $user["user_uuid"] = $item->user_uuid; $user["user_name"] = $item->user_name; $user["user_pass"] = $item->user_pass; $user["user_status"] = $item->user_status == 0 ? false : true; $user["user_pass"] = $item->user_pass; $user["user_status"] = $item->user_status; $user["salt"] = $item->salt; $user["created_at"] = $item->created_at; $user["updated_at"] = $item->updated_at; //查询用户Meta信息 $avatar = Yii::app()->params["defaultAvatar"]; if (!MiniHttp::isConsole()) { $avatar = MiniHttp::getMiniHost() . $avatar; } $user["avatar"] = $avatar; $user["nick"] = $user["user_name"]; $user["phone"] = ""; $user["email"] = ""; $user["space"] = MUtils::defaultTotalSize(); $user["is_admin"] = false; $metas = MiniUserMeta::getInstance()->getUserMetas($user["id"]); foreach ($metas as $key => $value) { if ($key === "nick") { $user["nick"] = $value; } if ($key === "phone") { $user["phone"] = $value; } if ($key === "email") { $user["email"] = $value; } if ($key === "space") { $user["space"] = $value; } if ($key === "is_admin") { $user["is_admin"] = $value === "1" ? true : false; } if ($key === 'file_sort_type') { $user["file_sort_type"] = $value; } if ($key === 'file_sort_order') { $user["file_sort_order"] = $value; } } //获得用户头像,如本地没有图片,则重新下载原始图片 if (array_key_exists("avatar", $metas)) { $value = $metas["avatar"]; if (strpos($value, "http") === 0) { $user["avatar"] = $value; } else { $savePath = THUMBNAIL_TEMP . "avatar"; $path = $savePath . '/' . $value; if (!file_exists($path)) { if (!file_exists($savePath)) { mkdir($savePath); } $url = $metas["avatar_url"]; file_put_contents($path, file_get_contents($url)); } $user["avatar"] = MiniHttp::getMiniHost() . "assets/thumbnails/avatar/" . $value; } } return $user; } return NULL; }
/** * delete头像 * @param * @return string */ public function deleteAvatar($avatar) { $userId = $this->user['id']; $file = MiniHttp::getMiniHost() . "static/thumbnails/avatar/" . $avatar; MUtils::RemoveFile($file); $result = MiniUserMeta::getInstance()->deleteAvatar($userId, $avatar); return array(success => $result); }
/** * 处理添加当前文件记录的版本 * @param string $file_path * @param int $version_id * @param string $user_nick */ private function handleFileMeta($file_path, $version_id, $user_id, $user_nick, $deviceName, $fileSize) { // // 查询之前的版本 // $file_meta = MFileMetas::queryFileMeta($file_path, MConst::VERSION); if ($file_meta) { $meta_value = MUtils::getFileVersions($deviceName, $fileSize, $version_id, MConst::DELETE, $user_id, $user_nick, $file_meta[0]["meta_value"]); $ret = MFileMetas::updateFileMeta($file_meta[0]["file_path"], MConst::VERSION, $meta_value); } else { $meta_value = MUtils::getFileVersions($deviceName, $fileSize, $version_id, MConst::DELETE, $user_id, $user_nick); $ret = MFileMetas::createFileMeta($file_path, MConst::VERSION, $meta_value); } return $ret; }
/** * 获取文件以前版本的mtadata * @param null $uri * @throws MException * @throws MFilesException */ public function invoke($uri = null) { parent::init(); // 解析url地址,获取root和path,path必须指向一个文件 $urlManager = new MUrlManager(); $path = $urlManager->parsePathFromUrl($uri); $root = $urlManager->parseRootFromUrl($uri); if ($path == false) { throw new MException(Yii::t('api', MConst::PATH_ERROR), MConst::HTTP_CODE_411); } $path = "/" . $path; // Default is 10. Max is 1,000. $revLimit = 10; if (isset($_REQUEST["rev_limit"]) != false) { $revLimit = $_REQUEST["rev_limit"]; } $revLimit = $revLimit <= 1000 ? $revLimit : 1000; // 文件大小格式化参数 $locale = "bytes"; if (isset($_REQUEST["locale"])) { $locale = $_REQUEST["locale"]; } // callback - // TODO 实现callback $callback = NULL; // 获取用户数据,如user_id $user = MUserManager::getInstance()->getCurrentUser(); $device = MUserManager::getInstance()->getCurrentDevice(); $userId = $user["user_id"]; $userNick = $user["user_name"]; $userDeviceId = $device["device_id"]; // // 查询文件 // $fileDetail = MFiles::queryAllFilesByPath("/" . $userId . $path); if ($fileDetail === false || count($fileDetail) == 0) { throw new MException(Yii::t('api', MConst::NOT_FOUND), MConst::HTTP_CODE_404); } // 判断文件类型,如不是文件则返回错误 if ($fileDetail[0]["file_type"] != 0) { throw new MException(Yii::t('api', "Not Acceptable"), MConst::HTTP_CODE_406); } $fileMeta = MFileMetas::queryFileMeta("/" . $userId . $path, MConst::VERSION); if ($fileMeta == false || empty($fileMeta)) { throw new MFilesException(Yii::t("api", MConst::INTERNAL_SERVER_ERROR), MConst::HTTP_CODE_500); } // // 文件版本历史 // $versions = unserialize($fileMeta[0]["meta_value"]); $count = 1; // 计数器 // // 轮询 // $response = array(); foreach ($versions as $k => $v) { $var = array(); $var["rev"] = strval($v["version_id"]); $var["revision"] = (int) $v["version_id"]; $var["bytes"] = 0; $var["size"] = "0 bytes"; $var["thumb_exists"] = false; $var["modified"] = MUtils::formatIntTime(microtime(true) * 10000); $var["mime_type"] = MConst::DEFAULT_FILE_MIME_TYPE; $var["path"] = $path; $var["is_dir"] = false; $var["root"] = $root; if ($v["type"] == MConst::DELETE) { $var["is_deleted"] = true; } // // 文件版本信息 // $fileVersion = MiniVersion::getInstance()->getVersion($v["version_id"]); if ($fileVersion == null) { $var["is_deleted"] = true; } else { $var['hash'] = $fileVersion["file_signature"]; $var["bytes"] = (int) $fileVersion["file_size"]; $var["size"] = MUtils::getSizeByLocale($locale, $fileVersion["file_size"]); $var["thumb_exists"] = $this->isExistThumbnail($fileVersion["file_size"], $fileVersion["mime_type"]); $var["modified"] = MUtils::formatIntTime($fileVersion["updated_at"]); $var["mime_type"] = is_null($fileVersion["mime_type"]) ? $var["mime_type"] : $fileVersion["mime_type"]; } array_push($response, $var); if ($count >= $revLimit) { break; } $count += 1; } echo json_encode($response); }
/** * 在线浏览文件获得内容 * @param string $path 文件当前路径 * @param string $type 文件类型,可选择pdf/png * @throws * @return NULL */ public function previewContent($path, $type) { $file = MiniFile::getInstance()->getByPath($path); // 权限处理 if (empty($file)) { return array('success' => false, 'msg' => 'file not existed'); } $fileBiz = new FileBiz(); $canRead = $fileBiz->privilege($path); if (!$canRead) { throw new MFileopsException(Yii::t('api', 'no permission'), MConst::HTTP_CODE_409); } //获得文件当前版本对应的version $version = PluginMiniDocVersion::getInstance()->getVersion($file["version_id"]); $signature = $version["file_signature"]; $localPath = PluginMiniDocOption::getInstance()->getMiniDocCachePath() . $signature . "/" . $signature . "." . $type; if (!file_exists($localPath)) { //文档还在转换中 $node = PluginMiniDocNode::getInstance()->getConvertNode($signature); if (empty($node)) { throw new MFileopsException(Yii::t('api', 'convert error'), MConst::HTTP_CODE_412); } //根据情况判断是否需要向迷你文档拉取内容 $parentPath = dirname($localPath); //如果缓存目录不存在,则需要创建 if (!file_exists($parentPath)) { MUtils::MkDirsLocal($parentPath); } //文件不存在,则需要从迷你文档拉取文件内容 $url = PluginMiniDocNode::getInstance()->getDownloadUrl($node["id"], $version, $type); $http = new HttpClient(); $http->get($url); $status = $http->get_status(); if ($status == "200") { $content = $http->get_body(); //把文件内容存储到本地硬盘 file_put_contents($localPath, $content); Yii::log($signature . " get " . $type . " success", CLogger::LEVEL_INFO, "doc.convert"); } else { if (!($version["doc_convert_status"] == -1)) { //如迷你文档服务器不存在该文档,说明迷你文档服务器发生了变动 //这个时候自动启动负载均衡机制,把文档重新转换 PluginMiniDocVersion::getInstance()->pushConvertSignature($signature, ""); Yii::log($signature . " get " . $type . " error", CLogger::LEVEL_ERROR, "doc.convert"); } } } if (file_exists($localPath)) { if ($type === "png") { $contentType = "image/png"; } if ($type === "pdf") { $contentType = "Content-type: application/pdf"; } //Firefox+混合云模式下直接输出内容 //其它浏览器使用sendfile模式输出内容 $isSendFile = true; if (MiniUtil::isMixCloudVersion()) { $ua = isset($_SERVER["HTTP_USER_AGENT"]) ? $_SERVER["HTTP_USER_AGENT"] : NULL; if (strpos($ua, "Firefox") > 0 || strpos($ua, "Safari") > 0) { $isSendFile = false; } } if ($isSendFile) { header('Location: ' . MiniHttp::getMiniHost() . "assets/minidoc/" . $signature . "/" . $signature . "." . $type); } else { Header("Content-type: " . $contentType); echo file_get_contents($localPath); exit; } } }
/** * 处理组装请求元数据 * */ private function assembleResponse($response, $file, $mimeType) { $filePath = $file["file_path"]; $response["size"] = MUtils::getSizeByLocale($this->_locale, $file["file_size"]); $response["bytes"] = (int) $file["file_size"]; $response["path"] = $filePath; $response["modified"] = MUtils::formatIntTime($file["file_update_time"]); $response["create_time"] = $file["file_create_time"]; $response["update_time"] = $file["file_update_time"]; $response["revision"] = intval($file["version_id"]); $response["rev"] = strval($file["version_id"]); $response["root"] = $this->_root; $response["hash"] = !empty($file["signature"]) ? $file["signature"] : ""; $response["event"] = $file["event_uuid"]; $response["sort"] = (int) $file["sort"]; //外链Key $response["share_key"] = $file["share_key"]; $response['is_dir'] = false; $permission = UserPermissionBiz::getInstance()->getPermission($filePath, $this->_user_id); if (!empty($permission)) { if (isset($permission['children_shared'])) { $response['children_shared'] = true; } else { $response['share'] = $permission; } if (empty($permission['permission'])) { //如果没有$permission['permission']权限 则直接返回null return null; } } if ($file["file_type"] == MConst::OBJECT_TYPE_FILE) { $response["hash"] = $file["signature"]; $mimeType = MiniUtil::getMimeType($file['file_path']); $response["thumb_exists"] = MUtils::isExistThumbnail($mimeType, (int) $file["file_size"]); } else { $response['is_dir'] = true; } if ($file["file_type"] > MConst::OBJECT_TYPE_FILE) { $response["type"] = (int) $file["file_type"]; } if (!empty($mimeType)) { $response["mime_type"] = $mimeType; } if ($file["is_deleted"] == true) { $response["is_deleted"] = true; } return $response; }
/** * 控制器执行主逻辑函数 */ public function invoke($uri = null) { $this->setAction(MConst::CREATE_FILE); // 调用父类初始化函数,注册自定义的异常和错误处理逻辑 parent::init(); $urlManager = new MUrlManager(); $root = $urlManager->parseRootFromUrl($uri); if ($root == false) { //支持参数模式传递上传路径 $path = MiniHttp::getParam("path", ""); if (empty($path)) { throw new MFilesException(Yii::t('api', MConst::PATH_ERROR), MConst::HTTP_CODE_411); } } // 初始化创建文件公共类句柄 $createFileHandler = MFilesCommon::initMFilesCommon(); if (count($_FILES) == 0) { throw new MFilesException(Yii::t('api', MConst::PARAMS_ERROR . "5"), MConst::HTTP_CODE_400); } $keys = array_keys($_FILES); if (count($keys) != 1) { throw new MFilesException(Yii::t('api', MConst::PARAMS_ERROR . "6"), MConst::HTTP_CODE_400); } $key = $keys[0]; // 检查请求参数$_FILES if (isset($_FILES[$key]) === false) { throw new MFilesException(Yii::t('api', MConst::PARAMS_ERROR . "7"), MConst::HTTP_CODE_400); } // 检查文件上传过程是否有错 if ($_FILES[$key]["error"] != 0) { throw new MFilesException(Yii::t('api', MConst::PARAMS_ERROR . "8"), MConst::HTTP_CODE_400); } $fileName = $_FILES[$key]["name"]; $type = MiniUtil::getMimeType($fileName); $size = $_FILES[$key]["size"]; $tmpName = $_FILES[$key]["tmp_name"]; // 验证文件是否已经上传成功 if (file_exists($tmpName) === false) { throw new MFilesException(Yii::t('api', MConst::INTERNAL_SERVER_ERROR), MConst::HTTP_CODE_500); } // 检查文件上传错误 if (filesize($tmpName) != $size) { throw new MFilesException(Yii::t('api', "The file upload error!"), MConst::HTTP_CODE_400); } //断点文件上传 if ($this->isBreakpointUpload()) { $filesController = new MFilePutController(); $filesController->invoke($uri); } else { //完整文件上传 $signature = MiniUtil::getFileHash($tmpName); // 解析路径 $path = MiniHttp::getParam("path", ""); $path = MiniUtil::specialWordReplace($path); $parentPath = dirname($path); $user = MUserManager::getInstance()->getCurrentUser(); $parentFile = MiniFile::getInstance()->getByPath($parentPath); //如果目录存在,且该目录is_delete=1,则把目录状态删除状态修改为0 if (!empty($parentFile) && $parentFile['is_deleted'] == 1) { $values = array(); $values['is_deleted'] = false; MiniFile::getInstance()->updateByPath($parentPath, $values); } else { //如果是根目录,则不用新建目录 //否则会创建文件名名称的文件夹出来,而且目标文件位于该文件夹的下面 if (!MiniUtil::isRootPath($parentPath, $user["id"])) { MiniFile::getInstance()->createFolder($parentPath, $user['id']); } } $createFileHandler->size = $size; $createFileHandler->parent_path = MUtils::convertStandardPath($parentPath); $createFileHandler->file_name = MiniUtil::specialWordReplace($fileName); $createFileHandler->root = $root; $createFileHandler->path = MUtils::convertStandardPath($path); $createFileHandler->type = $type; // 文件不存在,保存文件 $createFileHandler->saveFile($tmpName, $signature, $size); // 保存文件meta $createFileHandler->saveFileMeta(); // 处理不同端,不同返回值 if (MUserManager::getInstance()->isWeb() === true) { $createFileHandler->buildWebResponse(); return; } $createFileHandler->buildResult(); } }
/** * 当参数overwrite=false时,执行文件重命名,再创建文件 */ private function renameFile() { // overwrite=true,不执行之后操作 if ($this->overwrite == true) { return; } $children = MFiles::queryChildrenByParentId($this->user_id, $this->parent_file_id); if ($children === false) { throw new MFilesException(Yii::t('api', MConst::INTERNAL_SERVER_ERROR), MConst::HTTP_CODE_500); } $names = array(); foreach ($children as $k => $v) { $names[strtolower($v["file_name"])] = $v["file_name"]; } // // 执行重命名文件操作 // $this->file_name = MUtils::getConflictName($this->file_name, $names); $this->path = MUtils::convertStandardPath($this->parent_path . "/" . $this->file_name); $this->file_path = "/" . $this->user_id . $this->path; $this->create_file = true; }
private function hanleDescription($des_path, $cache, $total_size, $block_size, $hash) { // // 如果描述文件或者临时文件不存在则创建 // $blocks = ""; $count = $this->handleGetBlockCount($total_size, $block_size); if (!file_exists($des_path)) { if (!MUtils::MkDirsLocal(dirname($des_path))) { throw new MFilesException(Yii::t('api', MConst::INTERNAL_SERVER_ERROR), MConst::HTTP_CODE_500); } $description = array(); for ($i = 0; $i < $count; $i++) { $blocks .= "0"; } $description['hash'] = $hash; $description['total_size'] = $total_size; $description['block_size'] = $block_size; $description['blocks'] = $blocks; file_put_contents($des_path, serialize($description)); } else { $str = file_get_contents($des_path); $description = unserialize($str); } // 临时文件 if (!file_exists($cache) || filesize($cache) != $total_size) { $fp = fopen($cache, "wb"); fseek($fp, $total_size - 1); fwrite($fp, ""); fclose($fp); $blocks = ""; for ($i = 0; $i < $count; $i++) { $blocks .= "0"; } $description['blocks'] = $blocks; } // // 如果总大小不一致,则返回错误 // if ($total_size != $description['total_size']) { throw new MFilesException(Yii::t('api', MConst::PARAMS_ERROR), MConst::HTTP_CODE_400); } return $description; }
/** * 创建对象 */ public function create() { // 查询文件信息 $path = MiniUtil::getAbsolutePath($this->user_id, $this->path); $file = MiniFile::getInstance()->getByPath($path); if (empty($file)) { throw new MException(Yii::t('api', MConst::PATH_ERROR), MConst::HTTP_CODE_404); } $fileName = $file["file_name"]; $fileSize = $file["file_size"]; $versionId = $file["version_id"]; // 检查是否支持缩略图 $this->checkExistThumbnail($fileName, $fileSize); // 获取文件版本 $version = MFileVersions::queryFileVersionByID($versionId); if (count($version) == 0) { throw new MException(Yii::t('api', MConst::PATH_ERROR), MConst::HTTP_CODE_404); } // 获取文件存储路径 $isTmp = false; $signature = $_REQUEST["signature"]; if (empty($signature) || $signature === "undefined") { $signature = $version[0]["file_signature"]; } // 缩略图大小 $sizeInfo = self::$sizes[$this->size]; if ($sizeInfo === NULL) { $sizeStr = strtolower($this->size); $sizeList = explode("x", $sizeStr); $sizeInfo = array("w" => $sizeList[0], "h" => $sizeList[1]); } $this->width = $sizeInfo["w"]; $this->height = $sizeInfo["h"]; // 检查缩略图是否存在 $thumbnail = THUMBNAIL_TEMP . MiniUtil::getPathBySplitStr($signature); $thumbnail .= "_{$this->width}_{$this->height}.{$this->format}"; if (file_exists($thumbnail) == true) { //直接跳转,避免重复生成缩略图 $url = MiniHttp::getMiniHost() . "assets/thumbnails/" . MiniUtil::getPathBySplitStr($signature); $url .= "_{$this->width}_{$this->height}.{$this->format}"; header('Location: ' . $url); exit; } //判断文件是否在迷你存储中,兼容非迷你存储的文件 $version = MiniVersion::getInstance()->getBySignature($signature); $meta = MiniVersionMeta::getInstance()->getMeta($version["id"], "store_id"); $thumbnailData = array(); if (!empty($meta)) { //为迷你存储缩略图添加hook $thumbnailData["signature"] = $signature; $storePath = apply_filters("image_path", $thumbnailData); } if (empty($storePath) || $storePath === $thumbnailData) { //data源处理对象 $dataObj = Yii::app()->data; $signaturePath = MiniUtil::getPathBySplitStr($signature); if ($dataObj->isExistLocal()) { $storePath = $dataObj->documentStorePath($signaturePath) . $signaturePath; } } if (file_exists($storePath) == false) { throw new MException(Yii::t('api', "The file path was not found."), MConst::HTTP_CODE_404); } $pathInfo = MUtils::pathinfo_utf($fileName); $extension = $pathInfo["extension"]; $tmpPath = DOCUMENT_TEMP . $signature . ".{$extension}"; // 缩略图对象 $this->handler = NULL; $this->image = $tmpPath; $this->resize = true; // 创建缩略图片父目录 if (file_exists(dirname($thumbnail)) == false) { if (MUtils::MkDirsLocal(dirname($thumbnail)) == false) { throw new MException(Yii::t('api', "The file path was not found."), MConst::HTTP_CODE_404); } } // 临时文件父目录 if (file_exists(dirname($tmpPath)) == false) { if (MUtils::MkDirsLocal(dirname($tmpPath)) == false) { throw new MException(Yii::t('api', "The file path was not found."), MConst::HTTP_CODE_404); } } // 拷贝文件到临时目录 if (file_exists($tmpPath) == false) { if (copy($storePath, $tmpPath) == false) { throw new MException(Yii::t('api', "The file path was not found."), MConst::HTTP_CODE_404); } } // 如果图片格式与后缀不一致,转换为一致的 if ($this->format != strtolower($extension)) { $fm = new Image($tmpPath); $format_path = DOCUMENT_TEMP . $signature . ".{$this->format}"; $fm->save($format_path); // 转换成功删除临时文件 unlink($tmpPath); $this->image = $format_path; } if ($isTmp) { unlink($storePath); } // 初始化图像对象 try { $this->handler = new Image($this->image, isset($this->config) ? $this->config : NULL); } catch (MException $e) { Yii::log("Exception : {$e->getTraceAsString()}"); throw new MException(Yii::t('api', "The image is invalid and cannot be thumbnailed."), MConst::HTTP_CODE_415); } // 生成缩略图 if ($this->resize == true) { $this->handler->resize($this->width, $this->height)->rotate(0)->quality(75)->sharpen(20); $chmod = 0644; $keep_actions = true; try { $this->handler->save($thumbnail, $chmod, $keep_actions); $this->handler->setImageFile($thumbnail); $this->image = $thumbnail; @unlink($format_path); } catch (MException $e) { Yii::trace("Exception : {$e}", "miniyun.api"); throw new MException(Yii::t('api', "The image is invalid and cannot be thumbnailed."), MConst::HTTP_CODE_415); } } }
/** * 控制器执行主逻辑函数, 复制文件或者文件夹 */ public function invoke($uri = null) { $this->setAction(MConst::COPY); $this->beforeInvoke(); $this->beforecheck(); $user = MUserManager::getInstance()->getCurrentUser(); // 调用父类初始化函数,注册自定义的异常和错误处理逻辑 parent::init(); $params = $_REQUEST; // 检查参数 if (isset($params) === false) { throw new MFileopsException(Yii::t('api', 'Bad Request 11'), MConst::HTTP_CODE_400); } // 文件大小格式化参数 $locale = "bytes"; if (isset($params["root"]) === false || isset($params["from_path"]) === false || isset($params["to_path"]) === false) { throw new MFileopsException(Yii::t('api', 'Bad Request 12'), MConst::HTTP_CODE_400); } if (isset($params["locale"])) { $locale = $params["locale"]; } $root = $params["root"]; $this->_from_path = $params["from_path"]; $this->_to_path = $params["to_path"]; if ($params['is_root']) { $this->_to_path = '/' . $user['id'] . $this->_to_path; } // // 检查文件名是否有效 // $isInvalid = MUtils::checkNameInvalid(MUtils::get_basename($this->_to_path)); if ($isInvalid) { throw new MFileopsException(Yii::t('api', 'Bad Request 13'), MConst::HTTP_CODE_400); } // // 转换路径分隔符,便于以后跨平台,如:将 "\"=>"/" // $this->_from_path = MUtils::convertStandardPath($this->_from_path); $this->_to_path = MUtils::convertStandardPath($this->_to_path); if ($this->_from_path == "/" || $this->_to_path == "/" || $this->_from_path === false || $this->_to_path === false) { throw new MFileopsException(Yii::t('api', 'Bad Request 14'), MConst::HTTP_CODE_400); } if ($this->_to_path[strlen($this->_to_path) - 1] == "/") { // 目标文件无效,403 error throw new Exception(Yii::t('api', 'The file or folder name is invalid'), MConst::HTTP_CODE_403); } // // 检查共享 // $from_share_filter = MSharesFilter::init(); $this->to_share_filter = MSharesFilter::init(); // 当从共享目录拷贝到其他目录时,源目录用户id设置为共享用户id // if ($from_share_filter->handlerCheck($this->owner, $this->_from_path)) { // $this->master = $from_share_filter->master; // $this->_from_path = $from_share_filter->_path; // } // // // 当拷贝到共享目录的时候,目标目录的用户id设置为共享用户id // if ($this->to_share_filter->handlerCheck($this->_user_id, $this->_to_path)) { // $this->_user_id = $this->to_share_filter->master; // $this->user_nick = $this->to_share_filter->master_nick; // $this->_to_path = $this->to_share_filter->_path; // } // if($this->_from_shared_path){ // $this->_from_path = $this->_from_shared_path; // }else{ // $this->_from_path = "/".$this->master.$this->_from_path; // } // if($this->_to_shared_path){ // $this->_to_path = $this->_to_shared_path; // }else{ // $this->_to_path = "/".$this->_user_id.$this->_to_path; // } // // 检查目标路径是否在复制目录下 // if (strpos($this->_to_path, $this->_from_path . "/") === 0) { throw new MFileopsException(Yii::t('api', 'Can not be copied to the subdirectory'), MConst::HTTP_CODE_403); } $check = CUtils::removeUserFromPath($this->_to_path); if (empty($check) || $check == '/') { throw new MFileopsException(Yii::t('api', 'Can not be copied to the error directory'), MConst::HTTP_CODE_403); } // // 检查目标路径文件是否存在 // $queryToPathDbFile = MFiles::queryAllFilesByPath($this->_to_path); $isUpdate = false; if ($queryToPathDbFile) { if ($queryToPathDbFile[0]["is_deleted"] == false) { // 已经存在,403 error throw new MFileopsException(Yii::t('api', 'There is already a item at the given destination'), MConst::HTTP_CODE_403); } $isUpdate = true; } // // 查询其信息 // $fileName = MUtils::get_basename($this->_to_path); $queryFromPathDbFile = MFiles::queryFilesByPath($this->_from_path); $queryToPathDbFile = MFiles::queryFilesByPath(dirname($this->_to_path)); if ($queryFromPathDbFile === false || empty($queryFromPathDbFile)) { throw new MFileopsException(Yii::t('api', 'Not found the source files of the specified path'), MConst::HTTP_CODE_404); } $fromArr = explode('/', $this->_from_path); $fromId = $fromArr[1]; if ($params['root']) { $toArr = explode('/', $this->_to_path); $toId = $toArr[1]; } else { $toId = $user['id']; } //权限判断 //当属于共享目录时才进行权限控制(源路径) $fromFile = MiniFile::getInstance()->getByFilePath($this->_from_path); if ($fromId != $user['id']) { //判断文件重命名是否有权限操作 $permissionArr = UserPermissionBiz::getInstance()->getPermission($this->_from_path, $user['id']); if (!isset($permissionArr)) { $permission = MConst::SUPREME_PERMISSION; } else { $permission = $permissionArr['permission']; } $miniPermission = new MiniPermission($permission); $canCopy = $miniPermission->canCopy($fromFile['file_type']); if (!$canCopy) { throw new MFileopsException(Yii::t('api', 'no permission'), MConst::HTTP_CODE_409); } } $isSharedPath = false; //主要用于判断是否为被共享文件 //目标路径 if ($toId != $user['id']) { $isSharedPath = true; //拷贝到 (目标路径的创建权限) 的判断 // if ($query_from_path_db_file[0]["file_type"] == 0){ //文件 // $this->to_share_filter->hasPermissionExecute($this->_to_path, MPrivilege::FILE_CREATE); // } else { //文件夹 // $this->to_share_filter->hasPermissionExecute($this->_to_path, MPrivilege::FOLDER_CREATE); // } } else { $model = new GeneralFolderPermissionBiz($this->_to_path); if ($model->isParentShared($this->_to_path)) { //如果是父目录被共享 $isSharedPath = true; } } if ($isSharedPath) { $permissionArr = UserPermissionBiz::getInstance()->getPermission(dirname($this->_to_path), $user['id']); if (!isset($permissionArr)) { $permission = MConst::SUPREME_PERMISSION; } else { $permission = $permissionArr['permission']; $privilegeModel = new PrivilegeBiz(); $this->to_share_filter->slaves = $privilegeModel->getSlaveIdsByPath($permissionArr['share_root_path']); $this->to_share_filter->is_shared = true; } $miniPermission = new MiniPermission($permission); $toFile = MiniFile::getInstance()->getByFilePath(dirname($this->_to_path)); $canCopy = $miniPermission->canCopy($toFile['file_type']); if (!$canCopy) { throw new MFileopsException(Yii::t('api', 'no permission'), MConst::HTTP_CODE_409); } } // // 查询目标路径父目录信息 // $parentPath = dirname($this->_to_path); $createFolder = new MCreateFolderController(); $createFolder->_user_device_id = $this->_user_device_id; $createFolder->_user_id = $this->_user_id; $createFolder->share_filter = $this->to_share_filter; $parentFileId = $createFolder->handlerParentFolder($parentPath); // // 组装对象信息 // $fileDetail = new MFiles(); $fileDetail->file_name = $fileName; $fileDetail->file_path = $this->_to_path; $this->assembleFileDetail($fileName, $parentFileId, $fileDetail, $queryFromPathDbFile[0]); // // 首先处理复制根目录操作 // if ($isUpdate) { $fileDetail->event_uuid = MiniUtil::getEventRandomString(MConst::LEN_EVENT_UUID); $updates = array(); $updates["file_update_time"] = time(); $updates["is_deleted"] = intval(false); $updates["event_uuid"] = $fileDetail->event_uuid; $updates["file_type"] = $fileDetail->file_type; $retValue = MFiles::updateFileDetailByPath($this->_to_path, $updates); } else { $retValue = MFiles::CreateFileDetail($fileDetail, $this->_user_id); } if ($retValue === false) { throw new MFileopsException(Yii::t('api', 'Internal Server Error'), MConst::HTTP_CODE_500); } // // 更新版本信息 // $this->updateVerRef(array($fileDetail)); $retValue = MiniEvent::getInstance()->createEvent($this->_user_id, $this->_user_device_id, $fileDetail->event_action, $fileDetail->file_path, $fileDetail->context, $fileDetail->event_uuid, $this->to_share_filter->type); if ($retValue === false) { throw new MFileopsException(Yii::t('api', 'There is already a item at the given destination'), MConst::HTTP_CODE_500); } $context = $fileDetail->context; if ($fileDetail->file_type == 0) { $context = unserialize($context); } $this->to_share_filter->handlerAction($fileDetail->event_action, $this->_user_device_id, $fileDetail->file_path, $context); // // 判断操作的是文件夹,还是文件 // $createArray = array(); $queryDbFile = MFiles::queryFilesByPath($this->_to_path); // // 查询其复制目录路径id // if ($queryDbFile === false || empty($queryDbFile)) { throw new MFileopsException(Yii::t('api', 'Not found the source files of the specified path'), MConst::HTTP_CODE_404); } if ($fileDetail->file_type != MConst::OBJECT_TYPE_FILE) { $fileDetail->id = $queryDbFile[0]["id"]; $fileDetail->file_size = $queryDbFile[0]["file_size"]; $this->handlerChildrenFile($fileDetail); // // 处理版本信息 // $moveController = new MMoveController(); $moveController->versions = array(); $createArray = $moveController->handleChildrenVersions($createArray, $this->_user_id, $this->user_nick, $this->_from_path, $this->_to_path, $queryToPathDbFile[0]["id"], $this->_user_device_name, $queryFromPathDbFile[0]["file_size"]); $this->versions = $moveController->versions; } else { $fileMeta = new MFileMetas(); $fileMeta->version_id = $queryFromPathDbFile[0]["version_id"]; // // 查询其版本 // $fileVersion = MFileMetas::queryFileMeta($this->_to_path, MConst::VERSION); $fileMeta->is_add = false; if ($fileVersion) { $metaValue = MUtils::getFileVersions($this->_user_device_name, $fileDetail->file_size, $fileMeta->version_id, MConst::CREATE_FILE, $this->_user_id, $this->user_nick, $fileVersion[0]["meta_value"]); } else { $metaValue = MUtils::getFileVersions($this->_user_device_name, $fileDetail->file_size, $fileMeta->version_id, MConst::CREATE_FILE, $this->_user_id, $this->user_nick); $fileMeta->is_add = true; // 不存在记录,需要添加 } $fileMeta->meta_value = $metaValue; $fileMeta->file_path = $this->_to_path; $createArray[$queryFromPathDbFile[0]["file_path"]] = $fileMeta; // // 添加到需要更新的版本ref // array_push($this->versions, $fileMeta->version_id); } // // 创建版本信息 // MFileMetas::batchCreateFileMetas($createArray, MConst::VERSION); // if ($ret === false) // { // throw new MFileopsException( // Yii::t('api','Internal Server Error'), // MConst::HTTP_CODE_500); // } // // 更新版本 // foreach ($createArray as $key => $fileMeta) { if ($fileMeta->is_add === true) { // 不存在记录,不需要更新 continue; } MFileMetas::updateFileMeta($fileMeta->file_path, MConst::VERSION, $fileMeta->meta_value); } // // 处理不同端,不同返回值 // if (MUserManager::getInstance()->isWeb() === true) { $this->buildWebResponse(); return; } $response = array(); $isDir = true; if ($queryDbFile[0]["file_type"] == MConst::OBJECT_TYPE_FILE) { // TODO $mimeType = "text/plain"; $response["mime_type"] = $mimeType; $isDir = false; $response["thumb_exists"] = MUtils::isExistThumbnail($mimeType, (int) $queryDbFile[0]["file_size"]); } $size = $queryDbFile[0]["file_size"]; $response["size"] = MUtils::getSizeByLocale($locale, $size); $response["bytes"] = intval($size); $pathInfo = MUtils::pathinfo_utf($this->_to_path); $pathInfoOut = MUtils::pathinfo_utf($this->to_share_filter->src_path); $path = MUtils::convertStandardPath($pathInfoOut['dirname'] . "/" . $pathInfo['basename']); $response["path"] = $path; $response["root"] = $root; $response["is_dir"] = $isDir; $response["rev"] = strval($queryDbFile[0]["version_id"]); $response["revision"] = intval($queryDbFile[0]["version_id"]); $response["modified"] = MUtils::formatIntTime($queryDbFile[0]["file_update_time"]); // // 如果标记为不输出结果的话,直接返回$response // if (!$this->isOutput) { return $response; } echo json_encode($response); }
/** * (non-PHPdoc) * @see MIController::invoke() */ public function invoke($uri = NULL) { $this->setAction(MConst::CREATE_FILE); // 调用父类初始化函数,注册自定义的异常和错误处理逻辑 parent::init(); $hash = @$_REQUEST['hash']; if (empty($hash)) { $hash = MiniHttp::getParam("signature", ""); } // 接收参数 if (empty($hash)) { throw new MFilesException(Yii::t('api', MConst::PARAMS_ERROR . "Missing parameter 'hash'."), MConst::HTTP_CODE_400); } // 解析文件路径,若返回false,则错误处理 $urlManager = new MUrlManager(); $path = $urlManager->parsePathFromUrl($uri); $root = $urlManager->parseRootFromUrl($uri); if ($path == false || $root == false) { //支持参数模式传递上传路径 $path = MiniHttp::getParam("path", ""); $root = "miniyun"; $this->isNewVersion = true; if (empty($path)) { throw new MFilesException(Yii::t('api', MConst::PATH_ERROR), MConst::HTTP_CODE_411); } } $path = MiniUtil::specialWordReplace($path); $pathInfo = MUtils::pathinfo_utf($path); $fileName = $pathInfo["basename"]; $parentPath = $pathInfo["dirname"]; // 检查是否在共享文件夹内, 如果在共享文件夹内,则进行权限检查 $user = MUserManager::getInstance()->getCurrentUser(); $userId = $user["user_id"]; $shareFilter = MSharesFilter::init(); if ($shareFilter->handlerCheck($userId, $path)) { $userId = $shareFilter->master; $path = $shareFilter->_path; $filePath = "/" . $userId . $path; $shareFilter->hasPermissionExecute($filePath, MPrivilege::FILE_CREATE); } // 检查版本是否存在 if ($this->handleCheckFileVersion($hash, $fileName) == FALSE) { return; } $this->handler = MFilesCommon::initMFilesCommon(); $this->handler->parent_path = MUtils::convertStandardPath($parentPath); $this->handler->file_name = $fileName; $this->handler->root = $root; $this->handler->path = MUtils::convertStandardPath($path); $this->handler->type = MiniUtil::getMimeType($fileName); $this->handler->size = $this->size; $this->handler->file_hash = $hash; $this->handler->version_id = $this->version_id; // 保存文件meta $this->handler->saveFileMeta(); if (MUserManager::getInstance()->isWeb() === true) { $this->handler->buildWebResponse(); return; } $this->handler->buildResult(); }
/** * 处理创建文件信息及事件 * @param string $folderPath * @param int $parentFileId * @param boolean $hadFileDelete * @param int $userId * @return array */ private function createFileMeta($folderPath, $parentFileId, $hadFileDelete, $userId) { $fileName = MUtils::get_basename($folderPath); // 组装对象信息 $fileDetail = array(); $fileDetail["file_create_time"] = time(); $fileDetail["file_update_time"] = time(); $fileDetail["file_name"] = $fileName; $fileDetail["file_path"] = $folderPath; $fileDetail["file_size"] = 0; $fileDetail["file_type"] = MConst::OBJECT_TYPE_DIRECTORY; $fileDetail["parent_file_id"] = $parentFileId; $fileDetail["event_uuid"] = MiniUtil::getEventRandomString(MConst::LEN_EVENT_UUID); $fileDetail["mime_type"] = NULL; // 保存文件元数据 if ($hadFileDelete) { $updates = array(); $updates["file_update_time"] = time(); $updates["is_deleted"] = intval(false); $updates["file_type"] = MConst::OBJECT_TYPE_DIRECTORY; $updates["event_uuid"] = $fileDetail["event_uuid"]; // 存在已被删除的数据,只需更新 $this->updateByPath($folderPath, $updates); } else { // 不存在数据,添加 $file = $this->getByPath($folderPath); if (empty($file)) { if (!empty($fileDetail["file_name"])) { $this->create($fileDetail, $userId); $device = MUserManager::getInstance()->getCurrentDevice(); $event_action = MConst::CREATE_DIRECTORY; MiniEvent::getInstance()->createEvent($userId, $device["device_id"], $event_action, $fileDetail["file_path"], $fileDetail["file_path"], $fileDetail["event_uuid"], 0); } } } return $fileDetail; }
/** * 处理创建文件信息及事件 */ private function createFile($path, $parentFileId, $hadFileDelete) { $fileName = MUtils::get_basename($path); // 组装对象信息 $fileDetail = array(); $fileDetail["file_create_time"] = time(); $fileDetail["file_update_time"] = time(); $fileDetail["file_name"] = $fileName; $fileDetail["file_path"] = $path; $fileDetail["file_size"] = 0; $fileDetail["file_type"] = MConst::OBJECT_TYPE_DIRECTORY; $fileDetail["parent_file_id"] = $parentFileId; $fileDetail["event_uuid"] = MiniUtil::getEventRandomString(MConst::LEN_EVENT_UUID); $fileDetail["mime_type"] = NULL; // 保存文件元数据 if ($hadFileDelete) { $updates = array(); $updates["file_update_time"] = time(); $updates["is_deleted"] = intval(false); $updates["file_type"] = MConst::OBJECT_TYPE_DIRECTORY; $updates["event_uuid"] = $fileDetail["event_uuid"]; // 存在已被删除的数据,只需更新 $retValue = MiniFile::getInstance()->updateByPath($path, $updates); } else { $pathArr = explode("/", $path); // if($this->_user_id!=$pathArr[1]){ // $this->_user_id = $pathArr[1]; // } // 不存在数据,添加 $retValue = MiniFile::getInstance()->create($fileDetail, $pathArr[1]); $user = Yii::app()->session["user"]; if ((int) $pathArr[1] !== (int) $user['user_id']) { //只有当被共享者在共享目录下创建目录时,才会记录create_id MFileMetas::createFileMeta($path, 'create_id', $user['user_id']); } } if ($retValue === false) { throw new MFileopsException(Yii::t('api', 'Internal Server Error'), MConst::HTTP_CODE_500); } // 保存事件 $event_action = MConst::CREATE_DIRECTORY; $retValue = MiniEvent::getInstance()->createEvent($this->_user_id, $this->_user_device_id, $event_action, $fileDetail["file_path"], $fileDetail["file_path"], $fileDetail["event_uuid"], $this->share_filter->type); if ($retValue === false) { throw new MFileopsException(Yii::t('api', 'Internal Server Error'), MConst::HTTP_CODE_500); } // 为每个共享用户创建事件 if (isset($this->share_filter)) { $this->share_filter->handlerAction($event_action, $this->_user_device_id, $fileDetail["file_path"], $fileDetail["file_path"]); } return $fileDetail; }