Server IP : 80.87.202.40 / Your IP : 216.73.216.169 Web Server : Apache System : Linux rospirotorg.ru 5.14.0-539.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 5 22:26:13 UTC 2024 x86_64 User : bitrix ( 600) PHP Version : 8.2.27 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/landing/lib/copy/integration/ |
Upload File : |
<?php namespace Bitrix\Landing\Copy\Integration; use Bitrix\Landing; use Bitrix\Landing\Folder; use Bitrix\Landing\Site\Type; use Bitrix\Main\Config\Option; use Bitrix\Main\Copy\Container; use Bitrix\Main\Copy\ContainerCollection; use Bitrix\Main\Copy\EntityCopier; use Bitrix\Main\Loader; use Bitrix\Main\Result; use Bitrix\Main\Update\Stepper; class GroupStepper extends Stepper { protected static $moduleId = 'landing'; protected $queueName = 'LandingGroupQueue'; protected $checkerName = 'LandingGroupChecker_'; protected $baseName = 'LandingGroupStepper_'; protected $errorName = 'LandingGroupError_'; const LIMIT = 5; public function execute(array &$option) { if (!Loader::includeModule(self::$moduleId)) { return false; } try { $queue = $this->getQueue(); $this->setQueue($queue); $queueOption = $this->getOptionData($this->baseName); if (empty($queueOption)) { $this->deleteQueueOption(); return !$this->isQueueEmpty(); } $executiveUserId = ($queueOption["executiveUserId"] ?: 0); $siteId = ($queueOption['siteId'] ?: 0); $copiedSiteId = ($queueOption['copiedSiteId'] ?: 0); Landing\Rights::setContextUserId($executiveUserId); Type::setScope(Type::SCOPE_CODE_GROUP); $copiedPageIds = $this->getPageIdsBySiteId($copiedSiteId); $offset = count($copiedPageIds); $pageIdsToCopy = $this->getPageIdsBySiteId($siteId); $count = count($pageIdsToCopy); $pageIdsToCopy = array_slice($pageIdsToCopy, $offset, self::LIMIT); if ($pageIdsToCopy) { $pageCopier = $this->getPageCopier($copiedSiteId); $containerCollection = new ContainerCollection(); foreach ($pageIdsToCopy as $pageId) { $container = new Container($pageId); $containerCollection[] = $container; } $result = $pageCopier->copy($containerCollection); if (!$result->isSuccess()) { $this->deleteQueueOption(); return !$this->isQueueEmpty(); } $this->saveCopiedMapIds($pageCopier, $queueOption, $result); $option['count'] = $count; $option['steps'] = $offset; } else { $this->onAfterCopy($queueOption); $this->deleteQueueOption(); return !$this->isQueueEmpty(); } return true; } catch (\Exception $exception) { $this->clearContextUserId(); $this->writeToLog($exception); $this->deleteQueueOption(); return false; } } private function getPageIdsBySiteId(int $siteId): array { $pageIds = []; $queryObject = Landing\Landing::getList([ 'select' => ['ID'], 'filter' => ['SITE_ID' => $siteId], ]); while ($page = $queryObject->fetch()) { $pageIds[] = $page['ID']; } return $pageIds; } private function getPageCopier(int $copiedSiteId): EntityCopier { $pageCopyImplementer = new Landing\Copy\Implement\Landing(); $pageCopyImplementer->setTargetSiteId($copiedSiteId); return new EntityCopier($pageCopyImplementer); } private function saveCopiedMapIds(EntityCopier $pageCopier, array $queueOption, Result $result): void { $pageMapIds = ($queueOption['pageMapIds'] ?: []); $blockMapIds = ($queueOption['blockMapIds'] ?: []); $pageMapIds = $pageCopier->getMapIdsByImplementer( Landing\Copy\Implement\Landing::class, $result->getData() ) + $pageMapIds; $queueOption['pageMapIds'] = $pageMapIds; $blockMapIds = $pageCopier->getMapIdsByImplementer( 'LandingBlocks', $result->getData() ) + $blockMapIds; $queueOption['blockMapIds'] = $blockMapIds; $this->saveQueueOption($queueOption); } private function onAfterCopy(array $queueOption) { $siteId = ($queueOption['siteId'] ?: 0); $copiedSiteId = ($queueOption['copiedSiteId'] ?: 0); $pageMapIds = array_filter(($queueOption['pageMapIds'] ?: [])); $folderMapIds = array_filter(($queueOption['folderMapIds'] ?: [])); $folderIndexIds = array_filter(($queueOption['folderIndexIds'] ?: [])); $blockMapIds = array_filter(($queueOption['blockMapIds'] ?: [])); if ($pageMapIds) { if ($folderMapIds) { $this->updateFolderIds($copiedSiteId, $folderMapIds); $this->updateFolderIndexes($folderMapIds, $folderIndexIds, $pageMapIds); } $this->updateBlockIds($pageMapIds, $blockMapIds); $this->updateCopiedSite($siteId, $copiedSiteId, $pageMapIds); } $this->clearContextUserId(); } private function clearContextUserId() { Landing\Rights::clearContextUserId(); } private function updateFolderIds(int $siteId, array $folderMapIds): void { \Bitrix\Landing\Landing::disableCheckUniqueAddress(); $res = Landing\Landing::getList([ 'select' => [ 'ID', 'FOLDER_ID' ], 'filter' => [ 'SITE_ID' => $siteId, 'FOLDER_ID' => array_keys($folderMapIds) ] ]); while ($row = $res->fetch()) { if (isset($folderMapIds[$row['FOLDER_ID']])) { Landing\Landing::update($row['ID'], [ 'FOLDER_ID' => $folderMapIds[$row['FOLDER_ID']] ]); } } \Bitrix\Landing\Landing::enableCheckUniqueAddress(); } private function updateFolderIndexes(array $folderMapIds, array $folderIndexIds, array $pageMapIds): void { foreach ($folderMapIds as $oldFolderId => $newFolderId) { Folder::update($newFolderId, [ 'INDEX_ID' => $pageMapIds[ $folderIndexIds[$oldFolderId] ] ?? null ]); } } private function updateBlockIds(array $pageMapIds, array $blockMapIds): void { ksort($pageMapIds); ksort($blockMapIds); Landing\Landing::setEditMode(); foreach ($pageMapIds as $pageId => $copiedPageId) { $pageMapIds['#landing'.$pageId] = '#landing'.$copiedPageId; unset($pageMapIds[$pageId]); } foreach ($blockMapIds as $blockId => $copiedBlockId) { $blockMapIds['#block'.$blockId] = '#block'.$copiedBlockId; unset($blockMapIds[$blockId]); } foreach ($pageMapIds as $pageId => $copiedPageId) { $copiedLandingInstance = Landing\Landing::createInstance(mb_substr($copiedPageId, 8)); foreach ($copiedLandingInstance->getBlocks() as $copiedBlock) { $content = $copiedBlock->getContent(); $content = str_replace( array_keys($pageMapIds), array_values($pageMapIds), $content ); $content = str_replace( array_keys($blockMapIds), array_values($blockMapIds), $content ); $copiedBlock->saveContent($content); $copiedBlock->save(); } } } private function updateCopiedSite(int $siteId, int $copiedSiteId, array $pageMapIds): void { $siteData = $this->getSiteData($siteId); $siteDataForUpdate = $this->getSiteDataForUpdateCopiedSite($siteData, $pageMapIds); if ($siteData['TPL_ID']) { $siteDataForUpdate['TPL_ID'] = $siteData['TPL_ID']; $this->copyTemplate($siteId, $copiedSiteId, $pageMapIds); } if ($siteDataForUpdate) { Landing\Site::update($copiedSiteId, $siteDataForUpdate); } } private function getSiteData(int $siteId): array { $queryObject = Landing\Site::getList(['filter' => ['ID' => $siteId]]); return (($siteData = $queryObject->fetch()) ? $siteData : []); } private function getSiteDataForUpdateCopiedSite(array $siteData, array $pageMapIds): array { $copiedSiteData = []; $codes = ['LANDING_ID_INDEX', 'LANDING_ID_404', 'LANDING_ID_503']; foreach ($codes as $code) { if ($siteData[$code] && isset($pageMapIds[$siteData[$code]])) { $copiedSiteData[$code] = $pageMapIds[$siteData[$code]]; } } return $copiedSiteData; } private function copyTemplate(int $siteId, int $copiedSiteId, array $pageMapIds): void { if (($refs = Landing\TemplateRef::getForSite($siteId))) { foreach ($refs as $areaId => $oldId) { if (isset($pageMapIds[$oldId])) { $refs[$areaId] = $pageMapIds[$oldId]; } else { unset($refs[$areaId]); } } if ($refs) { Landing\TemplateRef::setForSite($copiedSiteId, $refs); } } } protected function getQueue(): array { return $this->getOptionData($this->queueName); } protected function setQueue(array $queue): void { $queueId = (string) current($queue); $this->checkerName = (mb_strpos($this->checkerName, $queueId) === false ? $this->checkerName.$queueId : $this->checkerName); $this->baseName = (mb_strpos($this->baseName, $queueId) === false ? $this->baseName.$queueId : $this->baseName); $this->errorName = (mb_strpos($this->errorName, $queueId) === false ? $this->errorName.$queueId : $this->errorName); } protected function getQueueOption() { return $this->getOptionData($this->baseName); } protected function saveQueueOption(array $data) { Option::set(static::$moduleId, $this->baseName, serialize($data)); } protected function deleteQueueOption() { $queue = $this->getQueue(); $this->setQueue($queue); $this->deleteCurrentQueue($queue); Option::delete(static::$moduleId, ["name" => $this->checkerName]); Option::delete(static::$moduleId, ["name" => $this->baseName]); } protected function deleteCurrentQueue(array $queue): void { $queueId = current($queue); $currentPos = array_search($queueId, $queue); if ($currentPos !== false) { unset($queue[$currentPos]); Option::set(static::$moduleId, $this->queueName, serialize($queue)); } } protected function isQueueEmpty() { $queue = $this->getOptionData($this->queueName); return empty($queue); } protected function getOptionData($optionName) { $option = Option::get(static::$moduleId, $optionName); $option = ($option !== "" ? unserialize($option, ['allowed_classes' => false]) : []); return (is_array($option) ? $option : []); } protected function deleteOption($optionName) { Option::delete(static::$moduleId, ["name" => $optionName]); } }