2namespace Bitrix\Landing;
4use Bitrix\Landing\Block\BlockRepo;
5use Bitrix\Landing\Site\Scope;
6use Bitrix\Landing\Site\Type;
7use \Bitrix\Main\Page\Asset;
8use Bitrix\Main\UI\Extension;
9use \Bitrix\Main\Web\Json;
10use \Bitrix\Main\Web\DOM;
11use \Bitrix\Main\Localization\Loc;
12use \Bitrix\Landing\Connector;
13use \Bitrix\Landing\Controller;
14use \Bitrix\Landing\Internals;
15use \Bitrix\Landing\Assets;
16use \Bitrix\Landing\Block\Cache;
17use \Bitrix\Landing\Restriction;
18use \Bitrix\Landing\Node\Type as
NodeType;
19use \Bitrix\Landing\Node\Img;
20use \Bitrix\Landing\PublicAction\Utils as UtilsAction;
22Loc::loadMessages(__FILE__);
238 'landing_google_maps_new',
241 'landing_gallery_cards',
266 'LANDING_TITLE' =>
'LANDING.TITLE',
267 'LANDING_ACTIVE' =>
'LANDING.ACTIVE',
268 'LANDING_TPL_CODE' =>
'LANDING.TPL_CODE',
269 'SITE_TPL_CODE' =>
'LANDING.SITE.TPL_CODE',
270 'SITE_TYPE' =>
'LANDING.SITE.TYPE',
271 'SITE_ID' =>
'LANDING.SITE_ID',
284 if (!isset(
$data[
'CONTENT']) || trim(
$data[
'CONTENT']) ==
'')
286 $data[
'CONTENT'] =
'';
289 $this->
id = intval(
$id);
290 $this->lid = isset(
$data[
'LID']) ? intval(
$data[
'LID']) : 0;
291 $this->parentId = isset(
$data[
'PARENT_ID']) ? intval(
$data[
'PARENT_ID']) : 0;
292 $this->siteId = isset(
$data[
'SITE_ID']) ? intval(
$data[
'SITE_ID']) : 0;
293 $this->sort = isset(
$data[
'SORT']) ? intval(
$data[
'SORT']) :
'';
294 $this->code = isset(
$data[
'CODE']) ? trim(
$data[
'CODE']) :
'';
295 $this->anchor = isset(
$data[
'ANCHOR']) ? trim(
$data[
'ANCHOR']) :
'';
296 $this->active = isset(
$data[
'ACTIVE']) &&
$data[
'ACTIVE'] ==
'Y';
297 $this->landingActive = isset(
$data[
'LANDING_ACTIVE']) &&
$data[
'LANDING_ACTIVE'] ==
'Y';
298 $this->deleted = isset(
$data[
'DELETED']) &&
$data[
'DELETED'] ==
'Y';
299 $this->designed = isset(
$data[
'DESIGNED']) &&
$data[
'DESIGNED'] ==
'Y';
300 $this->
public = isset(
$data[
'PUBLIC']) &&
$data[
'PUBLIC'] ==
'Y';
301 $this->content = (!$this->deleted && isset(
$data[
'CONTENT'])) ? trim(
$data[
'CONTENT']) :
'';
304 if (isset(
$data[
'ACCESS']))
306 $this->access =
$data[
'ACCESS'];
310 if (isset(
$data[
'ASSETS']))
312 $this->assets =
$data[
'ASSETS'];
317 'LID',
'FAVORITE_META',
'CREATED_BY_ID',
'DATE_CREATE',
318 'MODIFIED_BY_ID',
'DATE_MODIFY',
'SITE_TYPE',
320 foreach ($keys as
$key)
327 $this->metaData[
'LANDING_TITLE'] = isset(
$data[
'LANDING_TITLE']) ?
$data[
'LANDING_TITLE'] :
'';
328 $this->metaData[
'LANDING_TPL_CODE'] = isset(
$data[
'LANDING_TPL_CODE']) ?
$data[
'LANDING_TPL_CODE'] :
'';
329 $this->metaData[
'SITE_TPL_CODE'] = isset(
$data[
'SITE_TPL_CODE']) ?
$data[
'SITE_TPL_CODE'] :
'';
330 $this->metaData[
'XML_ID'] = isset(
$data[
'XML_ID']) ?
$data[
'XML_ID'] :
'';
331 $this->metaData[
'DESIGNER_MODE'] = isset(
$params[
'designer_mode']) &&
$params[
'designer_mode'] ===
true;
334 if (preg_match(self::REPO_MASK, $this->code,
$matches))
338 if (!$this->content && !$this->deleted)
340 $this->content = self::getContentFromRepository($this->code);
342 $this->error =
new Error;
346 if (isset(
$data[
'SOURCE_PARAMS']))
348 $this->dynamicParams = (
array)
$data[
'SOURCE_PARAMS'];
361 if ($landing->exist())
363 $editMode = $landing->getEditMode() || $landing->getPreviewMode();
368 'LID' => $landing->getId(),
369 '=PUBLIC' => $editMode ?
'N' :
'Y',
370 '=DELETED' => (isset(
$params[
'deleted']) &&
$params[
'deleted'] ===
true)
378 $res = parent::getList([
381 'LANDING_ACTIVE' =>
'LANDING.ACTIVE',
382 'LANDING_TPL_CODE' =>
'LANDING.TPL_CODE',
383 'SITE_TPL_CODE' =>
'LANDING.SITE.TPL_CODE',
384 'SITE_TYPE' =>
'LANDING.SITE.TYPE',
385 'SITE_ID' =>
'LANDING.SITE_ID',
392 'limit' => $limit ?:
null,
394 while ($row =
$res->fetch())
397 if (!$landing->canEdit())
399 $row[
'ACCESS'] = self::ACCESS_A;
401 $row[
'SITE_ID'] = $landing->getSiteId();
407 if ($block->getRepoId())
409 $repo[] = $block->getRepoId();
411 $blocks[$row[
'ID']] = $block;
419 foreach ($blocks as $block)
422 isset($repo[$block->getRepoId()][
'PAYMENT_ALLOW'])
423 && $repo[$block->getRepoId()][
'PAYMENT_ALLOW'] !=
'Y'
435 $landing->addBlockToCollection($block);
439 $landing->addBlockToCollection($block);
442 unset($blocks, $block, $repo);
456 if ($landing->exist())
463 'ID',
'LID',
'CODE',
'SORT',
'ACTIVE',
464 'CONTENT',
'PUBLIC',
'ACCESS',
'ANCHOR',
468 'LID' => $landing->getId(),
471 while ($row =
$res->fetch())
473 if ($row[
'PUBLIC'] !=
'Y')
482 $row[
'ANCHOR'] =
'b' . $row[
'ID'];
484 $row[
'PUBLIC'] =
'N';
485 $row[
'PARENT_ID'] = $row[
'ID'];
493 foreach ($forClone as $row)
527 while ($row =
$res->fetch())
529 $data[$row[
'ID']] = $row[
'LID'];
538 return array_pop(
$data);
571 while ($row =
$res->fetch())
573 $data[$row[
'ID']] = $row;
582 return array_pop(
$data);
597 if (isset($cached[
$code]))
599 return $cached[
$code];
602 $codeOriginal =
$code;
613 $res = Internals\BlockTable::getList([
615 'ID',
'CODE',
'CONTENT',
'SOURCE_PARAMS',
'DESIGNED',
619 if ($row =
$res->fetch())
621 $cached[$codeOriginal] = $row;
625 return $cached[$codeOriginal] ??
null;
636 if (!is_string(
$code))
641 if (strpos(
$code,
'@'))
643 $normalizedBlock = self::getNormalizedBlock(
$code);
644 return $normalizedBlock[
'CONTENT'] ??
null;
659 if (file_exists(
$path))
662 if (preg_match(
'/MESS\[[^\]]+\]/',
$content))
664 $mess = Loc::loadLanguageFile(
$path);
673 array_keys($replace),
674 array_values($replace),
695 if (!$blockRepo->isBlockInRepo(
$code))
697 $landing->getError()->addError(
698 'BLOCK_CANT_BE_ADDED',
699 Loc::getMessage(
'LANDING_BLOCK_CANT_BE_ADDED')
707 $filesFromContent = [];
709 $codeOriginal =
null;
712 if (isset(
$data[
'PREPARE_BLOCK_DATA'][
'ACTION']))
715 $data[
'PREPARE_BLOCK_DATA'][
'ACTION'] ===
'changeComponentParams'
716 && isset(
$data[
'PREPARE_BLOCK_DATA'][
'PARAMS'])
717 && is_array(
$data[
'PREPARE_BLOCK_DATA'][
'PARAMS'])
720 foreach (
$data[
'PREPARE_BLOCK_DATA'][
'PARAMS'] as $paramName => $paramValue)
722 $search =
"'" . $paramName .
"' => '',";
723 $replace =
"'" . $paramName .
"' => '". $paramValue .
"',";
728 if (strpos(
$code,
'@'))
730 $codeOriginal =
$code;
731 $normalizedBlock = self::getNormalizedBlock(
$code);
732 $designed = $normalizedBlock[
'DESIGNED'] ??
'N';
733 $filesFromContent = $normalizedBlock[
'FILES'] ?? [];
734 $sourceParams = $normalizedBlock[
'SOURCE_PARAMS'] ?? [];
737 $manifest = self::getManifestFile(
$code);
740 isset($manifest[
'block'][
'version']) &&
744 $landing->getError()->addError(
745 'BLOCK_WRONG_VERSION',
746 Loc::getMessage(
'LANDING_BLOCK_WRONG_VERSION')
751 if (!$landing->exist())
753 $landing->getError()->addError(
755 Loc::getMessage(
'LANDING_BLOCK_LANDING_NOT_EXIST')
761 $landing->getError()->addError(
763 Loc::getMessage(
'LANDING_BLOCK_NOT_FOUND')
769 'LID' => $landing->getId(),
771 'SOURCE_PARAMS' => $sourceParams,
776 $availableReplace =
array(
777 'ACTIVE',
'PUBLIC',
'ACCESS',
'SORT',
778 'CONTENT',
'ANCHOR',
'SOURCE_PARAMS',
779 'INITIATOR_APP_CODE',
'XML_ID',
780 'DESIGNED',
'FAVORITE_META',
782 foreach ($availableReplace as $replace)
784 if (isset(
$data[$replace]))
790 if (
$res->isSuccess())
792 $block =
new self(
$res->getId());
793 $manifest = $block->getManifest();
794 if (!$block->getLocalAnchor())
796 $historyActivity = History::isActive();
797 History::deactivate();
798 $block->setAnchor(
'b' . $block->getId());
799 $historyActivity ? History::activate() : History::deactivate();
801 Assets\PreProcessing::blockAddProcessing($block);
803 isset($manifest[
'callbacks'][
'afteradd']) &&
804 is_callable($manifest[
'callbacks'][
'afteradd'])
807 $manifest[
'callbacks'][
'afteradd']($block);
810 foreach ($block->getClass() as $class)
812 $classBlock = $block->includeBlockClass($class);
813 $classBlock->beforeAdd($block);
818 $block->saveDynamicParams(
822 self::prepareBlockContentFromRepository($block);
823 if (isset($manifest[
'block'][
'app_code']))
826 'INITIATOR_APP_CODE' => $manifest[
'block'][
'app_code'],
834 foreach ($filesFromContent as $fileId)
842 $landing->getError()->addFromResult(
$res);
849 $blockContent = $block->getContent();
850 if (mb_strpos($blockContent,
'#YEAR#') !==
false)
853 $replace[
'#YEAR#'] = date(
"Y");
854 $blockContent = str_replace(
855 array_keys($replace),
856 array_values($replace),
859 $block->saveContent($blockContent);
862 if (mb_strpos($blockContent,
'#COUNTDOWN#') !==
false)
866 $blockContent = str_replace(
867 array_keys($replace),
868 array_values($replace),
871 $block->saveContent($blockContent);
874 self::replaceVideoPlaceholders($block);
877 private static function replaceVideoPlaceholders($block): void
879 $blockContent = $block->getContent();
880 if (mb_strpos($blockContent,
'#DEFAULT_VIDEO_SRC#') !==
false)
885 '#DEFAULT_VIDEO_SRC#' =>
'data-src=""',
886 '#DEFAULT_VIDEO_SOURCE#' =>
'data-source=""',
887 '#DEFAULT_VIDEO_PREVIEW#' =>
'data-preview=""',
888 '#DEFAULT_VIDEO_STYLE#' =>
'style=""',
889 '#DEFAULT_VIDEO_SRC_2#' =>
'data-src=""',
890 '#DEFAULT_VIDEO_SOURCE_2#' =>
'data-source=""',
891 '#DEFAULT_VIDEO_PREVIEW_2#' =>
'data-preview=""',
892 '#DEFAULT_VIDEO_STYLE_2#' =>
'style=""',
898 '#DEFAULT_VIDEO_SRC#' =>
'data-src="//www.youtube.com/embed/q4d8g9Dn3ww?autoplay=0&controls=1&loop=1&mute=0&rel=0"',
899 '#DEFAULT_VIDEO_SOURCE#' =>
'data-source="https://www.youtube.com/watch?v=q4d8g9Dn3ww"',
900 '#DEFAULT_VIDEO_PREVIEW#' =>
'data-preview="//img.youtube.com/vi/q4d8g9Dn3ww/sddefault.jpg"',
901 '#DEFAULT_VIDEO_STYLE#' =>
'style="background-image:url(//img.youtube.com/vi/q4d8g9Dn3ww/sddefault.jpg)"',
902 '#DEFAULT_VIDEO_SRC_2#' =>
'data-src="//www.youtube.com/embed/IISycTRZ-UA?autoplay=0&controls=1&loop=1&mute=0&rel=0"',
903 '#DEFAULT_VIDEO_SOURCE_2#' =>
'data-source="https://www.youtube.com/watch?v=IISycTRZ-UA"',
904 '#DEFAULT_VIDEO_PREVIEW_2#' =>
'data-preview="//img.youtube.com/vi/q4d8g9Dn3ww/sddefault.jpg"',
905 '#DEFAULT_VIDEO_STYLE_2#' =>
'style="background-image:url(//img.youtube.com/vi/IISycTRZ-UA/sddefault.jpg)"',
908 $blockContent = str_replace(
909 array_keys($replace),
910 array_values($replace),
913 $block->saveContent($blockContent);
924 static $newBlocks =
null;
926 if (!is_string($block))
931 if ($newBlocks ===
null)
933 $newBlocks = unserialize(
Manager::getOption(
'new_blocks'), [
'allowed_classes' =>
false]);
934 if (!is_array($newBlocks))
936 $newBlocks =
array();
939 !isset($newBlocks[
'date']) ||
941 isset($newBlocks[
'date']) &&
946 $newBlocks =
array();
948 if (isset($newBlocks[
'items']))
950 $newBlocks = $newBlocks[
'items'];
954 return in_array($block, $newBlocks);
973 return (
new BlockRepo())->getRepository();
983 $res = Internals\BlockLastUsedTable::getList([
991 'DATE_CREATE' =>
'DESC',
993 'limit' =>
$count ?:
null,
996 while ($row =
$res->fetch())
998 $blocks[] = $row[
'CODE'];
1011 $res = Internals\BlockLastUsedTable::getList([
1017 '=CODE' => $blockCode,
1021 if ($row =
$res->fetch())
1023 Internals\BlockLastUsedTable::update($row[
'ID'], [
1029 Internals\BlockLastUsedTable::add([
1030 'CODE' => $blockCode,
1044 $res = Internals\BlockLastUsedTable::getList([
1049 '=CODE' => $blockCode,
1052 while ($row =
$res->fetch())
1054 Internals\BlockLastUsedTable::delete($row[
'ID']);
1064 return self::getSpecialManifest(
'style');
1073 return self::getSpecialManifest(
'semantic');
1082 return self::getSpecialManifest(
'attrs');
1094 if (array_key_exists(
$type, $style))
1096 return $style[
$type];
1108 while ((($entry = readdir(
$handle)) !==
false))
1111 $entry !=
'.' && $entry !=
'..' &&
1112 is_dir(
$path .
'/' . $entry) &&
1113 file_exists(
$path .
'/' . $entry .
'/.' .
$type .
'.php')
1116 $style[
$type][$entry] = include
$path .
'/' . $entry .
'/.' .
$type .
'.php';
1117 if (!is_array($style[
$type][$entry]))
1119 unset($style[
$type][$entry]);
1126 return $style[
$type];
1138 if (!isset(
$params[
'wrapper_show']))
1140 $params[
'wrapper_show'] =
true;
1144 $params[
'force_unactive'] =
true;
1146 $params[
'skip_system_script'] =
true;
1150 $block =
new self(
$id);
1153 if (($ext = $block->getExt()))
1155 foreach ($ext as $extCode)
1159 ?? Extension::getConfig($extCode)
1162 if (!empty($extInfo[
'lang']) && is_string($extInfo[
'lang']))
1164 $messages = Loc::loadLanguageFile(
$_SERVER[
'DOCUMENT_ROOT'] . $extInfo[
'lang']);
1169 $extContent = \CUtil::initJSCore($ext,
true);
1170 $extContent = preg_replace(
1171 '#<script(\sdata\-skip\-moving\="true")?>.*?</script>#is',
1176 $landing = Landing::createInstance(
1177 $block->getLandingId(),
1179 'skip_blocks' =>
true,
1188 $landing->exist() ? $landing :
null,
1197 if ($landing->exist())
1199 if (mb_strpos(
$content,
'#crm') !==
false)
1203 array_keys($replace),
1204 array_values($replace),
1208 if (mb_strpos(
$content,
'#YEAR#') !==
false)
1211 $replace[
'#YEAR#'] = date(
"Y");
1213 array_keys($replace),
1214 array_values($replace),
1220 if ($block->exist())
1224 $availableJS = !$editMode || !$block->getRepoId();
1227 $manifest = $block->getManifest();
1229 !isset($manifest[
'requiredUserAction']) &&
1230 $block->getRuntimeRequiredUserAction()
1233 $manifest[
'requiredUserAction'] = $block->getRuntimeRequiredUserAction();
1235 $sections = (
array)(($manifest[
'block'][
'section']) ??
null);
1238 'sections' => implode(
',', $sections),
1239 'active' => $block->isActive(),
1240 'access' => $block->getAccess(),
1241 'anchor' => $block->getLocalAnchor(),
1242 'php' => mb_strpos($block->getContent(),
'<?') !==
false,
1243 'designed' => $block->isDesigned(),
1244 'repoId' => $block->repoId ? (
int)$block->repoId :
null,
1246 'content_ext' => $extContent,
1247 'css' => $block->getCSS(),
1248 'js' => $availableJS ? $block->getJS() :
array(),
1249 'assetStrings' => $assetsManager->getStrings(),
1251 'manifest' => $manifest,
1252 'dynamicParams' => $block->dynamicParams,
1256 isset($return[
'manifest'][
'requiredUserAction'])
1259 $return[
'requiredUserAction'] = $return[
'manifest'][
'requiredUserAction'];
1263 $ajaxAssets = self::getAjaxInitiatedAssets();
1264 $return[
'js'] = array_merge($return[
'js'], $ajaxAssets[
'js']);
1265 $return[
'css'] = array_merge($return[
'css'], $ajaxAssets[
'css']);
1284 return 'block' . (int)
$id;
1295 static $namespace =
array();
1297 if (!is_string(
$code))
1315 foreach (array_reverse($namespaces) as $subdir)
1317 foreach ($generalPaths as
$path)
1320 if (file_exists(
$path .
'/' . $subdir .
'/' .
$code .
'/.description.php'))
1339 if (!is_string(
$code))
1344 if (strpos(
$code,
'@'))
1351 $namespace = self::getBlockNamespace(
$code);
1355 return \getLocalPath(
1369 return $this->
id > 0;
1414 return $this->anchor;
1433 $class = !empty($class) ? $class[0] :
null;
1434 if ($class !==
null)
1449 $this->allowedByTariff = $mark;
1458 $data = parent::getList([
1468 $this->content =
$data[
'CONTENT'];
1478 return $this->active;
1496 return $this->designed;
1515 if (is_string($letter))
1517 $this->access = $letter;
1528 if ($this->access < $this::ACCESS_W)
1530 $this->error->addError(
1532 Loc::getMessage(
'LANDING_BLOCK_ACCESS_DENIED')
1536 $this->active = (boolean)
$active;
1546 return $this->repoId;
1555 static $site =
null;
1564 'ID' => $this->siteId,
1578 $path = self::getBlockPath($this->code);
1579 if (
$path && file_exists($this->docRoot .
'/' .
$path .
'/' . self::PREVIEW_FILE_NAME))
1581 return $path .
'/' . self::PREVIEW_FILE_NAME;
1606 return Node\Type::getClassName(
$type);
1615 static $manifests = [];
1617 if (!$this->
id || !$this->designed)
1621 if (array_key_exists($this->
id, $manifests))
1623 return $manifests[$this->id];
1628 return $manifests[$this->id];
1638 if (isset($manifest[
'block'][
'name']))
1641 if (!empty($designerBlockManifest[
'nodes']))
1643 foreach ($designerBlockManifest[
'nodes'] as $keyNode => $node)
1645 if (isset($manifest[
'nodes'][$keyNode]))
1649 $node[
'code'] = $keyNode;
1650 $class = Node\Type::getClassName($node[
'type']);
1651 if (isset($node[
'type']) && class_exists($class))
1653 $node[
'handler'] = call_user_func(
1659 $manifest[
'nodes'][$keyNode] = $node;
1663 if (!empty($designerBlockManifest[
'style']))
1665 $manifest[
'style'][
'nodes'] = array_merge(
1666 $designerBlockManifest[
'style'],
1667 $manifest[
'style'][
'nodes']
1684 $manifest = self::getManifestInternal($missCache,
$params);
1687 if (isset($manifest[
'block'][
'name']))
1690 foreach ([
'cards',
'nodes',
'attrs',
'menu'] as
$code)
1692 if (!isset($manifest[
$code]) || !is_array($manifest[
$code]))
1699 foreach ($manifest[
'nodes'] as $keyNode => &$node)
1701 if (is_callable($node) && !$this->repoId)
1705 $node[
'code'] = $keyNode;
1706 $class = Node\Type::getClassName($node[
'type']);
1707 if (isset($node[
'type']) && class_exists($class))
1709 $node[
'handler'] = call_user_func(
array(
1713 if (method_exists($class,
'prepareManifest'))
1715 $node = call_user_func_array(
array(
1723 if (!is_array($node))
1725 unset($manifest[
'nodes'][$keyNode]);
1731 unset($manifest[
'nodes'][$keyNode]);
1736 foreach ($manifest[
'attrs'] as $keyNode => &$node)
1738 if (is_callable($node) && !$this->repoId)
1746 if (!isset($manifest[
'namespace']))
1751 isset($manifest[
'style'])
1753 isset($manifest[
'style'][
'block'])
1754 && isset($manifest[
'style'][
'nodes'])
1755 &&
count($manifest[
'style']) == 2
1759 $manifest[
'style'] = [
1761 'nodes' => is_array($manifest[
'style'])
1762 ? $manifest[
'style']
1767 !isset($manifest[
'style'])
1768 || !is_array($manifest[
'style'])
1771 $manifest[
'style'] = [
1779 !is_array($manifest[
'style'][
'block'])
1780 || empty($manifest[
'style'][
'block'])
1783 $manifest[
'style'][
'block'] = [
'type' => self::DEFAULT_WRAPPER_STYLE];
1784 $manifest[
'block'][
'section'] = (
array)$manifest[
'block'][
'section'];
1786 Site\Type::getCurrentScopeId() ===
'MAINPAGE'
1787 && !in_array(
'widgets_separators', $manifest[
'block'][
'section'],
true)
1790 $manifest[
'style'][
'block'][
'type'][] =
'widget-type';
1796 foreach ($manifest[
'style'][
'nodes'] as $selector => $styleNode)
1798 if (!isset($manifest[
'nodes'][$selector]) && isset($styleNode[
'type']) && is_array($styleNode))
1800 $styleNodes[$selector] = is_array($styleNode[
'type']) ? $styleNode[
'type'] : [$styleNode[
'type']];
1803 $styleNodes[
'#wrapper'] = is_array($manifest[
'style'][
'block'][
'type'])
1804 ? $manifest[
'style'][
'block'][
'type']
1805 : [$manifest[
'style'][
'block'][
'type']];
1807 foreach ($styleNodes as $selector =>
$type)
1811 $manifest[
'nodes'][$selector] = [
1813 'code' => $selector,
1830 isset($manifest[
'lang'])
1831 && isset($manifest[
'lang_original'])
1832 && is_array($manifest[
'lang'])
1837 $langPortal = LANGUAGE_ID;
1838 if (in_array($langPortal, [
'ru',
'kz',
'by',
'uz']))
1842 $langArray = $manifest[
'lang'];
1843 $langOrig = $manifest[
'lang_original'];
1844 if (isset($langArray[$langPortal]))
1846 $lang = $langArray[$langPortal];
1849 $langOrig != $langPortal
1850 && isset($langArray[
'en'])
1853 $lang = $langArray[
'en'];
1863 unset($manifest[
'lang']);
1875 private function getManifestInternal(
bool $missCache =
false):
array
1877 static $manifestsBase = [];
1878 static $manifestsFull = [];
1880 $code = $this->getCode();
1881 $id = $this->getId();
1885 && !empty($manifestsBase[
$code])
1887 !isset($manifestsBase[
$code][
'disableCache'])
1888 || $manifestsBase[
$code][
'disableCache'] !==
true
1892 $manifest = $manifestsBase[
$code];
1903 $includeDesc =
function (
$path)
1905 Loc::loadLanguageFile(
$path .
'/.description.php');
1906 $manifest = include
$path .
'/.description.php';
1907 $manifest[
'timestamp'] = file_exists(
$path .
'/block.php')
1908 ? filectime(
$path .
'/block.php')
1914 $manifest = $includeDesc($this->docRoot .
$path);
1918 if (!isset($manifest[
'block'][
'name']))
1923 $manifest = Type::prepareBlockManifest($manifest);
1924 $manifestsBase[
$code] = $manifest;
1926 if (isset($manifestsFull[
$code][
$id]))
1933 isset($manifest[
'block'][
'subtype'])
1935 !isset($params[
'miss_subtype'])
1936 || $params[
'miss_subtype'] !==
true
1940 $subtypes = (
array)$manifest[
'block'][
'subtype'];
1941 foreach ($subtypes as $subtype)
1943 $subtypeClass =
'\\Bitrix\\Landing\\Subtype\\';
1944 $subtypeClass .= $subtype;
1945 if (class_exists($subtypeClass))
1947 $manifest = $subtypeClass::prepareManifest(
1950 isset($manifest[
'block'][
'subtype_params'])
1951 ? (
array)$manifest[
'block'][
'subtype_params']
1960 isset($manifest[
'callbacks'])
1961 && is_array($manifest[
'callbacks'])
1965 foreach ($manifest[
'callbacks'] as
$name => $callback)
1972 $manifestsFull[
$code][
$id] = $manifest;
1985 foreach ($manifest as
$key => &$value)
1987 if (is_array($value))
1993 isset(
$lang[$value])
1996 $value =
$lang[$value];
2008 static $manifests =
array();
2010 if (!is_string(
$code))
2015 if (preg_match(
'/[^a-z0-9_.:-]+/i',
$code))
2020 if (isset($manifests[
$code]))
2022 return $manifests[
$code];
2028 if (mb_strpos(
$code,
':') !==
false)
2033 if (
$path = self::getBlockPath(
$code ,$namespace))
2036 Loc::loadLanguageFile(
$docRoot .
$path .
'/.description.php');
2040 return $manifests[
$code];
2050 $manifest = $this->getManifestInternal();
2059 if (isset($manifest[
'block'][
'namespace']))
2062 $classFile .=
'/' . $manifest[
'block'][
'namespace'] .
'/';
2063 $classFile .= $this->
getCode() .
'/class.php';
2067 $asset[
'class'][] = $this->docRoot . $classFile;
2071 foreach (array_keys($asset) as $ass)
2073 if (!empty($manifest[
'assets'][$ass]))
2075 foreach ($manifest[
'assets'][$ass] as $file)
2077 if (!is_string($file))
2083 $asset[$ass][] = trim($file);
2088 || in_array($file, $this->allowedExtensions)
2091 $asset[$ass][] = trim($file);
2095 && in_array($file, $this->allowedRepoExtensions)
2098 $asset[$ass][] = trim($file);
2101 $asset[$ass] = array_unique($asset[$ass]);
2106 $path = self::getBlockPath($this->code);
2113 $file =
$path .
'/' . ($this->metaData[
'DESIGNER_MODE'] ?
'design_' :
'') . self::CSS_FILE_NAME;
2114 if (file_exists($this->docRoot . $file))
2116 $asset[
'css'][] = $file;
2118 $file =
$path .
'/' . self::JS_FILE_NAME;
2119 if (file_exists($this->docRoot . $file))
2121 $asset[
'js'][] = $file;
2126 if (!empty($designerBlockManifest[
'assets']))
2128 foreach ($designerBlockManifest[
'assets'] as
$key =>
$assets)
2131 $asset[
$key] = array_unique($asset[
$key]);
2135 return $asset[
$type] ?? $asset;
2181 static $classes = [];
2182 static $calledClasses = [];
2184 if (!isset($classes[
$path]))
2187 $beforeClasses = get_declared_classes();
2188 $beforeClassesCount =
count($beforeClasses);
2189 include_once(
$path);
2190 $afterClasses = get_declared_classes();
2191 $afterClassesCount =
count($afterClasses);
2194 for (
$i = $beforeClassesCount;
$i < $afterClassesCount;
$i++)
2196 if (is_subclass_of($afterClasses[
$i],
'\\Bitrix\\Landing\\LandingBlock'))
2198 $classes[
$path] = $afterClasses[
$i];
2204 $landingPath =
$path .
'@' . $landingId;
2207 if (!isset($calledClasses[$landingPath]))
2209 $calledClasses[$landingPath] =
new $classes[
$path];
2210 $calledClasses[$landingPath]->init([
2216 return $calledClasses[$landingPath];
2229 'bitrix:landing.blocks.message',
2234 $blockMesage = ob_get_contents();
2237 return $blockMesage;
2255 if (!$blockRepo->isBlockInRepo($this->getCode()))
2261 if ($this->dynamicParams)
2266 if (!isset(
$params[
'wrapper_show']))
2268 $params[
'wrapper_show'] =
true;
2270 if (!isset(
$params[
'force_unactive']))
2272 $params[
'force_unactive'] =
false;
2274 if (!isset(
$params[
'skip_system_script']))
2276 $params[
'skip_system_script'] =
false;
2284 $params[
'wrapper_show'] =
false;
2292 if ($edit || $this->active ||
$params[
'force_unactive'])
2295 if ($css = $this->
getCSS())
2299 if ($ext = $this->
getExt())
2303 if (!$edit || !$this->repoId)
2305 if ($js = $this->
getJS())
2312 foreach ($this->
getClass() as $class)
2315 if ($classBlock->beforeView($this) ===
false)
2323 if ($edit && !
$params[
'skip_system_script'])
2331 !
$params[
'skip_system_script'] &&
2332 defined(
'LANDING_DEVELOPER_MODE') &&
2333 LANDING_DEVELOPER_MODE ===
true
2336 if (!isset($manifest))
2340 if (isset($this->metaData[
'DATE_MODIFY']))
2342 $modifyTime = $this->metaData[
'DATE_MODIFY']->getTimeStamp();
2348 if ($modifyTime < $manifest[
'timestamp'])
2352 Update\Block::executeStep([
2354 ],
$count, $limit, $paramsUpdater = []);
2360 if (!\
Bitrix\
Main\ModuleManager::isModuleInstalled(
'bitrix24'))
2362 if (mb_strpos($this->content,
'/upload/') !==
false)
2364 $this->content = preg_replace(
2365 '#"//[^\'^"]+/upload/#',
2372 if (mb_strpos($this->content,
'srcset="') !==
false)
2374 $this->content = str_replace(
2376 'data-srcset-bad="',
2380 if (mb_strpos($this->content,
'2x)') !==
false)
2382 $this->content = preg_replace(
2383 "#(, url\('[^'^\"]+'\) 2x)#",
2409 $anchor =
'block' . rand(10000, 100000);
2412 $classFromCode = preg_replace(
'/([^a-z0-9-])/i',
'-', $classFromCode);
2413 $classFromCode =
' ' . $classFromCode;
2415 if ($landing && $landing->getPreviewMode())
2417 $content .=
"<a id=\"editor{$this->getId()}\"></a>";
2420 ($edit ?
'data-id="' . $this->
id .
'" ' :
'') .
2421 (($edit && isset($manifest[
'block'][
'subtype'])) ?
'data-subtype="' . $manifest[
'block'][
'subtype'] .
'" ' :
'') .
2422 'class="block-wrapper' .
2423 (!$this->active ?
' landing-block-deactive' :
'') .
2424 ($this->metaData[
'DESIGNER_MODE'] ?
' landing-designer-block-mode' :
'') .
2436 if (mb_strpos($this->content,
'#requisiteCompanyTitle') !==
false)
2440 array_keys($replace),
2441 array_values($replace),
2450 if ($manifest ??
null)
2453 !isset($manifest[
'requiredUserAction']) &&
2454 $this->runtimeRequiredUserAction
2457 $manifest[
'requiredUserAction'] = $this->runtimeRequiredUserAction;
2459 $sections = (
array)($manifest[
'block'][
'section'] ??
null);
2465 ?
'block' . $this->parentId
2470 .
'BX.ready(function(){'
2471 .
'if (typeof BX.Landing.Block !== "undefined")'
2473 .
'new BX.Landing.' . ($this->metaData[
'DESIGNER_MODE'] ?
'DesignerBlock' :
'Block') .
'('
2474 .
'BX("block' . $this->
id .
'"), '
2476 .
'id: ' . $this->
id .
', '
2477 .
'lid: ' . $this->lid .
', '
2478 .
'code: "' . $this->code .
'", '
2479 .
'sections: "' . implode(
',', $sections) .
'", '
2480 .
'repoId: ' . ($this->repoId ? (int)$this->repoId :
"null") .
', '
2481 .
'php: ' . (mb_strpos(
$content,
'<?') !==
false ?
'true' :
'false') .
', '
2482 .
'designed: ' . ($this->designed ?
'true' :
'false') .
', '
2483 .
'active: ' . ($this->active ?
'true' :
'false') .
', '
2484 .
'allowedByTariff: ' . ($this->allowedByTariff ?
'true' :
'false') .
', '
2485 .
'autoPublicationEnabled: ' . ($autoPublicationEnabled ?
'true' :
'false') .
', '
2486 .
'anchor: ' .
'"' . \CUtil::jsEscape(
$anchor) .
'"' .
', '
2487 .
'access: ' .
'"' . $this->access .
'"' .
', '
2488 .
'dynamicParams: ' . Json::encode($this->dynamicParams) .
','
2489 . ($this->metaData[
'DESIGNER_MODE'] ?
'repository: ' . Json::encode($designerRepository) .
',' :
'')
2490 .
'manifest: ' . Json::encode($manifest)
2492 isset($manifest[
'requiredUserAction'])
2493 ?
', requiredUserAction: ' . Json::encode($manifest[
'requiredUserAction'])
2504 $event = new \Bitrix\Main\Event(
'landing',
'onBlockEditView', [
2524 catch (\ParseError $e)
2526 $errMessage = $this::getMessageBlock([
2527 'MESSAGE' => Loc::getMessage(
'LANDING_BLOCK_MESSAGE_ERROR_EVAL'),
2531 echo
'<div id="' .
$anchor .
'" class="block-wrapper' .
2532 (!$this->active ?
' landing-block-deactive' :
'') .
'">' .
2546 static $sysPagesSites = [];
2548 if (!array_key_exists($this->siteId, $sysPagesSites))
2550 $sysPages =
array();
2553 $sysPages[
'@#system_' . $syspage[
'TYPE'] .
'@'] = $syspage[
'LANDING_ID'];
2556 if (!isset($sysPages[
'@#system_mainpage@']))
2558 $currentSite = $this->
getSite();
2559 if ($currentSite[
'LANDING_ID_INDEX'])
2561 $sysPages[
'@#system_mainpage@'] = $currentSite[
'LANDING_ID_INDEX'];
2564 if (!empty($sysPages))
2566 $urls = $landing->getPublicUrl($sysPages);
2569 if (isset($urls[
$lid]))
2575 unset($sysPages[
$code]);
2593 if (!empty($sysPages))
2596 array_keys($sysPages),
2597 array_values($sysPages),
2602 $event = new \Bitrix\Main\Event(
'landing',
'onBlockPublicView', [
2622 catch (\ParseError $e)
2627 Assets\PreProcessing::blockViewProcessing($this, $edit);
2637 if ($this->access < $this::ACCESS_W)
2639 $this->error->addError(
2641 Loc::getMessage(
'LANDING_BLOCK_ACCESS_DENIED')
2646 foreach ([
'font',
'icon',
'ext'] as $assetCode)
2648 if (isset($this->assets[$assetCode]) && !isset(
$assets[$assetCode]))
2650 $assets[$assetCode] = $this->assets[$assetCode];
2667 return $this->assets;
2683 if ($this->access < $this::ACCESS_W)
2685 $this->error->addError(
2687 Loc::getMessage(
'LANDING_BLOCK_ACCESS_DENIED')
2693 $this->designed =
true;
2706 if ($this->access == $this::ACCESS_A)
2708 $this->error->addError(
2710 Loc::getMessage(
'LANDING_BLOCK_ACCESS_DENIED')
2716 'SORT' => $this->sort,
2717 'ACTIVE' => $this->active ?
'Y' :
'N',
2718 'ANCHOR' => $this->anchor,
2719 'DELETED' => $this->deleted ?
'Y' :
'N',
2720 'DESIGNED' => $this->designed ?
'Y' :
'N',
2721 'ASSETS' => $this->assets ? $this->assets :
null,
2723 if ($additionalFields)
2725 $data = array_merge(
$data, $additionalFields);
2730 $data[
'SEARCH_CONTENT'] = $this->getSearchContent();
2733 $res = parent::update($this->
id,
$data);
2734 $this->error->addFromResult(
$res);
2735 return $res->isSuccess();
2746 if ($this->access < $this::ACCESS_W)
2748 $this->error->addError(
2750 Loc::getMessage(
'LANDING_BLOCK_ACCESS_DENIED')
2756 'PARENT_ID' =>
null,
2759 $this->error->addFromResult(
$res);
2760 return $res->isSuccess();
2770 $res = parent::update($this->
id, [
2771 'TPL_CODE' => $meta[
'tpl_code'] ??
null,
2772 'FAVORITE_META' => $meta,
2774 $this->error->addFromResult(
$res);
2775 return $res->isSuccess();
2784 if ($this->access < $this::ACCESS_X)
2786 $this->error->addError(
2788 Loc::getMessage(
'LANDING_BLOCK_ACCESS_DENIED')
2794 $res = self::parentDelete($this->
id);
2795 if (!
$res->isSuccess())
2797 $this->error->addFromResult(
$res);
2799 return $res->isSuccess();
2809 if ($this->access < $this::ACCESS_X)
2811 $this->error->addError(
2813 Loc::getMessage(
'LANDING_BLOCK_ACCESS_DENIED')
2817 $this->deleted = (boolean) $mark;
2827 $this->sort =
$sort;
2842 $check = !
$anchor || preg_match_all(
'/^[a-z]{1}[a-z0-9\-\_\.\:]+$/i',
$anchor);
2845 $this->error->addError(
2847 Loc::getMessage(
'LANDING_BLOCK_BAD_ANCHOR')
2852 if (History::isActive())
2855 $history->push(
'CHANGE_ANCHOR', [
2857 'valueBefore' => $this->anchor,
2873 if ($this->access < $this::ACCESS_W)
2875 $this->error->addError(
2877 Loc::getMessage(
'LANDING_BLOCK_ACCESS_DENIED')
2882 $this->sort =
$sort;
2883 Internals\BlockTable::update($this->
id,
array(
2909 $res = parent::getList([
2917 if ($row =
$res->fetch())
2919 $params = $row[
'SOURCE_PARAMS'];
2925 $params = $this->dynamicParams;
2940 if (is_array($value))
2942 $data[
$key] = $this->dynamicLinkReplacer($value, $replace);
2947 array_keys($replace),
2948 array_values($replace),
2966 if ($this->access < $this::ACCESS_W)
2968 $this->error->addError(
2970 Loc::getMessage(
'LANDING_BLOCK_ACCESS_DENIED')
2976 isset(
$params[
'linkReplace']) &&
2977 is_array(
$params[
'linkReplace'])
2980 $sourceParams = $this->dynamicLinkReplacer(
2986 $paramsBefore = $this->dynamicParams;
2987 $this->dynamicParams = $sourceParams;
2988 $resUpdate = Internals\BlockTable::update($this->
id, [
2989 'SOURCE_PARAMS' => $sourceParams,
2992 if ($resUpdate->isSuccess())
2994 if (History::isActive())
2997 $history->push(
'UPDATE_DYNAMIC', [
2999 'valueBefore' => $paramsBefore,
3000 'valueAfter' => $sourceParams,
3005 unset($sourceParams,
$params);
3015 static $sourceList =
null;
3016 static $isDetailDynamic =
null;
3017 static $dynamicElementId =
null;
3018 static $dynamicFilter =
null;
3020 $data = $this->dynamicParams;
3025 if (!$this->active || !$this->content)
3036 'limit_sites_dynamic_blocks',
3037 [
'targetBlockId' => $this->
id]
3039 if (!$availableFeature)
3041 $hackContent = preg_replace(
3043 '<$1 style="display: none;" ',
3049 $this::getMessageBlock([
3050 'HEADER' => Loc::getMessage(
'LANDING_BLOCK_MESSAGE_ERROR_DYNAMIC_LIMIT_TITLE'),
3051 'MESSAGE' =>
Restriction\Manager::getSystemErrorMessage(
'limit_sites_dynamic_blocks'),
3052 'BUTTON' => Loc::getMessage(
'LANDING_BLOCK_MESSAGE_ERROR_LIMIT_BUTTON'),
3060 if ($isDetailDynamic ===
null)
3062 $isDetailDynamic = Landing::isDynamicDetailPage();
3064 if ($dynamicElementId ===
null)
3066 $dynamicElementId = Landing::getDynamicElementId();
3068 if ($dynamicFilter ===
null)
3070 $dynamicFilter = Landing::getDynamicFilter();
3075 $cache = new \CPHPCache();
3077 $cacheId =
'block_' . $this->
id .
'_' . $dynamicElementId .
'_';
3078 $cacheId .= md5(serialize($dynamicFilter));
3079 $cachePath =
'/landing/dynamic/' . $this->id;
3080 if ($cache->initCache($cacheTime, $cacheId, $cachePath))
3089 $this->access = $this::ACCESS_W;
3091 $this->access = $rememberAccess;
3092 header(
'X-Bitrix24-Page: dynamic');
3098 $cache->startDataCache($cacheTime, $cacheId, $cachePath);
3109 if ($sourceList ===
null)
3115 $getDetailPage =
function(
array $detailPage, $filterId = 0, $elemId = 0)
3117 $filterId = intval($filterId);
3118 $elemId = intval($elemId);
3121 if (isset($detailPage[
'query']))
3124 unset($detailPage[
'query']);
3128 $detailPage = array_merge(
3129 array_fill_keys([
'text',
'href',
'target'],
''),
3132 foreach ($detailPage as
$key => &$detailPageItem)
3134 if (!is_array($detailPageItem))
3136 $detailPageItem = trim($detailPageItem);
3138 if (empty($detailPageItem))
3140 unset($detailPage[
$key]);
3143 unset($detailPageItem);
3145 if ($filterId && $elemId && $detailPage[
'href'])
3147 $detailPage[
'href'] = str_replace(
3152 $detailPage[
'href'] .=
'_' . $filterId;
3153 $detailPage[
'href'] .=
'_' . $elemId;
3155 else if ($filterId && $elemId)
3157 $detailPage[
'href'] =
'#';
3160 if ($detailPage[
'href'] &&
$query)
3162 $detailPage[
'query'] = http_build_query(
$query);
3169 $disableUpdate =
false;
3171 foreach (
$data as $cardSelector => $item)
3174 $itemDetail = $cardSelector ==
'wrapper';
3176 !isset($item[
'source']) ||
3177 !isset($item[
'settings']) ||
3178 !isset($item[
'references'])
3184 $sourceId = $item[
'source'];
3186 $references = (
array)$item[
'references'];
3187 $filterId = isset($item[
'filterId'])
3188 ? intval($item[
'filterId'])
3190 $detailPage = isset(
$settings[
'detailPage'])
3205 $additional = isset(
$settings[
'source'][
'additional'])
3208 $stubs = isset($item[
'stubs'])
3209 ? (
array)$item[
'stubs']
3213 $isDetailDynamic && $itemDetail &&
3214 $dynamicFilter[
'SOURCE_ID'] == $sourceId
3217 $filter = $dynamicFilter[
'FILTER'];
3219 $sourceParameters = [
3220 'select' => array_values($references),
3223 'limit' => $pagesCount,
3224 'additional' => $additional,
3228 $source = $sourceList->getDataLoader(
3232 'context_filter' => [
3233 'SITE_ID' => $this->siteId,
3234 'LANDING_ID' => $this->lid,
3235 'LANDING_ACTIVE' => $this->landingActive ?
'Y' : [
'Y',
'N'],
3241 if (is_object($source))
3244 if ($isDetailDynamic && $itemDetail)
3246 $sourceData = $source->getElementData($dynamicElementId);
3249 $disableUpdate =
true;
3259 $sourceData = $source->getElementListData();
3260 $pagesCount = max(1,
count($sourceData));
3264 if (!empty($sourceData) && is_array($sourceData))
3267 foreach ($references as $selector => $field)
3269 if (empty($field) || !is_array($field))
3273 if (empty($field[
'id']))
3277 if (mb_strpos($selector,
'@') !==
false)
3279 [$selector,] = explode(
'@', $selector);
3281 if (!isset($update[$selector]))
3283 $update[$selector] = [];
3285 $fieldCode = $field[
'id'];
3286 $fieldType = isset($manifest[
'nodes'][$selector][
'type'])
3287 ? $manifest[
'nodes'][$selector][
'type']
3290 $detailPageData = [];
3291 foreach ($sourceData as $dataItem)
3296 $fieldType == NodeType::LINK &&
3297 isset($field[
'action'])
3300 switch ($field[
'action'])
3304 $detailPage[
'text'] = isset($field[
'text'])
3307 $update[$selector][] = $detailPageData[$selector][] = $getDetailPage(
3316 if (isset($field[
'link']))
3318 $field[
'link'] = (
array) $field[
'link'];
3319 if (isset($field[
'text']))
3321 $field[
'link'][
'text'] = $field[
'text'];
3323 $update[$selector][] = $getDetailPage(
3331 if (isset($dataItem[
'LINK']))
3333 $update[$selector][] = $detailPageData[$selector][] = $getDetailPage([
3334 'text' => isset($field[
'text'])
3337 'href' => $dataItem[
'LINK'],
3338 'target' =>
'_self',
3339 'query' => isset($dataItem[
'_GET']) ? $dataItem[
'_GET'] : [],
3347 $value = isset($dataItem[$fieldCode])
3348 ? $dataItem[$fieldCode]
3350 $update[$selector][] = $value;
3353 $detailPageData[$selector][] = $getDetailPage(
3359 else if (isset($dataItem[
'LINK']))
3361 $detailPageData[$selector][] = $getDetailPage([
3362 'text' => isset($field[
'text'])
3365 'href' => $dataItem[
'LINK'],
3366 'target' =>
'_self',
3367 'query' => isset($dataItem[
'_GET']) ? $dataItem[
'_GET'] : [],
3373 if (!$update[$selector])
3375 unset($update[$selector]);
3380 isset($field[
'link']) &&
3382 $fieldType == NodeType::IMAGE ||
3383 $fieldType == NodeType::TEXT
3387 if (!isset($detailPageData[$selector]))
3391 foreach ($update[$selector] as
$i => &$value)
3393 if ($fieldType == NodeType::IMAGE)
3395 $value = (
array) $value;
3400 'text' => (string) $value,
3404 $detailPageData[$selector][
$i] &&
3405 UtilsAction::isTrue($field[
'link'])
3408 $detailPageData[$selector][
$i][
'enabled'] =
true;
3412 $detailPageData[$selector][
$i][
'enabled'] =
false;
3414 if ($detailPageData[$selector][
$i][
'enabled'])
3416 $value[
'url'] = $detailPageData[$selector][
$i];
3425 $this->access = $this::ACCESS_W;
3430 $this->access = $rememberAccess;
3437 foreach ($stubs as $selector => $stub)
3439 if (mb_strpos($selector,
'@') !==
false)
3441 [$selector,] = explode(
'@', $selector);
3443 $update[$selector] = array_fill(0, $pagesCount, $stub);
3452 $this->access = $this::ACCESS_W;
3456 'sanitize' =>
false,
3457 'skipCheckAffected' =>
true,
3462 Assets\PreProcessing::blockSetDynamicProcessing($this);
3464 $this->access = $rememberAccess;
3466 header(
'X-Bitrix24-Page: dynamic');
3469 $cache->endDataCache([
3471 'content' => $this->content,
3478 $this->runtimeRequiredUserAction = [
3479 'header' => Loc::getMessage(
'LANDING_BLOCK_MESSAGE_ERROR_NO_DATA_TITLE'),
3480 'description' => Loc::getMessage(
'LANDING_BLOCK_MESSAGE_ERROR_NO_DATA_TEXT'),
3487 (!$updated && !Landing::getEditMode())
3492 $cache->abortDataCache();
3494 $this->deleted =
true;
3513 return $this->runtimeRequiredUserAction;
3522 $this->runtimeRequiredUserAction =
$action;
3532 static $doc =
array();
3536 isset($doc[$this->
id])
3539 unset($doc[$this->
id]);
3542 if (!isset($doc[$this->
id]))
3547 $doc[$this->id]->loadHTML($this->content);
3552 return $doc[$this->id];
3561 return $this->metaData;
3573 if (!is_string($selector))
3578 if ($this->access < $this::ACCESS_W)
3580 $this->error->addError(
3582 Loc::getMessage(
'LANDING_BLOCK_ACCESS_DENIED')
3588 if (isset($manifest[
'cards'][$selector]))
3592 $resultList = $doc->querySelectorAll($selector);
3593 $resultCount =
count($resultList);
3594 if (
$count > $resultCount)
3613 $this->error->addError(
3615 Loc::getMessage(
'LANDING_BLOCK_CARD_NOT_FOUND')
3630 if (!is_string($selector))
3635 if ($this->access < $this::ACCESS_W)
3637 $this->error->addError(
3639 Loc::getMessage(
'LANDING_BLOCK_ACCESS_DENIED')
3645 if (isset($manifest[
'cards'][$selector]))
3647 $position = intval($position);
3648 $position = max($position, -1);
3649 $realPosition = max($position, 0);
3651 $resultList = $doc->querySelectorAll($selector);
3652 if (isset($resultList[$realPosition]))
3654 $parentNode = $resultList[$realPosition]->getParentNode();
3655 $refChild = isset($resultList[$position + 1])
3656 ? $resultList[$position + 1]
3661 foreach ($parentNode->getChildNodes() as $child)
3663 if ($child === $refChild)
3670 if ($parentNode && (!$refChild || $haveChild))
3675 $tmpCardName = mb_strtolower(
'tmpcard'.
randString(10));
3677 $newChild->setOwnerDocument($doc);
3682 $newChild = $resultList[$realPosition];
3684 $parentNode->insertBefore(
3691 if (History::isActive())
3694 $history->push(
'ADD_CARD', [
3696 'selector' => $selector,
3697 'position' => $position,
3703 if (isset($tmpCardName))
3707 array(
'<' . $tmpCardName .
'>',
'</' . $tmpCardName .
'>'),
3724 $this->error->addError(
3726 Loc::getMessage(
'LANDING_BLOCK_CARD_NOT_FOUND')
3740 if (!is_string($selector))
3745 if ($this->access < $this::ACCESS_W)
3747 $this->error->addError(
3749 Loc::getMessage(
'LANDING_BLOCK_ACCESS_DENIED')
3755 $position = intval($position);
3756 $resultList = $doc->querySelectorAll($selector);
3757 if (isset($resultList[$position]))
3759 $resultList[$position]->setInnerHTML(
3766 $this->error->addError(
3768 Loc::getMessage(
'LANDING_BLOCK_CARD_NOT_FOUND')
3781 if (!is_string($selector))
3787 $position = intval($position);
3788 $resultList = $doc->querySelectorAll($selector);
3789 if (isset($resultList[$position]))
3791 return $resultList[$position]->getOuterHtml();
3804 if (!is_string($selector))
3810 $resultList = $doc->querySelectorAll($selector);
3811 return count($resultList);
3822 if (!is_string($selector))
3827 if ($this->access < $this::ACCESS_W)
3829 $this->error->addError(
3831 Loc::getMessage(
'LANDING_BLOCK_ACCESS_DENIED')
3837 $position = intval($position);
3838 if (isset($manifest[
'cards'][$selector]))
3841 $resultList = $doc->querySelectorAll($selector);
3842 if (isset($resultList[$position]))
3844 $resultList[$position]->getParentNode()->removeChild(
3845 $resultList[$position]
3849 if (History::isActive())
3852 $history->push(
'REMOVE_CARD', [
3854 'selector' => $selector,
3855 'position' => $position,
3860 Assets\PreProcessing::blockUpdateNodeProcessing($this);
3866 $this->error->addError(
3868 Loc::getMessage(
'LANDING_BLOCK_CARD_NOT_FOUND')
3880 if ($this->access < $this::ACCESS_W)
3882 $this->error->addError(
3884 Loc::getMessage(
'LANDING_BLOCK_ACCESS_DENIED')
3893 foreach ($manifest[
'nodes'] as $selector => $node)
3895 if (isset(
$data[$selector]))
3897 $resultList = $doc->querySelectorAll($selector);
3899 foreach (
$data[$selector] as $pos => $value)
3901 $value = trim($value[
'tagName'] ?? $value);
3903 preg_match(
'/^[a-z0-9]+$/i', $value) &&
3904 isset($resultList[$pos]))
3906 $valueBefore[$selector][$pos] = $resultList[$pos]->getNodeName();
3907 $resultList[$pos]->setNodeName($value);
3913 if (History::isActive())
3916 $history->push(
'CHANGE_NODE_NAME_ACTION', [
3918 'valueBefore' => $valueBefore,
3919 'valueAfter' =>
$data,
3937 if ($this->access < $this::ACCESS_W)
3939 $this->error->addError(
3941 Loc::getMessage(
'LANDING_BLOCK_ACCESS_DENIED')
3951 $manifest[
'nodes'] = $manifest[
'nodes'] ?? [];
3952 foreach ($manifest[
'nodes'] as $selector => $node)
3956 if (isset(
$data[$selector]))
3958 if (!is_array(
$data[$selector]))
3964 $data[$selector] = array_filter(
$data[$selector], fn($value) => !is_null($value));
3965 $nodeData =
$data[$selector];
3968 if (!$isFind && ($node[
'isWrapper'] ??
false) ===
true)
3970 if (isset(
$data[
'#wrapper']) && $node[
'type'] ===
'styleimg')
3972 if (!is_array(
$data[
'#wrapper']))
3978 $nodeData =
$data[
'#wrapper'];
3982 $selector =
'#wrapper';
3983 if (!is_array(
$data[$selector]))
3989 $nodeData =
$data[$selector];
3993 if ($node[
'type'] ===
'img')
3995 $node = Img::changeNodeType($node, $this);
4000 $affected[$selector] = call_user_func_array(
array(
4001 Node\Type::getClassName($node[
'type']),
4013 if (isset($additional[
'appendMenu']) && $additional[
'appendMenu'])
4015 $export = $this->export();
4019 $additional[
'appendMenu'] =
false;
4021 $manifest[
'menu'] = $manifest[
'menu'] ?? [];
4022 foreach ($manifest[
'menu'] as $selector => $node)
4024 if (isset(
$data[$selector]) && is_array(
$data[$selector]))
4026 if (isset(
$data[$selector][0][0]))
4028 $data[$selector] = array_shift(
$data[$selector]);
4030 if ($additional[
'appendMenu'] && isset($export[
'menu'][$selector]))
4032 $data[$selector] = array_merge(
4033 $export[
'menu'][$selector],
4038 $resultList = $doc->querySelectorAll($selector);
4039 foreach ($resultList as $pos => $resultNode)
4041 $parentNode = $resultNode->getParentNode();
4044 $parentNode->setInnerHtml(
4060 if (!($additional[
'skipCheckAffected'] ??
false) &&
Manager::getOption(
'strict_verification_update') ===
'Y')
4066 foreach ($affected as $selector => $resultItem)
4068 $selector = trim($selector,
'.');
4073 '/class="[^"]*[\s]+(' . $selector .
')[\s"]+[^"]*"[^>]*>/s',
4074 function($match) use(&$pos)
4076 return str_replace($match[1], $match[1] .
'@' . ($pos++), $match[0]);
4081 if (is_array($resultItem))
4083 foreach ($resultItem as $pos => $affectedItem)
4085 if ($affectedItem[
'content'] ??
null)
4087 $affectedItem[
'content'] = str_replace(
'/',
'\/', $affectedItem[
'content']);
4088 $mask =
'/class="[^"]*[\s]+' . $selector .
'@' . $pos .
'[\s"]+[^"]*"[^>]*>' . $affectedItem[
'content'] .
'<\//s';
4089 $domCorrect = preg_match_all($mask,
$content);
4101 $this->error->addError(
4102 'INCORRECT_AFFECTED',
4103 Loc::getMessage(
'LANDING_BLOCK_INCORRECT_AFFECTED')
4109 Assets\PreProcessing::blockUpdateNodeProcessing($this);
4123 if (!is_array(
$data) || !isset($manifestNode[$level]))
4129 $rootSelector = $manifestNode[$level];
4132 isset($rootSelector[
'ulClassName']) &&
4133 isset($rootSelector[
'liClassName']) &&
4134 isset($rootSelector[
'aClassName']) &&
4135 is_string($rootSelector[
'ulClassName']) &&
4136 is_string($rootSelector[
'liClassName']) &&
4137 is_string($rootSelector[
'aClassName'])
4140 foreach (
$data as $menuItem)
4143 isset($menuItem[
'text']) && is_string($menuItem[
'text']) &&
4144 isset($menuItem[
'href']) && is_string($menuItem[
'href'])
4147 if ($menuItem[
'href'] ===
'page:#landing0')
4149 $res = Landing::addByTemplate(
4153 'TITLE' => $menuItem[
'text'],
4156 if (
$res->isSuccess())
4158 $menuItem[
'href'] =
'#landing' .
$res->getId();
4161 if (isset($menuItem[
'target']) && is_string($menuItem[
'target']))
4163 $target = $menuItem[
'target'];
4170 $htmlContent .=
'<a href="' .
\htmlspecialcharsbx($menuItem[
'href']) .
'" target="' . $target .
'"
4173 $htmlContent .=
'</a>';
4174 if (isset($menuItem[
'children']))
4177 $menuItem[
'children'],
4182 $htmlContent .=
'</li>';
4191 else if ($level ==
'root')
4193 $htmlContent =
'<ul class="' .
\htmlspecialcharsbx($rootSelector[
'ulClassName']) .
'"></ul>';
4197 return $htmlContent;
4207 if ($this->access < $this::ACCESS_W)
4209 $this->error->addError(
4211 Loc::getMessage(
'LANDING_BLOCK_ACCESS_DENIED')
4218 foreach (
$data as $selector => $item)
4220 $cardManifest = $manifest[
'cards'][$selector];
4222 $cardContent =
array();
4224 for (
$i = 0;
$i < $cardCount;
$i++)
4233 isset($item[
'source']) &&
4234 is_array($item[
'source'])
4237 $newContent =
array();
4238 foreach ($item[
'source'] as
$i => $source)
4240 $type = isset($source[
'type'])
4242 : self::CARD_SYM_CODE;
4243 $value = isset($source[
'value'])
4248 $type == self::CARD_SYM_CODE &&
4249 isset($cardContent[$value])
4252 $newContent[
$i] = $cardContent[$value];
4256 $type ==
'preset' &&
4257 isset($cardManifest[
'presets'][$value][
'html'])
4260 $newContent[
$i] = $cardManifest[
'presets'][$value][
'html'];
4264 $newContent[
$i] =
'';
4267 $newContent = trim(implode(
'', $newContent));
4271 $resultList = $dom->querySelectorAll($selector);
4272 if (isset($resultList[0]))
4274 $resultList[0]->getParentNode()->setInnerHtml(
4285 isset($item[
'values']) &&
4286 is_array($item[
'values'])
4289 $updNodes =
array();
4290 foreach ($item[
'values'] as $upd)
4296 if(mb_strpos($sel,
'@'))
4298 [$sel, $pos] = explode(
'@', $sel);
4300 if (!isset($updNodes[$sel]))
4302 $updNodes[$sel] =
array();
4308 if (!empty($updNodes))
4326 foreach ($node->getChildNodesArray() as $nodeChild)
4331 if (!empty($styles))
4333 foreach ($styleToRemove as $remove)
4335 if (!is_array($remove))
4337 $remove = [$remove => $remove];
4339 $styles = array_diff_key($styles, $remove);
4344 $node = $this->
removeStyle($nodeChild, $styleToRemove);
4357 if ($this->access < $this::ACCESS_V)
4359 $this->error->addError(
4361 Loc::getMessage(
'LANDING_BLOCK_ACCESS_DENIED')
4374 if (mb_strpos($selector,
'@') !==
false)
4376 [$selector, $position] = explode(
'@', $selector);
4382 if ($selector ===
'#wrapper')
4384 $selector =
'#block' . $this->id;
4394 $data[$selector] = $item;
4398 $wrapper =
'#' . $this->
getAnchor($this->
id);
4401 $styles = $manifest[
'style'][
'nodes'];
4402 $styles[$wrapper] = $manifest[
'style'][
'block'];
4403 foreach ($styles as $selector => $node)
4405 if (isset(
$data[$selector]))
4408 if (!is_array(
$data[$selector]))
4410 $data[$selector] = [
4415 if (!isset(
$data[$selector][
'classList']))
4417 $data[$selector] = [
4421 if (!isset(
$data[$selector][
'affect']))
4423 $data[$selector][
'affect'] = [];
4426 if ($selector === $wrapper)
4428 $nodesArray = $doc->getChildNodesArray();
4429 $resultList = [array_pop($nodesArray)];
4434 $resultList = $doc->querySelectorAll($selector);
4436 foreach ($resultList as $pos => $resultNode)
4438 $relativeSelector = $selector;
4441 if (!in_array($pos,
$positions[$selector],
true))
4445 $relativeSelector .=
'@' . $pos;
4450 $contentBefore = $resultNode->getOuterHTML();
4451 if ((
int)$resultNode->getNodeType() === $resultNode::ELEMENT_NODE)
4453 $resultNode->setClassName(
4454 implode(
' ',
$data[$relativeSelector][
'classList'])
4459 if (!empty(
$data[$relativeSelector][
'affect']))
4463 $data[$relativeSelector][
'affect']
4468 if (!empty(
$data[$relativeSelector][
'style']))
4473 array_merge($stylesInline,
$data[$relativeSelector][
'style'])
4476 else if (preg_match_all(
'/background-image:.*;/i', $resultNode->getAttribute(
'style'),
$matches))
4478 $resultNode->removeAttribute(
'style');
4479 $resultNode->setAttribute(
'style', implode(
'',
$matches[0]));
4482 if (History::isActive())
4485 $history->push(
'EDIT_STYLE', [
4487 'selector' => $selector,
4488 'isWrapper' => ($selector === $wrapper),
4489 'position' => $position >= 0 ? (
int)$pos : -1,
4490 'affect' =>
$data[$relativeSelector][
'affect'],
4491 'contentBefore' => $contentBefore,
4492 'contentAfter' => $resultNode->getOuterHTML(),
4501 Assets\PreProcessing::blockUpdateClassesProcessing($this);
4513 foreach ($mixed as $itemSelector => $item)
4515 if (!is_string($itemSelector))
4517 $itemSelector = $selector;
4520 isset($item[
'attrs']) &&
4521 is_array($item[
'attrs'])
4524 self::collectAllowedAttrs($item[
'attrs'], $allowed, $itemSelector);
4527 isset($item[
'additional'][
'attrsType']) ||
4528 $itemSelector ===
'additional'
4531 $manifestAttrs = self::getAttrs();
4532 $attrs = $manifestAttrs[
'bitrix'][
'attrs'];
4533 if (is_array($item[
'additional'][
'attrsType']))
4535 foreach ($attrs as $attr) {
4536 $allowed[$itemSelector][] = $attr[
'attribute'];
4539 if (is_array($item[
'attrsType']))
4541 foreach ($attrs as $attr) {
4542 $allowed[
'#wrapper'][] = $attr[
'attribute'];
4547 isset($item[
'additional'][
'attrs']) &&
4548 is_array($item[
'additional'][
'attrs'])
4551 self::collectAllowedAttrs($item[
'additional'][
'attrs'], $allowed, $itemSelector);
4554 isset($item[
'additional']) &&
4555 is_array($item[
'additional'])
4558 self::collectAllowedAttrs($item[
'additional'], $allowed, $itemSelector);
4561 isset($item[
'attribute']) &&
4562 is_string($item[
'attribute'])
4566 isset($item[
'selector']) &&
4567 is_string($item[
'selector'])
4570 $itemSelector = trim($item[
'selector']);
4574 if (!isset($allowed[$itemSelector]))
4576 $allowed[$itemSelector] = [];
4578 $allowed[$itemSelector][] = $item[
'attribute'];
4581 else if (is_array($item))
4583 self::collectAllowedAttrs($item, $allowed, $itemSelector);
4595 if ($this->access < $this::ACCESS_W)
4597 $this->error->addError(
4599 Loc::getMessage(
'LANDING_BLOCK_ACCESS_DENIED')
4606 $wrapper =
'#' . $this->
getAnchor($this->
id);
4610 self::collectAllowedAttrs($manifest[
'style'][
'nodes'], $allowedAttrs);
4611 self::collectAllowedAttrs($manifest[
'attrs'], $allowedAttrs);
4612 self::collectAllowedAttrs($manifest[
'cards'], $allowedAttrs);
4613 self::collectAllowedAttrs($manifest[
'style'][
'block'], $allowedAttrs);
4619 foreach ($allowedAttrs as $selector => $allowed)
4622 if ((isset(
$data[$selector]) && is_array(
$data[$selector])) || isset(
$data[$wrapper]) )
4625 if ($selector ===
'#wrapper')
4627 $selector = $wrapper;
4629 if ($selector == $wrapper)
4631 $nodesArray = $doc->getChildNodesArray();
4632 $resultList = [array_pop($nodesArray)];
4637 $resultList = $doc->querySelectorAll($selector);
4640 foreach (
$data[$selector] as $attrKey => $attrData)
4643 if (!($attrKey == (
string)(
int)$attrKey))
4645 $attrData = [$attrKey => $attrData];
4648 if (!is_array($attrData))
4653 foreach ($attrData as
$key => $value)
4655 if (!in_array(
$key, $allowed))
4660 $value = is_array($value) ? json_encode($value) : $value;
4663 foreach ($resultList as $pos => $resultNode)
4666 if ($attrKey == -1 || $attrKey == $pos)
4668 $valueBefore = $resultNode->getAttribute(
$key);
4670 $resultNode->setAttribute(
$key, $value);
4671 if (History::isActive())
4674 $history->push(
'EDIT_ATTRIBUTES', [
4676 'selector' => $selector,
4677 'isWrapper' => ($selector === $wrapper),
4678 'attribute' =>
$key,
4679 'position' => (
int)$attrKey,
4680 'valueBefore' => $valueBefore,
4681 'valueAfter' => $value,
4703 if (mb_strpos(
$content,
'#breadcrumb#') !==
false)
4713 'TITLE' => Loc::getMessage(
'LANDING_BLOCK_BR1'),
4717 'TITLE' => Loc::getMessage(
'LANDING_BLOCK_BR2'),
4727 $strChainTemplate =
getLocalPath(
'templates/' . $tplId .
'/chain_template.php');
4729 if (file_exists($strChainTemplate))
4731 echo include $strChainTemplate;
4733 $breadcrumb = ob_get_contents();
4742 if (mb_strpos(
$content,
'#title#') !==
false)
4746 Loc::getMessage(
'LANDING_BLOCK_TITLE'),
4761 if (!is_array(
$code))
4773 while ($row =
$res->fetch())
4775 self::parentDelete($row[
'ID']);
4784 private static function parentDelete($id)
4786 return parent::delete($id);
4796 $res = parent::getList([
4804 while ($row =
$res->fetch())
4806 parent::delete($row[
'ID']);
4814 public function getSearchContent()
4816 $manifest = $this->getManifest();
4820 if (isset($manifest[
'nodes']))
4822 foreach ($manifest[
'nodes'] as $selector => $node)
4825 $class = NodeType::getClassName($node[
'type']);
4826 if (is_callable([$class,
'getSearchableNode']))
4828 $search = array_merge($search, $class::getSearchableNode($this, $selector));
4833 return $search ? implode(
' ', $search) :
'';
4841 public function export(
array $params = [])
4853 if (!isset($params[
'clear_form']))
4855 $params[
'clear_form'] =
true;
4859 if (isset($manifest[
'cards']))
4861 foreach ($manifest[
'cards'] as $selector => $node)
4863 $cards[$selector] = [
4866 $resultList = $doc->querySelectorAll($selector);
4867 $resultListCnt =
count($resultList);
4868 foreach ($resultList as $pos =>
$result)
4870 $cards[$selector][
'source'][$pos] =
array(
4871 'value' =>
$result->getAttribute(
'data-card-preset'),
4872 'type' => Block::PRESET_SYM_CODE,
4874 if (!$cards[$selector][
'source'][$pos][
'value'])
4877 if (mb_strpos($this->
getCode(),
'menu') !==
false)
4879 $cards[$selector][
'source'][$pos][
'value'] = $resultListCnt > 0 ? 1 : 0;
4883 $cards[$selector][
'source'][$pos][
'value'] = 0;
4885 $cards[$selector][
'source'][$pos][
'type'] = Block::CARD_SYM_CODE;
4890 isset($node[
'additional'][
'attrs']) &&
4891 is_array($node[
'additional'][
'attrs'])
4894 foreach ($node[
'additional'][
'attrs'] as $attr)
4896 if (isset($attr[
'attribute']))
4898 if (!isset($allAttrs[$selector]))
4900 $allAttrs[$selector] = [];
4902 $allAttrs[$selector][] = $attr[
'attribute'];
4909 if (isset($manifest[
'nodes']))
4911 foreach ($manifest[
'nodes'] as $selector => $node)
4914 $class = NodeType::getClassName($node[
'type']);
4915 $nodes[$selector] = $class::getNode($this, $selector);
4918 if (isset($manifest[
'menu']))
4921 $exportMenu =
function($resultList) use(&$exportMenu)
4929 foreach ($resultList->getChildNodesArray() as $pos => $node)
4932 if ($node->getNodeName() ==
'LI')
4934 foreach ($node->getChildNodesArray() as $nodeInner)
4936 if ($nodeInner->getNodeName() ==
'A')
4938 $menu[$pos][
'text'] = trim($nodeInner->getTextContent());
4939 $menu[$pos][
'href'] = trim($nodeInner->getAttribute(
'href'));
4940 $menu[$pos][
'target'] = trim($nodeInner->getAttribute(
'target'));
4942 else if ($nodeInner->getNodeName() ==
'UL')
4944 $menu[$pos][
'children'] = $exportMenu($nodeInner);
4953 return array_values($menu);
4955 foreach ($manifest[
'menu'] as $selector => $menuNode)
4957 $menu[$selector] = $exportMenu($doc->querySelector($selector));
4961 if (isset($manifest[
'style'][
'nodes']))
4963 foreach ($manifest[
'style'][
'nodes'] as $selector => $node)
4965 $nodeStyle = Node\Style::getStyle($this, $selector);
4968 $styles[$selector] = $nodeStyle;
4972 isset($node[
'additional'][
'attrs']) &&
4973 is_array($node[
'additional'][
'attrs'])
4976 foreach ($node[
'additional'][
'attrs'] as $attr)
4978 if (isset($attr[
'attribute']))
4980 if (!isset($allAttrs[$selector]))
4982 $allAttrs[$selector] = [];
4984 $allAttrs[$selector][] = $attr[
'attribute'];
4991 if (!empty($manifest[
'style'][
'block']))
4993 $selector =
'#wrapper';
4994 $wrapperStyle = Node\Style::getStyle($this, $selector);
4997 $styles[$selector] = $wrapperStyle;
5002 isset($manifest[
'style'][
'block'][
'additional'][
'attrs']) &&
5003 is_array($manifest[
'style'][
'block'][
'additional'][
'attrs'])
5006 $selector =
'#wrapper';
5007 foreach ($manifest[
'style'][
'block'][
'additional'][
'attrs'] as $attr)
5009 if (isset($attr[
'attribute']))
5011 if (!isset($allAttrs[$selector]))
5013 $allAttrs[$selector] = [];
5015 $allAttrs[$selector][] = $attr[
'attribute'];
5020 if (isset($manifest[
'attrs']))
5022 foreach ($manifest[
'attrs'] as $selector => $item)
5024 if (isset($item[
'attribute']))
5026 if (!isset($allAttrs[$selector]))
5028 $allAttrs[$selector] = [];
5030 $allAttrs[$selector][] = $item[
'attribute'];
5032 else if (is_array($item))
5034 foreach ($item as $itemAttr)
5036 if (isset($itemAttr[
'attribute']))
5038 if (!isset($allAttrs[$selector]))
5040 $allAttrs[$selector] = [];
5042 $allAttrs[$selector][] = $itemAttr[
'attribute'];
5050 $params[
'clear_form'] &&
5051 isset($allAttrs[
'.bitrix24forms'])
5054 unset($allAttrs[
'.bitrix24forms']);
5058 if (isset($allAttrs[
'#wrapper']))
5060 $allAttrsNew[
'#wrapper'] = [];
5061 $nodesArray = $doc->getChildNodesArray();
5062 $resultList = [array_pop($nodesArray)];
5063 foreach ($resultList as $pos =>
$result)
5065 foreach ($allAttrs[
'#wrapper'] as $attrKey)
5067 if (!isset($allAttrsNew[
'#wrapper'][$pos]))
5069 $allAttrsNew[
'#wrapper'][$pos] = [];
5071 $allAttrsNew[
'#wrapper'][$pos][$attrKey] =
$result->getAttribute($attrKey);
5074 unset($allAttrs[
'#wrapper']);
5076 foreach ($allAttrs as $selector => $attr)
5078 $resultList = $doc->querySelectorAll($selector);
5079 foreach ($resultList as $pos =>
$result)
5081 if (!isset($allAttrsNew[$selector]))
5083 $allAttrsNew[$selector] = [];
5085 if (!isset($allAttrsNew[$selector][$pos]))
5087 $allAttrsNew[$selector][$pos] = [];
5089 foreach ($attr as $attrKey)
5091 $allAttrsNew[$selector][$pos][$attrKey] =
$result->getAttribute($attrKey);
5096 $allAttrs = $allAttrsNew;
5097 unset($allAttrsNew);
5104 'attrs' => $allAttrs,
5105 'dynamic' => $this->dynamicParams,
5124 $res = Internals\BlockTable::getList([
5128 'order' => [
'SORT' =>
'desc'],
5130 while ($row =
$res->fetch())
5146 !defined(
'LANDING_MUTATOR_MODE') ||
5147 LANDING_MUTATOR_MODE !==
true
5150 throw new \Bitrix\Main\SystemException(
5151 'Disabled for direct access.'
5169 !defined(
'LANDING_MUTATOR_MODE') ||
5170 LANDING_MUTATOR_MODE !==
true
5173 throw new \Bitrix\Main\SystemException(
5174 'Disabled for direct access.'
5188 public static function delete(
$id)
5191 !defined(
'LANDING_MUTATOR_MODE') ||
5192 LANDING_MUTATOR_MODE !==
true
5195 throw new \Bitrix\Main\SystemException(
5196 'Disabled for direct access.'
5201 return parent::delete(
$id);
5212 return parent::getList([
5216 '=TPL_CODE' => $tplCode,
5232 !defined(
'LANDING_MUTATOR_MODE') ||
5233 LANDING_MUTATOR_MODE !==
true
5236 throw new \Bitrix\Main\SystemException(
5237 'Disabled for direct access.'
5242 return parent::getList(
$fields);
5255 Asset::getInstance()->getJs();
5256 Asset::getInstance()->getCss();
5257 Asset::getInstance()->getStrings();
5259 $targetTypeList =
array(
'JS',
'CSS');
5260 $CSSList = $JSList = $stringsList = [];
5262 foreach ($targetTypeList as $targetType)
5264 $targetAssetList = Asset::getInstance()->getTargetList($targetType);
5266 foreach ($targetAssetList as $targetAsset)
5268 $assetInfo = Asset::getInstance()->getAssetInfo($targetAsset[
'NAME'], \
Bitrix\
Main\
Page\AssetMode::ALL);
5270 if (!empty($assetInfo[
'JS']))
5272 $JSList = array_merge($JSList, $assetInfo[
'JS']);
5275 if (!empty($assetInfo[
'CSS']))
5277 $CSSList = array_merge($CSSList, $assetInfo[
'CSS']);
5280 if (!empty($assetInfo[
'STRINGS']))
5282 $stringsList = array_merge($stringsList, $assetInfo[
'STRINGS']);
5288 'js' => array_unique($JSList),
5289 'css' => array_unique($CSSList),
5290 'strings' => array_unique($stringsList),
5307 'CONTENT' =>
'%' . $needed .
'%',
5317 $res = parent::getList([
5320 'SITE_ID' =>
'LANDING.SITE_ID',
5324 if ($row =
$res->fetch())
5331 'ID' => $row[
'LID'],
5354 $path2Component = \CComponentEngine::MakeComponentPath(
$componentName);
5355 if ($path2Component !==
'')
5360 return file_exists($componentFile) && is_file($componentFile);
const LOCATION_AFTER_TEMPLATE
const FILTER_SKIP_HIDDEN_BLOCKS
const FILTER_SKIP_SYSTEM_BLOCKS
static getRepository(bool $installRepo=true)
static parseManifest(string $content)
getMenuHtml($data, $manifestNode, $level='root')
save(array $additionalFields=[])
getRuntimeRequiredUserAction()
static getList($fields=array())
static getFavorites(?string $tplCode)
adjustCards($selector, $count, &$changed=false)
static getBlockContent($id, $editMode=false, array $params=array())
static getAjaxInitiatedAssets()
static getMessageBlock($params, $template='')
saveAssets(array $assets)
static getNormalizedBlock(string $code)
static removeAsUsed(string $blockCode)
checkDesignedManifest(array $manifest)
static update($id, $fields=array())
static getManifestFile($code)
static getBlockNamespace($code)
static getContentFromRepository(string $code, string $namespace=null)
static getSpecialManifest(string $type)
updateNodes($data, $additional=array())
setCardContent($selector, $position, $content)
const DEFAULT_WRAPPER_STYLE
changeFavoriteMeta(array $meta)
$runtimeRequiredUserAction
saveContent(string $content, $designed=false)
saveDynamicParams(array $sourceParams=[], array $params=[])
static getLandingRowByBlockId($id, array $select=array('ID'))
static getBlockPath($code, $namespace=null)
removeStyle(DOM\Node $node, array $styleToRemove)
static collectAllowedAttrs(array $mixed, array &$allowed, $selector=null)
static getRowByBlockId($id, array $select=array('ID'))
getManifest(bool $extended=false, bool $missCache=false, array $params=array())
static clearRepositoryCache()
updateCards(array $data=array())
setAllowedByTariff(bool $mark)
array $allowedRepoExtensions
setRuntimeRequiredUserAction(array $action)
cloneCard($selector, $position, $content='')
static deleteByCode($code)
static fillLanding(Landing $landing, $limit=0, array $params=array())
removeCard($selector, $position)
static createFromRepository(Landing $landing, string $code, array $data=array())
localizationManifest(array &$manifest, array $lang)
static getLastUsed(int $count=15)
getCardContent($selector, $position)
static markAsUsed(string $blockCode)
view($edit=false, \Bitrix\Landing\Landing $landing=null, array $params=array())
static replaceMetaMarkers($content)
static getLandingIdByBlockId($id)
static checkComponentExists(string $componentName)
static isNewBlock($block)
static cloneForEdit(\Bitrix\Landing\Landing $landing)
static isContains(int $entityId, string $needed, bool $isLanding=false)
__construct($id, $data=[], array $params=[])
static prepareBlockContentFromRepository($block)
getDynamicParams($id=null)
static search($query, array $filter=[], array $select=['LID'], array $group=['LID'])
static publicationBlocks(\Bitrix\Landing\Landing $landing)
static getReplaceRequisiteCompanyNameForContent(string $xmlId)
static getReplacesForContent(int $siteId, bool $attributesReplace=true)
static getDownloadLink(string $scope, int $blockId, ?int $fileId=null)
static addToBlock(int $blockId, $fileId, bool $temp=false)
static getFilesFromBlockContent($blockId, $content)
static changeValue($key, $value)
static getOption($code, $default=null)
static setPageTitle($title, $single=false)
static getTemplateId($siteId=null)
static isAutoPublicationEnabled()
static blocksPublication(\Bitrix\Landing\Landing $landing, $_245979103=null)
static getManifest($lid, $block, array $params=array())
static isAllowed(string $code, array $params=[], string $cacheSalt='')
static get(int $id, bool $active=false, bool $force=false)
static getList(array $parameters=array())
static setStyle(Element $node, $styleList, $append=false)
static getStyle(Element $node, $singleStyle=true)
if( $strWarning=="") if($strWarning=="") $componentPath
for($fileNumber="";; $fileNumber++) $pageTitle
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
$_SERVER["DOCUMENT_ROOT"]
if(!is_null($config))($config as $configItem)(! $configItem->isVisible()) $code
if(!defined('SITE_ID')) $lang
if(!is_array($deviceNotifyCodes)) $access
htmlspecialcharsbx($string, $flags=ENT_COMPAT, $doubleEncode=true)
getLocalPath($path, $baseFolder="/bitrix")
randString($pass_len=10, $pass_chars=false)
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
if(empty($signedUserToken)) $key
</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."%"
if($inWords) echo htmlspecialcharsbx(Number2Word_Rus(roundEx($totalVatSum $params['CURRENCY']