nur-sery/nur_src/v/base/MenuManager.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,
];
}
}