230 lines
7.5 KiB
PHP
Raw Normal View History

2024-08-31 01:03:37 +08:00
<?php
/**
* 物理文件夹删除;
* 回收站支持处理;
*/
class explorerRecycleDriver extends Controller{
public function __construct(){
parent::__construct();
}
public function removeCheck($path,$toRecycle=true){
if(!$toRecycle) return IO::remove($path,$toRecycle);
$path = KodIO::clear($path);
$pathParse = KodIO::parse($path);
$beforePath = get_path_father($path);
$recycleName = '.recycle/user_'.USER_ID.'/';
$recycleLocal = rtrim(DATA_PATH,'/').'/'.$this->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;
}
}