1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312
<?php
/**
***********************************************************************************************
* @copyright 2004-2016 The Admidio Team
* @see http://www.admidio.org/
* @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License v2.0 only
***********************************************************************************************
*/
/**
* @class HtmlNavbar
* @brief Class manages display of navbar in modules
*
* This class manage the presentation of a module menu. You can add as many
* items to the menu and the class tries to display them in the perfect
* way for the module. If there are to many items to display all than it
* will create a menu button where you can find all the other menu items.
* The position of the items is important. Only the first items will display
* permanently in the module. The other items are summarized in a submenu.
* @par Examples
* @code // create module menu
* $myNavbar = new HtmlNavbar('menu_my_module', 'My module');
*
* // show link to create new announcement
* $myNavbar->addItem('menu_item_new_entry', $g_root_path.'/adm_program/modules/mymodule/mymodule_new.php',
* $gL10n->get('SYS_CREATE'), 'add.png');
* $myNavbar->show(); @endcode
*/
class HtmlNavbar
{
protected $leftItems; ///< An array with all items that should be displayed at the left part of the navbar
protected $rightItems; ///< An array with all items that should be displayed at the right part of the navbar
protected $htmlPage; ///< A HtmlPage object that will be used to add javascript code or files to the html output page.
protected $htmlForm; ///< Parameter that includes the html of the form that should be shown within the navbar
protected $name; ///< Name of the navbar that will be shown when navbar changed to vertical mode on small devices
protected $type; ///< Navbar type. There is the @b default and the @b filter type possible.
protected $id; ///< The id of the navbar.
protected $customCssClass; ///< A css class name that should be added to the main nav tag of the navbar
/**
* creates the object of the module menu and initialize all class parameters
* @param string $id Html id of the navbar
* @param string $name Name of the navbar that will be shown when navbar changed to vertical mode on small devices
* @param \HtmlPage $htmlPage Optional a HtmlPage object that will be used to add javascript code
* or files to the html output page.
* @param string $type Different types of the navbar can be defined.
* default: will be the standard navbar of all modules.
* filter: should be used if this navbar is used to filter data of within the script.
*/
public function __construct($id, $name = null, HtmlPage $htmlPage = null, $type = 'default')
{
global $gL10n;
if ($name === null)
{
if ($type === 'default')
{
$name = $gL10n->get('SYS_MENU');
}
elseif ($type === 'filter')
{
$name = $gL10n->get('SYS_FILTER');
}
}
if (is_object($htmlPage))
{
$this->htmlPage =& $htmlPage;
}
$this->leftItems = array();
$this->rightItems = array();
$this->htmlForm = '';
$this->name = $name;
$this->type = $type;
$this->id = $id;
$this->customCssClass = '';
}
/**
* Creates the html for the menu entry.
* @param string[] $data An array with all data if the item. This will be @id, @url, @text and @icon.
* @return string Returns the html for the menu entry
*/
protected function createHtmlLink(array $data)
{
$icon = '';
if ($data['icon'] !== '')
{
$icon = '<img src="' . $data['icon'] . '" alt="' . strip_tags($data['text']) . '" />';
}
$html = '
<li class="' . $data['class'] . '">
<a class="navbar-link" id="' . $data['id'] . '" href="' . $data['url'] . '">' . $icon . $data['text'] . '</a>
</li>';
return $html;
}
/**
* This method adds an additional css class to the main nav tag of the menu.
* @param string $className The name of a css class that should be add to the main nav tag of the manu
*/
public function addCssClass($className)
{
$this->customCssClass = ' '.$className;
}
/**
* Add a form to the menu. The form will be added between the left and the right part of the navbar.
* @param string $htmlForm A html code of a form that will be added to the menu
*/
public function addForm($htmlForm)
{
$this->htmlForm = $htmlForm;
}
/**
* Add a new item to the menu. This can be added to the left or right part of the navbar.
* You can also add another item to an existing dropdown item. Therefore use the @b $parentItem parameter.
* @param string $id Html id of the item.
* @param string $url The url of the generated link of this item.
* @param string $text The text of the item and the generated link.
* @param string $icon Icon of the menu item, that will also be linked
* @param string $orientation The item can be shown at the @b left or @b right part of the navbar.
* @param string $parentItem All items should be added to the @b navbar as parent. But if you
* have already added a dropdown than you can add the item to that
* dropdown. Just commit the id of that item.
* @param string $class Optional a css class that will be set for the item.
*/
public function addItem($id, $url, $text, $icon, $orientation = 'left', $parentItem = 'navbar', $class = '')
{
global $g_root_path;
$urlStartRegex = '/^(http(s?):)?\/\//';
// add root path to link unless the full URL is given
if ($url !== '' && $url !== '#' && preg_match($urlStartRegex, $url) === 0)
{
$url = $g_root_path . $url;
}
// add THEME_PATH to images unless the full URL is given
if ($icon !== '' && preg_match($urlStartRegex, $icon) === 0)
{
$icon = THEME_PATH . '/icons/' . $icon;
}
$item = array('id' => $id, 'text' => $text, 'icon' => $icon, 'url' => $url, 'class' => $class);
if ($orientation === 'left')
{
if ($parentItem === 'navbar')
{
$this->leftItems[$id] = $item;
}
elseif (array_key_exists($parentItem, $this->leftItems))
{
$this->leftItems[$parentItem]['items'][$id] = $item;
}
}
elseif ($orientation === 'right')
{
if ($parentItem === 'navbar')
{
$this->rightItems[$id] = $item;
}
elseif (array_key_exists($parentItem, $this->rightItems))
{
$this->rightItems[$parentItem]['items'][$id] = $item;
}
}
}
/**
* Set the name of the navbar that will be shown when navbar changed to vertical mode on small devices.
* @param string $name New name of the navbar.
*/
public function setName($name)
{
$this->name = $name;
}
/**
* @param array[] $items
* @param string $class
* @return string
*/
private function getNavHtml($items, $class = '')
{
$html = '<ul class="nav navbar-nav ' . $class . '">';
foreach($items as $key => $menuEntry)
{
if (array_key_exists('items', $menuEntry) && is_array($menuEntry['items']))
{
if (count($menuEntry['items']) === 1)
{
// only one entry then add a simple link to the navbar
$html .= $this->createHtmlLink(current($menuEntry['items']));
}
else
{
// add a dropdown to the navbar
$html .= '
<li class="dropdown ' . $menuEntry['class'] . '">
<a id="' . $menuEntry['id'] . '" href="#" class="dropdown-toggle" data-toggle="dropdown">
<span class="glyphicon glyphicon-menu-hamburger"></span>' . $menuEntry['text'] . '<span class="caret"></span>
</a>
<ul class="dropdown-menu" role="menu">';
foreach ($menuEntry['items'] as $keyDropDown => $menuEntryDropDown)
{
$html .= $this->createHtmlLink($menuEntryDropDown);
}
$html .= '</ul></li>';
}
}
else
{
// add a simple link to the navbar
$html .= $this->createHtmlLink($menuEntry);
}
}
$html .= '</ul>';
return $html;
}
/**
* Creates the html output of the module menu. Each added menu item will be displayed.
* If one item has several subitems than a dropdown button will be created.
* @return string Returns the html output for the complete menu
*/
public function show()
{
$showNavbar = false;
$navHtml = '';
// add left item block to navbar
if (count($this->leftItems) > 0)
{
$showNavbar = true;
$navHtml .= $this->getNavHtml($this->leftItems, 'navbar-left');
}
// add form to navbar
if ($this->htmlForm !== '')
{
$showNavbar = true;
$navHtml .= $this->htmlForm;
}
// add right item block to navbar
if (count($this->rightItems) > 0)
{
$showNavbar = true;
$navHtml .= $this->getNavHtml($this->rightItems, 'navbar-right');
}
if (!$showNavbar)
{
// dont show navbar if no menu item or form was added
return '';
}
// if navbar will be shown then set this flag in page object
if (is_object($this->htmlPage))
{
$this->htmlPage->hasNavbar();
}
$cssClassBrand = '';
$cssClassNavbar = '';
// default navbar should not show the brand, only in xs mode
if ($this->type === 'default')
{
$cssClassBrand = 'visible-xs-block';
}
elseif ($this->type === 'filter')
{
$cssClassNavbar = 'navbar-filter';
}
// add html for navbar
$html = '
<nav class="navbar navbar-default ' . $cssClassNavbar . $this->customCssClass . '" role="navigation">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#' . $this->id . '">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand ' . $cssClassBrand . '" href="#">' . $this->name . '</a>
</div>
<div class="collapse navbar-collapse" id="' . $this->id . '">';
$html .= $navHtml;
$html .= '</div></div></nav>';
// now show the complete html of the menu
return $html;
}
}