<?php /** * webtrees: online genealogy * Copyright (C) 2016 webtrees development team * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ namespace Fisharebest\Webtrees; use Rhumsaa\Uuid\Uuid; /** * System for generating menus. */ class Menu { /** @var string The text to be displayed in the mneu */ private $label; /** @var string The target URL or href*/ private $link; /** @var string The CSS class used to style this menu item */ private $class; /** @var string[] A list of optional HTML attributes, such as onclick or data-xxx */ private $attrs; /** @var Menu[] An optional list of sub-menus. */ private $submenus; /** @var string Used internally to create javascript menus */ private $parentmenu; /** @var string Used to format javascript menus */ private $submenuclass; /** @var string Used to format javascript menus */ private $menuclass; /** * Constructor for the menu class * * @param string $label The label for the menu item * @param string $link The target URL * @param string $class A CSS class * @param string[] $attrs Optional attributes, such as onclick or data-xxx * @param Menu[] $submenus Any submenus */ public function __construct($label, $link = '#', $class = '', array $attrs = array(), array $submenus = array()) { $this ->setLabel($label) ->setLink($link) ->setClass($class) ->setAttrs($attrs) ->setSubmenus($submenus); } /** * Convert this menu to an HTML list, for easy rendering of * lists of menus/nulls. * * @return string */ public function __toString() { return $this->getMenuAsList(); } /** * Render this menu using Bootstrap markup * * @return string */ public function bootstrap() { if ($this->submenus) { $submenus = ''; foreach ($this->submenus as $submenu) { $submenus .= $submenu->bootstrap(); } return '<li class="' . $this->class . ' dropdown">' . '<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">' . $this->label . ' <span class="caret"></span></a>' . '<ul class="dropdown-menu" role="menu">' . $submenus . '</ul>' . '</li>'; } else { $attrs = ''; foreach ($this->attrs as $key => $value) { $attrs .= ' ' . $key . '="' . Filter::escapeHtml($value) . '"'; } return '<li class="' . $this->class . '"><a href="' . $this->link . '"' . $attrs . '>' . $this->label . '</a></li>'; } } /** * Get the optional attributes. * * @return string[] */ public function getAttrs() { return $this->attrs; } /** * Set the optional attributes. * * @param string[] $attrs * * @return $this */ public function setAttrs(array $attrs) { $this->attrs = $attrs; return $this; } /** * Set the CSS classes for the (legacy) javascript menus * * @param string $menuclass * @param string $submenuclass */ public function addClass($menuclass, $submenuclass = '') { $this->menuclass = $menuclass; $this->submenuclass = $submenuclass; } /** * Get the class. * * @return string */ public function getClass() { return $this->class; } /** * Set the class. * * @param string $class * * @return $this */ public function setClass($class) { $this->class = $class; return $this; } /** * Get the label. * * @return string */ public function getLabel() { return $this->label; } /** * Set the label. * * @param string $label * * @return $this */ public function setLabel($label) { $this->label = $label; return $this; } /** * Get the link. * * @return string */ public function getLink() { return $this->link; } /** * Set the link. * * @param string $link * * @return $this */ public function setLink($link) { $this->link = $link; return $this; } /** * Add a submenu to this menu * * @param Menu $menu * * @return $this */ public function addSubmenu($menu) { $this->submenus[] = $menu; return $this; } /** * Render this menu using javascript popups.. * * @return string */ public function getMenu() { $menu_id = 'menu-' . Uuid::uuid4(); $sub_menu_id = 'sub-' . $menu_id; $html = '<a href="' . $this->link . '"'; foreach ($this->attrs as $key => $value) { $html .= ' ' . $key . '="' . Filter::escapeHtml($value) . '"'; } if (!empty($this->submenus)) { $html .= ' onmouseover="show_submenu(\'' . $sub_menu_id . '\', \'' . $menu_id . '\');"'; $html .= ' onmouseout="timeout_submenu(\'' . $sub_menu_id . '\');"'; } $html .= '>' . $this->label . '</a>'; if (!empty($this->submenus)) { $html .= '<div id="' . $sub_menu_id . '" class="' . $this->submenuclass . '"'; $html .= ' style="position: absolute; visibility: hidden; z-index: 100; text-align: ' . (I18N::direction() === 'ltr' ? 'left' : 'right') . '"'; $html .= ' onmouseover="show_submenu(\'' . $this->parentmenu . '\'); show_submenu(\'' . $sub_menu_id . '\');"'; $html .= ' onmouseout="timeout_submenu(\'' . $sub_menu_id . '\');">'; foreach ($this->submenus as $submenu) { $submenu->parentmenu = $sub_menu_id; $html .= $submenu->getMenu(); } $html .= '</div>'; } return '<div id="' . $menu_id . '" class="' . $this->menuclass . '">' . $html . '</div>'; } /** * Render this menu as an HTML list * * @return string */ public function getMenuAsList() { $attrs = ''; foreach ($this->attrs as $key => $value) { $attrs .= ' ' . $key . '="' . Filter::escapeHtml($value) . '"'; } if ($this->link) { $link = ' href="' . $this->link . '"'; } else { $link = ''; } $html = '<a' . $link . $attrs . '>' . $this->label . '</a>'; if ($this->submenus) { $html .= '<ul>'; foreach ($this->submenus as $submenu) { $html .= $submenu->getMenuAsList(); } $html .= '</ul>'; } return '<li class="' . $this->class . '">' . $html . '</li>'; } /** * Get the sub-menus. * * @return Menu[] */ public function getSubmenus() { return $this->submenus; } /** * Set the sub-menus. * * @param Menu[] $submenus * * @return $this */ public function setSubmenus(array $submenus) { $this->submenus = $submenus; return $this; } }