xref: /webtrees/app/Menu.php (revision c0af647e81556017a98111a745041435fb9eb47d)
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[]
210	 */
211	public function addSubmenu($menu) {
212		$this->submenus[] = $menu;
213	}
214
215	/**
216	 * Render this menu using javascript popups..
217	 *
218	 * @return string
219	 */
220	public function getMenu() {
221		global $menucount;
222
223		if (!isset($menucount)) {
224			$menucount = 0;
225		} else {
226			$menucount++;
227		}
228		$id = $menucount . rand();
229		$c = count($this->submenus);
230		$output = "<div id=\"menu{$id}\" class=\"{$this->class}\">";
231		$link = "<a href=\"{$this->link}\" onmouseover=\"";
232		if ($c >= 0) {
233			$link .= "show_submenu('menu{$id}_subs', 'menu{$id}');";
234		}
235		$link .= '" onmouseout="';
236		if ($c >= 0) {
237			$link .= "timeout_submenu('menu{$id}_subs');";
238		}
239		if ($this->onclick) {
240			$link .= "\" onclick=\"{$this->onclick}";
241		}
242		$link .= "\">";
243		$output .= $link;
244		$output .= $this->label;
245		$output .= "</a>";
246
247		if ($c > 0) {
248			$submenuid = "menu{$id}_subs";
249			if (I18N::direction() === 'ltr') {
250				$output .= '<div style="text-align: left;">';
251			} else {
252				$output .= '<div style="text-align: right;">';
253			}
254			$output .= "<div id=\"menu{$id}_subs\" class=\"{$this->submenuclass}\" style=\"position: absolute; visibility: hidden; z-index: 100;";
255			$output .= "\" onmouseover=\"show_submenu('{$this->parentmenu}'); show_submenu('{$submenuid}');\" onmouseout=\"timeout_submenu('menu{$id}_subs');\">";
256			foreach ($this->submenus as $submenu) {
257				$submenu->parentmenu = $submenuid;
258				$output .= $submenu->getMenu();
259			}
260			$output .= "</div></div>";
261		}
262		$output .= "</div>";
263
264		return $output;
265	}
266
267	/**
268	 * Render this menu as an HTML list
269	 *
270	 * @return string
271	 */
272	public function getMenuAsList() {
273		if ($this->iconclass) {
274			$class = ' class="' . $this->iconclass . '"';
275		} else {
276			$class = '';
277		}
278		if ($this->onclick) {
279			$onclick = ' onclick="' . $this->onclick . '"';
280		} else {
281			$onclick = '';
282		}
283		if ($this->link) {
284			$link = ' href="' . $this->link . '"';
285		} else {
286			$link = '';
287		}
288		if ($this->id) {
289			$id = ' id="' . $this->id . '"';
290		} else {
291			$id = '';
292		}
293		$html = '<a' . $link . $class . $onclick . '>' . $this->label . '</a>';
294		if ($this->submenus) {
295			$html .= '<ul>';
296			foreach ($this->submenus as $submenu) {
297				$html .= $submenu->getMenuAsList();
298			}
299			$html .= '</ul>';
300		}
301
302		return '<li' . $id . '>' . $html . '</li>';
303	}
304
305	/**
306	 * @return Menu[]
307	 */
308	public function getSubmenus() {
309		return $this->submenus;
310	}
311
312	/**
313	 * @param Menu[] $submenus
314	 *
315	 * @return $this
316	 */
317	public function setSubmenus(array $submenus) {
318		$this->submenus = $submenus;
319
320		return $this;
321	}
322}
323