xref: /webtrees/app/Menu.php (revision 76692c8b291f16d9251d67f27078779f6737fe7e)
1a25f0a04SGreg Roach<?php
2a25f0a04SGreg Roach/**
3a25f0a04SGreg Roach * webtrees: online genealogy
4a25f0a04SGreg Roach * Copyright (C) 2015 webtrees development team
5a25f0a04SGreg Roach * This program is free software: you can redistribute it and/or modify
6a25f0a04SGreg Roach * it under the terms of the GNU General Public License as published by
7a25f0a04SGreg Roach * the Free Software Foundation, either version 3 of the License, or
8a25f0a04SGreg Roach * (at your option) any later version.
9a25f0a04SGreg Roach * This program is distributed in the hope that it will be useful,
10a25f0a04SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of
11a25f0a04SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12a25f0a04SGreg Roach * GNU General Public License for more details.
13a25f0a04SGreg Roach * You should have received a copy of the GNU General Public License
14a25f0a04SGreg Roach * along with this program. If not, see <http://www.gnu.org/licenses/>.
15a25f0a04SGreg Roach */
16*76692c8bSGreg Roachnamespace Fisharebest\Webtrees;
17a25f0a04SGreg Roach
18fee045eeSGreg Roachuse Rhumsaa\Uuid\Uuid;
19fee045eeSGreg Roach
20a25f0a04SGreg Roach/**
21*76692c8bSGreg Roach * System for generating menus.
22a25f0a04SGreg Roach */
23a25f0a04SGreg Roachclass Menu {
24a25f0a04SGreg Roach	/** @var string The text to be displayed in the mneu */
25a25f0a04SGreg Roach	private $label;
26a25f0a04SGreg Roach
27a25f0a04SGreg Roach	/** @var string The target URL or href*/
28a25f0a04SGreg Roach	private $link;
29a25f0a04SGreg Roach
303d0a6fa1SGreg Roach	/** @var string The CSS class used to style this menu item */
313d0a6fa1SGreg Roach	private $class;
32a25f0a04SGreg Roach
33a25f0a04SGreg Roach	/** @var string An onclick action, typically used with a link of "#" */
34a25f0a04SGreg Roach	private $onclick;
35a25f0a04SGreg Roach
36*76692c8bSGreg Roach	/** @var Menu[] An optional list of sub-menus. */
37a25f0a04SGreg Roach	private $submenus;
38a25f0a04SGreg Roach
39a25f0a04SGreg Roach	/** @var string Used internally to create javascript menus */
40a25f0a04SGreg Roach	private $parentmenu;
41a25f0a04SGreg Roach
42a25f0a04SGreg Roach	/** @var string Used to format javascript menus */
43a25f0a04SGreg Roach	private $submenuclass;
44a25f0a04SGreg Roach
45a25f0a04SGreg Roach	/** @var string Used to format javascript menus */
463d0a6fa1SGreg Roach	private $menuclass;
47a25f0a04SGreg Roach
48a25f0a04SGreg Roach	/**
49a25f0a04SGreg Roach	 * Constructor for the menu class
50a25f0a04SGreg Roach	 *
51a25f0a04SGreg Roach	 * @param string    $label    The label for the menu item
52a25f0a04SGreg Roach	 * @param string    $link     The target URL
533d0a6fa1SGreg Roach	 * @param string    $class    An CSS class
54a25f0a04SGreg Roach	 * @param string    $onclick  A javascript onclick handler
55a25f0a04SGreg Roach	 * @param Menu[] $submenus Any submenus
56a25f0a04SGreg Roach	 */
573d0a6fa1SGreg Roach	public function __construct($label, $link = '#', $class = '', $onclick = '', $submenus = array()) {
58a25f0a04SGreg Roach		$this
59a25f0a04SGreg Roach			->setLabel($label)
60a25f0a04SGreg Roach			->setLink($link)
613d0a6fa1SGreg Roach			->setClass($class)
62a25f0a04SGreg Roach			->setOnclick($onclick)
63a25f0a04SGreg Roach			->setSubmenus($submenus);
64a25f0a04SGreg Roach	}
65a25f0a04SGreg Roach
66a25f0a04SGreg Roach	/**
67a25f0a04SGreg Roach	 * Convert this menu to an HTML list, for easy rendering of
68a25f0a04SGreg Roach	 * lists of menus/nulls.
69a25f0a04SGreg Roach	 *
70a25f0a04SGreg Roach	 * @return string
71a25f0a04SGreg Roach	 */
72a25f0a04SGreg Roach	public function __toString() {
73a25f0a04SGreg Roach		return $this->getMenuAsList();
74a25f0a04SGreg Roach	}
75a25f0a04SGreg Roach
76a25f0a04SGreg Roach	/**
77a25f0a04SGreg Roach	 * Render this menu using Bootstrap markup
78a25f0a04SGreg Roach	 *
79a25f0a04SGreg Roach	 * @return string
80a25f0a04SGreg Roach	 */
81a25f0a04SGreg Roach	public function bootstrap() {
82a25f0a04SGreg Roach		if ($this->submenus) {
83a25f0a04SGreg Roach			$submenus = '';
84a25f0a04SGreg Roach			foreach ($this->submenus as $submenu) {
85a25f0a04SGreg Roach				$submenus .= $submenu->bootstrap();
86a25f0a04SGreg Roach			}
87a25f0a04SGreg Roach
88a25f0a04SGreg Roach			return
893d0a6fa1SGreg Roach				'<li class="' . $this->class . ' dropdown">' .
90a25f0a04SGreg Roach				'<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">' .
91a25f0a04SGreg Roach				$this->label .
92a25f0a04SGreg Roach				' <span class="caret"></span></a>' .
93a25f0a04SGreg Roach				'<ul class="dropdown-menu" role="menu">' .
94a25f0a04SGreg Roach				$submenus .
95a25f0a04SGreg Roach				'</ul>' .
96a25f0a04SGreg Roach				'</li>';
97a25f0a04SGreg Roach		} else {
98a25f0a04SGreg Roach			if ($this->onclick) {
99a25f0a04SGreg Roach				$onclick = ' onclick="' . $this->onclick . '"';
100a25f0a04SGreg Roach			} else {
101a25f0a04SGreg Roach				$onclick = '';
102a25f0a04SGreg Roach			}
103a25f0a04SGreg Roach
1043d0a6fa1SGreg Roach			return '<li class="' . $this->class . '"><a href="' . $this->link . '"' . $onclick . '>' . $this->label . '</a></li>';
105a25f0a04SGreg Roach		}
106a25f0a04SGreg Roach	}
107a25f0a04SGreg Roach
108a25f0a04SGreg Roach	/**
1093d0a6fa1SGreg Roach	 * Set the CSS classes for the (legacy) javascript menus
110a25f0a04SGreg Roach	 *
111794c6b5bSGreg Roach	 * @param string $menuclass
112a25f0a04SGreg Roach	 * @param string $submenuclass
113a25f0a04SGreg Roach	 */
114cfd4d92fSGreg Roach	public function addClass($menuclass, $submenuclass = '') {
1153d0a6fa1SGreg Roach		$this->menuclass    = $menuclass;
116a25f0a04SGreg Roach		$this->submenuclass = $submenuclass;
117a25f0a04SGreg Roach	}
118a25f0a04SGreg Roach
119a25f0a04SGreg Roach	/**
120*76692c8bSGreg Roach	 * Get the class.
121*76692c8bSGreg Roach	 *
122a25f0a04SGreg Roach	 * @return string
123a25f0a04SGreg Roach	 */
1243d0a6fa1SGreg Roach	public function getClass() {
1253d0a6fa1SGreg Roach		return $this->class;
126a25f0a04SGreg Roach	}
127a25f0a04SGreg Roach
128a25f0a04SGreg Roach	/**
129*76692c8bSGreg Roach	 * Set the class.
130*76692c8bSGreg Roach	 *
1313d0a6fa1SGreg Roach	 * @param string $class
132a25f0a04SGreg Roach	 *
133a25f0a04SGreg Roach	 * @return $this
134a25f0a04SGreg Roach	 */
1353d0a6fa1SGreg Roach	public function setClass($class) {
1363d0a6fa1SGreg Roach		$this->class = $class;
137a25f0a04SGreg Roach
138a25f0a04SGreg Roach		return $this;
139a25f0a04SGreg Roach	}
140a25f0a04SGreg Roach
141a25f0a04SGreg Roach	/**
142*76692c8bSGreg Roach	 * Get the label.
143*76692c8bSGreg Roach	 *
144a25f0a04SGreg Roach	 * @return string
145a25f0a04SGreg Roach	 */
146a25f0a04SGreg Roach	public function getLabel() {
147a25f0a04SGreg Roach		return $this->label;
148a25f0a04SGreg Roach	}
149a25f0a04SGreg Roach
150a25f0a04SGreg Roach	/**
151*76692c8bSGreg Roach	 * Set the label.
152*76692c8bSGreg Roach	 *
153a25f0a04SGreg Roach	 * @param string $label
154a25f0a04SGreg Roach	 *
155a25f0a04SGreg Roach	 * @return $this
156a25f0a04SGreg Roach	 */
157a25f0a04SGreg Roach	public function setLabel($label) {
158a25f0a04SGreg Roach		$this->label = $label;
159a25f0a04SGreg Roach
160a25f0a04SGreg Roach		return $this;
161a25f0a04SGreg Roach	}
162a25f0a04SGreg Roach
163a25f0a04SGreg Roach	/**
164*76692c8bSGreg Roach	 * Get the link.
165a25f0a04SGreg Roach	 * @return string
166a25f0a04SGreg Roach	 */
167a25f0a04SGreg Roach	public function getLink() {
168a25f0a04SGreg Roach		return $this->link;
169a25f0a04SGreg Roach	}
170a25f0a04SGreg Roach
171a25f0a04SGreg Roach	/**
172*76692c8bSGreg Roach	 * Set the link.
173*76692c8bSGreg Roach	 *
174a25f0a04SGreg Roach	 * @param string $link
175a25f0a04SGreg Roach	 *
176a25f0a04SGreg Roach	 * @return $this
177a25f0a04SGreg Roach	 */
178a25f0a04SGreg Roach	public function setLink($link) {
179a25f0a04SGreg Roach		$this->link = $link;
180a25f0a04SGreg Roach
181a25f0a04SGreg Roach		return $this;
182a25f0a04SGreg Roach	}
183a25f0a04SGreg Roach
184a25f0a04SGreg Roach	/**
185*76692c8bSGreg Roach	 * Get the click handler.
186*76692c8bSGreg Roach	 *
187a25f0a04SGreg Roach	 * @return string
188a25f0a04SGreg Roach	 */
189a25f0a04SGreg Roach	public function getOnclick() {
190a25f0a04SGreg Roach		return $this->onclick;
191a25f0a04SGreg Roach	}
192a25f0a04SGreg Roach
193a25f0a04SGreg Roach	/**
194*76692c8bSGreg Roach	 * Set the click handler.
195*76692c8bSGreg Roach	 *
196a25f0a04SGreg Roach	 * @param string $onclick
197a25f0a04SGreg Roach	 *
198a25f0a04SGreg Roach	 * @return $this
199a25f0a04SGreg Roach	 */
200a25f0a04SGreg Roach	public function setOnclick($onclick) {
201a25f0a04SGreg Roach		$this->onclick = $onclick;
202a25f0a04SGreg Roach
203a25f0a04SGreg Roach		return $this;
204a25f0a04SGreg Roach	}
205a25f0a04SGreg Roach
206a25f0a04SGreg Roach	/**
207a25f0a04SGreg Roach	 * Add a submenu to this menu
208a25f0a04SGreg Roach	 *
209ecb5b5e9SGreg Roach	 * @param Menu $menu
210ecb5b5e9SGreg Roach	 *
211ecb5b5e9SGreg Roach	 * @return $this
212a25f0a04SGreg Roach	 */
213a25f0a04SGreg Roach	public function addSubmenu($menu) {
214a25f0a04SGreg Roach		$this->submenus[] = $menu;
215ecb5b5e9SGreg Roach
216ecb5b5e9SGreg Roach		return $this;
217a25f0a04SGreg Roach	}
218a25f0a04SGreg Roach
219a25f0a04SGreg Roach	/**
220a25f0a04SGreg Roach	 * Render this menu using javascript popups..
221a25f0a04SGreg Roach	 *
222a25f0a04SGreg Roach	 * @return string
223a25f0a04SGreg Roach	 */
224a25f0a04SGreg Roach	public function getMenu() {
225fee045eeSGreg Roach		$menu_id     = 'menu-' . Uuid::uuid4();
226fee045eeSGreg Roach		$sub_menu_id = 'sub-' . $menu_id;
227a25f0a04SGreg Roach
228fee045eeSGreg Roach		$html = '<a href="' . $this->link . '"';
229a25f0a04SGreg Roach		if ($this->onclick) {
230fee045eeSGreg Roach			$html .= ' onclick="' . $this->onclick . '"';
231a25f0a04SGreg Roach		}
232fee045eeSGreg Roach		if (!empty($this->submenus)) {
233fee045eeSGreg Roach			$html .= ' onmouseover="show_submenu(\'' . $sub_menu_id . '\', \'' . $menu_id . '\');"';
234fee045eeSGreg Roach			$html .= ' onmouseout="timeout_submenu(\'' . $sub_menu_id . '\');"';
235fee045eeSGreg Roach		}
236fee045eeSGreg Roach		$html .= '>' . $this->label . '</a>';
237a25f0a04SGreg Roach
238fee045eeSGreg Roach		if (!empty($this->submenus)) {
239fee045eeSGreg Roach			$html .= '<div id="' . $sub_menu_id . '" class="' . $this->submenuclass . '"';
240fee045eeSGreg Roach			$html .= ' style="position: absolute; visibility: hidden; z-index: 100; text-align: ' . (I18N::direction() === 'ltr' ? 'left' : 'right') . '"';
241fee045eeSGreg Roach			$html .= ' onmouseover="show_submenu(\'' . $this->parentmenu . '\'); show_submenu(\'' . $sub_menu_id . '\');"';
242fee045eeSGreg Roach			$html .= ' onmouseout="timeout_submenu(\'' . $sub_menu_id . '\');">';
243a25f0a04SGreg Roach			foreach ($this->submenus as $submenu) {
244fee045eeSGreg Roach				$submenu->parentmenu = $sub_menu_id;
245fee045eeSGreg Roach				$html .= $submenu->getMenu();
246a25f0a04SGreg Roach			}
247fee045eeSGreg Roach			$html .= '</div></div>';
248a25f0a04SGreg Roach		}
249a25f0a04SGreg Roach
250fee045eeSGreg Roach		return '<div id="' . $menu_id . '" class="' . $this->menuclass . '">' . $html . '</div>';
251a25f0a04SGreg Roach	}
252a25f0a04SGreg Roach
253a25f0a04SGreg Roach	/**
254a25f0a04SGreg Roach	 * Render this menu as an HTML list
255a25f0a04SGreg Roach	 *
256a25f0a04SGreg Roach	 * @return string
257a25f0a04SGreg Roach	 */
258a25f0a04SGreg Roach	public function getMenuAsList() {
259a25f0a04SGreg Roach		if ($this->onclick) {
260a25f0a04SGreg Roach			$onclick = ' onclick="' . $this->onclick . '"';
261a25f0a04SGreg Roach		} else {
262a25f0a04SGreg Roach			$onclick = '';
263a25f0a04SGreg Roach		}
264a25f0a04SGreg Roach		if ($this->link) {
265a25f0a04SGreg Roach			$link = ' href="' . $this->link . '"';
266a25f0a04SGreg Roach		} else {
267a25f0a04SGreg Roach			$link = '';
268a25f0a04SGreg Roach		}
2693d0a6fa1SGreg Roach		$html = '<a' . $link . $onclick . '>' . $this->label . '</a>';
270a25f0a04SGreg Roach		if ($this->submenus) {
271a25f0a04SGreg Roach			$html .= '<ul>';
272a25f0a04SGreg Roach			foreach ($this->submenus as $submenu) {
273a25f0a04SGreg Roach				$html .= $submenu->getMenuAsList();
274a25f0a04SGreg Roach			}
275a25f0a04SGreg Roach			$html .= '</ul>';
276a25f0a04SGreg Roach		}
277a25f0a04SGreg Roach
2783d0a6fa1SGreg Roach		return '<li class="' . $this->class . '">' . $html . '</li>';
279a25f0a04SGreg Roach	}
280a25f0a04SGreg Roach
281a25f0a04SGreg Roach	/**
282*76692c8bSGreg Roach	 * Get the sub-menus.
283*76692c8bSGreg Roach	 *
284a25f0a04SGreg Roach	 * @return Menu[]
285a25f0a04SGreg Roach	 */
286a25f0a04SGreg Roach	public function getSubmenus() {
287a25f0a04SGreg Roach		return $this->submenus;
288a25f0a04SGreg Roach	}
289a25f0a04SGreg Roach
290a25f0a04SGreg Roach	/**
291*76692c8bSGreg Roach	 * Set the sub-menus.
292*76692c8bSGreg Roach	 *
293a25f0a04SGreg Roach	 * @param Menu[] $submenus
294a25f0a04SGreg Roach	 *
295a25f0a04SGreg Roach	 * @return $this
296a25f0a04SGreg Roach	 */
297a25f0a04SGreg Roach	public function setSubmenus(array $submenus) {
298a25f0a04SGreg Roach		$this->submenus = $submenus;
299a25f0a04SGreg Roach
300a25f0a04SGreg Roach		return $this;
301a25f0a04SGreg Roach	}
302a25f0a04SGreg Roach}
303