/** * 恢复版本 * @param $signature * @param $filePath * @return mixed */ public function recover($signature, $filePath) { $share = new MiniShare(); $minFileMeta = $share->getMinFileMetaByPath($filePath); $filePath = $minFileMeta["ori_path"]; return MiniFile::getInstance()->recover($this->user["id"], $filePath, $signature); }
/** * * @param $path * @param $originDomain口 * @param $chooserAppKey * @param $session */ public function LinkCreateBiz($path, $originDomain, $chooserAppKey, $session) { parent::MiniBiz(); $arr = explode('/', $path); $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); } $this->originDomain = $originDomain; $this->appKey = $chooserAppKey; $this->session = $session; $path = MiniUtil::joinPath($path); $this->file = MiniFile::getInstance()->getByPath($path); }
/** * 根據文件Id获取文件数据 */ public function getLink($fileId, $linkType, $shareKey) { $data = array(); $file = MiniFile::getInstance()->getById($fileId); $data["name"] = $file["file_name"]; $data["bytes"] = intval($file["file_size"] + ""); $fileType = $file["file_type"]; if ($fileType == 0) { $data["icon"] = MiniHttp::getIcon4File($file["file_name"]); if (!MiniUtil::isMixCloudVersion()) { $data["icon"] = MiniHttp::getMiniHost() . "statics/static/mini-box/images/link/" . $data["icon"]; } else { $data["icon"] = "http://static.miniyun.cn/static/mini-box/images/link/" . $data["icon"]; } } $ext = MiniUtil::getFileExtension($file["file_name"]); $path = MiniUtil::getRelativePath($file["file_path"]); if ($ext == "jpg" || $ext == "jpeg" || $ext == "png" || $ext == "gif") { $data["thumbnail_link"] = MiniHttp::createAnonymousUrl("linkAccess/thumbnail?key=" . $shareKey . "&size=256x256&path=" . urlencode($path)); } else { $data["thumbnail_link"] = ""; } if ($linkType == MiniLink::$PREVIEW_LINK) { $data["link"] = MiniHttp::createUrl("link/access/key/" . $shareKey); } else { $data["link"] = MiniHttp::createAnonymousUrl("linkAccess/download?key=" . $shareKey . "&path=" . urlencode($path)); } return $data; }
/** *根据文件的Hash值下载内容 * @param string $signature 文件hash值 * @throws 404错误 */ public function download($signature) { $version = MiniVersion::getInstance()->getBySignature($signature); if (!empty($version)) { //根据文件内容输出文件内容 MiniFile::getInstance()->getContentBySignature($signature, $signature, $version["mime_type"]); } else { throw new MFileopsException(Yii::t('api', 'File Not Found'), 404); } }
/** * 获取公共目录列表 * @return array */ public function getList() { $publicFolderList = MiniGroupPrivilege::getInstance()->getPublic(); $fileList = array(); foreach ($publicFolderList as $publicFolder) { $filePath = $publicFolder['file_path']; $file = MiniFile::getInstance()->getByPath($filePath); $file['permission'] = $publicFolder['permission']; $file['is_public_folder'] = true; array_push($fileList, $file); } return $this->list = $fileList; }
/** * 控制器执行主逻辑函数 * */ 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); }
/** * 获取用户全部的共享目录 * @param integer $userId * @return array */ public function handleGetAllSharesFolder($userId) { $files = MiniFile::getInstance()->getShares($userId); $paths = array(); foreach ($files as $file) { $fileMeta = MiniFileMeta::getInstance()->getFileMeta($file['file_path'], 'shared_folders'); if ($fileMeta === NULL) { continue; } $metaValue = unserialize($fileMeta['meta_value']); array_push($paths, $metaValue['path']); array_push($paths, $file['file_path']); } return $paths; }
/** * 删除多余数据 */ private function modifyData() { $users = MiniUser::getInstance()->getAll(); foreach ($users as $user) { $path = "/" . $user["id"]; $file = MiniFile::getInstance()->getByPath($path); if (!empty($file)) { if ($user["id"] === $file["user_id"]) { try { MiniFile::getInstance()->deleteFile($file["id"]); } catch (Exception $e) { } } } } }
/** * 判断文件夹内是否有父目录被共享 */ public function isParentShared($path) { $arr = explode('/', $path); $parentPath = "/" . $arr[1]; for ($i = 2; $i < count($arr); $i++) { $parentPath = $parentPath . "/" . $arr[$i]; $file = MiniFile::getInstance()->getByFilePath($parentPath); if ($file['file_type'] == 2 || $file['file_type'] == 4) { $user = MUserManager::getInstance()->getCurrentUser(); $userId = $user['user_id']; $this->permission = $this->getPermission($userId, $file['file_path']); $this->shareRootPath = $file['file_path']; return true; } } return false; }
/** 按照文件名查找假删除文件 * @param $fileName * @return mixed */ public function search($fileName) { $sessionUser = $this->user; $user_id = $sessionUser["id"]; $deleteList = MiniFile::getInstance()->getFileByNameRecycle($user_id, $fileName); $list = array(); $data = array(); foreach ($deleteList as $value) { $data["file_name"] = $value["file_name"]; $data["file_size"] = $value["file_size"]; $data["file_path"] = MiniUtil::getRelativePath($value["file_path"]); $data["create_time"] = $value["file_create_time"]; $data["is_deleted"] = $value["is_deleted"]; $data["type"] = $value["file_type"]; $list[] = $data; } $dataList['list'] = $list; return $dataList; }
/** * 全文检索 * @param string $key 关键字 * @param string $path 路径 * @return array */ public function search($key, $path) { $siteId = MiniSiteUtils::getSiteID(); $searchItems = $this->searchKeyWordAndSiteId($siteId, $key); $values = array(); foreach ($searchItems as $searchItem) { //遍历,查询文件signature,根据signature判断当前用户有无浏览该文件权限 $version = MiniVersion::getInstance()->getBySignature($searchItem["signature"]); //反向查询系统所有的文件记录 $fileList = MiniFile::getInstance()->getAllByVersionId($version["id"]); foreach ($fileList as $file) { //对具有相同signature的文件进行过滤 $filePath = $file['file_path']; $isInString = strpos($filePath, $path); if ($isInString === false) { continue; } $userId = (int) $this->user['id']; $permission = UserPermissionBiz::getInstance()->getPermission($filePath, $userId); if ($permission['permission'] == '000000000' || $permission['permission'] == '011111111') { //没有读权限则不显示出来 continue; } if (empty($permission)) { //如果上面读权限为空,则说明没有共享,这时当前用户只能看见自己的文件 $pathArr = explode('/', $filePath); $masterId = $pathArr[1]; if ($masterId != $userId) { continue; } } $item = array(); $item['signature'] = $searchItem["signature"]; //相同的signature可能对应多个文件 $item['file_name'] = $file['file_name']; $item['file_path'] = $filePath; $item['summary'] = $searchItem["summary"]; array_push($values, $item); } } return $values; }
/** * 根据相对路径获得文件最小对象 * @param $relativePath * @return Array|NULL */ public function getMinFileMetaByPath($absolutePath) { $data = array(); //如果是根目錄 $relativePath = rawurldecode($absolutePath); // $absolutePath = MiniUtil::joinPath($this->user["id"], rawurldecode($relativePath)); if (empty($relativePath)) { $data["ori_path"] = $absolutePath; return $data; } $file = MiniFile::getInstance()->getByPath($absolutePath); if (!empty($file)) { $data["mime_type"] = $file["mime_type"]; $data["version_id"] = $file["version_id"]; $data["ori_path"] = $file["file_path"]; return $data; } $info = explode("/", $absolutePath); if (count($info) < 2) { return NULL; } // //共享目录都在根目录下,在这里拼接出file_mates需要的file_path // $shareFilePath = MiniUtil::joinPath($info[1],$info[2]); // //查询所在的根目录是否是共享目录 // $meta = MiniFileMeta::getInstance()->getFileMeta($shareFilePath,"shared_folders"); // if($meta===NULL){ // return NULL; // } // $metaValue = $meta["meta_value"]; // //获得发起人所在的目录根目录信息,并且拼接出文件原始路径 // $shareDetail = unserialize($metaValue); // $initiatorRootPath = $shareDetail["path"]; // $shareRelativePath = substr($absolutePath,strlen($shareFilePath)); // $oriPath = $initiatorRootPath.$shareRelativePath; // $file = MiniFile::getInstance()->getByPath($oriPath); // $data["mime_type"] = $file["mime_type"]; // $data["version_id"] = $file["version_id"]; // $data["ori_path"] = $file["file_path"]; // return $data; }
/** * 分享用户指定分享 * @param $userNames * @return bool */ public function sendToTransfer($userNames) { $link = MiniLink::getInstance()->getByKey($this->key); if ($link === NULL) { return; } $file = MiniFile::getInstance()->getById($link["file_id"]); if ($file === NULL) { return; } $deviceId = $this->device["id"]; if (count($userNames) > 0) { foreach ($userNames as $name) { $user = MiniUser::getInstance()->getUserByName($name); if ($user === NULL) { continue; } MiniFile::getInstance()->copy($file["id"], $user['id'], $deviceId, 0); } return true; } return false; }
/** * 根据path检查是否属于共享 * @param integer $userId * @param string $path - 不含user_id的路径 */ public function handlerCheck($userId, $path, $action = false) { $this->is_shared = false; $this->operator = $userId; $this->master = $userId; $this->src_path = $path; $this->_path = $path; $parts = explode('/', $path); // 去掉空值 $parts = array_filter($parts); // 组装路径 $paths = array(); for ($i = 0; $i < count($parts); $i++) { $tarray = array_slice($parts, 0, $i + 1); $tmp = join('/', $tarray); $paths['/' . $userId . '/' . $tmp] = $tmp; } //根据用户查询属于用户的共享 $files = MiniFile::getInstance()->getShares($userId); $sharedPath = ''; foreach ($files as $file) { //表示这是共享目录 if (isset($paths[$file['file_path']])) { $sharedPath = $file['file_path']; break; } } if ($sharedPath == '') { return false; } $file_meta = MiniFileMeta::getInstance()->getFileMeta($sharedPath, "shared_folders"); if ($file_meta === NULL) { return $this->is_shared; } $meta_value = unserialize($file_meta['meta_value']); $this->master = $meta_value['master']; $this->slaves = $meta_value['slaves']; // 共享者的共享目录path $this->_shared_path = $meta_value['path']; $path = '/' . $this->operator . $path; $this->_path = substr_replace($path, $this->_shared_path, 0, strlen($sharedPath)); $this->_path = substr_replace($this->_path, '', 0, strlen('/' . $this->master)); // 如果这两个地址相同,则表示是共享目录本身的操作 if ($this->_shared_path == '/' . $this->master . $this->_path) { $this->_is_shared_path = true; } // 判断用户是否对共享文件夹下面的文件拥有权限 $this->hasPermission($this->_shared_path, $action); $this->file_type = $file['file_type']; $muser = User::model()->findByPk($this->master); if (!$muser) { throw new Exception(Yii::t('api', 'Internal Server Error'), '500'); } $this->master_nick = $muser['user_name']; $this->is_shared = true; return $this->is_shared; }
/** * 获取根目录下文件夹 */ public function getFolders() { $userId = $this->user['id']; $folders = MiniFile::getInstance()->getChildrenFolderByParentId($userId, 0, 0); $folderArr = array(); foreach ($folders as $folder) { $publicFolderPrivilege = MiniGroupPrivilege::getInstance()->getByPublicPath($folder['file_path']); $folder['privilege'] = $publicFolderPrivilege; array_push($folderArr, $folder); } return $folderArr; }
private function updateData() { MiniFile::getInstance()->updateAllFileNamePinyin(); }
/** * 获取文本内容 * @param $key * @param $path * @return mixed */ public function txtContent($key, $path) { $link = MiniLink::getInstance()->getByKey($key); if ($link !== NULL) { $file = MiniFile::getInstance()->getById($link["file_id"]); $parentPath = $file["file_path"]; if ($file !== NULL) { $userId = $file["user_id"]; $absolutePath = MiniUtil::getAbsolutePath($userId, $path); //必须限定子目录在外链目录下 if (strpos($absolutePath, $parentPath) == 0) { return MiniFile::getInstance()->getTxtContent($absolutePath); } } } }
/** * 获取文件的相关信息 */ public function info($path) { $data = MiniFile::getInstance()->getByFilePath($path); return $data; }
/** * 控制器执行主逻辑函数, 处理删除文件或者文件夹 */ public function invoke($uri = null) { $this->setAction(MConst::DELETE); // 调用父类初始化函数,注册自定义的异常和错误处理逻辑 parent::init(); $params = $_REQUEST; // 检查参数 if (isset($params) === false) { throw new MFileopsException(Yii::t('api', 'Bad Request 8'), MConst::HTTP_CODE_400); } // // 获取用户数据,如user_id $user = MUserManager::getInstance()->getCurrentUser(); $device = MUserManager::getInstance()->getCurrentDevice(); $this->_user_id = $user["user_id"]; $user_nick = $user["user_name"]; $user_device_id = $device["device_id"]; $this->_user_device_name = $device["user_device_name"]; // 文件大小格式化参数 $locale = "bytes"; if (isset($params["locale"])) { $locale = $params["locale"]; } if (isset($params["root"]) === false || isset($params["path"]) === false) { throw new MFileopsException(Yii::t('api', 'Bad Request 9'), MConst::HTTP_CODE_400); } $root = $params["root"]; $path = $params["path"]; $isDir = $params["is_dir"]; $pathArr = explode('/', $path); if ($path == '/' || empty($pathArr[2]) || empty($pathArr[1])) { return; } if ($isDir) { //避免人为添加删除目录 $arr = explode('/', $path); $isRoot = false; $isMine = false; if (count($arr) == 3) { $isRoot = true; } $fileOwnerId = $arr[1]; $currentUserId = $this->_user_id; if ($fileOwnerId == $currentUserId) { $isMine = true; } if ($isRoot && !$isMine) { //如果是在根目录下且不是自己的目录 则后台控制不准取消共享 throw new MFileopsException(Yii::t('api', 'Internal Server Error'), MConst::HTTP_CODE_409); } } // // 转换路径分隔符,便于以后跨平台,如:将 "\"=>"/" // $path = MUtils::convertStandardPath($path); if ($path == "" || $path == "/" || $path === false) { throw new MFileopsException(Yii::t('api', 'Bad request 10'), MConst::HTTP_CODE_400); } // 检查是否是共享目录 $share_filter = MSharesFilter::init(); if ($share_filter->handlerCheck($this->_user_id, $path)) { $this->_user_id = $share_filter->master; $path = $share_filter->_path; } // // 如果删除的是共享目录,则转到ShareManager处理 // if ($share_filter->_is_shared_path && $share_filter->operator != $share_filter->master) { $file = MFiles::queryFilesByPath("/" . $share_filter->operator . $share_filter->src_path); if (!$file) { throw new MFileopsException(Yii::t('api', 'Internal Server Error'), MConst::HTTP_CODE_500); } $id = $file[0]["id"]; $handler = new ShareManager(); $handler->_userId = $share_filter->operator; $handler->_id = $id; try { $handler->invoke(ShareManager::CANCEL_SHARED); } catch (Exception $e) { throw new MFileopsException(Yii::t('api', 'Internal Server Error'), MConst::HTTP_CODE_500); } // 输出返回值 $path = MUtils::convertStandardPath($share_filter->src_path); $this->buildResult($root, $path, $handler->_file["version_id"], $handler->_file["file_update_time"], true); return; } if ($share_filter->_is_shared_path && $share_filter->operator != $share_filter->master) { throw new MException(Yii::t('api', 'You do not have permission to perform the delete operation.'), MConst::HTTP_CODE_409); } // // 组装对象信息 // $file_name = MUtils::get_basename($path); $file_detail = new MFiles(); $file_detail->file_name = $file_name; $file_detail->file_path = $path; // // 查询其目录信息,是否存在 // $query_db_file = MFiles::queryFilesByPath($file_detail->file_path); //数据已不存在 if (count($query_db_file) <= 0) { throw new MFileopsException(Yii::t('api', 'Not found the source files of the specified path'), MConst::HTTP_CODE_404); } $data = array("obj" => $this, "share_filter" => $share_filter, "query_db_file" => $query_db_file[0]); //在共享文件夹中进行删除权限判断 if ($share_filter->is_shared && $query_db_file[0]["file_type"] != MConst::OBJECT_TYPE_BESHARED) { if ($query_db_file[0]["file_type"] == 0) { //文件删除 $share_filter->hasPermissionExecute($query_db_file[0]["file_path"], MPrivilege::FILE_DELETE); } else { //文件夹删除 $share_filter->hasPermissionExecute($query_db_file[0]["file_path"], MPrivilege::FOLDER_DELETE); } } // // 可以删除包含子文件的目录 // 检查其是否为文件夹 // $files = array(); $file_detail->is_dir = false; $file_detail->id = $query_db_file[0]["id"]; $file_detail->file_size = $query_db_file[0]["file_size"]; $file_detail->file_type = $query_db_file[0]["file_type"]; if ($query_db_file[0]["file_type"] > MConst::OBJECT_TYPE_FILE) { $file_detail->is_dir = true; $files = $this->handleChildrenFile($file_detail->file_path, $files); } else { // 处理加入版本历史 $this->handleFileMeta($file_detail->file_path, $query_db_file[0]["version_id"], $this->_user_id, $user_nick, $this->_user_device_name, $file_detail->file_size); } $isSharedPath = false; $pathArr = explode('/', $file_detail->file_path); $masterId = $pathArr[1]; if ($masterId != $this->_user_id) { $isSharedPath = true; } else { $model = new GeneralFolderPermissionBiz($file_detail->file_path); if ($model->isParentShared($file_detail->file_path)) { //如果是父目录被共享 $isSharedPath = true; } } if ($isSharedPath) { $permissionArr = UserPermissionBiz::getInstance()->getPermission($file_detail->file_path, $user["user_id"]); $permission = $permissionArr['permission']; if (!empty($permission)) { $privilegeModel = new PrivilegeBiz(); $share_filter->slaves = $privilegeModel->getSlaveIdsByPath($permissionArr['share_root_path']); $share_filter->is_shared = true; if ($file_detail->file_type == 0) { //删除文件 $can_file_delete = substr($permission, 7, 1); if ($can_file_delete == 0) { throw new MFileopsException(Yii::t('api', 'no permission'), MConst::HTTP_CODE_409); } } if ($file_detail->file_type == 1 || $file_detail->file_type == 2 || $file_detail->file_type == 4) { $can_folder_delete = substr($permission, 3, 1); if ($can_folder_delete == 0) { throw new MFileopsException(Yii::t('api', 'no permission'), MConst::HTTP_CODE_409); } } } } // // 更新文件元数据的为删除数据 // $this->assembleFileDetail($file_detail, $query_db_file[0]); $ret_value = MFiles::updateRemoveFileDetail($file_detail); if ($ret_value === false) { throw new MFileopsException(Yii::t('api', 'Internal Server Error'), MConst::HTTP_CODE_500); } // // 将删除目录加入数组 // array_push($files, $file_detail); // // 保存事件 // $ret_value = MiniEvent::getInstance()->createEvents($this->_user_id, $user_device_id, $files, $share_filter->type); if ($ret_value === false) { throw new MFileopsException(Yii::t('api', 'Internal Server Error'), MConst::HTTP_CODE_500); } // // // if ($share_filter->is_shared) { foreach ($files as $file) { $share_filter->handlerAction($file->event_action, $user_device_id, $file->from_path, $file->context); } } // // 删除共享目录(删除共享目录,对应的权限也一起删除) // //首先判断用户有无删除权限 $userPrivilegeList = MiniUserPrivilege::getInstance()->getPrivilegeList($file_detail->file_path); $groupPrivilegeList = MiniGroupPrivilege::getInstance()->getPrivilegeList($file_detail->file_path); if (!empty($userPrivilegeList)) { MiniUserPrivilege::getInstance()->deleteByFilePath($file_detail->file_path); } if (!empty($groupPrivilegeList)) { MiniGroupPrivilege::getInstance()->deleteByFilePath($file_detail->file_path); } //并且将file_type改为1 if ($file_detail->file_type == 0) { MiniFile::getInstance()->togetherShareFile($file_detail->file_path, Mconst::OBJECT_TYPE_FILE); } else { MiniFile::getInstance()->togetherShareFile($file_detail->file_path, Mconst::OBJECT_TYPE_DIRECTORY); } if ($filter !== true && $share_filter->_is_shared_path && $share_filter->operator == $share_filter->master) { $file = MFiles::queryFilesByPath("/" . $share_filter->operator . $path, true); if (!$file) { throw new MFileopsException(Yii::t('api', 'Internal Server Error'), MConst::HTTP_CODE_500); } $id = $file[0]["id"]; $handler = new ShareManager(); $handler->_userId = $share_filter->operator; $handler->_id = $id; try { $handler->invoke(ShareManager::CANCEL_SHARED); } catch (Exception $e) { throw new MFileopsException(Yii::t('api', 'Internal Server Error'), MConst::HTTP_CODE_500); } } // 如果彻底删除,则调用回收站 if ($this->completely_remove) { $trash = new Trash(); $trash->_userId = $this->_user_id; $trash->fromIds = $file_detail->id; try { $trash->invoke(Trash::DELETE); } catch (Exception $e) { throw new MFileopsException(Yii::t('api', 'Internal Server Error'), MConst::HTTP_CODE_500); } //执行的额外操作 $this->extend($share_filter, $query_db_file, $file_detail); return; } $path = CUtils::removeUserFromPath($query_db_file[0]["file_path"]); $path_info = MUtils::pathinfo_utf($path); $path_info_out = MUtils::pathinfo_utf($share_filter->src_path); $path = MUtils::convertStandardPath($path_info_out['dirname'] . "/" . $path_info['basename']); //执行的额外操作 $this->extend($share_filter, $query_db_file, $file_detail); $this->buildResult($root, $path, $query_db_file[0]["version_id"], $query_db_file[0]["file_update_time"], $file_detail->is_dir); }
/** * 获取用户使用的空间大小 * 在计算用户空间这里, * @param $userId 用户ID * @return bool|mixed */ private function getUsedSize($userId) { $usedSpace = MiniFile::getInstance()->getUsedSize($userId); return $usedSpace; }
/** * 控制器执行主逻辑函数 */ 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(); } }
/** * 控制器执行主逻辑函数, 处理移动文件或者文件夹 * * @return mixed $value 返回最终需要执行完的结果 */ public function invoke($uri = null) { // 调用父类初始化函数,注册自定义的异常和错误处理逻辑 parent::init(); $this->setAction(MConst::MOVE); $params = $_REQUEST; // 检查参数 if (isset($params) === false) { throw new MException(Yii::t('api', 'Bad Request 7')); } // // 获取用户数据,如user_id $user = MUserManager::getInstance()->getCurrentUser(); $device = MUserManager::getInstance()->getCurrentDevice(); $this->_userId = $user["user_id"]; $this->master = $user["user_id"]; $user_nick = $user["user_name"]; $user_device_id = $device["device_id"]; $this->_user_device_name = $device["user_device_name"]; // 文件大小格式化参数 $this->_locale = "bytes"; if (isset($params["locale"])) { $this->_locale = $params["locale"]; } if (isset($params["root"]) === false || isset($params["from_path"]) === false || isset($params["to_path"]) === false) { throw new MFileopsException(Yii::t('api', 'Bad Request'), MConst::HTTP_CODE_400); } $this->_root = $params["root"]; $from_path = $params["from_path"]; $to_path = $params["to_path"]; $arr = explode('/', $from_path); $isRoot = false; $isMine = false; if (count($arr) == 3) { $isRoot = true; } $fileOwnerId = $arr[1]; $currentUserId = $this->_userId; if ($fileOwnerId == $currentUserId) { $isMine = true; } if ($isRoot && !$isMine) { //如果是在根目录下且不是自己的目录 则后台控制不准取消共享 throw new MFileopsException(Yii::t('api', 'Internal Server Error'), MConst::HTTP_CODE_409); } $to_parts = explode('/', $to_path); $from_parts = explode('/', $from_path); if (count($to_parts) == 2) { $to_path = '/' . $this->_userId . $to_path; } $to_parts = explode('/', $to_path); $file = MiniFile::getInstance()->getByPath($from_path); $isSelfFile = false; if (!empty($file) && $file['user_id'] == $this->_userId) { $isSelfFile = true; } // 转换路径分隔符,便于以后跨平台,如:将 "\"=>"/" $from_path = MUtils::convertStandardPath($from_path); $to_path = MUtils::convertStandardPath($to_path); if ($to_path[strlen($to_path) - 1] == "/") { // 目标文件无效,403 error throw new MFileopsException(Yii::t('api', 'The file or folder name is invalid'), MConst::HTTP_CODE_403); } // 检查共享 $this->from_share_filter = MSharesFilter::init(); $this->to_share_filter = MSharesFilter::init(); $isSharedPath = true; $this->rename = false; // 检查移动方式 if ($this->rename == true) { // 先copy再删除,如果是移动共享文件夹则只copy,再执行shareManager取消共享 $copy_handler = new MCopyController(); $copy_handler->isOutput = false; $response = $copy_handler->invoke(); $_REQUEST['path'] = $params["from_path"]; $delete_handler = new MDeleteController(); $delete_handler->isOutput = false; $delete_handler->completely_remove = true; $delete_handler->invoke(); if (MUserManager::getInstance()->isWeb() === true) { $this->buildWebResponse(); exit; return; } echo json_encode($response); return; } $file_name = MUtils::get_basename($to_path); // 检查文件名是否有效 $is_invalid = MUtils::checkNameInvalid($file_name); if ($is_invalid) { throw new MFileopsException(Yii::t('api', 'The file or folder name is invalid'), MConst::HTTP_CODE_400); } // 检查是否移动到其子目录下 if (strpos($to_path, $from_path . "/") === 0) { throw new MFileopsException(Yii::t('api', 'Can not be moved to the subdirectory'), MConst::HTTP_CODE_403); } if ($to_path == "/{$this->_userId}" || $to_path == "/{$this->_userId}/") { throw new MFileopsException(Yii::t('api', 'Can not be moved to the error directory'), MConst::HTTP_CODE_403); } $from_parent = CUtils::pathinfo_utf($from_path); $to_parent = CUtils::pathinfo_utf($to_path); $privilegeModel = new PrivilegeBiz(); if (!(count($to_parts) == 3)) { $isSharedPath = false; $toPathArr = explode('/', $to_path); $masterId = $toPathArr[1]; if ($masterId != $this->_userId) { $isSharedPath = true; } else { $model = new GeneralFolderPermissionBiz($to_parent['dirname']); if ($model->isParentShared($to_parent['dirname'])) { //如果是父目录被共享 $isSharedPath = true; } } if ($isSharedPath) { $toPrivilege = UserPermissionBiz::getInstance()->getPermission($to_parent['dirname'], $this->_userId); if (empty($toPrivilege)) { $toPrivilege['permission'] = MConst::SUPREME_PERMISSION; } else { $this->to_share_filter->slaves = $privilegeModel->getSlaveIdsByPath($toPrivilege['share_root_path']); $this->to_share_filter->is_shared = true; } } else { $toPrivilege['permission'] = MConst::SUPREME_PERMISSION; } $toFilter = new MiniPermission($toPrivilege['permission']); } else { if ($to_parent['dirname'] == $from_parent['dirname']) { $isSharedPath = false; $fromPathArr = explode('/', $from_path); $masterId = $fromPathArr[1]; if ($masterId != $this->_userId) { $isSharedPath = true; } else { $model = new GeneralFolderPermissionBiz($from_path); if ($model->isParentShared($from_path)) { //如果是父目录被共享 $isSharedPath = true; } } if ($isSharedPath) { $toPrivilege = UserPermissionBiz::getInstance()->getPermission($from_path, $this->_userId); if (!empty($toPrivilege)) { $this->to_share_filter->slaves = $privilegeModel->getSlaveIdsByPath($toPrivilege['share_root_path']); $this->to_share_filter->is_shared = true; } else { $toPrivilege['permission'] = MConst::SUPREME_PERMISSION; } } else { $toPrivilege['permission'] = MConst::SUPREME_PERMISSION; } } $toFilter = new MiniPermission(MConst::SUPREME_PERMISSION); } $isSharedPath = false; $fromPathArr = explode('/', $from_path); $masterId = $fromPathArr[1]; if ($masterId != $this->_userId) { $isSharedPath = true; } else { $model = new GeneralFolderPermissionBiz($from_path); if ($model->isParentShared($from_path)) { //如果是父目录被共享 $isSharedPath = true; } } if ($isSharedPath) { $fromPrivilege = UserPermissionBiz::getInstance()->getPermission($from_path, $this->_userId); if (empty($fromPrivilege)) { $fromPrivilege['permission'] = MConst::SUPREME_PERMISSION; } else { $this->from_share_filter->slaves = $privilegeModel->getSlaveIdsByPath($fromPrivilege['share_root_path']); $this->from_share_filter->is_shared = true; } } else { $fromPrivilege['permission'] = MConst::SUPREME_PERMISSION; } $fromFilter = new MiniPermission($fromPrivilege['permission']); if ($to_parent['dirname'] == $from_parent['dirname']) { $this->setAction(MConst::RENAME); $this->isRename = true; $canRenameFile = $fromFilter->canModifyFileName(); $canRenameFolder = $fromFilter->canModifyFolderName(); $canRenameFile2 = $toFilter->canModifyFileName(); $canRenameFolder2 = $toFilter->canModifyFolderName(); if ($file['file_type'] > 0 && !$canRenameFolder && !$isSelfFile) { //如果目标是目录,则当其不为己文件,且无更名权限时 exception throw new MFileopsException(Yii::t('api', 'have no permission to rename folder'), MConst::HTTP_CODE_409); } if ($file['file_type'] == 0 && !$canRenameFile && !$isSelfFile) { //如果目标是文件,则当其不为己文件,且无更名权限时 exception throw new MFileopsException(Yii::t('api', 'have no permission to rename file'), MConst::HTTP_CODE_409); } if ($file['file_type'] > 0 && !$canRenameFolder2 && !$isSelfFile) { //如果目标是目录,则当其不为己文件,且无更名权限时 exception throw new MFileopsException(Yii::t('api', 'have no permission to rename folder'), MConst::HTTP_CODE_409); } if ($file['file_type'] == 0 && !$canRenameFile2 && !$isSelfFile) { //如果目标是文件,则当其不为己文件,且无更名权限时 exception throw new MFileopsException(Yii::t('api', 'have no permission to rename file'), MConst::HTTP_CODE_409); } } else { $canDeleteFile = $fromFilter->canDeleteFile(); $canDeleteFile2 = $toFilter->canDeleteFile(); if (!$canDeleteFile || !$canDeleteFile2) { throw new MFileopsException(Yii::t('api', 'have no permission to move file'), MConst::HTTP_CODE_409); } } // 先检查源目录是否存在,如果不存在抛出404错误 // $query_db_file = MFiles::queryFilesByPath($from_path); if ($query_db_file === false || empty($query_db_file)) { throw new MFileopsException(Yii::t('api', 'The source file was not found at the specified path'), MConst::HTTP_CODE_404); } // // 检查目标是否存在(包括已被删除的状态) // $deleted = null; $query_db_goal_file = MFiles::queryAllFilesByPath($to_path); if ($query_db_goal_file) { if ($from_path !== $to_path && $query_db_goal_file[0]["is_deleted"] == false) { throw new MFileopsException(Yii::t('api', 'There is already a item at the given destination'), MConst::HTTP_CODE_403); } // 已删除文件的处理 if ($query_db_goal_file[0]["is_deleted"] == 1) { MFiles::deleteById($query_db_goal_file[0]["id"]); if ($query_db_goal_file[0]["file_type"] != 0) { // 文件则直接删除 $deleted = $query_db_goal_file[0]["id"]; } } } $query_db_file = MFiles::queryFilesByPath($from_path); if ($query_db_file === false || empty($query_db_file)) { throw new MFileopsException(Yii::t('api', 'Not found the source files of the specified path'), MConst::HTTP_CODE_404); } // // 检查移动原路径与目标路径是否一致,一致则则返回其文件信息 // if ($from_path === $to_path) { $this->buildResult($query_db_file[0]); return; } // // 查询目标路径父目录信息 // $pathInfo = MUtils::pathinfo_utf($to_path); $parent_path = $pathInfo["dirname"]; $create_folder = new MCreateFolderController(); $create_folder->_user_device_id = $user_device_id; $create_folder->_user_id = $this->_userId; if (count(explode('/', $parent_path)) == 2) { $parent_file_id = 0; } else { $parent_file_id = $create_folder->handlerParentFolder($parent_path); } $fromUserId = $from_parts[1]; $toUserId = $to_parts[1]; // // 组装对象信息 // $file_detail = new MFiles(); $file_detail->file_name = $file_name; $file_detail->file_path = $to_path; $file_detail->file_type = $query_db_file[0]["file_type"]; $file_detail->id = $query_db_file[0]["id"]; $file_detail->from_path = $from_path; $file_detail->parent_file_id = $parent_file_id; $file_detail->user_id = $toUserId; $file_detail->mime_type = NULL; $create_array = array(); // // 判断操作的是文件夹,还是文件 // if ($file_detail->file_type > MConst::OBJECT_TYPE_FILE) { if ($file['user_id'] != $this->_userId) { $updateUserId = $query_db_file[0]["user_id"]; } else { $updateUserId = $this->master; } // // 文件夹,将会对其子文件做进一步处理 // $ret_value = MFiles::updateMoveChildrenFileDetail($updateUserId, $file_detail); if ($ret_value === false) { throw new MFileopsException(Yii::t('api', 'Not found the source files of the specified path'), MConst::HTTP_CODE_404); } // // 针对文件夹下的文件,组装需要添加版本信息的文件 // $create_array = $this->handleChildrenVersions($create_array, $this->_userId, $user_nick, $from_path, $to_path, $query_db_file[0]["id"], $this->_user_device_name, $query_db_file[0]["file_size"]); } else { $file_detail->mime_type = MiniUtil::getMimeType($file_name); $file_meta = new MFileMetas(); $file_meta->version_id = $query_db_file[0]["version_id"]; // // 查询之前是否包含其版本 // $file_version = MFileMetas::queryFileMeta($to_path, MConst::VERSION); if ($file_version) { $meta_value = MUtils::getFileVersions($this->_user_device_name, $query_db_file[0]['file_size'], $file_meta->version_id, MConst::CREATE_FILE, $this->_userId, $user_nick, $file_version[0]["meta_value"]); $file_meta->is_add = false; } else { $meta_value = MUtils::getFileVersions($this->_user_device_name, $query_db_file[0]['file_size'], $file_meta->version_id, MConst::CREATE_FILE, $this->_userId, $user_nick); $file_meta->is_add = true; } $file_meta->meta_value = $meta_value; $file_meta->file_path = $to_path; $create_array[$to_path] = $file_meta; // // 添加到需要更新的版本ref // array_push($this->versions, $file_meta->version_id); } if ($file['file_type'] == 2 || $file['file_type'] == 4) { MiniUserPrivilege::getInstance()->updateByPath($from_path, $to_path); MiniGroupPrivilege::getInstance()->updateByPath($from_path, $to_path); if ($to_parent['dirname'] != $from_parent['dirname']) { MiniUserPrivilege::getInstance()->deleteByFilePath($to_path); MiniGroupPrivilege::getInstance()->deleteByFilePath($to_path); } } // // 创建版本信息 // $ret = MFileMetas::batchCreateFileMetas($create_array, MConst::VERSION); // if ($ret === false) // { // throw new MFileopsException( // Yii::t('api','Internal Server Error'), // MConst::HTTP_CODE_500); // } // // 更新版本 // foreach ($create_array as $file_meta) { if ($file_meta->is_add === true) { // 不存在记录,不需要更新 continue; } MFileMetas::updateFileMeta($file_meta->file_path, MConst::VERSION, $file_meta->meta_value); } // // 更新版本引用次数 // foreach ($this->versions as $vid) { MiniVersion::getInstance()->updateRefCount($vid); } // // 更新该对象元数据 // $file_detail->event_uuid = MiniUtil::getEventRandomString(MConst::LEN_EVENT_UUID); $ret_value = MFiles::updateMoveFileDetail($file_detail); // 移动目录 or 文件 if ($ret_value === false) { throw new MFileopsException(Yii::t('api', 'Internal Server Error'), MConst::HTTP_CODE_500); } $updates = array(); if ($file['file_type'] == 2 || $file['file_type'] == 4) { if ($to_parent['dirname'] != $from_parent['dirname']) { $updates['file_type'] = 1; $updates['user_id'] = $this->_userId; } } if ($fromUserId != $toUserId) { $updates['user_id'] = $toUserId; } MiniFile::getInstance()->updateByPath($to_path, $updates); //被共享者更改文件名更新file_meta记录 MiniFileMeta::getInstance()->modifyFilePath($from_path, 'create_id', $to_path, $file['file_type']); // // 保存移动事件 // by Kindac; // $event_action = $this->getGroupMove($file_detail->from_path, $file_detail->file_path); $ret_value = MiniEvent::getInstance()->createEvent($this->_userId, $user_device_id, $event_action, $file_detail->from_path, $file_detail->file_path, $file_detail->event_uuid, $this->to_share_filter->type); if ($ret_value === false) { throw new MFileopsException(Yii::t('api', 'Internal Server Error'), MConst::HTTP_CODE_500); } if ($file['type'] != 0) { $eventAction = MConst::CREATE_DIRECTORY; } else { $eventAction = MConst::CREATE_FILE; } if ($to_parent['dirname'] == $from_parent['dirname']) { $this->to_share_filter->handlerAction($event_action, $user_device_id, $file_detail->from_path, $file_detail->file_path); } else { if ($this->to_share_filter->is_shared) { $this->to_share_filter->handlerAction($eventAction, $user_device_id, $file_detail->file_path, $file_detail->file_path); } if ($this->from_share_filter->is_shared) { $this->from_share_filter->handlerAction(MConst::DELETE, $user_device_id, $file_detail->from_path, $file_detail->from_path); } } $query_db_file[0]["file_path"] = $file_detail->file_path; $query_db_file[0]["event_uuid"] = $file_detail->event_uuid; if (!empty($deleted)) { MFiles::updateParentId($deleted, $file_detail->id); } //进行扩展操作 $this->extend($from_path, $to_path); //执行完删除操作后执行的额外事物 $after = new MMoveAfter(); $after->action = self::$scene; // $after->from_share_filter = $from_share_filter; $after->to_share_filter = $this->to_share_filter; $after->from_path = $from_path; $after->to_path = $to_path; $after->file_detail = $file_detail; $after->execute(); $this->buildResult($query_db_file[0], $to_path); }
/** * 控制器执行主逻辑函数, 复制文件或者文件夹 */ 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); }
/** * * @param <string> $filename File path and name * @param <type> $used_fields array which contains the fields used in the array */ public function init_base64_array_from_file($filename, $used_fields) { $this->mode = "base64_array"; $mf = new MiniFile($filename); $this->array_data = array(); $input_array = $mf->getArray(); $outk = 0; foreach ($input_array as $id => $line) { $output_array = array($id); $k = 1; foreach ($line as $column_key => $column_value) { if (in_array($column_key, $used_fields)) { $output_array[$k] = $this->getRealValue($column_value, $column_key); $k = $k + 1; } } $this->array_data[$outk] = $output_array; $outk = $outk + 1; } }
/** * 判断目录是否可发起共享 * 递归查询父目录file_type情况,file_type=1时返回false,file_type==2||3时返回true */ public function getFolderPrivilege($currentUserId, $file) { $filePath = $file['file_path']; $fileType = (int) $file['file_type']; //被共享目录本身可以修改和删除 $privilege = array('resource.read' => 1, 'folder.create' => 1, 'folder.rename' => 1, 'folder.delete' => 1, 'file.create' => 1, 'file.modify' => 1, 'file.rename' => 1, 'file.delete' => 1, 'permission.grant' => 1, 'can_set_share' => 1); if ($fileType == 3) { $parentPath = $file['file_path']; //当用户,群组与部门中的用户权限出现重复时,获取最小部门的权限,顺序为用户,群组,部门 $userPrivilege = MiniUserPrivilege::getInstance()->getSpecifyPrivilege($currentUserId, $parentPath); if (empty($userPrivilege)) { $userGroupRelations = MiniUserGroupRelation::getInstance()->getByUserId($currentUserId); if (count($userGroupRelations) > 1) { //说明用户对应了群组和部门, $groupIdsArr = array(); //获取群组id foreach ($userGroupRelations as $userGroupRelation) { $group = MiniGroup::getInstance()->findById($userGroupRelation['group_id']); if ($group['user_id'] != -1) { array_push($groupIdsArr, $userGroupRelation['group_id']); } else { $departmentId = $userGroupRelation['group_id']; } } //将所有群组的权限放入数组 $permissionArr = array(); foreach ($groupIdsArr as $groupId) { $privilege_0 = MiniGroupPrivilege::getInstance()->getSpecifyPrivilege($groupId, $parentPath); if (!empty($privilege_0)) { array_push($permissionArr, $privilege_0['permission']); } } //拼接群组中权限的最大值,如果为空则为空字符串 $permission = ""; if (count($permissionArr) > 0) { for ($j = 0; $j < 10; $j++) { $isHighestAuthority = false; foreach ($permissionArr as $per) { if ($per[$j] == 1) { $isHighestAuthority = true; break; } } if ($isHighestAuthority) { $permission .= "1"; } else { $permission .= "0"; } } } if ($permission == "") { $groupPrivilege = MiniGroupPrivilege::getInstance()->getSpecifyPrivilege($departmentId, $parentPath); if (empty($groupPrivilege)) { $groupPrivilege = MiniGroupPrivilege::getInstance()->getGroupPrivilege($filePath, $departmentId); } $permission = $groupPrivilege['permission']; } } else { $groupId = $userGroupRelations[0]['group_id']; $groupPrivilege = MiniGroupPrivilege::getInstance()->getSpecifyPrivilege($groupId, $parentPath); if (empty($groupPrivilege)) { $groupPrivilege = MiniGroupPrivilege::getInstance()->getGroupPrivilege($filePath, $groupId); } $permission = $groupPrivilege['permission']; } } else { $permission = $userPrivilege['permission']; } for ($i = 0; $i < strlen($permission); $i++) { $privilege['resource.read'] = (int) $permission[0]; $privilege['folder.create'] = (int) $permission[1]; $privilege['folder.rename'] = (int) $permission[2]; $privilege['folder.delete'] = (int) $permission[3]; $privilege['file.create'] = (int) $permission[4]; $privilege['file.modify'] = (int) $permission[5]; $privilege['file.rename'] = (int) $permission[6]; $privilege['file.delete'] = (int) $permission[7]; $privilege['permission.grant'] = (int) $permission[8]; $privilege["can_set_share"] = 0; } } if ($fileType == 1) { $isShared = false; $userId = $file['user_id']; //判断下级目录是否有共享目录 $filePath = $file['file_path']; $children = MiniFile::getInstance()->getShowChildrenByPath($currentUserId, $filePath); $userGroupRelation = MiniUserGroupRelation::getInstance()->getByUserId($userId); $groupId = $userGroupRelation['group_id']; $arr = array(); array_push($arr, $groupId); foreach ($children as $child) { $childFilePath = $child['file_path']; if ($childFilePath == $filePath) { continue; } $file = MiniFile::getInstance()->getByFilePath($childFilePath); if ($file['file_type'] == 2) { $isShared = true; break; } } if ($isShared) { //子目录已经共享则不能二次共享 $privilege["can_set_share"] = 0; } else { //判断上级目录是否有共享目录 $arr = explode('/', $filePath); $parentPath = "/" . $userId; for ($i = 2; $i < count($arr); $i++) { $parentPath = $parentPath . "/" . $arr[$i]; $file = MiniFile::getInstance()->getByFilePath($parentPath); if ($file['file_type'] == 2) { $privilege["can_set_share"] = 0; } } } } return $privilege; }
/** * 创建对象 */ 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 getSharedParentPath($sharedpath) { $arr = explode('/', $sharedpath); $parentPath = "/" . $arr[1]; for ($i = 2; $i < count($arr); $i++) { $parentPath = $parentPath . "/" . $arr[$i]; $file = MiniFile::getInstance()->getByFilePath($parentPath); if ($file['file_type'] == 2) { return $parentPath; } } return null; }
/** 组装数组 * @param $fileList * @param $shareList * @param $key * @return array */ private function do2vo($fileList, $shareList, $key) { if ($key == 1) { $list = $fileList; } else { $list = $shareList; } $listShare = array(); foreach ($list as $value) { if ($key == 1) { $file = $value; $shareList = MiniLink::getInstance()->getByFileId($file["id"]); $share = $shareList; $shareData['file_name'] = null; } else { $share = $value; $fileList = MiniFile::getInstance()->getUndeleteFile($share['file_id']); $file = $fileList; } if (empty($file)) { break; } $shareData['file_name'] = $file['file_name']; $shareData['path'] = MiniUtil::getRelativePath($file['file_path']); $shareData['size'] = $file['file_size']; $shareData['updated_at'] = $share['updated_at']; $shareData['share_key'] = $share['share_key']; $shareData['file_type'] = $file['file_type']; $shareData['link'] = $this->link($share['share_key']); $listShare[] = $shareData; } return $listShare; }
/** * 根据路径,回复假删除文件 * @param string $path * @param int $userId * @param string $device * @return bool */ public function recoverDelete($path, $userId, $device) { if (strlen($path) != 0) { $path = "/" . $userId . $path; $pathArr = explode('/', $path); $jointPath = '/' . $userId; for ($i = 2; $i < count($pathArr); $i++) { $jointPath .= '/' . $pathArr[$i]; $criteria = new CDbCriteria(); $criteria->condition = "file_path = :path"; $criteria->params = array(":path" => $jointPath); $item = UserFile::model()->find($criteria); $item->is_deleted = 0; $item->save(); } } else { $items = $this->getDeleteFile($userId, null, null, null, 1); foreach ($items as $item) { $pathArr = explode('/', $item['file_path']); $jointPath = '/' . $userId; for ($i = 2; $i < count($pathArr); $i++) { $jointPath .= '/' . $pathArr[$i]; $criteria = new CDbCriteria(); $criteria->condition = "file_path = :path"; $criteria->params = array(":path" => $jointPath); $item = UserFile::model()->find($criteria); $item->is_deleted = 0; $item->save(); } } } /** * 为创建事件做准备 */ $file = MiniFile::getInstance()->getByPath($path); $version = FileVersion::model()->findByPk($file["version_id"]); $context = array("hash" => $version["file_signature"], "rev" => (int) $file['version_id'], "bytes" => (int) $file['file_size'], "update_time" => (int) $file['file_update_time'], "create_time" => (int) $file['file_create_time']); $action = 3; $context = serialize($context); if ($file['file_type'] == 1) { $context = $path; $action = 0; } MiniEvent::getInstance()->createEvent($userId, $device['device_id'], $action, $path, $context, MiniUtil::getEventRandomString(MConst::LEN_EVENT_UUID), MSharesFilter::init()); return true; }
public function getPermission($path, $userId) { $file = MiniFile::getInstance()->getByPath($path); if (empty($file)) { throw new MFilesException(Yii::t('api', MConst::PARAMS_ERROR), MConst::HTTP_CODE_400); } //查询公共目录 $pathArr = explode('/', $path); $masterId = $pathArr[1]; $master = MiniUser::getInstance()->getUser($masterId, false); $shareUserNick = $master['nick']; $privilegeLength = 9; $file = MiniFile::getInstance()->getByPath($path); $fileType = $file['file_type']; if ($fileType == 2) { //如果刚好是共享目录 if ((int) $masterId != $userId) { //该共享目录非当前用户目录时才会涉及权限 $userPrivilege = MiniUserPrivilege::getInstance()->getSpecifyPrivilege($userId, $path); if (empty($userPrivilege)) { //如果不存在user_privilege,则向上查找group_privilege和department_privilege $groupPermission = GroupPermissionBiz::getInstance()->getPermission($path, $userId); $departmentPrivilege = new DepartmentPermissionBiz(); $departmentPermission = $departmentPrivilege->getPermission($userId, $path); if (empty($groupPermission)) { $permission = $departmentPermission; } if (empty($departmentPermission)) { $permission = $groupPermission; } if (!empty($groupPermission) && !empty($departmentPermission)) { $permission = ''; $total = $groupPermission + $departmentPermission; for ($i = 0; $i < $privilegeLength; $i++) { $value = substr($total, $i, 1); if ($value == '1' || $value == '2') { $permission .= '1'; } else { $permission .= '0'; } } } if (empty($groupPermission) && empty($departmentPermission)) { $permission = null; } } else { $permission = $userPrivilege['permission']; } if ($permission == null) { return array('permission' => $permission); } return array("permission" => $permission, "share_root_path" => $path, "share_user_nick" => $shareUserNick, "is_share_folder" => true, 'can_set_share' => 0); } return array("permission" => MConst::SUPREME_PERMISSION, "share_root_path" => $path, "share_user_nick" => $shareUserNick, 'can_set_share' => 1); } if ($fileType == 1 || $fileType == 0) { //普通目录情况 $model = new GeneralFolderPermissionBiz($path); // if($model->permission == null){ if ($model->isChildrenShared($path)) { $permission = MConst::SUPREME_PERMISSION; return array("permission" => $permission, "share_user_nick" => $shareUserNick, 'children_shared' => true, 'can_set_share' => 0); } // } if ($model->isShared) { //如果该普通目录向上或者向下有共享 if ($model->isParentShared($path)) { //如果是父目录被共享 if ((int) $masterId != $userId) { //非共享者本人操作此文件 $permission = $model->permission; return array("permission" => $permission, "share_root_path" => $model->shareRootPath, "share_user_nick" => $shareUserNick, "is_share_folder" => true, 'can_set_share' => 0); } else { //本人操作文件 $permission = MConst::SUPREME_PERMISSION; return array("permission" => $permission, "share_root_path" => $model->shareRootPath, "share_user_nick" => $shareUserNick, "is_share_folder" => true, 'can_set_share' => 0); } } } else { //向上向下均没有共享 return null; } } if ($fileType == 4) { //公共目录情况 $model = new PublicFolderPermissionBiz(); $permission = $model->getPublicPermission($path); if ($permission == null) { return null; } if ((int) $masterId != $userId) { //非共享者本人操作此文件 return array("permission" => $permission, "share_user_nick" => $shareUserNick, "is_public_folder" => true, 'can_set_share' => 0); } else { $permission = MConst::SUPREME_PERMISSION; return array("permission" => $permission, "share_user_nick" => $shareUserNick, "is_public_folder" => true, 'can_set_share' => 0); } } }