1<?php 2 3/** 4 * webtrees: online genealogy 5 * Copyright (C) 2019 webtrees development team 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18declare(strict_types=1); 19 20namespace Fisharebest\Webtrees; 21 22/** 23 * System for generating menus. 24 */ 25class Menu 26{ 27 /** @var string The text to be displayed in the mneu */ 28 private $label; 29 30 /** @var string The target URL or href */ 31 private $link; 32 33 /** @var string The CSS class used to style this menu item */ 34 private $class; 35 36 /** @var string[] A list of optional HTML attributes, such as onclick or data-xxx */ 37 private $attrs; 38 39 /** @var Menu[] An optional list of sub-menus. */ 40 private $submenus; 41 42 /** 43 * Constructor for the menu class 44 * 45 * @param string $label The label for the menu item 46 * @param string $link The target URL 47 * @param string $class A CSS class 48 * @param string[] $attrs Optional attributes, such as onclick or data-xxx 49 * @param Menu[] $submenus Any submenus 50 */ 51 public function __construct($label, $link = '#', $class = '', array $attrs = [], array $submenus = []) 52 { 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(): string 67 { 68 if (!empty($this->submenus)) { 69 $submenus = ''; 70 foreach ($this->submenus as $submenu) { 71 $attrs = ''; 72 foreach ($submenu->attrs as $key => $value) { 73 $attrs .= ' ' . $key . '="' . e($value) . '"'; 74 } 75 76 $class = trim('dropdown-item ' . $submenu->class); 77 $submenus .= '<a class="' . $class . '" href="' . e($submenu->link) . '"' . $attrs . '>' . $submenu->label . '</a>'; 78 } 79 80 $class = trim('nav-item dropdown ' . $this->class); 81 82 return 83 '<li class="' . $class . '">' . 84 '<a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">' . 85 $this->label . 86 '<span class="caret"></span></a>' . 87 '<div class="dropdown-menu" role="menu">' . 88 $submenus . 89 '</div>' . 90 '</li>'; 91 } 92 93 $attrs = ''; 94 foreach ($this->attrs as $key => $value) { 95 $attrs .= ' ' . $key . '="' . e($value) . '"'; 96 } 97 98 $class = trim('nav-item ' . $this->class); 99 100 return '<li class="' . $class . '"><a class="nav-link" href="' . e($this->link) . '"' . $attrs . '>' . $this->label . '</a></li>'; 101 } 102 103 /** 104 * Get the optional attributes. 105 * 106 * @return string[] 107 */ 108 public function getAttrs(): array 109 { 110 return $this->attrs; 111 } 112 113 /** 114 * Set the optional attributes. 115 * 116 * @param string[] $attrs 117 * 118 * @return $this 119 */ 120 public function setAttrs(array $attrs): self 121 { 122 $this->attrs = $attrs; 123 124 return $this; 125 } 126 127 /** 128 * Get the class. 129 * 130 * @return string 131 */ 132 public function getClass(): string 133 { 134 return $this->class; 135 } 136 137 /** 138 * Set the class. 139 * 140 * @param string $class 141 * 142 * @return $this 143 */ 144 public function setClass($class): self 145 { 146 $this->class = $class; 147 148 return $this; 149 } 150 151 /** 152 * Get the label. 153 * 154 * @return string 155 */ 156 public function getLabel(): string 157 { 158 return $this->label; 159 } 160 161 /** 162 * Set the label. 163 * 164 * @param string $label 165 * 166 * @return $this 167 */ 168 public function setLabel($label): self 169 { 170 $this->label = $label; 171 172 return $this; 173 } 174 175 /** 176 * Get the link. 177 * 178 * @return string 179 */ 180 public function getLink(): string 181 { 182 return $this->link; 183 } 184 185 /** 186 * Set the link. 187 * 188 * @param string $link 189 * 190 * @return $this 191 */ 192 public function setLink($link): self 193 { 194 $this->link = $link; 195 196 return $this; 197 } 198 199 /** 200 * Add a submenu to this menu 201 * 202 * @param Menu $menu 203 * 204 * @return $this 205 */ 206 public function addSubmenu($menu): self 207 { 208 $this->submenus[] = $menu; 209 210 return $this; 211 } 212 213 /** 214 * Get the sub-menus. 215 * 216 * @return Menu[] 217 */ 218 public function getSubmenus(): array 219 { 220 return $this->submenus; 221 } 222 223 /** 224 * Set the sub-menus. 225 * 226 * @param Menu[] $submenus 227 * 228 * @return $this 229 */ 230 public function setSubmenus(array $submenus): self 231 { 232 $this->submenus = $submenus; 233 234 return $this; 235 } 236} 237