xref: /webtrees/app/Menu.php (revision bba27599b02e0b6f90f62348bb4fa32bd74056d0)
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