Current Path : /var/www/www-root/data/www.catalog.monolith-realty.ru/bitrix/modules/landing/lib/node/ |
Current File : /var/www/www-root/data/www.catalog.monolith-realty.ru/bitrix/modules/landing/lib/node/styleimg.php |
<?php namespace Bitrix\Landing\Node; use Bitrix\Landing\Block; use Bitrix\Landing\File; use Bitrix\Landing\Manager; use Bitrix\Landing\Node; use Bitrix\Main\Web\DOM; /** * Fake node for images, then add in design. Not using in edit panel! */ class StyleImg extends Node { public const STYLES_WITH_IMAGE = [ 'background', 'block-default', 'block-border', ]; protected const STYLES_VARIABLES_WITH_FILES = [ '1x' => [ '--bg-url' => "url('#url#')", ], '2x' => [ '--bg-url-2x' => "url('#url#')", ], ]; protected const STYLES_URL_MARKER = '#url#'; protected const STYLES_URL_REGEXP = '/url\([\'"]?([^\'")]+)[\'")]?\)/i'; protected const STYLES_NODE_CLASS = 'g-bg-image'; /** * Get class - frontend handler. * @return string */ public static function getHandlerJS() { return 'BX.Landing.Block.Node.StyleImg'; } /** * Save data for this node. * @param Block $block Block instance. * @param string $selector Selector. * @param array $data Data array. * @return void */ public static function saveNode(Block $block, $selector, array $data): void { if (!self::isCorrectNodeType($block, $selector)) { Img::saveNode($block, $selector, $data); } else { $resultList = Node\Style::getNodesBySelector($block, $selector); $files = null; foreach ($data as $pos => $value) { $id = isset($value['id']) ? (int)$value['id'] : 0; $id2x = isset($value['id2x']) ? (int)$value['id2x'] : 0; // check permissions to this file ids if ($id || $id2x) { if ($files === null) { $files = File::getFilesFromBlock($block->getId()); } if (!in_array($id, $files)) { $id = 0; } if (!in_array($id2x, $files)) { $id2x = 0; } } if (isset($resultList[$pos])) { // update in content if ($resultList[$pos]->getTagName() !== 'IMG') { $styles = DOM\StyleInliner::getStyle($resultList[$pos]); if (isset($styles['--bg-url'])) { $styles['background-image'] = ''; } if (!isset($styles['background'])) { if ($id) { $stylesChanged = false; $resultList[$pos]->setAttribute('data-fileid', $id); foreach (self::STYLES_VARIABLES_WITH_FILES['1x'] as $var => $pattern) { if (isset($styles[$var])) { $fileArray = \CFile::GetFileArray($id); $styles[$var] = str_replace( self::STYLES_URL_MARKER, $fileArray['SRC'], $pattern ); $stylesChanged = true; } } if ($id2x) { $resultList[$pos]->setAttribute('data-fileid2x', $id2x); foreach (self::STYLES_VARIABLES_WITH_FILES['2x'] as $var => $pattern) { if (isset($styles[$var])) { $fileArray = \CFile::GetFileArray($id2x); $styles[$var] = str_replace( self::STYLES_URL_MARKER, $fileArray['SRC'], $pattern ); $stylesChanged = true; } } } if (!$stylesChanged) { $classList = $resultList[$pos]->getAttribute('class'); if (!stripos($classList, self::STYLES_NODE_CLASS)) { $classList .= ' ' . self::STYLES_NODE_CLASS; } $resultList[$pos]->setAttribute('class', $classList); $fileArray1x = \CFile::GetFileArray($id); $src1x = $fileArray1x['SRC']; $styles['--bg-url'] = "url('{$src1x}');"; if ($id2x <= 0 && $id > 0) { $id2x = $id; } $fileArray2x = \CFile::GetFileArray($id2x); $src2x = $fileArray2x['SRC']; $styles['--bg-url-2x'] = "url('{$src2x}');"; $stylesChanged = true; } if ($stylesChanged) { DOM\StyleInliner::setStyle($resultList[$pos], $styles); } } else { foreach (['fileid', 'fileid2x'] as $dataCode) { $attribute = 'data-' . $dataCode; $oldId = $resultList[$pos]->getAttribute($attribute); if ($oldId > 0) { File::deleteFromBlock( $block->getId(), $oldId ); } } } } } } } } } /** * Get data for this node. * @param Block $block Block instance. * @param string $selector Selector. * @return array */ public static function getNode(Block $block, $selector): array { if (!self::isCorrectNodeType($block, $selector)) { $data = Img::getNode($block, $selector); } else { $data = []; $resultList = Node\Style::getNodesBySelector($block, $selector); foreach ($resultList as $pos => $res) { $data[$pos] = [ 'src' => '', 'src2x' => '', 'id' => null, 'id2x' => null, 'alt' => '', 'isLazy' => 'N', ]; if ($res->getTagName() !== 'IMG') { $isLazy = $res->getAttribute('data-lazy-styleimg') && $res->getAttribute('data-lazy-styleimg') === 'Y' ; $nodeData = $isLazy ? self::getNodeDataLazy($res) : self::getNodeData($res) ; if ($nodeData) { $files = File::getFilesFromBlock($block->getId()); if (!in_array($nodeData['id'], $files)) { continue; } if ($nodeData['id2x'] && !in_array($nodeData['id'], $files)) { unset($nodeData['id2x'], $nodeData['src2x'], $nodeData['lazyOrigSrc2x']); } $data[$pos] = $nodeData; } } } } return $data; } protected static function getNodeData(DOM\Node $node): ?array { $data = null; $styles = DOM\StyleInliner::getStyle($node); if ( (!isset($styles['background']) || $styles['background'] === '') && (!isset($styles['background-image']) || $styles['background-image'] === '') ) { $fileId = (int)$node->getAttribute('data-fileid'); if ($fileId) { $data = []; $data['id'] = $fileId; $data['src'] = self::getSrcFromStyles($styles, '1x'); $fileId2x = (int)$node->getAttribute('data-fileid2x'); if ($fileId2x) { $data['id2x'] = $fileId2x; $data['src2x'] = self::getSrcFromStyles($styles, '2x'); } } } return $data; } protected static function getNodeDataLazy(DOM\Node $node): ?array { $data = null; $styles = $node->getAttribute('data-style'); if ($styles) { $stylesConverted = []; foreach (explode(';', $styles) as $style) { // can has mode then one ':', can't use explode! $separator = strpos( $style, ':'); $key = substr($style, 0, $separator); $val = substr($style, $separator + 1); $stylesConverted[$key] = trim($val); } $fileId = (int)$node->getAttribute('data-fileid'); if ($fileId) { $data = ['isLazy' => 'Y']; $data['id'] = $fileId; $data['lazyOrigSrc'] = self::getSrcFromStyles($stylesConverted, '1x'); $fileId2x = (int)$node->getAttribute('data-fileid2x'); if ($fileId2x) { $data['id2x'] = $fileId2x; $data['lazyOrigSrc2x'] = self::getSrcFromStyles($stylesConverted, '2x'); } } } return $data; } /** * Find src in inline styles variables * @param array $styles * @param string $resolution * @return string|null */ protected static function getSrcFromStyles(array $styles, string $resolution): ?string { if (array_key_exists($resolution, self::STYLES_VARIABLES_WITH_FILES)) { foreach (self::STYLES_VARIABLES_WITH_FILES[$resolution] as $var => $pattern) { $matches = []; if ( $styles[$var] && preg_match(self::STYLES_URL_REGEXP, $styles[$var], $matches) && $matches[1] ) { return Manager::getUrlFromFile($matches[1]); } } } return null; } /** * This node may participate in searching. * @param Block $block Block instance. * @param string $selector Selector. * @return array */ public static function getSearchableNode(Block $block, string $selector): array { if (!self::isCorrectNodeType($block, $selector)) { $data = Img::getSearchableNode($block, $selector); } else { $data = []; } return $data; } /** * Find src in inline styles variables * @param Block $block Block instance. * @param string $selector Selector. * @return bool */ protected static function isCorrectNodeType(Block $block, string $selector): bool { $matches = []; $pattern = '/' . substr($selector, 1) . '[^\"]*/i'; if (preg_match($pattern, $block->getContent(), $matches) === 1) { $pattern = '/[\s]?' . self::STYLES_NODE_CLASS . '[\s]?/i'; if (preg_match($pattern, $matches[0]) === 1) { return true; } } return false; } }