xref: /webtrees/app/Menu.php (revision 76692c8b291f16d9251d67f27078779f6737fe7e)
1<?php
2/**
3 * webtrees: online genealogy
4 * Copyright (C) 2015 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
18use Rhumsaa\Uuid\Uuid;
19
20/**
21 * System for generating menus.
22 */
23class Menu {
24	/** @var string The text to be displayed in the mneu */
25	private $label;
26
27	/** @var string The target URL or href*/
28	private $link;
29
30	/** @var string The CSS class used to style this menu item */
31	private $class;
32
33	/** @var string An onclick action, typically used with a link of "#" */
34	private $onclick;
35
36	/** @var Menu[] An optional list of sub-menus. */
37	private $submenus;
38
39	/** @var string Used internally to create javascript menus */
40	private $parentmenu;
41
42	/** @var string Used to format javascript menus */
43	private $submenuclass;
44
45	/** @var string Used to format javascript menus */
46	private $menuclass;
47
48	/**
49	 * Constructor for the menu class
50	 *
51	 * @param string    $label    The label for the menu item
52	 * @param string    $link     The target URL
53	 * @param string    $class    An CSS class
54	 * @param string    $onclick  A javascript onclick handler
55	 * @param Menu[] $submenus Any submenus
56	 */
57	public function __construct($label, $link = '#', $class = '', $onclick = '', $submenus = array()) {
58		$this
59			->setLabel($label)
60			->setLink($link)
61			->setClass($class)
62			->setOnclick($onclick)
63			->setSubmenus($submenus);
64	}
65
66	/**
67	 * Convert this menu to an HTML list, for easy rendering of
68	 * lists of menus/nulls.
69	 *
70	 * @return string
71	 */
72	public function __toString() {
73		return $this->getMenuAsList();
74	}
75
76	/**
77	 * Render this menu using Bootstrap markup
78	 *
79	 * @return string
80	 */
81	public function bootstrap() {
82		if ($this->submenus) {
83			$submenus = '';
84			foreach ($this->submenus as $submenu) {
85				$submenus .= $submenu->bootstrap();
86			}
87
88			return
89				'<li class="' . $this->class . ' dropdown">' .
90				'<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">' .
91				$this->label .
92				' <span class="caret"></span></a>' .
93				'<ul class="dropdown-menu" role="menu">' .
94				$submenus .
95				'</ul>' .
96				'</li>';
97		} else {
98			if ($this->onclick) {
99				$onclick = ' onclick="' . $this->onclick . '"';
100			} else {
101				$onclick = '';
102			}
103
104			return '<li class="' . $this->class . '"><a href="' . $this->link . '"' . $onclick . '>' . $this->label . '</a></li>';
105		}
106	}
107
108	/**
109	 * Set the CSS classes for the (legacy) javascript menus
110	 *
111	 * @param string $menuclass
112	 * @param string $submenuclass
113	 */
114	public function addClass($menuclass, $submenuclass = '') {
115		$this->menuclass    = $menuclass;
116		$this->submenuclass = $submenuclass;
117	}
118
119	/**
120	 * Get the class.
121	 *
122	 * @return string
123	 */
124	public function getClass() {
125		return $this->class;
126	}
127
128	/**
129	 * Set the class.
130	 *
131	 * @param string $class
132	 *
133	 * @return $this
134	 */
135	public function setClass($class) {
136		$this->class = $class;
137
138		return $this;
139	}
140
141	/**
142	 * Get the label.
143	 *
144	 * @return string
145	 */
146	public function getLabel() {
147		return $this->label;
148	}
149
150	/**
151	 * Set the label.
152	 *
153	 * @param string $label
154	 *
155	 * @return $this
156	 */
157	public function setLabel($label) {
158		$this->label = $label;
159
160		return $this;
161	}
162
163	/**
164	 * Get the link.
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	 * Get the click handler.
186	 *
187	 * @return string
188	 */
189	public function getOnclick() {
190		return $this->onclick;
191	}
192
193	/**
194	 * Set the click handler.
195	 *
196	 * @param string $onclick
197	 *
198	 * @return $this
199	 */
200	public function setOnclick($onclick) {
201		$this->onclick = $onclick;
202
203		return $this;
204	}
205
206	/**
207	 * Add a submenu to this menu
208	 *
209	 * @param Menu $menu
210	 *
211	 * @return $this
212	 */
213	public function addSubmenu($menu) {
214		$this->submenus[] = $menu;
215
216		return $this;
217	}
218
219	/**
220	 * Render this menu using javascript popups..
221	 *
222	 * @return string
223	 */
224	public function getMenu() {
225		$menu_id     = 'menu-' . Uuid::uuid4();
226		$sub_menu_id = 'sub-' . $menu_id;
227
228		$html = '<a href="' . $this->link . '"';
229		if ($this->onclick) {
230			$html .= ' onclick="' . $this->onclick . '"';
231		}
232		if (!empty($this->submenus)) {
233			$html .= ' onmouseover="show_submenu(\'' . $sub_menu_id . '\', \'' . $menu_id . '\');"';
234			$html .= ' onmouseout="timeout_submenu(\'' . $sub_menu_id . '\');"';
235		}
236		$html .= '>' . $this->label . '</a>';
237
238		if (!empty($this->submenus)) {
239			$html .= '<div id="' . $sub_menu_id . '" class="' . $this->submenuclass . '"';
240			$html .= ' style="position: absolute; visibility: hidden; z-index: 100; text-align: ' . (I18N::direction() === 'ltr' ? 'left' : 'right') . '"';
241			$html .= ' onmouseover="show_submenu(\'' . $this->parentmenu . '\'); show_submenu(\'' . $sub_menu_id . '\');"';
242			$html .= ' onmouseout="timeout_submenu(\'' . $sub_menu_id . '\');">';
243			foreach ($this->submenus as $submenu) {
244				$submenu->parentmenu = $sub_menu_id;
245				$html .= $submenu->getMenu();
246			}
247			$html .= '</div></div>';
248		}
249
250		return '<div id="' . $menu_id . '" class="' . $this->menuclass . '">' . $html . '</div>';
251	}
252
253	/**
254	 * Render this menu as an HTML list
255	 *
256	 * @return string
257	 */
258	public function getMenuAsList() {
259		if ($this->onclick) {
260			$onclick = ' onclick="' . $this->onclick . '"';
261		} else {
262			$onclick = '';
263		}
264		if ($this->link) {
265			$link = ' href="' . $this->link . '"';
266		} else {
267			$link = '';
268		}
269		$html = '<a' . $link . $onclick . '>' . $this->label . '</a>';
270		if ($this->submenus) {
271			$html .= '<ul>';
272			foreach ($this->submenus as $submenu) {
273				$html .= $submenu->getMenuAsList();
274			}
275			$html .= '</ul>';
276		}
277
278		return '<li class="' . $this->class . '">' . $html . '</li>';
279	}
280
281	/**
282	 * Get the sub-menus.
283	 *
284	 * @return Menu[]
285	 */
286	public function getSubmenus() {
287		return $this->submenus;
288	}
289
290	/**
291	 * Set the sub-menus.
292	 *
293	 * @param Menu[] $submenus
294	 *
295	 * @return $this
296	 */
297	public function setSubmenus(array $submenus) {
298		$this->submenus = $submenus;
299
300		return $this;
301	}
302}
303