1<?php 2/** 3 * webtrees: online genealogy 4 * Copyright (C) 2017 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 18/** 19 * System for generating menus. 20 */ 21class Menu { 22 /** @var string The text to be displayed in the mneu */ 23 private $label; 24 25 /** @var string The target URL or href*/ 26 private $link; 27 28 /** @var string The CSS class used to style this menu item */ 29 private $class; 30 31 /** @var string[] A list of optional HTML attributes, such as onclick or data-xxx */ 32 private $attrs; 33 34 /** @var Menu[] An optional list of sub-menus. */ 35 private $submenus; 36 37 /** @var string Used to format javascript menus */ 38 private $submenuclass; 39 40 /** @var string Used to format javascript menus */ 41 private $menuclass; 42 43 /** 44 * Constructor for the menu class 45 * 46 * @param string $label The label for the menu item 47 * @param string $link The target URL 48 * @param string $class A CSS class 49 * @param string[] $attrs Optional attributes, such as onclick or data-xxx 50 * @param Menu[] $submenus Any submenus 51 */ 52 public function __construct($label, $link = '#', $class = '', array $attrs = [], array $submenus = []) { 53 $this 54 ->setLabel($label) 55 ->setLink($link) 56 ->setClass($class) 57 ->setAttrs($attrs) 58 ->setSubmenus($submenus); 59 } 60 61 /** 62 * Render this menu using Bootstrap4 markup 63 * 64 * @return string 65 */ 66 public function bootstrap4() { 67 if ($this->submenus) { 68 $submenus = ''; 69 foreach ($this->submenus as $submenu) { 70 $attrs = ''; 71 foreach ($submenu->attrs as $key => $value) { 72 $attrs .= ' ' . $key . '="' . e($value) . '"'; 73 } 74 75 $class = trim('dropdown-item ' . $submenu->class); 76 $submenus .= '<a class="' . $class . '" href="' . $submenu->link . '"' . $attrs . '>' . $submenu->label . '</a>'; 77 } 78 79 $class = trim('nav-item dropdown ' . $this->class); 80 81 return 82 '<li class="' . $class . '">' . 83 '<a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">' . 84 $this->label . 85 '<span class="caret"></span></a>' . 86 '<div class="dropdown-menu" role="menu">' . 87 $submenus . 88 '</div>' . 89 '</li>'; 90 } else { 91 $attrs = ''; 92 foreach ($this->attrs as $key => $value) { 93 $attrs .= ' ' . $key . '="' . e($value) . '"'; 94 } 95 96 $class = trim('nav-item ' . $this->class); 97 98 return '<li class="' . $class . '"><a class="nav-link" href="' . $this->link . '"' . $attrs . '>' . $this->label . '</a></li>'; 99 } 100 } 101 102 /** 103 * Get the optional attributes. 104 * 105 * @return string[] 106 */ 107 public function getAttrs() { 108 return $this->attrs; 109 } 110 111 /** 112 * Set the optional attributes. 113 * 114 * @param string[] $attrs 115 * 116 * @return $this 117 */ 118 public function setAttrs(array $attrs) { 119 $this->attrs = $attrs; 120 121 return $this; 122 } 123 124 /** 125 * Set the CSS classes for the (legacy) javascript menus 126 * 127 * @param string $menuclass 128 * @param string $submenuclass 129 */ 130 public function addClass($menuclass, $submenuclass = '') { 131 $this->menuclass = $menuclass; 132 $this->submenuclass = $submenuclass; 133 } 134 135 /** 136 * Get the class. 137 * 138 * @return string 139 */ 140 public function getClass() { 141 return $this->class; 142 } 143 144 /** 145 * Set the class. 146 * 147 * @param string $class 148 * 149 * @return $this 150 */ 151 public function setClass($class) { 152 $this->class = $class; 153 154 return $this; 155 } 156 157 /** 158 * Get the label. 159 * 160 * @return string 161 */ 162 public function getLabel() { 163 return $this->label; 164 } 165 166 /** 167 * Set the label. 168 * 169 * @param string $label 170 * 171 * @return $this 172 */ 173 public function setLabel($label) { 174 $this->label = $label; 175 176 return $this; 177 } 178 179 /** 180 * Get the link. 181 * 182 * @return string 183 */ 184 public function getLink() { 185 return $this->link; 186 } 187 188 /** 189 * Set the link. 190 * 191 * @param string $link 192 * 193 * @return $this 194 */ 195 public function setLink($link) { 196 $this->link = $link; 197 198 return $this; 199 } 200 201 /** 202 * Add a submenu to this menu 203 * 204 * @param Menu $menu 205 * 206 * @return $this 207 */ 208 public function addSubmenu($menu) { 209 $this->submenus[] = $menu; 210 211 return $this; 212 } 213 214 /** 215 * Render this menu as an HTML list 216 * 217 * @return string 218 */ 219 public function getMenuAsList() { 220 $attrs = ''; 221 foreach ($this->attrs as $key => $value) { 222 $attrs .= ' ' . $key . '="' . e($value) . '"'; 223 } 224 if ($this->link) { 225 $link = ' href="' . $this->link . '"'; 226 } else { 227 $link = ''; 228 } 229 $html = '<a' . $link . $attrs . '>' . $this->label . '</a>'; 230 if ($this->submenus) { 231 $html .= '<ul>'; 232 foreach ($this->submenus as $submenu) { 233 $html .= $submenu->getMenuAsList(); 234 } 235 $html .= '</ul>'; 236 } 237 238 return '<li class="' . $this->class . '">' . $html . '</li>'; 239 } 240 241 /** 242 * Get the sub-menus. 243 * 244 * @return Menu[] 245 */ 246 public function getSubmenus() { 247 return $this->submenus; 248 } 249 250 /** 251 * Set the sub-menus. 252 * 253 * @param Menu[] $submenus 254 * 255 * @return $this 256 */ 257 public function setSubmenus(array $submenus) { 258 $this->submenus = $submenus; 259 260 return $this; 261 } 262} 263