xref: /webtrees/app/Menu.php (revision 3d0a6fa104c785a847746348b8ca40fdd4474e89)
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 class used to style this menu item */
30	private $class;
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 $menuclass;
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    $class    An CSS class
56	 * @param string    $onclick  A javascript onclick handler
57	 * @param Menu[] $submenus Any submenus
58	 */
59	public function __construct($label, $link = '#', $class = '', $onclick = '', $submenus = array()) {
60		$this
61			->setLabel($label)
62			->setLink($link)
63			->setClass($class)
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->submenus) {
85			$submenus = '';
86			foreach ($this->submenus as $submenu) {
87				$submenus .= $submenu->bootstrap();
88			}
89
90			return
91				'<li class="' . $this->class . ' dropdown">' .
92				'<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">' .
93				$this->label .
94				' <span class="caret"></span></a>' .
95				'<ul class="dropdown-menu" role="menu">' .
96				$submenus .
97				'</ul>' .
98				'</li>';
99		} else {
100			if ($this->onclick) {
101				$onclick = ' onclick="' . $this->onclick . '"';
102			} else {
103				$onclick = '';
104			}
105
106			return '<li class="' . $this->class . '"><a href="' . $this->link . '"' . $onclick . '>' . $this->label . '</a></li>';
107		}
108	}
109
110	/**
111	 * Set the CSS classes for the (legacy) javascript menus
112	 *
113	 * @param string $class
114	 * @param string $submenuclass
115	 * @param string $iconclass
116	 */
117	public function addClass($menuclass, $submenuclass = '', $iconclass = '') {
118		$this->menuclass = $menuclass;
119		$this->submenuclass = $submenuclass;
120		$this->iconclass = $iconclass;
121	}
122
123	/**
124	 * @return string
125	 */
126	public function getClass() {
127		return $this->class;
128	}
129
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	 * @return string
143	 */
144	public function getLabel() {
145		return $this->label;
146	}
147
148	/**
149	 * @param string $label
150	 *
151	 * @return $this
152	 */
153	public function setLabel($label) {
154		$this->label = $label;
155
156		return $this;
157	}
158
159	/**
160	 * @return string
161	 */
162	public function getLink() {
163		return $this->link;
164	}
165
166	/**
167	 * @param string $link
168	 *
169	 * @return $this
170	 */
171	public function setLink($link) {
172		$this->link = $link;
173
174		return $this;
175	}
176
177	/**
178	 * @return string
179	 */
180	public function getOnclick() {
181		return $this->onclick;
182	}
183
184	/**
185	 * @param string $onclick
186	 *
187	 * @return $this
188	 */
189	public function setOnclick($onclick) {
190		$this->onclick = $onclick;
191
192		return $this;
193	}
194
195	/**
196	 * Add a submenu to this menu
197	 *
198	 * @param Menu $menu
199	 *
200	 * @return $this
201	 */
202	public function addSubmenu($menu) {
203		$this->submenus[] = $menu;
204
205		return $this;
206	}
207
208	/**
209	 * Render this menu using javascript popups..
210	 *
211	 * @return string
212	 */
213	public function getMenu() {
214		global $menucount;
215
216		if (!isset($menucount)) {
217			$menucount = 0;
218		} else {
219			$menucount++;
220		}
221		$id = $menucount . rand();
222		$c = count($this->submenus);
223		$output = "<div id=\"menu{$id}\" class=\"{$this->menuclass}\">";
224		$link = "<a href=\"{$this->link}\" onmouseover=\"";
225		if ($c >= 0) {
226			$link .= "show_submenu('menu{$id}_subs', 'menu{$id}');";
227		}
228		$link .= '" onmouseout="';
229		if ($c >= 0) {
230			$link .= "timeout_submenu('menu{$id}_subs');";
231		}
232		if ($this->onclick) {
233			$link .= "\" onclick=\"{$this->onclick}";
234		}
235		$link .= "\">";
236		$output .= $link;
237		$output .= $this->label;
238		$output .= "</a>";
239
240		if ($c > 0) {
241			$submenuid = "menu{$id}_subs";
242			if (I18N::direction() === 'ltr') {
243				$output .= '<div style="text-align: left;">';
244			} else {
245				$output .= '<div style="text-align: right;">';
246			}
247			$output .= "<div id=\"menu{$id}_subs\" class=\"{$this->submenuclass}\" style=\"position: absolute; visibility: hidden; z-index: 100;";
248			$output .= "\" onmouseover=\"show_submenu('{$this->parentmenu}'); show_submenu('{$submenuid}');\" onmouseout=\"timeout_submenu('menu{$id}_subs');\">";
249			foreach ($this->submenus as $submenu) {
250				$submenu->parentmenu = $submenuid;
251				$output .= $submenu->getMenu();
252			}
253			$output .= "</div></div>";
254		}
255		$output .= "</div>";
256
257		return $output;
258	}
259
260	/**
261	 * Render this menu as an HTML list
262	 *
263	 * @return string
264	 */
265	public function getMenuAsList() {
266		if ($this->onclick) {
267			$onclick = ' onclick="' . $this->onclick . '"';
268		} else {
269			$onclick = '';
270		}
271		if ($this->link) {
272			$link = ' href="' . $this->link . '"';
273		} else {
274			$link = '';
275		}
276		$html = '<a' . $link . $onclick . '>' . $this->label . '</a>';
277		if ($this->submenus) {
278			$html .= '<ul>';
279			foreach ($this->submenus as $submenu) {
280				$html .= $submenu->getMenuAsList();
281			}
282			$html .= '</ul>';
283		}
284
285		return '<li class="' . $this->class . '">' . $html . '</li>';
286	}
287
288	/**
289	 * @return Menu[]
290	 */
291	public function getSubmenus() {
292		return $this->submenus;
293	}
294
295	/**
296	 * @param Menu[] $submenus
297	 *
298	 * @return $this
299	 */
300	public function setSubmenus(array $submenus) {
301		$this->submenus = $submenus;
302
303		return $this;
304	}
305}
306