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