Einzelnen Beitrag anzeigen

Benutzerbild von S2B
S2B

Registriert seit: 1. Feb 2004
Ort: Aachen
1.268 Beiträge
 
#4

Re: Navigation mit Nested Sets

  Alt 28. Mai 2009, 19:32
Ich habe mich nun entschieden, das Problem auf PHP-Seite anzupacken. Nach ein paar Stunden Gefrickel hatte ich eine funktionierende Version:
Dieses Query liest den kompletten Navigationsbaum aus:
SQL-Code:
SELECT n.item_id, n.left_id, n.item_title, n.item_url, n.content_id, c.content_path,
   (COUNT(p.item_id) - 1) AS level
FROM s2b_navigation_items n
INNER JOIN s2b_navigation_items p
   ON n.left_id BETWEEN p.left_id AND p.right_id
LEFT JOIN s2b_content c
   ON c.content_id = n.content_id
WHERE n.nav_id = 1
GROUP BY n.item_id
ORDER BY n.left_id
Das Ergebnis packe ich in ein Array $tree, wobei die item_ids als Schlüssel verwendet werden.

Das zweite Query liefert den Pfad zur aktuell ausgewählten Seite (in diesem Fall #2):
SQL-Code:
SELECT p.item_id, p.left_id, p.right_id, p.content_id
FROM s2b_navigation_items p
INNER JOIN s2b_navigation_items n
   ON n.left_id BETWEEN p.left_id AND p.right_id
WHERE n.nav_id = 1
   AND n.content_id = 2
ORDER BY p.left_id
Das Ergebnis speichere ich analog zu oben in ein Array $path, zusätzlich werden die direkten Übereinstimmungen (= aktuell ausgewählte Seite) in ein separates Array $selected gespeichert.

Anschließend generiere ich das Array $items, also die fertige Navigation, folgendermaßen:
Code:
$items = array();
foreach ($tree as $item_id => $item_data)
{
   $item_level = $item_data['level'];
   $item_left_id = $item_data['left_id'];

   // Root-Ebene immer anzeigen
   if ($item_level == 0)
   {
      $items[$item_id] = $item_data;
      continue;
   }

   // Direkte Nachkommen der aktuellen Seite anzeigen (unterstützt mehrere Navigationspunkte für eine Seite)
   foreach ($selected as $selected_id)
   {
      if ($item_left_id > $path[$selected_id]['left_id'] && $item_left_id < $path[$selected_id]['right_id'] && $item_level == $tree[$selected_id]['level'] + 1)
      {
         $items[$item_id] = $item_data;
         continue 2;
      }
   }

   // Nachbarelemente auf dem Pfad anzeigen
   $last_id = null;
   foreach ($path as $path_id => $path_data)
   {
      if (isset($last_id) && isset($tree[$path_id]))
      {
         if ($item_left_id > $path[$last_id]['left_id'] && $item_left_id < $path[$last_id]['right_id'] && $item_level == $tree[$path_id]['level'])
         {
            $items[$item_id] = $item_data;
            continue 2;
         }
      }

      $last_id = $path_id;
   }
}
Zum Schluss wird das ganze über die Template-Engine ausgegeben - es funktioniert tadellos.
Simon Praetorius
Gruß
S2B
  Mit Zitat antworten Zitat