xref: /webtrees/app/Menu.php (revision 15d603e7c7c15d20f055d3d9c38d6b133453c5be)
1a25f0a04SGreg Roach<?php
2a25f0a04SGreg Roach/**
3a25f0a04SGreg Roach * webtrees: online genealogy
46bdf7674SGreg Roach * Copyright (C) 2017 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 */
1676692c8bSGreg Roachnamespace Fisharebest\Webtrees;
17a25f0a04SGreg Roach
18a25f0a04SGreg Roach/**
1976692c8bSGreg Roach * System for generating menus.
20a25f0a04SGreg Roach */
21a25f0a04SGreg Roachclass Menu {
22a25f0a04SGreg Roach	/** @var string The text to be displayed in the mneu */
23a25f0a04SGreg Roach	private $label;
24a25f0a04SGreg Roach
25a25f0a04SGreg Roach	/** @var string The target URL or href*/
26a25f0a04SGreg Roach	private $link;
27a25f0a04SGreg Roach
283d0a6fa1SGreg Roach	/** @var string The CSS class used to style this menu item */
293d0a6fa1SGreg Roach	private $class;
30a25f0a04SGreg Roach
313cf92ae2SGreg Roach	/** @var string[] A list of optional HTML attributes, such as onclick or data-xxx */
323cf92ae2SGreg Roach	private $attrs;
33a25f0a04SGreg Roach
3476692c8bSGreg Roach	/** @var Menu[] An optional list of sub-menus. */
35a25f0a04SGreg Roach	private $submenus;
36a25f0a04SGreg Roach
37a25f0a04SGreg Roach	/** @var string Used internally to create javascript menus */
38a25f0a04SGreg Roach	private $parentmenu;
39a25f0a04SGreg Roach
40a25f0a04SGreg Roach	/** @var string Used to format javascript menus */
41a25f0a04SGreg Roach	private $submenuclass;
42a25f0a04SGreg Roach
43a25f0a04SGreg Roach	/** @var string Used to format javascript menus */
443d0a6fa1SGreg Roach	private $menuclass;
45a25f0a04SGreg Roach
46a25f0a04SGreg Roach	/**
47a25f0a04SGreg Roach	 * Constructor for the menu class
48a25f0a04SGreg Roach	 *
49a25f0a04SGreg Roach	 * @param string   $label    The label for the menu item
50a25f0a04SGreg Roach	 * @param string   $link     The target URL
513cf92ae2SGreg Roach	 * @param string   $class    A CSS class
523cf92ae2SGreg Roach	 * @param string[] $attrs    Optional attributes, such as onclick or data-xxx
53a25f0a04SGreg Roach	 * @param Menu[]   $submenus Any submenus
54a25f0a04SGreg Roach	 */
5513abd6f3SGreg Roach	public function __construct($label, $link = '#', $class = '', array $attrs = [], array $submenus = []) {
56a25f0a04SGreg Roach		$this
57a25f0a04SGreg Roach			->setLabel($label)
58a25f0a04SGreg Roach			->setLink($link)
593d0a6fa1SGreg Roach			->setClass($class)
603cf92ae2SGreg Roach			->setAttrs($attrs)
61a25f0a04SGreg Roach			->setSubmenus($submenus);
62a25f0a04SGreg Roach	}
63a25f0a04SGreg Roach
64a25f0a04SGreg Roach	/**
65*15d603e7SGreg Roach	 * Render this menu using Bootstrap4 markup
66a25f0a04SGreg Roach	 *
67a25f0a04SGreg Roach	 * @return string
68a25f0a04SGreg Roach	 */
69*15d603e7SGreg Roach	public function bootstrap4() {
70a25f0a04SGreg Roach		if ($this->submenus) {
71a25f0a04SGreg Roach			$submenus = '';
72a25f0a04SGreg Roach			foreach ($this->submenus as $submenu) {
73*15d603e7SGreg Roach				$attrs = '';
74*15d603e7SGreg Roach				foreach ($submenu->attrs as $key => $value) {
75*15d603e7SGreg Roach					$attrs .= ' ' . $key . '="' . Filter::escapeHtml($value) . '"';
76a25f0a04SGreg Roach				}
77a25f0a04SGreg Roach
78*15d603e7SGreg Roach				$class = trim('dropdown-item ' . $submenu->class);
79*15d603e7SGreg Roach				$submenus .= '<a class="' . $class . '" href="' . $submenu->link . '"' . $attrs . '>' . $submenu->label . '</a>';
80*15d603e7SGreg Roach			}
81*15d603e7SGreg Roach
82*15d603e7SGreg Roach			$class = trim('nav-item dropdown ' . $this->class);
83*15d603e7SGreg Roach
84a25f0a04SGreg Roach			return
85*15d603e7SGreg Roach				'<li class="' . $class . '">' .
86*15d603e7SGreg Roach				'<a href="#" class="nav-link dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">' .
87a25f0a04SGreg Roach				$this->label .
88a25f0a04SGreg Roach				'<span class="caret"></span></a>' .
89*15d603e7SGreg Roach				'<div class="dropdown-menu" role="menu">' .
90a25f0a04SGreg Roach				$submenus .
91*15d603e7SGreg Roach				'</div>' .
92a25f0a04SGreg Roach				'</li>';
93a25f0a04SGreg Roach		} else {
943cf92ae2SGreg Roach			$attrs = '';
953cf92ae2SGreg Roach			foreach ($this->attrs as $key => $value) {
963cf92ae2SGreg Roach				$attrs .= ' ' . $key . '="' . Filter::escapeHtml($value) . '"';
97a25f0a04SGreg Roach			}
98a25f0a04SGreg Roach
99*15d603e7SGreg Roach			$class = trim('nav-item ' . $this->class);
100*15d603e7SGreg Roach
101*15d603e7SGreg Roach			return '<li class="' . $class . '"><a class="nav-link" href="' . $this->link . '"' . $attrs . '>' . $this->label . '</a></li>';
102a25f0a04SGreg Roach		}
103a25f0a04SGreg Roach	}
104a25f0a04SGreg Roach
105a25f0a04SGreg Roach	/**
1063cf92ae2SGreg Roach	 * Get the optional attributes.
1073cf92ae2SGreg Roach	 *
1083cf92ae2SGreg Roach	 * @return string[]
1093cf92ae2SGreg Roach	 */
1103cf92ae2SGreg Roach	public function getAttrs() {
1113cf92ae2SGreg Roach		return $this->attrs;
1123cf92ae2SGreg Roach	}
1133cf92ae2SGreg Roach
1143cf92ae2SGreg Roach	/**
1153cf92ae2SGreg Roach	 * Set the optional attributes.
1163cf92ae2SGreg Roach	 *
1173cf92ae2SGreg Roach	 * @param string[] $attrs
1183cf92ae2SGreg Roach	 *
1193cf92ae2SGreg Roach	 * @return $this
1203cf92ae2SGreg Roach	 */
1213cf92ae2SGreg Roach	public function setAttrs(array $attrs) {
1223cf92ae2SGreg Roach		$this->attrs = $attrs;
1233cf92ae2SGreg Roach
1243cf92ae2SGreg Roach		return $this;
1253cf92ae2SGreg Roach	}
1263cf92ae2SGreg Roach
1273cf92ae2SGreg Roach	/**
1283d0a6fa1SGreg Roach	 * Set the CSS classes for the (legacy) javascript menus
129a25f0a04SGreg Roach	 *
130794c6b5bSGreg Roach	 * @param string $menuclass
131a25f0a04SGreg Roach	 * @param string $submenuclass
132a25f0a04SGreg Roach	 */
133cfd4d92fSGreg Roach	public function addClass($menuclass, $submenuclass = '') {
1343d0a6fa1SGreg Roach		$this->menuclass    = $menuclass;
135a25f0a04SGreg Roach		$this->submenuclass = $submenuclass;
136a25f0a04SGreg Roach	}
137a25f0a04SGreg Roach
138a25f0a04SGreg Roach	/**
13976692c8bSGreg Roach	 * Get the class.
14076692c8bSGreg Roach	 *
141a25f0a04SGreg Roach	 * @return string
142a25f0a04SGreg Roach	 */
1433d0a6fa1SGreg Roach	public function getClass() {
1443d0a6fa1SGreg Roach		return $this->class;
145a25f0a04SGreg Roach	}
146a25f0a04SGreg Roach
147a25f0a04SGreg Roach	/**
14876692c8bSGreg Roach	 * Set the class.
14976692c8bSGreg Roach	 *
1503d0a6fa1SGreg Roach	 * @param string $class
151a25f0a04SGreg Roach	 *
152a25f0a04SGreg Roach	 * @return $this
153a25f0a04SGreg Roach	 */
1543d0a6fa1SGreg Roach	public function setClass($class) {
1553d0a6fa1SGreg Roach		$this->class = $class;
156a25f0a04SGreg Roach
157a25f0a04SGreg Roach		return $this;
158a25f0a04SGreg Roach	}
159a25f0a04SGreg Roach
160a25f0a04SGreg Roach	/**
16176692c8bSGreg Roach	 * Get the label.
16276692c8bSGreg Roach	 *
163a25f0a04SGreg Roach	 * @return string
164a25f0a04SGreg Roach	 */
165a25f0a04SGreg Roach	public function getLabel() {
166a25f0a04SGreg Roach		return $this->label;
167a25f0a04SGreg Roach	}
168a25f0a04SGreg Roach
169a25f0a04SGreg Roach	/**
17076692c8bSGreg Roach	 * Set the label.
17176692c8bSGreg Roach	 *
172a25f0a04SGreg Roach	 * @param string $label
173a25f0a04SGreg Roach	 *
174a25f0a04SGreg Roach	 * @return $this
175a25f0a04SGreg Roach	 */
176a25f0a04SGreg Roach	public function setLabel($label) {
177a25f0a04SGreg Roach		$this->label = $label;
178a25f0a04SGreg Roach
179a25f0a04SGreg Roach		return $this;
180a25f0a04SGreg Roach	}
181a25f0a04SGreg Roach
182a25f0a04SGreg Roach	/**
18376692c8bSGreg Roach	 * Get the link.
1843cf92ae2SGreg Roach	 *
185a25f0a04SGreg Roach	 * @return string
186a25f0a04SGreg Roach	 */
187a25f0a04SGreg Roach	public function getLink() {
188a25f0a04SGreg Roach		return $this->link;
189a25f0a04SGreg Roach	}
190a25f0a04SGreg Roach
191a25f0a04SGreg Roach	/**
19276692c8bSGreg Roach	 * Set the link.
19376692c8bSGreg Roach	 *
194a25f0a04SGreg Roach	 * @param string $link
195a25f0a04SGreg Roach	 *
196a25f0a04SGreg Roach	 * @return $this
197a25f0a04SGreg Roach	 */
198a25f0a04SGreg Roach	public function setLink($link) {
199a25f0a04SGreg Roach		$this->link = $link;
200a25f0a04SGreg Roach
201a25f0a04SGreg Roach		return $this;
202a25f0a04SGreg Roach	}
203a25f0a04SGreg Roach
204a25f0a04SGreg Roach	/**
205a25f0a04SGreg Roach	 * Add a submenu to this menu
206a25f0a04SGreg Roach	 *
207ecb5b5e9SGreg Roach	 * @param Menu $menu
208ecb5b5e9SGreg Roach	 *
209ecb5b5e9SGreg Roach	 * @return $this
210a25f0a04SGreg Roach	 */
211a25f0a04SGreg Roach	public function addSubmenu($menu) {
212a25f0a04SGreg Roach		$this->submenus[] = $menu;
213ecb5b5e9SGreg Roach
214ecb5b5e9SGreg Roach		return $this;
215a25f0a04SGreg Roach	}
216a25f0a04SGreg Roach
217a25f0a04SGreg Roach	/**
218a25f0a04SGreg Roach	 * Render this menu as an HTML list
219a25f0a04SGreg Roach	 *
220a25f0a04SGreg Roach	 * @return string
221a25f0a04SGreg Roach	 */
222a25f0a04SGreg Roach	public function getMenuAsList() {
2233cf92ae2SGreg Roach		$attrs = '';
2243cf92ae2SGreg Roach		foreach ($this->attrs as $key => $value) {
2253cf92ae2SGreg Roach			$attrs .= ' ' . $key . '="' . Filter::escapeHtml($value) . '"';
226a25f0a04SGreg Roach		}
227a25f0a04SGreg Roach		if ($this->link) {
228a25f0a04SGreg Roach			$link = ' href="' . $this->link . '"';
229a25f0a04SGreg Roach		} else {
230a25f0a04SGreg Roach			$link = '';
231a25f0a04SGreg Roach		}
2323cf92ae2SGreg Roach		$html = '<a' . $link . $attrs . '>' . $this->label . '</a>';
233a25f0a04SGreg Roach		if ($this->submenus) {
234a25f0a04SGreg Roach			$html .= '<ul>';
235a25f0a04SGreg Roach			foreach ($this->submenus as $submenu) {
236a25f0a04SGreg Roach				$html .= $submenu->getMenuAsList();
237a25f0a04SGreg Roach			}
238a25f0a04SGreg Roach			$html .= '</ul>';
239a25f0a04SGreg Roach		}
240a25f0a04SGreg Roach
2413d0a6fa1SGreg Roach		return '<li class="' . $this->class . '">' . $html . '</li>';
242a25f0a04SGreg Roach	}
243a25f0a04SGreg Roach
244a25f0a04SGreg Roach	/**
24576692c8bSGreg Roach	 * Get the sub-menus.
24676692c8bSGreg Roach	 *
247a25f0a04SGreg Roach	 * @return Menu[]
248a25f0a04SGreg Roach	 */
249a25f0a04SGreg Roach	public function getSubmenus() {
250a25f0a04SGreg Roach		return $this->submenus;
251a25f0a04SGreg Roach	}
252a25f0a04SGreg Roach
253a25f0a04SGreg Roach	/**
25476692c8bSGreg Roach	 * Set the sub-menus.
25576692c8bSGreg Roach	 *
256a25f0a04SGreg Roach	 * @param Menu[] $submenus
257a25f0a04SGreg Roach	 *
258a25f0a04SGreg Roach	 * @return $this
259a25f0a04SGreg Roach	 */
260a25f0a04SGreg Roach	public function setSubmenus(array $submenus) {
261a25f0a04SGreg Roach		$this->submenus = $submenus;
262a25f0a04SGreg Roach
263a25f0a04SGreg Roach		return $this;
264a25f0a04SGreg Roach	}
265a25f0a04SGreg Roach}
266