drastically reduce DB calls to build the menu
authorJeremy Laine <jeremy.laine@m4x.org>
Wed, 31 May 2006 19:02:36 +0000 (19:02 +0000)
committerJeremy Laine <jeremy.laine@m4x.org>
Wed, 31 May 2006 19:02:36 +0000 (19:02 +0000)
include/admin/menus.php
include/diogenes.barrel.inc.php

index e272780..269c4c7 100644 (file)
@@ -207,7 +207,9 @@ while (list($MID,$ordre,$title,$link,$PID,$ptitle) = mysql_fetch_row($res)) {
 }
 mysql_free_result($res);
 
-$filiation = $page->menuToRoot($MIDpere,array());
+// all menu entries from database
+$mcache = $page->menuRead();
+$filiation = $page->menuToRoot($mcache,$MIDpere,array());
 $menubar = array();
 foreach($filiation as $mykey=>$myval) {
   if ($myval == 0) {
index d217a35..e9dbbe4 100644 (file)
@@ -352,35 +352,36 @@ class DiogenesBarrel extends DiogenesPage
     if (!isset($this->table_menu))
       return;
    
+    // all menu entries from database
+    $mcache = $this->menuRead();
+
     // try to figure out the current MID from the current PID
     // and build filiation
     $filiation = array();
-    $res = $this->dbh->query("select MID from {$this->table_menu} where PID='$PID'");
-    while (list($MID) = mysql_fetch_row($res))
-      $filiation = $this->menuToRoot($MID, $filiation);
-    mysql_free_result($res);
+    foreach ($mcache as $mid => $mentry)
+    {
+      if ($mentry['pid'] == $PID)
+        $filiation = $this->menuToRoot($mcache, $mid, $filiation);
+    }
 
     // add the user-defined part of the menu
-    $this->menu = array_merge($this->menu,$this->menuRecurse(0,$filiation,0));
+    $this->menu = array_merge($this->menu,$this->menuRecurse($mcache,0,$filiation,0));
   }
 
 
   /** Return the filiation to get to the root element.
    *
+   * @param mcache
    * @param MID
    * @param path
    */
-  function menuToRoot($MID, $path) {
+  function menuToRoot($mcache, $MID, $path) {
     /* add ourself to the path */
     array_push($path,$MID);
 
     if ($MID) {
       /* recursion */
-      $res = $this->dbh->query("select MIDpere from {$this->table_menu} where MID=$MID");
-      list($MIDpere) = mysql_fetch_row($res);
-      mysql_free_result($res);
-
-      return $this->menuToRoot($MIDpere, $path);
+      return $this->menuToRoot($mcache, $mcache[$MID]['parent'], $path);
     } else {
       /* termination */
       return $path;
@@ -390,38 +391,64 @@ class DiogenesBarrel extends DiogenesPage
 
   /** Recursively add menu entries
    *
+   * @param mcache
    * @param MIDpere
    * @param filiation
    * @param level
    */
-  function menuRecurse($MIDpere, $filiation, $level) {
+  function menuRecurse($mcache, $MIDpere, $filiation, $level) {
     // the produced output
     $out = array();
 
-    $res = $this->dbh->query("select m.MID,m.title,m.link,m.PID ".
-                       "from {$this->table_menu} as m ".
-                       "where MIDpere=$MIDpere order by ordre");
-
-    while(list($mid,$title,$link,$pid) = mysql_fetch_row($res)) {
-      $location = $this->barrel->getLocation($pid);
+    foreach ($mcache[$MIDpere]['children'] as $mid)
+    {
+      $mentry = $mcache[$mid];
 //      echo "pid : $pid, location : $location<br/>";
-      $title = stripslashes($title);
-      $entry = htmlentities(stripslashes($title), ENT_QUOTES);
-      $link = $pid ? $this->urlSite($location) : $link;      
+      $entry = htmlentities(stripslashes($mentry['title']), ENT_QUOTES);
+      if ($mentry['pid'])
+      {
+        $link = $this->urlSite($this->barrel->getLocation($mentry['pid']));
+      } else {
+        $link = $mentry['link'];
+      }
       // decide whether this menu should be expanded
       $expanded = ($this->barrel->options->menu_min_level == 0) || 
                   ($level+1 < $this->barrel->options->menu_min_level) || 
                    in_array($mid, $filiation);
-      array_push($out, array($level, $entry, $link, $expanded));      
-      $out = array_merge($out, $this->menuRecurse($mid, $filiation, $level+1));
+      array_push($out, array($level, $entry, $link, $expanded));
+      $out = array_merge($out, $this->menuRecurse($mcache, $mid, $filiation, $level+1));
     }
 
-    // free MySQL result and return output
-    mysql_free_result($res);
     return $out;
   }
 
 
+  /** Read this barrel's menu entries from database.
+   */
+  function menuRead()
+  {
+    $menu = array();
+    $res = $this->dbh->query("select MID,MIDpere,title,link,PID from {$this->table_menu} order by ordre");
+    while (list($mid, $parent, $title, $link, $pid) = mysql_fetch_row($res))
+    {
+      $menu[$mid]['parent'] = $parent;
+      $menu[$mid]['title'] = $title;
+      $menu[$mid]['link'] = $link;
+      $menu[$mid]['title'] = $title;
+      $menu[$mid]['pid'] = $pid;
+      if (!is_array($menu[$mid]['children']))
+        $menu[$mid]['children'] = array();
+
+      // register this entry with its parent
+      if (!is_array($menu[$parent]['children']))
+        $menu[$parent]['children'] = array();
+      array_push($menu[$parent]['children'], $mid);
+    }
+    mysql_free_result($res);
+    return $menu;
+  }
+
+
   /** 
    * Break down a PATH_INFO into site, page id and file
    * Directories *must* be accessed with a final slash.