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