Набор классов для построения деревьев

10.06.2016

Рекурсивное построение дерева на основе элементов полученных из базы данных.

Библиотеку для соединения с ДБ можно выбрать на свое усмотрение.

Пример вывода

pic1

Код для подключения (Дэмо)

_init_.php (Download)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<?
 
 /**
 * Базовый класс для дерева
 *
 */
 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);
   }
 
 }

Моледь

tree.php (Download)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
<?
 
 /**
 * Модель. Класс для получения данных о дереве из БД
 */
 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.php (Download)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<?
 
 /**
 * Представлени. Класс для формирует вывод дерева в 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>';
   }
 }


Скачать


Категории: PHP, Class
Яндекс.Метрика