xref: /webtrees/app/Menu.php (revision b78374c50ebb252fee5fd5a0776cef82b73f2bf3)
1<?php
2namespace Fisharebest\Webtrees;
3
4/**
5 * webtrees: online genealogy
6 * Copyright (C) 2015 webtrees development team
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19/**
20 * Class Menu - System for generating menus.
21 */
22class Menu {
23	/** @var string The text to be displayed in the mneu */
24	private $label;
25
26	/** @var string The target URL or href*/
27	private $link;
28
29	/** @var string The CSS ID to be used for this menu item */
30	private $id;
31
32	/** @var string An onclick action, typically used with a link of "#" */
33	private $onclick;
34
35	/** @var Menu[] */
36	private $submenus;
37
38	/** @var string Used internally to create javascript menus */
39	private $parentmenu;
40
41	/** @var string Used to format javascript menus */
42	private $submenuclass;
43
44	/** @var string Used to format javascript menus */
45	private $iconclass;
46
47	/** @var string Used to format javascript menus */
48	private $class;
49
50	/**
51	 * Constructor for the menu class
52	 *
53	 * @param string    $label    The label for the menu item
54	 * @param string    $link     The target URL
55	 * @param string    $id       An CSS identifier
56	 * @param string    $onclick  A javascript onclick handler
57	 * @param Menu[] $submenus Any submenus
58	 */
59	public function __construct($label, $link = '#', $id = '', $onclick = '', $submenus = array()) {
60		$this
61			->setLabel($label)
62			->setLink($link)
63			->setId($id)
64			->setOnclick($onclick)
65			->setSubmenus($submenus);
66	}
67
68	/**
69	 * Convert this menu to an HTML list, for easy rendering of
70	 * lists of menus/nulls.
71	 *
72	 * @return string
73	 */
74	public function __toString() {
75		return $this->getMenuAsList();
76	}
77
78	/**
79	 * Render this menu using Bootstrap markup
80	 *
81	 * @return string
82	 */
83	public function bootstrap() {
84		if ($this->iconclass) {
85			$class = ' class="' . $this->iconclass . '"';
86		} else {
87			$class = '';
88		}
89		if ($this->id) {
90			$id = ' id="' . $this->id . '"';
91		} else {
92			$id = '';
93		}
94
95		if ($this->submenus) {
96			$submenus = '';
97			foreach ($this->submenus as $submenu) {
98				$submenus .= $submenu->bootstrap();
99			}
100
101			return
102				'<li' . $id . ' class="dropdown">' .
103				'<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">' .
104				$this->label .
105				' <span class="caret"></span></a>' .
106				'<ul class="dropdown-menu" role="menu">' .
107				$submenus .
108				'</ul>' .
109				'</li>';
110		} else {
111			if ($this->onclick) {
112				$onclick = ' onclick="' . $this->onclick . '"';
113			} else {
114				$onclick = '';
115			}
116
117			return '<li' . $id . $class . '><a href="' . $this->link . '"' . $onclick . '>' . $this->label . '</a></li>';
118		}
119	}
120
121	/**
122	 * Set the CSS classes for this menu
123	 *
124	 * @param string $class
125	 * @param string $submenuclass
126	 * @param string $iconclass
127	 */
128	public function addClass($class, $submenuclass = '', $iconclass = '') {
129		$this->class = $class;
130		$this->submenuclass = $submenuclass;
131		$this->iconclass = $iconclass;
132	}
133
134	/**
135	 * @return string
136	 */
137	public function getId() {
138		return $this->id;
139	}
140
141	/**
142	 * @param string $id
143	 *
144	 * @return $this
145	 */
146	public function setId($id) {
147		$this->id = $id;
148
149		return $this;
150	}
151
152	/**
153	 * @return string
154	 */
155	public function getLabel() {
156		return $this->label;
157	}
158
159	/**
160	 * @param string $label
161	 *
162	 * @return $this
163	 */
164	public function setLabel($label) {
165		$this->label = $label;
166
167		return $this;
168	}
169
170	/**
171	 * @return string
172	 */
173	public function getLink() {
174		return $this->link;
175	}
176
177	/**
178	 * @param string $link
179	 *
180	 * @return $this
181	 */
182	public function setLink($link) {
183		$this->link = $link;
184
185		return $this;
186	}
187
188	/**
189	 * @return string
190	 */
191	public function getOnclick() {
192		return $this->onclick;
193	}
194
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		global $menucount;
226
227		if (!isset($menucount)) {
228			$menucount = 0;
229		} else {
230			$menucount++;
231		}
232		$id = $menucount . rand();
233		$c = count($this->submenus);
234		$output = "<div id=\"menu{$id}\" class=\"{$this->class}\">";
235		$link = "<a href=\"{$this->link}\" onmouseover=\"";
236		if ($c >= 0) {
237			$link .= "show_submenu('menu{$id}_subs', 'menu{$id}');";
238		}
239		$link .= '" onmouseout="';
240		if ($c >= 0) {
241			$link .= "timeout_submenu('menu{$id}_subs');";
242		}
243		if ($this->onclick) {
244			$link .= "\" onclick=\"{$this->onclick}";
245		}
246		$link .= "\">";
247		$output .= $link;
248		$output .= $this->label;
249		$output .= "</a>";
250
251		if ($c > 0) {
252			$submenuid = "menu{$id}_subs";
253			if (I18N::direction() === 'ltr') {
254				$output .= '<div style="text-align: left;">';
255			} else {
256				$output .= '<div style="text-align: right;">';
257			}
258			$output .= "<div id=\"menu{$id}_subs\" class=\"{$this->submenuclass}\" style=\"position: absolute; visibility: hidden; z-index: 100;";
259			$output .= "\" onmouseover=\"show_submenu('{$this->parentmenu}'); show_submenu('{$submenuid}');\" onmouseout=\"timeout_submenu('menu{$id}_subs');\">";
260			foreach ($this->submenus as $submenu) {
261				$submenu->parentmenu = $submenuid;
262				$output .= $submenu->getMenu();
263			}
264			$output .= "</div></div>";
265		}
266		$output .= "</div>";
267
268		return $output;
269	}
270
271	/**
272	 * Render this menu as an HTML list
273	 *
274	 * @return string
275	 */
276	public function getMenuAsList() {
277		if ($this->iconclass) {
278			$class = ' class="' . $this->iconclass . '"';
279		} else {
280			$class = '';
281		}
282		if ($this->onclick) {
283			$onclick = ' onclick="' . $this->onclick . '"';
284		} else {
285			$onclick = '';
286		}
287		if ($this->link) {
288			$link = ' href="' . $this->link . '"';
289		} else {
290			$link = '';
291		}
292		if ($this->id) {
293			$id = ' id="' . $this->id . '"';
294		} else {
295			$id = '';
296		}
297		$html = '<a' . $link . $class . $onclick . '>' . $this->label . '</a>';
298		if ($this->submenus) {
299			$html .= '<ul>';
300			foreach ($this->submenus as $submenu) {
301				$html .= $submenu->getMenuAsList();
302			}
303			$html .= '</ul>';
304		}
305
306		return '<li' . $id . '>' . $html . '</li>';
307	}
308
309	/**
310	 * @return Menu[]
311	 */
312	public function getSubmenus() {
313		return $this->submenus;
314	}
315
316	/**
317	 * @param Menu[] $submenus
318	 *
319	 * @return $this
320	 */
321	public function setSubmenus(array $submenus) {
322		$this->submenus = $submenus;
323
324		return $this;
325	}
326}
327