1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
TaskCreateBlocks.php
См. документацию.
1<?php
2declare(strict_types=1);
3
4namespace Bitrix\Landing\Copilot\Generation\Step;
5
6use Bitrix\Landing\Copilot\Connector;
7use Bitrix\Landing\Copilot\Generation\GenerationException;
8use Bitrix\Landing\Copilot\Generation\PromptGenerator;
9use Bitrix\Landing\Copilot\Generation\PromptTemplateProvider;
10use Bitrix\Landing\Copilot\Generation\Request;
11use Bitrix\Landing\Copilot\Generation\Type\GenerationErrors;
12use Bitrix\Landing\Copilot\Data\Block\Collector;
13use Bitrix\Landing\Copilot\Data;
14use Bitrix\Landing\Copilot\Model\RequestToEntitiesTable;
15use Bitrix\Landing\Landing;
16use Bitrix\Landing\PublicAction\Block;
17use Bitrix\Landing\Site;
18use Bitrix\Landing\Rights;
19use Bitrix\Landing\Metrika;
20
22{
28 private const DEFAULT_PADDING = '50';
29
35 private const TITLE_PADDING_BOTTOM = '15';
36
42 private const BLOCK_AFTER_TITLE_PADDING_TOP = '15';
43
44 private const EVENT_NAME = 'onBlocksCreated';
45
52
58 protected int $landingId;
59
65 public function execute(): bool
66 {
67 parent::execute();
68
70 $this->landingInstance = $this->siteData->getLandingInstance();
71 $this->landingId = $this->landingInstance->getId();
72 $this->addBlocks();
73
74 $metrika = new Metrika\Metrika(
75 Metrika\Categories::Site,
76 Metrika\Events::createTemplate,
77 );
78 $siteId = $this->siteData->getSiteId() ?? 0;
79 $metrika->setType(Metrika\Types::ai)
80 ->setParam(3, 'siteId', (string)$siteId)
81 ->send()
82 ;
83
84 $metrikaParams = new Metrika\FieldsDto(
85 subSection: 'from_ai',
86 element: 'auto',
87 );
88 Site::publication($this->landingInstance->getSiteId(), true, $metrikaParams);
90
91 $this->updateRequestEntityInTable();
92
93 $this->sendMessage();
94
95 return true;
96 }
97
103 public function isFinished(): bool
104 {
105 foreach ($this->siteData->getBlocks() as $block)
106 {
107 if ($block->getId() === 0)
108 {
109 throw new GenerationException(
110 GenerationErrors::dataValidation,
111 "Block not exist correct id.",
112 );
113 }
114 }
115
116 return true;
117 }
118
124 protected function sendMessage(): void
125 {
126 $this->generation->getScenario()?->getChatbot()?->sendGenerationEndMessage(
127 new Connector\Chat\ChatBotMessageDto($this->generation->getChatId(), $this->generation->getId())
128 );
129 }
130
136 protected function addBlocks(): void
137 {
138 foreach ($this->siteData->getBlocks() as $block)
139 {
140 $this->addBlock($block);
141 }
142 $this->configureMenuBlock();
143
144 $this->getEvent()->send(self::EVENT_NAME);
145 }
146
153 protected function configureMenuBlock(): void
154 {
155 $menuBlock = $this->siteData->getMenuBlock();
156
157 if (!$menuBlock)
158 {
159 return;
160 }
161
162 $blockInstance = $this->landingInstance->getBlockById($menuBlock->getId());
163
164 if (!$blockInstance)
165 {
166 return;
167 }
168
169 $linkItemsNodeCode = Collector::getMenuItemsNodeCode($menuBlock->getCode());
170 $linkCardsNodeCode = Collector::getMenuCardsNodeCode($menuBlock->getCode());
171 $blockInstance->updateCards($this->getMenuCardsData($linkItemsNodeCode, $linkCardsNodeCode));
172 $blockInstance->save();
173 }
174
182 private function addBlock(Data\Block $blockData): void
183 {
184 $blockCode = $blockData->getCode();
185
186 if ($blockCode)
187 {
188 $blockId = $this->landingInstance->addBlock($blockCode, [
189 'SORT' => 0,
190 'PUBLIC' => 'N',
191 ]);
192 $blockInstance = $this->landingInstance->getBlockById($blockId);
193 $blockData->setId($blockId);
194
195 $blockNodes = $blockData->getNodes();
196 if ($blockInstance)
197 {
198 if ($blockNodes)
199 {
200 $nodesArray = [];
201 foreach ($blockNodes as $blockNode)
202 {
203 $code = $blockNode->getCode();
204 $nodesArray[$code] = $blockNode->getValues();
205 }
206 $blockInstance->updateNodes($nodesArray);
207 $blockInstance->save();
208 }
209
210 $wrapperSelectorClasses = explode(" ", Data\Block\Operator::extractWrapperClasses($blockInstance->getContent()));
211 $blockData->setWrapperClasses($wrapperSelectorClasses);
212
213 $this->updateBlockStyles($blockInstance, $blockData);
214 }
215 }
216 }
217
226 private function getMenuCardsData(string $nodeCode, string $cardCode): array
227 {
228 $blocks = $this->siteData->getBlocks();
229 $menuData = [];
230 $count = 0;
231 foreach ($blocks as $block)
232 {
233 $blockMenuTitle = $block->getMenuTitle();
234 if ($blockMenuTitle)
235 {
236 $menuData['source'][] = [
237 'value' => (string)$count,
238 'type' => 'card',
239 ];
240 $codeKey = sprintf('%s@%d', $nodeCode, $count);
241 $menuDataItem = [
242 $codeKey => [
243 'text' => $blockMenuTitle,
244 'href' => sprintf('block:#block%d', $block->getId()),
245 'target' => '_self',
246 ],
247 ];
248 $menuData['values'][] = $menuDataItem;
249 $count++;
250 }
251 }
252
253 return [$cardCode => $menuData];
254 }
255
264 private function updateBlockStyles(\Bitrix\Landing\Block $blockInstance, Data\Block $blockData): void
265 {
266 $this->updateStylesForBlockWithSpecificSection($blockInstance, $blockData);
267
268 //background styles
269 $this->updateBackgroundColorForWrapperNode($blockInstance, $blockData);
270 $this->updateImageNodesEditingInStyle($blockInstance, $blockData);
271
272 //color styles for nodes in block with 'primary' bg type
273 $this->updateColorStylesForNodesAtBlockWithPrimaryBgType($blockInstance, $blockData);
274
275 //by properties
276 $this->updatePaddingStyles($blockInstance, $blockData);
277 $this->updateTitleStyles($blockInstance, $blockData);
278 }
279
288 private function updateTitleStyles(\Bitrix\Landing\Block $blockInstance, Data\Block $blockData): void
289 {
290 $titleNodes = Collector::getTitleNodes($blockData->getCode());
291 if (count($titleNodes) > 0)
292 {
293 $selector = $titleNodes[0];
294 $classList = [];
295 if (
296 preg_match(
297 '/class="([^"]*' . substr($selector, 1) . '[^"]*)"/',
298 $blockInstance->getContent(),
300 )
301 )
302 {
303 $classList = explode(" ", $matches[1]);
304 }
305
306 $filteredClassList = array_filter($classList, static function($className) {
307 return !str_starts_with($className, 'u-heading-v2-');
308 });
309 $filteredClassList = array_values($filteredClassList);
310 $filteredClassList[] = $this->siteData->getTitleStyleClass();
311
312 $styles = [
313 $selector => [
314 'classList' => $filteredClassList,
315 ],
316 ];
317
318 Block::updateStyles($this->landingId, $blockInstance->getId(), $styles, true);
319 }
320 }
321
330 private function updateStylesForBlockWithSpecificSection(
331 \Bitrix\Landing\Block $blockInstance,
332 Data\Block $blockData
333 ): void
334 {
335 if ($blockData->isSeparator())
336 {
337 $this->updateSeparatorStyles($blockInstance, $blockData);
338 }
339 elseif ($blockData->isMenu())
340 {
341 $this->updateMenuStyles($blockInstance, $blockData);
342 }
343 }
344
355 private function updateBackgroundColorForWrapperNode(
356 \Bitrix\Landing\Block $blockInstance,
357 Data\Block $blockData
358 ): void
359 {
360 $bgType = $blockData->getBgType();
361 if ($bgType === 'primary' || $bgType === 'transparent')
362 {
363 $wrapperSelector = '#block' . $blockInstance->getId();
364 $this->updateBackgroundColorStyles($blockInstance, $blockData, $wrapperSelector);
365 }
366 }
367
376 private function updateImageNodesEditingInStyle(\Bitrix\Landing\Block $blockInstance, Data\Block $blockData): void
377 {
378 foreach ($blockData->getNodes() as $node)
379 {
380 if (
381 $node->getType() === Data\Type\NodeType::Img
382 && method_exists($node, 'isEditInStyle')
383 && $node->isEditInStyle()
384 )
385 {
386 $values = $node->getValues();
387 if (!empty($values))
388 {
389 $firstValue = array_shift($values);
390 if (isset($firstValue['src']))
391 {
392 $this->updateBackgroundImageStyles(
393 $blockInstance,
394 $blockData,
395 $node->getCode(),
396 $firstValue['src']
397 );
398 }
399 }
400 }
401 }
402 }
403
412 private function updateSeparatorStyles(\Bitrix\Landing\Block $blockInstance, Data\Block $blockData): void
413 {
414 $selector = '#block' . $blockInstance->getId();
415 $selectorClasses = $blockData->getWrapperClasses();
416 $bgType = $blockData->getBgType();
417 $firstColor = '';
418 $secondColor = '';
419 if ($bgType === 'primaryToTransparent')
420 {
421 $firstColor = 'var(--primary)';
422 $secondColor = 'hsla(0, 0%, 100%, 0)';
423 }
424 if ($bgType === 'transparentToPrimary')
425 {
426 $firstColor = 'hsla(0, 0%, 100%, 0)';
427 $secondColor = 'var(--primary)';
428 }
429
430 $separatorsHeight = Collector::getSeparatorsHeight();
431 $code = $blockData->getCode();
432 if (isset($separatorsHeight[$code]['heightClass']))
433 {
434 $filteredClasses = array_filter($selectorClasses, static function($class) {
435 return !preg_match('/g-height-\d+--md/', $class);
436 });
437 $selectorClasses = array_values($filteredClasses);
438 $selectorClasses[] = $separatorsHeight[$code]['heightClass'];
439 }
440
441 $styles = [
442 $selector => [
443 'style' => [
444 '--fill-first' => $firstColor,
445 '--fill-second' => $secondColor,
446 ],
447 'classList' => $selectorClasses,
448 ],
449 ];
450 $blockData->setWrapperClasses($selectorClasses);
451
452 Block::updateStyles($this->landingId, $blockInstance->getId(), $styles, true);
453 }
454
465 private function updateBackgroundImageStyles(
466 \Bitrix\Landing\Block $blockInstance,
467 Data\Block $blockData,
468 string $selector,
469 string $imageBackgroundLink = ''
470 ): void
471 {
472 $isWrapper = false;
473 $preparedSelectorClasses = [];
474
475 if (
476 str_starts_with($selector, '.')
477 && in_array(substr($selector, 1), $blockData->getWrapperClasses(), true)
478 )
479 {
480 $isWrapper = true;
481 }
482 if ($isWrapper)
483 {
484 $selector = '#block' . $blockInstance->getId();
485 $selectorClasses = $blockData->getWrapperClasses();
486 }
487 else
488 {
489 $blockContent = $blockInstance->getContent();
490 $selectorClasses = explode(' ', Data\Block\Operator::extractNodeClasses($selector, $blockContent));
491 }
492 $selectorClasses[] = 'g-bg-image';
493 $url = 'url("' . $imageBackgroundLink . '")';
494 $wrapperStyle = [
495 'background-image' => '',
496 '--bg-url' => $url,
497 '--bg-url-2x' => $url,
498 '--bg-overlay' => 'hsla(0, 0%, 0%, 0.5)',
499 '--bg-size' => 'cover',
500 '--bg-attachment' => 'scroll',
501 ];
502 foreach ($selectorClasses as $class)
503 {
504 if (
505 $class === 'g-bg-image'
506 || (!str_starts_with($class, 'g-bg') && !str_starts_with($class, 'g-theme-'))
507 )
508 {
509 $preparedSelectorClasses[] = $class;
510 }
511 }
512
513 $styles = [
514 $selector => [
515 'style' => $wrapperStyle,
516 'classList' => $preparedSelectorClasses,
517 ],
518 ];
519 if ($isWrapper)
520 {
521 $blockData->setWrapperClasses($preparedSelectorClasses);
522 }
523
524 Block::updateStyles($this->landingId, $blockInstance->getId(), $styles, true);
525 }
526
536 private function updateBackgroundColorStyles(
537 \Bitrix\Landing\Block $blockInstance,
538 Data\Block $blockData,
539 string $selector,
540 ): void
541 {
542 $preparedSelectorClasses = [];
543 $selectorClasses = $blockData->getWrapperClasses();
544 $selectorClasses[] = 'g-bg';
545 $bgType = $blockData->getBgType();
546 $bgStyle = '';
547 if ($bgType === 'transparent')
548 {
549 $bgStyle = 'hsla(0, 0%, 100%, 0)';
550 }
551 if ($bgType === 'primary')
552 {
553 $bgStyle = 'var(--primary)';
554 }
555 $wrapperStyle = [
556 '--bg' => $bgStyle,
557 ];
558 foreach ($selectorClasses as $class)
559 {
560 if (
561 $class === 'g-bg'
562 || (!str_starts_with($class, 'g-bg-') && !str_starts_with($class, 'g-theme-'))
563 )
564 {
565 $preparedSelectorClasses[] = $class;
566 }
567 }
568
569 $styles = [
570 $selector => [
571 'style' => $wrapperStyle,
572 'classList' => $preparedSelectorClasses,
573 ],
574 ];
575
576 $blockData->setWrapperClasses($preparedSelectorClasses);
577
578 Block::updateStyles($this->landingId, $blockInstance->getId(), $styles, true);
579 }
580
589 private function updatePaddingStyles(\Bitrix\Landing\Block $blockInstance, Data\Block $blockData): void
590 {
591 $selectorClasses = $blockData->getWrapperClasses();
592 $bgType = $blockData->getBgType();
593 if (
594 $bgType !== 'image'
595 && !$blockData->isMenu()
596 && !$blockData->isSeparator()
597 && !$blockData->isCover()
598 )
599 {
600 $filteredClasses = array_filter($selectorClasses, static function($class) {
601 return !preg_match('/g-(pb|pt)-\d+/', $class);
602 });
603 $selectorClasses = array_values($filteredClasses);
604
605 $paddingTopClass = 'g-pt-' . self::DEFAULT_PADDING;
606 $paddingBottomClass = 'g-pb-' . self::DEFAULT_PADDING;
607 if ($blockData->isTitle())
608 {
609 $paddingBottomClass = 'g-pb-' . self::TITLE_PADDING_BOTTOM;
610 }
611 else
612 {
613 $blocks = $this->siteData->getBlocks();
614 foreach ($blocks as $block)
615 {
616 if ($block === $blockData)
617 {
618 break;
619 }
620 $previousBlock = $block;
621 }
622
623 if (isset($previousBlock) && $previousBlock->getSection() === 'title')
624 {
625 $paddingTopClass = 'g-pt-' . self::BLOCK_AFTER_TITLE_PADDING_TOP;
626 }
627 }
628 $selectorClasses[] = $paddingTopClass;
629 $selectorClasses[] = $paddingBottomClass;
630
631 $selector = '#block' . $blockInstance->getId();
632 $styles = [
633 $selector => [
634 'classList' => $selectorClasses,
635 ],
636 ];
637 $blockData->setWrapperClasses($selectorClasses);
638
639 Block::updateStyles($this->landingId, $blockInstance->getId(), $styles, true);
640 }
641 }
642
651 private function updateMenuStyles(\Bitrix\Landing\Block $blockInstance, Data\Block $blockData): void
652 {
653 $blockContent = $blockInstance->getContent();
654 $classList = [];
655 if (preg_match('/class="([^"]*navbar [^"]*)"/', $blockContent, $matches))
656 {
657 $classList = explode(" ", $matches[1]);
658 }
659 if (count($classList) > 0)
660 {
661 $style = [];
662 $bgType = $blockData->getBgType();
663 $colors = $this->siteData->getColors();
664 switch ($bgType)
665 {
666 case 'transparent':
667 $classList[] = 'u-navbar-color';
668 $style['--navbar-color'] = 'var(--theme-color-title)';
669 break;
670 case 'primary':
671 $classList[] = 'u-navbar-color';
672 $classList[] = 'u-navbar-color--hover';
673 $style['--navbar-color'] = $colors->headersTheme;
674 $style['--navbar-color--hover'] = $colors->textsTheme;
675 break;
676 }
677 $styles = [
678 '.navbar' => [
679 'style' => $style,
680 'classList' => $classList,
681 ],
682 ];
683
684 Block::updateStyles($this->landingId, $blockInstance->getId(), $styles, true);
685 }
686 }
687
696 private function updateColorStylesForNodesAtBlockWithPrimaryBgType(
697 \Bitrix\Landing\Block $blockInstance,
698 Data\Block $blockData
699 ): void
700 {
701 if ($blockData->getBgType() !== 'primary')
702 {
703 return;
704 }
705
706 $blockWithPrimaryBg = Collector::getStylesDataForBlockWithPrimaryBg($blockData->getCode());
707 if (!$blockWithPrimaryBg)
708 {
709 return;
710 }
711
712 $styles = [];
713 $colors = $this->siteData->getColors();
714 $blockContent = $blockInstance->getContent();
715 foreach ($blockWithPrimaryBg as $styleNodeName => $styleNodeValues)
716 {
717 $properties = $styleNodeValues['property'];
718 $styleValues = $styleNodeValues['styleValue'];
719 $count = 0;
720 foreach ($styleValues as $styleValue)
721 {
722 if ($styleValue === 'colorsHeadersTheme')
723 {
724 $value = $colors->headersTheme;
725 }
726 elseif ($styleValue === 'colorsTextsTheme')
727 {
728 $value = $colors->textsTheme;
729 }
730 else
731 {
732 $value = $styleValue;
733 }
734 $styles[$styleNodeName]['style'][$properties[$count]] = $value;
735 $styles[$styleNodeName]['classList'][] = Data\Block\Operator::extractNodeClasses($styleNodeName, $blockContent);
736 $count++;
737 }
738 }
739
740 Block::updateStyles($this->landingId, $blockInstance->getId(), $styles, true);
741 }
742
743 private function updateRequestEntityInTable(): void
744 {
745 $blockId = 0;
746 $imgNodesUsesPreviewImage = Collector::getImgNodesUsePreviewImage();
747 foreach ($this->siteData->getBlocks() as $block)
748 {
749 $codeBlock = $block->getCode();
750 foreach ($block->getNodes() as $node)
751 {
752 $codeNode = $node->getCode();
753 if (
754 isset($imgNodesUsesPreviewImage[$codeBlock])
755 && in_array($codeNode, $imgNodesUsesPreviewImage[$codeBlock])
756 )
757 {
758 $blockId = $block->getId();
759
760 $promptGenerator = new PromptGenerator(new PromptTemplateProvider(), $this->siteData);
761 $promptTexts = $promptGenerator->getUpdatedPromptTexts((array)$this->siteData->getPreviewImagePromptText());
762 $node->setPromptTexts($promptTexts);
763
764 break 2;
765 }
766 }
767 }
768
769 $requestIds = [];
770 foreach($this->generation->getScenario()?->getMap() as $stepId => $step)
771 {
772 if ($stepId >= $this->stepId)
773 {
774 break;
775 }
776
777 $requests = Request::getByGeneration($this->generation->getId(), $stepId);
778 foreach ($requests as $request)
779 {
780 $requestIds[] = $request->getId();
781 }
782 }
783
784 if (!empty($requestIds))
785 {
786 $items = RequestToEntitiesTable::getList([
787 'select' => ['ID'],
788 'filter' => [
789 'REQUEST_ID' => $requestIds,
790 'LANDING_ID' => false,
791 ],
792 ]);
793
794 while ($item = $items->fetch())
795 {
796 RequestToEntitiesTable::update(
797 $item['ID'],
798 [
799 'LANDING_ID' => $this->siteData->getLandingId(),
800 'BLOCK_ID' => $blockId,
801 ],
802 );
803 }
804 }
805 }
806}
$count
Определения admin_tab.php:4
if(!Loader::includeModule('catalog')) if(!AccessController::getCurrent() ->check(ActionDictionary::ACTION_PRICE_EDIT)) if(!check_bitrix_sessid()) $request
Определения catalog_reindex.php:36
static getByGeneration(int $generationId, int $stepId)
Определения Request.php:347
static setGlobalOn()
Определения rights.php:116
static setGlobalOff()
Определения rights.php:107
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
if(!is_null($config))($config as $configItem)(! $configItem->isVisible()) $code
Определения options.php:195
$siteId
Определения ajax.php:8
$value
Определения Param.php:39
Определения binding.php:2
Определения ai.php:3
Определения agent.php:3
Определения aliases.php:105
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
</p ></td >< td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 2.0pt 0cm 2.0pt;height:9.0pt'>< p class=Normal align=center style='margin:0cm;margin-bottom:.0001pt;text-align:center;line-height:normal'>< a name=ТекстовоеПоле54 ></a ><?=($taxRate > count( $arTaxList) > 0) ? $taxRate."%"
Определения waybill.php:936
$items
Определения template.php:224
$matches
Определения index.php:22
$url
Определения iframe.php:7