• Модуль: landing
  • Путь к файлу: ~/bitrix/modules/landing/lib/update/block/nodeattributes.php
  • Класс: BitrixLandingUpdateBlockNodeAttributes
  • Вызов: NodeAttributes::updateBlock
private function updateBlock(Block $block)
{
	$code = $block->getCode();
	$doc = $block->getDom();

	foreach ($this->dataToUpdate['BLOCKS'][$code]['NODES'] as $selector => $rules)
	{
		$resultList = $doc->querySelectorAll($selector);

//			prepare ATTRS
		$nodeAttrs = array();
		if (is_array($rules['ATTRS_ADD']) && !empty($rules['ATTRS_ADD']))
		{
			$nodeAttrs = array_merge($nodeAttrs, $rules['ATTRS_ADD']);
		}
		if (is_array($rules['ATTRS_REMOVE']) && !empty($rules['ATTRS_REMOVE']))
		{
			$nodeAttrs = array_merge($nodeAttrs, array_fill_keys(array_values($rules['ATTRS_REMOVE']), ''));
		}

//			PROCESS
		foreach ($resultList as $nth => $resultNode)
		{
//				FILTER
//				use until cant add some filters in DOMParser
			if (is_array($rules['FILTER']) && !empty($rules['FILTER']))
			{
				$notFilterd = false;
//					By content. May have 'NOT' key
				if (
					isset($rules['FILTER']['CONTENT']) && is_array($rules['FILTER']['CONTENT']) &&
					(
						$rules['FILTER']['CONTENT']['VALUE'] != $resultNode->getInnerHTML() ||
						(
							$rules['FILTER']['CONTENT']['NOT'] &&
							$rules['FILTER']['CONTENT']['VALUE'] == $resultNode->getInnerHTML()
						)
					)
				)
				{
					$notFilterd = true;
				}

//					by position in DOM
				if (
					isset($rules['FILTER']['NTH']) && is_array($rules['FILTER']['NTH']) &&
					isset($rules['FILTER']['NTH']['VALUE']) &&
					$nth + 1 != $rules['FILTER']['NTH']['VALUE']
				)
				{
					$notFilterd = true;
				}
				
				if ($notFilterd)
				{
					continue;
				}
			}

//				CLASSES
			$classesChange = false;
			$nodeClasses = $resultNode->getClassList();
			if (is_array($rules['CLASSES_REMOVE']) && !empty($rules['CLASSES_REMOVE']))
			{
				$nodeClasses = array_diff($nodeClasses, $rules['CLASSES_REMOVE']);
				$classesChange = true;
			}
			
			if (is_array($rules['CLASSES_ADD']) && !empty($rules['CLASSES_ADD']))
			{
				$nodeClasses = array_merge($nodeClasses, $rules['CLASSES_ADD']);
				$classesChange = true;
			}
			
			if (is_array($rules['CLASSES_REPLACE']) &&
				array_key_exists('PATTERN', $rules['CLASSES_REPLACE']) &&
				array_key_exists('REPLACE', $rules['CLASSES_REPLACE']))
			{
				$nodeClassesStr = implode(' ', $nodeClasses);
				$nodeClassesReplace = preg_replace(
					'/' . $rules['CLASSES_REPLACE']['PATTERN'] . '/i',
					$rules['CLASSES_REPLACE']['REPLACE'],
					$nodeClassesStr
				);
				if ($nodeClassesReplace !== null)
				{
					$nodeClasses = explode(' ', $nodeClassesReplace);
					$classesChange = true;
				}
			}
			
//				APPLY changes
			$nodeClasses = array_unique($nodeClasses);
			if ($classesChange)
			{
				$resultNode->setClassName(implode(' ', $nodeClasses));
			}

//				ID
			if ($rules['ID_REMOVE'] && $rules['ID_REMOVE'] == 'Y')
			{
				$resultNode->removeAttribute('id');
			}

//				ATTRS
			foreach ($nodeAttrs as $name => $value)
			{
//					reduce string (in attributes may be a complex data)
				$value = str_replace(array("n", "t"), "", $value);
				
				if ($value)
				{
					$resultNode->setAttribute($name, is_array($value) ? json_encode($value) : $value);
				}
				else
				{
					$resultNode->removeAttribute($name);
				}
			}

//				REMOVE NODE
			if (isset($rules['NODE_REMOVE']) && $rules['NODE_REMOVE'] === true)
			{
				$resultNode->getParentNode()->removeChild($resultNode);
			}
			
//				REPLACE CONTENT by regexp
//				be CAREFUL!
			if (
				isset($rules['REPLACE_CONTENT']) && is_array($rules['REPLACE_CONTENT']) &&
				array_key_exists('regexp', $rules['REPLACE_CONTENT']) &&
				array_key_exists('replace', $rules['REPLACE_CONTENT'])
			)
			{
				$innerHtml = $resultNode->getInnerHTML();
				$innerHtml = preg_replace($rules['REPLACE_CONTENT']['regexp'], $rules['REPLACE_CONTENT']['replace'], $innerHtml);
				if($innerHtml <> '')
				{
					$resultNode->setInnerHTML($innerHtml);
				}
			}
		}


//			add CONTAINER around nodes.
		if (
			isset($rules['CONTAINER_ADD']) && is_array($rules['CONTAINER_ADD']) &&
			isset($rules['CONTAINER_ADD']['CLASSES']) &&
			!empty($resultList)
		)
		{
			if (!is_array($rules['CONTAINER_ADD']['CLASSES']))
			{
				$rules['CONTAINER_ADD']['CLASSES'] = [$rules['CONTAINER_ADD']['CLASSES']];
			}
//				check if container exist
			$firstNode = $resultList[0];
			$parentNode = $firstNode->getParentNode();
			$parentClasses = $parentNode->getClassList();
			if (!empty(array_diff($rules['CONTAINER_ADD']['CLASSES'], $parentClasses)))
			{
//					param TO_EACH - add container to each element. Default (false) - add container once to all nodes
				if (!isset($rules['CONTAINER_ADD']['TO_EACH']) || $rules['CONTAINER_ADD']['TO_EACH'] !== true)
				{
					$containerNode = new Element($rules['CONTAINER_ADD']['TAG'] ? $rules['CONTAINER_ADD']['TAG'] : 'div');
					$containerNode->setOwnerDocument($doc);
					$containerNode->setClassName(implode(' ', $rules['CONTAINER_ADD']['CLASSES']));
					$parentNode->insertBefore($containerNode, $firstNode);
					foreach ($resultList as $resultNode)
					{
						$parentNode->removeChild($resultNode);
						$containerNode->appendChild($resultNode);
					}
				}
				else
				{
					foreach ($resultList as $resultNode)
					{
						$containerNode = new Element($rules['CONTAINER_ADD']['TAG'] ? $rules['CONTAINER_ADD']['TAG'] : 'div');
						$containerNode->setOwnerDocument($doc);
						$containerNode->setClassName(implode(' ', $rules['CONTAINER_ADD']['CLASSES']));
						$parentNode->insertBefore($containerNode, $resultNode);
						
						$parentNode->removeChild($resultNode);
						$containerNode->appendChild($resultNode);
					}
				}
			}
		}
	}
	$block->saveContent($doc->saveHTML());

//		updates COMPONENTS params
	if (is_array($this->dataToUpdate['BLOCKS'][$code]['UPDATE_COMPONENTS']))
	{
		foreach ($this->dataToUpdate['BLOCKS'][$code]['UPDATE_COMPONENTS'] as $selector => $params)
		{
			$block->updateNodes(array($selector => $params));
		}
	}

//		if need remove PHP - we must use block content directly, not DOM parser
	if (
		$this->dataToUpdate['BLOCKS'][$code]['CLEAR_PHP'] &&
		$this->dataToUpdate['BLOCKS'][$code]['CLEAR_PHP'] == 'Y'
	)
	{
		$content = $block->getContent();
		$content = preg_replace('//s', '', $content);
		$block->saveContent($content);
	}

//		change block SORT
	if (
		$this->dataToUpdate['BLOCKS'][$code]['SET_SORT'] &&
		is_numeric($this->dataToUpdate['BLOCKS'][$code]['SET_SORT'])
	)
	{
		$block->setSort($this->dataToUpdate['BLOCKS'][$code]['SET_SORT']);
	}

	$block->save();
}