Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
groupstepper.php
1<?php
3
14
15class GroupStepper extends Stepper
16{
17 protected static $moduleId = 'landing';
18
19 protected $queueName = 'LandingGroupQueue';
20 protected $checkerName = 'LandingGroupChecker_';
21 protected $baseName = 'LandingGroupStepper_';
22 protected $errorName = 'LandingGroupError_';
23
24 const LIMIT = 5;
25
26 public function execute(array &$option)
27 {
28 if (!Loader::includeModule(self::$moduleId))
29 {
30 return false;
31 }
32
33 try
34 {
35 $queue = $this->getQueue();
36 $this->setQueue($queue);
37 $queueOption = $this->getOptionData($this->baseName);
38 if (empty($queueOption))
39 {
40 $this->deleteQueueOption();
41 return !$this->isQueueEmpty();
42 }
43
44 $executiveUserId = ($queueOption["executiveUserId"] ?: 0);
45
46 $siteId = ($queueOption['siteId'] ?: 0);
47 $copiedSiteId = ($queueOption['copiedSiteId'] ?: 0);
48
49 Landing\Rights::setContextUserId($executiveUserId);
50
51 Type::setScope(Type::SCOPE_CODE_GROUP);
52
53 $copiedPageIds = $this->getPageIdsBySiteId($copiedSiteId);
54 $offset = count($copiedPageIds);
55
56 $pageIdsToCopy = $this->getPageIdsBySiteId($siteId);
57 $count = count($pageIdsToCopy);
58 $pageIdsToCopy = array_slice($pageIdsToCopy, $offset, self::LIMIT);
59
60 if ($pageIdsToCopy)
61 {
62 $pageCopier = $this->getPageCopier($copiedSiteId);
63
64 $containerCollection = new ContainerCollection();
65 foreach ($pageIdsToCopy as $pageId)
66 {
67 $container = new Container($pageId);
68 $containerCollection[] = $container;
69 }
70 $result = $pageCopier->copy($containerCollection);
71 if (!$result->isSuccess())
72 {
73 $this->deleteQueueOption();
74 return !$this->isQueueEmpty();
75 }
76
77 $this->saveCopiedMapIds($pageCopier, $queueOption, $result);
78
79 $option['count'] = $count;
80 $option['steps'] = $offset;
81 }
82 else
83 {
84 $this->onAfterCopy($queueOption);
85 $this->deleteQueueOption();
86 return !$this->isQueueEmpty();
87 }
88
89 return true;
90 }
91 catch (\Exception $exception)
92 {
93 $this->clearContextUserId();
94 $this->writeToLog($exception);
95 $this->deleteQueueOption();
96 return false;
97 }
98 }
99
100 private function getPageIdsBySiteId(int $siteId): array
101 {
102 $pageIds = [];
103 $queryObject = Landing\Landing::getList([
104 'select' => ['ID'],
105 'filter' => ['SITE_ID' => $siteId],
106 ]);
107 while ($page = $queryObject->fetch())
108 {
109 $pageIds[] = $page['ID'];
110 }
111 return $pageIds;
112 }
113
114 private function getPageCopier(int $copiedSiteId): EntityCopier
115 {
116 $pageCopyImplementer = new Landing\Copy\Implement\Landing();
117 $pageCopyImplementer->setTargetSiteId($copiedSiteId);
118
119 return new EntityCopier($pageCopyImplementer);
120 }
121
122 private function saveCopiedMapIds(EntityCopier $pageCopier, array $queueOption, Result $result): void
123 {
124 $pageMapIds = ($queueOption['pageMapIds'] ?: []);
125 $blockMapIds = ($queueOption['blockMapIds'] ?: []);
126
127 $pageMapIds = $pageCopier->getMapIdsByImplementer(
128 Landing\Copy\Implement\Landing::class, $result->getData()
129 ) + $pageMapIds;
130 $queueOption['pageMapIds'] = $pageMapIds;
131
132 $blockMapIds = $pageCopier->getMapIdsByImplementer(
133 'LandingBlocks', $result->getData()
134 ) + $blockMapIds;
135 $queueOption['blockMapIds'] = $blockMapIds;
136
137 $this->saveQueueOption($queueOption);
138 }
139
140 private function onAfterCopy(array $queueOption)
141 {
142 $siteId = ($queueOption['siteId'] ?: 0);
143 $copiedSiteId = ($queueOption['copiedSiteId'] ?: 0);
144 $pageMapIds = array_filter(($queueOption['pageMapIds'] ?: []));
145 $folderMapIds = array_filter(($queueOption['folderMapIds'] ?: []));
146 $folderIndexIds = array_filter(($queueOption['folderIndexIds'] ?: []));
147 $blockMapIds = array_filter(($queueOption['blockMapIds'] ?: []));
148
149 if ($pageMapIds)
150 {
151 if ($folderMapIds)
152 {
153 $this->updateFolderIds($copiedSiteId, $folderMapIds);
154 $this->updateFolderIndexes($folderMapIds, $folderIndexIds, $pageMapIds);
155 }
156 $this->updateBlockIds($pageMapIds, $blockMapIds);
157 $this->updateCopiedSite($siteId, $copiedSiteId, $pageMapIds);
158 }
159
160 $this->clearContextUserId();
161 }
162
163 private function clearContextUserId()
164 {
165 Landing\Rights::clearContextUserId();
166 }
167
168 private function updateFolderIds(int $siteId, array $folderMapIds): void
169 {
170 \Bitrix\Landing\Landing::disableCheckUniqueAddress();
171
172 $res = Landing\Landing::getList([
173 'select' => [
174 'ID', 'FOLDER_ID'
175 ],
176 'filter' => [
177 'SITE_ID' => $siteId,
178 'FOLDER_ID' => array_keys($folderMapIds)
179 ]
180 ]);
181 while ($row = $res->fetch())
182 {
183 if (isset($folderMapIds[$row['FOLDER_ID']]))
184 {
185 Landing\Landing::update($row['ID'], [
186 'FOLDER_ID' => $folderMapIds[$row['FOLDER_ID']]
187 ]);
188 }
189 }
190
191 \Bitrix\Landing\Landing::enableCheckUniqueAddress();
192 }
193
194 private function updateFolderIndexes(array $folderMapIds, array $folderIndexIds, array $pageMapIds): void
195 {
196 foreach ($folderMapIds as $oldFolderId => $newFolderId)
197 {
198 Folder::update($newFolderId, [
199 'INDEX_ID' => $pageMapIds[ $folderIndexIds[$oldFolderId] ] ?? null
200 ]);
201 }
202 }
203
204 private function updateBlockIds(array $pageMapIds, array $blockMapIds): void
205 {
206 ksort($pageMapIds);
207 ksort($blockMapIds);
208
209 Landing\Landing::setEditMode();
210
211 foreach ($pageMapIds as $pageId => $copiedPageId)
212 {
213 $pageMapIds['#landing'.$pageId] = '#landing'.$copiedPageId;
214 unset($pageMapIds[$pageId]);
215 }
216 foreach ($blockMapIds as $blockId => $copiedBlockId)
217 {
218 $blockMapIds['#block'.$blockId] = '#block'.$copiedBlockId;
219 unset($blockMapIds[$blockId]);
220 }
221
222 foreach ($pageMapIds as $pageId => $copiedPageId)
223 {
224 $copiedLandingInstance = Landing\Landing::createInstance(mb_substr($copiedPageId, 8));
225 foreach ($copiedLandingInstance->getBlocks() as $copiedBlock)
226 {
227 $content = $copiedBlock->getContent();
228 $content = str_replace(
229 array_keys($pageMapIds),
230 array_values($pageMapIds),
231 $content
232 );
233 $content = str_replace(
234 array_keys($blockMapIds),
235 array_values($blockMapIds),
236 $content
237 );
238 $copiedBlock->saveContent($content);
239 $copiedBlock->save();
240 }
241 }
242 }
243
244 private function updateCopiedSite(int $siteId, int $copiedSiteId, array $pageMapIds): void
245 {
246 $siteData = $this->getSiteData($siteId);
247 $siteDataForUpdate = $this->getSiteDataForUpdateCopiedSite($siteData, $pageMapIds);
248 if ($siteData['TPL_ID'])
249 {
250 $siteDataForUpdate['TPL_ID'] = $siteData['TPL_ID'];
251 $this->copyTemplate($siteId, $copiedSiteId, $pageMapIds);
252 }
253 if ($siteDataForUpdate)
254 {
255 Landing\Site::update($copiedSiteId, $siteDataForUpdate);
256 }
257 }
258
259 private function getSiteData(int $siteId): array
260 {
261 $queryObject = Landing\Site::getList(['filter' => ['ID' => $siteId]]);
262 return (($siteData = $queryObject->fetch()) ? $siteData : []);
263 }
264
265 private function getSiteDataForUpdateCopiedSite(array $siteData, array $pageMapIds): array
266 {
267 $copiedSiteData = [];
268 $codes = ['LANDING_ID_INDEX', 'LANDING_ID_404', 'LANDING_ID_503'];
269 foreach ($codes as $code)
270 {
271 if ($siteData[$code] && isset($pageMapIds[$siteData[$code]]))
272 {
273 $copiedSiteData[$code] = $pageMapIds[$siteData[$code]];
274 }
275 }
276 return $copiedSiteData;
277 }
278
279 private function copyTemplate(int $siteId, int $copiedSiteId, array $pageMapIds): void
280 {
281 if (($refs = Landing\TemplateRef::getForSite($siteId)))
282 {
283 foreach ($refs as $areaId => $oldId)
284 {
285 if (isset($pageMapIds[$oldId]))
286 {
287 $refs[$areaId] = $pageMapIds[$oldId];
288 }
289 else
290 {
291 unset($refs[$areaId]);
292 }
293 }
294 if ($refs)
295 {
296 Landing\TemplateRef::setForSite($copiedSiteId, $refs);
297 }
298 }
299 }
300
301 protected function getQueue(): array
302 {
303 return $this->getOptionData($this->queueName);
304 }
305
306 protected function setQueue(array $queue): void
307 {
308 $queueId = (string) current($queue);
309 $this->checkerName = (mb_strpos($this->checkerName, $queueId) === false ?
310 $this->checkerName.$queueId : $this->checkerName);
311 $this->baseName = (mb_strpos($this->baseName, $queueId) === false ?
312 $this->baseName.$queueId : $this->baseName);
313 $this->errorName = (mb_strpos($this->errorName, $queueId) === false ?
314 $this->errorName.$queueId : $this->errorName);
315 }
316
317 protected function getQueueOption()
318 {
319 return $this->getOptionData($this->baseName);
320 }
321
322 protected function saveQueueOption(array $data)
323 {
324 Option::set(static::$moduleId, $this->baseName, serialize($data));
325 }
326
327 protected function deleteQueueOption()
328 {
329 $queue = $this->getQueue();
330 $this->setQueue($queue);
331 $this->deleteCurrentQueue($queue);
332 Option::delete(static::$moduleId, ["name" => $this->checkerName]);
333 Option::delete(static::$moduleId, ["name" => $this->baseName]);
334 }
335
336 protected function deleteCurrentQueue(array $queue): void
337 {
338 $queueId = current($queue);
339 $currentPos = array_search($queueId, $queue);
340 if ($currentPos !== false)
341 {
342 unset($queue[$currentPos]);
343 Option::set(static::$moduleId, $this->queueName, serialize($queue));
344 }
345 }
346
347 protected function isQueueEmpty()
348 {
349 $queue = $this->getOptionData($this->queueName);
350 return empty($queue);
351 }
352
353 protected function getOptionData($optionName)
354 {
355 $option = Option::get(static::$moduleId, $optionName);
356 $option = ($option !== "" ? unserialize($option, ['allowed_classes' => false]) : []);
357 return (is_array($option) ? $option : []);
358 }
359
360 protected function deleteOption($optionName)
361 {
362 Option::delete(static::$moduleId, ["name" => $optionName]);
363 }
364}
writeToLog(\Exception $exception)
Definition stepper.php:406