Index: taxonomy_menu.inc
===================================================================
RCS file: /pph/v6/modules/taxonomy_menu/taxonomy_menu.inc,v
retrieving revision 1.11
diff -u -r1.11 taxonomy_menu.inc
--- taxonomy_menu.inc	14 Oct 2008 04:45:17 -0000	1.11
+++ taxonomy_menu.inc	14 Oct 2008 05:08:50 -0000
@@ -1,5 +1,5 @@
 <?php
-// $Id: taxonomy_menu.inc,v 1.11 2008-10-14 04:45:17 caoky Exp $
+// $Id: taxonomy_menu.inc,v 1.8 2008-10-10 04:33:35 caoky Exp $
 
 /**
  * @author Jonathan Chaffer   <jchaffer@structureinteractive.com>
@@ -21,6 +21,10 @@
     TAXONOMY_MENU_NONE    => t('No'),
     TAXONOMY_MENU_NORMAL  => t('Normal')
   );
+  $options2 = array(
+    TAXONOMY_MENU_NONE    => t('No'),
+    TAXONOMY_MENU_NORMAL  => t('Yes')
+  );
 
   // If the Views module is enabled, add some special
   // new features
@@ -62,7 +66,36 @@
       '#title'          => t('Show this category in menu'),
       '#type'           => 'radios'
     );
-
+    $form[$vocab->vid]['taxonomy_menu_show_node_'. $vocab->vid] = array(
+      '#default_value'  => variable_get('taxonomy_menu_show_node_'. $vocab->vid, 1),
+      '#options'        => $options2,
+      '#title'          => t('Add node list in this category to the menu'),
+      '#type'           => 'radios'
+    );    
+    // Generate a list of possible parents (not including this item or descendants).
+    $itemtmp = array(
+      "link_title" => "",
+      "mlid" => 0,
+      "plid" => 0,
+      "menu_name"=> "primary-links",
+      "weight" => 0,
+      "link_path" => "",
+      "options" => array(),
+      "module" => "menu",
+      "expanded" => 0,
+      "hidden" => 0,
+      "has_children" => 0,
+    );
+    $optionsparent = menu_parent_options(menu_get_menus(),$itemtmp);
+    $default = variable_get('taxonomy_menu_parent_'. $vocab->vid, 'navigation:0');
+    $form[$vocab->vid]['taxonomy_menu_parent_'. $vocab->vid] = array(
+      '#type' => 'select',
+      '#title' => t('Parent item'),
+      '#default_value' => $default,
+      '#options' => $optionsparent,
+      '#description' => t('The maximum depth for an item and all its children is fixed at !maxdepth. Some menu items may not be available as parents if selecting them would exceed this limit.', array('!maxdepth' => MENU_MAX_DEPTH)),
+      '#attributes' => array('class' => 'menu-title-select'),
+    );
     // In case of View options selected, select Views
 //     if (module_exists('views')) {
 //       $form[$vocab->vid]['taxonomy_menu_show_view_'. $vocab->vid] = array(
@@ -76,7 +109,7 @@
 
   // General options
   $form['taxonomy_menu_display_page'] = array(
-    '#default_value'  => variable_get('taxonomy_menu_display_page', 'category'),
+    '#default_value'  => variable_get('taxonomy_menu_display_page', 'taxonomymenu'),
     '#description'    => t('How should be the first item on the menu? Example: categories/1/2/3, technology/1/2/3'),
     '#title'          => t('Module page'),
     '#type'           => 'textfield',
@@ -118,21 +151,151 @@
   variable_set('taxonomy_menu_display_num',         $form_state['values']['taxonomy_menu_display_num']);
   variable_set('taxonomy_menu_hide_empty',          $form_state['values']['taxonomy_menu_hide_empty']);
   variable_set('taxonomy_menu_display_descendants', $form_state['values']['taxonomy_menu_display_descendants']);
+  
 
+  // Clear the menu
+  _taxonomy_menu_moduledelete("taxonomy_menu");  
   // Save which category should be displayed on menu
   // and save which views it should use, in case Views
-  // mode is selected
+  // mode is selected    
   foreach (taxonomy_get_vocabularies() as $vocab) {
     variable_set('taxonomy_menu_show_'. $vocab->vid,
-      $form_state['values']['taxonomy_menu_show_'. $vocab->vid]);
+      $form_state['values']['taxonomy_menu_show_'. $vocab->vid]);    
+    variable_set('taxonomy_menu_show_node_'. $vocab->vid,
+      $form_state['values']['taxonomy_menu_show_node_'. $vocab->vid]);  
     variable_set('taxonomy_menu_show_views_'. $vocab->vid,
       $form_state['values']['taxonomy_menu_show_view_'. $vocab->vid]);
+    variable_set('taxonomy_menu_parent_'. $vocab->vid,
+      $form_state['values']['taxonomy_menu_parent_'. $vocab->vid]);          
+    if ($form_state['values']['taxonomy_menu_show_'. $vocab->vid] == 1) {
+    _taxonomy_menu_savevocab($vocab);    
+    }
   }
-
   // Rebuild the menu to include these features
   menu_rebuild();
 }
+function _taxonomy_menu_menuitem($newitempath, $newitemtitle, $newitemparent) {  
+  $originitem = array(
+          "link_title" => "",
+          "mlid" => 0,
+          "plid" => 0,
+          "menu_name"=> "primary-links",
+          "weight" => 0,
+          "link_path" => "",
+          "options" => array(),
+          "module" => "taxonomy_menu",
+          "expanded" => 0,
+          "hidden" => 0,
+          "has_children" => 0,
+        );    
+  $newitem = array(
+    "link_path" =>$newitempath,
+    "mlid" => 0,
+    "module" => "taxonomy_menu",
+    "has_children" => 0,
+    "options" =>  array(
+      "attributes" => array(
+        "title" => "",
+      ),
+    ),
+    "customized" => 1,
+    "original_item" => $originitem,
+    "link_title" => $newitemtitle,
+    "description" => "",
+    "expanded" => 0,
+    "parent" => $newitemparent,
+    "weight" => "0",
+    "hidden" => 0,
+    "plid" => "", // analyze this attribute later
+    "menu_name" => "", // analyze this attribute later
+  );
+  list($newitem['menu_name'], $newitem['plid']) = explode(':', $newitem['parent']);   
+  return $newitem;
+}
+/**
+ * _taxonomy_menu_moduledelete
+ *
+ * Delete a menu tree, or a path
+ */
+function _taxonomy_menu_moduledelete($modulename) {
+  if (isset($modulename)) {
+    db_query("DELETE FROM {menu_links} WHERE module = '%s'", $modulename);
+
+    // Update the has_children status of the parent.
+    _menu_update_parental_status($item);
+    menu_cache_clear($item['menu_name']);
+    _menu_clear_page_cache();    
+  }  
+}
+/**
+ * _taxonomy_menu_savevocab
+ *
+ * Save vocab to the menu
+ */
+function _taxonomy_menu_savevocab($vocab) {
+      // Add to the custom menu
+      $path =  variable_get('taxonomy_menu_display_page', 'taxonomymenu') .'/'. $vocab->vid;          
+      $vocabmenuitem = _taxonomy_menu_menuitem($path, $vocab->name, variable_get('taxonomy_menu_parent_'. $vocab->vid, 'navigation:0'));
+      $mlidvocabmenuitem = menu_link_save($vocabmenuitem);      
+      if (!$mlidvocabmenuitem) {
+        drupal_set_message(t('There was an error saving the menu link.'), 'error');
+      }  
+      else {      
+      variable_set('taxonomy_menu_vocab_mlid_' . $vocab->vid, $vocabmenuitem["mlid"]);
+      // Childs Oliver
+      // Create a menu array to store menu items
+      $itemlist = array();
+      $itemlist["0"] = $vocabmenuitem;      
+      $tree = taxonomy_get_tree($vocab->vid);      
+      $old_depth = -1;
+      $old_path = $path;
 
+      foreach ($tree as $term) {
+        
+        // build path
+        if ($term->depth <= $old_depth) {
+          $slashes_to_remove = $old_depth - $term->depth + 1;
+          for ($i = 0; $i < $slashes_to_remove; $i++) {
+            $old_path = substr($old_path, 0, strrpos($old_path, '/'));
+          }
+        }        
+        $path       = $old_path .'/'. $term->tid;        
+        $old_depth  = $term->depth;
+        $old_path   = $path;
+        
+        // check if term is available
+        $num = taxonomy_term_count_nodes($term->tid);        
+        if (variable_get('taxonomy_menu_hide_empty', FALSE) == FALSE or $num != 0) {      
+          // create the title
+          $name = $term->name;
+          if (variable_get('taxonomy_menu_display_num', FALSE) == TRUE) {
+            $name .= ' ('. $num .')';
+          }                     
+          // get parent item
+          $parentitem = isset($itemlist[$term->parents[0]]) ? $itemlist[$term->parents[0]] : $vocabmenuitem;
+          $menuitem = _taxonomy_menu_menuitem($path, $name, $parentitem["menu_name"] . ':' . $parentitem["mlid"]);            
+          if (!menu_link_save($menuitem)) {
+            drupal_set_message(t('There was an error saving the menu link.'), 'error');
+          } 
+          else {
+          // Save the menu item to menu list
+          $itemlist[$term->tid] = $menuitem;          
+          }          
+          if (variable_get('taxonomy_menu_show_node_'. $vocab->vid, 1) == 1) {
+            $nodelists = taxonomy_select_nodes_core(array($term->tid), 'or', 0);          
+            while ($node = db_fetch_object($nodelists)) {  
+              $nodepath =  $path . "/" . $node->nid;
+              // Add child nodes
+              $nodeitem = _taxonomy_menu_menuitem($nodepath, $node->title, $menuitem["menu_name"] . ':' . $menuitem["mlid"]);            
+              if (!menu_link_save($nodeitem)) {
+                drupal_set_message(t('There was an error saving the menu link.'), 'error');
+              }
+            }      
+          }
+        }
+      }  
+      }
+}
 /**
  * Implementation of hook_menu().
  *
@@ -147,18 +310,20 @@
     'page arguments'      => array('_taxonomy_menu_admin'),
     'path'                => 'admin/settings/taxonomy_menu',
     'title'               => t('Taxonomy Menu settings'),
-    'type'                => MENU_NORMAL_ITEM
+    'type'                => MENU_NORMAL_ITEM,
   );
+  
 
-  foreach (taxonomy_get_vocabularies() as $vocab) {
+  foreach (taxonomy_get_vocabularies() as $vocab) {  
     if (variable_get('taxonomy_menu_show_'. $vocab->vid, TAXONOMY_MENU_NONE)) {
-      $path =  variable_get('taxonomy_menu_display_page', 'category') .'/'. $vocab->vid;
+      $path =  variable_get('taxonomy_menu_display_page', 'taxonomymenu') .'/'. $vocab->vid;
       $items[$path] = array(
         'access arguments'    => array('access content'),
         'file'            => 'taxonomy_menu.inc',
         'page callback'   => '_taxonomy_menu_page',
-        'title'           => t($vocab->name),
-        'weight'          => $vocab->weight
+        'title'           => $vocab->name,
+        'weight'          => $vocab->weight,
+        'type' => MENU_CALLBACK,
       );
 
       $tree = taxonomy_get_tree($vocab->vid);
@@ -171,8 +336,9 @@
           for ($i = 0; $i < $slashes_to_remove; $i++) {
             $old_path = substr($old_path, 0, strrpos($old_path, '/'));
           }
-        }
-        $path       = $old_path .'/'. $term->tid;
+        }        
+        $path =  variable_get('taxonomy_menu_display_page', 'taxonomymenu') .'/term/'. $term->tid;
+        $path       = $old_path .'/'. $term->tid;        
         $old_depth  = $term->depth;
         $old_path   = $path;
 
@@ -182,19 +348,36 @@
         // If the number of children nodes of this term is
         // zero and the Hide Empty Terms option is enabled,
         // dont create the menu item
-        if (variable_get('taxonomy_menu_hide_empty', FALSE) == FALSE or $num != 0) {
-          $name = t($term->name);
+        if (variable_get('taxonomy_menu_hide_empty', FALSE) == FALSE or $num != 0) {                  
+          $name = $term->name;
           if (variable_get('taxonomy_menu_display_num', FALSE) == TRUE) {
             $name .= ' ('. $num .')';
-          }
+          }                     
           $items[$path] = array(
-            'access arguments' => array('access content'),
-            'file'            => 'taxonomy_menu.inc',
-            'page callback'   => '_taxonomy_menu_page',
+            'access arguments' => array($term, 'access content'),            
+            'access callback' => 'taxonomy_menu_access',            
+            'file'            => 'taxonomy.pages.inc',
+            'file path' => drupal_get_path('module', 'taxonomy'),
+            'page callback'   => 'taxonomy_term_page',
+            'page arguments' => array(2+$term->depth),
             'description'     => t($term->description),
             'title'           => $name,
             'weight'          => $term->weight,
+            'type' => MENU_CALLBACK,
           );
+          // Add node under category
+          $nodelists = taxonomy_select_nodes_core(array($term->tid), 'or', 0);          
+          while ($node = db_fetch_object($nodelists)) {            
+            $nodepath =  $path . "/" . $node->nid;
+            $items[$nodepath] = array(
+              'access arguments' => array($term, 'access content'),            
+              'access callback' => 'taxonomy_menu_access',              
+              'page callback'   => 'gotoNode',
+              'page arguments' => array(3+$term->depth),  
+              'title'           => $node->title,
+              'type' => MENU_CALLBACK,
+            );                      
+          }      
         }
       }
     }
@@ -202,6 +385,69 @@
 
   return $items;
 }
+/**
+ * Finds all nodes that match selected taxonomy conditions.
+ *
+ * @param $tids
+ *   An array of term IDs to match.
+ * @param $operator
+ *   How to interpret multiple IDs in the array. Can be "or" or "and".
+ * @param $depth
+ *   How many levels deep to traverse the taxonomy tree. Can be a nonnegative
+ *   integer or "all".
+ * @param $pager
+ *   Whether the nodes are to be used with a pager (the case on most Drupal
+ *   pages) or not (in an XML feed, for example).
+ * @param $order
+ *   The order clause for the query that retrieve the nodes.
+ * @return
+ *   A resource identifier pointing to the query results.
+ */
+ 
+function taxonomy_select_nodes_core($tids = array(), $operator = 'or', $depth = 0, $pager = TRUE, $order = 'n.sticky DESC, n.created DESC') {
+  if (count($tids) > 0) {
+    // For each term ID, generate an array of descendant term IDs to the right depth.
+    $descendant_tids = array();
+    if ($depth === 'all') {
+      $depth = NULL;
+    }
+    foreach ($tids as $index => $tid) {
+      $term = taxonomy_get_term($tid);
+      $tree = taxonomy_get_tree($term->vid, $tid, -1, $depth);
+      $descendant_tids[] = array_merge(array($tid), array_map('_taxonomy_get_tid_from_term', $tree));
+    }
+
+    if ($operator == 'or') {
+      $args = call_user_func_array('array_merge', $descendant_tids);
+      $placeholders = db_placeholders($args, 'int');
+      $sql = 'SELECT DISTINCT(n.nid), n.sticky, n.title, n.created FROM {node} n INNER JOIN {term_node} tn ON n.vid = tn.vid WHERE tn.tid IN ('. $placeholders .') AND n.status = 1 ORDER BY '. $order;
+      $sql_count = 'SELECT COUNT(DISTINCT(n.nid)) FROM {node} n INNER JOIN {term_node} tn ON n.vid = tn.vid WHERE tn.tid IN ('. $placeholders .') AND n.status = 1';
+    }
+    else {
+      $joins = '';
+      $wheres = '';
+      $args = array();
+      foreach ($descendant_tids as $index => $tids) {
+        $joins .= ' INNER JOIN {term_node} tn'. $index .' ON n.vid = tn'. $index .'.vid';
+        $wheres .= ' AND tn'. $index .'.tid IN ('. db_placeholders($tids, 'int') .')';
+        $args = array_merge($args, $tids);
+      }
+      $sql = 'SELECT DISTINCT(n.nid), n.sticky, n.title, n.created FROM {node} n '. $joins .' WHERE n.status = 1 '. $wheres .' ORDER BY '. $order;
+      $sql_count = 'SELECT COUNT(DISTINCT(n.nid)) FROM {node} n '. $joins .' WHERE n.status = 1 '. $wheres;
+    }    
+    //$sql = db_rewrite_sql($sql);    
+    $sql_count = db_rewrite_sql($sql_count);
+    if ($pager) {
+      $result = pager_query($sql, variable_get('default_nodes_main', 10), 0, $sql_count, $args);
+    }
+    else {
+      $result = db_query_range($sql, $args, 0, variable_get('feed_default_items', 10));
+    }
+  }
+
+  return $result;
+}
+
 
 /**
  * Generates the breadcumb for nodes that
@@ -214,9 +460,9 @@
  *   terms that this node have and are also
  *   menus
  */
-function _taxonomy_menu_node_view(&$node, &$vocabs) {
+function _taxonomy_menu_node_view(&$node, &$vocabs) {  
   foreach ($vocabs as $vid => $vocab) {
-    $path = variable_get('taxonomy_menu_display_page', 'category') .'/'. $vid;
+    $path = variable_get('taxonomy_menu_display_page', 'taxonomymenu') .'/'. $vid;
 
     $tree = taxonomy_get_tree($vid);
     $old_depth = -1;

