localRecycleFolder().'/user_'.USER_ID.'/'; if(!$pathParse['type']){// 物理路径 $recyclePath = $recycleLocal; return $this->moveToRecycle($path,$recyclePath,$beforePath); } // io路径 if($pathParse['type'] == KodIO::KOD_IO){ $recyclePath = rtrim($pathParse['pathBase'],'/').'/'.$recycleName; return $this->moveToRecycle($path,$recyclePath,$beforePath); } // 协作分享内容: 某人删除时, 移动到自己的回收站(物理路径及io路径; db路径处理) if($pathParse['type'] == KodIO::KOD_SHARE_ITEM){ $driver = IO::init($path); if($driver->getType() == 'drivershareitem'){ $pathParseIO = KodIO::parse($driver->path); if(!$pathParseIO['type']){// 物理路径 $recyclePath = $recycleLocal; return $this->moveToRecycle($driver->path,$recyclePath,$beforePath); } // io路径 if($pathParseIO['type'] == KodIO::KOD_IO){ $recyclePath = rtrim($pathParse['pathBase'],'/').'/'.$recycleName; return $this->moveToRecycle($driver->path,$recyclePath,$beforePath); } } // 个人或部门文件夹协作分享给其他人; 其他任何人删除后进入自己的回收站; if($driver->getType() == 'dbshareitem' && $toRecycle){ $list = $this->listData();$list[$path] = $beforePath;$this->resetList($list); } } return IO::remove($path,$toRecycle); } /** * 追加物理路径 */ public function appendList(&$data,$pathParse){ if($pathParse['type'] != KodIO::KOD_USER_RECYCLE) return; $list = $this->listData(); $listNew = $list; foreach ($list as $toPath => $fromPath){ $parse = KodIO::parse($toPath); if($parse['driverType'] == 'io') { $info = Model('Storage')->driverInfo($parse['id']); if(!$info) { unset($listNew[$toPath]); continue; } } $ioType = IO::getType($toPath); $allowInfo = $ioType == 'local' || $ioType == 'dbshareitem'; // 仅允许本地存储属性访问; 访问速度优化处理; if(!$allowInfo){ $name = get_path_this($toPath); $info = array( 'path' => rtrim($fromPath,'/').'/'.$name, 'name' => $name, 'type' => preg_match("/.+\.[a-zA-Z0-9]{1,6}$/",$name,$match) ? 'file' : 'folder', 'size' => '-1', ); if($info['type'] == 'folder'){ $data['folderList'][] = $info; }else{ $data['fileList'][] = $info; } continue; } // $pathParse['type'];local;miniIO; info; 网络存储则不获取属性; $info = IO::info($toPath); if(!$info){ unset($listNew[$toPath]); continue; } // 协作分享,删除到回收站的内容; 有权限时数据会重复/去重处理; if($info['sourceID']){ foreach($data['fileList'] as $i=>$item) { if($info['sourceID'] == $item['sourceID']){unset($data['fileList'][$i]);} } foreach($data['folderList'] as $index=>$item) { if($info['sourceID'] == $item['sourceID']){unset($data['folderList'][$i]);} } } $info['path'] = rtrim($fromPath,'/').'/'.$info['name']; if($parse['type'] == KodIO::KOD_SHARE_ITEM){$info['path'] = $toPath;} if($info['type'] == 'folder'){ $data['folderList'][] = $info; }else{ $data['fileList'][] = $info; } } // 有不存在内容则自动清除; if(count($listNew) != count($list)){ $this->resetList($listNew); } $data['folderList'] = array_values($data['folderList']); $data['fileList'] = array_values($data['fileList']); // pr($data);exit; } // 彻底删除; public function remove($sourceArr){ $list = $this->listData(); $listNew = $list; foreach ($list as $toPath => $fromPath){ // 删除所有, 或者当前在待删除列表中则删除该项; $beforePath = rtrim($fromPath,'/').'/'.get_path_this($toPath); if(!$sourceArr || in_array($beforePath,$sourceArr) || in_array(trim($beforePath,'/').'/',$sourceArr) ){ IO::remove($toPath); unset($listNew[$toPath]); } } if(count($listNew) != count($list)){ $this->resetList($listNew); } } // 还原 public function restore($sourceArr){ $list = $this->listData(); $listNew = $list; foreach ($list as $toPath => $fromPath){ // 还原所有, 或者当前在待还原列表中则还原该项; $beforePath = rtrim($fromPath,'/').'/'.get_path_this($toPath); if(!$sourceArr || in_array($beforePath,$sourceArr) || in_array(rtrim($beforePath,'/'),$sourceArr) || in_array(rtrim($beforePath,'/').'/',$sourceArr) ){ IO::move($toPath,$fromPath,REPEAT_RENAME_FOLDER); unset($listNew[$toPath]); } } if(count($listNew) != count($list)){ $this->resetList($listNew); } } /** * 删除到回收站; * 物理路径: 移动到 TEMP_PATH/.recycle/[user_id] * io路径 : 移动到该io/.recycle 下; */ private function moveToRecycle($path,$recyclePath,$beforePath){ if(substr($path,0,strlen($recyclePath)) == $recyclePath){ return IO::remove($path);//已经在回收站中,则不再处理; } $destPath = IO::mkdir($recyclePath); $destInfo = $destPath ? IO::info($destPath):false; if(!$destInfo){return IO::remove($path);} //新建失败,则尝试直接删除; $toPath = IO::move($path,$recyclePath,REPEAT_RENAME_FOLDER); $list = $this->listData(); $list[$toPath] = $beforePath; $this->resetList($list); return $toPath; } private function listData(){ $this->localRecycleFolder(); $list = Model("UserOption")->get('recycleList','recycle'); return $list ? json_decode($list,true):array(); } private function resetList($list){ $listData = json_encode($list); // options表key=>value value最长长度限制; if(strlen($listData) > 65536){ show_json(LNG('explorer.recycleClearForce'),false); } Model("UserOption")->set('recycleList',$listData,'recycle'); } // 物理路径回收站文件名处理(安全优化, 隐藏文件夹名,避免被遍历) private function localRecycleFolder(){ // Model("SystemOption")->set('recycleFolder','');return '.recycle';//debug; $recycleFolder = Model("SystemOption")->get('recycleFolder'); if($recycleFolder) return $recycleFolder; $recycleFolder = '.recycle_'.rand_string(8); $recycleLocal = DATA_PATH.$recycleFolder.'/'; // =====1.35前版本兼容处理;==== $recycleBefore= DATA_PATH.'.recycle/'; $list = Model("UserOption")->get('recycleList','recycle'); $list = $list ? json_decode($list,true):array(); $listNew = array(); foreach ($list as $path => $beforeAt){ $newPath = $path; if(substr($path,0,strlen($recycleBefore)) == $recycleBefore){ $newPath = $recycleLocal.substr($path,strlen($recycleBefore)); } $listNew[$newPath] = $beforeAt; } Model("UserOption")->set('recycleList',json_encode($listNew),'recycle'); @rename($recycleBefore,get_path_father($recycleBefore).'/'.$recycleFolder); // =====兼容end==== IO::mkdir($recycleLocal); file_put_contents($recycleLocal.'index.html',''); Model("SystemOption")->set('recycleFolder',$recycleFolder); return $recycleFolder; } }