1a25f0a04SGreg Roach<?php 2a25f0a04SGreg Roach/** 3a25f0a04SGreg Roach * webtrees: online genealogy 4*8fcd0d32SGreg Roach * Copyright (C) 2019 webtrees development team 5a25f0a04SGreg Roach * This program is free software: you can redistribute it and/or modify 6a25f0a04SGreg Roach * it under the terms of the GNU General Public License as published by 7a25f0a04SGreg Roach * the Free Software Foundation, either version 3 of the License, or 8a25f0a04SGreg Roach * (at your option) any later version. 9a25f0a04SGreg Roach * This program is distributed in the hope that it will be useful, 10a25f0a04SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of 11a25f0a04SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12a25f0a04SGreg Roach * GNU General Public License for more details. 13a25f0a04SGreg Roach * You should have received a copy of the GNU General Public License 14a25f0a04SGreg Roach * along with this program. If not, see <http://www.gnu.org/licenses/>. 15a25f0a04SGreg Roach */ 16e7f56f2aSGreg Roachdeclare(strict_types=1); 17e7f56f2aSGreg Roach 1876692c8bSGreg Roachnamespace Fisharebest\Webtrees; 19a25f0a04SGreg Roach 20a25f0a04SGreg Roach/** 2176692c8bSGreg Roach * System for generating menus. 22a25f0a04SGreg Roach */ 23c1010edaSGreg Roachclass Menu 24c1010edaSGreg Roach{ 25a25f0a04SGreg Roach /** @var string The text to be displayed in the mneu */ 26a25f0a04SGreg Roach private $label; 27a25f0a04SGreg Roach 28a25f0a04SGreg Roach /** @var string The target URL or href */ 29a25f0a04SGreg Roach private $link; 30a25f0a04SGreg Roach 313d0a6fa1SGreg Roach /** @var string The CSS class used to style this menu item */ 323d0a6fa1SGreg Roach private $class; 33a25f0a04SGreg Roach 343cf92ae2SGreg Roach /** @var string[] A list of optional HTML attributes, such as onclick or data-xxx */ 353cf92ae2SGreg Roach private $attrs; 36a25f0a04SGreg Roach 3776692c8bSGreg Roach /** @var Menu[] An optional list of sub-menus. */ 38a25f0a04SGreg Roach private $submenus; 39a25f0a04SGreg Roach 40a25f0a04SGreg Roach /** 41a25f0a04SGreg Roach * Constructor for the menu class 42a25f0a04SGreg Roach * 43a25f0a04SGreg Roach * @param string $label The label for the menu item 44a25f0a04SGreg Roach * @param string $link The target URL 453cf92ae2SGreg Roach * @param string $class A CSS class 463cf92ae2SGreg Roach * @param string[] $attrs Optional attributes, such as onclick or data-xxx 47a25f0a04SGreg Roach * @param Menu[] $submenus Any submenus 48a25f0a04SGreg Roach */ 49c1010edaSGreg Roach public function __construct($label, $link = '#', $class = '', array $attrs = [], array $submenus = []) 50c1010edaSGreg Roach { 51a25f0a04SGreg Roach $this 52a25f0a04SGreg Roach ->setLabel($label) 53a25f0a04SGreg Roach ->setLink($link) 543d0a6fa1SGreg Roach ->setClass($class) 553cf92ae2SGreg Roach ->setAttrs($attrs) 56a25f0a04SGreg Roach ->setSubmenus($submenus); 57a25f0a04SGreg Roach } 58a25f0a04SGreg Roach 59a25f0a04SGreg Roach /** 6015d603e7SGreg Roach * Render this menu using Bootstrap4 markup 61a25f0a04SGreg Roach * 62a25f0a04SGreg Roach * @return string 63a25f0a04SGreg Roach */ 64c1010edaSGreg Roach public function bootstrap4() 65c1010edaSGreg Roach { 6626eae716SGreg Roach if (!empty($this->submenus)) { 67a25f0a04SGreg Roach $submenus = ''; 68a25f0a04SGreg Roach foreach ($this->submenus as $submenu) { 6915d603e7SGreg Roach $attrs = ''; 7015d603e7SGreg Roach foreach ($submenu->attrs as $key => $value) { 71d53324c9SGreg Roach $attrs .= ' ' . $key . '="' . e($value) . '"'; 72a25f0a04SGreg Roach } 73a25f0a04SGreg Roach 7415d603e7SGreg Roach $class = trim('dropdown-item ' . $submenu->class); 7525b2dde3SGreg Roach $submenus .= '<a class="' . $class . '" href="' . e($submenu->link) . '"' . $attrs . '>' . $submenu->label . '</a>'; 7615d603e7SGreg Roach } 7715d603e7SGreg Roach 7815d603e7SGreg Roach $class = trim('nav-item dropdown ' . $this->class); 7915d603e7SGreg Roach 80a25f0a04SGreg Roach return 8115d603e7SGreg Roach '<li class="' . $class . '">' . 8215d603e7SGreg Roach '<a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">' . 83a25f0a04SGreg Roach $this->label . 84a25f0a04SGreg Roach '<span class="caret"></span></a>' . 8515d603e7SGreg Roach '<div class="dropdown-menu" role="menu">' . 86a25f0a04SGreg Roach $submenus . 8715d603e7SGreg Roach '</div>' . 88a25f0a04SGreg Roach '</li>'; 89b2ce94c6SRico Sonntag } 90b2ce94c6SRico Sonntag 913cf92ae2SGreg Roach $attrs = ''; 923cf92ae2SGreg Roach foreach ($this->attrs as $key => $value) { 93d53324c9SGreg Roach $attrs .= ' ' . $key . '="' . e($value) . '"'; 94a25f0a04SGreg Roach } 95a25f0a04SGreg Roach 9615d603e7SGreg Roach $class = trim('nav-item ' . $this->class); 9715d603e7SGreg Roach 9825b2dde3SGreg Roach return '<li class="' . $class . '"><a class="nav-link" href="' . e($this->link) . '"' . $attrs . '>' . $this->label . '</a></li>'; 99a25f0a04SGreg Roach } 100a25f0a04SGreg Roach 101a25f0a04SGreg Roach /** 1023cf92ae2SGreg Roach * Get the optional attributes. 1033cf92ae2SGreg Roach * 1043cf92ae2SGreg Roach * @return string[] 1053cf92ae2SGreg Roach */ 1068f53f488SRico Sonntag public function getAttrs(): array 107c1010edaSGreg Roach { 1083cf92ae2SGreg Roach return $this->attrs; 1093cf92ae2SGreg Roach } 1103cf92ae2SGreg Roach 1113cf92ae2SGreg Roach /** 1123cf92ae2SGreg Roach * Set the optional attributes. 1133cf92ae2SGreg Roach * 1143cf92ae2SGreg Roach * @param string[] $attrs 1153cf92ae2SGreg Roach * 1163cf92ae2SGreg Roach * @return $this 1173cf92ae2SGreg Roach */ 1188f53f488SRico Sonntag public function setAttrs(array $attrs): self 119c1010edaSGreg Roach { 1203cf92ae2SGreg Roach $this->attrs = $attrs; 1213cf92ae2SGreg Roach 1223cf92ae2SGreg Roach return $this; 1233cf92ae2SGreg Roach } 1243cf92ae2SGreg Roach 1253cf92ae2SGreg Roach /** 12676692c8bSGreg Roach * Get the class. 12776692c8bSGreg Roach * 128a25f0a04SGreg Roach * @return string 129a25f0a04SGreg Roach */ 1308f53f488SRico Sonntag public function getClass(): string 131c1010edaSGreg Roach { 1323d0a6fa1SGreg Roach return $this->class; 133a25f0a04SGreg Roach } 134a25f0a04SGreg Roach 135a25f0a04SGreg Roach /** 13676692c8bSGreg Roach * Set the class. 13776692c8bSGreg Roach * 1383d0a6fa1SGreg Roach * @param string $class 139a25f0a04SGreg Roach * 140a25f0a04SGreg Roach * @return $this 141a25f0a04SGreg Roach */ 1428f53f488SRico Sonntag public function setClass($class): self 143c1010edaSGreg Roach { 1443d0a6fa1SGreg Roach $this->class = $class; 145a25f0a04SGreg Roach 146a25f0a04SGreg Roach return $this; 147a25f0a04SGreg Roach } 148a25f0a04SGreg Roach 149a25f0a04SGreg Roach /** 15076692c8bSGreg Roach * Get the label. 15176692c8bSGreg Roach * 152a25f0a04SGreg Roach * @return string 153a25f0a04SGreg Roach */ 1548f53f488SRico Sonntag public function getLabel(): string 155c1010edaSGreg Roach { 156a25f0a04SGreg Roach return $this->label; 157a25f0a04SGreg Roach } 158a25f0a04SGreg Roach 159a25f0a04SGreg Roach /** 16076692c8bSGreg Roach * Set the label. 16176692c8bSGreg Roach * 162a25f0a04SGreg Roach * @param string $label 163a25f0a04SGreg Roach * 164a25f0a04SGreg Roach * @return $this 165a25f0a04SGreg Roach */ 1668f53f488SRico Sonntag public function setLabel($label): self 167c1010edaSGreg Roach { 168a25f0a04SGreg Roach $this->label = $label; 169a25f0a04SGreg Roach 170a25f0a04SGreg Roach return $this; 171a25f0a04SGreg Roach } 172a25f0a04SGreg Roach 173a25f0a04SGreg Roach /** 17476692c8bSGreg Roach * Get the link. 1753cf92ae2SGreg Roach * 176a25f0a04SGreg Roach * @return string 177a25f0a04SGreg Roach */ 1788f53f488SRico Sonntag public function getLink(): string 179c1010edaSGreg Roach { 180a25f0a04SGreg Roach return $this->link; 181a25f0a04SGreg Roach } 182a25f0a04SGreg Roach 183a25f0a04SGreg Roach /** 18476692c8bSGreg Roach * Set the link. 18576692c8bSGreg Roach * 186a25f0a04SGreg Roach * @param string $link 187a25f0a04SGreg Roach * 188a25f0a04SGreg Roach * @return $this 189a25f0a04SGreg Roach */ 1908f53f488SRico Sonntag public function setLink($link): self 191c1010edaSGreg Roach { 192a25f0a04SGreg Roach $this->link = $link; 193a25f0a04SGreg Roach 194a25f0a04SGreg Roach return $this; 195a25f0a04SGreg Roach } 196a25f0a04SGreg Roach 197a25f0a04SGreg Roach /** 198a25f0a04SGreg Roach * Add a submenu to this menu 199a25f0a04SGreg Roach * 200ecb5b5e9SGreg Roach * @param Menu $menu 201ecb5b5e9SGreg Roach * 202ecb5b5e9SGreg Roach * @return $this 203a25f0a04SGreg Roach */ 2048f53f488SRico Sonntag public function addSubmenu($menu): self 205c1010edaSGreg Roach { 206a25f0a04SGreg Roach $this->submenus[] = $menu; 207ecb5b5e9SGreg Roach 208ecb5b5e9SGreg Roach return $this; 209a25f0a04SGreg Roach } 210a25f0a04SGreg Roach 211a25f0a04SGreg Roach /** 212a25f0a04SGreg Roach * Render this menu as an HTML list 213a25f0a04SGreg Roach * 214a25f0a04SGreg Roach * @return string 215a25f0a04SGreg Roach */ 2168f53f488SRico Sonntag public function getMenuAsList(): string 217c1010edaSGreg Roach { 2183cf92ae2SGreg Roach $attrs = ''; 2193cf92ae2SGreg Roach foreach ($this->attrs as $key => $value) { 220d53324c9SGreg Roach $attrs .= ' ' . $key . '="' . e($value) . '"'; 221a25f0a04SGreg Roach } 222a25f0a04SGreg Roach if ($this->link) { 22325b2dde3SGreg Roach $link = ' href="' . e($this->link) . '"'; 224a25f0a04SGreg Roach } else { 225a25f0a04SGreg Roach $link = ''; 226a25f0a04SGreg Roach } 2273cf92ae2SGreg Roach $html = '<a' . $link . $attrs . '>' . $this->label . '</a>'; 22826eae716SGreg Roach if (!empty($this->submenus)) { 229a25f0a04SGreg Roach $html .= '<ul>'; 230a25f0a04SGreg Roach foreach ($this->submenus as $submenu) { 231a25f0a04SGreg Roach $html .= $submenu->getMenuAsList(); 232a25f0a04SGreg Roach } 233a25f0a04SGreg Roach $html .= '</ul>'; 234a25f0a04SGreg Roach } 235a25f0a04SGreg Roach 2363d0a6fa1SGreg Roach return '<li class="' . $this->class . '">' . $html . '</li>'; 237a25f0a04SGreg Roach } 238a25f0a04SGreg Roach 239a25f0a04SGreg Roach /** 24076692c8bSGreg Roach * Get the sub-menus. 24176692c8bSGreg Roach * 242a25f0a04SGreg Roach * @return Menu[] 243a25f0a04SGreg Roach */ 2448f53f488SRico Sonntag public function getSubmenus(): array 245c1010edaSGreg Roach { 246a25f0a04SGreg Roach return $this->submenus; 247a25f0a04SGreg Roach } 248a25f0a04SGreg Roach 249a25f0a04SGreg Roach /** 25076692c8bSGreg Roach * Set the sub-menus. 25176692c8bSGreg Roach * 252a25f0a04SGreg Roach * @param Menu[] $submenus 253a25f0a04SGreg Roach * 254a25f0a04SGreg Roach * @return $this 255a25f0a04SGreg Roach */ 2568f53f488SRico Sonntag public function setSubmenus(array $submenus): self 257c1010edaSGreg Roach { 258a25f0a04SGreg Roach $this->submenus = $submenus; 259a25f0a04SGreg Roach 260a25f0a04SGreg Roach return $this; 261a25f0a04SGreg Roach } 262a25f0a04SGreg Roach} 263