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