You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
333 lines
7.4 KiB
333 lines
7.4 KiB
<?php declare(strict_types = 0);
|
|
/*
|
|
** Zabbix
|
|
** Copyright (C) 2001-2023 Zabbix SIA
|
|
**
|
|
** 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 2 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, write to the Free Software
|
|
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
**/
|
|
|
|
|
|
class CMenuItem extends CTag {
|
|
|
|
/**
|
|
* @var string
|
|
*/
|
|
private $action;
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
private $aliases = [];
|
|
|
|
/**
|
|
* @var string
|
|
*/
|
|
private $icon_class;
|
|
|
|
/**
|
|
* @var string
|
|
*/
|
|
private $label;
|
|
|
|
/**
|
|
* @var CMenu
|
|
*/
|
|
private $sub_menu;
|
|
|
|
/**
|
|
* @var string
|
|
*/
|
|
private $title;
|
|
|
|
/**
|
|
* @var string
|
|
*/
|
|
private $target;
|
|
|
|
/**
|
|
* @var CUrl
|
|
*/
|
|
private $url;
|
|
|
|
/**
|
|
* @var bool
|
|
*/
|
|
private $is_selected = false;
|
|
|
|
/**
|
|
* Create menu item.
|
|
*
|
|
* @param string $label Menu item visual label.
|
|
*/
|
|
public function __construct(string $label) {
|
|
parent::__construct('li', true);
|
|
|
|
$this->label = $label;
|
|
}
|
|
|
|
/**
|
|
* Get action name.
|
|
*
|
|
* @return string|null
|
|
*/
|
|
public function getAction(): ?string {
|
|
return $this->action;
|
|
}
|
|
|
|
/**
|
|
* Set action name and derive a corresponding URL for menu item link.
|
|
*
|
|
* @param string $action_name Action name.
|
|
*
|
|
* @return CMenuItem
|
|
*/
|
|
public function setAction(string $action_name): self {
|
|
return $this->setUrl((new CUrl('zabbix.php'))->setArgument('action', $action_name), $action_name);
|
|
}
|
|
|
|
/**
|
|
* Get action name aliases.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getAliases(): array {
|
|
return $this->aliases;
|
|
}
|
|
|
|
/**
|
|
* Set action name aliases.
|
|
*
|
|
* @param array $aliases The aliases of menu item. Is able to specify the alias in following formats:
|
|
* - {action_name} - The alias is applicable to page with specified action name with any GET
|
|
* parameters in URL or without them;
|
|
* - {action_name}?{param}={value} - The alias is applicable to page with specified action
|
|
* when specified GET parameter exists in URL and have the same value;
|
|
* - {action_name}?{param}=* - The alias is applicable to page with specified action
|
|
* when specified GET parameter exists in URL and have any value;
|
|
* - {action_name}?!{param}={value} - The alias is applicable to page with specified action
|
|
* when specified GET parameter not exists in URL or have different value;
|
|
* - {action_name}?!{param}=* - The alias is applicable to page with specified action
|
|
* when specified GET parameter not exists in URL.
|
|
*
|
|
* @return CMenuItem
|
|
*/
|
|
public function setAliases(array $aliases): self {
|
|
foreach ($aliases as $alias) {
|
|
['path' => $action_name, 'query' => $query_string] = parse_url($alias) + ['query' => ''];
|
|
parse_str($query_string, $query_params);
|
|
$this->aliases[$action_name][] = $query_params;
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Set icon CSS class for menu item link.
|
|
*
|
|
* @param string $icon_class
|
|
*
|
|
* @return CMenuItem
|
|
*/
|
|
public function setIcon(string $icon_class): self {
|
|
$this->icon_class = $icon_class;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Get visual label of menu item.
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getLabel(): string {
|
|
return $this->label;
|
|
}
|
|
|
|
/**
|
|
* Check if menu item is marked as selected.
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function isSelected(): bool {
|
|
return $this->is_selected;
|
|
}
|
|
|
|
/**
|
|
* Mark menu item as selected.
|
|
*
|
|
* @return CMenuItem
|
|
*/
|
|
public function setSelected(): self {
|
|
$this->is_selected = true;
|
|
$this->addClass('is-selected');
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Deep find menu item (including this one) by action name and mark the whole chain as selected.
|
|
*
|
|
* @param string $action_name Action name to search for.
|
|
* @param array $request_params Parameters of current HTTP request to compare in search process.
|
|
* @param bool $expand Add 'is-expanded' class for selected submenus.
|
|
*
|
|
* @return bool True, if menu item was selected.
|
|
*/
|
|
public function setSelectedByAction(string $action_name, array $request_params, bool $expand = false): bool {
|
|
if (array_key_exists($action_name, $this->aliases)) {
|
|
foreach ($this->aliases[$action_name] as $alias_params) {
|
|
$has_mandatory_params = true;
|
|
|
|
foreach ($alias_params as $name => $value) {
|
|
if (!array_key_exists($name, $request_params)
|
|
|| ($value !== '*' && $value !== $request_params[$name])) {
|
|
$has_mandatory_params = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ($has_mandatory_params) {
|
|
$this->setSelected();
|
|
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($this->sub_menu !== null && $this->sub_menu->setSelectedByAction($action_name, $request_params, $expand)) {
|
|
$this->setSelected();
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Get submenu of menu item or create new one, if not exists.
|
|
*
|
|
* @return CMenu
|
|
*/
|
|
public function getSubMenu(): CMenu {
|
|
if ($this->sub_menu === null) {
|
|
$this->setSubMenu(new CMenu());
|
|
}
|
|
|
|
return $this->sub_menu;
|
|
}
|
|
|
|
/**
|
|
* Set submenu for menu item.
|
|
*
|
|
* @param CMenu $sub_menu
|
|
*
|
|
* @return CMenuItem
|
|
*/
|
|
public function setSubMenu(CMenu $sub_menu): self {
|
|
$this->sub_menu = $sub_menu->addClass('submenu');
|
|
$this->addClass('has-submenu');
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Check if menu item has submenu.
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function hasSubMenu(): bool {
|
|
return ($this->sub_menu !== null);
|
|
}
|
|
|
|
/**
|
|
* Set target attribute for the menu item link.
|
|
*
|
|
* @param string $target
|
|
*
|
|
* @return CMenuItem
|
|
*/
|
|
public function setTarget(string $target): self {
|
|
$this->target = $target;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Set title attribute for the menu item link.
|
|
*
|
|
* @param string $title
|
|
*
|
|
* @return CMenuItem
|
|
*/
|
|
public function setTitle($title): self {
|
|
$this->title = $title;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Get url of the menu item link.
|
|
*
|
|
* @return CUrl|null
|
|
*/
|
|
public function getUrl(): ?CUrl {
|
|
return $this->url;
|
|
}
|
|
|
|
/**
|
|
* Set url for the menu item link.
|
|
*
|
|
* @param CUrl $url
|
|
* @param string|null $action_name Associate action name to be matched by setSelected method.
|
|
*
|
|
* @return CMenuItem
|
|
*/
|
|
public function setUrl(CUrl $url, string $action_name = null): self {
|
|
$action = null;
|
|
|
|
if ($action_name !== null) {
|
|
$this->setAliases([$action_name]);
|
|
['path' => $action] = parse_url($action_name);
|
|
}
|
|
|
|
$this->url = $url;
|
|
$this->action = $action;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function toString($destroy = true)
|
|
{
|
|
if ($this->url !== null || $this->sub_menu !== null) {
|
|
$this->addItem([
|
|
(new CLink($this->label, $this->sub_menu !== null ? '#' : $this->url->getUrl()))
|
|
->addClass($this->icon_class)
|
|
->setTitle($this->title)
|
|
->setTarget($this->target),
|
|
$this->sub_menu
|
|
]);
|
|
}
|
|
else {
|
|
$this->addItem(
|
|
(new CSpan($this->label))
|
|
->addClass($this->icon_class)
|
|
->setTitle($this->title)
|
|
);
|
|
}
|
|
|
|
return parent::toString($destroy);
|
|
}
|
|
}
|