1<?php 2namespace Fisharebest\Webtrees; 3 4/** 5 * webtrees: online genealogy 6 * Copyright (C) 2015 webtrees development team 7 * This program is free software: you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation, either version 3 of the License, or 10 * (at your option) any later version. 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 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19/** 20 * Class Menu - System for generating menus. 21 */ 22class Menu { 23 /** @var string The text to be displayed in the mneu */ 24 private $label; 25 26 /** @var string The target URL or href*/ 27 private $link; 28 29 /** @var string The CSS ID to be used for this menu item */ 30 private $id; 31 32 /** @var string An onclick action, typically used with a link of "#" */ 33 private $onclick; 34 35 /** @var Menu[] */ 36 private $submenus; 37 38 /** @var string Used internally to create javascript menus */ 39 private $parentmenu; 40 41 /** @var string Used to format javascript menus */ 42 private $submenuclass; 43 44 /** @var string Used to format javascript menus */ 45 private $iconclass; 46 47 /** @var string Used to format javascript menus */ 48 private $class; 49 50 /** 51 * Constructor for the menu class 52 * 53 * @param string $label The label for the menu item 54 * @param string $link The target URL 55 * @param string $id An CSS identifier 56 * @param string $onclick A javascript onclick handler 57 * @param Menu[] $submenus Any submenus 58 */ 59 public function __construct($label, $link = '#', $id = '', $onclick = '', $submenus = array()) { 60 $this 61 ->setLabel($label) 62 ->setLink($link) 63 ->setId($id) 64 ->setOnclick($onclick) 65 ->setSubmenus($submenus); 66 } 67 68 /** 69 * Convert this menu to an HTML list, for easy rendering of 70 * lists of menus/nulls. 71 * 72 * @return string 73 */ 74 public function __toString() { 75 return $this->getMenuAsList(); 76 } 77 78 /** 79 * Render this menu using Bootstrap markup 80 * 81 * @return string 82 */ 83 public function bootstrap() { 84 if ($this->iconclass) { 85 $class = ' class="' . $this->iconclass . '"'; 86 } else { 87 $class = ''; 88 } 89 if ($this->id) { 90 $id = ' id="' . $this->id . '"'; 91 } else { 92 $id = ''; 93 } 94 95 if ($this->submenus) { 96 $submenus = ''; 97 foreach ($this->submenus as $submenu) { 98 $submenus .= $submenu->bootstrap(); 99 } 100 101 return 102 '<li' . $id . ' class="dropdown">' . 103 '<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">' . 104 $this->label . 105 ' <span class="caret"></span></a>' . 106 '<ul class="dropdown-menu" role="menu">' . 107 $submenus . 108 '</ul>' . 109 '</li>'; 110 } else { 111 if ($this->onclick) { 112 $onclick = ' onclick="' . $this->onclick . '"'; 113 } else { 114 $onclick = ''; 115 } 116 117 return '<li' . $id . $class . '><a href="' . $this->link . '"' . $onclick . '>' . $this->label . '</a></li>'; 118 } 119 } 120 121 /** 122 * Set the CSS classes for this menu 123 * 124 * @param string $class 125 * @param string $submenuclass 126 * @param string $iconclass 127 */ 128 public function addClass($class, $submenuclass = '', $iconclass = '') { 129 $this->class = $class; 130 $this->submenuclass = $submenuclass; 131 $this->iconclass = $iconclass; 132 } 133 134 /** 135 * @return string 136 */ 137 public function getId() { 138 return $this->id; 139 } 140 141 /** 142 * @param string $id 143 * 144 * @return $this 145 */ 146 public function setId($id) { 147 $this->id = $id; 148 149 return $this; 150 } 151 152 /** 153 * @return string 154 */ 155 public function getLabel() { 156 return $this->label; 157 } 158 159 /** 160 * @param string $label 161 * 162 * @return $this 163 */ 164 public function setLabel($label) { 165 $this->label = $label; 166 167 return $this; 168 } 169 170 /** 171 * @return string 172 */ 173 public function getLink() { 174 return $this->link; 175 } 176 177 /** 178 * @param string $link 179 * 180 * @return $this 181 */ 182 public function setLink($link) { 183 $this->link = $link; 184 185 return $this; 186 } 187 188 /** 189 * @return string 190 */ 191 public function getOnclick() { 192 return $this->onclick; 193 } 194 195 /** 196 * @param string $onclick 197 * 198 * @return $this 199 */ 200 public function setOnclick($onclick) { 201 $this->onclick = $onclick; 202 203 return $this; 204 } 205 206 /** 207 * Add a submenu to this menu 208 * 209 * @param Menu[] 210 */ 211 public function addSubmenu($menu) { 212 $this->submenus[] = $menu; 213 } 214 215 /** 216 * Render this menu using javascript popups.. 217 * 218 * @return string 219 */ 220 public function getMenu() { 221 global $menucount; 222 223 if (!isset($menucount)) { 224 $menucount = 0; 225 } else { 226 $menucount++; 227 } 228 $id = $menucount . rand(); 229 $c = count($this->submenus); 230 $output = "<div id=\"menu{$id}\" class=\"{$this->class}\">"; 231 $link = "<a href=\"{$this->link}\" onmouseover=\""; 232 if ($c >= 0) { 233 $link .= "show_submenu('menu{$id}_subs', 'menu{$id}');"; 234 } 235 $link .= '" onmouseout="'; 236 if ($c >= 0) { 237 $link .= "timeout_submenu('menu{$id}_subs');"; 238 } 239 if ($this->onclick) { 240 $link .= "\" onclick=\"{$this->onclick}"; 241 } 242 $link .= "\">"; 243 $output .= $link; 244 $output .= $this->label; 245 $output .= "</a>"; 246 247 if ($c > 0) { 248 $submenuid = "menu{$id}_subs"; 249 if (I18N::direction() === 'ltr') { 250 $output .= '<div style="text-align: left;">'; 251 } else { 252 $output .= '<div style="text-align: right;">'; 253 } 254 $output .= "<div id=\"menu{$id}_subs\" class=\"{$this->submenuclass}\" style=\"position: absolute; visibility: hidden; z-index: 100;"; 255 $output .= "\" onmouseover=\"show_submenu('{$this->parentmenu}'); show_submenu('{$submenuid}');\" onmouseout=\"timeout_submenu('menu{$id}_subs');\">"; 256 foreach ($this->submenus as $submenu) { 257 $submenu->parentmenu = $submenuid; 258 $output .= $submenu->getMenu(); 259 } 260 $output .= "</div></div>"; 261 } 262 $output .= "</div>"; 263 264 return $output; 265 } 266 267 /** 268 * Render this menu as an HTML list 269 * 270 * @return string 271 */ 272 public function getMenuAsList() { 273 if ($this->iconclass) { 274 $class = ' class="' . $this->iconclass . '"'; 275 } else { 276 $class = ''; 277 } 278 if ($this->onclick) { 279 $onclick = ' onclick="' . $this->onclick . '"'; 280 } else { 281 $onclick = ''; 282 } 283 if ($this->link) { 284 $link = ' href="' . $this->link . '"'; 285 } else { 286 $link = ''; 287 } 288 if ($this->id) { 289 $id = ' id="' . $this->id . '"'; 290 } else { 291 $id = ''; 292 } 293 $html = '<a' . $link . $class . $onclick . '>' . $this->label . '</a>'; 294 if ($this->submenus) { 295 $html .= '<ul>'; 296 foreach ($this->submenus as $submenu) { 297 $html .= $submenu->getMenuAsList(); 298 } 299 $html .= '</ul>'; 300 } 301 302 return '<li' . $id . '>' . $html . '</li>'; 303 } 304 305 /** 306 * @return Menu[] 307 */ 308 public function getSubmenus() { 309 return $this->submenus; 310 } 311 312 /** 313 * @param Menu[] $submenus 314 * 315 * @return $this 316 */ 317 public function setSubmenus(array $submenus) { 318 $this->submenus = $submenus; 319 320 return $this; 321 } 322} 323