Исправляем баг меню

+5
1.85K
Баг, конечно, не критичный но крайне неприятный для тех, кому нужно многоуровневое меню с разграничениями прав доступа к вложенным пунктам.

Описание бага

Предположим нам нужно сделать многоуровневое меню
Иллюстрация

Так оно будет выглядеть в свернутом виде
Иллюстрация

Теперь нам понадобилось скрыть от гостей доступ к одному из разделов
Иллюстрация

Вот, что гости увидят в итоге
Иллюстрация


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

В свернутом виде это будет выглядеть так
Иллюстрация

А в развернутом
Иллюстрация

Я не рискнул экспериментировать, что получится, если мы захотим одновременно скрыть вышеупомянутые пункты и раздел:)
Еще раз хочу подчеркнуть, что лично я особых ужасов в этом не вижу. Этот баг из разряда неприятностей, которые можно было бы обойти средствами системы, правда, не без некоторых потерь. Но если говорить о том, как это должно выглядеть ПРАВИЛЬНО, то по логике вещей, в развернутом виде примерно так
Иллюстрация

На всякий случай напомню исходное меню
Иллюстрация

Устранение бага

Открываем файл /modules/mod_menu/module.php
Строки:
  1.  
  2. while ($row = $inDB->fetch_assoc($rs_rows)){
  3. if ($row['menu'] == $menu){
  4.  
Заменяем на:
  1.  
  2. $m_inside = array(); // массив для подсчета к-ва прямых потомков разделов
  3. $m_num = 0; // счетчик "актуальных" пунктов меню
  4.  
  5. while ($row = $inDB->fetch_assoc($rs_rows)){
  6. if ( ($row['menu'] == $menu) &
  7. (($row['allow_group'] == -1)||($row['allow_group'] == $inUser->group_id)||$inUser->is_admin) &
  8. // заносим в массив только "актуальные" пункты меню
  9. (($row['parent_id'] == $root_id)||(isset($m_inside[$row['parent_id']]))) ){
  10. // отсекаем вложенные пункты, к родительскому разделу которых нет прав доступа
  11.  
  12. if ( $row['NSRight'] - $row['NSLeft'] != 1 ) { // если не 1 - значит имеются потомки
  13. $m_inside[$row['id']]['count'] = 0; // стартовое значение счетчика прямых потомков
  14. $m_inside[$row['id']]['num'] = $m_num; // индекс пункта меню в массиве
  15. }
  16.  
  17. if ( $row['parent_id'] != $root_id ) { // если родительский раздел не является корнем
  18. $m_inside[$row['parent_id']]['count']++; // счетчик прямых потомков родительского раздела увеличивается на 1
  19. }
  20.  
Идем дальше.
Строку:
  1.  
  2. $items[] = $item;
  3.  
Заменяем на:
  1.  
  2. $items[$m_num++] = $item; // заносим данные в текущую ячейку массива и увеличиваем счетчик на 1
  3.  
Идем дальше.
ПЕРЕД строкой:
  1.  
  2. $smarty = $inCore->initSmarty('modules', 'mod_menu.tpl');
  3.  
Вставляем:
  1.  
  2. foreach ( $m_inside as $m_par ) {
  3. if ( !$m_par['count'] ) { // если нет "актуальных потомков"
  4. $items[$m_par['num']]['NSRight'] = $items[$m_par['num']]['NSLeft'] + 1; // снимаем статус родителя
  5. }
  6. }
  7.  
Все.
Помним, что после копирования нужно менять кавычки!

Те, кому лень или нет нужды ковырять код, могут скачать патч в каталоге дополнений.

P.S. Если разработчики сочтут целесообразным включить это решение в оф.релиз, то будет не лишним оптимизировать файл шаблона. Из него можно исключить логику отображения скрытых пунктов. Мне не составит труда это сделать.
0
14 лет назад #
А как то можете обосновать свои слова! по какой причине то удалять данный пост!?? И хотелось бы услышать тогда ответ по причастности вот этих блогов http://instantcms.ru/blogs/0/dopolnenija-dlja-novichkov  ; непосредственно к ИНСТНАТ и вообще! Вроде они в большей степени нарушают правила чем реальный пост???? Или я опять неправ!?
0
14 лет назад #
Спасибо за хак!
Но вот у меня возникла еще более серьезная проблема. Она заключается в том, что менюшка нивкакую не хочет разворачиваться. Т.е. когда есть вложенный пункт он, по идее, должен появиться при щелчке на главный пункт меню. У меня же при клике на основной пункт список разворачивается и сразуже сворачивается. Это происходит и в эксплорере и в опере. Посмотрите сами на моем сайте пункт "Аудио, видео, книги" в левом верхнем меню. Можете что-то посоветовать по этому поводу? как решить эту проблему?
0
neart neart 14 лет назад #
Поставьте этот хак и будет Вам счастье:)

Еще от автора

Инвайты – забрасываем удочку пользователю
Пару дней назад в личку пришло уже второе письмо с вопросом об использовании инвайтов.
Новый модуль ` Универсальное меню `
Честно говоря, не думал возвращаться на сайт и просил Максисофта передать сообществу мой прощальный подарок (Универсальное меню).
Юзабилити-меню для InstantCMS
Работая над юзабилити-шаблоном для Инстанта стал переделывать главное меню.
Используя этот сайт, вы соглашаетесь с тем, что мы используем файлы cookie.