HEX
Server: Apache/2.4.6 (CentOS) mpm-itk/2.4.7-04 mod_fcgid/2.3.9 PHP/5.4.16
System: Linux dvm.vladweb.ru 3.10.0-1160.119.1.el7.x86_64 #1 SMP Tue Jun 4 14:43:51 UTC 2024 x86_64
User: region-gk.ru (1016)
PHP: 7.3.33
Disabled: NONE
Upload Files
File: //home/temp/yarusvl.ru/api/Menu.php
<?php

require_once('Mgc.php');
define("MENU_VAR_PREFIX", "menu_");

class Menu extends Mgc {

    // Список указателей на элементы меню в дереве элементов меню (ключ = id элемента меню)
    private $all_menu_items;
    // Дерево элементов меню
    private $menu_items_tree;

    private function init_menu_items() {
        $menu_items = $this->menu_items_tree = $this->all_menu_items = array();
        $lang_sql = $this->languages->get_query(array('object'=>'menu_item', 'px'=>'it'));
        // Выбираем все элементы меню
        $query = $this->db->placehold("SELECT 
                it.id,
                it.menu_id,
                it.parent_id,
                it.url,
                it.is_target_blank,
                it.visible,
                it.position,
                $lang_sql->fields
            FROM __menu_items it
            $lang_sql->join
            ORDER BY it.parent_id, it.position
        ");
        $this->db->query($query);
        foreach ($this->db->results() as $item) {
            if (!isset($menu_items[$item->menu_id]))  {
                $menu_items[$item->menu_id] = array();
            }
            $menu_items[$item->menu_id][] = $item;
        }

        foreach ($menu_items as $menu_id => $items) {
            // Дерево элементов меню
            $tree = new stdClass();
            $tree->submenus = array();

            // Указатели на узлы дерева
            $pointers = array();
            $pointers[0] = &$tree;
            $pointers[0]->path = array();
            $pointers[0]->level = 0;

            $finish = false;
            // Не кончаем, пока не кончатся элементы, или пока ниодну из оставшихся некуда приткнуть
            while (!empty($items) && !$finish) {
                $flag = false;
                // Проходим все выбранные элементы
                foreach ($items as $k => $item) {
                    if (isset($pointers[$item->parent_id])) {
                        // В дерево элементов меню (через указатель) добавляем текущий элемент
                        $pointers[$item->id] = $pointers[$item->parent_id]->submenus[] = $item;

                        // Путь к текущему элементу
                        $curr = $pointers[$item->id];
                        $pointers[$item->id]->path = array_merge((array)$pointers[$item->parent_id]->path, array($curr));

                        // Уровень вложенности элементов
                        $pointers[$item->id]->level = 1 + $pointers[$item->parent_id]->level;

                        // Убираем использованный элемент из массива
                        unset($items[$k]);
                        $flag = true;
                    }
                }
                if (!$flag) $finish = true;
            }

            // Для каждого элемента id всех его деток узнаем
            $ids = array_reverse(array_keys($pointers));
            foreach ($ids as $id) {
                if ($id > 0) {
                    $pointers[$id]->children[] = $id;

                    if (isset($pointers[$pointers[$id]->parent_id]->children)) {
                        $pointers[$pointers[$id]->parent_id]->children = array_merge($pointers[$id]->children, $pointers[$pointers[$id]->parent_id]->children);
                    } else {
                        $pointers[$pointers[$id]->parent_id]->children = $pointers[$id]->children;
                    }
                }
            }
            unset($pointers[0]);
            unset($ids);
            $this->menu_items_tree[$menu_id] = $tree->submenus;
            $this->all_menu_items = array_merge($this->all_menu_items, $pointers);
        }
    }

    public function get_menu_items_tree($menu_id = 0) {
        if (!isset($this->menu_items_tree)) {
            $this->init_menu_items();
        }
        if ($menu_id > 0) {
            if (!isset($this->menu_items_tree[$menu_id])) {
                return array();
            }
            return $this->menu_items_tree[$menu_id];
        }
        return $this->menu_items_tree;
    }

    public function get_menu_items() {
        if (!isset($this->menu_items_tree)) {
            $this->init_menu_items();
        }
        return $this->all_menu_items;
    }

    public function add_menu_item($menu_item) {
        $menu_item = (object)$menu_item;
        $result = $this->languages->get_description($menu_item, 'menu_item');

        $this->db->query("INSERT INTO __menu_items SET ?%", $menu_item);
        $id = $this->db->insert_id();
        $this->db->query("UPDATE __menu_items SET position=id WHERE id=?", $id);

        if(!empty($result->description)) {
            $this->languages->action_description($id, $result->description, 'menu_item');
        }

        unset($this->menu_items_tree);
        unset($this->all_menu_items);
        return $id;
    }

    public function update_menu_item($id, $menu_item) {
        $menu_item = (object)$menu_item;
        $result = $this->languages->get_description($menu_item, 'menu_item');

        $query = $this->db->placehold("UPDATE __menu_items SET ?% WHERE id=? LIMIT 1", $menu_item, (int)$id);
        $this->db->query($query);

        if(!empty($result->description)) {
            $this->languages->action_description($id, $result->description, 'menu_item', $this->languages->lang_id());
        }

        unset($this->menu_items_tree);
        unset($this->all_menu_items);
        return (int)$id;
    }

    public function delete_menu_item($id) {
        if(!empty($id)) {
            $id = (int)$id;
            $query = $this->db->placehold("DELETE FROM __menu_items WHERE id=? LIMIT 1", $id);
            if($this->db->query($query)) {
                $this->db->query("DELETE FROM __lang_menu_items where menu_item_id=?", $id);
                return true;
            }
        }
        return false;
    }

    /*Выбираем все меню*/
    public function get_menus($filter = array()) {
        $visible_filter = '';

        if(isset($filter['visible'])) {
            $visible_filter = $this->db->placehold('AND visible = ?', (int)$filter['visible']);
        }

        $query = "SELECT * FROM __menu WHERE 1 $visible_filter ORDER BY position";

        $this->db->query($query);
        $menus = $this->db->results();
        if (!empty($menus)) {
            foreach ($menus as $menu) {
                $menu->var = '{$'.MENU_VAR_PREFIX.$menu->group_id."}";
            }
        }
        return $menus;
    }

    /*Выбираем определенное меню*/
    public function get_menu($id, $visible = false) {
        if (empty($id)) {
            return false;
        }

        $is_visible = '';
        if($visible) {
            $is_visible = 'AND visible=1';
        }

        if(is_int($id)) {
            $menu_id_filter = $this->db->placehold('AND id=? ', $id);
        } else {
            $menu_id_filter = $this->db->placehold('AND group_id=? ', $id);
        }

        $query = $this->db->placehold("SELECT * FROM __menu WHERE 1 $menu_id_filter $is_visible LIMIT 1");
        $this->db->query($query);
        $menu = $this->db->result();
        if (!empty($menu)) {
            $menu->var = '{$'.MENU_VAR_PREFIX.$menu->group_id."}";
        }
        return $menu;
    }

    /*Обновляем меню*/
    public function update_menu($id, $menu) {
        $query = $this->db->placehold("UPDATE __menu SET ?% WHERE id in (?@) LIMIT ?", $menu, (array)$id, count((array)$id));
        if($this->db->query($query)) {
            return $id;
        } else {
            return false;
        }
    }

    /*Добавляем меню*/
    public function add_menu($menu) {
        $menu = (array) $menu;

        if($this->db->query("INSERT INTO __menu SET ?%", $menu)) {
            $id = $this->db->insert_id();
            $this->db->query("UPDATE __menu SET position=id WHERE id=?", $id);
            return $id;
        } else {
            return false;
        }
    }

    /*Удаляем меню*/
    public function delete_menu($id) {
        $id = (int)$id;
        if(!empty($id)) {
            $this->db->query("SELECT id FROM __menu_items where menu_id=?", $id);
            $menu_items_ids = $this->db->results('id');
            if (!empty($menu_items_ids)) {
                foreach ($menu_items_ids as $bi_id) {
                    $this->delete_menu_item($bi_id);
                }
            }

            $query = $this->db->placehold("DELETE FROM __menu WHERE id=? LIMIT 1", $id);
            if($this->db->query($query)) {
                return true;
            }
        }
        return false;
    }

}