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 19use Rhumsaa\Uuid\Uuid; 20 21/** 22 * Class Menu - System for generating menus. 23 */ 24class Menu { 25 /** @var string The text to be displayed in the mneu */ 26 private $label; 27 28 /** @var string The target URL or href*/ 29 private $link; 30 31 /** @var string The CSS class used to style this menu item */ 32 private $class; 33 34 /** @var string An onclick action, typically used with a link of "#" */ 35 private $onclick; 36 37 /** @var Menu[] */ 38 private $submenus; 39 40 /** @var string Used internally to create javascript menus */ 41 private $parentmenu; 42 43 /** @var string Used to format javascript menus */ 44 private $submenuclass; 45 46 /** @var string Used to format javascript menus */ 47 private $menuclass; 48 49 /** 50 * Constructor for the menu class 51 * 52 * @param string $label The label for the menu item 53 * @param string $link The target URL 54 * @param string $class An CSS class 55 * @param string $onclick A javascript onclick handler 56 * @param Menu[] $submenus Any submenus 57 */ 58 public function __construct($label, $link = '#', $class = '', $onclick = '', $submenus = array()) { 59 $this 60 ->setLabel($label) 61 ->setLink($link) 62 ->setClass($class) 63 ->setOnclick($onclick) 64 ->setSubmenus($submenus); 65 } 66 67 /** 68 * Convert this menu to an HTML list, for easy rendering of 69 * lists of menus/nulls. 70 * 71 * @return string 72 */ 73 public function __toString() { 74 return $this->getMenuAsList(); 75 } 76 77 /** 78 * Render this menu using Bootstrap markup 79 * 80 * @return string 81 */ 82 public function bootstrap() { 83 if ($this->submenus) { 84 $submenus = ''; 85 foreach ($this->submenus as $submenu) { 86 $submenus .= $submenu->bootstrap(); 87 } 88 89 return 90 '<li class="' . $this->class . ' dropdown">' . 91 '<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">' . 92 $this->label . 93 ' <span class="caret"></span></a>' . 94 '<ul class="dropdown-menu" role="menu">' . 95 $submenus . 96 '</ul>' . 97 '</li>'; 98 } else { 99 if ($this->onclick) { 100 $onclick = ' onclick="' . $this->onclick . '"'; 101 } else { 102 $onclick = ''; 103 } 104 105 return '<li class="' . $this->class . '"><a href="' . $this->link . '"' . $onclick . '>' . $this->label . '</a></li>'; 106 } 107 } 108 109 /** 110 * Set the CSS classes for the (legacy) javascript menus 111 * 112 * @param string $menuclass 113 * @param string $submenuclass 114 */ 115 public function addClass($menuclass, $submenuclass = '') { 116 $this->menuclass = $menuclass; 117 $this->submenuclass = $submenuclass; 118 } 119 120 /** 121 * @return string 122 */ 123 public function getClass() { 124 return $this->class; 125 } 126 127 /** 128 * @param string $class 129 * 130 * @return $this 131 */ 132 public function setClass($class) { 133 $this->class = $class; 134 135 return $this; 136 } 137 138 /** 139 * @return string 140 */ 141 public function getLabel() { 142 return $this->label; 143 } 144 145 /** 146 * @param string $label 147 * 148 * @return $this 149 */ 150 public function setLabel($label) { 151 $this->label = $label; 152 153 return $this; 154 } 155 156 /** 157 * @return string 158 */ 159 public function getLink() { 160 return $this->link; 161 } 162 163 /** 164 * @param string $link 165 * 166 * @return $this 167 */ 168 public function setLink($link) { 169 $this->link = $link; 170 171 return $this; 172 } 173 174 /** 175 * @return string 176 */ 177 public function getOnclick() { 178 return $this->onclick; 179 } 180 181 /** 182 * @param string $onclick 183 * 184 * @return $this 185 */ 186 public function setOnclick($onclick) { 187 $this->onclick = $onclick; 188 189 return $this; 190 } 191 192 /** 193 * Add a submenu to this menu 194 * 195 * @param Menu $menu 196 * 197 * @return $this 198 */ 199 public function addSubmenu($menu) { 200 $this->submenus[] = $menu; 201 202 return $this; 203 } 204 205 /** 206 * Render this menu using javascript popups.. 207 * 208 * @return string 209 */ 210 public function getMenu() { 211 $menu_id = 'menu-' . Uuid::uuid4(); 212 $sub_menu_id = 'sub-' . $menu_id; 213 214 $html = '<a href="' . $this->link . '"'; 215 if ($this->onclick) { 216 $html .= ' onclick="' . $this->onclick . '"'; 217 } 218 if (!empty($this->submenus)) { 219 $html .= ' onmouseover="show_submenu(\'' . $sub_menu_id . '\', \'' . $menu_id . '\');"'; 220 $html .= ' onmouseout="timeout_submenu(\'' . $sub_menu_id . '\');"'; 221 } 222 $html .= '>' . $this->label . '</a>'; 223 224 if (!empty($this->submenus)) { 225 $html .= '<div id="' . $sub_menu_id . '" class="' . $this->submenuclass . '"'; 226 $html .= ' style="position: absolute; visibility: hidden; z-index: 100; text-align: ' . (I18N::direction() === 'ltr' ? 'left' : 'right') . '"'; 227 $html .= ' onmouseover="show_submenu(\'' . $this->parentmenu . '\'); show_submenu(\'' . $sub_menu_id . '\');"'; 228 $html .= ' onmouseout="timeout_submenu(\'' . $sub_menu_id . '\');">'; 229 foreach ($this->submenus as $submenu) { 230 $submenu->parentmenu = $sub_menu_id; 231 $html .= $submenu->getMenu(); 232 } 233 $html .= '</div></div>'; 234 } 235 236 return '<div id="' . $menu_id . '" class="' . $this->menuclass . '">' . $html . '</div>'; 237 } 238 239 /** 240 * Render this menu as an HTML list 241 * 242 * @return string 243 */ 244 public function getMenuAsList() { 245 if ($this->onclick) { 246 $onclick = ' onclick="' . $this->onclick . '"'; 247 } else { 248 $onclick = ''; 249 } 250 if ($this->link) { 251 $link = ' href="' . $this->link . '"'; 252 } else { 253 $link = ''; 254 } 255 $html = '<a' . $link . $onclick . '>' . $this->label . '</a>'; 256 if ($this->submenus) { 257 $html .= '<ul>'; 258 foreach ($this->submenus as $submenu) { 259 $html .= $submenu->getMenuAsList(); 260 } 261 $html .= '</ul>'; 262 } 263 264 return '<li class="' . $this->class . '">' . $html . '</li>'; 265 } 266 267 /** 268 * @return Menu[] 269 */ 270 public function getSubmenus() { 271 return $this->submenus; 272 } 273 274 /** 275 * @param Menu[] $submenus 276 * 277 * @return $this 278 */ 279 public function setSubmenus(array $submenus) { 280 $this->submenus = $submenus; 281 282 return $this; 283 } 284} 285