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 class used to style this menu item */ 30 private $class; 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 $menuclass; 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 $class An CSS class 56 * @param string $onclick A javascript onclick handler 57 * @param Menu[] $submenus Any submenus 58 */ 59 public function __construct($label, $link = '#', $class = '', $onclick = '', $submenus = array()) { 60 $this 61 ->setLabel($label) 62 ->setLink($link) 63 ->setClass($class) 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->submenus) { 85 $submenus = ''; 86 foreach ($this->submenus as $submenu) { 87 $submenus .= $submenu->bootstrap(); 88 } 89 90 return 91 '<li class="' . $this->class . ' dropdown">' . 92 '<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">' . 93 $this->label . 94 ' <span class="caret"></span></a>' . 95 '<ul class="dropdown-menu" role="menu">' . 96 $submenus . 97 '</ul>' . 98 '</li>'; 99 } else { 100 if ($this->onclick) { 101 $onclick = ' onclick="' . $this->onclick . '"'; 102 } else { 103 $onclick = ''; 104 } 105 106 return '<li class="' . $this->class . '"><a href="' . $this->link . '"' . $onclick . '>' . $this->label . '</a></li>'; 107 } 108 } 109 110 /** 111 * Set the CSS classes for the (legacy) javascript menus 112 * 113 * @param string $menuclass 114 * @param string $submenuclass 115 * @param string $iconclass 116 */ 117 public function addClass($menuclass, $submenuclass = '', $iconclass = '') { 118 $this->menuclass = $menuclass; 119 $this->submenuclass = $submenuclass; 120 $this->iconclass = $iconclass; 121 } 122 123 /** 124 * @return string 125 */ 126 public function getClass() { 127 return $this->class; 128 } 129 130 /** 131 * @param string $class 132 * 133 * @return $this 134 */ 135 public function setClass($class) { 136 $this->class = $class; 137 138 return $this; 139 } 140 141 /** 142 * @return string 143 */ 144 public function getLabel() { 145 return $this->label; 146 } 147 148 /** 149 * @param string $label 150 * 151 * @return $this 152 */ 153 public function setLabel($label) { 154 $this->label = $label; 155 156 return $this; 157 } 158 159 /** 160 * @return string 161 */ 162 public function getLink() { 163 return $this->link; 164 } 165 166 /** 167 * @param string $link 168 * 169 * @return $this 170 */ 171 public function setLink($link) { 172 $this->link = $link; 173 174 return $this; 175 } 176 177 /** 178 * @return string 179 */ 180 public function getOnclick() { 181 return $this->onclick; 182 } 183 184 /** 185 * @param string $onclick 186 * 187 * @return $this 188 */ 189 public function setOnclick($onclick) { 190 $this->onclick = $onclick; 191 192 return $this; 193 } 194 195 /** 196 * Add a submenu to this menu 197 * 198 * @param Menu $menu 199 * 200 * @return $this 201 */ 202 public function addSubmenu($menu) { 203 $this->submenus[] = $menu; 204 205 return $this; 206 } 207 208 /** 209 * Render this menu using javascript popups.. 210 * 211 * @return string 212 */ 213 public function getMenu() { 214 global $menucount; 215 216 if (!isset($menucount)) { 217 $menucount = 0; 218 } else { 219 $menucount++; 220 } 221 $id = $menucount . rand(); 222 $c = count($this->submenus); 223 $output = "<div id=\"menu{$id}\" class=\"{$this->menuclass}\">"; 224 $link = "<a href=\"{$this->link}\" onmouseover=\""; 225 if ($c >= 0) { 226 $link .= "show_submenu('menu{$id}_subs', 'menu{$id}');"; 227 } 228 $link .= '" onmouseout="'; 229 if ($c >= 0) { 230 $link .= "timeout_submenu('menu{$id}_subs');"; 231 } 232 if ($this->onclick) { 233 $link .= "\" onclick=\"{$this->onclick}"; 234 } 235 $link .= "\">"; 236 $output .= $link; 237 $output .= $this->label; 238 $output .= "</a>"; 239 240 if ($c > 0) { 241 $submenuid = "menu{$id}_subs"; 242 if (I18N::direction() === 'ltr') { 243 $output .= '<div style="text-align: left;">'; 244 } else { 245 $output .= '<div style="text-align: right;">'; 246 } 247 $output .= "<div id=\"menu{$id}_subs\" class=\"{$this->submenuclass}\" style=\"position: absolute; visibility: hidden; z-index: 100;"; 248 $output .= "\" onmouseover=\"show_submenu('{$this->parentmenu}'); show_submenu('{$submenuid}');\" onmouseout=\"timeout_submenu('menu{$id}_subs');\">"; 249 foreach ($this->submenus as $submenu) { 250 $submenu->parentmenu = $submenuid; 251 $output .= $submenu->getMenu(); 252 } 253 $output .= "</div></div>"; 254 } 255 $output .= "</div>"; 256 257 return $output; 258 } 259 260 /** 261 * Render this menu as an HTML list 262 * 263 * @return string 264 */ 265 public function getMenuAsList() { 266 if ($this->onclick) { 267 $onclick = ' onclick="' . $this->onclick . '"'; 268 } else { 269 $onclick = ''; 270 } 271 if ($this->link) { 272 $link = ' href="' . $this->link . '"'; 273 } else { 274 $link = ''; 275 } 276 $html = '<a' . $link . $onclick . '>' . $this->label . '</a>'; 277 if ($this->submenus) { 278 $html .= '<ul>'; 279 foreach ($this->submenus as $submenu) { 280 $html .= $submenu->getMenuAsList(); 281 } 282 $html .= '</ul>'; 283 } 284 285 return '<li class="' . $this->class . '">' . $html . '</li>'; 286 } 287 288 /** 289 * @return Menu[] 290 */ 291 public function getSubmenus() { 292 return $this->submenus; 293 } 294 295 /** 296 * @param Menu[] $submenus 297 * 298 * @return $this 299 */ 300 public function setSubmenus(array $submenus) { 301 $this->submenus = $submenus; 302 303 return $this; 304 } 305} 306