Current Path : /var/www/www-root/data/www/info.monolith-realty.ru/bitrix/modules/landing/lib/update/ |
Current File : /var/www/www-root/data/www/info.monolith-realty.ru/bitrix/modules/landing/lib/update/block.php |
<?php namespace Bitrix\Landing\Update; use \Bitrix\Landing\Block as BlockCore; use \Bitrix\Landing\UpdateBlock; use \Bitrix\Landing\Rights; use \Bitrix\Landing\Internals\BlockTable; class Block extends \Bitrix\Main\Update\Stepper { /** * Items count for one step. */ const STEPPER_COUNT = 1; /** * Target module for stepper. * @var string */ protected static $moduleId = 'landing'; /** * Register new block for stepper update. * @param string|string[] $codes Block codes. * @param array $params Additional params. * @return void */ public static function register($codes, array $params = []) { if (!is_array($codes)) { $codes = [$codes]; } $res = UpdateBlock::getList([ 'select' => [ 'ID', 'CODE' ], 'filter' => [ '=CODE' => $codes ] ]); while ($row = $res->fetch()) { UpdateBlock::update($row['ID'], [ 'LAST_BLOCK_ID' => 0, 'PARAMS' => $params ]); $codes = array_diff($codes, [$row['CODE']]); } if (!empty($codes)) { foreach ($codes as $code) { UpdateBlock::add([ 'CODE' => $code, 'PARAMS' => $params ]); } } // reg stepper \Bitrix\Main\Update\Stepper::bindClass( 'Bitrix\Landing\Update\Block', 'landing', 600 ); } /** * Unregister block for stepper update. * @param string[] $codes Block codes. * @return void */ public static function unregister($codes) { if (!is_array($codes)) { $codes = [$codes]; } $res = UpdateBlock::getList([ 'select' => [ 'ID' ], 'filter' => [ '=CODE' => $codes ] ]); while ($row = $res->fetch()) { UpdateBlock::delete($row['ID']); } } /** * Preparing css classes array before set to node. * @param array|string $classes Base classes to set. * @param array $addClasses New classes for base array. * @param array $removeClasses Classes to remove from base array. * @return array */ protected static function prepareClassesToSet($classes, array $addClasses = [], array $removeClasses = []) { if (is_array($classes) && isset($classes['classList'])) { $classes = $classes['classList']; } if (!is_array($classes)) { $classes = [$classes]; } $classesUnique = array_unique($classes); // all nodes have equal classes if (count($classesUnique) === 1) { $result = [ [ 'classList' => $classesUnique[0], 'suffix' => '', ], ]; } // different classes else { $classesSorted = []; // find most frequent class $counts = array_count_values($classes); arsort($counts); $mainClass = key($counts); foreach ($classes as $pos => $class) { if ($class !== $mainClass) { $classesSorted[] = [ 'classList' => $class, 'suffix' => '@' . $pos, ]; } } $result = array_merge( [ [ 'classList' => $mainClass, 'suffix' => '', ], ], $classesSorted ); } // add and remove classes foreach ($result as $pos => $class) { if ($addClasses || $removeClasses) { $classList = explode(' ', $class['classList']); if ($addClasses) { $classList = array_merge($classList, $addClasses); } if ($removeClasses) { $classList = array_diff($classList, $removeClasses); } $result[$pos]['classList'] = implode(' ', array_unique($classList)); } } return $result; } /** * Execute one step. * @param array $filter Filter for step. * @param int &$count Updated count. * @param int $limit Select limit. * @param array $params Additional params. * @return int Last updated id. */ public static function executeStep(array $filter, &$count = 0, $limit = 0, array $params = []) { $lastId = 0; Rights::setOff(); $res = BlockTable::getList([ 'select' => [ 'ID', 'CONTENT' ], 'filter' => $filter, 'order' => [ 'ID' => 'asc' ], 'limit' => $limit ?: null, ]); while ($row = $res->fetch()) { $lastId = $row['ID']; $count++; // gets content from exist block $block = new BlockCore($row['ID']); $block->setAccess(BlockCore::ACCESS_X); $export = $block->export([ 'clear_form' => false ]); // and apply to the new layout $newContent = BlockCore::getContentFromRepository( $block->getCode() ); $block->saveContent($newContent); // update cards if ($export['cards']) { $block->updateCards( $export['cards'] ); } // update style if ($export['style']) { foreach ($export['style'] as $selector => $classes) { $addClasses = []; if (isset($params[$selector]['new_class'])) { if (is_array($params[$selector]['new_class'])) { if (count($params[$selector]['new_class']) > 1) { $addClasses = $params[$selector]['new_class']; } else { $addClasses = explode(' ', trim($params[$selector]['new_class'][0])); } } else { $addClasses = explode(' ', trim($params[$selector]['new_class'])); } } $removeClasses = []; if (isset($params[$selector]['remove_class'])) { if (is_array($params[$selector]['remove_class'])) { if (count($params[$selector]['remove_class']) > 1) { $removeClasses = $params[$selector]['remove_class']; } else { $removeClasses = explode(' ', trim($params[$selector]['remove_class'][0])); } } else { $removeClasses = explode(' ', trim($params[$selector]['remove_class'])); } } // change wrapper to valid selector if ($selector == '#wrapper') { $selector = '#' . $block->getAnchor($block->getId()); } foreach (self::prepareClassesToSet($classes, $addClasses, $removeClasses) as $class) { $block->setClasses(array( $selector . $class['suffix'] => array( 'classList' => [$class['classList']] ) )); } } } // update nodes if ($export['nodes']) { foreach ($export['nodes'] as $selector => $node) { if (isset($params[$selector]['update_video_to_lazyload'])) { $export['nodes'][$selector] = self::updateVideoToLazyload($node); } } $block->updateNodes( $export['nodes'] ); } // update menu if ($export['menu']) { $block->updateNodes( $export['menu'] ); } // update attrs if ($export['attrs']) { if (isset($export['attrs']['#wrapper'])) { $wrapperCode = '#' . $block->getAnchor($block->getId()); $export['attrs'][$wrapperCode] = $export['attrs']['#wrapper']; unset($export['attrs']['#wrapper']); } $block->setAttributes( $export['attrs'] ); } // and save block with new layout and old content $block->save(); } Rights::setOn(); return $lastId; } /** * One step of stepper. * @param array &$result Result array. * @return bool */ public function execute(array &$result) { $finished = true; // check queue $res = UpdateBlock::getList([ 'select' => [ 'ID', 'CODE', 'LAST_BLOCK_ID', 'PARAMS' ], 'order' => [ 'ID' => 'asc' ], 'limit' => 1 ]); if (!($rowUpdate = $res->fetch())) { return false; } // gets common quantity $res = BlockTable::getList([ 'select' => [ new \Bitrix\Main\Entity\ExpressionField( 'CNT', 'COUNT(*)' ) ], 'filter' => [ '=CODE' => $rowUpdate['CODE'], '!=DESIGNED' => 'Y', ] ]); // skip blocks that not exists $row = $res->fetch(); if(!$row || (int) $row['CNT'] === 0) { UpdateBlock::delete( $rowUpdate['ID'] ); return $this->execute($result); } $result['count'] = $row['CNT']; // gets finished count $res = BlockTable::getList([ 'select' => [ new \Bitrix\Main\Entity\ExpressionField( 'CNT', 'COUNT(*)' ) ], 'filter' => [ '<=ID' => $rowUpdate['LAST_BLOCK_ID'], '=CODE' => $rowUpdate['CODE'], '!=DESIGNED' => 'Y', ] ] ); if ($row = $res->fetch()) { $result['steps'] = $row['CNT']; } // gets block group for update $lastId = $this::executeStep([ '>ID' => $rowUpdate['LAST_BLOCK_ID'], '=CODE' => $rowUpdate['CODE'], '!=DESIGNED' => 'Y', ], $count, $this::STEPPER_COUNT, $rowUpdate['PARAMS'] ); if ($lastId > 0) { $finished = false; } // finish or continue if (!$finished) { UpdateBlock::update($rowUpdate['ID'], [ 'LAST_BLOCK_ID' => $lastId ]); return true; } else { UpdateBlock::delete($rowUpdate['ID']); return true;//for check next item in UpdateBlock } } protected static function updateVideoToLazyload($nodes) { foreach($nodes as $key => $node) { if($node['src']) { // youtube if (strpos($node['src'], 'www.youtube.com') !== false) { if ($node['source']) { $pattern = "#(youtube\\.com|youtu\\.be|youtube\\-nocookie\\.com)\\/(watch\\?(.*&)?v=|v\\/|u\\/|embed\\/?)?(videoseries\\?list=(.*)|[\\w-]{11}|\\?listType=(.*)&list=(.*))(.*)#"; if(preg_match($pattern, $node['source'], $matches)) { $nodes[$key]['preview'] = "//img.youtube.com/vi/{$matches[4]}/sddefault.jpg"; } } } } } return $nodes; } }