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