/** * * 更新文件 */ public function updateRefCountByIds($ids, $add = false) { $sql_str = 'UPDATE ' . FileVersion::model()->tableName() . ' SET ref_count=ref_count - 1 WHERE id = ?'; if ($add) { $sql_str = 'UPDATE ' . FileVersion::model()->tableName() . ' SET ref_count=ref_count + 1 WHERE id = ?'; } foreach ($ids as $id) { // 文件版本引用次数减 1 $sql = Yii::app()->db->createCommand($sql_str); $sql->execute(array($id)); } }
/** *获得文档类所有的文档 * @return array */ public function getDocBuildList() { $mimeTypeList = array("application/mspowerpoint", "application/msword", "application/msexcel", "application/pdf"); $data = array(); foreach ($mimeTypeList as $mimeType) { $criteria = new CDbCriteria(); $criteria->condition = "mime_type=:mime_type and doc_convert_status=2"; $criteria->params = array("mime_type" => $mimeType); $list = FileVersion::model()->findAll($criteria); if (count($list) > 0) { $list = $this->db2list($list); foreach ($list as $item) { array_push($data, $item); } } } return $data; }
/** * 根据路径,回复假删除文件 * @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 revertFileAll() { $models = $this->findAllByAttributes(array('is_deleted' => 1)); $device_id = Yii::app()->session["deviceId"]; foreach ($models as $model) { $shareFilter = MSharesFilter::init(); $shareFilter->handlerCheckByFile($model['user_id'], $model); $user_id = $model['user_id']; $path = $model['file_path']; $context = $path; $event_uuid = MiniUtil::getEventRandomString(46); $action = 0; // 修改文件 if ($model['file_type'] == 0) { // // 如果是文件,需要创建版本 // $user = Yii::app()->session['user']; $device = UserDevice::model()->findByUserIdAndType($user['id'], CConst::DEVICE_WEB); $deviceName = $device["user_device_name"]; $this->_saveFileMeta($path, $model['version_id'], $user['id'], $user['name'], CConst::WEB_RESTORE, $deviceName, $model['file_size']); $action = CConst::CREATE_FILE; $version = FileVersion::model()->findByPk($model["version_id"]); $context = array("hash" => $version['file_signature'], "rev" => (int) $model["version_id"], "bytes" => (int) $model["file_size"]); $context = serialize($context); } $model['event_uuid'] = $event_uuid; $model["is_deleted"] = 0; $model->save(); MiniEvent::getInstance()->createEvent($user_id, $device_id, $action, $path, $context, $event_uuid, $shareFilter->type); } return true; }
/** * 处理meta信息 * @param $metas */ private function handleMeta($metas) { $list = array(); if (empty($metas)) { return; } $deleted = 0; $last = $metas[count($metas) - 1]; // // 如果最后一次操作是删除 则去掉 // if ($last['type'] == MConst::DELETE) { $deleted = $last['version_id']; } foreach ($metas as $index => $meta) { // 防止出现只有一条记录的情况,产生场景重命名 if ($deleted == $meta['version_id'] && count($metas) > 1) { $deleted = 0; continue; } switch ($meta['type']) { case MConst::CREATE_FILE: case MConst::MODIFY_FILE: case CConst::WEB_RESTORE: array_push($list, $meta['version_id']); break; default: break; } } if (empty($list)) { return; } FileVersion::model()->updateRefCountByIds($list); }
/** * 获得要删除的记录 * @param $limit * @return array */ public function getCleanFiles($limit = 100) { $criteria = new CDbCriteria(); $criteria->condition = "ref_count<=0"; $criteria->limit = $limit; $criteria->offset = 0; $list = FileVersion::model()->findAll($criteria); if (count($list) > 0) { return $this->db2list($list); } return NULL; }
/** * 通过signature获得记录 * @param string $signature * @return array */ private function get4DbBySignature($signature) { $item = FileVersion::model()->find("file_signature=:signature", array("signature" => $signature)); return $this->db2Item($item); }
/** * 冗余备份成功 * @param $signature */ public function replicateSuccess($signature) { $item = FileVersion::model()->find("file_signature=:file_signature", array("file_signature" => $signature)); if (isset($item)) { $item->replicate_status = 2; $item->save(); } }
/** * 为前30个文件生成冗余备份任务 * 并把任务推送到备份服务器 * @param int $limit * @return int */ public function replicateFile($limit = 30) { $miniHost = PluginMiniStoreOption::getInstance()->getMiniyunHost(); $criteria = new CDbCriteria(); $criteria->condition = "replicate_status=0"; $criteria->limit = $limit; $criteria->offset = 0; $versions = FileVersion::model()->findAll($criteria); $fileCount = 0; foreach ($versions as $version) { //设置replicate_status=1 $signature = $version->file_signature; $version->replicate_status = 1; $version->save(); //为其它节点生成冗余备份记录 $nodes = PluginMiniStoreNode::getInstance()->getReplicateNodes($signature); foreach ($nodes as $node) { $task = ReplicateTask::model()->find("file_signature=:file_signature and node_id=:node_id", array("file_signature" => $signature, "node_id" => $node["id"])); if (!isset($task)) { $task = new ReplicateTask(); $task->file_signature = $signature; $task->node_id = $node["id"]; $task->status = 0; $task->save(); $this->pushReplicateTask($miniHost, $task); $fileCount++; } } } return $fileCount; }
/** * * 合并历史版本 * @param array $metas * @param int $limit * @return array * @since 1.0.7 */ public static function mergeFileMetaVersion($metas, $limit = 0) { $list = array(); if (empty($metas)) { return $metas; } $offset = $limit; $limit = $limit == 0 ? count($metas) : $limit; foreach ($metas as $index => $meta) { if ($index > $limit - 1) { break; } switch ($meta['type']) { case MConst::CREATE_FILE: case MConst::MODIFY_FILE: case CConst::WEB_RESTORE: array_push($list, $meta['version_id']); break; default: break; } } // // 去掉前$offset个meta // $metas = array_slice($metas, $offset); if (empty($list)) { return $metas; } FileVersion::model()->updateRefCountByIds($list); return $metas; }
/** 创建meta信息 */ public function handleFileMeta($filePath, $versionId, $userId, $userNick, $action, $deviceName, $fileSize) { // // 查询之前的版本 // $handler = new FileMeta(); $meta = $handler->getFileMeta($filePath, "version"); if (!$meta) { $meta = new FileMeta(); $meta["file_path"] = $filePath; $meta["meta_key"] = "version"; $meta["meta_value"] = serialize(array()); } $value = CUtils::getFileVersions($deviceName, $fileSize, $versionId, $action, $userId, $userNick, $meta["meta_value"]); $meta["meta_value"] = $value; if ($action == MConst::CREATE_FILE || $action == MConst::MODIFY_FILE || $action == CConst::WEB_RESTORE) { FileVersion::model()->updateRefCountByIds(array($versionId), TRUE); } return $meta->save(); }
/** * * 复制文件 * @param string $fromPath * @param string $toPath */ private function handleCopyFile($fromPath, $toPath) { $createFolder = new CreateFolder(); $createFolder->_deviceId = $this->_deviceId; $createFolder->_userId = $this->_userId; $pathInfo = CUtils::pathinfo_utf($toPath); $parentId = $createFolder->handleCreateByPath($pathInfo["dirname"]); // 重命名 $name = $this->handleRename($parentId, $pathInfo["basename"]); $toPath = $pathInfo["dirname"] . "/" . $name; $version = FileVersion::model()->findByPk($this->from["version_id"]); $hash = $version["file_signature"]; // // 保存事件 // $context = array("hash" => $hash, "rev" => (int) $this->from["version_id"], "bytes" => (int) $this->from["file_size"]); // // 如果是存在同名的已经删除的记录,则还原之 // $target = UserFile::model()->findByAttributes(array("user_id" => $this->_userId, "file_path" => $this->toPath, "is_deleted" => 1)); if (!$target) { $target = new UserFile(); $target["user_id"] = $this->_userId; $target["parent_file_id"] = $parentId; $target["file_create_time"] = time(); } $target["file_type"] = 0; $target["is_deleted"] = 0; $target["version_id"] = $this->from["version_id"]; $target["file_size"] = $this->from["file_size"]; $target["file_path"] = $toPath; $target["file_name"] = $name; $target["file_update_time"] = time(); $target["event_uuid"] = MiniUtil::getEventRandomString(46); $target->save(); // 创建meta $this->handleFileMeta($toPath, $this->from["version_id"], $this->_userId, $this->_userNick, CConst::CREATE_FILE, $this->_deviceName, $this->from["file_size"]); // 创建事件 MiniEvent::getInstance()->createEvent($this->_userId, $this->_deviceId, CConst::CREATE_FILE, $toPath, serialize($context), $target["event_uuid"]); $this->to_share_filter->handlerAction(3, $this->_deviceId, $toPath, $context); }