1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
landing.php
См. документацию.
1<?php
3
6use \Bitrix\Landing\Landing as LandingCore;
8use \Bitrix\Landing\Site as SiteCore;
10use \Bitrix\Landing\Transfer\AppConfiguration;
11use \Bitrix\Landing\File;
12use \Bitrix\Landing\Folder;
13use \Bitrix\Landing\Hook;
14use \Bitrix\Landing\Repo;
15use \Bitrix\Landing\Block;
16use \Bitrix\Landing\Node;
17use \Bitrix\Main\Event;
21use \Bitrix\Rest\AppTable;
22use \Bitrix\Rest\Configuration;
23use \Bitrix\Crm;
24
29{
34 protected static $forceAppendRestBlocks = true;
35
41 public static function setForceAppendRestBlocks(bool $mode): void
42 {
43 self::$forceAppendRestBlocks = $mode;
44 }
45
52 public static function getRepoId(string $appCode, string $xmlId): ?int
53 {
54 static $items = null;
55
56 if ($items === null)
57 {
58 $items = [];
59 $res = Repo::getList([
60 'select' => [
61 'ID', 'APP_CODE', 'XML_ID',
62 ],
63 ]);
64 while ($row = $res->fetch())
65 {
66 $items[$row['APP_CODE'] . '@' . $row['XML_ID']] = $row['ID'];
67 }
68 }
69
70 if (isset($items[$appCode . '@' . $xmlId]))
71 {
72 return $items[$appCode . '@' . $xmlId];
73 }
74
75 return null;
76 }
77
86 protected static function addFilesToBlock(Block $block, array $data, Configuration\Structure $structure, bool $ignoreManifest = false): array
87 {
88 if (!$ignoreManifest)
89 {
90 $manifest = $block->getManifest();
91 }
92
93 foreach ($data as $selector => &$nodes)
94 {
95 if (!$ignoreManifest)
96 {
97 if (!isset($manifest['nodes'][$selector]))
98 {
99 continue;
100 }
101 if (
102 $manifest['nodes'][$selector]['type'] !== Node\Type::IMAGE
103 && $manifest['nodes'][$selector]['type'] !== Node\Type::STYLE_IMAGE
104 )
105 {
106 continue;
107 }
108 }
109 foreach ($nodes as &$node)
110 {
111 foreach (['', '2x'] as $x)
112 {
113 if (isset($node['id' . $x]))
114 {
115 $unpackedFile = $structure->getUnpackFile($node['id' . $x]);
116 if ($unpackedFile)
117 {
118 $newFileId = AppConfiguration::saveFile($unpackedFile);
119 if ($newFileId)
120 {
121 $newFilePath = File::getFilePath($newFileId);
122 if ($newFilePath)
123 {
124 File::addToBlock($block->getId(), $newFileId);
125 $node['id' . $x] = $newFileId;
126 $node['src' . $x] = $newFilePath;
127 }
128 }
129 }
130 }
131 }
132 }
133 unset($node);
134 }
135 unset($nodes);
136
137 return $data;
138 }
139
145 public static function saveDataToBlock(Block $blockInstance, array $block): void
146 {
147 // update cards
148 if (isset($block['cards']) && is_array($block['cards']))
149 {
150 $blockInstance->updateCards(
151 $block['cards']
152 );
153 }
154 // update style
155 if (isset($block['style']) && is_array($block['style']))
156 {
157 foreach ($block['style'] as $selector => $styleData)
158 {
159 if ($selector === '#wrapper')
160 {
161 $selector = '#' . $blockInstance->getAnchor($blockInstance->getId());
162 }
163 $styleToSet = [];
164 // compatibility for old style export
165 if (!isset($styleData['classList']) && !isset($styleData['style']))
166 {
167 foreach ((array)$styleData as $clPos => $clVal)
168 {
169 // todo: check compatibility
170 $selectorUpd = $selector . '@' . $clPos;
171 $styleToSet[$selectorUpd]['classList'] = (array)$clVal;
172 }
173 }
174
175 // new style export format (classList + style)
176 if (isset($styleData['classList']))
177 {
178 foreach ($styleData['classList'] as $clPos => $class)
179 {
180 if ($class)
181 {
182 $selectorUpd = $selector . '@' . $clPos;
183 $styleToSet[$selectorUpd]['classList'] = explode(' ', $class);
184 }
185 }
186 }
187 if (isset($styleData['style']))
188 {
189 foreach ($styleData['style'] as $stPos => $styles)
190 {
191 if (!empty($styles))
192 {
193 $selectorUpd = $selector . '@' . $stPos;
194 $styleToSet[$selectorUpd]['style'] = $styles;
195 }
196 }
197 }
198
199 if (!empty($styleToSet))
200 {
201 $blockInstance->setClasses($styleToSet);
202 }
203 }
204 }
205 // update nodes
206 if (isset($block['nodes']) && is_array($block['nodes']))
207 {
208 $blockInstance->updateNodes($block['nodes']);
209 }
210 // update menu
211 if (isset($block['menu']) && !empty($block['menu']))
212 {
213 $blockInstance->updateNodes($block['menu']);
214 }
215 // update attrs
216 if (isset($block['attrs']) && !empty($block['attrs']))
217 {
218 if (isset($block['attrs']['#wrapper']))
219 {
220 $attrCode = '#' . $blockInstance->getAnchor($blockInstance->getId());
221 $block['attrs'][$attrCode] = $block['attrs']['#wrapper'];
222 unset($block['attrs']['#wrapper']);
223 }
224 $blockInstance->setAttributes($block['attrs']);
225 }
226 // update dynamic source
227 if (isset($block['dynamic']) && is_array($block['dynamic']))
228 {
229 $blockInstance->saveDynamicParams($block['dynamic']);
230 }
231 }
232
241 protected static function importBlock(LandingCore $landing, array $block, Configuration\Structure $structure, bool &$pending = false): int
242 {
243 static $sort = 0;
244 static $appChecked = [];
245
246 $blockId = 0;
247
248 // if this is a REST block
249 if (
250 isset($block['repo_block']['app_code']) &&
251 isset($block['repo_block']['xml_id']) &&
252 is_string($block['repo_block']['app_code']) &&
253 is_string($block['repo_block']['xml_id'])
254 )
255 {
256 unset($block['code']);
257
258 $repoId = self::getRepoId(
259 $block['repo_block']['app_code'],
260 $block['repo_block']['xml_id']
261 );
262 if ($repoId)
263 {
264 $block['code'] = 'repo_' . $repoId;
265 }
266
267 // force append REST blocks
268 if (
269 !isset($block['code']) &&
270 !empty($block['repo_info']) &&
271 self::$forceAppendRestBlocks
272 )
273 {
274 $appCode = $block['repo_block']['app_code'];
275 if (!array_key_exists($appCode, $appChecked))
276 {
277 $appChecked[$appCode] = \Bitrix\Landing\Repo::getAppByCode($appCode);
278 }
279
280 if ($appChecked[$appCode])
281 {
282 $repoInfo = $block['repo_info'];
283 $res = Repo::add([
284 'APP_CODE' => $block['repo_block']['app_code'],
285 'XML_ID' => $block['repo_block']['xml_id'],
286 'NAME' => $repoInfo['NAME'] ?? null,
287 'DESCRIPTION' => $repoInfo['DESCRIPTION'] ?? null,
288 'SECTIONS' => $repoInfo['SECTIONS'] ?? null,
289 'PREVIEW' => $repoInfo['PREVIEW'] ?? null,
290 'MANIFEST' => serialize(unserialize($repoInfo['MANIFEST'] ?? '', ['allowed_classes' => false])),
291 'CONTENT' => $repoInfo['CONTENT'] ?? null,
292 ]);
293 if ($res->isSuccess())
294 {
295 $block['code'] = 'repo_' . $res->getId();
296 }
297 }
298 }
299
300 if (!isset($block['code']))
301 {
302 $pending = true;
303 $blockId = $landing->addBlock(
305 [
306 'PUBLIC' => 'N',
307 'SORT' => $sort,
308 'ANCHOR' => $block['anchor'] ?? '',
309 'INITIATOR_APP_CODE' => $block['repo_block']['app_code'] ?? null,
310 ]
311 );
312 if ($blockId)
313 {
314 $sort += 500;
315 $blockInstance = $landing->getBlockById($blockId);
316 if ($blockInstance)
317 {
318 if (isset($block['nodes']) && is_array($block['nodes']))
319 {
320 $block['nodes'] = self::addFilesToBlock(
321 $blockInstance,
322 $block['nodes'],
323 $structure,
324 true
325 );
326 }
327 $blockInstance->updateNodes([
329 'BLOCK_ID' => $blockId,
330 'DATA' => base64_encode(serialize($block)),
331 ],
332 ]);
333 $blockInstance->save();
334 }
335 }
336 return $blockId;
337 }
338 }
339
340 if (!isset($block['code']))
341 {
342 return $blockId;
343 }
344
345 // add block to the landing
346 $blockFields = [
347 'PUBLIC' => 'N',
348 'SORT' => $sort,
349 'ANCHOR' => $block['anchor'] ?? '',
350 'INITIATOR_APP_CODE' => $block['repo_block']['app_code'] ?? null,
351 ];
352 if ($block['full_content'] ?? null)
353 {
354 $blockFields['CONTENT'] = str_replace(
355 ['<?', '?>'],
356 ['< ?', '? >'],
357 $block['full_content']
358 );
359 }
360 if ($block['designed'] ?? null)
361 {
362 $blockFields['DESIGNED'] = 'Y';
363 }
364 $blockId = $landing->addBlock(
365 $block['code'],
366 $blockFields
367 );
368 if ($blockId)
369 {
370 $sort += 500;
371 $blockInstance = $landing->getBlockById($blockId);
372 if (isset($block['nodes']) && is_array($block['nodes']))
373 {
374 $block['nodes'] = self::addFilesToBlock(
375 $blockInstance,
376 $block['nodes'],
377 $structure
378 );
379 }
380 if ($block['meta']['FAVORITE_META'] ?? [])
381 {
382 $favoriteMeta = $block['meta']['FAVORITE_META'];
383 if ($block['repo_block']['app_code'] ?? null)
384 {
385 $favoriteMeta['tpl_code'] = $block['repo_block']['app_code'];
386 }
387 if (intval($favoriteMeta['preview'] ?? 0) > 0)
388 {
389 $unpackFile = $structure->getUnpackFile($favoriteMeta['preview']);
390 if ($unpackFile)
391 {
392 $favoriteMeta['preview'] = AppConfiguration::saveFile($unpackFile);
393 File::addToBlock($blockInstance->getId(), $favoriteMeta['preview']);
394 }
395 if (!$favoriteMeta['preview'])
396 {
397 unset($favoriteMeta['preview']);
398 }
399 }
400 $blockInstance->changeFavoriteMeta($favoriteMeta);
401 \Bitrix\Landing\Block::clearRepositoryCache();
402 }
403 if ($blockFields['CONTENT'] ?? null)
404 {
405 $blockInstance->saveContent($blockFields['CONTENT'], $block['designed'] ?? false);
406 }
407 self::saveDataToBlock($blockInstance, $block);
408 $blockInstance->save();
409 // if block is favorite
410 if (intval($block['meta']['LID'] ?? -1) === 0)
411 {
412 $blockInstance->changeLanding(0);
413 }
414 }
415
416 return $blockId;
417 }
418
424 public static function importLanding(Event $event): ?array
425 {
426 $code = $event->getParameter('CODE');
427 $content = $event->getParameter('CONTENT');
428 $ratio = $event->getParameter('RATIO');
429 $contextUser = $event->getParameter('CONTEXT_USER');
430 $additional = $event->getParameter('ADDITIONAL_OPTION');
431 $appId = $event->getParameter('APP_ID');
432 $isReplaceSiteLandings = ($ratio[$code]['REPLACE_SITE_ID'] ?? 0) > 0;
433 $isMainPage = self::isMainpage($event);
434
435 $structure = new Configuration\Structure($contextUser);
436 $return = [
437 'RATIO' => $ratio[$code] ?? [],
438 'ERROR_MESSAGES' => [],
439 ];
440
441 if (!isset($content['~DATA']))
442 {
443 return null;
444 }
445
446 if (isset($return['RATIO']['TYPE']))
447 {
449 $return['RATIO']['TYPE']
450 );
451 }
452
453 if (!self::isNeedImport($event))
454 {
455 return $return;
456 }
457
458 $data = $content['~DATA'];
459 $oldLid = $data['ID'] ?? null;
460 if (!$oldLid)
461 {
462 return $return;
463 }
464
465 $siteId = null;
466 if (isset($ratio[$code]['SITE_ID']) && (int)$ratio[$code]['SITE_ID'] > 0)
467 {
468 $siteId = (int)$ratio[$code]['SITE_ID'];
469 }
470 elseif ($additional && (int)$additional['siteId'] > 0)
471 {
472 $siteId = (int)$additional['siteId'];
473 $return['RATIO']['SITE_ID'] = (int)$additional['siteId'];
474 }
475
476 if (($additional['siteId'] ?? 0) > 0)
477 {
478 LandingCore::enableCheckUniqueAddress();
479 }
480
481 $data['SITE_ID'] = $siteId;
482 $data = self::prepareData($data);
483 if ($isReplaceSiteLandings && $isMainPage)
484 {
485 $additionalFieldSite = (array)($ratio[$code]['ADDITIONAL_FIELDS_SITE'] ?? []);
486 $data = self::mergeAdditionalFieldsForReplace($data, $additionalFieldSite);
487 $return['RATIO']['ADDITIONAL_FIELDS_SITE'] = $data['ADDITIONAL_FIELDS'];
488 }
489 $return['RATIO']['ADDITIONAL_FIELDS'][$oldLid] = $data['ADDITIONAL_FIELDS'];
490 $data = self::prepareAdditionalFiles($data, $structure);
491
492 // folders' old format
493 $convertFolderOldFormat = false;
494 $return['RATIO']['FOLDERS_REF'] = $return['RATIO']['FOLDERS_REF'] ?? [];
495 if ($data['FOLDER'] === 'Y')
496 {
497 $convertFolderOldFormat = true;
498 $data['FOLDER'] = 'N';
499 $res = SiteCore::addFolder($ratio[$code]['SITE_ID'], [
500 'TITLE' => $data['TITLE'],
501 'CODE' => $data['CODE'],
502 ]);
503 if ($res->isSuccess())
504 {
505 $data['FOLDER_ID'] = $res->getId();
506 $return['RATIO']['FOLDERS_REF'][$oldLid] = $data['FOLDER_ID'];
507 }
508 }
509 elseif ($additional && $additional['folderId'])
510 {
511 $data['FOLDER_ID'] = (int)$additional['folderId'];
512 }
513
514 // set external partners info
515 $appCode = null;
516 if ($appId)
517 {
518 $app = AppTable::getById($appId)->fetch();
519 $appCode = $app['CODE'] ?? null;
520 if ($appCode)
521 {
522 $data['XML_ID'] = $data['TITLE'] . '|' . $appCode;
523 $data['PREVIOUS_TPL_CODE'] = $data['TPL_CODE'];
524 $data['TPL_CODE'] = $appCode;
525 }
526 }
527
528 // base adding
529 $data['ACTIVE'] = 'N';
530 $data['PUBLIC'] = 'N';
531 $data['FOLDER_SKIP_CHECK'] = 'Y';
532 $data['INITIATOR_APP_CODE'] = $appCode;
533 unset($data['CODE']);
534 if ($additional)
535 {
536 $data = self::prepareAdditionalFields($data, $additional, $ratio);
537 }
539 if ($res->isSuccess())
540 {
541 if ($convertFolderOldFormat && ($data['FOLDER_ID'] ?? 0))
542 {
543 Folder::update($data['FOLDER_ID'], ['INDEX_ID' => $res->getId()]);
544 }
545
546 if (isset($data['BLOCKS']) && is_array($data['BLOCKS']))
547 {
548 $data = self::prepareBlocksData($data, $event);
549 }
550
551 self::saveAdditionalFilesToLanding($data, $res->getId());
552
553 $landing = LandingCore::createInstance($res->getId());
554
555 // store old id and other references
556 if ($oldLid)
557 {
558 $return['RATIO']['LANDINGS'][$oldLid] = $res->getId();
559 }
560
561 if (isset($data['TPL_ID']) && $data['TPL_ID'])
562 {
563 $return['RATIO']['TEMPLATE_LINKING'][$res->getId()] = [
564 'TPL_ID' => (int)$data['TPL_ID'],
565 'TEMPLATE_REF' => (array)($data['TEMPLATE_REF'] ?? []),
566 ];
567 }
568 elseif ($isReplaceSiteLandings && $isMainPage && $siteId)
569 {
570 $siteTemplate = (array)($return['RATIO']['TEMPLATE_LINKING'][-1 * $siteId] ?? []);
571 if (!empty($siteTemplate))
572 {
573 $return['RATIO']['TEMPLATE_LINKING'][$res->getId()] = $siteTemplate;
574 unset($return['RATIO']['TEMPLATE_LINKING'][-1 * $siteId]);
575 }
576 }
577
578 if (isset($data['BLOCKS']) && is_array($data['BLOCKS']))
579 {
580 foreach ($data['BLOCKS'] as $oldBlockId => $blockItem)
581 {
582 if (is_array($blockItem))
583 {
584 $pending = false;
585 $newBlockId = self::importBlock(
586 $landing,
587 $blockItem,
588 $structure,
589 $pending
590 );
591 $return['RATIO']['BLOCKS'][$oldBlockId] = $newBlockId;
592 if ($pending)
593 {
594 $return['RATIO']['BLOCKS_PENDING'][] = $newBlockId;
595 }
596 }
597 }
598 }
599 }
600 else
601 {
602 $return['ERROR_MESSAGES'] = $res->getErrorMessages();
603 }
604
605 return $return;
606 }
607
613 public static function replaceLanding(Event $event): ?array
614 {
615 $code = $event->getParameter('CODE');
616 $content = $event->getParameter('CONTENT');
617 $ratio = $event->getParameter('RATIO');
618 $contextUser = $event->getParameter('CONTEXT_USER');
619 $structure = new Configuration\Structure($contextUser);
620
621 if (!isset($content['~DATA']))
622 {
623 return null;
624 }
625
626 $return = [
627 'RATIO' => $ratio[$code] ?? [],
628 'ERROR_MESSAGES' => [],
629 ];
630
631 if (
632 !isset($ratio[$code]['REPLACE_LID'])
633 || (int)$ratio[$code]['REPLACE_LID'] <= 0
634 )
635 {
636 $return['ERROR_MESSAGES'] = 'Not set landing ID for replace';
637
638 return $return;
639 }
640 $replaceLid = (int)$ratio[$code]['REPLACE_LID'];
641
642 if (isset($return['RATIO']['TYPE']))
643 {
644 SiteCore\Type::setScope($return['RATIO']['TYPE']);
645 }
646 LandingCore::setEditMode();
647 $landing = LandingCore::createInstance($replaceLid);
648 if (!$landing->exist())
649 {
650 $return['ERROR_MESSAGES'] = 'Raplaced landing is not exists';
651
652 return $return;
653 }
654
655 // no landing imported
656 $return['RATIO']['LANDINGS'][$replaceLid] = $replaceLid;
657
658 if (!self::isNeedImport($event))
659 {
660 return $return;
661 }
662
663 $data = $content['~DATA'];
664 $data = self::prepareData($data);
665
666 $additionalFieldsBefore = self::getAdditionalFieldsForReplaceByLanding($replaceLid);
667 if (is_array($ratio[$code]['ADDITIONAL_FIELDS_SITE']) && !empty($ratio[$code]['ADDITIONAL_FIELDS_SITE']))
668 {
669 $data = self::mergeAdditionalFieldsForReplace($data, $ratio[$code]['ADDITIONAL_FIELDS_SITE']);
670 $data = self::prepareAdditionalFiles($data, $structure);
671 self::saveAdditionalFieldsToLanding($data, $replaceLid);
672 self::saveAdditionalFilesToLanding($data, $replaceLid);
673 }
674
675 if (isset($data['BLOCKS']) && is_array($data['BLOCKS']))
676 {
677 $data = self::prepareBlocksData($data, $event);
678 $blocksBefore = [];
679 $blocksAfter = [];
680
681 History::deactivate();
682 foreach ($landing->getBlocks() as $block)
683 {
684 $blockId = $block->getId();
685 $block->setAccess(Block::ACCESS_X);
686 if ($landing->markDeletedBlock($block->getId(), true))
687 {
688 $blocksBefore[] = $blockId;
689 }
690 }
691
692 foreach ($data['BLOCKS'] as $oldBlockId => $block)
693 {
694 if (is_array($block) && !empty($block))
695 {
696 $pending = false;
697 $newBlockId = self::importBlock(
698 $landing,
699 $block,
700 $structure,
701 $pending
702 );
703 $blocksAfter[] = $newBlockId;
704 $return['RATIO']['BLOCKS'][$oldBlockId] = $newBlockId;
705 if ($pending)
706 {
707 $return['RATIO']['BLOCKS_PENDING'][] = $newBlockId;
708 }
709 }
710 }
711
712 // find form block and replace form ID if need
713 $meta = $landing->getMeta();
714 $isCrmFormSite = null;
715 if ($meta['SITE_SPECIAL'] === 'Y')
716 {
717 $isCrmFormSite =
719 }
720 if ($isCrmFormSite && Loader::includeModule('crm'))
721 {
722 // find form
723 $res = Crm\WebForm\Internals\LandingTable::getList([
724 'select' => [
725 'FORM_ID',
726 ],
727 'filter' => [
728 '=LANDING_ID' => $replaceLid,
729 ],
730 ]);
731 $row = $res->fetch();
732 $formId = $row ? $row['FORM_ID'] : null;
733 if ($formId)
734 {
735 foreach ($landing->getBlocks() as $block)
736 {
737 $manifest = $block->getManifest();
738 if (($manifest['block']['subtype'] ?? null) === 'form')
739 {
740 Form::setFormIdToBlock($block->getId(), $formId);
741 if ($block->getAccess() > Block::ACCESS_W)
742 {
743 BlockTable::update($block->getId(), [
744 'ACCESS' => Block::ACCESS_W,
745 ]);
746 }
747 }
748 }
749 }
750 }
751
753 {
754 $landing->publication();
755 }
756
757 History::activate();
758 $history = new History($replaceLid, History::ENTITY_TYPE_LANDING);
759 $history->push('REPLACE_LANDING', [
760 'lid' => $replaceLid,
761 'template' => $code,
762 'blocksBefore' => $blocksBefore,
763 'blocksAfter' => $blocksAfter,
764 'additionalFieldsBefore' => $additionalFieldsBefore,
765 'additionalFieldsAfter' => $data['ADDITIONAL_FIELDS'],
766 ]);
767 }
768
769 return $return;
770 }
771
777 protected static function isNeedImport(Event $event): bool
778 {
779 $code = $event->getParameter('CODE');
780 $content = $event->getParameter('CONTENT');
781 $ratio = $event->getParameter('RATIO');
782
783 if (($ratio[$code]['REPLACE_SITE_ID'] ?? 0) > 0)
784 {
785 return true;
786 }
787
788 if (
789 $ratio[$code]['IS_PAGE_IMPORT']
790 && isset($ratio[$code]['SPECIAL_PAGES']['LANDING_ID_INDEX'])
791 && (int)$content['DATA']['ID'] !== $ratio[$code]['SPECIAL_PAGES']['LANDING_ID_INDEX']
792 )
793 {
794 return false;
795 }
796
797 return true;
798 }
799
805 protected static function isMainpage(Event $event): bool
806 {
807 $code = $event->getParameter('CODE');
808 $content = $event->getParameter('CONTENT');
809 $ratio = $event->getParameter('RATIO');
810
811 return
812 isset($ratio[$code]['SPECIAL_PAGES']['LANDING_ID_INDEX'])
813 && (int)$content['DATA']['ID'] === $ratio[$code]['SPECIAL_PAGES']['LANDING_ID_INDEX']
814 ;
815 }
816
817 protected static function prepareData(array $data): array
818 {
819 // clear old keys
820 $notAllowedKeys = [
821 'ID', 'VIEWS', 'DATE_CREATE', 'DATE_MODIFY',
822 'DATE_PUBLIC', 'CREATED_BY_ID', 'MODIFIED_BY_ID',
823 ];
824 foreach ($notAllowedKeys as $key)
825 {
826 if (isset($data[$key]))
827 {
828 unset($data[$key]);
829 }
830 }
831
832 return $data;
833 }
834
835 protected static function prepareBlocksData(array $data, Event $event): array
836 {
837 $data = self::fixWrapperClasses($data);
838 $data = self::deleteCopyrightBlock($data, $event);
839 $data = self::fixContactDataAndCountdown($data);
840
841 self::enableHiddenBlocksForCreatingPage();
842
843 return $data;
844 }
845
850 protected static function enableHiddenBlocksForCreatingPage(): void
851 {
852 $eventManager = EventManager::getInstance();
853 $eventManager->addEventHandler('landing', 'onBlockRepoSetFilters',
854 function(Event $event)
855 {
856 $result = new Entity\EventResult();
857 $result->modifyFields([
858 'DISABLE' => Block\BlockRepo::FILTER_SKIP_HIDDEN_BLOCKS,
859 ]);
860
861 return $result;
862 }
863 );
864 }
865
872 protected static function prepareAdditionalFiles(array $data, Configuration\Structure $structure): array
873 {
874 foreach (Hook::HOOKS_CODES_FILES as $hookCode)
875 {
876 if (
877 isset($data['ADDITIONAL_FIELDS'][$hookCode]) &&
878 $data['ADDITIONAL_FIELDS'][$hookCode] > 0
879 )
880 {
881 $unpackFile = $structure->getUnpackFile($data['ADDITIONAL_FIELDS'][$hookCode]);
882
883 if ($unpackFile)
884 {
885 $data['ADDITIONAL_FIELDS'][$hookCode] = AppConfiguration::saveFile(
886 $unpackFile
887 );
888 }
889 else
890 {
891 unset($data['ADDITIONAL_FIELDS'][$hookCode]);
892 }
893 }
894 }
895
896 return $data;
897 }
898
905 protected static function saveAdditionalFilesToLanding(array $data, $landingId): void
906 {
907 foreach (Hook::HOOKS_CODES_FILES as $hookCode)
908 {
909 if (
910 isset($data['ADDITIONAL_FIELDS'][$hookCode]) &&
911 $data['ADDITIONAL_FIELDS'][$hookCode] > 0
912 )
913 {
914 File::addToLanding($landingId, $data['ADDITIONAL_FIELDS'][$hookCode]);
915 }
916 }
917 }
918
926 protected static function prepareAdditionalFields(array $data, array $additional, array $ratio = null): array
927 {
928 $data['ADDITIONAL_FIELDS']['THEME_USE'] = 'N';
929 if (isset($additional['theme']) || isset($additional['theme_use_site']))
930 {
931 $color = $additional['theme_use_site'] ?? $additional['theme'];
932 if ($color[0] !== '#')
933 {
934 $color = '#'.$color;
935 }
936 $data['ADDITIONAL_FIELDS']['THEME_COLOR'] = $color;
937 unset($data['ADDITIONAL_FIELDS']['THEME_CODE']);
938
939 // for variant if import only page in existing site
940 $isSinglePage = !is_array($ratio) || empty($ratio);
941 if ($isSinglePage && !$additional['theme_use_site'])
942 {
943 $data['ADDITIONAL_FIELDS']['THEME_USE'] = 'Y';
944 }
945 }
946
947 // todo: move to isMainpage (need pass event)?
948 $isMainpage = false;
949 if ($additional['title'] && $isMainpage)
950 {
951 $data['ADDITIONAL_FIELDS']['METAOG_TITLE'] = $additional['title'];
952 $data['ADDITIONAL_FIELDS']['METAMAIN_TITLE'] = $additional['title'];
953 }
954
955 if ($additional['description'] && $isMainpage)
956 {
957 $data['ADDITIONAL_FIELDS']['METAOG_DESCRIPTION'] = $additional['description'];
958 $data['ADDITIONAL_FIELDS']['METAMAIN_DESCRIPTION'] = $additional['description'];
959 }
960
961 //default widget value
963 $buttonKeys = array_keys($buttons);
964 if (!empty($buttonKeys))
965 {
966 $data['ADDITIONAL_FIELDS']['B24BUTTON_CODE'] = $buttonKeys[0];
967 }
968 else
969 {
970 $data['ADDITIONAL_FIELDS']['B24BUTTON_CODE'] = 'N';
971 }
972 $data['ADDITIONAL_FIELDS']['B24BUTTON_USE'] = 'N';
973
974 return $data;
975 }
976
982 protected static function getAdditionalFieldsForReplaceByLanding(int $lid): array
983 {
984 $additionalFields = [];
985 $hooks = Hook::getData($lid, Hook::ENTITY_TYPE_LANDING);
986 foreach ($hooks as $hook => $fields)
987 {
988 foreach ($fields as $code => $field)
989 {
990 $additionalFields[$hook . '_' . $code] = $field;
991 }
992 }
993
994 return self::getAdditionalFieldsForReplace($additionalFields);
995 }
996
1003 {
1004 $additionalFields = [];
1005 $hooks = Hook::getData($siteId, Hook::ENTITY_TYPE_SITE);
1006 foreach ($hooks as $hook => $fields)
1007 {
1008 foreach ($fields as $code => $field)
1009 {
1010 $additionalFields[$hook . '_' . $code] = $field;
1011 }
1012 }
1013
1014 return self::getAdditionalFieldsForReplace($additionalFields);
1015 }
1016
1017
1024 protected static function mergeAdditionalFieldsForReplace(array $data, array $additionalFieldsSite): array
1025 {
1026 $additionalFields = $data['ADDITIONAL_FIELDS'] ?? [];
1027 foreach (self::getAdditionalFieldsForReplace($additionalFieldsSite) as $code => $field)
1028 {
1029 if (!isset($additionalFields[$code]))
1030 {
1031 $additionalFields[$code] = $field;
1032 }
1033 }
1034 $data['ADDITIONAL_FIELDS'] = $additionalFields;
1035
1036 return $data;
1037 }
1038
1044 protected static function getAdditionalFieldsForReplace(array $additionalFields): array
1045 {
1046 $result = [];
1047 foreach (Hook::HOOKS_CODES_DESIGN as $hookCode)
1048 {
1049 $result[$hookCode] = $additionalFields[$hookCode] ?? '';
1050 }
1051
1052 return $result;
1053 }
1054
1055 protected static function saveAdditionalFieldsToLanding(array $data, int $landingId): void
1056 {
1057 if (is_array($data['ADDITIONAL_FIELDS']) && !empty($data['ADDITIONAL_FIELDS']))
1058 {
1059 LandingCore::saveAdditionalFields($landingId, $data['ADDITIONAL_FIELDS']);
1060 }
1061 }
1062
1063 protected static function fixWrapperClasses(array $data): array
1064 {
1065 // @fix wrapper classes from original
1066 $appCode = $data['INITIATOR_APP_CODE'];
1067 $newTplCode = $data['PREVIOUS_TPL_CODE'] ?? $data['TPL_CODE'];
1068 $delobotAppCode = 'local.5eea949386cd05.00160385';
1069 $kraytAppCode = 'local.5f11a19f813b13.97126836';
1070 $bitrixAppCode = 'bitrix.';
1071 if (
1072 strpos($newTplCode, $delobotAppCode) !== false
1073 || strpos($newTplCode, $kraytAppCode) !== false
1074 || strpos($appCode, $bitrixAppCode) === 0
1075 )
1076 {
1077 $wrapperClasses = [];
1078 $http = new \Bitrix\Main\Web\HttpClient;
1079 $resPreview = $http->get(Manager::getPreviewHost() . '/tools/blocks.php?tplCode=' . $newTplCode);
1080 if ($resPreview)
1081 {
1082 try
1083 {
1084 $wrapperClasses = \Bitrix\Main\Web\Json::decode($resPreview);
1085 }
1086 catch (\Exception $e){}
1087 }
1088
1089 if ($wrapperClasses)
1090 {
1091 $i = 0;
1092 foreach ($data['BLOCKS'] as &$blockData)
1093 {
1094 if (isset($wrapperClasses[$i]) && $wrapperClasses[$i]['code'] === $blockData['code'])
1095 {
1096 $blockData['style']['#wrapper'] = ['classList' => [$wrapperClasses[$i]['classList']]];
1097 }
1098 $i++;
1099 }
1100 unset($blockData);
1101 }
1102 }
1103 unset($delobotAppCode, $kraytAppCode);
1104
1105 return $data;
1106 }
1107
1108 protected static function deleteCopyrightBlock(array $data, Event $event): array
1109 {
1110 //fix, delete copyright block
1111 $appCode = $data['INITIATOR_APP_CODE'];
1112 $content = $event->getParameter('CONTENT');
1113 $templateDateCreate = strtotime($content['DATA']['DATE_CREATE']);
1114 $lastDate = strtotime('17.02.2022 00:00:00');
1115 if ($templateDateCreate < $lastDate)
1116 {
1117 $kraytCode = 'bitrix.krayt';
1118 $delobotCode = 'bitrix.delobot';
1119 if (strpos($appCode, $kraytCode) !== false || strpos($appCode, $delobotCode) !== false)
1120 {
1121 if (array_slice($data['BLOCKS'], -1)[0]['code'] === '17.copyright')
1122 {
1123 array_pop($data['BLOCKS']);
1124 }
1125 }
1126 unset($kraytCode, $delobotCode);
1127 }
1128
1129 return $data;
1130 }
1131
1132 protected static function fixContactDataAndCountdown(array $data): array
1133 {
1134 $appCode = $data['INITIATOR_APP_CODE'];
1135 $bitrixAppCode = 'bitrix.';
1136
1137 foreach ($data['BLOCKS'] as &$block)
1138 {
1139 //fix contact data
1140 if (isset($block['nodes']) && strpos($appCode, $bitrixAppCode) === 0)
1141 {
1142 foreach ($block['nodes'] as &$node)
1143 {
1144 $countNodeItem = 0;
1145 foreach ($node as &$nodeItem)
1146 {
1147 if (isset($nodeItem['href']))
1148 {
1149 $setContactsBlockCode = [
1150 '14.1.contacts_4_cols',
1151 '14.2contacts_3_cols',
1152 '14.3contacts_2_cols',
1153 ];
1154 if (preg_match('/^tel:.*$/i', $nodeItem['href']))
1155 {
1156 $nodeItem['href'] = 'tel:#crmPhone1';
1157 if (isset($nodeItem['text']))
1158 {
1159 $nodeItem['text'] = '#crmPhoneTitle1';
1160 }
1161 if (
1162 (isset($block['nodes']['.landing-block-node-linkcontact-text'])
1163 && in_array($block['code'], $setContactsBlockCode, true))
1164 )
1165 {
1166 $block['nodes']['.landing-block-node-linkcontact-text'][$countNodeItem] = '#crmPhoneTitle1';
1167 }
1168 }
1169 if (preg_match('/^mailto:.*$/i', $nodeItem['href']))
1170 {
1171 $nodeItem['href'] = 'mailto:#crmEmail1';
1172 if (isset($nodeItem['text']))
1173 {
1174 $nodeItem['text'] = '#crmEmailTitle1';
1175 }
1176 if (
1177 isset($block['nodes']['.landing-block-node-linkcontact-text'])
1178 && (in_array($block['code'], $setContactsBlockCode, true))
1179 )
1180 {
1181 $block['nodes']['.landing-block-node-linkcontact-text'][$countNodeItem] = '#crmEmailTitle1';
1182 }
1183 }
1184 }
1185 $countNodeItem++;
1186 }
1187 unset($nodeItem);
1188 }
1189 unset($node);
1190 }
1191 //fix countdown until the next unexpired date
1192 if (isset($block['attrs']))
1193 {
1194 foreach ($block['attrs'] as &$attr)
1195 {
1196 foreach ($attr as &$attrItem)
1197 {
1198 if (array_key_exists('data-end-date', $attrItem))
1199 {
1200 $neededAttr = $attrItem['data-end-date'] / 1000;
1201 $currenDate = time();
1202 if ($neededAttr < $currenDate)
1203 {
1204 $m = date('m', $neededAttr);
1205 $d = date('d', $neededAttr);
1206 $currenDateY = (int)date('Y', $currenDate);
1207 $currenDateM = date('m', $currenDate);
1208 $currenDateD = date('d', $currenDate);
1209 if ($currenDateM > $m)
1210 {
1211 $y = $currenDateY + 1;
1212 }
1213 else if (($currenDateM === $m) && $currenDateD >= $d)
1214 {
1215 $y = $currenDateY + 1;
1216 }
1217 else
1218 {
1219 $y = $currenDateY;
1220 }
1221 $time = '10:00:00';
1222 $timestamp = strtotime($y . '-' . $m . '-' . $d . ' ' . $time) * 1000;
1223 $attrItem['data-end-date'] = (string)$timestamp;
1224
1225 if (preg_match_all(
1226 '/data-end-date="\d+"/',
1227 $block['full_content'],
1228 $matches)
1229 )
1230 {
1231 $block['full_content'] = str_replace(
1232 $matches[0],
1233 'data-end-date="' . $attrItem['data-end-date'] . '"',
1234 $block['full_content']
1235 );
1236 }
1237 }
1238 }
1239 }
1240 unset($attrItem);
1241 }
1242 unset($attr);
1243 }
1244 }
1245 unset($block);
1246
1247 return $data;
1248 }
1249}
setClasses($data)
Определения block.php:4355
getId()
Определения block.php:1376
setAttributes($data)
Определения block.php:4593
updateNodes($data, $additional=array())
Определения block.php:3935
saveDynamicParams(array $sourceParams=[], array $params=[])
Определения block.php:2964
getManifest(bool $extended=false, bool $missCache=false, array $params=array())
Определения block.php:1682
updateCards(array $data=array())
Определения block.php:4205
static getAnchor($id)
Определения block.php:1282
static addToLanding($lid, $fileId)
Определения file.php:266
static addToBlock(int $blockId, $fileId, bool $temp=false)
Определения file.php:305
static getFilePath($fileId)
Определения file.php:600
static getButtons()
Определения b24button.php:40
static saveAdditionalFields(Entity\Event $event)
Определения site.php:1329
static getPreviewHost()
Определения manager.php:1105
static isAutoPublicationEnabled()
Определения manager.php:442
static getAppByCode($code)
Определения repo.php:302
static add($fields)
Определения repo.php:21
static getSiteSpecialType(string $siteCode)
Определения type.php:72
static setScope($scope, array $params=[])
Определения type.php:88
const PSEUDO_SCOPE_CODE_FORMS
Определения type.php:29
static setFormIdToBlock(int $blockId, int $formId)
Определения form.php:706
static saveFile(array $file)
Определения appconfiguration.php:311
static fixContactDataAndCountdown(array $data)
Определения landing.php:1132
static getAdditionalFieldsForReplaceBySite(int $siteId)
Определения landing.php:1002
static addFilesToBlock(Block $block, array $data, Configuration\Structure $structure, bool $ignoreManifest=false)
Определения landing.php:86
static mergeAdditionalFieldsForReplace(array $data, array $additionalFieldsSite)
Определения landing.php:1024
static deleteCopyrightBlock(array $data, Event $event)
Определения landing.php:1108
static fixWrapperClasses(array $data)
Определения landing.php:1063
static prepareBlocksData(array $data, Event $event)
Определения landing.php:835
static setForceAppendRestBlocks(bool $mode)
Определения landing.php:41
static $forceAppendRestBlocks
Определения landing.php:34
static saveDataToBlock(Block $blockInstance, array $block)
Определения landing.php:145
static isNeedImport(Event $event)
Определения landing.php:777
static replaceLanding(Event $event)
Определения landing.php:613
static importLanding(Event $event)
Определения landing.php:424
static saveAdditionalFieldsToLanding(array $data, int $landingId)
Определения landing.php:1055
static prepareAdditionalFields(array $data, array $additional, array $ratio=null)
Определения landing.php:926
static enableHiddenBlocksForCreatingPage()
Определения landing.php:850
static getAdditionalFieldsForReplaceByLanding(int $lid)
Определения landing.php:982
static saveAdditionalFilesToLanding(array $data, $landingId)
Определения landing.php:905
static prepareAdditionalFiles(array $data, Configuration\Structure $structure)
Определения landing.php:872
static getRepoId(string $appCode, string $xmlId)
Определения landing.php:52
static isMainpage(Event $event)
Определения landing.php:805
static importBlock(LandingCore $landing, array $block, Configuration\Structure $structure, bool &$pending=false)
Определения landing.php:241
static prepareData(array $data)
Определения landing.php:817
static getAdditionalFieldsForReplace(array $additionalFields)
Определения landing.php:1044
Определения event.php:5
Определения loader.php:13
static decode($data)
Определения json.php:50
$content
Определения commerceml.php:144
$data['IS_AVAILABLE']
Определения .description.php:13
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$res
Определения filter_act.php:7
$result
Определения get_property_values.php:14
$app
Определения proxy.php:8
if(!is_null($config))($config as $configItem)(! $configItem->isVisible()) $code
Определения options.php:195
$siteId
Определения ajax.php:8
Определения agent.php:3
Определения ufield.php:9
$time
Определения payment.php:61
$event
Определения prolog_after.php:141
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
if(empty($signedUserToken)) $key
Определения quickway.php:257
$i
Определения factura.php:643
$items
Определения template.php:224
$matches
Определения index.php:22
$eventManager
Определения include.php:412
$fields
Определения yandex_run.php:501