/[drupal]/contributions/modules/category/category.inc
ViewVC logotype

Diff of /contributions/modules/category/category.inc

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph | View Patch Patch

revision 1.70, Mon Jul 21 09:30:48 2008 UTC revision 1.71, Wed Aug 5 04:52:53 2009 UTC
# Line 1  Line 1 
1  <?php  <?php
2  // $Id$  // $Id: category.inc,v 1.70 2008/07/21 09:30:48 jaza Exp $
3    
4  /**  /**
5   * @file   * @file
# Line 18  Line 18 
18   *   If set, return only those containers associated with this node type.   *   If set, return only those containers associated with this node type.
19   */   */
20  function category_get_containers($type = NULL) {  function category_get_containers($type = NULL) {
21    $type_sql = $type ? " WHERE nt.type = '%s'" : "";    $cache_key = 'c_get_conts'. $type;
22    $result = db_query(db_rewrite_sql("SELECT n.nid, n.title, cn.*, c.weight, c.depth, n.status, nt.type FROM {category_cont} cn INNER JOIN {category} c ON cn.cid = c.cid INNER JOIN {node} n ON cn.cid = n.nid LEFT JOIN {category_cont_node_types} nt ON cn.cid = nt.cid". $type_sql ." ORDER BY c.weight, n.title", 'n', 'nid'), $type);    $containers = category_cache_op('get', 0, $cache_key);
23      if (!isset($containers)) {
24    
25    $containers = array();      $type_sql = $type ? " WHERE nt.type = '%s'" : "";
26    $node_types = array();      $result = db_query(db_rewrite_sql("SELECT n.nid, n.title, cn.*, c.weight, c.depth, n.status, nt.type FROM {category_cont} cn INNER JOIN {category} c ON cn.cid = c.cid INNER JOIN {node} n ON cn.cid = n.nid LEFT JOIN {category_cont_node_types} nt ON cn.cid = nt.cid". $type_sql ." ORDER BY c.weight, n.title", 'n', 'nid'), $type);
27    while ($container = db_fetch_object($result)) {  
28      // If no node types are associated with a container, the LEFT JOIN will      $containers = array();
29      // return a NULL value for type.      $node_types = array();
30      if (isset($container->type)) {      while ($container = db_fetch_object($result)) {
31        $node_types[$container->cid][$container->type] = $container->type;        // If no node types are associated with a container, the LEFT JOIN will
32        unset($container->type);        // return a NULL value for type.
33        $container->nodes = $node_types[$container->cid];        if (isset($container->type)) {
34      }          $node_types[$container->cid][$container->type] = $container->type;
35      elseif (!isset($container->nodes)) {          unset($container->type);
36        $container->nodes = array();          $container->nodes = $node_types[$container->cid];
37      }        }
38          elseif (!isset($container->nodes)) {
39      if (empty($container->admin_title)) {          $container->nodes = array();
40        $container->admin_title = '';        }
41        $container->has_admin_title = FALSE;  
42      }        if (empty($container->admin_title)) {
43      else {          $container->admin_title = '';
44        $container->has_admin_title = TRUE;          $container->has_admin_title = FALSE;
45          }
46          else {
47            $container->has_admin_title = TRUE;
48          }
49          $containers[$container->cid] = $container;
50      }      }
51      $containers[$container->cid] = $container;  
52        category_cache_op('set', 0, $cache_key, $containers);
53    }    }
54    
55    return $containers;    return $containers;
# Line 52  function category_get_containers($type = Line 59  function category_get_containers($type =
59   * Find all categories associated to the given node, within one container.   * Find all categories associated to the given node, within one container.
60   */   */
61  function category_node_get_categories_by_container($node, $cnid, $key = 'cid') {  function category_node_get_categories_by_container($node, $cnid, $key = 'cid') {
62    $result = db_query(db_rewrite_sql('SELECT c.*, n.title FROM {category} c INNER JOIN {category_node} r ON c.cid = r.cid INNER JOIN {node} n ON c.cid = n.nid WHERE c.cnid = %d AND r.vid = %d AND n.status = 1 ORDER BY c.weight'), $cnid, $node->vid);    $cache_key = 'c_node_get_cats_by_cont'. $node->vid .':'. $cnid .':'. $key;
63    $categories = array();    $categories = category_cache_op('get', $node->nid, $cache_key);
64    while ($category = db_fetch_object($result)) {    if (!isset($categories)) {
65      $categories[$category->$key] = $category;  
66        $result = db_query(db_rewrite_sql('SELECT c.*, n.title FROM {category} c INNER JOIN {category_node} r ON c.cid = r.cid INNER JOIN {node} n ON c.cid = n.nid WHERE c.cnid = %d AND r.vid = %d AND n.status = 1 ORDER BY c.weight'), $cnid, $node->vid);
67        $categories = array();
68        while ($category = db_fetch_object($result)) {
69          $categories[$category->$key] = $category;
70        }
71    
72        category_cache_op('set', $node->nid, $cache_key, $categories);
73    }    }
74    return $categories;    return $categories;
75  }  }
# Line 63  function category_node_get_categories_by Line 77  function category_node_get_categories_by
77  /**  /**
78   * Find all categories associated to the given node, ordered by container and category weight.   * Find all categories associated to the given node, ordered by container and category weight.
79   */   */
80  function category_node_get_categories($node, $key = 'cid', $reset = FALSE) {  function category_node_get_categories($node, $key = 'cid') {
81    static $categories = array();    $cache_key = 'cat_node_get_cats'. $node->vid .':'. $key;
82      $categories = category_cache_op('get', $node->nid, $cache_key);
83      if (!isset($categories)) {
84    
85    if (!isset($categories[$node->vid]) || $reset) {      $categories = array();
     $categories[$node->vid] = array();  
86    
87      $result = db_query(db_rewrite_sql('SELECT n.nid, nr.teaser AS description, r.vid AS node_id, c.*, n.title FROM {category} c INNER JOIN {category_node} r ON c.cid = r.cid INNER JOIN {category} cn ON c.cnid = cn.cid INNER JOIN {node} n ON c.cid = n.nid INNER JOIN {node_revisions} nr ON n.vid = nr.vid INNER JOIN {node} cnn ON cn.cid = cnn.nid WHERE n.status = 1 AND r.vid = %d ORDER BY cn.weight, cnn.title, c.weight, n.title', 'n', 'nid'), $node->vid);      $result = db_query(db_rewrite_sql('SELECT n.nid, nr.teaser AS description, r.vid AS node_id, c.*, n.title FROM {category} c INNER JOIN {category_node} r ON c.cid = r.cid INNER JOIN {category} cn ON c.cnid = cn.cid INNER JOIN {node} n ON c.cid = n.nid INNER JOIN {node_revisions} nr ON n.vid = nr.vid INNER JOIN {node} cnn ON cn.cid = cnn.nid WHERE n.status = 1 AND r.vid = %d ORDER BY cn.weight, cnn.title, c.weight, n.title', 'n', 'nid'), $node->vid);
88    
89      while ($category = db_fetch_object($result)) {      while ($category = db_fetch_object($result)) {
90        $categories[$node->vid][$category->$key] = $category;        $categories[$category->$key] = $category;
91      }      }
   }  
92    
93    return $categories[$node->vid];      category_cache_op('set', $node->nid, $cache_key, $categories);
94      }
95      return $categories;
96  }  }
97    
98  /**  /**
# Line 84  function category_node_get_categories($n Line 100  function category_node_get_categories($n
100   */   */
101  function category_get_related($cid, $key = 'cid') {  function category_get_related($cid, $key = 'cid') {
102    if ($cid) {    if ($cid) {
103      $result = db_query(db_rewrite_sql('SELECT c.*, n.title, cid1, cid2 FROM {category_relation}, {category} c, {node} n WHERE (c.cid = cid1 OR c.cid = cid2) AND (cid1 = %d OR cid2 = %d) AND c.cid = n.nid AND c.cid != %d AND n.status = 1 ORDER BY c.weight, n.title'), $cid, $cid, $cid);      $cache_key = 'cat_get_related'. $key;
104      $related = array();      $related = category_cache_op('get', $cid, $cache_key);
105      while ($category = db_fetch_object($result)) {      if (!isset($related)) {
106        $related[$category->$key] = $category;  
107          $result = db_query(db_rewrite_sql('SELECT c.*, n.title, cid1, cid2 FROM {category_relation}, {category} c, {node} n WHERE (c.cid = cid1 OR c.cid = cid2) AND (cid1 = %d OR cid2 = %d) AND c.cid = n.nid AND c.cid != %d AND n.status = 1 ORDER BY c.weight, n.title'), $cid, $cid, $cid);
108          $related = array();
109          while ($category = db_fetch_object($result)) {
110            $related[$category->$key] = $category;
111          }
112    
113          category_cache_op('set', $cid, $cache_key, $related);
114      }      }
115      return $related;      return $related;
116    }    }
# Line 100  function category_get_related($cid, $key Line 123  function category_get_related($cid, $key
123   * Find all parents of a given category ID.   * Find all parents of a given category ID.
124   * This function will return the parents in an indexed array sorted by the parents' weight and title.   * This function will return the parents in an indexed array sorted by the parents' weight and title.
125   */   */
126  function category_get_parents($cid, $key = 'cid', $distant = TRUE, $reset = FALSE) {  function category_get_parents($cid, $key = 'cid', $distant = TRUE) {
   static $parents, $distant_parents;  
   
127    if (!$cid) {    if (!$cid) {
128      return array();      return array();
129    }    }
130    
131    if (($distant && !isset($distant_parents)) || (!$distant && !isset($parents)) || $reset) {    $cache_key = 'cat_get_parents'. ($distant ? 'd' : 'n');
132      $parents = category_cache_op('get', 0, $cache_key);
133      if (!isset($parents)) {
134    
135      $distant_sql = $distant ? '' : ' AND (c.cnid = cc.cnid OR c.cnid = 0)';      $distant_sql = $distant ? '' : ' AND (c.cnid = cc.cnid OR c.cnid = 0)';
136      $result = db_query(db_rewrite_sql('SELECT c.*, h.cid AS child, n.title, cn.admin_title FROM {category} c INNER JOIN {category_hierarchy} h ON c.cid = h.parent INNER JOIN {node} n ON c.cid = n.nid LEFT JOIN {category_cont} cn ON c.cid = cn.cid INNER JOIN {category} cc ON h.cid = cc.cid WHERE n.status = 1'. $distant_sql .' ORDER BY c.weight, n.title'), $cid);      $result = db_query(db_rewrite_sql('SELECT c.*, h.cid AS child, n.title, cn.admin_title FROM {category} c INNER JOIN {category_hierarchy} h ON c.cid = h.parent INNER JOIN {node} n ON c.cid = n.nid LEFT JOIN {category_cont} cn ON c.cid = cn.cid INNER JOIN {category} cc ON h.cid = cc.cid WHERE n.status = 1'. $distant_sql .' ORDER BY c.weight, n.title'), $cid);
137      if ($distant) {      $parents = array();
       $distant_parents = array();  
     }  
     else {  
       $parents = array();  
     }  
138      while ($parent = db_fetch_object($result)) {      while ($parent = db_fetch_object($result)) {
139        if (empty($parent->admin_title)) {        if (empty($parent->admin_title)) {
140          $parent->admin_title = $parent->title;          $parent->admin_title = $parent->title;
141        }        }
142        if ($distant) {        $parents[$parent->child][$parent->$key] = $parent;
         $distant_parents[$parent->child][$parent->$key] = $parent;  
       }  
       else {  
         $parents[$parent->child][$parent->$key] = $parent;  
       }  
143      }      }
144    
145        category_cache_op('set', 0, $cache_key, $parents);
146    }    }
147    
148    $no_parent = new StdClass();    $no_parent = new StdClass();
# Line 137  function category_get_parents($cid, $key Line 153  function category_get_parents($cid, $key
153    $no_parent->title = '';    $no_parent->title = '';
154    $no_parent->admin_title = '';    $no_parent->admin_title = '';
155    $no_parent->child = $cid;    $no_parent->child = $cid;
156    return $distant ? (isset($distant_parents[$cid]) ? $distant_parents[$cid] : array(0 => $no_parent)) : (isset($parents[$cid]) ? $parents[$cid] : array(0 => $no_parent));    return isset($parents[$cid]) ? $parents[$cid] : array(0 => $no_parent);
157  }  }
158    
159  /**  /**
# Line 159  function category_get_parents_all($cid, Line 175  function category_get_parents_all($cid,
175  /**  /**
176   * Find all children of a category ID.   * Find all children of a category ID.
177   */   */
178  function category_get_children($cid, $cnid = 0, $key = 'cid', $reset = FALSE) {  function category_get_children($cid, $cnid = 0, $key = 'cid') {
   static $children;  
179    
180    if ($cnid) {    if ($cnid) {
181      $result = db_query(db_rewrite_sql('SELECT c.*, n.title FROM {category} c INNER JOIN {category_hierarchy} h ON c.cid = h.cid INNER JOIN {node} n ON c.cid = n.nid WHERE h.parent = %d AND n.status = 1 AND c.cnid = %d ORDER BY c.weight, n.title'), $cid, $cnid);      $cache_key = 'cat_get_children_cn'. $cnid .':'. $key;
182        $children = category_cache_op('get', $cid, $cache_key);
183        if (!isset($children)) {
184    
185          $result = db_query(db_rewrite_sql('SELECT c.*, n.title FROM {category} c INNER JOIN {category_hierarchy} h ON c.cid = h.cid INNER JOIN {node} n ON c.cid = n.nid WHERE h.parent = %d AND n.status = 1 AND c.cnid = %d ORDER BY c.weight, n.title'), $cid, $cnid);
186    
187          $children = array();
188          while ($category = db_fetch_object($result)) {
189            $children[$category->$key] = $category;
190          }
191    
192      $results = array();        category_cache_op('set', $cid, $cache_key, $children);
     while ($category = db_fetch_object($result)) {  
       $results[$category->$key] = $category;  
193      }      }
194        return $children;
     return $results;  
195    }    }
196    elseif (!isset($children) || $reset) {  
197      $cache_key = 'cat_get_children_c0'. $key;
198      $children = category_cache_op('get', 0, $cache_key);
199      if (!isset($children)) {
200    
201      $result = db_query(db_rewrite_sql('SELECT c.*, h.parent, n.title FROM {category} c INNER JOIN {category_hierarchy} h ON c.cid = h.cid INNER JOIN {node} n ON c.cid = n.nid WHERE n.status = 1 ORDER BY c.weight, n.title'), $cid);      $result = db_query(db_rewrite_sql('SELECT c.*, h.parent, n.title FROM {category} c INNER JOIN {category_hierarchy} h ON c.cid = h.cid INNER JOIN {node} n ON c.cid = n.nid WHERE n.status = 1 ORDER BY c.weight, n.title'), $cid);
202    
203      $children = array();      $children = array();
204      while ($category = db_fetch_object($result)) {      while ($category = db_fetch_object($result)) {
205        $children[$category->parent][$category->$key] = $category;        $children[$category->parent][$category->$key] = $category;
206      }      }
207    
208        category_cache_op('set', 0, $cache_key, $children);
209    }    }
210    
211    return isset($children[$cid]) ? $children[$cid] : array();    return isset($children[$cid]) ? $children[$cid] : array();
# Line 209  function category_get_children($cid, $cn Line 236  function category_get_children($cid, $cn
236   *   to have "depth" and "parents" attributes in addition to its normal ones.   *   to have "depth" and "parents" attributes in addition to its normal ones.
237   */   */
238  function category_get_tree($cnid, $parent = NULL, $depth = -1, $max_depth = NULL, $distant = FALSE) {  function category_get_tree($cnid, $parent = NULL, $depth = -1, $max_depth = NULL, $distant = FALSE) {
   static $children, $parents, $categories;  
   
239    if (empty($cnid) && $depth == -1) {    if (empty($cnid) && $depth == -1) {
240      $distant = TRUE;      $distant = TRUE;
241    }    }
# Line 222  function category_get_tree($cnid, $paren Line 247  function category_get_tree($cnid, $paren
247    
248    // We cache trees, so it's not CPU-intensive to call get_tree() on a category    // We cache trees, so it's not CPU-intensive to call get_tree() on a category
249    // and its children, too.    // and its children, too.
250    if (!isset($children[$cnid])) {    $cache_key = 'cat_get_tree'. $depth .':'. ($distant ? 'd' : 'n');
251      $data = category_cache_op('get', $cnid, $cache_key);
252      if (isset($data)) {
253        $children = $data['children'];
254        $categories = $data['categories'];
255        $parents = $data['parents'];
256      }
257      else {
258    
259      $distant_sql = ($distant) ? '' : 'AND c.cnid = %d ';      $distant_sql = ($distant) ? '' : 'AND c.cnid = %d ';
260    
261      $children[$cnid] = array();      $children = array();
262        $categories = array();
263        $parents = array();
264      $result = db_query(db_rewrite_sql('SELECT c.cid, c.cnid, c.weight, c.depth, h.parent, n.title, cn.admin_title FROM {category} c INNER JOIN {category_hierarchy} h ON c.cid = h.cid INNER JOIN {node} n ON c.cid = n.nid LEFT JOIN {category_cont} cn ON c.cid = cn.cid LEFT JOIN {category} c2 ON h.parent = c2.cid WHERE (c2.cid IS NOT NULL OR h.parent = 0) AND n.status = 1 '. $distant_sql .'ORDER BY c.weight, n.title', 'n', 'nid'), $cnid);      $result = db_query(db_rewrite_sql('SELECT c.cid, c.cnid, c.weight, c.depth, h.parent, n.title, cn.admin_title FROM {category} c INNER JOIN {category_hierarchy} h ON c.cid = h.cid INNER JOIN {node} n ON c.cid = n.nid LEFT JOIN {category_cont} cn ON c.cid = cn.cid LEFT JOIN {category} c2 ON h.parent = c2.cid WHERE (c2.cid IS NOT NULL OR h.parent = 0) AND n.status = 1 '. $distant_sql .'ORDER BY c.weight, n.title', 'n', 'nid'), $cnid);
265    
266      while ($category = db_fetch_object($result)) {      while ($category = db_fetch_object($result)) {
# Line 236  function category_get_tree($cnid, $paren Line 271  function category_get_tree($cnid, $paren
271          }          }
272        }        }
273    
274        $children[$cnid][$category->parent][] = $category->cid;        $children[$category->parent][] = $category->cid;
275        $categories[$cnid][$category->cid] = $category;        $categories[$category->cid] = $category;
276        $parents[$cnid][$category->cid][] = $category->parent;        $parents[$category->cid][] = $category->parent;
277      }      }
278        category_cache_op('set', $cnid, $cache_key, array('children' => $children, 'categories' => $categories, 'parents' => $parents));
279    }    }
280    
281    $max_depth = (is_null($max_depth) && isset($children[$cnid])) ? count($children[$cnid]) : $max_depth;    $max_depth = (is_null($max_depth) && !empty($children)) ? count($children) : $max_depth;
282    $tree = array();    $tree = array();
283    if (!empty($children[$cnid]) && !empty($children[$cnid][$parent])) {    if (!empty($children) && !empty($children[$parent])) {
284      foreach ($children[$cnid][$parent] as $child) {      foreach ($children[$parent] as $child) {
285        if ($max_depth > $depth) {        if ($max_depth > $depth) {
286          $cat = drupal_clone($categories[$cnid][$child]);          $cat = drupal_clone($categories[$child]);
287          $cat->depth = $depth;          $cat->depth = $depth;
288          // The "parent" attribute is not useful, as it would show one parent only.          // The "parent" attribute is not useful, as it would show one parent only.
289          unset($cat->parent);          unset($cat->parent);
290          $cat->parents = $parents[$cnid][$child];          $cat->parents = $parents[$child];
291    
292          if (!$cat->cnid && empty($cat->admin_title)) {          if (!$cat->cnid && empty($cat->admin_title)) {
293            $cat->admin_title = $cat->title;            $cat->admin_title = $cat->title;
294          }          }
295          $tree[] = $cat;          $tree[] = $cat;
296    
297          if (!empty($children[$cnid][$child])) {          if (!empty($children[$child])) {
298            $tree = array_merge($tree, category_get_tree($cnid, $child, $depth, $max_depth, $distant));            $tree = array_merge($tree, category_get_tree($cnid, $child, $depth, $max_depth, $distant));
299          }          }
300        }        }
# Line 273  function category_get_tree($cnid, $paren Line 309  function category_get_tree($cnid, $paren
309   */   */
310  function category_get_synonyms($cid) {  function category_get_synonyms($cid) {
311    if ($cid) {    if ($cid) {
312      $synonyms = array();      $cache_key = 'cat_get_synonyms';
313      $result = db_query('SELECT name FROM {category_synonym} WHERE cid = %d', $cid);      $synonyms = category_cache_op('get', $cid, $cache_key);
314      while ($synonym = db_fetch_array($result)) {      if (!isset($synonyms)) {
315        $synonyms[] = $synonym['name'];  
316          $synonyms = array();
317          $result = db_query('SELECT name FROM {category_synonym} WHERE cid = %d', $cid);
318          while ($synonym = db_fetch_array($result)) {
319            $synonyms[] = $synonym['name'];
320          }
321    
322        category_cache_op('set', $cid, $cache_key, $synonyms);
323      }      }
324      return $synonyms;      return $synonyms;
325    }    }
# Line 296  function category_get_synonym_root($syno Line 339  function category_get_synonym_root($syno
339   * Given a category id, count the number of published nodes in it.   * Given a category id, count the number of published nodes in it.
340   */   */
341  function category_category_count_nodes($cid, $type = 0) {  function category_category_count_nodes($cid, $type = 0) {
342    static $count;    $cache_key = 'cat_cat_count_nodes'. $type;
343      $count = category_cache_op('get', 0, $cache_key);
344    if (!isset($count[$type])) {    if (!isset($count)) {
345      // $type == 0 always evaluates true if $type is a string      // $type == 0 always evaluates true if $type is a string
346      if (is_numeric($type)) {      if (is_numeric($type)) {
347        $result = db_query(db_rewrite_sql('SELECT c.cid, COUNT(n.nid) AS cnt FROM {category_node} c INNER JOIN {node} n ON c.nid = n.nid WHERE n.status = 1 GROUP BY c.cid'));        $result = db_query(db_rewrite_sql('SELECT c.cid, COUNT(n.nid) AS cnt FROM {category_node} c INNER JOIN {node} n ON c.nid = n.nid WHERE n.status = 1 GROUP BY c.cid'));
# Line 307  function category_category_count_nodes($ Line 350  function category_category_count_nodes($
350        $result = db_query(db_rewrite_sql("SELECT c.cid, COUNT(n.nid) AS cnt FROM {category_node} c INNER JOIN {node} n ON c.nid = n.nid WHERE n.status = 1 AND n.type = '%s' GROUP BY c.cid"), $type);        $result = db_query(db_rewrite_sql("SELECT c.cid, COUNT(n.nid) AS cnt FROM {category_node} c INNER JOIN {node} n ON c.nid = n.nid WHERE n.status = 1 AND n.type = '%s' GROUP BY c.cid"), $type);
351      }      }
352      while ($category = db_fetch_object($result)) {      while ($category = db_fetch_object($result)) {
353        $count[$type][$category->cid] = $category->cnt;        $count[$category->cid] = $category->cnt;
354      }      }
355        category_cache_op('set', 0, $cache_key, $count);
356    }    }
357    $children_count = 0;    $children_count = 0;
358    foreach (_category_category_children($cid) as $c) {    foreach (_category_category_children($cid) as $c) {
359      $children_count += category_category_count_nodes($c, $type);      $children_count += category_category_count_nodes($c, $type);
360    }    }
361    return $children_count + (isset($count[$type][$cid]) ? $count[$type][$cid] : 0);    return $children_count + (isset($count[$cid]) ? $count[$cid] : 0);
362  }  }
363    
364  /**  /**
365   * Helper for category_category_count_nodes().   * Helper for category_category_count_nodes().
366   */   */
367  function _category_category_children($cid) {  function _category_category_children($cid) {
368    static $children;    $cache_key = 'cat_cat_childr';
369      $children = category_cache_op('get', 0, $cache_key);
370    if (!isset($children)) {    if (!isset($children)) {
371      $result = db_query('SELECT cid, parent FROM {category_hierarchy}');      $result = db_query('SELECT cid, parent FROM {category_hierarchy}');
372      while ($category = db_fetch_object($result)) {      while ($category = db_fetch_object($result)) {
373        $children[$category->parent][] = $category->cid;        $children[$category->parent][] = $category->cid;
374      }      }
375        category_cache_op('set', 0, $cache_key, $children);
376    }    }
377    return isset($children[$cid]) ? $children[$cid] : array();    return isset($children[$cid]) ? $children[$cid] : array();
378  }  }
# Line 362  function category_get_category_by_name($ Line 407  function category_get_category_by_name($
407   *   *
408   * @return   * @return
409   *   The container object with all of its metadata, if exists, NULL otherwise.   *   The container object with all of its metadata, if exists, NULL otherwise.
410   *   Results are statically cached.   *   Results are cached.
411   */   */
412  function category_get_container($cnid) {  function category_get_container($cnid) {
413    static $containers = array();    $cache_key = 'cat_get_cont';
414      $container = category_cache_op('get', $cnid, $cache_key);
415    if (!isset($containers[$cnid])) {    if (!isset($container)) {
416      // Initialize so if this container does not exist, we have      // Initialize so if this container does not exist, we have
417      // that cached, and we will not try to load this later.      // that cached, and we will not try to load this later.
418      $containers[$cnid] = FALSE;      $container = FALSE;
419      // Try to load the data and fill up the object.      // Try to load the data and fill up the object.
420      $result = db_query(db_rewrite_sql('SELECT n.nid, cn.*, n.title, c.weight, c.depth, ct.type, c.weight AS cont_weight, c.depth AS cont_depth FROM {category} c INNER JOIN {category_cont} cn ON c.cid = cn.cid INNER JOIN {node} n ON c.cid = n.nid LEFT JOIN {category_cont_node_types} ct ON c.cid = ct.cid WHERE c.cid = %d ORDER BY c.weight, n.title', 'n', 'nid'), $cnid);      $result = db_query(db_rewrite_sql('SELECT n.nid, cn.*, n.title, c.weight, c.depth, ct.type, c.weight AS cont_weight, c.depth AS cont_depth FROM {category} c INNER JOIN {category_cont} cn ON c.cid = cn.cid INNER JOIN {node} n ON c.cid = n.nid LEFT JOIN {category_cont_node_types} ct ON c.cid = ct.cid WHERE c.cid = %d ORDER BY c.weight, n.title', 'n', 'nid'), $cnid);
421      $node_types = array();      $node_types = array();
# Line 392  function category_get_container($cnid) { Line 437  function category_get_container($cnid) {
437          $cont->has_admin_title = TRUE;          $cont->has_admin_title = TRUE;
438        }        }
439    
440        $containers[$cnid] = $cont;        $container = $cont;
441      }      }
442        category_cache_op('set', $cnid, $cache_key, $container);
443    }    }
444    
445    // Return NULL if this vocabulary does not exist.    // Return NULL if this vocabulary does not exist.
446    return (isset($containers[$cnid]) ? $containers[$cnid] : NULL);    return (!empty($container) ? $container : NULL);
447  }  }
448    
449  /**  /**
# Line 405  function category_get_container($cnid) { Line 451  function category_get_container($cnid) {
451   *   *
452   * @param $cid   * @param $cid
453   *   The node/category ID of the category to be retrieved.   *   The node/category ID of the category to be retrieved.
  * @param $reset  
  *   Whether or not to reset the cache of categories. Default is FALSE.  
454   *   *
455   * @return   * @return
456   *   Populated category object if the category is found, NULL otherwise.   *   Populated category object if the category is found, NULL otherwise.
457   */   */
458  function category_get_category($cid, $reset = FALSE) {  function category_get_category($cid) {
459    static $categories = array();    $cache_key = 'cat_get_cat';
460      $category = category_cache_op('get', $cid, $cache_key);
461    if (!isset($categories[$cid])) {    if (!isset($category)) {
462      $categories[$cid] = db_fetch_object(db_query('SELECT n.nid, n.title, c.* FROM {category} c INNER JOIN {node} n ON c.cid = n.nid WHERE cid = %d', $cid));      $category = db_fetch_object(db_query('SELECT n.nid, n.title, c.* FROM {category} c INNER JOIN {node} n ON c.cid = n.nid WHERE cid = %d', $cid));
463        if (empty($category)) {
464          $category = FALSE;
465        }
466        category_cache_op('set', $cid, $cache_key, $category);
467    }    }
468    
469    return (isset($categories[$cid]) ? $categories[$cid] : NULL);    return (!empty($category) ? $category : NULL);
470  }  }
471    
472  /**  /**
# Line 490  function category_select_nodes($cids = a Line 538  function category_select_nodes($cids = a
538  /**  /**
539   * Accepts the result of a pager_query() call, such as that performed by   * Accepts the result of a pager_query() call, such as that performed by
540   * category_select_nodes(), and formats each node along with a pager.   * category_select_nodes(), and formats each node along with a pager.
541  */   */
542  function category_render_nodes($result, $category_display) {  function category_render_nodes($result, $category_display = NULL) {
543    $output = '';    $output = '';
544    $has_rows = FALSE;    $has_rows = FALSE;
545    while ($node = db_fetch_object($result)) {    while ($node = db_fetch_object($result)) {
# Line 534  function category_categories_parse_strin Line 582  function category_categories_parse_strin
582    }    }
583    return $categories;    return $categories;
584  }  }
585    
586    /**
587     * Central caching function for all kinds of node-related category data,
588     * so that all data for a given node may be loaded by single query from
589     * cache table into static variable, and then returned by various API
590     * functions without any queries needed. The cache is stored per-node,
591     * and flushed only when given node is saved or deleted. The $nid of '0'
592     * is used for global summary-data, and flushed on every node save.
593     * While saving a category or container, we flush the whole cache, as
594     * this affects the whole hiearchy, and happens rarely. This should not
595     * be used for data affected by other factors (such as current user's
596     * permissions), unless the condition is incorporated into the cache key.
597     *
598     * @param op
599     *   Operation to be performed - either 'get', 'set', or 'flush'.
600     *
601     * @param nid
602     *   Node id to handle data for. 0 is general data, 'all' flushes all.
603     *
604     * @param key
605     *   Name of node-data subset to work with. (Usually an API function identificator.)
606     *
607     * @param data
608     *   Data for the 'set' operation (will get added to the existing per-node record).
609     *
610     * @return
611     *   Cached data, or NULL if none.
612     */
613    function category_cache_op($op, $nid, $key = '', $data = NULL) {
614      static $cache;
615      if (!isset($cache)) {
616        $cache = array('n' => array(), 'g' => array());
617      }
618    
619      // Flush cache if requested
620      if ($op == 'flush') {
621        if ($nid === 'all') {
622          // Total flush: Empty {cache_category} and static cache entirely
623          cache_clear_all('*', 'cache_category', TRUE);
624          $cache = array('n' => array(), 'g' => array());
625        }
626        else {
627          // Node flush: Delete entries for given node
628          cache_clear_all('n'. $nid, 'cache_category');
629          unset($cache['n'][$nid]);
630          // Delete also all entries for global data, because we don't really
631          // know how these might be affected.
632          cache_clear_all('g', 'cache_category', TRUE);
633          $cache['g'] = array();
634        }
635        return;
636      }
637    
638      // For global data, we use the $key instead of $nid as identificator, for
639      // better granularity of data loading (as these are larger pieces). Both
640      // node/global parts of the cache are separated, to allow for all-global
641      // flush.
642      $part = ($nid == 0) ? 'g' : 'n';
643      $id = ($nid == 0) ? $key : $nid;
644    
645      // Load existing record, if not available in static variable already.
646      if (!isset($cache[$part][$id])) {
647        $entry = cache_get($part . $id, 'cache_category');
648        if ($entry) {
649          $cache[$part][$id] = $entry->data;
650        }
651        else {
652          $cache[$part][$id] = array();
653        }
654      }
655    
656      // Save new data if required.
657      if ($op == 'set') {
658        // Store serialized data, to ensure a fresh copy being always returned from
659        // static cache, without any references to the original (which might be
660        // further changed, after it got set to the cache). This is to avoid issues
661        // with PHP5 always passing and assigning objects as references, and/or with
662        // any nested by-reference elements.
663        $cache[$part][$id][$key] = serialize($data);
664        cache_set($part . $id, $cache[$part][$id], 'cache_category');
665      }
666    
667      // Return data for given node/key combination.
668      return isset($cache[$part][$id][$key]) ? unserialize($cache[$part][$id][$key]) : NULL;
669    }

Legend:
Removed from v.1.70  
changed lines
  Added in v.1.71

  ViewVC Help
Powered by ViewVC 1.1.2