- Модуль: 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();
}