Your IP : 18.226.185.28
<?php
namespace Bitrix\Landing;
use \Bitrix\Main\Web\Json;
use \Bitrix\Main\Page\Asset;
use \Bitrix\Main\Web\DOM;
use \Bitrix\Main\Localization\Loc;
use \Bitrix\Landing\Internals;
Loc::loadMessages(__FILE__);
class Block extends \Bitrix\Landing\Internals\BaseTable
{
/**
* Dir of repoitory of blocks.
*/
const BLOCKS_DIR = '/bitrix/blocks';
/**
* Block preview filename.
*/
const PREVIEW_FILE_NAME = 'preview.png';
/**
* Internal class.
* @var string
*/
public static $internalClass = 'BlockTable';
/**
* Id of current block.
* @var int
*/
protected $id = 0;
/**
* Sort of current block.
* @var int
*/
protected $sort = 0;
/**
* Is the rest block if > 0.
* @var int
*/
protected $repoId = 0;
/**
* Code of current block.
* @var string
*/
protected $code = '';
/**
* Actually content of current block.
* @var string
*/
protected $content = '';
/**
* Data row of current block.
* @var array
*/
protected $data = array();
/**
* Active or not current block.
* @var boolean
*/
protected $active = false;
/**
* Local path to the block.
* @var string
*/
protected $path = null;
/**
* Absolutely path to the block.
* @var string
*/
protected $pathFull = null;
/**
* Instance of Error.
* @var \Bitrix\Landing\Error
*/
protected $error = null;
/**
* Constructor.
* @param int $id Block id.
* @param array $data Data row from BlockTable (by default get from DB).
*/
public function __construct($id, $data = array())
{
if (empty($data) || !is_array($data))
{
$data = parent::getList(array(
'filter' => array(
'ID' => $id
)
))->fetch();
if (!$data)
{
$id = 0;
}
}
$this->id = intval($id);
$this->sort = isset($data['SORT']) ? intval($data['SORT']) : '';
$this->code = isset($data['CODE']) ? trim($data['CODE']) : '';
$this->content = isset($data['CONTENT']) ? trim($data['CONTENT']) : '';
$this->active = isset($data['ACTIVE']) && $data['ACTIVE'] == 'Y';
if (preg_match('/repo_([\d]+)/', $this->code, $matches))
{
$this->repoId = $matches[1];
}
if (!$this->repoId)
{
$this->path = self::getBlockPath($this->code);
$this->pathFull = Manager::getDocRoot() . $this->path;
}
$this->error = new Error;
}
/**
* Fill landing with blocks.
* @param \Bitrix\Landing\Landing $landing Landing instance.
* @param int $limit Limit count for blocks.
* @return boolean
*/
public static function fillLanding(\Bitrix\Landing\Landing $landing, $limit = 0)
{
if ($landing->exist())
{
$res = parent::getList(array(
'filter' => array(
'LID' => $landing->getId(),
'=PUBLIC' => $landing->getEditMode() ? 'N' : 'Y'
),
'order' => array(
'SORT' => 'ASC',
'ID' => 'ASC'
),
'limit' => $limit
));
while ($row = $res->fetch())
{
$block = new self($row['ID'], $row);
$landing->addBlockToCollection($block);
}
return true;
}
return false;
}
/**
* Create copy of blocks for draft version.
* @param \Bitrix\Landing\Landing $landing Landing instance.
* @return void
*/
public static function cloneForEdit(\Bitrix\Landing\Landing $landing)
{
if ($landing->exist())
{
$res = parent::getList(array(
'select' => array(
'LID', 'CODE', 'SORT', 'ACTIVE', 'CONTENT'
),
'filter' => array(
'LID' => $landing->getId(),
'=PUBLIC' => 'Y'
)
));
while ($row = $res->fetch())
{
$row['PUBLIC'] = 'N';
parent::add($row);
}
}
}
/**
* Publication blocks for landing.
* @param \Bitrix\Landing\Landing $landing Landing instance.
* @return void
*/
public static function publicationBlocks(\Bitrix\Landing\Landing $landing)
{
if ($landing->exist())
{
$toDelete = array();
$updateExist = false;
$res = parent::getList(array(
'select' => array(
'ID', 'PUBLIC'
),
'filter' => array(
'LID' => $landing->getId()
)
));
while ($row = $res->fetch())
{
if ($row['PUBLIC'] == 'Y')
{
$toDelete[] = $row['ID'];
}
else
{
$updateExist = true;
parent::update($row['ID'], array(
'PUBLIC' => 'Y'
));
}
}
if ($updateExist)
{
foreach ($toDelete as $id)
{
parent::delete($id);
}
}
}
}
/**
* Recognize landing id by block id.
* @param int|array $id Block id (id array).
* @return int|array|false
*/
public static function getLandingIdByBlockId($id)
{
$data = array();
$res = parent::getList(array(
'select' => array(
'ID', 'LID'
),
'filter' => array(
'ID' => $id
)
));
while ($row = $res->fetch())
{
$data[$row['ID']] = $row['LID'];
}
if (is_array($id))
{
return $data;
}
elseif (!empty($data))
{
return array_pop($data);
}
return false;
}
/**
* Create instance by string code.
* @param \Bitrix\Landing\Landing $landing Landing - owner for new block.
* @param string $code Code of block from repository.
* @param array $data Additional data array.
* @return Block|false
*/
public static function createFromRepository(\Bitrix\Landing\Landing $landing, $code, $data = array())
{
// get content
$content = '';
// local repo
if (preg_match('/repo_([\d]+)/', $code, $matches))
{
$repo = Repo::getById($matches[1])->fetch();
$content = $repo['CONTENT'];
}
// files storage
elseif (($path = self::getBlockPath($code)))
{
$path = Manager::getDocRoot() . $path . '/block.php';
if (file_exists($path))
{
$content = file_get_contents($path);
}
}
// check errors
if (!$landing->exist())
{
$landing->getError()->addError(
'LANDING_NOT_EXIST',
Loc::getMessage('LANDING_BLOCK_LANDING_NOT_EXIST')
);
return false;
}
if ($content == '')
{
$landing->getError()->addError(
'BLOCK_NOT_FOUND',
Loc::getMessage('LANDING_BLOCK_NOT_FOUND')
);
return false;
}
// add
$fields = array(
'LID' => $landing->getId(),
'CODE' => $code,
'CONTENT' => $content,
'ACTIVE' => 'Y'
);
if (isset($data['ACTIVE']))
{
$fields['ACTIVE'] = $data['ACTIVE'];
}
if (isset($data['PUBLIC']))
{
$fields['PUBLIC'] = $data['PUBLIC'];
}
if (isset($data['SORT']))
{
$fields['SORT'] = $data['SORT'];
}
if (isset($data['CONTENT']))
{
$fields['CONTENT'] = $data['CONTENT'];
}
$res = parent::add($fields);
if ($res->isSuccess())
{
$block = new self($res->getId());
$manifest = $block->getManifest();
if (
isset($manifest['callbacks']['afteradd']) &&
is_callable($manifest['callbacks']['afteradd'])
)
{
$manifest['callbacks']['afteradd']($block);
}
return $block;
}
else
{
$landing->getError()->addFromResult($res);
return false;
}
}
/**
* Get blocks from repository.
* @return array
*/
public static function getRepository()
{
$blocks = array();
$path = Manager::getDocRoot() . self::BLOCKS_DIR;
// read all subdirs ($namespaces) in block dir
$namespaces = array();
if (($handle = opendir($path)))
{
while ((($entry = readdir($handle)) !== false))
{
if (
$entry != '.' && $entry != '..' &&
is_dir($path . '/' . $entry)
)
{
$namespaces[] = $entry;
}
}
}
//get all blocks with description-file
sort($namespaces);
foreach ($namespaces as $subdir)
{
if (($handle = opendir($path . '/' . $subdir)))
{
while ((($entry = readdir($handle)) !== false))
{
$descriptionPath = $path . '/' . $subdir . '/' . $entry . '/.description.php';
$previewPath = $path . '/' . $subdir . '/' . $entry . '/' . self::PREVIEW_FILE_NAME;
if ($entry != '.' && $entry != '..' && file_exists($descriptionPath))
{
Loc::loadLanguageFile($descriptionPath);
$description = include $descriptionPath;
if (isset($description['block']['name']))
{
$blocks[$entry] = array(
'name' => $description['block']['name'],
'namespace' => $subdir,
'section' => isset($description['block']['section'])
? $description['block']['section']
: 'other',
'description' => isset($description['block']['description'])
? $description['block']['description']
: '',
'preview' => file_exists($previewPath)
? self::BLOCKS_DIR . '/' . $subdir . '/' . $entry . '/' . self::PREVIEW_FILE_NAME
: ''
);
}
}
}
}
}
// rest repo
$blocks += \Bitrix\Landing\Repo::getRepository();
// set by sections
Loc::loadMessages(Manager::getDocRoot() . '/bitrix/modules/landing/blocks/sections.php');
$blocksCats = array();
$otherTitle = Loc::getMessage('LD_BLOCK_SECTION_OTHER');
foreach ($blocks as $key => $block)
{
if (!is_array($block['section']))
{
$block['section'] = array($block['section']);
}
foreach ($block['section'] as $section)
{
$section = trim($section);
if (!isset($blocksCats[$section]))
{
$blocksCats[$section] = array(
'name' => Loc::getMessage('LD_BLOCK_SECTION_' . strtoupper($section)),
'items' => array()
);
if (!$blocksCats[$section]['name'])
{
$blocksCats[$section]['name'] = $otherTitle;
}
}
$blocksCats[$section]['items'][$key] = $block;
}
}
return $blocksCats;
}
/**
* Get blocks style manifest from repository.
* @return array
*/
public static function getStyle()
{
$style = array();
// read all subdirs ($namespaces) in block dir
$path = Manager::getDocRoot() . self::BLOCKS_DIR;
if (($handle = opendir($path)))
{
while ((($entry = readdir($handle)) !== false))
{
if (
$entry != '.' && $entry != '..' &&
is_dir($path . '/' . $entry) &&
file_exists($path . '/' . $entry . '/.style.php')
)
{
$style[$entry] = include $path . '/' . $entry . '/.style.php';
}
}
}
return $style;
}
/**
* Get block content array.
* @param int $id Block id.
* @return array
*/
public static function getBlockContent($id)
{
ob_start();
$block = new self($id);
$extContent = '';
if (($ext = $block->getExt()))
{
$extContent = \CUtil::InitJSCore($ext, true);
}
$block->view();
$content = ob_get_contents();
ob_end_clean();
if ($block->exist())
{
return array(
'id' => $id,
'content' => $content,
'content_ext' => $extContent,
'css' => $block->getCSS(),
'js' => $block->getJS(),
'manifest' => $block->getManifest()
);
}
else
{
return array();
}
}
/**
* Get namespace for block.
* @param string $code Code of block.
* @return string
*/
protected static function getBlockNamespace($code)
{
static $pathes = array();
static $namespace = array();
$code = trim($code);
if (isset($pathes[$code]))
{
return $pathes[$code];
}
$pathes[$code] = '';
$path = Manager::getDocRoot() . self::BLOCKS_DIR;
// read all subdirs ($namespaces) in block dir
if (empty($namespace))
{
if (($handle = opendir($path)))
{
while ((($entry = readdir($handle)) !== false))
{
if (
is_dir($path . '/' . $entry) &&
$entry != '.' && $entry != '..'
)
{
$namespace[] = $entry;
}
}
}
sort($namespace);
}
// get first needed block from end
foreach (array_reverse($namespace) as $subdir)
{
if (file_exists($path . '/' . $subdir . '/' . $code . '/block.php'))
{
$pathes[$code] = $subdir;
break;
}
}
return $pathes[$code];
}
/**
* Get local path for block.
* @param string $code Code of block.
* @return string
*/
protected static function getBlockPath($code)
{
if (($namespace = self::getBlockNamespace($code)))
{
return self::BLOCKS_DIR . '/' . $namespace . '/' . $code;
}
else
{
return '';
}
}
/**
* Exist or not block in current instance.
* @return boolean
*/
public function exist()
{
return $this->id > 0;
}
/**
* Get id of the block.
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Get code of the block.
* @return string
*/
public function getCode()
{
return $this->code;
}
/**
* Get content of the block.
* @return string
*/
public function getContent()
{
return $this->content;
}
/**
* Active or not the block.
* @return boolean
*/
public function isActive()
{
return $this->active;
}
/**
* Set active to the block.
* @param boolean $active Bool: true or falce.
* @return void
*/
public function setActive($active)
{
$this->active = (boolean) $active;
}
/**
* Get local path to the block.
* @return string|null
*/
public function getPath()
{
return $this->path;
}
/**
* Get preview picture of the block.
* @return string
*/
public function getPreview()
{
if (file_exists($this->pathFull . '/' . self::PREVIEW_FILE_NAME))
{
return $this->path . '/' . self::PREVIEW_FILE_NAME;
}
return '';
}
/**
* Get error collection
* @return \Bitrix\Landing\Error
*/
public function getError()
{
return $this->error;
}
/**
* Get class handler for type of node.
* @param string $type Type.
* @return string
*/
protected function getTypeClass($type)
{
static $classes = array();
$type = strtolower($type);
if (isset($classes[$type]))
{
return $classes[$type];
}
$class = __NAMESPACE__ . '\\Node\\' . $type;
// check custom classes
$event = new \Bitrix\Main\Event('landing', 'onGetNodeClass', array(
'type' => $type,
));
$event->send();
foreach ($event->getResults() as $result)
{
if ($result->getResultType() != \Bitrix\Main\EventResult::ERROR)
{
if (
($modified = $result->getModified()) &&
isset($modified['class'])
)
{
$class = $modified['class'];
}
}
}
$classes[$type] = $class;
return $classes[$type];
}
/**
* Get manifest array from block.
* @return array
*/
public function getManifest()
{
static $manifestStore = array();
if (isset($manifestStore[$this->code]))
{
return $manifestStore[$this->code];
}
$manifest = array();
// manifet is exist and correct
if ($this->repoId || file_exists($this->pathFull . '/.description.php'))
{
if ($this->repoId)
{
$manifest = Repo::getBlock($this->repoId);
}
else
{
Loc::loadLanguageFile($this->pathFull . '/.description.php');
$manifest = include $this->pathFull . '/.description.php';
}
if (isset($manifest['block']['name']))
{
// set empty array if no exists
foreach (array('cards', 'nodes', 'attrs') as $code)
{
if (!isset($manifest[$code]) || !is_array($manifest[$code]))
{
$manifest[$code] = array();
}
}
// prepare every node
foreach ($manifest['nodes'] as $keyNode => &$node)
{
if (is_callable($node))
{
$node = $node();
}
$node['code'] = $keyNode;
$class = $this->getTypeClass($node['type']);
if (isset($node['type']) && class_exists($class))
{
$node['handler'] = call_user_func(array(
$class,
'getHandlerJS'
));
if (method_exists($class, 'prepareManifest'))
{
$node = call_user_func_array(array(
$class,
'prepareManifest'
), array(
$this,
$node
));
if (!is_array($node))
{
unset($manifest['nodes'][$keyNode]);
}
}
}
else
{
unset($manifest['nodes'][$keyNode]);
}
}
unset($node);
// and attrs
foreach ($manifest['attrs'] as $keyNode => &$node)
{
if (is_callable($node))
{
$node = $node();
}
}
unset($node);
// callbacks
if (isset($manifest['callbacks']) && is_array($manifest['callbacks']))
{
$callbacks = array();
foreach ($manifest['callbacks'] as $code => $callback)
{
$callbacks[strtolower($code)] = $callback;
}
$manifest['callbacks'] = $callbacks;
}
// prepare styles
if (!isset($manifest['namespace']))
{
$manifest['namespace'] = $this->getBlockNamespace($this->code);
}
if (
isset($manifest['style']) &&
!(
isset($manifest['style']['block']) &&
isset($manifest['style']['nodes']) &&
count($manifest['style']) == 2
)
)
{
$manifest['style'] = array(
'block' => array(),
'nodes' => $manifest['style']
);
}
elseif (
!isset($manifest['style']) ||
!is_array($manifest['style'])
)
{
$manifest['style'] = array(
'block' => array(),
'nodes' => array()
);
}
// other
$manifest['code'] = $this->code;
}
else
{
$manifest = array();
}
}
$manifestStore[$this->code] = $manifest;
return $manifest;
}
/**
* Get manifest array as is from block.
* @param string $code Code name, format "namespace:code".
* @return array
*/
public static function getManifestFile($code)
{
$manifest = array();
if (strpos($code, ':') !== false)
{
list($namespace, $code) = explode(':', $code);
$pathFull = self::BLOCKS_DIR . '/' . $namespace . '/' . $code;
$pathFull = Manager::getDocRoot() . $pathFull;
if (file_exists($pathFull . '/.description.php'))
{
Loc::loadLanguageFile($pathFull . '/.description.php');
$manifest = include $pathFull . '/.description.php';
}
}
return $manifest;
}
/**
* Get CSS/JS array of block.
* @param string $type What return: css or js.
* @return array
*/
public function getAsset($type = false)
{
static $asset = array();
if (!isset($asset[$this->code]))
{
$asset[$this->code] = array(
'css' => array(),
'js' => array(),
'ext' => array()
);
// additional asset first
if ($this->repoId || file_exists($this->pathFull . '/.description.php'))
{
if ($this->repoId)
{
$keys = array('css', 'js');
$manifest = Repo::getBlock($this->repoId);
}
else
{
$keys = array('css', 'js', 'ext');
$manifest = include $this->pathFull . '/.description.php';
}
foreach ($keys as $ass)
{
if (
isset($manifest['assets'][$ass]) &&
!empty($manifest['assets'][$ass])
)
{
$asset[$this->code][$ass] = array_merge(
$asset[$this->code][$ass],
(array)$manifest['assets'][$ass]
);
}
}
}
if (!$this->repoId)
{
// base files next
$file = $this->getPath() . '/style.css';
if (file_exists(Manager::getDocRoot() . $file))
{
$asset[$this->code]['css'][] = $file;
}
$file = $this->getPath() . '/script.js';
if (file_exists(Manager::getDocRoot() . $file))
{
$asset[$this->code]['js'][] = $file;
}
}
}
return isset($asset[$this->code][$type])
? $asset[$this->code][$type]
: $asset[$this->code];
}
/**
* Get css file path, if exists.
* @return array
*/
public function getCSS()
{
return $this->getAsset('css');
}
/**
* Get js file path, if exists.
* @return array
*/
public function getJS()
{
return $this->getAsset('js');
}
/**
* Get extensions.
* @return array
*/
public function getExt()
{
return $this->getAsset('ext');
}
/**
* Get block anchor.
* @param int $id Block id.
* @return string
*/
public static function getAnchor($id)
{
return 'block' . $id;
}
/**
* Out the block.
* @param boolean $edit Out block in edit mode.
* @return void
*/
public function view($edit = false)
{
global $APPLICATION;
if ($edit || $this->active)
{
if (!$this->repoId)
{
Loc::loadMessages($this->pathFull . '/block.php');
}
foreach ($this->getCSS() as $css)
{
Asset::getInstance()->addCSS($css);
}
if (($ext = $this->getExt()))
{
\CUtil::InitJSCore($ext);
}
if (!$edit || !$this->repoId)
{
foreach ($this->getJS() as $js)
{
Asset::getInstance()->addJS($js);
}
}
}
$content = '<div id="' . $this->getAnchor($this->id) . '" class="block-wrapper' . (!$this->active ? ' landing-block-deactive' : '') . '">' .
$this->content .
'</div>';
if ($edit)
{
$manifest = $this->getManifest();
if ($manifest)
{
echo '<script type="text/javascript">'
. 'BX.ready(function(){'
. 'if (typeof BX.Landing.Block !== "undefined")'
. '{'
. 'new BX.Landing.Block('
. 'BX("block' . $this->id . '"), '
. '{'
. 'id: ' . $this->id . ', '
. 'active: ' . ($this->active ? 'true' : 'false') . ', '
. 'manifest: ' . Json::encode($manifest)
. '}'
. ');'
. '}'
. '});'
. '</script>';
}
if ($this->repoId)
{
echo $content;
}
else
{
eval('?>' . $content . '<?');
}
}
elseif ($this->active)
{
if ($this->repoId)
{
echo $content;
}
else
{
eval('?>' . $content . '<?');
}
}
}
/**
* Set new content.
* @param string $content New content.
* @return void
*/
protected function saveContent($content)
{
$this->content = trim($content);
}
/**
* Save current block in DB.
* @return boolean
*/
public function save()
{
$data = array(
'SORT' => $this->sort,
'ACTIVE' => $this->active ? 'Y' : 'N',
'CONTENT' => $this->content
);
$res = parent::update($this->id, $data);
$this->error->addFromResult($res);
return $res->isSuccess();
}
/**
* Change landing of current block.
* @param int $lid New landing id.
* @return boolean
*
*/
public function changeLanding($lid)
{
$res = parent::update($this->id, array(
'LID' => $lid
));
$this->error->addFromResult($res);
return $res->isSuccess();
}
/**
* Delete current block.
* @return boolean
*/
public function unlink()
{
$res = parent::delete($this->id);
if (!$res->isSuccess())
{
$this->error->addFromResult($res);
}
return $res->isSuccess();
}
/**
* Set new sort to current block.
* @param int $sort New sort.
* @return void
*/
public function setSort($sort)
{
$this->sort = $sort;
}
/**
* Save new sort to current block to DB.
* @param int $sort New sort.
* @return void
*/
public function saveSort($sort)
{
$this->sort = $sort;
Internals\BlockTable::update($this->id, array(
'SORT' => $sort
));
}
/**
* Get sort of current block.
* @return int
*/
public function getSort()
{
return $this->sort;
}
/**
* Load current content in DOM html structure.
* @return DOM\Document
*/
public function getDom()
{
static $doc = array();
if (!isset($doc[$this->code]))
{
$doc[$this->code] = new DOM\Document;
$doc[$this->code]->loadHTML($this->content);
}
return $doc[$this->code];
}
/**
* Clone one card in block by selector.
* @param string $selector Selector.
* @param int $position Card position.
* @return boolean Success or failure.
*/
public function cloneCard($selector, $position)
{
$manifest = $this->getManifest();
if (isset($manifest['cards'][$selector]))
{
$doc = $this->getDom();
$resultList = $doc->querySelectorAll($selector);
if (isset($resultList[$position]))
{
$resultList[$position]->getParentNode()->insertBefore(
$resultList[$position],
isset($resultList[$position + 1])
? $resultList[$position + 1]
: null,
false
);
$this->saveContent($doc->saveHTML());
return true;
}
}
$this->error->addError(
'CARD_NOT_FOUND',
Loc::getMessage('LANDING_BLOCK_CARD_NOT_FOUND')
);
return false;
}
/**
* Remove one card from block by selector.
* @param string $selector Selector.
* @param int $position Card position.
* @return boolean Success or failure.
*/
public function removeCard($selector, $position)
{
$manifest = $this->getManifest();
if (isset($manifest['cards'][$selector]))
{
$doc = $this->getDom();
$resultList = $doc->querySelectorAll($selector);
if (isset($resultList[$position]))
{
$resultList[$position]->getParentNode()->removeChild(
$resultList[$position]
);
$this->saveContent($doc->saveHTML());
return true;
}
}
$this->error->addError(
'CARD_NOT_FOUND',
Loc::getMessage('LANDING_BLOCK_CARD_NOT_FOUND')
);
return false;
}
/**
* Set new content to nodes of block.
* @param array $data Nodes data array.
* @return void
*/
public function updateNodes($data)
{
$doc = $this->getDom();
$manifest = $this->getManifest();
// find available nodes by manifest from data
foreach ($manifest['nodes'] as $selector => $node)
{
if (isset($data[$selector]))
{
if (!is_array($data[$selector]))
{
$data[$selector] = array(
$data[$selector]
);
}
// and save content from frontend in DOM by handler-class
call_user_func_array(array(
$this->getTypeClass($node['type']),
'saveNode'
), array(
&$this,
$selector,
$data[$selector]
));
}
}
// save rebuild html as text
$this->saveContent($doc->saveHTML());
}
/**
* Recursive styles remove in Node.
* @param \Bitrix\Main\Web\DOM\Node $node Node for clear.
* @param array $styleToRemove Array of styles to remove.
* @return \Bitrix\Main\Web\DOM\Node
*/
protected function removeStyle(\Bitrix\Main\Web\DOM\Node $node, array $styleToRemove)
{
foreach ($node->getChildNodesArray() as $nodeChild)
{
if ($nodeChild instanceof \Bitrix\Main\Web\DOM\Element)
{
$styles = DOM\StyleInliner::getStyle($nodeChild);
if (!empty($styles))
{
foreach ($styleToRemove as $remove)
{
if (isset($styles[$remove]))
{
unset($styles[$remove]);
}
}
DOM\StyleInliner::setStyle($nodeChild, $styles);
}
}
$node = $this->removeStyle($nodeChild, $styleToRemove);
}
return $node;
}
/**
* Set new classes to nodes of block.
* @param array $data Classes data array.
* @return void
*/
public function setClasses($data)
{
$doc = $this->getDom();
$manifest = $this->getManifest();
// wrapper (not realy exist)
$wrapper = '#' . $this->getAnchor($this->id);
// find available nodes by manifest from data
$styles = array_merge(
$manifest['style']['block'],
$manifest['style']['nodes']
);
$styles[$wrapper] = array(
//
);
foreach ($styles as $selector => $node)
{
if (isset($data[$selector]))
{
// prepare data
if (!is_array($data[$selector]))
{
$data[$selector] = array(
$data[$selector]
);
}
if (!isset($data[$selector]['classList']))
{
$data[$selector] = array(
'classList' => $data[$selector]
);
}
if (!isset($data[$selector]['affect']))
{
$data[$selector]['affect'] = array();
}
// apply classes to the block
if ($selector == $wrapper)
{
$resultList = array(
array_pop($doc->getChildNodesArray())
);
}
// or by selector
else
{
$resultList = $doc->querySelectorAll($selector);
}
foreach ($resultList as $resultNode)
{
$resultNode->setClassName(
implode(' ', $data[$selector]['classList'])
);
// affected styles
if (!empty($data[$selector]['affect']))
{
$resultNode = $this->removeStyle(
$resultNode,
$data[$selector]['affect']
);
}
}
}
}
// save rebuild html as text
$this->saveContent($doc->saveHTML());
}
/**
* Set attributes to nodes of block.
* @param array $data Attrs data array.
* @return void
*/
public function setAttributes($data)
{
$doc = $this->getDom();
$manifest = $this->getManifest();
// wrapper (not realy exist)
$wrapper = '#' . $this->getAnchor($this->id);
// find available nodes by manifest from data
$attrs = $manifest['attrs'];
$attrs[$wrapper] = array(
//
);
foreach ($attrs as $selector => $item)
{
if (isset($data[$selector]))
{
// not multi
if (!isset($item[0]))
{
$item = array($item);
}
// prepare attrs
$attrItems = array();
foreach ($item as $val)
{
if (
isset($val['attribute']) &&
isset($data[$selector][$val['attribute']])
)
{
$attrItems[$val['attribute']] = $data[$selector][$val['attribute']];
}
}
// set attrs to the block
if ($selector == $wrapper)
{
$resultList = array(
array_pop($doc->getChildNodesArray())
);
}
// or by selector
else
{
$resultList = $doc->querySelectorAll($selector);
}
foreach ($resultList as $resultNode)
{
foreach ($attrItems as $code => $val)
{
$resultNode->setAttribute(
\htmlspecialcharsbx($code),
$val
);
}
}
}
}
// save rebuild html as text
$this->saveContent($doc->saveHTML());
}
public static function add($fields)
{
throw new \Bitrix\Main\SystemException(
'Disabled for direct access.'
);
}
public static function update($id, $fields = array())
{
throw new \Bitrix\Main\SystemException(
'Disabled for direct access.'
);
}
public static function delete($id)
{
throw new \Bitrix\Main\SystemException(
'Disabled for direct access.'
);
}
public static function getList($fields = array())
{
throw new \Bitrix\Main\SystemException(
'Disabled for direct access.'
);
}
}