|
|
|
| Добрый день.
С точки зрения работоспособности работает на ура, строит правильные списки <ul><li>, нареканий нет, но такое ощущение, что я перемудрил, и есть гораздо проще решение, поэтому прошу взглянуть трезвым взглядом. Во первых не нравиться запрос в цикле, он больше всех и раздражает.... Во вторых, просто не нравиться, громоздко слишком.
Таблицы
// NESTED SETS (категории)
| id | parent_id | name | tree_left | tree_right | tree_level |
// Страницы
| id | cat_id | name | sort |
// Сама функция построения списков
function ISMmenu()
{
global $dbInit, $settings_table;
$retMenu = '';
$menu = '';
// Считываем какое меню у нас установлено
$query_menu = "
SELECT pos_menu
FROM " . $settings_table['settings_menu'] . "
ORDER BY id
LIMIT 1
";
if ($row_menu = $dbInit -> get_row($query_menu))
{
$current_level = 0;
$pos_menu = $row_menu -> pos_menu;
$query_cat = "
SELECT *
FROM " . $settings_table['page_cat'] . "
ORDER BY parent_id, tree_left
";
if ($rows_pageCat = $dbInit -> get_results($query_cat))
{
$retMenu .= '<ul id = "navDropTopMenu">';
foreach ($rows_pageCat as $row_pageCat)
{
$cat_id = intval($row_pageCat -> id);
$cat_name = '<a href = "">' . htmlspecialchars_decode($row_pageCat -> name) . ' »</a>';
$tree_left = intval($row_pageCat -> tree_left);
$tree_right = intval($row_pageCat -> tree_right);
$tree_level = intval($row_pageCat -> tree_level);
if ($tree_level === $current_level)
{
$retMenu .= '<li>' . $cat_name;
}
else if ($tree_level > $current_level)
{
$retMenu .= '<ul><li>' . $cat_name;
$current_level++;
}
$query_page = "
SELECT id, link, name
FROM " . $settings_table['pages'] . "
WHERE approved = 'Yes'
AND cat_id = " . $cat_id . "
ORDER BY sort
";
if ($rows_page = $dbInit -> get_results($query_page))
{
if ($tree_level === $current_level)
{
$retMenu .= '<ul>';
}
foreach ($rows_page as $row_page)
{
$id = intval($row_page -> id);
$name = htmlspecialchars_decode($row_page -> name);
if ($tree_level < $current_level)
{
$menu = '<ul><li><a href = "#">' . $name . '</a></li></ul>';
}
else
{
$retMenu .= '<li><a href = "#">' . $name . '</a></li>';
}
}
if ($tree_level === $current_level)
{
$retMenu .= '</ul>';
}
}
if ($tree_level === $current_level && $tree_right - $tree_left === 1)
{
$retMenu .= '</li>';
}
else if ($tree_level < $current_level)
{
$retMenu .= '</ul></li><li>' . $cat_name . $menu . '</li>';
$current_level--;
}
}
$retMenu .= '</ul>';
}
}
else
{
return LANG_ERROR_NOMENUPOS;
}
return $retMenu;
}
|
| |
|
|
|
|
|
|
|
для: Assessor
(28.09.2008 в 13:56)
| | Вообще-то метод NESTED SETS ориентирован в первую очередь на то, чтобы выборку дерева (в порядке обхода в глубину) можно было делать одним единственным SQL-запросом. | |
|
|
|
|
|
|
|
для: Trianon
(28.09.2008 в 14:12)
| | Я с этим и не спорю... Я ж говорю, не могу построить валидный спискок "<ul>" одним запросом.... | |
|
|
|
|
|
|
|
для: Assessor
(28.09.2008 в 13:56)
| | [поправлено модератором] | |
|
|
|
|
|
|
|
для: mihdan
(28.09.2008 в 14:22)
| | и? может я не понимаю, тогда ткните мне строчку где написано, как правильно расставить тэги списка... как обойти дерево, как удалить ветку, как переместить я знаю. | |
|
|
|
|
|
|
|
для: Assessor
(28.09.2008 в 14:29)
| | Вы статью прочтите, посмотрите ссылки внизу ее - все есть только читать нужно.
Загляните сюда | |
|
|
|
|
|
|
|
для: mihdan
(28.09.2008 в 14:41)
| | но... вы сами смотрели класс который работает с NESTED SETS деревьями? и понимаете что я делаю в коде? думаете, я вот так взял и написал, не пошарив при этом инет? вы мне пальцем ткните, а то я уже чувствую себя ущербным, не видя очевидные вещи | |
|
|
|
|
|
|
|
для: Assessor
(28.09.2008 в 18:08)
| | А как эти самые <li> и <ul> должны расставляться?
Я тут попробовал набросать скрипт вывода списка, но понял, что расстановка самих тегов для меня - темный лес.
Пример бы. Аргументированный. | |
|
|
|
|
|
|
|
для: Trianon
(28.09.2008 в 19:12)
| | Набросал черновик, который выводит нечто напоминающее то, что строит word.
<?php
require_once('dbconfig.php');
function tab($s) { return "\r\n".str_repeat(' ', 2*count($s)); }
function drop($x,$s)
{
for($v = ''; !empty($s) && $x > $s[$t = count($s)-1]; $v .= tab($s)."</ul>")
unset($s[$t]);
return $v;
}
$sql = "SELECT * FROM dirtree ORDER BY lb ";
$res=mysql_query($sql) or exit("Error in $sql " . mysql_error());
for(; $row = mysql_fetch_assoc($res); )
{
echo drop($lb = intval($row['lb']), &$s);
echo tab($s)."<li>". htmlspecialchars($row['name']). "</li>";
if($lb+1 < ($rb=intval($row['rb'])))
{
echo tab($s)."<ul>";
$s[] = $rb;
}
}
echo drop($s[0]+1,&$s);
?>
|
PS1. В примере таблица с полями name, lb, rb
lb и rb - соответственно левая и правая границы поддерева. Вообще-то никакие другие ключи для вывода NESTED SETS не требуются.
PS2. tab() - чисто для красоты вывода. Ничего, кроме пробелов, она не вычисляет. | |
|
|
|
|
|
|
|
для: Trianon
(28.09.2008 в 20:01)
| | Мой гибрид из Nested Sets и списков смежности, строит многоуровневое выпадающее меню.
На выходе получается примерно такой код
<ul>
<li>Тест1
<ul>
<li>Тест1.1
<ul>
<li>Тест1.1.1</li>
</ul>
</li>
<li>Тест1.2
</li>
</ul>
</li>
<li>Тест2
</li>
</ul> | |
|
|
|
|
|
|
|
для: Assessor
(29.09.2008 в 07:50)
| | так тоже можно. Три строки изменить.
<?php
require_once('dbconfig.php');
function tab($s) { return "\r\n".str_repeat(' ', 2*count($s)); }
function drop($x,$s)
{
for($v = ''; !empty($s) && $x > $s[$t = count($s)-1]; $v .= tab($s)."</ul></li>")
unset($s[$t]);
return $v;
}
$sql = "SELECT * FROM dirtree ORDER BY lb ";
$res=mysql_query($sql) or exit("Error in $sql " . mysql_error());
for(; $row = mysql_fetch_assoc($res); )
{
echo drop($lb = intval($row['lb']), &$s);
echo tab($s)."<li>". htmlspecialchars($row['name']);
if($lb+1 < ($rb=intval($row['rb'])))
{
echo tab($s)."<ul>";
$s[] = $rb;
} else echo "</li>";
}
echo drop($s[0]+1,&$s);
?>
|
| |
|
|
|