Как сделать два меню вместо одного [Решено]

Главные вкладки

Аватар пользователя designeng designeng 23 декабря 2009 в 14:42

Добрый день! Есть такая проблема: меню secondary-links слишком перегружено (вложения до третьего уровня), memory_limit для выполнения скрипта не хватает - в результате вываливается пустая страница по адресу admin/build/menu-customize/secondary-links. Можно ли разбить меню на два разных пользовательских меню не переписывая вручную всю таблицу menu_links? Спасибо заранее.

Комментарии

Аватар пользователя Xaber@drupal.org Xaber@drupal.org 23 декабря 2009 в 19:15

А так полагаю, чтобы перенести ссылки в другое меню, с учетом того, что через веб этого сделать не получится, вам потребуется в любом случае лезть в бд. Тем более, что страшного в этом ничего нет. И переписывать всю таблицу вам не придется Smile

 
menu_name |
          |_____mlid  "==" plid |
                                |______mlid
                                |
                                |______mlid

то есть вам нужно не потеряв логичности дерева сменить menu_name на новое, при этом у всех "детей" изменить это значение на то же, где mid родителя равен pid ребенка. По идее этого должно хватать.

menu_name - имя меню, все ссылки с тем же именем меню, являются частью одного меню.
mlid - идентификатор ссылки меню. Целочисленный первичный ключ. Его не меняем... Если не хотим проблем. А если знаете что делаете.... то....
plid - идентификатор родительской ссылки, это mlid ссылки, находящейся ниже в иерархии, или 0, если ссылка находится в верхнем уровне меню.

при этом стоит учесть, если будуте капитально перелопачивать меню, что depth - это глубина относительно верхнего уровня. у plid == 0 depth == 1
и если будете перелопачивать структуру меню - то учтите поля p{1,9} - mlid'ы в материализованном пути (хотя ... )

логика получается не очень страшной) так что удачи )

Аватар пользователя designeng designeng 28 декабря 2009 в 14:30

Xaber@drupal.org, спасибо огромное! Да, логика, оказывается, не лишена изящества. В итоге написал такую функцию:

/*
 * Split initial menu into two menus and asset them new machine-readable names
 * param $menu_name  название исходного меню
 * param $name1  название первого меню
 * param $name2  название второго меню
 * param $delimiter  в первое меню будут входить пункты с именами в интервале А-<$delimiter-1>, во второе <$delimiter>-Я
 * Usage: menudivider_reorganize_menu('secondary-links', 'menu-countries-1', 'menu-countries-2', 'К');
 * Меню countries-1 и countries-2 должны быть созданы заранее
 */

function menudivider_reorganize_menu ($menu_name, $name1 = 'secondary-links', $name2 = 'secondary-links', $delimiter = "Я"){
        $rootitems = array();
        //выбираем корневые items из исходного меню (plid=0)
        $result=db_query("SELECT * FROM {menu_links} WHERE menu_name = '%s' AND plid=%d", $menu_name, 0);
        while ($m = db_fetch_array($result)) {
        //сортируем относительно $delimiter, назначая новые имена
                        if(strCaseCmp($m['link_title'], $delimiter) < 0) $menu_new_name = $name1; else $menu_new_name = $name2;
                        //задаем для них новые menu_name
                        db_query("UPDATE {menu_links} SET menu_name='%s' WHERE mlid = %d AND plid=%d", $menu_new_name , $m['mlid'], 0);
                        $rootitems[$m['mlid']] = $menu_new_name;
                        echo('<br>'.$menu_new_name.': mlid: '.$m['mlid'].' '.$m['link_title']);
        }
        //меняем menu_name всех items 2...9 уровней в соответствии с данными ассоциативного массива
        foreach($rootitems as $key=>$value){
                db_query("UPDATE {menu_links} SET menu_name='%s' WHERE menu_name = '%s' AND p1=%d AND plid>%d", $value , $menu_name, $key, 0);
        }
}