• Модуль: 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;
}