1<?php 2/* 3** Zabbix 4** Copyright (C) 2001-2021 Zabbix SIA 5** 6** This program is free software; you can redistribute it and/or modify 7** it under the terms of the GNU General Public License as published by 8** the Free Software Foundation; either version 2 of the License, or 9** (at your option) any later version. 10** 11** This program is distributed in the hope that it will be useful, 12** but WITHOUT ANY WARRANTY; without even the implied warranty of 13** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14** GNU General Public License for more details. 15** 16** You should have received a copy of the GNU General Public License 17** along with this program; if not, write to the Free Software 18** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19**/ 20 21 22/** 23 * A class for rendering HTML trees. 24 */ 25class CTree { 26 27 protected $tree; 28 private $fields; 29 private $treename; 30 private $size; 31 private $maxlevel; 32 33 public function __construct($treename, $value = [], $fields = []) { 34 $this->maxlevel = 0; 35 $this->tree = $value; 36 $this->fields = $fields; 37 $this->treename = $treename; 38 $this->size = count($value); 39 40 if (!$this->checkTree()) { 41 $this->destroy(); 42 return false; 43 } 44 else { 45 $this->countDepth(); 46 } 47 } 48 49 public function getTree() { 50 return $this->tree; 51 } 52 53 public function getHTML() { 54 $html[] = $this->createJS(); 55 $html[] = $this->simpleHTML(); 56 return $html; 57 } 58 59 private function makeHeaders() { 60 $headers = array_values($this->fields); 61 62 $keys = array_keys($this->fields); 63 array_shift($keys); 64 $this->fields = $keys; 65 66 return $headers; 67 } 68 69 private function simpleHTML() { 70 $table = (new CTableInfo()) 71 ->setHeader($this->makeHeaders()); 72 73 foreach ($this->tree as $id => $rows) { 74 $table->addRow($this->makeRow($id)); 75 } 76 return $table; 77 } 78 79 private function makeRow($id) { 80 $tr = (new CRow())->setId('id_'.$id); 81 if ($this->tree[$id]['parentid'] != 0) { 82 $tr->setAttribute('style', 'display: none;'); 83 } 84 85 $tr->addItem($this->makeCell($id)); 86 foreach ($this->fields as $value) { 87 $tr->addItem($this->makeCol($id, $value)); 88 } 89 return $tr; 90 } 91 92 /** 93 * Returns a column object for the given row and field. 94 * 95 * @param $rowId 96 * @param $colName 97 * 98 * @return CCol 99 */ 100 protected function makeCol($rowId, $colName) { 101 return new CCol($this->tree[$rowId][$colName]); 102 } 103 104 private function makeCell($id) { 105 $td = new CCol(); 106 107 $caption = new CSpan(); 108 109 if ($id != 0 && array_key_exists('childnodes', $this->tree[$id])) { 110 $caption->addItem((new CSimpleButton((new CSpan())->addClass('arrow-right'))) 111 ->addClass(ZBX_STYLE_TREEVIEW) 112 ->onClick($this->treename.'.closeSNodeX("'.$id.'", this.getElementsByTagName(\'span\')[0]);') 113 ->setId('idi_'.$id) 114 ); 115 } 116 $caption->addItem($this->tree[$id]['caption']); 117 118 if ($this->tree[$id]['Level'] != 0) { 119 $level = $this->tree[$id]['Level']; 120 $caption->setAttribute('style', 'padding-left:'.(2 * $level).'em;'); 121 } 122 $td->addItem($caption); 123 124 return $td; 125 } 126 127 private function countDepth() { 128 foreach ($this->tree as $id => $rows) { 129 if ($rows['id'] == 0) { 130 $this->tree[$id]['Level'] = 0; 131 continue; 132 } 133 $parentid = $this->tree[$id]['parentid']; 134 135 $this->tree[$parentid]['nodetype'] = 2; 136 $this->tree[$id]['Level'] = isset($this->tree[$parentid]['Level']) ? $this->tree[$parentid]['Level'] + 1 : 1; 137 138 if ($this->maxlevel < $this->tree[$id]['Level']) { 139 $this->maxlevel = $this->tree[$id]['Level']; 140 } 141 } 142 } 143 144 public function createJS() { 145 $js = '<script src="js/class.ctree.js" type="text/javascript"></script>'."\n". 146 '<script type="text/javascript"> var '.$this->treename.'_tree = {};'; 147 148 foreach ($this->tree as $id => $rows) { 149 $parentid = $rows['parentid']; 150 $this->tree[$parentid]['nodelist'] .= $id.','; 151 } 152 153 foreach ($this->tree as $id => $rows) { 154 if ($rows['nodetype'] == '2') { 155 $rows['nodelist'] = rtrim($rows['nodelist'], ','); 156 $js .= $this->treename.'_tree[\''.$id.'\'] = { status: \'close\', nodelist : \''.$rows['nodelist'].'\', parentid : \''.$rows['parentid'].'\'};'; 157 $js .= "\n"; 158 } 159 } 160 161 $js.= 'var '.$this->treename.' = null'; 162 $js.= '</script>'."\n"; 163 164 zbx_add_post_js($this->treename.' = new CTree("tree_'.CWebUser::$data['alias'].'_'.$this->treename.'", '.$this->treename.'_tree);'); 165 166 return new CJsScript($js); 167 } 168 169 private function checkTree() { 170 if (!is_array($this->tree)) { 171 return false; 172 } 173 foreach ($this->tree as $id => $cell) { 174 $this->tree[$id]['nodetype'] = 0; 175 176 $parentid = $cell['parentid']; 177 $this->tree[$parentid]['childnodes'][] = $id; 178 $this->tree[$id]['nodelist'] = ''; 179 } 180 return true; 181 } 182 183 private function destroy() { 184 unset($this->tree); 185 } 186} 187