Mercurial
view .cms/mod/menu.mod.php @ 1:1d486627aa1e draft default tip
24.10
author | Coffee CMS <info@coffee-cms.ru> |
---|---|
date | Sat, 12 Oct 2024 02:51:39 +0000 |
parents | 78edf6b517a0 |
children |
line wrap: on
line source
<?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.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.mod.php.html", ), ); // Return if module disabled if ( ! empty( $cms["config"]["menu.mod.php"]["disabled"] ) ) { return; } else { 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 ); } } function cms_menu_admin_header() { global $cms; $conf = $cms["config"]["menu.mod.php"]["menu"]["menu"]; if ( empty( $conf["hide"] ) && empty( $cms["config"]["admin_sections"][ $conf["section"] ]["hide"] ) ) { echo "<link rel=stylesheet href='{$cms['base_path']}css/menu.css'>"; echo "<script src='{$cms['base_path']}js/menu.js'></script>"; } } function cms_menu_api() { global $cms; if ( ! empty( $_POST["fn"] ) ) { switch ( $_POST["fn"] ) { case "create_menu_item": if ( empty( $cms["base"] ) ) { echo( json_encode( array( "info_text" => __( "no_connect_db" ), "info_class" => "info-error", "info_time" => 5000, ) ) ); return; } $sort = 10; // Пересортировываем имеющиеся $pid = (int) $_POST["pid"]; $q = "SELECT mid FROM menu WHERE pid={$pid} ORDER BY `sort`"; if ( $r = mysqli_query( $cms["base"], $q ) ) { while ( $i = mysqli_fetch_assoc( $r ) ) { $q = "UPDATE menu SET `sort`={$sort} WHERE mid={$i['mid']}"; mysqli_query( $cms["base"], $q ); $sort += 10; } } $q = "INSERT INTO menu SET pid={$pid}, url='', sort={$sort}"; if ( $r = mysqli_query( $cms["base"], $q ) ) { $mid = mysqli_insert_id( $cms["base"] ); echo( json_encode( array( "info_text" => __( "created" ), "info_class" => "info-success", "info_time" => 5000, "list" => cms_menu_get_items_list(), "parents" => cms_menu_get_parents_list(), "mid" => $mid, ) ) ); return; } else { echo( json_encode( array( "info_text" => __( "sql_error" ) . mysqli_error( $cms["base"] ), "info_class" => "info-error", "info_time" => 5000, ) ) ); return; } break; case "get_menu_items": if ( empty( $cms["base"] ) ) { echo( json_encode( array( "info_text" => __( "no_connect_db" ), "info_class" => "info-error", "info_time" => 5000, ) ) ); return; } echo( json_encode( array( "list" => cms_menu_get_items_list(), "parents" => cms_menu_get_parents_list(), ) ) ); return; break; case "del_menu_item": if ( $mid = (int) $_POST["mid"] ) { cms_menu_del( $mid ); cms_clear_cache(); echo( json_encode( array( "info_text" => __( "deleted" ), "info_class" => "info-success", "info_time" => 5000, "list" => cms_menu_get_items_list(), "parents" => cms_menu_get_parents_list(), ) ) ); return; } break; case "save_menu_item": $mid = (int) $_POST["mid"]; $pid = (int) $_POST["pid"]; $old_pid = (int) $_POST["old_pid"]; $id = (int) $_POST["id"]; $sort = (int) $_POST["sort"]; $title = mysqli_real_escape_string( $cms["base"], $_POST["title"] ); $tag_title = mysqli_real_escape_string( $cms["base"], $_POST["tag_title"] ); $classes = mysqli_real_escape_string( $cms["base"], $_POST["classes"] ); $url = mysqli_real_escape_string( $cms["base"], $_POST["url"] ); $area = mysqli_real_escape_string( $cms["base"], $_POST["area"] ); if ( $_POST["target"] === "true" ) { $target_blank = 1; } else { $target_blank = 0; } $q = "UPDATE menu SET pid={$pid}, id={$id}, sort={$sort}, title='{$title}', tag_title='{$tag_title}', class='{$classes}', url='{$url}', area='{$area}', target_blank={$target_blank} WHERE mid={$mid}"; if ( $r = mysqli_query( $cms["base"], $q ) ) { cms_clear_cache(); $r = array( "ok" => "true", "info_text" => __( "updated" ), // FIXME: never fire "info_class" => "info-success", "info_time" => 5000, //"list" => cms_menu_get_items_list(), "parents" => cms_menu_get_parents_list(), ); if ( $pid != $old_pid ) { $r["list"] = cms_menu_get_items_list(); } echo ( json_encode( $r ) ); return; } else { echo( json_encode( array( "ok" => "false", "info_text" => __( "update_properties_error" ), "info_class" => "info-error", "info_time" => 5000, ) ) ); return; } break; case "get_search_pages_list": if ( empty( $cms["base"] ) ) { echo( json_encode( array( "no_database" => "<span class=no-database>" . __( "no_connect_db" ) . "</span>", ) ) ); return; } //$s = mysqli_real_escape_string( $cms["base"], $_POST["search"] ); //$s = str_replace( " ", "%", $s ); $s = preg_replace( "/\s/u", "", $_POST["search"] ); $s = preg_split( '//u', $s, -1, PREG_SPLIT_NO_EMPTY ); foreach( $s as $n => $ch ) { $s[$n] = mysqli_real_escape_string( $cms["base"], $ch ); } $s = implode( "%", $s ); $html[] = array( "sort" => 2000000000, "html" => "<li data-id=0 data-url>" . __( "no_page" ) . "</li>" ); // pages without blocks $q = "SELECT id, title, url, pin FROM pages WHERE title LIKE '%{$s}%' OR url LIKE '%{$s}%' ORDER BY ( id + pin * 1000000000 ) DESC LIMIT 10"; if ( $res = mysqli_query( $cms["base"], $q ) ) { while ( $page = mysqli_fetch_assoc( $res ) ) { $title = htmlspecialchars( $page["title"] ); $html[] = array( "sort" => $page["id"] + $page["pin"] * 1000000000, "html" => "<li data-id={$page['id']} data-url='{$page['url']}'>{$title}</li>" ); } } // pages with blocks $q = "SELECT id, title, url, pin FROM blocks_pages WHERE title LIKE '%{$s}%' OR url LIKE '%{$s}%' ORDER BY ( id + pin * 1000000000 ) DESC LIMIT 10"; if ( $res = mysqli_query( $cms["base"], $q ) ) { while ( $page = mysqli_fetch_assoc( $res ) ) { $title = htmlspecialchars( $page["title"] ); $html[] = array( "sort" => $page["id"] + $page["pin"] * 1000000000, "html" => "<li data-id={$page['id']} data-url='{$page['url']}'>{$title}</li>" ); } } cms_asort( $html ); $html = array_reverse( $html ); $list = ""; foreach( $html as $item ) { $list .= $item["html"]; } echo( json_encode( array( "html" => $list, ) ) ); return; break; } } } function cms_menu_del( $mid ) { global $cms; // Recursively delete children items $q = "SELECT mid FROM menu WHERE pid={$mid}"; if ( $res = mysqli_query( $cms["base"], $q ) ) { while ( $r = mysqli_fetch_assoc( $res ) ) { cms_menu_del( $r["mid"] ); } } mysqli_query( $cms["base"], "DELETE FROM menu WHERE mid=$mid" ); } function cms_menu_get_items_list( $pid = 0 ) { global $cms; if ( empty( $cms["base"] ) ) { echo( json_encode( array( "no_database" => "<span class=no-database>" . __( "no_connect_db" ) . "</span>", ) ) ); return; } $list = ""; $q = "SELECT * FROM menu WHERE pid={$pid} ORDER BY sort, title"; if ( ! $res = mysqli_query( $cms["base"], $q ) ) { return "<span class=no-tables>" . __( "no_tables_db" ) . "</span>"; } else { // Read template settings cms_template_load_settings(); // Menu Areas $area_options = ""; $tpl = $cms["config"]["template.mod.php"]["template"]; if ( isset( $cms["menu_areas"] ) ) { foreach ( $cms["menu_areas"] as $area => $a ) { //- удалить после перехода на $cms["menu_areas"]["header_en"] = "Header En"; if ( is_array( $a ) && isset( $a["title"] ) ) { $title = $a["title"]; } elseif ( is_string( $a ) ) { $title = $a; } $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_append = __( "append_item" ); $tr_prop = __( "properties" ); $tr_parent = __( "parent" ); $tr_no_parent = __( "no_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" ); $tr_menu_item = __( "no_page" ); while ( $item = mysqli_fetch_assoc( $res ) ) { // Children Items $sublist = cms_menu_get_items_list( $item["mid"] ); if ( $sublist ) { $sublist = "<div class=items-grid>{$sublist}</div>"; } if ( $item["pid"] == 0 ) { // area title //- подправить после перехода на $cms["menu_areas"]["header_en"] = "Header En"; if ( empty( $item["area"] ) ) { $area_title = $tr_no_area; } elseif ( isset( $cms["menu_areas"][ $item['area'] ] ) && is_string( $cms["menu_areas"][ $item['area'] ] ) ) { $area_title = $cms["menu_areas"][ $item['area'] ]; } elseif ( isset( $cms["menu_areas"][ $item['area'] ] ) && is_array( $cms["menu_areas"][ $item['area'] ] ) ) { $area_title = $cms["menu_areas"][ $item['area'] ]['title']; } else { $area_title = $item['area']; } $list .= " <div> <div class=menu data-item={$item['mid']}> <input name=title type=text value='{$item['title']}'> <input name=sort type=text value='{$item['sort']}' data-sort='{$item['sort']}'> <div class=menu-buttons> <div class=prop>{$tr_prop}</div> <div class=append>{$tr_append}</div> <div class=save><span>{$tr_save}</span></div> <div class=del>{$tr_delete}</div> </div> <div class=menu-prop> <div class='area title'>{$tr_area}:</div> <div class=area-select-grid> <div class=field-select-menu data-menu-area='{$item['area']}'> <div class=value>{$area_title}</div> <div class=icon></div> </div> <div class=field-options> <div class=option value=''>{$tr_no_area}</div> {$area_options} </div> </div> <div class='classes title'>{$tr_classes}:</div> <input name=classes type=text value='{$item['class']}'> </div> </div> {$sublist} </div>"; } else { $disabled_url = "disabled"; if ( $item["id"] === "0" ) { $item["select_title"] = $tr_no_page; $disabled_url = ""; // free item if ( ! empty( $item["title"] ) ) { $item["link_title"] = $item["title"]; } else { $item["link_title"] = $tr_menu_item; } } else { // Дернуть модуль страниц и модуль страниц с блоками // чтобы предоставили информацию $cms["menu.mod.php"]["item"] = &$item; do_hook( "mod_menu_item" ); } // Wrap title in URL if ( $item["id"] === "0" && empty( $item['url'] ) ) { $link = "<a target=_blank>{$item["link_title"]}</a>"; } elseif ( $item["id"] === "0" && ! empty( $item['url'] ) ) { $link = "<a href='{$item['url']}' target=_blank>{$item["link_title"]}</a>"; } else { $link = "<a href='{$cms['base_path']}{$item['url']}' target=_blank>{$item["link_title"]}</a>"; } // Checkbox "Open in new Tab" if ( $item["target_blank"] ) { $checked = "checked"; } else { $checked = ""; } $e_tag_title = htmlspecialchars( $item["tag_title"] ); $list .= " <div> <div class=item data-item={$item['mid']}> {$link} <div class=menu-buttons> <div class=prop>{$tr_prop}</div> <div class=append>{$tr_append}</div> <div class=save><span>{$tr_save}</span></div> <div class=del>{$tr_delete}</div> </div> <div class=menu-prop> <div class='title name'>{$tr_title}:</div> <input name=title type=text value='{$item['title']}' placeholder='{$tr_placeholder}'> <div class='sort title'>{$tr_sort}:</div> <input name=sort type=text value='{$item['sort']}'> <div class='parent title'>{$tr_parent}:</div> <div class=parent-select-grid> <div class=field-select data-parent='{$item['pid']}' data-old-parent='{$item['pid']}'> <div class=value></div> <div class=icon></div> </div> <div class=field-options> <div class=option value=0>{$tr_no_parent}</div> </div> </div> <div class='classes title'>{$tr_classes}:</div> <input name=classes type=text value='{$item['class']}'> <div class='page title'>{$tr_page}:</div> <div class=select-grid> <div class=field-select name=id data-id={$item['id']} data-old-id={$item['id']}> <div class=value>{$item['select_title']}</div> <div class=icon></div> </div> <div class=field-options> <div class=select-dropdown> <div class=field-search> <input class=search-field type=text placeholder='{$tr_search}'> </div> <ul class=list-search> <li data-id=0 data-url>{$tr_no_page}</li> </ul> </div> </div> </div> <div class='tag title'>{$tr_tag_title}:</div> <input name=tag_title type=text value=\"{$e_tag_title}\"> <div class='url title'>URL:</div> <div class=target-blank> <input name=url type=text value='{$item['url']}' {$disabled_url}> <input name=targetblank type=checkbox {$checked} title='{$tr_new_window}'> </div> </div> </div> {$sublist} </div>"; } } } return $list; } function cms_menu_get_parents_list( $pid = 0, $lvl = 0 ) { global $cms; $parents = ""; if ( empty( $cms["base"] ) ) { return ""; } $q = "SELECT mid, pid, title, id FROM menu WHERE pid={$pid} ORDER BY sort"; if ( $res = mysqli_query( $cms["base"], $q ) ) { while ( $item = mysqli_fetch_assoc( $res ) ) { if ( empty( $item["title"] ) and $item["id"] !== "0" ) { $q = "SELECT title FROM pages WHERE id={$item['id']}"; if ( $res_page = mysqli_query( $cms["base"], $q ) and $page = mysqli_fetch_assoc( $res_page ) ) { $item["title"] = $page["title"]; } else { $item["title"] = __( "deleted_page" ); } } elseif ( empty( $item["title"] ) ) { $item["title"] = __( "no_page" ); } $title = htmlspecialchars( $item["title"] ); $ident = str_repeat( " ", $lvl ); $parents .= "<div class=option value={$item['mid']}>{$ident}{$title}</div>"; $parents .= cms_menu_get_parents_list( $item["mid"], $lvl + 1 ); } } return $parents; } function cms_menu_admin() { global $cms; $conf = $cms["config"]["menu.mod.php"]["menu"]["menu"]; if ( empty( $conf["hide"] ) && empty( $cms["config"]["admin_sections"][ $conf["section"] ]["hide"] ) ) { $page = " <div class=main-main> <div class=menu-grid> </div> </div> <div class=main-footer> <a class=create data-item=0>" . __( "add_menu" ) . "</a> </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; mysqli_query( $cms["base"], " CREATE TABLE IF NOT EXISTS `menu` ( `mid` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, `pid` int(11) DEFAULT 0, `id` int(11) 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(11) NOT NULL DEFAULT 1000, `class` varchar(255) NOT NULL DEFAULT '', `area` varchar(32) NOT NULL DEFAULT '', `target_blank` tinyint(1) NOT NULL DEFAULT 0, UNIQUE KEY `mid` (`mid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; "); } // One or more Menus function menu( $area ) { global $cms; if ( empty( $cms["base"] ) ) { return ""; } // fix php 8.0 $area = mysqli_real_escape_string( $cms["base"], $area ); $q = "SELECT * FROM menu WHERE pid=0 AND area='{$area}' ORDER BY sort"; $html = ""; $cms["menu"] = array(); if ( $res = mysqli_query( $cms["base"], $q ) ) { while ( $menu = mysqli_fetch_assoc( $res ) ) { $cms["menu.mod.php"]["menu"] = $menu; $html .= menu1( $menu["mid"] ); } } return $html; } function menu1( $pid = 0 ) { global $cms; $html = ""; $q = "SELECT * FROM menu WHERE pid={$pid} ORDER BY sort"; // Child Items if ( $res2 = mysqli_query( $cms["base"], $q ) ) { while ( $item = mysqli_fetch_assoc( $res2 ) ) { // Совместимость с модулем блоков $q_blocks = "SELECT * FROM blocks_pages WHERE id={$item['id']}"; $page = NULL; if ( $res_b = mysqli_query( $cms["base"], $q_blocks ) ) { $page = mysqli_fetch_assoc( $res_b ); } // Если отработал модуль блоков, то не искать страницы $q_pages = "SELECT * FROM pages WHERE id={$item['id']}"; if ( ! $page && $res_p = mysqli_query( $cms["base"], $q_pages ) ) { $page = mysqli_fetch_assoc( $res_p ); } if ( $item["id"] !== "0" ) { $item["url"] = $cms["base_path"] . $page["url"]; if ( empty( $item["title"] ) ) { if ( empty( $page["title"] ) ) { $item["title"] = __( "deteled_page" ); } else { $item["title"] = $page["title"]; } } } if ( isset( $cms["page"]["url"] ) && $item["url"] === $cms["base_path"] . $cms["page"]["url"] && !( $item["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["mid"] ); if ( ! empty( $sub ) ) { $class .= " has-sub-menu"; $has_submenu = true; } else { $has_submenu = false; } if ( ! empty( $class ) || ! empty( $item["class"] ) ) { $class = trim( "{$class} {$item['class']}" ); } // Формирование ссылки или span if ( $item["id"] === "0" && empty( $item['url'] ) ) { $link = "<a{$tag_title}>{$item['title']}</a>"; } elseif ( $item["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["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"]; } } $q = "SELECT * FROM menu WHERE mid={$pid}"; // If exists childs items if ( ! empty( $html ) and $res = mysqli_query( $cms["base"], $q ) and $menu = mysqli_fetch_assoc( $res ) ) { if ( ! empty( $menu["class"] ) && $menu["pid"] == 0 ) { $class = " class='{$menu['class']}'"; } elseif ( $menu["pid"] != 0 ) { $class = " class='sub-menu'"; } else { $class = ""; } $html = "<ul{$class}>{$html}</ul>"; } return $html; } // Новое меню function dyn_menu( $area ) { global $cms; if ( empty( $cms["base"] ) ) { return ""; } // fix php 8.0 //file_put_contents( __DIR__ . "/menu_export.php", "<?php\n" ); $cms["menu"] = array(); $area = mysqli_real_escape_string( $cms["base"], $area ); $q = "SELECT * FROM menu WHERE pid=0 AND area='{$area}' ORDER BY sort"; if ( $res = mysqli_query( $cms["base"], $q ) ) { while ( $menu = mysqli_fetch_assoc( $res ) ) { $cms["menu"][ $menu["mid"] ] = $menu; menu_get_items( $menu["mid"], $cms["menu"][ $menu["mid"] ] ); } } do_hook( "menu" ); //file_put_contents( __DIR__ . "/menu_export.php", "\$cms['menu'] = " . var_export( $cms["menu"], true ) . ";\n", FILE_APPEND ); } function menu_get_items( $pid, &$items ) { global $cms; $items["items"] = array(); $q = "SELECT * FROM menu WHERE pid={$pid} ORDER BY sort"; if ( $res = mysqli_query( $cms["base"], $q ) ) { while ( $item = mysqli_fetch_assoc( $res ) ) { menu_get_items( $item["mid"], $item ); $items["items"][] = $item; } } //file_put_contents( __DIR__ . "/menu_export.php", "\$a = " . var_export( $items, true ) . ";\n", FILE_APPEND ); }