138 lines
3.6 KiB
PHP
138 lines
3.6 KiB
PHP
|
<?php
|
||
|
namespace nur\v\base;
|
||
|
|
||
|
use nur\A;
|
||
|
use nur\authz;
|
||
|
use nur\md;
|
||
|
use nur\v\model\IMenuManager;
|
||
|
|
||
|
class MenuManager implements IMenuManager {
|
||
|
function __construct($menu=null, ?string $selectedId=null) {
|
||
|
$this->init($menu, $selectedId);
|
||
|
}
|
||
|
|
||
|
/** @var array */
|
||
|
private $menu;
|
||
|
|
||
|
/** @var string */
|
||
|
private $selectedId;
|
||
|
|
||
|
/** @var bool */
|
||
|
private $built;
|
||
|
|
||
|
/** @var string */
|
||
|
private $brand;
|
||
|
|
||
|
/** @var array */
|
||
|
private $navbarItems;
|
||
|
|
||
|
function init($menu, ?string $selectedId): void {
|
||
|
$this->menu = null;
|
||
|
$this->selectedId = null;
|
||
|
$this->built = false;
|
||
|
$this->brand = null;
|
||
|
$this->navbarItems = null;
|
||
|
if ($menu !== null) {
|
||
|
md::ensure_schema($menu, self::MENU_SCHEMA, null, false);
|
||
|
$this->menu = $menu;
|
||
|
$this->selectedId = $selectedId;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private function build($id, array $item, string $menuType="menu"): ?array {
|
||
|
md::ensure_schema($item, self::ITEM_SCHEMA);
|
||
|
A::replace_n($item, "id", $id);
|
||
|
A::replace_n_indirect($item, "id", "url");
|
||
|
|
||
|
$perms = $item["perm"];
|
||
|
$roles = $item["role"];
|
||
|
if ($perms !== null || $roles !== null) {
|
||
|
$user = authz::get();
|
||
|
if ($perms !== null && !$user->isPerm($perms)) return null;
|
||
|
if ($roles !== null && !$user->isRole($roles)) return null;
|
||
|
}
|
||
|
|
||
|
$id = $item["id"];
|
||
|
$text = $item["text"];
|
||
|
$accesskey = $item["accesskey"];
|
||
|
$target = $item["target"];
|
||
|
$active = $id === $this->selectedId;
|
||
|
|
||
|
$startOfMenu = false;
|
||
|
$setNavbarItems = false;
|
||
|
$subItems = $item["items"];
|
||
|
$navbarItems = null;
|
||
|
if ($subItems) {
|
||
|
$index = 0;
|
||
|
foreach ($subItems as $subId => $subItem) {
|
||
|
if ($subId === $index) {
|
||
|
$subId = null;
|
||
|
$index++;
|
||
|
}
|
||
|
$navbarItem = $this->build($subId, $subItem, "link");
|
||
|
if ($navbarItem === null) continue;
|
||
|
if (!$active && $navbarItem["active"]) {
|
||
|
$active = true;
|
||
|
$startOfMenu = true;
|
||
|
}
|
||
|
if ($navbarItem["som"]) $setNavbarItems = true;
|
||
|
A::append($navbarItems, $navbarItem);
|
||
|
}
|
||
|
}
|
||
|
$itemType = $navbarItems ? $menuType : "link";
|
||
|
if ($setNavbarItems) $this->navbarItems = $navbarItems;
|
||
|
|
||
|
$url = $item["url"];
|
||
|
if ($itemType == "link" && $url === null) {
|
||
|
$class = is_array($text) && count($text) == 1? $text[0]: $text;
|
||
|
if (class_exists($class)) {
|
||
|
$url = $class;
|
||
|
$text = $class::TITLE;
|
||
|
} else if ($navbarItems) {
|
||
|
$url = $navbarItems[0]["url"];
|
||
|
}
|
||
|
}
|
||
|
A::merge($tmpText, $item["prefix"], $text, $item["suffix"]);
|
||
|
$text = $tmpText;
|
||
|
$params = $item["params"];
|
||
|
|
||
|
return [
|
||
|
"item" => $itemType,
|
||
|
"text" => $text,
|
||
|
"url" => $url,
|
||
|
"params" => $params,
|
||
|
"active" => $active,
|
||
|
"show_active" => $item["show_active"],
|
||
|
"links" => $navbarItems,
|
||
|
"accesskey" => $accesskey,
|
||
|
"target" => $target,
|
||
|
"som" => $startOfMenu,
|
||
|
];
|
||
|
}
|
||
|
|
||
|
function get(): array {
|
||
|
if (!$this->built) {
|
||
|
$this->brand = $this->menu["brand"];
|
||
|
$this->navbarItems = $navbarItems = null;
|
||
|
$index = 0;
|
||
|
$items = $this->menu["items"];
|
||
|
if ($items !== null) {
|
||
|
foreach ($items as $id => $item) {
|
||
|
if ($id === $index) {
|
||
|
$id = null;
|
||
|
$index++;
|
||
|
}
|
||
|
$navbarItem = $this->build($id, $item);
|
||
|
if ($navbarItem !== null) $navbarItems[] = $navbarItem;
|
||
|
}
|
||
|
}
|
||
|
if ($this->navbarItems === null) $this->navbarItems = $navbarItems;
|
||
|
$this->built = true;
|
||
|
}
|
||
|
return [
|
||
|
"brand" => $this->brand,
|
||
|
"navbar_items" => $this->navbarItems,
|
||
|
];
|
||
|
}
|
||
|
}
|