• Модуль: main
  • Путь к файлу: ~/bitrix/modules/main/classes/general/file.php
  • Класс: CFile
  • Вызов: CFile::DeleteDuplicates
static function DeleteDuplicates($originalId, array $duplicteIds)
{
	$connection = BitrixMainApplication::getConnection();
	$helper = $connection->getSqlHelper();

	$original = InternalFileHashTable::getList([
		'select' => ['FILE_SIZE', 'FILE_HASH', 'FILE.*'],
		'filter' => ['=FILE_ID' => $originalId],
	])->fetchObject();
	if (!$original)
	{
		return;
	}

	$originalPath = '/' . $original->getFile()->getSubdir() . '/' . $original->getFile()->getFileName();

	$io = CBXVirtualIo::GetInstance();
	$uploadDir = COption::GetOptionString("main", "upload_dir", "upload");
	$deleteSize = 0;
	$lockId = '';
	$fileList = BitrixMainFileTable::getList([
		'select' => ['ID', 'FILE_SIZE', 'SUBDIR', 'FILE_NAME'],
		'filter' => [
			'=ID' => $duplicteIds,
			'=HANDLER_ID' => $original->getFile()->getHandlerId(),
		],
		'order' => [
			'ID' => 'ASC',
		],
	]);
	while ($duplicate = $fileList->fetchObject())
	{
		if (!$lockId)
		{
			$lockId = static::lockFileHash($original->getFileSize(), $original->getFileHash());
		}

		$deleteResult = InternalFileHashTable::delete($duplicate->getId());

		$duplicatePath = '/' . $duplicate->getSubdir() . '/' . $duplicate->getFileName();
		if ($originalPath == $duplicatePath)
		{
			continue;
		}

		$cancel = false;
		foreach (GetModuleEvents('main', 'OnBeforeFileDeleteDuplicate', true) as $event)
		{
			$cancel = ExecuteModuleEventEx($event, array($original->getFile(), $duplicate));
			if ($cancel)
			{
				break;
			}
		}
		if ($cancel)
		{
			continue;
		}

		static::AddDuplicate($originalId, $duplicate->getId(), false);

		$update = $helper->prepareUpdate('b_file', [
			'SUBDIR' => $original->getFile()->getSubdir(),
			'FILE_NAME' => $original->getFile()->getFileName(),
		]);
		$ddl = 'UPDATE b_file SET ' . $update[0] . 'WHERE ID = ' . $duplicate->getId();
		$connection->queryExecute($ddl);

		static::cleanCache($duplicate->getId());

		$isExternal = false;
		foreach (GetModuleEvents('main', 'OnAfterFileDeleteDuplicate', true) as $event)
		{
			$isExternal = ExecuteModuleEventEx($event, array($original->getFile(), $duplicate)) || $isExternal;
		}

		if (!$isExternal)
		{
			$dname = $_SERVER["DOCUMENT_ROOT"] . '/' . $uploadDir . '/' . $duplicate->getSubdir();
			$fname = $dname . '/' . $duplicate->getFileName();

			$file = $io->GetFile($fname);
			if ($file->isExists() && $file->unlink())
			{
				$deleteSize += $duplicate->getFileSize();
			}

			$directory = $io->GetDirectory($dname);
			if ($directory->isExists() && $directory->isEmpty())
			{
				if ($directory->rmdir())
				{
					$parent = $io->GetDirectory(GetDirPath($dname));
					if ($parent->isExists() && $parent->isEmpty())
					{
						$parent->rmdir();
					}
				}
			}
		}
	}

	if ($lockId)
	{
		static::unlockFileHash($lockId);
	}

	/****************************** QUOTA ******************************/
	if ($deleteSize > 0 && COption::GetOptionInt("main", "disk_space") > 0)
	{
		CDiskQuota::updateDiskQuota("file", $deleteSize, "delete");
	}
	/****************************** QUOTA ******************************/
}