Рекурсивное построение дерева на основе элементов полученных из базы данных.
Библиотеку для соединения с ДБ можно выбрать на свое усмотрение.
Пример вывода
Код для подключения (Дэмо)
<?
/**
* Базовый класс для дерева
*
*/
class soTree
{
/**
* Демонстрационный метод, для создания дерева.
* Возвращает дерево в виде UL>LI списка
*
* @return string
*/
static function demoUl()
{
require_once('models/tree.php');
$oModel = new soModelTree();
require_once('views/ul.php');
$oView = new soViewTreeUL();
// Предаем на вход ID активного элемента.
// В дереве будет подсветка пути до выбранного элемента
$aItems = $oModel->getItems(['id_selected' => 10]);
return $oView->render($aItems);
}
/**
* Демонстрационный метод, для создания дерева.
* Возвращает дерево в виде DIV списка
*
* @return string
*/
static function demoDiv()
{
require_once('models/tree.php');
$oModel = new soModelTree();
require_once('views/div.php');
$oView = new soViewTreeDiv();
// Предаем на вход ID активного элемента.
// В дереве будет подсветка пути до выбранного элемента
$aItems = $oModel->getItems(['id_selected' => 10]);
return $oView->render($aItems);
}
}
Моледь
<?
/**
* Модель. Класс для получения данных о дереве из БД
*/
class soModelTree
{
/**
*
* @var array - массав "для пути" от корня до выбранного элемента, со всеми id
*
*/
protected $_aActivePath = array();
/**
*
* @var object - объект для взаимодействия с ДБ
*
*/
protected $_oDB = NULL;
#-------------------------------------------------------#
/**
* Construct
*/
function __construct()
{
// !!! Т.к. Модуль может использоватся для разных целей, то тут нужно писать индивидуально.
//- $this->_oDB = soLibKeeper::factory('DBO');
global $oDB;
$this->_oDB = $oDB;
}
/**
* Метод для формирования "пути" (списка всех ID от корян до выбранного элемента)
*
* @param int $id
*
* @return $this
*/
protected function _initActivePath($id)
{
$this->_aActivePath[] = $id;
$sSql = 'SELECT * FROM `tree` WHERE published=1 AND id='.$id;
$oRow = $this->_getRow($sSql);
if($oRow->id_parent)
{
$this->_initActivePath($oRow->id_parent);
}
return $this;
}
/**
* Метод для получения ОДНОЙ записи из БД.
* Т.к. драйвер может быть разным, метод может быть реализован по разному
*
* @param string $sSql
*
* @return object
*/
protected function _getRow($sSql)
{
$this->_oDB->setQuery($sSql);
return $this->_oDB->loadObject();
}
/**
* Метод для получения МАССИВА данных из БД.
* Т.к. драйвер может быть разным, метод может быть реализован по разному
*
* @param string $sSql
*
* @return array
*/
protected function _getRows($sSql)
{
$this->_oDB->setQuery($sSql);
return $this->_oDB->loadObjectsList();
}
/**
* Рекурсивное получение элементов из БД
*
* @param int $id_parent
* @param int $iLevel
*
* @return
*/
protected function _getAllRecursively($id_parent, $iLevel = 0)
{
$sSql = 'SELECT * FROM `tree` WHERE published=1 AND id_parent='.$id_parent.' ORDER BY ordering';
$aRows = $this->_getRows($sSql);
$aRet = array();
$iNextLevel = $iLevel +1;
if (count($aRows))
{
foreach($aRows as $oRow)
{
$oRow->__iLevel = $iLevel;
$aSubRows = $this->_getAllRecursively($oRow->id, $iNextLevel);
if (count($aSubRows))
{
$oRow->__aSubLevel = $aSubRows;
}
if(count($this->_aActivePath))
{
if(in_array($oRow->id, $this->_aActivePath))
{
$oRow->__isActive = TRUE;
}
}
$aRet[] = $oRow;
}
}
return $aRet;
}
/**
* Возвращает дерево в виде массива
*
* @param array $aOptions - массив с входными параметрами
* int id_selected - активный элемент
*
* @return array
*/
public function getItems($aOptions)
{
$id_selected = isset($aOptions['id_selected'])?$aOptions['id_selected']:0;
if($id_selected)
{
$this->_initActivePath($id_selected);
}
$aRet = $this->_getAllRecursively(0, 0);
return count($aRet)?$aRet:[];
}
}
Одио из двух представлений
<?
/**
* Представлени. Класс для формирует вывод дерева в UL>li список
*/
class soViewTreeUL
{
/**
* Формирует один уровень списка
*
* @param array $aItems
* @param int $iLevel
*
* @return string
*/
protected function _makeLevel(&$aItems, $iLevel = 0)
{
$sRet = '';
$iNextLevel = $iLevel + 1;
foreach($aItems as $oItem)
{
$sRet .= '<li'.(isset($oItem->__isActive)?' class="active"':'').'>'.$oItem->title.'</li>';
if(isset($oItem->__aSubLevel))
{
$sRet .= '<ul class="hidden" id="itm_'.$oItem->id.'">';
$sRet .= $this->_makeLevel($oItem->__aSubLevel, $iNextLevel);
$sRet .= '</ul>';
}
}
//return ob_get_clean();
return $sRet;
}
/**
* Формирует вывод
*
* @param array $aItems
*
* @return string
*/
public function render(&$aItems)
{
return '<ul id="ul_menu">'.$this->_makeLevel($aItems, 0).'</ul>';
}
}
Скачать