- Модуль: disk
- Путь к файлу: ~/bitrix/modules/disk/lib/volume/cleaner.php
- Класс: BitrixDiskVolumeCleaner
- Вызов: Cleaner::deleteFolder
public function deleteFolder(DiskFolder $folder, bool $emptyOnly = false): bool
{
$subTaskDone = true;
if (!$this->isAllowClearStorage($folder->getStorage()))
{
$this->collectError(
new Error('Access denied to storage #'. $folder->getStorageId(), 'ACCESS_DENIED'),
false,
true
);
return false;
}
if (!$this->isAllowClearFolder($folder))
{
$this->collectError(
new Error('Not allowed to drop #'. $folder->getId(), 'ACCESS_DENIED'),
false,
true
);
return false;
}
// restrict delete root folder
$isRootFolder = false;
if ($folder->getStorage()->getRootObjectId() == $folder->getId())
{
$isRootFolder = true;
$emptyOnly = true;
}
if (!$emptyOnly && !$this->isAllowDeleteFolder($folder))
{
$this->collectError(
new Error('Not allowed to drop #'. $folder->getId(), 'ACCESS_DENIED'),
false,
false
);
return false;
}
$countFileErasure = 0;
$objectList = DiskInternalsObjectTable::getList([
'filter' => [
'=PATH_CHILD.PARENT_ID' => $folder->getId(),
],
'order' => [
'PATH_CHILD.DEPTH_LEVEL' => 'DESC',
'ID' => 'ASC'
],
'limit' => self::MAX_FOLDER_PER_INTERACTION,
]);
$task = $this->instanceTask();
$task->setIterationFileCount($objectList->getSelectedRowsCount());
foreach ($objectList as $row)
{
if ($row['ID'] == $folder->getId())
{
continue;
}
if ($isRootFolder)
{
// allow delete only files in root folder
if ($row['PARENT_ID'] != $folder->getId() || $row['TYPE'] != DiskInternalsObjectTable::TYPE_FILE)
{
continue;
}
}
$object = DiskBaseObject::buildFromArray($row);
/** @var DiskFolder|DiskFile $object */
if ($object instanceof DiskFolder)
{
if ($isRootFolder)
{
// disallow recursive delete from root
continue;
}
/** @var DiskFile $object */
$securityContext = $this->getSecurityContext($this->getOwner(), $object);
if ($object->canDelete($securityContext))
{
if ($this->isAllowDeleteFolder($object))
{
try
{
$logData = $task->collectLogData($object);
/** @var DiskFolder $object */
if (!$object->deleteTree($task->getOwnerId()))
{
$this->collectError($object->getErrors(), false);
$subTaskDone = false;
}
else
{
$task->log($logData, __FUNCTION__);
$task->increaseDroppedFolderCount();
}
}
catch (MainSystemException $exception)
{
$this->collectError(
new Error($exception->getMessage(), $exception->getCode()),
true,
false
);
}
}
else
{
$this->collectError(
new Error('Not allowed to drop folder #'. $object->getId(), 'ACCESS_DENIED'),
false,
false
);
}
}
else
{
$this->collectError(
new Error('Access denied to folder #'. $object->getId(), 'ACCESS_DENIED'),
true,
false
);
}
}
elseif($object instanceof DiskFile)
{
/** @var DiskFile $object */
$securityContext = $this->getSecurityContext($this->getOwner(), $object);
if($object->canDelete($securityContext))
{
$subTaskDone = $this->deleteFile($object);
}
else
{
$this->collectError(new Error('Access denied to file #'. $object->getId(), 'ACCESS_DENIED'));
}
}
// fix interval task state
$countFileErasure ++;
if ($countFileErasure >= self::STATUS_FIX_INTERVAL)
{
$countFileErasure = 0;
if ($task->hasUserCanceled())
{
$subTaskDone = false;
break;
}
$task->fixState();
// count statistic for progress bar
self::countWorker((int)$task->getOwnerId());
}
if (!$this->checkTimeEnd())
{
$subTaskDone = false;
break;
}
}
if ($subTaskDone)
{
if ($emptyOnly === false)
{
try
{
$logData = $task->collectLogData($folder);
if (!$folder->deleteTree($task->getOwnerId()))
{
$this->collectError($folder->getErrors());
return false;
}
$task->log($logData, __FUNCTION__);
$task->increaseDroppedFolderCount();
}
catch (MainSystemException $exception)
{
$this->collectError(new Error($exception->getMessage(), $exception->getCode()));
}
}
}
return $subTaskDone;
}