示例#1
0
 /**
  * 静态方法, 单例统一访问入口
  * @return object  返回对象的唯一实例
  */
 public static function getInstance()
 {
     if (is_null(self::$_instance) || !isset(self::$_instance)) {
         self::$_instance = new self();
     }
     return self::$_instance;
 }
示例#2
0
 /**
  * 获取当前文件版本列表
  * @param $path
  * @return mixed
  */
 public function getList($path)
 {
     $item = explode("/", $path);
     $permissionArr = UserPermissionBiz::getInstance()->getPermission($path, $this->user['id']);
     if ($item[1] !== $this->user['id'] && count($permissionArr) == 0) {
         throw new MFilesException(Yii::t('api', MConst::PARAMS_ERROR), MConst::HTTP_CODE_400);
     }
     $file = MiniFile::getInstance()->getByPath($path);
     $version_id = $file['version_id'];
     $fileMeta = MiniFileMeta::getInstance()->getFileMeta($path, "version");
     $fileVersion = MiniVersion::getInstance()->getVersion($version_id);
     $currentSignature = $fileVersion['file_signature'];
     $historyArr = array_reverse(unserialize($fileMeta['meta_value']));
     // 去掉delete事件版本
     $histories = array();
     foreach ($historyArr as $item) {
         $history = array();
         if ($item['type'] == CConst::DELETE) {
             continue;
         }
         $history['type'] = $item['type'];
         $history['file_size'] = $item['file_size'];
         $history['user_nick'] = $item['user_nick'];
         $history['device_name'] = $item['device_name'];
         $history['datetime'] = MiniUtil::formatTime(strtotime($item['datetime']));
         $fileVersion = MiniVersion::getInstance()->getVersion($item['version_id']);
         $history['signature'] = $fileVersion['file_signature'];
         array_push($histories, $history);
     }
     $data['histories'] = $histories;
     $data['current_signature'] = $currentSignature;
     return $data;
 }
 /**
  * 为文件增加冗余备份节点
  * @param $signature
  * @param $nodeId
  */
 public function addReplicateNode($signature, $nodeId)
 {
     $version = MiniVersion::getInstance()->getBySignature($signature);
     if (!empty($version)) {
         $meta = FileVersionMeta::model()->find("version_id=:version_id and meta_key='store_id'", array("version_id" => $version["id"]));
         if (isset($meta)) {
             $value = $meta->meta_value;
             $isExist = false;
             $ids = explode(",", $value);
             foreach ($ids as $id) {
                 if ($id === $nodeId) {
                     $isExist = true;
                 }
             }
             if (!$isExist) {
                 $value .= "," . $nodeId;
                 $meta->meta_value = $value;
                 $meta->save();
                 $ids = explode(",", $value);
                 if (count($ids) >= 3) {
                     //整个文件冗余备份成功
                     PluginMiniStoreVersion::getInstance()->replicateSuccess($signature);
                 }
             }
         } else {
             $meta = new FileVersionMeta();
             $meta->version_id = $version["id"];
             $meta->meta_value = $nodeId;
             $meta->save();
         }
     }
 }
示例#4
0
 /**
  *
  * 检查文件data和 meta是否存在
  */
 protected function handleCheckFileVersion($hash)
 {
     $version = MiniVersion::getInstance()->getBySignature($hash);
     if ($version === NULL) {
         $version = MiniVersion::getInstance()->create($hash, $this->size, $this->type);
     }
     $this->version_id = $version["id"];
     $this->file_hash = $version["file_signature"];
     return true;
 }
示例#5
0
 /**
  * 迷你存储报俊
  * @param string $path 用户文件的存储路径
  * @param string $signature 文件sha1
  * @param int $size 文件大小,单位字节
  * @param int $nodeId 迷你存储节点值 
  */
 public function report($path, $signature, $size, $nodeId)
 {
     //防止重复文件通过网页上传,生成多条记录
     $version = MiniVersion::getInstance()->getBySignature($signature);
     if (empty($version)) {
         //创建version/versionMeta数据
         $pathParts = pathinfo($path);
         $type = MiniUtil::getMimeType($pathParts["basename"]);
         $version = MiniVersion::getInstance()->create($signature, $size, $type);
         MiniVersionMeta::getInstance()->create($version["id"], "store_id", $nodeId);
         //更新迷你存储节点状态,把新上传的文件数+1
         PluginMiniStoreNode::getInstance()->newUploadFile($nodeId);
         //清理垃圾数据
         PluginMiniBreakFile::getInstance()->deleteBySignature($signature);
     }
     //执行文件秒传逻辑
     $filesController = new MFileSecondsController();
     $filesController->invoke();
 }
示例#6
0
 /**
  *给迷你云报告文件转换过程
  * @param int $nodeId 文档转换服务器Id
  * @param string $signature 文件hash值
  * @param string $status 文件状态
  * @return array
  */
 public function report($nodeId, $signature, $status)
 {
     $version = MiniVersion::getInstance()->getBySignature($signature);
     if (!empty($version)) {
         //文件转换成功
         if ($status === "1") {
             //更新迷你存储节点状态,把新上传的文件数+1
             PluginMiniDocNode::getInstance()->newConvertFile($nodeId);
             PluginMiniDocVersion::getInstance()->updateDocConvertStatus($nodeId, $signature, 2);
             //通过回调方式让迷你搜索把文件文本内容编制索引到数据库中
             do_action("pull_text_search", $signature);
         }
         //文件转换失败
         if ($status === "0") {
             PluginMiniDocVersion::getInstance()->updateDocConvertStatus($nodeId, $signature, -1);
         }
     }
     return array("success" => true);
 }
 /**
  * 全文检索
  * @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;
 }
示例#8
0
 /**
  * 控制器执行主逻辑函数, 处理移动文件或者文件夹
  *
  * @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);
 }
 /**
  * 推送任务到文件冗余备份服务器
  * @param $miniHost
  * @param $task
  */
 private function pushReplicateTask($miniHost, $task)
 {
     $node = PluginMiniStoreNode::getInstance()->getNodeById($task->node_id);
     //如目标服务器不可用,则不用发送请求
     if ($node["status"] == 1) {
         $signature = $task->file_signature;
         $version = MiniVersion::getInstance()->getBySignature($signature);
         $downloadUrl = $miniHost . "api.php?route=module/miniStore/download&signature=" . $signature;
         $callbackUrl = $miniHost . "api.php?route=module/miniStore/replicateReport&signature=" . $signature . "&node_id=" . $node["id"];
         //向迷你存储发送冗余备份请求
         $data = array('route' => "file/replicate", 'size' => $version["file_size"], 'signature' => $signature, 'download_url' => $downloadUrl, "callback_url" => $callbackUrl);
         $http = new HttpClient();
         $http->post($node["host"] . "/api.php", $data);
         $content = $http->get_body();
         if (!empty($content)) {
             $status = @json_decode($content)->{"status"};
             if ($status == 1) {
                 //目标服务器接受请求后,更改任务状态
                 $task->status = 1;
                 $task->save();
             }
         }
     }
 }
示例#10
0
 /**
  * 删除回收站所有记录, 但保留源数据
  * @since 1.0.0
  * by Kindac
  */
 private function handleSuperClean()
 {
     $this->fromIds = $this->getTrashList();
     if (empty($this->fromIds)) {
         $this->handleResult(TRUE, 0, Yii::t('api_message', 'action_success'));
         Yii::app()->end();
     }
     $files = UserFile::model()->getFilesByIds($this->fromIds, 1);
     //         $files = UserFile::model()->findAllByAttributes(array("user_id" => $this->_userId, "is_deleted" => 1));
     $ids = array();
     foreach ($files as $file) {
         array_push($ids, $file["id"]);
         //
         // 将文件的版本引用次数减1
         //
         if ($file['file_type'] == 0) {
             MiniVersion::getInstance()->updateRefCount($file['version_id'], FALSE);
         }
     }
     $ids = join(",", $ids);
     // 我的最爱和分享都删除
     $value = 0;
     if (!empty($ids)) {
         FileStar::model()->deleteAll('id in (' . $ids . ')');
         MiniLink::getInstance()->unlink($ids);
         $value = UserFile::model()->updateAll(array("is_deleted" => -1), "id in ({$ids})");
     }
     if ($value >= 0) {
         $this->handleResult(TRUE, 0, Yii::t('api_message', 'action_success'));
     }
 }
示例#11
0
 /**
  * 处理非根目录下文件查询
  * @param $path
  * @param $includeDeleted
  * @return array
  * @throws MFileopsException
  */
 private function handleNotRootPath($path, $includeDeleted)
 {
     // 查询其是否存在信息
     $currentFile = MiniFile::getInstance()->getByPath($path);
     if (empty($currentFile)) {
         throw new MFileopsException(Yii::t('api', 'not existed'), MConst::HTTP_CODE_404);
     }
     //查询文件类型
     $version = MiniVersion::getInstance()->getVersion($currentFile["version_id"]);
     $mimeType = null;
     if ($version != NULL) {
         $currentFile["signature"] = $version["file_signature"];
         $mimeType = $version["mime_type"];
     }
     $response = array();
     $shareKeyPrivilege = MiniFile::getInstance()->getFileExtendProperty($currentFile);
     $response['share_key'] = $shareKeyPrivilege['share_key'];
     $response = $this->assembleResponse($response, $currentFile, $mimeType);
     // 组装子文件数据
     $childrenFiles = MiniFile::getInstance()->getChildrenByFileID($parentFileId = $currentFile['id'], $includeDeleted);
     $contents = array();
     if (!empty($childrenFiles)) {
         foreach ($childrenFiles as $childrenFile) {
             $childrenFileMeta = MiniFileMeta::getInstance()->getFileMeta($childrenFile['file_path'], 'create_id');
             if (!empty($childrenFileMeta)) {
                 $filePathArr = explode('/', $childrenFile['file_path']);
                 $fileOwnerId = $filePathArr[1];
                 $childrenFileCreateId = $childrenFileMeta['meta_value'];
                 $currentUser = Yii::app()->session["user"];
                 if ((int) $fileOwnerId !== (int) $currentUser['user_id']) {
                     //当前目录不为当前用户所有(共享目录/公共目录)
                     if ($response['share']['permission'] === '000000000') {
                         continue;
                     }
                     $readPrivilege = substr($response['share']['permission'], 0, 1);
                     if ($readPrivilege === '0') {
                         //如果父目录没有只读权限
                         if ($childrenFileCreateId != $currentUser['user_id']) {
                             //当没有只读权限时,过滤(用户只能看见共享目录中自己的文件)
                             continue;
                         }
                     }
                 }
             }
             $content = array();
             $version = MiniVersion::getInstance()->getVersion($childrenFile["version_id"]);
             $mimeType = null;
             if ($version != NULL) {
                 $mimeType = $version["mime_type"];
                 $childrenFile["signature"] = $version["file_signature"];
             }
             $content = $this->assembleResponse($content, $childrenFile, $mimeType);
             if (!empty($content) && $childrenFile['is_deleted'] == 0) {
                 array_push($contents, $content);
             }
         }
     }
     $response['contents'] = $contents;
     return $response;
 }
示例#12
0
 /**
  * 将文件拷贝到临时目录
  * @param $zip
  * @param $file
  * @param $storePath
  */
 private function addToFile($zip, $file, $storePath)
 {
     $fileVersion = MiniVersion::getInstance()->getVersion($file["version_id"]);
     $content = MiniFile::getInstance()->getFileContentBySignature($fileVersion["file_signature"]);
     $zip->addFromString($storePath, $content);
 }
示例#13
0
 /**
  * 获取使用空间百分比
  * @return number
  */
 public function getUsedPercent()
 {
     $remain = $this->getDiskFreeSpace();
     //空闲空间
     $total = $this->getDiskTotalSpace();
     //总空间
     $usedSpace = MiniVersion::getInstance()->getTotalSize();
     $percent = 0;
     if ($total > 0) {
         $percent = (double) $usedSpace / $total;
     }
     $retval = round($percent, 3) * 100;
     return $retval;
 }
示例#14
0
 /**
  * 控制器执行主逻辑函数
  *
  * @return mixed $value 返回最终需要执行完的结果
  */
 public function invoke($uri = null)
 {
     // 调用父类初始化函数,注册自定义的异常和错误处理逻辑
     parent::init();
     $params = $_REQUEST;
     // 检查参数
     if (isset($params) === false || $params == null) {
         throw new Exception(Yii::t('api', 'Invalid parameters'));
     }
     // 文件大小格式化参数
     $locale = "bytes";
     if (isset($params["locale"])) {
         $locale = $params["locale"];
     }
     $url = $uri;
     $url_manager = new MUrlManager();
     $this->_root = $url_manager->parseRootFromUrl($uri);
     $path = $url_manager->parsePathFromUrl($uri);
     $path = MUtils::convertStandardPath($path);
     $originalPath = $path;
     // 检查共享
     $share_filter = MSharesFilter::init();
     //        $share_filter
     //
     // 获取用户数据,如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"];
     $rev = $params["rev"];
     $rev = intval($rev);
     $path = "/{$this->_user_id}{$path}";
     //
     // 该文件是否具有此版本
     //
     $file_meta = MFileMetas::queryFileMeta($path, MConst::VERSION);
     if ($file_meta == false || empty($file_meta)) {
         throw new MFileopsException(Yii::t('api', '    Unable to find the revision at that path'), MConst::HTTP_CODE_404);
     }
     if (MUtils::isExistReversion($rev, $file_meta[0]["meta_value"]) == false) {
         throw new MFileopsException(Yii::t('api', '    Unable to find the revision at that path'), MConst::HTTP_CODE_404);
     }
     //
     // 查询版本信息
     //
     $version = MiniVersion::getInstance()->getVersion($rev);
     if ($version == null) {
         throw new MFileopsException(Yii::t('api', '    Unable to find the revision at that path'), MConst::HTTP_CODE_404);
     }
     $size = $version["file_size"];
     $file_hash = $version["file_signature"];
     //
     // 查询文件信息
     //
     $query_db_file = MFiles::queryFilesByPath($path);
     if ($query_db_file === false || empty($query_db_file)) {
         throw new MFileopsException(Yii::t('api', 'not existed'), MConst::HTTP_CODE_404);
     }
     if ($query_db_file[0]["file_type"] == MConst::OBJECT_TYPE_DIRECTORY) {
         // 文件夹不需要版本
         throw new MFileopsException(Yii::t('api', 'folder not existed version'), MConst::HTTP_CODE_403);
     }
     if ($rev !== $query_db_file[0]["version_id"]) {
         //
         // 更新文件版本
         //
         $updates = array();
         $updates["version_id"] = $rev;
         $updates["file_update_time"] = time();
         $updates["file_size"] = $size;
         $updates["event_uuid"] = MiniUtil::getEventRandomString(MConst::LEN_EVENT_UUID);
         $ret = MFiles::updateFileDetailById($query_db_file[0]["id"], $updates);
         if ($ret === false) {
             throw new MFileopsException(Yii::t('api', 'Internal Server Error'), MConst::HTTP_CODE_500);
         }
         $file_detail = new MFiles();
         $file_detail->file_name = $query_db_file[0]["file_name"];
         //
         // 保存事件
         //
         $context = array("hash" => $file_hash, "rev" => (int) $rev, "bytes" => (int) $size);
         //
         // 增加修改事件
         //
         $ret = MiniEvent::getInstance()->createEvent($this->_user_id, $user_device_id, MConst::MODIFY_FILE, $path, serialize($context), $updates["event_uuid"]);
         if ($ret === false) {
             throw new MFileopsException(Yii::t('api', 'Internal Server Error'), MConst::HTTP_CODE_500);
         }
         $this->handleFileMeta($path, $rev, $user_nick, $this->_user_device_name, $query_db_file[0]["file_size"]);
     }
     // TODO
     $mime_type = $version["mime_type"];
     $response = array();
     $response["size"] = MUtils::getSizeByLocale($locale, $size);
     $response["is_deleted"] = true;
     $response["bytes"] = intval($size);
     $response["thumb_exists"] = MUtils::isExistThumbnail($mime_type, $size);
     $response["path"] = $originalPath;
     $response["root"] = $this->_root;
     $response["is_dir"] = false;
     $response["mime_type"] = $mime_type;
     $response["modified"] = MUtils::formatIntTime(time());
     $response["rev"] = strval($rev);
     $response["revision"] = $rev;
     echo json_encode($response);
 }
示例#15
0
 /**
  * 获取文件以前版本的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);
 }
示例#16
0
 /**
  * 系统空间是否还有剩余
  */
 public static function hasOverSysSpace()
 {
     $value = MiniOption::getInstance()->getOptionValue("site_sys_space");
     if (isset($value) && $value > 0) {
         $usedSpace = MiniVersion::getInstance()->getTotalSize();
         $overSpace = $value * 1024 * 1024 - $usedSpace;
         if ($overSpace < 0) {
             return false;
         }
     }
     return true;
 }
示例#17
0
 /**
  * 控制器执行主逻辑函数
  */
 public function invoke($uri = null)
 {
     // 调用父类初始化函数,注册自定义的异常和错误处理逻辑
     parent::init();
     $params = $_REQUEST;
     // 检查参数
     if (isset($params) === false || $params == null) {
         throw new MAuthorizationException(Yii::t('api', 'Invalid parameters'));
     }
     $url_manager = new MUrlManager();
     $path = MUtils::convertStandardPath($url_manager->parsePathFromUrl($uri));
     $root = $url_manager->parseRootFromUrl($uri);
     // 去掉问号后面参数
     if ($pos = strpos($this->_root, '?')) {
         $this->_root = substr($this->_root, 0, $pos);
     }
     if ($pos = strpos($path, '?')) {
         $path = substr($path, 0, $pos);
     }
     // 获取用户数据,如user_id
     $user = MUserManager::getInstance()->getCurrentUser();
     $this->_user_id = $user["user_id"];
     $query = "";
     if (isset($params["query"])) {
         $query = $params["query"];
     }
     if ($query === "") {
         throw new MFileopsException(Yii::t('api', 'bad request 15'), MConst::HTTP_CODE_400);
     }
     $file_limit = 10000;
     if (isset($params["file_limit"])) {
         $file_limit = $params["file_limit"];
     }
     $include_deleted = false;
     // 处理删除的同样也需要返回
     //        if(isset($params["include_deleted"])) {
     //            $include_deleted = $params["include_deleted"];
     //            if(is_string($include_deleted) === true) {
     //                if(strtolower($include_deleted) === "false") {
     //                    $include_deleted = false;
     //                } elseif(strtolower($include_deleted) === "true") {
     //                    $include_deleted = true;
     //                }
     //            }
     //        }
     $this->_locale = "bytes";
     if (isset($params["locale"])) {
         $this->_locale = $params["locale"];
     }
     $callback = null;
     if (isset($params["callback"])) {
         $callback = $params["callback"];
     }
     if (empty($path) || "/" . $this->_user_id == $path) {
         $path = '/' . $this->_user_id;
         $userFiles = array();
         $query_db_file = MFiles::searchFilesByPath($path, $query, $this->_user_id, $include_deleted);
         foreach ($query_db_file as $db_file) {
             // if(($db_file['parent_file_id'] == 0) and ($db_file['file_type'] != 4) and ($db_file['file_type'] != 2)){
             $userFiles[] = $db_file;
             // }
         }
         $retval = $this->handleSearchRoot($path, $query);
         $files = array_merge($retval, $userFiles);
     } else {
         //            $files = array();
         $includeDeleted = false;
         $currentFile = MiniFile::getInstance()->getByPath($path);
         //            if (empty($currentFile)){
         //                throw new MFileopsException(Yii::t('api','not existed'),MConst::HTTP_CODE_404);
         //            }
         //            //查询文件类型
         //            $version = MiniVersion::getInstance()->getVersion($currentFile["version_id"]);
         //            $mimeType = null;
         //            if ($version != NULL)
         //            {
         //                $currentFile["signature"] = $version["file_signature"];
         //                $mimeType = $version["mime_type"];
         //            }
         //            // 组装子文件数据
         $childrenFiles = MiniFile::getInstance()->getChildrenByFileID($parentFileId = $currentFile['id'], $includeDeleted);
         $currentFileParts = explode('/', $path);
         $currentFileUserId = $currentFileParts[1];
         $files = $childrenFiles;
         //            $query = str_replace("%", "\\%", $query);
         //            $sql = ' file_name like "%' . $query . '%"';
         //            $sql = '';
         //            $files = array();
         //            foreach($childrenFiles as $childrenFile){
         //                $condition = $sql . 'file_path="' . $childrenFile['file_path'] . '" ';
         //                $file = MFiles::findAll($condition);
         //                $files = array_merge($files,$file);
         //            }
         //            $contents = array();
         //            if(!empty($childrenFiles)){
         //                foreach($childrenFiles as $childrenFile){
         //                    $content = array();
         //                    $version = MiniVersion::getInstance()->getVersion($childrenFile["version_id"]);
         //                    $mimeType = null;
         //                    if ($version != NULL){
         //                        $mimeType = $version["mime_type"];
         //                        $childrenFile["signature"] = $version["file_signature"];
         //                    }
         //                    $content = $this->assembleResponse($content, $childrenFile, $mimeType);
         //                    if(!empty($content) && $childrenFile['is_deleted'] == 0){
         //                        array_push($contents, $content);
         //                    }
         //                }
         //            }
         //            $response['contents'] = $contents;
     }
     $result = array();
     $query = str_replace("%", "\\%", $query);
     $sql = ' file_name like "%' . $query . '%"';
     foreach ($files as $file) {
         $condition = $sql . 'and file_path like"' . $file['file_path'] . '%" ';
         $file = MFiles::findAll($condition);
         if (empty($file)) {
             continue;
         }
         $result = array_merge($result, $file);
     }
     //        $path        = "/{$this->_user_id}{$path}";
     //        $path        = MUtils::convertStandardPath($path) . "/";
     // 查询其 信息
     //        $operator = $this->_user_id;
     //
     //        $sharefilter = MSharesFilter::init();
     //        $sharefilter->handlerCheck($this->_user_id, CUtils::removeUserFromPath($path));
     //        if($sharefilter->is_shared) {
     //            $operator = $sharefilter->master;
     //            $qpath = '/' . $sharefilter->master . $sharefilter->_path;
     //            $query_db_file = MFiles::searchFilesByPath($qpath, $query, $sharefilter->master, $include_deleted);
     //
     //            // 判断搜索出来的文件是否有权限访问
     //            foreach($query_db_file as $index => $file) {
     //                // 列表权限,如果没有列表权限,则不进行显示
     //                try {
     //                    $sharefilter->hasPermissionExecute($file['file_path'], MPrivilege::RESOURCE_READ);
     //                }catch(Exception $e) {
     //                    unset($query_db_file[$index]);
     //                    continue;
     //                }
     //            }
     //        } else {
     //            $query_db_file = MFiles::searchFilesByPath($path, $query, $this->_user_id, $include_deleted);
     //        }
     //
     // 查询根目录
     //
     //        $retval = $this->handleSearchRoot($path, $query);
     //        $query_db_file = array_merge($query_db_file, $retval);
     // if (count($query_db_file) > $file_limit)
     // {
     // throw new MFileopsException(
     // Yii::t('api','Too many file entries to return'),
     // MConst::HTTP_CODE_406);
     // }
     //        $keys = array();
     $response = array();
     $filePaths = array();
     if (!empty($result)) {
         foreach ($result as $file) {
             if (in_array($file['file_path'], $filePaths)) {
                 continue;
             }
             array_push($filePaths, $file['file_path']);
             $item = array();
             $version = MiniVersion::getInstance()->getVersion($file["version_id"]);
             $mimeType = null;
             $signature = null;
             if ($version != NULL) {
                 $mimeType = $version["mime_type"];
                 $signature = $version["file_signature"];
                 $file["signature"] = $signature;
             }
             $item = $this->assembleResponse($item, $file, $mimeType);
             if (!empty($item)) {
                 array_push($response, $item);
             }
         }
     }
     //        foreach($query_db_file as $key => $db_file) {
     //            if ($key >= $file_limit)
     //                break;
     //            $file_array = array();
     //            $mime_type = null;
     //            if($db_file["file_type"] == MConst::OBJECT_TYPE_FILE) {
     //                $version = MiniVersion::getInstance()->getVersion($db_file["version_id"]);
     //                if($version) {
     //                    $mime_type = $version["mime_type"];
     //                }
     //            }
     //            $file_array = $this->assembleResponse($file_array, $db_file, $mime_type);
     //            #这里对数据进行了二次过滤,如果路径是一致的,则过滤掉
     //            #TODO 这里的冗余数据初步分析是权限导致的,二次重构要去掉这个代码
     //            $path = $file_array["path"];
     //            if(!array_key_exists($path, $keys)){
     //                $keys[$path] = $file_array;
     //                array_push($response, $file_array);
     //            }
     //        }
     echo json_encode($response);
 }
示例#18
0
 /**
  * create file
  * @param $userId
  * @param $file
  * @param $deviceId
  * @return array
  */
 public function createFile($userId, $file, $deviceId)
 {
     $event = new Event();
     $event->user_id = $userId;
     $event->user_device_id = $deviceId;
     if ((int) $file["file_type"] === MiniFile::$TYPE_FILE) {
         $event->action = MiniEvent::$CREATE_FILE;
     } else {
         //TODO include public folder/share folder/
         $event->action = MiniEvent::$CREATE_FOLDER;
     }
     $event->file_path = $file["file_path"];
     $context = $file["file_path"];
     if ((int) $file["file_type"] === MiniFile::$TYPE_FILE) {
         //get version
         $version = MiniVersion::getInstance()->getVersion($file["version_id"]);
         $versionInfo = array("hash" => $version["file_signature"], "rev" => (int) $version["id"], "bytes" => (int) $file["file_size"], "update_time" => (int) $file["file_update_time"], "create_time" => (int) $file["file_create_time"]);
         $context = serialize($versionInfo);
     }
     $event->context = $context;
     $event->event_uuid = MiniUtil::getEventRandomString(MConst::LEN_EVENT_UUID);
     $event->type = MiniEvent::$EVENT_COMMON_TYPE;
     $event->save();
     //update file event_uuid
     MiniFile::getInstance()->update($file["id"], array("event_uuid" => $event->event_uuid));
 }
示例#19
0
 /**
  * 获得有效文件下载服务器节点
  * 找到min(downloaded_file_count) and status=1的记录分配
  * @param string $signature 文件内容hash
  * @return array
  */
 private function getDownloadNode($signature)
 {
     $version = MiniVersion::getInstance()->getBySignature($signature);
     if (!empty($version)) {
         $metaKey = "store_id";
         $meta = MiniVersionMeta::getInstance()->getMeta($version["id"], $metaKey);
         if (!empty($meta)) {
             $value = $meta["meta_value"];
             $ids = explode(",", $value);
             $nodes = $this->getNodeList();
             $validNodes = array();
             foreach ($nodes as $node) {
                 //先找到当前文件存储的节点
                 $isValidNode = false;
                 foreach ($ids as $validNodeId) {
                     if ($validNodeId == $node["id"]) {
                         $isValidNode = true;
                     }
                 }
                 if (!$isValidNode) {
                     continue;
                 }
                 //然后判断节点是否有效,并在有效的节点找到下载次数最小的节点
                 if ($node["status"] == 1) {
                     array_push($validNodes, $node);
                 }
             }
             //选出downloaded_file_count最小的个节点
             $validNodes = MiniUtil::arraySort($validNodes, "downloaded_file_count", SORT_ASC);
             $nodes = MiniUtil::getFistArray($validNodes, 1);
             if (count($nodes) > 0) {
                 $node = $nodes[0];
                 $urlInfo = parse_url($node["host"]);
                 if ($urlInfo["host"] == "127.0.0.1") {
                     //说明迷你存储在本机,直接把127.0.0.1替换为迷你存储端口
                     $defaultHost = MiniHttp::getMiniHost();
                     $miniHostInfo = parse_url($defaultHost);
                     $node['host'] = $miniHostInfo["scheme"] . "://" . $miniHostInfo["host"] . ":" . $urlInfo["port"] . $miniHostInfo["path"];
                 }
                 return $node;
             }
             return null;
         }
     }
     return null;
 }
示例#20
0
 /**
  * 获取系统节约空间
  */
 public function getSaveSpace()
 {
     $saveSpace = MiniFile::getInstance()->getTotalSize() - MiniVersion::getInstance()->getTotalSize();
     return $saveSpace;
 }
示例#21
0
 /**
  * 
  * 更新文件版本引用次数
  * @since 0.9.6
  * @param array $files
  */
 private function updateVerRef($files)
 {
     foreach ($files as $file) {
         if ($file->file_type != 0) {
             continue;
         }
         MiniVersion::getInstance()->updateRefCount($file->version_id);
     }
 }
 /**
  *
  * 检查文件data和 meta是否存在
  * @param string $hash      文件sha1
  * @param string $fileName  文件名
  * @return bool|void
  */
 protected function handleCheckFileVersion($hash, $fileName)
 {
     $version = MiniVersion::getInstance()->getBySignature($hash);
     if (!$this->isNewVersion) {
         //data源处理对象
         if ($version == null) {
             return $this->handleAssign();
         }
         // 检查文件是否存在
         $dataObj = Yii::app()->data;
         $storePath = MiniUtil::getPathBySplitStr($hash);
         if ($dataObj->exists($storePath) == false) {
             return $this->handleAssign();
         }
         $this->version_id = $version['id'];
         $this->size = $version['file_size'];
         return true;
     } else {
         //返回断点文件信息
         $data = array();
         if (empty($version)) {
             $miniStoreInfo = MiniUtil::getPluginMiniStoreData();
             if (empty($miniStoreInfo)) {
                 //普通文件上传
                 $data['success'] = false;
                 $data['url'] = MiniHttp::getMiniHost() . "api.php";
                 $storePath = MiniUtil::getPathBySplitStr($hash);
                 $filePath = BASE . "upload_block/cache/" . $storePath;
                 if (file_exists($filePath)) {
                     $data['offset'] = filesize($filePath);
                     //如文件大小相同而且Hash值相同,说明流数据文件已经存在,直接生成元数据即可
                     $size = MiniHttp::getParam("size", "");
                     if ($data['offset'] == $size) {
                         //生成version记录,为使用老逻辑代码,这里处理得很羞涩
                         //理想的逻辑是在这里直接返回相关结果
                         $mimeType = MiniUtil::getMimeType($fileName);
                         $version = MiniVersion::getInstance()->create($hash, $size, $mimeType);
                         $this->version_id = $version['id'];
                         $this->size = $version['file_size'];
                         return true;
                     }
                 } else {
                     $data['offset'] = 0;
                 }
                 echo json_encode($data);
                 exit;
             } else {
                 //迷你存储与第3方存储秒传接口
                 apply_filters("file_sec", array("route" => "module/miniStore/report", "sign" => MiniHttp::getParam("sign", ""), "access_token" => MiniHttp::getParam("access_token", ""), "signature" => $hash, "size" => MiniHttp::getParam("size", ""), "path" => MiniHttp::getParam("path", "")));
             }
         } else {
             //上传文件到其它目录下,支持秒传
             $this->version_id = $version['id'];
             $this->size = $version['file_size'];
             return true;
         }
     }
 }
示例#23
0
 /**
  * 清理全部的缓存,包括多余的file_meta
  * @param $limit
  */
 public function cleanCache($limit)
 {
     //data源处理对象
     $dataObj = Yii::app()->data;
     // 回收站插件: -1保留值 0正常 1删除
     $this->handleCleanFileMeta($limit);
     // 清理ref_count等于0的文件
     $versions = MiniVersion::getInstance()->getCleanFiles(100);
     foreach ($versions as $version) {
         $files = UserFile::model()->findAll('version_id=?', array($version['id']));
         // 如果$file存在此version_id,不删除
         if (!empty($files)) {
             for ($i = 0; $i < count($files); $i++) {
                 MiniVersion::getInstance()->updateRefCount($version["id"]);
             }
             continue;
         }
         // 如果不存在的话,删除流文件,删除该条version记录
         $signature = $version['file_signature'];
         $signaturePath = MiniUtil::getPathBySplitStr($signature);
         // 判断文件是否存在
         if ($dataObj->exists($signaturePath) === false) {
             MiniVersion::getInstance()->deleteById($version["id"]);
             continue;
         }
         // 删除文件
         $dataObj->delete($signaturePath);
         //删除空的文件夹
         $parts = CUtils::getFoldersBySplitStr($signature);
         foreach ($parts as $part) {
             $dataObj->delete($part);
         }
         // 删除version记录
         MiniVersion::getInstance()->deleteById($version["id"]);
     }
     MiniUtil::deleteDir(BASE . 'temp');
 }
示例#24
0
 /**
  * 创建对象
  */
 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);
         }
     }
 }
示例#25
0
 /**
  * 历史版本恢复
  * @param int $deviceId
  * @param string $filePath
  * @param string $signature
  * @return bool
  */
 public function recover($deviceId, $filePath, $signature)
 {
     $version = MiniVersion::getInstance()->getBySignature($signature);
     $file = $this->getModelByPath($filePath);
     if ($version["id"] == $file['version_id']) {
         return true;
     }
     $device = MiniUserDevice::getInstance()->getById($deviceId);
     $userId = $device["user_id"];
     $user = MiniUser::getInstance()->getUser($userId);
     $userNick = $user["nick"];
     // events表 相关操作
     $userDeviceName = $device["user_device_name"];
     $userDeviceId = $device["id"];
     $signature = $version['file_signature'];
     $action = CConst::MODIFY_FILE;
     $file->file_update_time = time();
     $context = array('hash' => $signature, 'rev' => (int) $version["id"], 'bytes' => (int) $version['file_size'], 'update_time' => (int) $file->file_update_time, 'create_time' => (int) $file['file_create_time']);
     $filePath = $file['file_path'];
     $eventUuid = MiniUtil::getEventRandomString(CConst::LEN_EVENT_UUID);
     MiniEvent::getInstance()->createEvent($file['user_id'], $userDeviceId, $action, $filePath, serialize($context), $eventUuid);
     //create event
     // files表相关操作
     $file->version_id = $version["id"];
     $file->event_uuid = $eventUuid;
     $file->file_size = $version['file_size'];
     $file->save();
     // meta表相关操作
     $fileMeta = FileMeta::model()->find('file_path = ?', array($filePath));
     $versions = CUtils::getFileVersions($userDeviceName, $version['file_size'], $version["id"], CConst::WEB_RESTORE, $userId, $userNick, $fileMeta['meta_value']);
     $fileMeta->meta_value = $versions;
     $fileMeta->save();
     //更新版本引用数
     MiniVersion::getInstance()->updateRefCountByIds(array($version["id"]), TRUE);
     return true;
 }
示例#26
0
 /**
  * 创建文件
  * @param array $fileDetail
  * @throws
  * @return array
  */
 private function createFile($fileDetail)
 {
     //
     // 如果创建文件标志为false,则不执行创建
     //
     if ($this->create_file == false) {
         return;
     }
     //
     // 是否有标记为删除的对象,可能存在多个
     //
     $conflictFile = MFiles::queryFilesByPath($this->file_path, TRUE);
     if ($conflictFile != false && empty($conflictFile) == false) {
         foreach ($conflictFile as $file) {
             //
             // 如果非文件类型,删除
             //
             if ($file["file_type"] == MConst::OBJECT_TYPE_FILE) {
                 $fileDetail = MFiles::exchange2Object($file, TRUE);
                 $this->creatFileDeleted($fileDetail);
                 return;
             } else {
                 // 彻底删除之后再进行创建
                 $trash = new Trash();
                 $trash->_userId = $this->user_id;
                 $trash->fromIds = $file['id'];
                 try {
                     $trash->invoke(Trash::DELETE);
                 } catch (Exception $e) {
                     throw new MFileopsException(Yii::t('api', 'Internal Server Error'), MConst::HTTP_CODE_500);
                 }
             }
         }
     }
     $this->spaceFilter($this->size);
     // 过滤器,空间大小计算
     $fileDetail->file_create_time = $this->file_create_time;
     $fileDetail->file_update_time = $this->file_update_time;
     $fileDetail->file_size = $this->size;
     $fileDetail->file_type = MConst::OBJECT_TYPE_FILE;
     $fileDetail->parent_file_id = $this->parent_file_id;
     $fileDetail->version_id = $this->version_id;
     $fileDetail->file_path = $this->path;
     $fileDetail->file_name = $this->file_name;
     $fileDetail->event_uuid = MiniUtil::getEventRandomString(MConst::LEN_EVENT_UUID);
     $fileDetail->mime_type = $this->type;
     //
     // 创建文件时,如果存在老的版本 需要兼容 不能覆盖
     //
     $metaValue = null;
     $fileMeta = MFileMetas::queryFileMeta($fileDetail->file_path, MConst::VERSION);
     if ($fileMeta) {
         $metaValue = $fileMeta[0]['meta_value'];
     }
     //
     // 文件meta属性,版本信息
     //
     $version = MUtils::getFileVersions($this->user_device_name, $fileDetail->file_size, $this->version_id, $this->action, $this->user_id, $this->user_nick, $metaValue);
     //
     // 保存文件元数据
     //
     $retVal = MFiles::CreateFileDetail($fileDetail, $this->user_id, $this->user_nick);
     if ($retVal === false) {
         throw new MFilesException(Yii::t('api', MConst::INTERNAL_SERVER_ERROR), MConst::HTTP_CODE_500);
     }
     //
     // 保存事件
     //
     $this->context = array("hash" => $this->file_hash, "rev" => (int) $this->version_id, "bytes" => (int) $this->size, "update_time" => (int) $this->file_update_time, "create_time" => (int) $this->file_create_time);
     $retVal = MiniEvent::getInstance()->createEvent($this->currentUserId, $this->user_device_id, $this->action, $this->file_path, serialize($this->context), $fileDetail->event_uuid, $this->share_filter->type);
     // 为每个共享用户创建事件
     $this->share_filter->handlerAction($this->action, $this->user_device_id, $this->file_path, $this->context);
     if (isset($fileDetail->event_uuid)) {
         $this->event_uuid = $fileDetail->event_uuid;
     }
     if ($retVal === false) {
         throw new MFilesException(Yii::t('api', MConst::INTERNAL_SERVER_ERROR), MConst::HTTP_CODE_500);
     }
     // 文件版本引用次数更新
     if (MiniVersion::getInstance()->updateRefCount($this->version_id) == false) {
         throw new MFilesException(Yii::t('api', MConst::INTERNAL_SERVER_ERROR), MConst::HTTP_CODE_500);
     }
     if ($fileMeta) {
         $retVal = MFileMetas::updateFileMeta($this->file_path, MConst::VERSION, $version);
     } else {
         $retVal = MFileMetas::createFileMeta($this->file_path, MConst::VERSION, $version);
         $pathArr = explode('/', $this->file_path);
         $user = Yii::app()->session["user"];
         if ((int) $pathArr[1] !== (int) $user['user_id']) {
             //只有当被共享者在共享目录下创建文件时,才会记录create_id
             MFileMetas::createFileMeta($this->file_path, 'create_id', $user['user_id']);
         }
     }
     if ($retVal === false) {
         throw new MFilesException(Yii::t('api', MConst::INTERNAL_SERVER_ERROR), MConst::HTTP_CODE_500);
     }
 }