<?php

$cms["modules"]["menu.mod.php"] = array(
    "name"        => "menu_module_name",
    "description" => "menu_module_description",
    "files"       => array(
        ".cms/mod/menu.mod.php",
        ".cms/css/menu.less",
        ".cms/css/menu.css",
        ".cms/js/menu.js",
        ".cms/lang/ru_RU.UTF-8/menu.mod.php",
        ".cms/lang/en_US.UTF-8/menu.mod.php",
        ".cms/lang/uk_UA.UTF-8/menu.mod.php",
        ".cms/man/ru_RU.UTF-8/menu.html",
    ),
);

// Return if module disabled
if ( ! empty( $cms["config"]["menu.mod.php"]["disabled"] ) ) {
    return;
}

if ( is_admin() ) {
    hook_add_fn( "create_tables", "cms_menu_create_table" );
    hook_add_fn( "admin",         "cms_menu_admin", 20 );
    hook_add_fn( "admin_header",  "cms_menu_admin_header" );
    hook_add_fn( "api",           "cms_menu_api", 20 );
    hook_add_fn( "mod_pages_page_saved", "cms_menu_page_saved" );
}

// Нужно ли обновить меню в админке
function cms_menu_page_saved( &$req ) {
    global $cms;
    try {
        $stmt = $cms["pdo"]->prepare( "SELECT * FROM menu WHERE page_id = ?" );
        $stmt->execute( array( $req["page_id"] ) );
        if ( $item = $stmt->fetch( PDO::FETCH_ASSOC ) ) {
            $req["update_menu"] = true;
        }
    } catch ( PDOException $e ) {
        error_log( $e->getMessage() );
    }
}

function cms_menu_admin_header() {
    global $cms;
    if ( is_admin_header_on( "menu.mod.php" ) ) {
        echo "        <link rel=stylesheet href='{$cms["base_path"]}css/menu.css'>\n";
        echo "        <script src='{$cms["base_path"]}js/menu.js'></script>\n";
    }
}

function cms_menu_resort( $parent_id ) {
    global $cms;
    $sort = 10;
    try {
        $stmt = $cms["pdo"]->prepare( "SELECT id FROM menu WHERE parent_id = ? ORDER BY sort" );
        $stmt->execute( array( $parent_id ) );
        
        while ( $item = $stmt->fetch( PDO::FETCH_ASSOC ) ) {
            $stmt_update = $cms["pdo"]->prepare( "UPDATE menu SET sort = ? WHERE id = ?" );
            $stmt_update->execute( array( $sort, $item["id"] ) );
            $sort += 10;
        }
    } catch ( PDOException $e ) {
        error_log( $e->getMessage() );
    }
}

function cms_menu_api() {
    global $cms;

    if ( empty( $cms["pdo"] ) ) {
        return;
    }
    
    if ( ! empty( $_POST["fn"] ) ) {
        
        switch ( $_POST["fn"] ) {

            case "create_menu_item":
                $parent_id = (int) $_POST["parent_id"];
                $sort      = (int) $_POST["sort"];

                // Сначала вставляем элемент с указанной сортировкой
                // потому что пункт может быть добавлен выше или ниже
                // и только потом пересортировываем
                try {
                    $stmt = $cms["pdo"]->prepare( "INSERT INTO menu (parent_id, url, sort) VALUES (?, '', ?)" );
                    $stmt->execute( array( $parent_id, $sort ) );
                    $id = $cms["pdo"]->lastInsertId();
                } catch ( PDOException $e ) {
                    error_log( $e->getMessage() );
                    break;
                }

                // Пересортировываем имеющиеся на том же уровне иерархии
                cms_menu_resort( $parent_id );

                echo( json_encode( array( 
                    "result" => array(
                        "list"       => cms_menu_get_items_list(),
                        "parents"    => cms_menu_get_parents_list2(),
                        "id"        => $id,
                    )
                ) ) );
            break;

            case "get_menu_items":
                echo( json_encode( array(
                    "result" => array(
                        "list"       => cms_menu_get_items_list(),
                        "parents"    => cms_menu_get_parents_list2(),
                    )
                ) ) );
            break;

            case "del_menu_item":
                if ( $id = (int) $_POST["id"] ) {
                    // Вынесено в функцию потому что рекурсивно удаляет
                    cms_menu_del( $id );
                    
                    if ( function_exists( "cms_clear_cache" ) ) {
                        cms_clear_cache();
                    }
                    
                    echo( json_encode( array( 
                        "result" => array(
                            "list"       => cms_menu_get_items_list(),
                            "parents"    => cms_menu_get_parents_list2(),
                        )
                    ) ) );
                }
            break;

            case "save_menu_item":
                try {
                    $stmt = $cms["pdo"]->prepare(
                        "UPDATE menu SET
                            parent_id = ?,
                            page_id = ?,
                            sort = ?,
                            title = ?,
                            tag_title = ?,
                            classes = ?,
                            url = ?,
                            area = ?,
                            target_blank = ?
                        WHERE id = ?"
                    );

                    if ( ! isset( $_POST["target_blank"] ) ) {
                        $target_blank = 0;
                    } else {
                        if ( "pgsql" === $cms["pdo"]->getAttribute( PDO::ATTR_DRIVER_NAME ) ) {
                            $target_blank = $_POST["target_blank"] === "true";
                        } else {
                            $target_blank = (int) ($_POST["target_blank"] === "true" );
                        }
                    }

                    // Убрать варнинги
                    if ( ! isset( $_POST["page_id"] ) ) { $_POST["page_id"] = 0; }
                    if ( ! isset( $_POST["tag_title"] ) ) { $_POST["tag_title"] = ""; }
                    if ( ! isset( $_POST["url"] ) ) { $_POST["url"] = ""; }
                    if ( ! isset( $_POST["area"] ) ) { $_POST["area"] = ""; }

                    $title   = (string) $_POST["title"];
                    $url     = trim( (string) $_POST["url"] );
                    $page_id = (int) $_POST["page_id"];
                    $params = array(
                        (int) $_POST["parent_id"],
                        $page_id,
                        (int) $_POST["sort"],
                        $title,
                        (string) $_POST["tag_title"],
                        (string) $_POST["classes"],
                        $url,
                        (string) $_POST["area"],
                        $target_blank,
                        (int) $_POST["id"]
                    );
                    $stmt->execute( $params );

                    if ( function_exists( "cms_clear_cache" ) ) {
                        cms_clear_cache();
                    }

                    if ( $page_id !== 0 ) {
                        if ( empty( $title ) ) {
                            $page = array( "page_id" => $page_id );
                            do_hook( "mod_menu_item", $page );
                            if ( $page["found"] ) {
                                $title = $page["link_title"];
                            }
                        }
                        $url = $page["url"];
                    }
                    
                    $result = array(
                        "parents"     => cms_menu_get_parents_list2(),
                        "title"       => $title, // для простановки у дочерних
                        "url"         => $url,
                    );
                    // При изменении родителя возвращаем полный список
                    if ( $_POST["parent_id"] != $_POST["old_parent_id"] ) {
                        cms_menu_resort( $_POST["parent_id"] );
                        $result["list"] = cms_menu_get_items_list();
                    }
                    echo ( json_encode( array(
                        "result" => $result
                    ) ) );
                } catch ( PDOException $e ) {
                    error_log( $e->getMessage() );
                }
            break;

            case "get_search_pages_list":
                $data = array(
                    "search" => $_POST["search"],
                    "limit"  => 100,
                    "pages"  => array(),
                );
                do_hook( "mod_menu_pages_for_selector", $data );

                $html[] = "<div class=option data-page-id=0 data-url>" . __( "no_page" ) . "</div>";
                foreach ( $data["pages"] as $page ) {
                    $title = htmlspecialchars( $page["title"] );
                    $html[] = "<div class='option {$page["classes"]}' data-page-id={$page["id"]} data-url='{$page["url"]}'>{$title}</div>";
                }

                echo( json_encode( array(
                    "result" => array(
                        "html" => implode( "\n", $html ),
                    )
                ) ) );
            break;

        }
    }
}

function cms_menu_del( $id ) {
    global $cms;

    try {
        // Рекурсивное удаление дочерних
        $stmt_select = $cms["pdo"]->prepare( "SELECT id FROM menu WHERE parent_id = ?" );
        $stmt_select->execute( array( $id ) );
        while ( $child = $stmt_select->fetch( PDO::FETCH_ASSOC ) ) {
            cms_menu_del( $child["id"] );
        }
        // Удаление текущего
        $stmt_delete = $cms["pdo"]->prepare( "DELETE FROM menu WHERE id = ?" );
        $stmt_delete->execute( array( $id ) );
    } catch ( PDOException $e ) {
        error_log( $e->getMessage() );
    }
}

function cms_menu_get_items_list( $parent_id = 0 ) {
    global $cms;

    $list = "";

    try {
        $res = $cms["pdo"]->prepare( "SELECT * FROM menu WHERE parent_id = ? ORDER BY sort, title" );
        $res->execute( array( $parent_id ) );
    } catch ( PDOException $e ) {
        error_log( $e->getMessage() );
        return "<span class=no-tables>" . __( "no_tables_db" ) . "</span>";
    }

    if ( $res ) {

        $tpl = $cms["config"]["template.mod.php"]["template"];
        $tpl_file = "{$cms["cms_dir"]}/{$tpl}/html.php";
        $tpl_content = file_get_contents($tpl_file);

        // Извлекаем все PHP-блоки
        $php_blocks = array();
        preg_match_all('/<\?php(.*?)\?>/is', $tpl_content, $matches, PREG_SET_ORDER);

        $collected_areas = array();
        foreach ($matches as $match) {
            $php_block = $match[1];
            
            // Удаляем комментарии из PHP-блока
            $php_block = preg_replace('/\/\*.*?\*\//s', '', $php_block); // многострочные комментарии
            $php_block = preg_replace('/\/\/.*$/m', '', $php_block);     // однострочные комментарии
            
            // Ищем menu(...) и dyn_menu(...)
            $pattern = '/(?:menu|dyn_menu)\s*\(\s*[\'"]([^\'"]+)[\'"]\s*\)/';
            if ( preg_match_all($pattern, $php_block, $area_matches) ) {
                foreach ($area_matches[1] as $area) {
                    $collected_areas[] = $area;
                }
            }
        }

        // Убираем дубликаты
        $collected_areas = array_unique($collected_areas);

        // Формируем список опций
        $areas = array();
        $area_options = "";
        foreach ($collected_areas as $area) {
            $title = __($area, $tpl);
            $areas[$area] = $title;
            $area_options .= "<div class='option' value='{$area}'>{$title}</div>";
        }

        // Translations
        $tr_title              = __( "title" );
        $tr_area               = __( "area" );
        $tr_no_area            = __( "no_area" );
        $tr_classes            = __( "classes" );
        $tr_sort               = __( "sort" );
        $tr_save               = __( "save" );
        $tr_delete             = __( "delete" );
        $tr_add_sub            = __( "add_sub" );
        $tr_add_prev           = __( "add_prev" );
        $tr_add_next           = __( "add_next" );
        $tr_prop               = __( "properties" );
        $tr_parent             = __( "parent" );
        $tr_placeholder        = __( "placeholder_hint" );
        $tr_no_page            = __( "no_page" );
        $tr_search             = __( "search" );
        $tr_tag_title          = __( "hint" );
        $tr_new_window         = __( "target_blank" );
        $tr_page               = __( "page" );
        $tr_page_deleted       = __( "deleted_page" );

        while ( $item = $res->fetch( PDO::FETCH_ASSOC ) ) {

            // Children Items
            $sublist = cms_menu_get_items_list( $item["id"] );
            if ( $sublist ) {
                $sublist = "<div class='items resort'>{$sublist}</div>";
            }

            if ( $item["parent_id"] == 0 ) {
                // Это меню

                // area title
                if ( empty( $item["area"] ) ) {
                    $area_title = $tr_no_area;
                } elseif ( isset( $areas[ $item['area'] ] ) ) {
                    $area_title = $areas[ $item['area'] ];
                } else {
                    $area_title = $item['area'];
                }

                $list   .= "
<div class=area>

    <div class=menu data-type=menu data-item={$item["id"]} data-parent='{$item["parent_id"]}'>

        <div class='header'>
            <input name=title type=text value='{$item['title']}'>
            <input name=sort type=text value='{$item['sort']}' data-old-sort='{$item['sort']}' size=4>
        </div>

        <div class='buttons'>
            <div class='button save'>
                <span>{$tr_save}</span>
            </div>
            <div class='button prop'>
                <span>{$tr_prop}</span>
            </div>
            <div class='button add sub'>
                <span>{$tr_add_sub}</span>
            </div>
            <div class='button del'>
                <span>{$tr_delete}</span>
            </div>
        </div>

        <div class='properties'>
            <div class='title'>{$tr_area}:</div>
            <div class='areas select widget'>
                <div class=selected data-menu-area='{$item['area']}'>
                    <div class=value>{$area_title}</div>
                    <div class='button icon down'><span></span></div>
                </div>
                <div class='options scrollable'>
                    <div class=option value=''>{$tr_no_area}</div>
                    {$area_options}
                </div>
            </div>

            <div class='title'>{$tr_parent}:</div>
            <div class='parents select widget'>
                <div class=selected data-parent='{$item["parent_id"]}' data-old-parent='{$item["parent_id"]}'>
                    <div class=value></div>
                    <div class='button icon down'><span></span></div>
                </div>
                <div class=options>
                    <div class=search>
                        <input class=search-field type=search name=search placeholder='{$tr_search}'>
                    </div>
                    <div class=scrollable>
                        
                    </div>
                </div>
            </div>

            <div class='title'>{$tr_classes}:</div>
            <input name=classes type=text value='{$item['classes']}'>
        </div>

    </div>

    {$sublist}

</div>";

            } else {
                // Это пункт меню
                
                $disabled_url = "disabled";
                $href = "";

                if ( $item["page_id"] === 0 ) { // Произвольная ссылка
                    $item["select_title"] = $tr_no_page;
                    $disabled_url = "";
                    
                    if ( ! empty( $item["title"] ) ) {
                        $item["link_title"] = $item["title"];
                    } else {
                        $item["link_title"] = "";
                    }

                    // Отличаем абсолютные ссылки от относительных в пределах сайта
                    if ( substr( $item["url"], 0, 2 ) === "//" || strpos( $item["url"], "://" ) !== false ) {
                        $href = "href='{$item["url"]}'";
                    } else {
                        $href = "href='{$cms["base_path"]}{$item["url"]}'";
                    }
                } else {
                    // Дернуть модуль страниц и модуль страниц с блоками
                    // чтобы предоставили информацию
                    do_hook( "mod_menu_item", $item );
                    // Но перекрыть title если он задан в Меню
                    if ( ! empty( $item["title"] ) ) {
                        $item["link_title"] = $item["title"];
                    }
                    $href = "href='{$cms["base_path"]}{$item["url"]}'";
                }

                // Checkbox "Open in new Tab"
                if ( $item["target_blank"] ) {
                    $checked = "checked";
                } else {
                    $checked = "";
                }

                $e_tag_title = htmlspecialchars( $item["tag_title"] );

                if ( isset( $item["published"] ) && $item["published"] === "0" ) {
                    $pub_class = " unpublished";
                } else {
                    $pub_class = "";
                }

                $list .= "
<div class=padding>

    <div class='item{$pub_class}' data-type=item data-item={$item['id']}>

        <div class='header'>
            <a class=title target=_blank {$href}>{$item["link_title"]}</a>
            <input name=sort type=text value='{$item['sort']}' data-old-sort='{$item['sort']}' size=4>
        </div>

        <div class='buttons'>
            <div class='button save'>
                <span>{$tr_save}</span>
            </div>
            <div class='button prop'>
                <span>{$tr_prop}</span>
            </div>
            <div class='button add sub'>
                <span>{$tr_add_sub}</span>
            </div>
            <div class='button add prev'>
                <span>{$tr_add_prev}</span>
            </div>
            <div class='button add next'>
                <span>{$tr_add_next}</span>
            </div>
            <div class='button del'>
                <span>{$tr_delete}</span>
            </div>
        </div>

        <div class='properties'>

            <div class=left>

                <div class='title'>{$tr_page}:</div>
                <div class='pages select widget'>
                    <div class=selected name=page_id data-page-id={$item["page_id"]} data-old-page-id={$item["page_id"]} data-old-item-url='{$item["url"]}'>
                        <div class=value>{$item['select_title']}</div>
                        <div class='button icon down'><span></span></div>
                    </div>
                    <div class=options>
                        <div class=search>
                            <input class=search-field type=search name=search placeholder='{$tr_search}'>
                        </div>
                        <div class=scrollable>
                            <div class=option data-page-id=0 data-url>{$tr_no_page}</div>
                        </div>
                    </div>
                </div>

                <div class='title'>{$tr_title}:</div>
                <input name=title type=text value='{$item['title']}' placeholder='{$tr_placeholder}'>

                <div class='title'>URL:</div>
                <div class=target>
                    <input name=url type=text value='{$item['url']}' {$disabled_url}>
                    <input name=target_blank type=checkbox {$checked} title='{$tr_new_window}'>
                </div>
            </div>

            <div class=right>

                <div class='title'>{$tr_parent}:</div>
                <div class='parents select widget'>
                    <div class=selected data-parent='{$item["parent_id"]}' data-old-parent='{$item["parent_id"]}'>
                        <div class=value></div>
                        <div class='button icon down'><span></span></div>
                    </div>
                    <div class=options>
                        <div class=search>
                            <input class=search-field type=search name=search placeholder='{$tr_search}'>
                        </div>
                        <div class=scrollable>
                            
                        </div>
                    </div>
                </div>

                <div class='title'>{$tr_tag_title}:</div>
                <input name=tag_title type=text value=\"{$e_tag_title}\">

                <div class='title'>{$tr_classes}:</div>
                <input name=classes type=text value='{$item['classes']}'>

            </div>

        </div>
    </div>
    
    {$sublist}

</div>";
            }
            
        }
    }
    return $list;
}

function cms_menu_get_parents_list2() {
    return "<div class=option value=0>" . __( "make_menu" ) . "</div>"
    . cms_menu_get_parents_list();
}

function cms_menu_get_parents_list( $parent_id = 0, $lvl = 0 ) {
    global $cms;
    $parents = "";
    if ( empty( $cms["pdo"] ) ) {
        return "";
    }

    try {
        $stmt = $cms["pdo"]->prepare( "SELECT id, parent_id, title, page_id FROM menu WHERE parent_id = ? ORDER BY sort" );
        $stmt->execute( array( $parent_id ) );

        while ( $menu_item = $stmt->fetch( PDO::FETCH_ASSOC ) ) {
            // Обработка пустого заголовка
            if ( empty( $menu_item["title"] ) ) {
                // Это может быть меню или пункт меню.
                if ( $menu_item["parent_id"] == 0 ) { // Это меню
                    $menu_item["title"] = "\u{00A0}"; // Неразрывный пробел. Чтобы не уменьшалась высота
                } else { // Это пункт меню
                    if ( empty( $menu_item["title"] ) ) {
                        $page = array( "page_id" => $menu_item["page_id"] );
                        do_hook( "mod_menu_item", $page );
                        if ( $page["found"] ) {
                            $menu_item["title"] = $page["link_title"];
                        }
                    }
                }
            }

            $title = htmlspecialchars( $menu_item["title"] );
            $ident = str_repeat( "&emsp;", $lvl );
            $parents .= "<div class=option value={$menu_item['id']}>{$ident}{$title}</div>";
            $parents .= cms_menu_get_parents_list( $menu_item["id"], $lvl + 1 );
        }
    } catch ( PDOException $e ) {
        error_log( $e->getMessage() );
    }
    return $parents;
}

function cms_menu_admin() {
    global $cms;
    if ( is_admin_header_on( "menu.mod.php" ) ) {

        $page = "
            <div class=header>
                <div class='button create' data-item=0>
                    <span>" . __( "add_menu" ) . "</span>
                </div>
            </div>
            <div class='main resort'>

            </div>
        ";

        // Create menu item if not exists
        if ( empty( $cms["config"]["menu.mod.php"]["menu"]["menu"] ) ) {
            $cms["config"]["menu.mod.php"]["menu"]["menu"] = array(
                "title"    => "menu_module_name",
                "sort"     => 200,
                "section"  => "content",
            );
            cms_save_config();
        }

        $cms["admin_pages"]["menu"] = $page;

    }
}

function cms_menu_create_table() {
    global $cms;

    if ( empty( $cms["pdo"] ) ) {
        return;
    }

    $db_type = $cms["pdo"]->getAttribute( PDO::ATTR_DRIVER_NAME );

    if ( $db_type === "mysql" ) {
        $id_column = "id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY";
    } elseif ( $db_type === "pgsql" ) {
        $id_column = "id BIGSERIAL PRIMARY KEY";
    } else {
        return; // Неизвестный тип БД
    }

    $sql = "
    CREATE TABLE IF NOT EXISTS menu (
        {$id_column},
        parent_id INT DEFAULT 0,
        page_id INT NOT NULL DEFAULT 0,
        title VARCHAR(255) NOT NULL DEFAULT '',
        tag_title VARCHAR(255) NOT NULL DEFAULT '',
        url VARCHAR(255) NOT NULL DEFAULT '',
        sort INT NOT NULL DEFAULT 1000,
        classes VARCHAR(255) NOT NULL DEFAULT '',
        area VARCHAR(32) NOT NULL DEFAULT '',
        target_blank BOOLEAN NOT NULL DEFAULT FALSE
    );";

    try {
        $cms["pdo"]->exec( $sql );
    } catch ( PDOException $e ) {
        error_log( "Table 'menu' creation failed: " . $e->getMessage() );
    }
}


function menu( $area ) {
    global $cms;
    if ( empty( $cms["pdo"] ) ) { return ""; }

    $html = "";
    $cms["menu"] = array();

    try {
        $stmt = $cms["pdo"]->prepare( "SELECT * FROM menu WHERE parent_id = 0 AND area = ? ORDER BY sort" );
        $stmt->execute( array( $area ) );

        while ( $menu = $stmt->fetch( PDO::FETCH_ASSOC ) ) {
            $cms["menu.mod.php"]["menu"] = $menu;
            $html .= menu1( $menu["id"] );
        }
    } catch ( PDOException $e ) {
        error_log( "Error in menu function: " . $e->getMessage() );
        return ""; // Or handle the error as appropriate
    }

    return $html;
}


function menu1( $parent_id = 0 ) {
    global $cms;
    
    $html = "";

    try {
        $stmt = $cms["pdo"]->prepare( "SELECT * FROM menu WHERE parent_id = ? ORDER BY sort" );
        $stmt->execute( array( $parent_id ) );
    } catch ( PDOException $e ) {
        error_log( "Error in menu1 function (select menu items): " . $e->getMessage() );
        return ""; // Exit if we can't get menu items
    }
    
    while ( $item = $stmt->fetch( PDO::FETCH_ASSOC ) ) {

        $page = null; // Reset page data for each item

        if ( $item["page_id"] !== "0" ) {
            try {
                $stmt_page = $cms["pdo"]->prepare( "SELECT * FROM pages WHERE id = ?" );
                $stmt_page->execute( array( $item['page_id'] ) );
                $page = $stmt_page->fetch( PDO::FETCH_ASSOC );

                if ( $page ) {
                    $item["url"] = $cms["base_path"] . $page["url"];
                    if ( empty( $item["title"] ) ) {
                        if ( empty( $page["title"] ) ) {
                            // Пишем что страница удалена, но не скрываем потому что могут быть дочерние
                            $item["title"] = __( "deleted_page" );
                            // Чтобы не указывала на главную и не путала этим
                            $item["url"] = "#";
                        } else {
                            $item["title"] = $page["title"];
                        }
                    }
                }
            } catch ( PDOException $e ) {
                error_log( "Error in menu1 function (select page): " . $e->getMessage() );
                // Continue execution, as the original code did not handle this error
            }
        }

        if ( isset( $cms["page"]["url"] ) && $item["url"] === $cms["base_path"] . $cms["page"]["url"] && !( $item["page_id"] === "0" && empty( $item['url'] ) ) ) {
            $class = "active";
        } else {
            $class = "";
        }
        if ( $item["target_blank"] ) {
            $target_blank = " target=_blank";
        } else {
            $target_blank = "";
        }
        if ( $item["tag_title"] ) {
            $e_tag_title = htmlspecialchars( $item["tag_title"] );
            $tag_title = " title=\"{$e_tag_title}\"";
        } else {
            $tag_title = "";
        }

        // submenu
        $sub = menu1( $item["id"] );
        if ( ! empty( $sub ) ) {
            $class .= " has-sub-menu";
            $has_submenu = true;
        } else {
            $has_submenu = false;
        }
        if ( ! empty( $class ) || ! empty( $item["classes"] ) ) {
            $class = trim( "{$class} {$item["classes"]}" );
        }
        
        // Формирование ссылки или span
        if ( $item["page_id"] === "0" && substr( $item["url"], 0, 2 ) === "//" ) {
            $link = "<a href='{$item["url"]}'{$target_blank}{$tag_title}>{$item["title"]}</a>";
        } elseif ( $item["page_id"] === "0" && strpos( $item["url"], "://" ) !== false ) {
            $link = "<a href='{$item["url"]}'{$target_blank}{$tag_title}>{$item["title"]}</a>";
        } elseif ( $item["page_id"] !== "0" && isset( $page["published"] ) && $page["published"] === "0" ) {
            // снята с публикации
            $link = "<a{$tag_title}>{$item["title"]}</a>";
            $class = trim( "{$class} unpublished" );
        } else {
            $link = "<a href='{$item["url"]}'{$target_blank}{$tag_title}>{$item["title"]}</a>";
        }

        
        // Для хука
        $cms["menu.mod.php"]["item_link"] = array(
            "link" => $link,
            "has_submenu" => $has_submenu,
        );
        do_hook( "menu_item_link" );


        if ( empty( $sub ) && $item["page_id"] !== "0" && isset( $page["published"] ) &&  $page["published"] === "0" ) {
            // Если нет дочерних и страница снята с публикации, то не добавлять
            $item_html = "";
        } else {
            if ( ! empty( $class ) ) {
                $tag_class = " class='{$class}'";
            } else {
                $tag_class = "";
            }
            $item_html = "<li{$tag_class}>{$cms["menu.mod.php"]["item_link"]["link"]}{$sub}</li>";
        }


        // Для хука
        $cms["menu.mod.php"]["item"] = array(
            "html" => $item_html,
            "has_submenu" => $has_submenu,
        );
        do_hook( "menu_item" );
        

        $html .= $cms["menu.mod.php"]["item"]["html"];
    }

    if ( ! empty( $html ) ) {
        try {
            $stmt = $cms["pdo"]->prepare( "SELECT classes, parent_id FROM menu WHERE id = ?" );
            $stmt->execute( array( $parent_id ) );
            if ( $menu = $stmt->fetch( PDO::FETCH_ASSOC ) ) {
                $classes = explode( " ", $menu["classes"] );
                if ( $menu["parent_id"] != 0 ) {
                    $classes[] = "sub-menu";
                }

                $classes_str = implode( " ", $classes );
                if ( $classes_str ) {
                    $class = " class='{$classes_str}'";
                } else {
                    $class = "";
                }

                $html = "<ul{$class}>{$html}</ul>";
            }
        } catch ( PDOException $e ) {
            error_log( "Error in menu1 function (select parent menu): " . $e->getMessage() );
        }
    }

    return $html;
}


// Новое меню
// Еще не подключено
function dyn_menu( $area ) {
    global $cms;

    if ( empty( $cms["pdo"] ) ) { return "<!-- pdo empty -->"; }

    $menu = array();

    try {
        $stmt = $cms["pdo"]->prepare( "SELECT * FROM menu WHERE parent_id = 0 AND area = ? ORDER BY sort" );
        $stmt->execute( array( $area ) );

        while ( $item = $stmt->fetch( PDO::FETCH_ASSOC ) ) {
            $menu[ $item["id"] ] = $item;
            menu_get_items( $item["id"], $menu[ $item["id"] ] );
        }
    } catch ( PDOException $e ) {
        error_log( $e->getMessage() );
        return "<!-- pdo error -->";
    }

    do_hook( "menu", $menu );
}


function menu_get_items( $parent_id, &$items ) {
    global $cms;
    
    $items["items"] = array();

    if ( empty( $cms["pdo"] ) ) { return; }

    try {
        $stmt = $cms["pdo"]->prepare( "SELECT * FROM menu WHERE parent_id = ? ORDER BY sort" );
        $stmt->execute( array( $parent_id ) );

        while ( $item = $stmt->fetch( PDO::FETCH_ASSOC ) ) {
            menu_get_items( $item["id"], $item );
            $items["items"][] = $item;
        }
    } catch ( PDOException $e ) {
        error_log( $e->getMessage() );
    }
}

