| 1 |
<?php |
<?php |
| 2 |
// $Id$ |
// $Id: category.inc,v 1.70 2008/07/21 09:30:48 jaza Exp $ |
| 3 |
|
|
| 4 |
/** |
/** |
| 5 |
* @file |
* @file |
| 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; |
| 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 |
} |
} |
| 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 |
/** |
/** |
| 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 |
} |
} |
| 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(); |
| 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 |
/** |
/** |
| 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(); |
| 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 |
} |
} |
| 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)) { |
| 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 |
} |
} |
| 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 |
} |
} |
| 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')); |
| 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 |
} |
} |
| 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(); |
| 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 |
/** |
/** |
| 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 |
/** |
/** |
| 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)) { |
| 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 |
|
} |