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,
 | 
						|
    ];
 | 
						|
  }
 | 
						|
}
 |