Server IP : 80.87.202.40 / Your IP : 216.73.216.169 Web Server : Apache System : Linux rospirotorg.ru 5.14.0-539.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 5 22:26:13 UTC 2024 x86_64 User : bitrix ( 600) PHP Version : 8.2.27 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/landing/lib/assets/preprocessing/ |
Upload File : |
<?php namespace Bitrix\Landing\Assets\PreProcessing; use \Bitrix\Landing\Block; use \Bitrix\Landing\Site; use \Bitrix\Landing\Manager; class Theme { /** * Manifest path template. */ const FILE_PATH_SITE_MANIFEST = '/bitrix/components/bitrix/landing.demo/data/site/#code#/.theme.php'; /** * Default page template for page creating. */ const DEFAULT_PAGE_TEMPLATE = 'empty'; /** * Returns all class attribute from block content. * @param string $content Block content. * @return array */ private static function getStyleClasses(string $content): array { if (preg_match_all('/class="([^"]+)"/', $content, $matches)) { $allClasses = []; foreach ($matches[1] as $classes) { // some hack for future search optimization $allClasses[] = ' ' . $classes . ' '; } return $allClasses; } return []; } /** * Returns manifest array by template code. * @param string $tplCode Template code. * @return array */ private static function getThemeManifest(string $tplCode): array { $path = self::FILE_PATH_SITE_MANIFEST; $path = Manager::getDocRoot() . str_replace('#code#', $tplCode, $path); if (file_exists($path)) { $manifest = include $path; if (is_array($manifest)) { return $manifest; } } return []; } /** * Removes siblings classes and returns new class attribute. * @param string $classString Attribute class string. * @param array $targetClasses New classes for this attribute. * @param string $namespace Namespace for getting styles data. * @return string */ private static function removeSiblingsClasses(string $classString, array $targetClasses, string $namespace): string { static $classesGroups = []; $styleManifest = Block::getStyle(); // build classes groups (static cache) if (!array_key_exists($namespace, $classesGroups)) { $classesGroups[$namespace] = []; if ( isset($styleManifest[$namespace]['style']) && is_array($styleManifest[$namespace]['style']) ) { foreach ($styleManifest[$namespace]['style'] as $style) { if (isset($style['items']) && is_array($style['items'])) { $classesGroup = []; foreach ($style['items'] as $item) { if (isset($item['value']) && is_string($item['value'])) { $classesGroup[] = trim($item['value']); } } if ($classesGroup) { $classesGroups[$namespace][] = $classesGroup; } } } } } $allClasses = $classesGroups[$namespace]; // local function to find siblings $findSiblings = function($targetClass) use($allClasses) { $targetClass = trim($targetClass); foreach ($allClasses as $classes) { if (in_array($targetClass, $classes)) { return $classes; } } return []; }; // try to find siblings of each target class foreach ($targetClasses as $targetClass) { // and remove from class attribute foreach ($findSiblings($targetClass) as $classRemove) { $classString = str_replace(' ' . $classRemove . ' ', ' ', $classString); } } return trim($classString); } /** * Processing theme manifest. * @param Block $block Block instance. * @return void */ public static function processing(Block $block): void { // first we check all we need $blockMetadata = $block->getMeta(); if (!$blockMetadata['SITE_TPL_CODE']) { return; } $themeManifest = self::getThemeManifest($blockMetadata['SITE_TPL_CODE']); if ( isset($themeManifest['newBlockStyle']) && is_array($themeManifest['newBlockStyle']) ) { $themeManifest = $themeManifest['newBlockStyle']; } else { return; } $contentWasChanged = false; $blockContent = $block->getContent(); $blockClasses = self::getStyleClasses($blockContent); if (!$blockClasses) { return; } $blockManifest = $block->getManifest(); if (!isset($blockManifest['namespace'])) { return; } $blockNamespace = $blockManifest['namespace']; $semanticManifest = Block::getSemantic(); if (isset($semanticManifest[$blockNamespace])) { $semanticManifest = $semanticManifest[$blockNamespace]; } else { return; } // work with theme manifest foreach ($themeManifest as $semanticCode => $needClasses) { if (!isset($semanticManifest[$semanticCode])) { continue; } if (!is_array($needClasses)) { $needClasses = (array)$needClasses; } // by specific style class we redefine some classes foreach ((array) $semanticManifest[$semanticCode] as $semanticClass) { $semanticClass = ' ' . $semanticClass . ' '; foreach ($blockClasses as $classesString) { if (mb_strpos($classesString, $semanticClass) !== false) { $contentWasChanged = true; $newClassString = self::removeSiblingsClasses( $classesString, $needClasses, $blockNamespace ); $blockContent = str_replace( 'class="' . trim($classesString) . '"', 'class="' . $newClassString . ' ' . implode(' ', $needClasses) . '"', $blockContent ); } } } } // save content to the block if ($contentWasChanged) { $block->saveContent($blockContent); } } /** * Finds new page template in site manifest, returns DEFAULT_PAGE_TEMPLATE by default. * @param int $siteId Site id. * @return string */ public static function getNewPageTemplate(int $siteId): string { static $sites = []; if (!array_key_exists($siteId, $sites)) { $sites[$siteId] = null; $res = Site::getList([ 'select' => [ 'XML_ID', 'TPL_CODE' ], 'filter' => [ 'ID' => $siteId ] ]); if ($row = $res->fetch()) { if (!$row['TPL_CODE'] && mb_strpos($row['XML_ID'], '|')) { [, $row['TPL_CODE']] = explode('|', $row['XML_ID']); } if ($row['TPL_CODE']) { $manifest = self::getThemeManifest($row['TPL_CODE']); if ( isset($manifest['newPageTemplate'][0]) && is_string($manifest['newPageTemplate'][0]) ) { $sites[$siteId] = $manifest['newPageTemplate'][0]; } } } } if ($sites[$siteId]) { return $sites[$siteId]; } return self::DEFAULT_PAGE_TEMPLATE; } }