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