prepareTree($tree, $parent, $selectedId);
return $this->renderItems($tree, $attribs);
}
protected function prepareTree(&$tree, &$parent, $selectedId)
{
if ($parent) {
$parent['opened'] = false;
}
foreach ($tree as &$item) {
$item['selected'] = $item['id'] == $selectedId;
if (!empty($item['sub'])) {
$this->prepareTree($item['sub'], $item, $selectedId);
}
if (($item['id'] == $selectedId || Qs_Array::get($item, 'opened'))) {
if ($parent) {
$parent['opened'] = true;
}
$item['opened'] = true;
}
}
return $this;
}
protected function renderItems($tree, $attribs, $level = 1)
{
$xhtml = '';
$index = 0;
$count = count($tree);
foreach ($tree as $item) {
$xhtml .= $this->renderItem($item, $level, ++$index == $count);
}
return Html::renderContainer('ul', $xhtml, $attribs);
}
protected function renderItem($item, $level, $last)
{
$attribs = [
'class' => [],
];
if (($isTop = (1 == $level))) {
$attribs['class'][] = 'top-level';
}
$xhtml = '';
$opened = Qs_Array::get($item, 'opened');
if (!empty($item['sub'])) {
$branchClass = $opened ? 'collapsable' : 'expandable';
$attribs['class'][] = $branchClass;
if ($last) {
$attribs['class'][] = 'last' . ucfirst($branchClass);
}
$xhtml .= $this->renderHitarea($isTop, $opened, $last);
}
$xhtml .= $this->renderLink($item, $isTop);
if (!empty($item['sub'])) {
$ulAttribs = [];
if (!$opened) {
$ulAttribs['style'] = 'display:none';
}
$xhtml .= $this->renderItems($item['sub'], $ulAttribs, $level + 1);
} elseif ($last) {
$attribs['class'][] = 'last';
}
$attribs['class'] = implode(' ', $attribs['class']);
return Html::renderContainer('li', $xhtml, $attribs);
}
protected function renderLink($item, $isTop)
{
$attribs = ['href' => $item['url'], 'class' => []];
if ($isTop) {
$attribs['class'][] = 'top-level';
}
if ($item['selected']) {
$attribs['class'][] = 'selected';
}
if (!empty($attribs['class'])) {
$attribs['class'] = implode(' ', $attribs['class']);
} else {
unset($attribs['class']);
}
return Html::renderContainer('a', $item['title'], $attribs);
}
protected function renderHitarea($isTop, $opened, $last)
{
$class = ['hitarea'];
if ($isTop) {
$class[] = 'top-level-hitarea';
}
$class[] = ($stateClass = ($opened ? 'collapsable' : 'expandable') . '-hitarea');
if ($last) {
$class[] = 'last' . ucfirst($stateClass);
}
return Html::renderContainer('div', '', ['class' => implode(' ', $class)]);
}
}