• Модуль: translate
  • Путь к файлу: ~/bitrix/modules/translate/lib/index/fileindexcollection.php
  • Класс: BitrixTranslateIndexFileIndexCollection
  • Вызов: FileIndexCollection::collect
public function collect(TranslateFilter $filter = null, TranslateControllerITimeLimit $timer = null, TranslateFilter $seek = null): int
{
	self::configure();

	if (isset($filter, $filter->path))
	{
		$relPath = $filter->path;
	}
	else
	{
		$relPath = TranslateConfig::getDefaultPath();
	}

	$relPath = '/'. trim($relPath, '/');
	$relPath = TranslateIOPath::replaceLangId($relPath, '#LANG_ID#');

	$this->checkLanguages = self::$enabledLanguages;
	if (isset($filter, $filter->langId))
	{
		$this->checkLanguages = array_intersect($filter->langId, $this->checkLanguages);
	}


	$topPathRes = IndexInternalsPathIndexTable::getList([
		'select' => ['ID'],
		'filter' => ['=PATH' => $relPath]
	]);
	if (!($topPath = $topPathRes->fetch()))
	{
		return 0;
	}

	$pathFilter = [
		'=IS_DIR' => 'N',
		'=IS_LANG' => 'Y',
		'=%PATH' => $relPath.'%#LANG_ID#%',
		'=DESCENDANTS.PARENT_ID' => $topPath['ID'],//ancestor
		//todo: add filter by INDEXED_TIME
	];
	if (isset($seek, $seek->pathId))
	{
		$pathFilter['>ID'] = $seek->pathId;
	}

	// path list
	$pathListRes = IndexInternalsPathIndexTable::getList([
		'select' => ['ID', 'PATH'],
		'filter' => $pathFilter,
		'order' => ['ID' => 'ASC'],
		//todo: add limit here
	]);

	$processedItemCount = 0;

	while (true)
	{
		$lastPathId = null;
		$pathPortion = [];
		$pathIdPortion = [];
		while ($pathRow = $pathListRes->fetch())
		{
			$pathIdPortion[] = $lastPathId = (int)$pathRow['ID'];
			$pathPortion[$lastPathId] = $pathRow['PATH'];
			if (count($pathIdPortion) >= 100)
			{
				break;
			}
		}
		if (empty($pathIdPortion))
		{
			break;
		}

		$indexFileCacheRes = IndexInternalsFileIndexTable::getList([
			'select' => ['ID', 'PATH_ID', 'LANG_ID'],
			'filter' => [
				'=PATH_ID' => $pathIdPortion,
				'=LANG_ID' => $this->checkLanguages,
			]
		]);
		$indexFileCache = [];
		while ($indexFile = $indexFileCacheRes->fetch())
		{
			if (!isset($indexFileCache[(int)$indexFile['PATH_ID']]))
			{
				$indexFileCache[(int)$indexFile['PATH_ID']] = [];
			}
			$indexFileCache[(int)$indexFile['PATH_ID']][$indexFile['LANG_ID']] = (int)$indexFile['ID'];
		}
		unset($indexFileCacheRes, $indexFile);

		$nonexistentFiles = [];
		$fileData = [];

		foreach ($pathPortion as $pathId => $path)
		{
			foreach ($this->checkLanguages as $langId)
			{
				$fullPath = self::$documentRoot. str_replace('#LANG_ID#', $langId, $path);
				$fullPath = MainLocalizationTranslation::convertLangPath($fullPath, $langId);

				if (self::$verbose)
				{
					echo "Lang file: {$fullPath}n";
				}

				if (!file_exists($fullPath))
				{
					if (isset($indexFileCache[$pathId][$langId]))
					{
						// remove file from index
						$nonexistentFiles[] = $indexFileCache[$pathId][$langId];
					}
					continue;
				}

				if (!isset($indexFileCache[$pathId][$langId]))
				{
					$fileData[] = [
						'PATH_ID' => $pathId,
						'LANG_ID' => $langId,
						'FULL_PATH' => $fullPath,
					];
				}
			}
		}
		if (count($fileData) > 0)
		{
			IndexInternalsFileIndexTable::bulkAdd($fileData);
		}

		if (count($nonexistentFiles) > 0)
		{
			IndexInternalsFileIndexTable::purge(new TranslateFilter(['fileId' => $nonexistentFiles]), true);
		}

		$processedItemCount += count($pathIdPortion);

		if ($timer !== null && $timer->hasTimeLimitReached())
		{
			if ($seek !== null)
			{
				$seek->nextPathId = $lastPathId;
			}
			break;
		}
	}

	return $processedItemCount;
}