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 */ 17declare(strict_types=1); 18 19namespace Fisharebest\Webtrees; 20 21/** 22 * System for generating menus. 23 */ 24class Menu 25{ 26 /** @var string The text to be displayed in the mneu */ 27 private $label; 28 29 /** @var string The target URL or href */ 30 private $link; 31 32 /** @var string The CSS class used to style this menu item */ 33 private $class; 34 35 /** @var string[] A list of optional HTML attributes, such as onclick or data-xxx */ 36 private $attrs; 37 38 /** @var Menu[] An optional list of sub-menus. */ 39 private $submenus; 40 41 /** 42 * Constructor for the menu class 43 * 44 * @param string $label The label for the menu item 45 * @param string $link The target URL 46 * @param string $class A CSS class 47 * @param string[] $attrs Optional attributes, such as onclick or data-xxx 48 * @param Menu[] $submenus Any submenus 49 */ 50 public function __construct($label, $link = '#', $class = '', array $attrs = [], array $submenus = []) 51 { 52 $this 53 ->setLabel($label) 54 ->setLink($link) 55 ->setClass($class) 56 ->setAttrs($attrs) 57 ->setSubmenus($submenus); 58 } 59 60 /** 61 * Render this menu using Bootstrap4 markup 62 * 63 * @return string 64 */ 65 public function bootstrap4(): string 66 { 67 if (!empty($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="' . e($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 } 91 92 $attrs = ''; 93 foreach ($this->attrs as $key => $value) { 94 $attrs .= ' ' . $key . '="' . e($value) . '"'; 95 } 96 97 $class = trim('nav-item ' . $this->class); 98 99 return '<li class="' . $class . '"><a class="nav-link" href="' . e($this->link) . '"' . $attrs . '>' . $this->label . '</a></li>'; 100 } 101 102 /** 103 * Get the optional attributes. 104 * 105 * @return string[] 106 */ 107 public function getAttrs(): array 108 { 109 return $this->attrs; 110 } 111 112 /** 113 * Set the optional attributes. 114 * 115 * @param string[] $attrs 116 * 117 * @return $this 118 */ 119 public function setAttrs(array $attrs): self 120 { 121 $this->attrs = $attrs; 122 123 return $this; 124 } 125 126 /** 127 * Get the class. 128 * 129 * @return string 130 */ 131 public function getClass(): string 132 { 133 return $this->class; 134 } 135 136 /** 137 * Set the class. 138 * 139 * @param string $class 140 * 141 * @return $this 142 */ 143 public function setClass($class): self 144 { 145 $this->class = $class; 146 147 return $this; 148 } 149 150 /** 151 * Get the label. 152 * 153 * @return string 154 */ 155 public function getLabel(): string 156 { 157 return $this->label; 158 } 159 160 /** 161 * Set the label. 162 * 163 * @param string $label 164 * 165 * @return $this 166 */ 167 public function setLabel($label): self 168 { 169 $this->label = $label; 170 171 return $this; 172 } 173 174 /** 175 * Get the link. 176 * 177 * @return string 178 */ 179 public function getLink(): string 180 { 181 return $this->link; 182 } 183 184 /** 185 * Set the link. 186 * 187 * @param string $link 188 * 189 * @return $this 190 */ 191 public function setLink($link): self 192 { 193 $this->link = $link; 194 195 return $this; 196 } 197 198 /** 199 * Add a submenu to this menu 200 * 201 * @param Menu $menu 202 * 203 * @return $this 204 */ 205 public function addSubmenu($menu): self 206 { 207 $this->submenus[] = $menu; 208 209 return $this; 210 } 211 212 /** 213 * Get the sub-menus. 214 * 215 * @return Menu[] 216 */ 217 public function getSubmenus(): array 218 { 219 return $this->submenus; 220 } 221 222 /** 223 * Set the sub-menus. 224 * 225 * @param Menu[] $submenus 226 * 227 * @return $this 228 */ 229 public function setSubmenus(array $submenus): self 230 { 231 $this->submenus = $submenus; 232 233 return $this; 234 } 235} 236