Вход Регистрация
Файл: DESURE-dcms-f12de01ac63e/sys/plugins/classes/menu.class.php
Строк: 171
<?php

class menu
{
    protected
        
$_require_keys = array(
        
'id',
        
'id_parent',
        
'position',
        
'title',
        
'url'
    
);
    protected
        
$_menu_key,
        
$_items,
        
$_last_item_id 0;

    function 
__construct($key_or_items null)
    {
        if (
is_array($key_or_items)) {
            
$this->_items $this->_parseItems($key_or_items);
            
$this->_menu_key $this->_parseKeyFromItems($this->_items);
        } elseif (
is_scalar($key_or_items)) {
            
$items $this->_getItemsFromBase($key_or_items);
            
$this->_items $this->_parseItems($items);
            
$this->_menu_key $key_or_items;
        } else {
            
$this->_items = array();
            
$this->_menu_key null;
        }
    }

    private function 
_parseItems($its)
    {
        
$items = array();
        foreach (
$its as $item) {
            foreach (
$this->_require_keys as $require_key) {
                if (!
array_key_exists($require_key$item)) {
                    throw new 
Exception(__('У элемента отсутствует параметр %s'$require_key));
                }
            }

            if (!
is_numeric($item['id'])) {
                throw new 
Exception(__('Параметр %s должен быть %s''id''integer'));
            }

            
$items[] = $item;
            
$this->_last_item_id max($this->_last_item_id$item['id']);
        }
        return 
$items;
    }

    private function 
_parseKeyFromItems($items)
    {
        foreach (
$items AS $item) {
            if (
array_key_exists('menu_key'$item)) {
                return 
$item['menu_key'];
            }
        }
        return 
null;
    }

    private function 
_getItemsFromBase($menu_key)
    {
        
$db db::me();
        
$res $db->prepare("SELECT * FROM `menu` WHERE `menu_key` = :menu_key");
        
$res->execute(array(':menu_key' => $menu_key));
        return 
$res->fetchAll();
    }

    private function 
_setItemId($old_id$now_id)
    {
        foreach (
$this->_items AS $index => $item) {
            if (
$item['id'] === $old_id) {
                
$this->_items[$index]['id'] = $now_id;
            }
            if (
$item['id_parent'] === $old_id) {
                
$this->_items[$index]['id_parent'] = $now_id;
            }
        }
    }

    private function 
_saveByParent($id_parent null$level 0)
    {
        if (
$level 10) {
            throw new 
Exception(__("Слишком большая вложенность меню"));
        }

        
$items $this->getItems($id_parent);
        
$db db::me();
        
$res $db->prepare("INSERT INTO `menu` (`menu_key`, `id_parent`, `position`, `title`, `url`, `data`) VALUES (:menu_key, :id_parent, :position, :title, :url, :dt)");
        
$position 0;
        foreach (
$items AS $item) {
            
$res->execute(array(
                
':menu_key' => $this->_menu_key,
                
':id_parent' => $id_parent,
                
':position' => ++$position,
                
':title' => $item['title'],
                
':url' => $item['url'],
                
':dt' => array_key_exists('data'$item) ? $item['data'] : null
            
));
            
$id $db->lastInsertId();
            
$this->_setItemId($item['id'], $id);
            
$this->setItemPosition($id$position);
            
$this->_saveByParent($id$level 1);
        }
    }

    
/**
     * @return null|string
     */
    
public function getMenuKey()
    {
        return 
$this->_menu_key;
    }

    private function 
_position_cmp($item1$item2)
    {
        
$a $item1['position'];
        
$b $item2['position'];

        switch (
true) {
            case 
$a == $b:
                return 
0;
            case 
$a $b:
                return 
1;
            case 
$a $b:
                return -
1;
        }
    }

    
/**
     * Сохранение меню в базе
     * @param string $key Ключ меню (можно не указывать, если меню инициализировано по ключу)
     * @throws Exception
     */
    
public function save($key null)
    {
        if (!
$key && !$this->_menu_key) {
            throw new 
Exception(__('Ключ меню не задан'));
        }

        if (
$this->_menu_key) {
            
$db db::me();
            
$res $db->prepare("DELETE FROM `menu` WHERE `menu_key` = :menu_key");
            
$res->execute(array(':menu_key' => $this->_menu_key));
        }

        if (
$key && is_scalar($key)) {
            
$this->_menu_key $key;
        }
        
$this->_saveByParent(null); // рекурсивное сохранение от корня
    
}

    
/**
     * Добавление пункта меню
     * @param string $url Ссылка
     * @param string $title Заголовок
     * @param int $position Позиция на уровне
     * @param int|null $id_parent Родитель (null-корень)
     * @return int Идентификатор нового пункта
     * @throws Exception
     */
    
public function addItem($title$url$position 0$id_parent null)
    {
        if (!
is_null($id_parent) && !$this->getItemById($id_parent)) {
            throw new 
Exception(__("Родитель с id %s не найден"$id_parent));
        }

        
$id = ++$this->_last_item_id;
        
$this->_items[] = array(
            
'id' => $id,
            
'menu_key' => $this->_menu_key,
            
'id_parent' => $id_parent,
            
'position' => $position,
            
'title' => $title,
            
'url' => $url
        
);
        return 
$id;
    }

    
/**
     * Установка позиции пункта меню
     * @param int $id Идентификатор
     * @param int $position позиция на уровне
     */
    
public function setItemPosition($id$position)
    {
        foreach (
$this->_items AS $key => $item) {
            if (
$item['id'] === $id) {
                
$this->_items[$key]['position'] = $position;
            }
        }
    }

    
/**
     * Удаление пункта меню со всеми дочерними пунктами
     * @param int $id
     */
    
public function removeItemById($id)
    {
        
$child_items $this->getItems($id);
        foreach (
$child_items as $item) {
            
$this->removeItemById($item['id']);
        }
        foreach (
$this->_items as $key => $item) {
            if (
$item['id'] === $id) {
                unset(
$this->_items[$key]);
            }
        }
        
$this->_items array_values($this->_items); // сбрасываем ключи элементов.
    
}

    
/**
     * Получение пункта меню по его идентификатору
     * @param int $id Идентификатор
     * @return array|null
     */
    
public function getItemById($id)
    {
        foreach (
$this->_items as $item) {
            if (
$item['id'] === $id) {
                return 
$item;
            }
        }
        return 
null;
    }

    
/**
     * Получение списка пунктов меню
     * @param int|null $id_parent Родитель (null - корневые элементы)
     * @param bool $recursive Рекурсивное получение всех дочерних пунктов меню
     * @return array
     */
    
public function getItems($id_parent null$recursive false)
    {
        
$items = array();
        foreach (
$this->_items AS $item) {
            if (
$item['id_parent'] === $id_parent) {
                
$it $item;
                if (
$recursive) {
                    
$it['items'] = $this->getItems($it['id'], true);
                }
                
$items[] = $it;
            }
        }
        
usort($items, array($this'_position_cmp'));
        return 
$items;
    }
}
Онлайн: 1
Реклама