protected function runIblock(): bool
{
$result = true;
$timeFinish = self::getTimeFinish();
$isFinished = false;
$bCheckFinished = false;
$runtimeIblock = false;
$currentIBlock = false;
$sitemapFile = null;
$iblockId = 0;
$dbOldIblockResult = null;
$dbIblockResult = null;
if (isset($_SESSION["SEO_SITEMAP_" . $this->sitemapId]))
{
$this->state['IBLOCK_MAP'] = $_SESSION["SEO_SITEMAP_" . $this->sitemapId];
unset($_SESSION["SEO_SITEMAP_" . $this->sitemapId]);
}
while (!$isFinished && microtime(true) <= $timeFinish && Loader::includeModule('iblock'))
{
if (!$runtimeIblock)
{
$dbRes = RuntimeTable::getList([
'order' => ['ID' => 'ASC'],
'filter' => [
'PID' => $this->sitemapId,
'ITEM_TYPE' => RuntimeTable::ITEM_TYPE_IBLOCK,
'PROCESSED' => RuntimeTable::UNPROCESSED,
],
'limit' => 1,
]);
$runtimeIblock = $dbRes->fetch();
if ($runtimeIblock)
{
$iblockId = intval($runtimeIblock['ITEM_ID']);
$dbIBlock = CIBlock::GetByID($iblockId);
$currentIBlock = $dbIBlock->Fetch();
if (!$currentIBlock)
{
RuntimeTable::update($runtimeIblock['ID'], [
'PROCESSED' => RuntimeTable::PROCESSED,
]);
$this->state['LEFT_MARGIN'] = 0;
$this->state['IBLOCK_LASTMOD'] = 0;
$this->state['LAST_ELEMENT_ID'] = 0;
unset($this->state['CURRENT_SECTION']);
$this->statusMessage = Loc::getMessage(
'SITEMAP_RUN_IBLOCK_NAME',
['#IBLOCK_NAME#' => $currentIBlock['NAME']]
);
}
else
{
if ($currentIBlock['LIST_PAGE_URL'] == '')
{
$this->sitemapData['SETTINGS']['IBLOCK_LIST'][$iblockId] = 'N';
}
if ($currentIBlock['SECTION_PAGE_URL'] == '')
{
$this->sitemapData['SETTINGS']['IBLOCK_SECTION'][$iblockId] = 'N';
}
if ($currentIBlock['DETAIL_PAGE_URL'] == '')
{
$this->sitemapData['SETTINGS']['IBLOCK_ELEMENT'][$iblockId] = 'N';
}
$this->state['IBLOCK_LASTMOD'] =
max($this->state['IBLOCK_LASTMOD'], MakeTimeStamp($currentIBlock['TIMESTAMP_X']));
if ($this->state['LEFT_MARGIN'] <= 0 && $this->sitemapData['SETTINGS']['IBLOCK_ELEMENT'][$iblockId] != 'N')
{
$this->state['CURRENT_SECTION'] = 0;
}
$fileName = str_replace(
['#IBLOCK_ID#', '#IBLOCK_CODE#', '#IBLOCK_XML_ID#'],
[$iblockId, $currentIBlock['CODE'], $currentIBlock['XML_ID']],
$this->sitemapData['SETTINGS']['FILENAME_IBLOCK']
);
$sitemapFile =
new FileRuntime(
$this->sitemapId,
$fileName,
$this->getSitemapSettings()
);
}
}
}
if (!$runtimeIblock || !$sitemapFile)
{
$isFinished = true;
}
elseif (is_array($currentIBlock))
{
if ($dbIblockResult == null)
{
if (isset($this->state['CURRENT_SECTION']))
{
$dbIblockResult = CIBlockElement::GetList(
['ID' => 'ASC'],
[
'IBLOCK_ID' => $iblockId,
'ACTIVE' => 'Y',
'SECTION_ID' => intval($this->state['CURRENT_SECTION']),
'>ID' => intval($this->state['LAST_ELEMENT_ID']),
'SITE_ID' => $this->sitemapData['SITE_ID'],
"ACTIVE_DATE" => "Y",
],
false,
['nTopCount' => 1000],
['ID', 'TIMESTAMP_X', 'DETAIL_PAGE_URL']
);
}
else
{
$this->state['LAST_ELEMENT_ID'] = 0;
$dbIblockResult = CIBlockSection::GetList(
['LEFT_MARGIN' => 'ASC'],
[
'IBLOCK_ID' => $iblockId,
'GLOBAL_ACTIVE' => 'Y',
'>LEFT_BORDER' => intval($this->state['LEFT_MARGIN']),
],
false,
['ID', 'TIMESTAMP_X', 'SECTION_PAGE_URL', 'LEFT_MARGIN', 'IBLOCK_SECTION_ID'],
['nTopCount' => 100]
);
}
}
if (isset($this->state['CURRENT_SECTION']))
{
$arElement = $dbIblockResult->fetch();
if ($arElement)
{
if (!is_array($this->state['IBLOCK_MAP'][$iblockId]))
{
$this->state['IBLOCK_MAP'][$iblockId] = [];
}
if (!array_key_exists($arElement['ID'], $this->state['IBLOCK_MAP'][$iblockId]))
{
$arElement['LANG_DIR'] = $this->sitemapData['SITE']['DIR'];
$bCheckFinished = false;
$elementLastmod = MakeTimeStamp($arElement['TIMESTAMP_X']);
$this->state['IBLOCK_LASTMOD'] = max($this->state['IBLOCK_LASTMOD'], $elementLastmod);
$this->state['LAST_ELEMENT_ID'] = $arElement['ID'];
$this->state['IBLOCK'][$iblockId]['E']++;
$this->state['IBLOCK_MAP'][$iblockId][$arElement["ID"]] = 1;
// remove or replace SERVER_NAME
$url =
SourceIblock::prepareUrlToReplace(
$arElement['DETAIL_PAGE_URL'],
$this->sitemapData['SITE_ID']
);
$url = CIBlock::ReplaceDetailUrl($url, $arElement, false, "E");
$sitemapFile->addIBlockEntry($url, $elementLastmod);
}
}
elseif (!$bCheckFinished)
{
$bCheckFinished = true;
$dbIblockResult = null;
}
else
{
$bCheckFinished = false;
unset($this->state['CURRENT_SECTION']);
$this->state['LAST_ELEMENT_ID'] = 0;
$dbIblockResult = null;
if ($dbOldIblockResult)
{
$dbIblockResult = $dbOldIblockResult;
$dbOldIblockResult = null;
}
}
}
else
{
$arSection = $dbIblockResult->fetch();
if ($arSection)
{
$bCheckFinished = false;
$sectionLastmod = MakeTimeStamp($arSection['TIMESTAMP_X']);
$this->state['LEFT_MARGIN'] = $arSection['LEFT_MARGIN'];
$this->state['IBLOCK_LASTMOD'] = max($this->state['IBLOCK_LASTMOD'], $sectionLastmod);
$bActive = false;
$bActiveElement = false;
if (isset($this->sitemapData['SETTINGS']['IBLOCK_SECTION_SECTION'][$iblockId][$arSection['ID']]))
{
$bActive =
$this->sitemapData['SETTINGS']['IBLOCK_SECTION_SECTION'][$iblockId][$arSection['ID']] == 'Y';
$bActiveElement =
$this->sitemapData['SETTINGS']['IBLOCK_SECTION_ELEMENT'][$iblockId][$arSection['ID']] == 'Y';
}
elseif ($arSection['IBLOCK_SECTION_ID'] > 0)
{
$dbRes = RuntimeTable::getList([
'filter' => [
'PID' => $this->sitemapId,
'ITEM_TYPE' => RuntimeTable::ITEM_TYPE_SECTION,
'ITEM_ID' => $arSection['IBLOCK_SECTION_ID'],
'PROCESSED' => RuntimeTable::PROCESSED,
],
'select' => ['ACTIVE', 'ACTIVE_ELEMENT'],
'limit' => 1,
]);
$parentSection = $dbRes->fetch();
if ($parentSection)
{
$bActive = $parentSection['ACTIVE'] == RuntimeTable::ACTIVE;
$bActiveElement = $parentSection['ACTIVE_ELEMENT'] == RuntimeTable::ACTIVE;
}
}
else
{
$bActive = $this->sitemapData['SETTINGS']['IBLOCK_SECTION'][$iblockId] == 'Y';
$bActiveElement = $this->sitemapData['SETTINGS']['IBLOCK_ELEMENT'][$iblockId] == 'Y';
}
$arRuntimeData = [
'PID' => $this->sitemapId,
'ITEM_ID' => $arSection['ID'],
'ITEM_TYPE' => RuntimeTable::ITEM_TYPE_SECTION,
'ACTIVE' => $bActive ? RuntimeTable::ACTIVE : RuntimeTable::INACTIVE,
'ACTIVE_ELEMENT' => $bActiveElement ? RuntimeTable::ACTIVE : RuntimeTable::INACTIVE,
'PROCESSED' => RuntimeTable::PROCESSED,
];
if ($bActive)
{
$this->state['IBLOCK'][$iblockId]['S']++;
$arSection['LANG_DIR'] = $this->sitemapData['SITE']['DIR'];
// remove or replace SERVER_NAME
$url =
SourceIblock::prepareUrlToReplace(
$arSection['SECTION_PAGE_URL'],
$this->sitemapData['SITE_ID']
);
$url = CIBlock::ReplaceDetailUrl($url, $arSection, false, "S");
$sitemapFile->addIBlockEntry($url, $sectionLastmod);
}
RuntimeTable::add($arRuntimeData);
if ($bActiveElement)
{
$this->state['CURRENT_SECTION'] = $arSection['ID'];
$this->state['LAST_ELEMENT_ID'] = 0;
$dbOldIblockResult = $dbIblockResult;
$dbIblockResult = null;
}
}
elseif (!$bCheckFinished)
{
unset($this->state['CURRENT_SECTION']);
$bCheckFinished = true;
$dbIblockResult = null;
}
else
{
$bCheckFinished = false;
// we have finished current iblock
RuntimeTable::update($runtimeIblock['ID'], [
'PROCESSED' => RuntimeTable::PROCESSED,
]);
if ($this->sitemapData['SETTINGS']['IBLOCK_LIST'][$iblockId] == 'Y'
&& $currentIBlock['LIST_PAGE_URL']
<> '')
{
$this->state['IBLOCK'][$iblockId]['I']++;
$currentIBlock['IBLOCK_ID'] = $currentIBlock['ID'];
$currentIBlock['LANG_DIR'] = $this->sitemapData['SITE']['DIR'];
// remove or replace SERVER_NAME
$url =
SourceIblock::prepareUrlToReplace(
$currentIBlock['LIST_PAGE_URL'],
$this->sitemapData['SITE_ID']
);
$url = CIBlock::ReplaceDetailUrl($url, $currentIBlock, false, "");
$sitemapFile->addIBlockEntry($url, $this->state['IBLOCK_LASTMOD']);
}
if ($sitemapFile->isNotEmpty())
{
if ($sitemapFile->isCurrentPartNotEmpty())
{
$sitemapFile->finish();
}
else
{
$sitemapFile->delete();
}
if (!is_array($this->state['XML_FILES']))
{
$this->state['XML_FILES'] = [];
}
$xmlFiles = $sitemapFile->getNameList();
$directory = $sitemapFile->getPathDirectory();
foreach ($xmlFiles as &$xmlFile)
$xmlFile = $directory . $xmlFile;
$this->state['XML_FILES'] = array_unique(array_merge($this->state['XML_FILES'], $xmlFiles));
}
else
{
$sitemapFile->delete();
}
$runtimeIblock = false;
$this->state['LEFT_MARGIN'] = 0;
$this->state['IBLOCK_LASTMOD'] = 0;
unset($this->state['CURRENT_SECTION']);
$this->state['LAST_ELEMENT_ID'] = 0;
}
}
}
}
if ($this->step < Step::STEPS[Step::STEP_IBLOCK] - 1)
{
$this->step++;
}
if ($isFinished)
{
$this->step = Step::STEPS[Step::STEP_IBLOCK];
$this->statusMessage = Loc::getMessage('SITEMAP_RUN_FINALIZE');
}
return $result;
}