<?php
/**
* 管理菜单
*
*/
class App_Helper_Admin_Menu {
const quuid = 'q';
const qargs = 'args';
const qtitle = 'title';
const qtype = 'type';
const qparent = 'parent';
/**
* 扩展选项,如 style class 等等
*/
const qoptions = 'options';
const qchildren = 'children';
const qactive = 'active';
/**
* 顶级菜单标识
*/
const qparent_top = '#ROOT#';
/**
* 茎节点
*/
const qtype_stem = 'stem';
/**
* 叶节点
*/
const qtype_leaf = 'leaf';
private function __construct(){
$this->init();
}
/**
* @return App_Helper_Admin_Menu
*/
static function getInstance(){
static $it = false;
if (!$it){
$it = new self();
}
return $it;
}
/**
* 返回生成的 菜单
*
* @return array
*/
private function init(){
$qid = Core_AppUtils::get(Core_Mvc_Router::queryAccessor);
$active = false;
$catalog = $this->aclFilter($this->loadData());
do {
$item = Core_AppUtils::val($catalog,$qid,null);
if (empty($item)) break;
$active = $catalog[$qid][self::qactive] = true;
if (self::qparent_top == $item[self::qparent]) break;
$qid = $item[self::qparent];
} while(true);
// 转成树
$catalog = (array) Core_AppUtils::array_to_tree($catalog,self::quuid,self::qparent,self::qchildren);
// 节点过滤,规范 茎叶类型
$catalog = $this->nodeFilter($catalog);
$this->activeItems = array();
$this->catalog = $this->locateActiveItem($catalog);
}
/**
* 返回激活的菜单项数组
*
* @return array
*/
function getActiveItems(){
return $this->activeItems;
}
/**
* 返回生成的菜单数据
*
* @return array
*/
function getCatalog(){
return $this->catalog;
}
/**
* 生成菜单项
*
* @param string $quuid
* @param array $qargs
* @param string $qtitle
* @param string $qparent
* @param string $qtype
* @param array $qoptions
*
* @return array
*/
static function createItem($quuid ,$qargs ,$qtitle ,$qparent ,$qtype ,$qoptions=null){
$d = array(
self::quuid => $quuid,
self::qargs => $qargs,
self::qtitle => $qtitle,
self::qparent => $qparent,
self::qtype => $qtype,
);
if (!empty($qoptions)) $d[self::qoptions] = (array) $qoptions;
return $d;
}
private function loadData(){
$catalog = (array) Core_Autoloader::loadFile(APPPATH . '/config/adminmenu.php',false);
return Core_AppUtils::array_to_hashmap($catalog,self::quuid) ;
}
private function addActiveItem(array $item){
if (self::qtype_stem == $item[self::qtype]){
unset($item[self::qchildren]);
}
$this->activeItems[] = $item;
}
private function locateActiveItem(array $items){
$activeItem = null;
foreach ($items as $offset => $item){
if (Core_AppUtils::val($item,self::qactive,false)){
$activeItem = & $items[$offset];
break;
}
}
if (empty($activeItem)) {
$activeItem = & $items[0];
$activeItem[self::qactive] = true;
}
$this->addActiveItem($activeItem);
if (self::qtype_stem == $activeItem[self::qtype]){
$activeItem[self::qchildren] = $this->locateActiveItem($activeItem[self::qchildren]);
}
return $items;
}
private function nodeFilter(array $items){
if (empty($items)) return $items;
$data = array();
foreach ($items as $item){
switch ($item[self::qtype]) {
case self::qtype_leaf:
unset($item[self::qchildren]);
break;
case self::qtype_stem:
if (empty($item[self::qchildren])){
$item[self::qtype] = self::qtype_leaf;
unset($item[self::qchildren]);
}else {
$item[self::qchildren] = $this->nodeFilter($item[self::qchildren]);
}
break;
default:
$item = null;
}
if (!empty($items)) $data[] = $item;
}
return $data;
}
private function aclFilter(array $items){
if (empty($items)) return $items;
if (Core_Event::isRegistered(Core_Mvc_EventId::dispatching_aclcheck)){
$data = array();
foreach ($items as $uuid => $item){
if (App_Convention::canAccess($uuid) ){
$data[$uuid] = $item;
}
}
return $data;
}
return $items;
}
}
?