diff -Naur includes/common.inc includes/common.inc --- includes/common.inc 2007-10-17 17:28:59.000000000 -0400 +++ includes/common.inc 2007-11-04 19:56:50.000000000 -0500 @@ -1288,6 +1288,7 @@ if (variable_get('cache', 0)) { page_set_cache(); } + drupal_lookup_path('cache'); module_invoke_all('exit'); } diff -Naur includes/path.inc includes/path.inc --- includes/path.inc 2006-12-23 17:04:52.000000000 -0500 +++ includes/path.inc 2007-11-04 19:56:50.000000000 -0500 @@ -32,6 +32,7 @@ * - wipe: delete the alias cache. * - alias: return an alias for a given Drupal system path (if one exists). * - source: return the Drupal system URL for a path alias (if one exists). + * - cache: (internal use only) save the maps into the cache_path table. * @param $path * The path to investigate for corresponding aliases or system URLs. * @@ -41,44 +42,89 @@ */ function drupal_lookup_path($action, $path = '') { // $map keys are Drupal paths and the values are the corresponding aliases - static $map = array(), $no_src = array(); - static $count; + static + $map, $no_src, + $map_dirty = FALSE, $no_src_dirty = FALSE, + $count, $expire = 0; + global $base_root; // Use $count to avoid looking up paths in subsequent calls if there simply are no aliases if (!isset($count)) { - $count = db_result(db_query('SELECT COUNT(pid) FROM {url_alias}')); + $count = db_result(db_query('SELECT COUNT(*) FROM {url_alias}')); } - - if ($action == 'wipe') { - $map = array(); - $no_src = array(); + if ($count == 0) { + return FALSE; } - elseif ($count > 0 && $path != '') { - if ($action == 'alias') { - if (isset($map[$path])) { - return $map[$path]; + + if (!isset($map)) { + $cache = cache_get('map_'. $base_root . request_uri(), 'cache_path'); + if ($cache) { + $map = unserialize($cache->data); + $expire = $cache->expire; } - $alias = db_result(db_query("SELECT dst FROM {url_alias} WHERE src = '%s'", $path)); - $map[$path] = $alias; - return $alias; + else { + $map = array(); + } + + $cache = cache_get('no_src_'. $base_root . request_uri(), 'cache_path'); + if ($cache) { + $no_src = unserialize($cache->data); + $expire = $cache->expire; + } + else { + $no_src = array(); } - // Check $no_src for this $path in case we've already determined that there - // isn't a path that has this alias - elseif ($action == 'source' && !isset($no_src[$path])) { - // Look for the value $path within the cached $map - if (!$src = array_search($path, $map)) { - if ($src = db_result(db_query("SELECT src FROM {url_alias} WHERE dst = '%s'", $path))) { - $map[$src] = $path; + } + switch ($action) { + case 'alias': + if ($count > 0 && $path) { + if (isset($map[$path])) { + return $map[$path]; + } + if (!$alias = db_result(db_query("SELECT dst FROM {url_alias} WHERE src = '%s'", $path))) { + $alias = FALSE; + } + $map[$path] = $alias; + $map_dirty = TRUE; + return $alias; } - else { - // We can't record anything into $map because we do not have a valid - // index and there is no need because we have not learned anything - // about any Drupal path. Thus cache to $no_src. - $no_src[$path] = TRUE; + break; + case 'source': + // Check $no_src for this $path in case we've already determined that there + // isn't a path that has this alias + if ($count > 0 && $path && !isset($no_src[$path])) { + if (!$src = array_search($path, $map)) { + if ($src = db_result(db_query("SELECT src FROM {url_alias} WHERE dst = '%s'", $path))) { + $map[$src] = $path; + $map_dirty = TRUE; + } + else { + // We can't record anything into $map because we do not have a valid + // index and there is no need because we have not learned anything + // about any Drupal path. Thus cache to $no_src. + $no_src[$path] = TRUE; + $no_src_dirty = TRUE; + return FALSE; + } } + return $src; } - return $src; - } + break; + case 'wipe': + $map = array(); + $no_src = array(); + break; + case 'cache': + if (!$expire) { + $expire = time() + (60 * 60 * 24); + } + if ($map_dirty) { + cache_set('map_'. $base_root . request_uri(), 'cache_path', serialize($map), $expire); + } + if ($no_src_dirty) { + cache_set('no_src_' . $base_root . request_uri(), 'cache_path', serialize($no_src), $expire); + } + break; } return FALSE; diff -Naur modules/block/block.module modules/block/block.module --- modules/block/block.module 2007-09-12 03:49:35.000000000 -0400 +++ modules/block/block.module 2007-11-04 20:05:33.000000000 -0500 @@ -286,6 +286,7 @@ } drupal_set_message(t('The block settings have been updated.')); cache_clear_all(); + cache_clear_all('*', 'cache_advcache_block', TRUE); } /** @@ -500,6 +501,7 @@ module_invoke($form_values['module'], 'block', 'save', $form_values['delta'], $form_values); drupal_set_message(t('The block configuration has been saved.')); cache_clear_all(); + cache_clear_all('*', 'cache_advcache_block', TRUE); return 'admin/build/block'; } } @@ -538,6 +540,7 @@ db_query("DELETE FROM {blocks} WHERE module = 'block' AND delta = %d", $form_values['bid']); drupal_set_message(t('The block %name has been removed.', array('%name' => $form_values['info']))); cache_clear_all(); + cache_clear_all('*', 'cache_advcache_block', TRUE); return 'admin/build/block'; }; @@ -643,26 +646,37 @@ static $blocks = array(); if (!count($blocks)) { - $rids = array_keys($user->roles); - $placeholders = implode(',', array_fill(0, count($rids), '%d')); - $result = db_query("SELECT DISTINCT b.* FROM {blocks} b LEFT JOIN {blocks_roles} r ON b.module = r.module AND b.delta = r.delta WHERE b.theme = '%s' AND b.status = 1 AND (r.rid IN ($placeholders) OR r.rid IS NULL) ORDER BY b.region, b.weight, b.module", array_merge(array($theme_key), $rids)); - while ($block = db_fetch_object($result)) { - if (!isset($blocks[$block->region])) { - $blocks[$block->region] = array(); - } - // Use the user's block visibility setting, if necessary - if ($block->custom != 0) { - if ($user->uid && isset($user->block[$block->module][$block->delta])) { - $enabled = $user->block[$block->module][$block->delta]; + $cache_key = $user->uid. '::'. $theme_key; + $cache = cache_get($cache_key, 'cache_advcache_block'); + $enabled_blocks = unserialize($cache->data); + if (empty($enabled_blocks)) { + $enabled_blocks = array(); + $result = db_query("SELECT DISTINCT b.* FROM {blocks} b LEFT JOIN {blocks_roles} r ON b.module = r.module AND b.delta = r.delta WHERE b.theme = '%s' AND b.status = 1 AND (r.rid IN (%s) OR r.rid IS NULL) ORDER BY b.region, b.weight, b.module", $theme_key, implode(',', array_keys($user->roles))); + while ($block = db_fetch_object($result)) { + if (!isset($blocks[$block->region])) { + $blocks[$block->region] = array(); + } + // Use the user's block visibility setting, if necessary + if ($block->custom != 0) { + if ($user->uid && isset($user->block[$block->module][$block->delta])) { + $enabled = $user->block[$block->module][$block->delta]; + } + else { + $enabled = ($block->custom == 1); + } + } else { - $enabled = ($block->custom == 1); + $enabled = TRUE; + } + if ($enabled) { + $enabled_blocks[] = $block; } } - else { - $enabled = TRUE; - } + cache_set($cache_key, 'cache_advcache_block', serialize($enabled_blocks)); + } + foreach ($enabled_blocks as $block) { // Match path if necessary if ($block->pages) { if ($block->visibility < 2) { @@ -686,7 +700,7 @@ $page_match = TRUE; } - if ($enabled && $page_match) { + if ($page_match) { // Check the current throttle status and see if block should be displayed // based on server load. if (!($block->throttle && (module_invoke('throttle', 'status') > 0))) { diff -Naur modules/comment/comment.module modules/comment/comment.module --- modules/comment/comment.module 2007-10-17 17:29:00.000000000 -0400 +++ modules/comment/comment.module 2007-11-04 19:56:37.000000000 -0500 @@ -931,6 +931,16 @@ function comment_render($node, $cid = 0) { global $user; + // If this is an authenticated user who only has one role and cannot admin- + // ister comments, look for a cached copy of the comment, or in the case + // of $cid = 0, the whole tree of comments. + $cache_key = 0; + if (!user_access('administer comments') && count($user->roles) === 1 && in_array('authenticated user', $user->roles)) { + // Must accommodate pagination + $page = isset($_GET['page']) ? $_GET['page'] : ''; + $cache_key = 'nid-'. $node->nid. '::cid-'. $cid. '::'. $page; + } + $output = ''; if (user_access('access comments')) { @@ -945,6 +955,12 @@ $comments_per_page = _comment_get_display_setting('comments_per_page'); if ($cid) { + if ($cache_key) { + $cache = cache_get($cache_key, 'cache_comment'); + $comment = unserialize($cache->data); + } + + if (!$comment) { // Single comment view. $query = 'SELECT c.cid, c.pid, c.nid, c.subject, c.comment, c.format, c.timestamp, c.name, c.mail, c.homepage, u.uid, u.name AS registered_name, u.picture, u.data, c.score, c.users, c.status FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid WHERE c.cid = %d'; $query_args = array($cid); @@ -963,11 +979,26 @@ $function = $module .'_link_alter'; $function($node, $links); } + } + } + if ($comment) { $output .= theme('comment_view', $comment, $links); } } else { + if ($cache_key) { + if ($cache = cache_get($cache_key, 'cache_comment')) { + $comments = unserialize($cache->data); + $comment_count = count($comments); + + // Get the pager + $cache = cache_get($cache_key. '::pager', 'cache_comment'); + $pager = $cache->data; + } + } + + if (empty($comments)) { // Multiple comment view $query_count = 'SELECT COUNT(*) FROM {comments} WHERE nid = %d'; $query = 'SELECT c.cid as cid, c.pid, c.nid, c.subject, c.comment, c.format, c.timestamp, c.name, c.mail, c.homepage, u.uid, u.name AS registered_name, u.picture, u.data, c.score, c.users, c.thread, c.status FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid WHERE c.nid = %d'; @@ -1002,21 +1033,32 @@ $query .= ' ORDER BY SUBSTRING(c.thread, 1, (LENGTH(c.thread) - 1))'; } } - // Start a form, for use with comment control. $result = pager_query($query, $comments_per_page, 0, $query_count, $query_args); - if (db_num_rows($result) && (variable_get('comment_controls', COMMENT_CONTROLS_HIDDEN) == COMMENT_CONTROLS_ABOVE || variable_get('comment_controls', COMMENT_CONTROLS_HIDDEN) == COMMENT_CONTROLS_ABOVE_BELOW)) { + $comment_count = db_num_rows($result); + } + + + if ($comment_count && (variable_get('comment_controls', COMMENT_CONTROLS_HIDDEN) == COMMENT_CONTROLS_ABOVE || variable_get('comment_controls', COMMENT_CONTROLS_HIDDEN) == COMMENT_CONTROLS_ABOVE_BELOW)) { $output .= drupal_get_form('comment_controls', $mode, $order, $comments_per_page); } $divs = 0; $last_depth = 0; drupal_add_css(drupal_get_path('module', 'comment') .'/comment.css'); + + if (empty($comments)) { + $comments = array(); while ($comment = db_fetch_object($result)) { $comment = drupal_unpack($comment); $comment->name = $comment->uid ? $comment->registered_name : $comment->name; $comment->depth = count(explode('.', $comment->thread)) - 1; + $comments[] = $comment; + } + cache_set($cache_key, 'cache_comment', serialize($comments)); + } + foreach ($comments as $comment) { if ($mode == COMMENT_MODE_THREADED_COLLAPSED || $mode == COMMENT_MODE_THREADED_EXPANDED) { if ($comment->depth > $last_depth) { $divs++; @@ -1048,9 +1090,15 @@ for ($i = 0; $i < $divs; $i++) { $output .= ''; } - $output .= theme('pager', NULL, $comments_per_page, 0); - if (db_num_rows($result) && (variable_get('comment_controls', COMMENT_CONTROLS_HIDDEN) == COMMENT_CONTROLS_BELOW || variable_get('comment_controls', COMMENT_CONTROLS_HIDDEN) == COMMENT_CONTROLS_ABOVE_BELOW)) { + if (empty($pager)) { + $pager = theme('pager', NULL, $comments_per_page, 0); + cache_set($cache_key. '::pager', 'cache_comment', $pager); + } + + $output .= $pager; + + if ($comment_count && (variable_get('comment_controls', COMMENT_CONTROLS_HIDDEN) == COMMENT_CONTROLS_BELOW || variable_get('comment_controls', COMMENT_CONTROLS_HIDDEN) == COMMENT_CONTROLS_ABOVE_BELOW)) { $output .= drupal_get_form('comment_controls', $mode, $order, $comments_per_page); } } @@ -2016,4 +2064,3 @@ function vancode2int($c = '00') { return base_convert(substr($c, 1), 36, 10); } - diff -Naur modules/forum/forum.module modules/forum/forum.module --- modules/forum/forum.module 2007-08-08 02:27:22.000000000 -0400 +++ modules/forum/forum.module 2007-11-04 19:56:42.000000000 -0500 @@ -709,6 +709,17 @@ */ function forum_get_forums($tid = 0) { + // This caching breaks forum access! The results of db_rewrite_sql will + // be cached, meaning the first user to load this node after a cache + // refresh will set the permissions for everyone. If you are using a module + // that does query rewriting on forum queries, don't use this patch. + // If you're not sure whether or not this is the case, don't use this patch! + $cache = cache_get('forums::'. $tid, 'cache_forum'); + if ($cache) { + $forums = unserialize($cache->data); + return $forums; + } + $forums = array(); $_forums = taxonomy_get_tree(variable_get('forum_nav_vocabulary', ''), $tid); @@ -754,6 +765,8 @@ $forums[$forum->tid] = $forum; } + cache_set('forums::'. $tid, 'cache_forum', serialize($forums)); + return $forums; } diff -Naur modules/node/node.module modules/node/node.module --- modules/node/node.module 2007-09-29 19:41:28.000000000 -0400 +++ modules/node/node.module 2007-11-04 19:56:46.000000000 -0500 @@ -501,17 +501,31 @@ * A fully-populated node object. */ function node_load($param = array(), $revision = NULL, $reset = NULL) { + global $user; static $nodes = array(); if ($reset) { $nodes = array(); } - $cachable = ($revision == NULL); + $cache_id = 0; $arguments = array(); if (is_numeric($param)) { - if ($cachable && isset($nodes[$param])) { - return is_object($nodes[$param]) ? drupal_clone($nodes[$param]) : $nodes[$param]; + if (module_exists('advcache')) { + $cache_id = ($revision == NULL) ? $param. '::'. advcache_array2int($user->roles) : 0; + } + if ($cache_id > 0) { + if (isset($nodes[$param])) { + return is_object($nodes[$param]) ? drupal_clone($nodes[$param]) : $nodes[$param]; + } + if ($user->uid != 1) { + $cache = cache_get($cache_id, 'cache_node'); + if ($cache) { + $cache = unserialize($cache->data); + $nodes[$param] = is_object($cache) ? drupal_clone($cache) : $cache; + return $nodes[$param]; + } + } } $cond = 'n.nid = %d'; $arguments[] = $param; @@ -549,8 +563,13 @@ $node->$key = $value; } } - if ($cachable) { + if ($cache_id > 0) { $nodes[$node->nid] = is_object($node) ? drupal_clone($node) : $node; + if ($user->uid != 1) { + if (!in_array($node->type, variable_get('advcache_node_exclude_types', array('poll')))) { + cache_set($cache_id, 'cache_node', serialize($nodes[$node->nid])); + } + } } } @@ -1973,8 +1992,8 @@ if (isset($node->body) && count(explode(' ', $node->body)) < $type->min_word_count) { form_set_error('body', t('The body of your @type is too short. You need at least %words words.', array('%words' => $type->min_word_count, '@type' => $type->name))); } - - if (isset($node->nid) && (node_last_changed($node->nid) > $node->changed)) { + $changed = node_last_changed($node->nid); + if (isset($node->nid) && ($changed > $node->changed)) { form_set_error('changed', t('This content has been modified by another user, changes cannot be saved.')); } @@ -2463,7 +2482,7 @@ /** * Menu callback; view a single node. */ -function node_page_view($node, $cid = NULL) { +function node_page_view($node, $cid = 0) { drupal_set_title(check_plain($node->title)); return node_show($node, $cid); } diff -Naur modules/path/path.module modules/path/path.module --- modules/path/path.module 2007-05-20 20:52:28.000000000 -0400 +++ modules/path/path.module 2007-11-04 19:56:50.000000000 -0500 @@ -130,11 +130,9 @@ function path_set_alias($path = NULL, $alias = NULL, $pid = NULL) { if ($path && !$alias) { db_query("DELETE FROM {url_alias} WHERE src = '%s'", $path); - drupal_clear_path_cache(); } else if (!$path && $alias) { db_query("DELETE FROM {url_alias} WHERE dst = '%s'", $alias); - drupal_clear_path_cache(); } else if ($path && $alias) { $path = urldecode($path); @@ -145,7 +143,6 @@ // We have an insert: if ($path_count == 0 && $alias_count == 0) { db_query("INSERT INTO {url_alias} (src, dst) VALUES ('%s', '%s')", $path, $alias); - drupal_clear_path_cache(); } else if ($path_count >= 1 && $alias_count == 0) { if ($pid) { @@ -154,11 +151,9 @@ else { db_query("INSERT INTO {url_alias} (src, dst) VALUES ('%s', '%s')", $path, $alias); } - drupal_clear_path_cache(); } else if ($path_count == 0 && $alias_count == 1) { db_query("UPDATE {url_alias} SET src = '%s' WHERE dst = '%s'", $path, $alias); - drupal_clear_path_cache(); } else if ($path_count == 1 && $alias_count == 1) { // This will delete the path that alias was originally pointing to: @@ -167,6 +162,10 @@ path_set_alias($path, $alias); } } + + // Clear the static and the database cache. + drupal_clear_path_cache(); + cache_clear_all(NULL, 'cache_path'); } /** diff -Naur modules/search/search.module modules/search/search.module --- modules/search/search.module 2007-07-26 15:16:48.000000000 -0400 +++ modules/search/search.module 2007-11-04 19:56:55.000000000 -0500 @@ -272,6 +272,8 @@ // When re-indexing, keep link references db_query("DELETE FROM {search_index} WHERE sid = %d AND type = '%s'". ($reindex ? " AND fromsid = 0" : ''), $sid, $type); } + // Cached search results may no longer be valid. + cache_clear_all(NULL, 'cache_search'); } /** @@ -304,6 +306,34 @@ foreach (module_list() as $module) { module_invoke($module, 'update_index'); } + + // Don't allow search result caching if any node access modules such as organic + // groups have placed viewing restrictions on any nodes. Even if you have had + // organic groups enabled and have since disabled it, search caching will + // be prevented. If you find yourself in this position, you can restore the + // original un-restricted state of node_access like this: + // TRUNCATE node_access; + // INSERT INTO node_access VALUES (0,0,'all',1,0,0); + $r1 = db_result(db_query("SELECT count(*) FROM {node_access}")); + $r2 = db_result(db_query("SELECT count(*) FROM {node_access} WHERE grant_view = 1")); + if (($r1 == 1) && ($r2 == 1)) { + // Recalculate the list of popular search terms + $tops = array(); + $result = db_query("SELECT location, count(*) AS count FROM {watchdog} WHERE type = 'search' GROUP BY location HAVING count(*) > 2"); + while ($row = db_fetch_object($result)) { + $tops[] = strtolower($row->location); + } + // Since we just potentially indexed new or updated content, clear the cache. + cache_clear_all(NULL, 'cache_search'); + + // Set the search_cache_queries to the new top queries. + cache_set('search_cache_queries', 'cache_search', serialize($tops)); + } + else { + // No guarantee that the cache complies with node access restrictions, so + // wipe it. + cache_clear_all(NULL, 'cache_search'); + } } /** @@ -890,6 +920,7 @@ * Menu callback; presents the search form and/or search results. */ function search_view() { + global $base_root, $user; $type = arg(1); // Search form submits with POST but redirects to GET. This way we can keep @@ -909,8 +940,29 @@ // Log the search keys: watchdog('search', t('%keys (@type).', array('%keys' => $keys, '@type' => module_invoke($type, 'search', 'name'))), WATCHDOG_NOTICE, l(t('results'), 'search/'. $type .'/'. $keys)); - // Collect the search results: - $results = search_data($keys, $type); + // Look to the cache to see if this is a popular (thus cached) query + $request_uri = strtolower($base_root . request_uri()); + $results = NULL; + // Only cache results if the user is not an admin, is authenticated, has + // exactly one role, and the query is in the popular search queries array. + if ($cachable = ($user->uid > 1 && count($user->roles) === 1 && in_array('authenticated user', $user->roles))) { + $queries_cache = cache_get('search_cache_queries', 'cache_search'); + } + if ($cachable && $queries_cache) { + $search_cache_queries = unserialize($queries_cache->data); + if (in_array($request_uri, $search_cache_queries)) { + if ($search_cache = cache_get($request_uri, 'cache_search')) { + $results = $search_cache->data; + } + } + } + if (empty($results)) { + // Collect the search results: + $results = search_data($keys, $type); + if ($cachable) { + cache_set($request_uri, 'cache_search', $results); + } + } if ($results) { $results = theme('box', t('Search results'), $results); diff -Naur modules/taxonomy/taxonomy.module modules/taxonomy/taxonomy.module --- modules/taxonomy/taxonomy.module 2007-09-12 03:49:36.000000000 -0400 +++ modules/taxonomy/taxonomy.module 2007-11-04 19:57:00.000000000 -0500 @@ -779,12 +779,25 @@ static $terms; if (!isset($terms[$nid][$key])) { - $result = db_query(db_rewrite_sql('SELECT t.* FROM {term_node} r INNER JOIN {term_data} t ON r.tid = t.tid INNER JOIN {vocabulary} v ON t.vid = v.vid WHERE r.nid = %d ORDER BY v.weight, t.weight, t.name', 't', 'tid'), $nid); - $terms[$nid][$key] = array(); - while ($term = db_fetch_object($result)) { - $terms[$nid][$key][$term->$key] = $term; + // This caching breaks taxonomy access! The results of db_rewrite_sql will + // be cached, meaning the first user to load this node after a cache + // refresh will set the permissions for everyone. If you are using a module + // that does query rewriting on taxonomy queries, don't use this patch. + // If you're not sure whether or not this is the case, don't use this patch! + $cache_key = 'node::'. $nid. '::'. $key; + if ($cache = cache_get($cache_key, 'cache_taxonomy')) { + $terms[$nid][$key] = unserialize($cache->data); + } + else { + $result = db_query(db_rewrite_sql('SELECT t.* FROM {term_node} r INNER JOIN {term_data} t ON r.tid = t.tid INNER JOIN {vocabulary} v ON t.vid = v.vid WHERE r.nid = %d ORDER BY v.weight, t.weight, t.name', 't', 'tid'), $nid); + $terms[$nid][$key] = array(); + while ($term = db_fetch_object($result)) { + $terms[$nid][$key][$term->$key] = $term; + } + cache_set($cache_key, 'cache_taxonomy', serialize($terms[$nid][$key])); } } + return $terms[$nid][$key]; } @@ -988,7 +1001,14 @@ */ function taxonomy_get_tree($vid, $parent = 0, $depth = -1, $max_depth = NULL) { static $children, $parents, $terms; - + if ((0 === $parent) && (-1 === $depth)) { + if ($cache = cache_get('tree::'. $vid, 'cache_taxonomy')) { + return unserialize($cache->data); + } + else { + $cache_tree = TRUE; + } + } $depth++; // We cache trees, so it's not CPU-intensive to call get_tree() on a term @@ -1022,6 +1042,10 @@ } } + if ($cache_tree) { + cache_set('tree::'. $vid, 'cache_taxonomy', serialize($tree)); + } + return $tree ? $tree : array(); } @@ -1144,13 +1168,19 @@ static $vocabularies = array(); if (!array_key_exists($vid, $vocabularies)) { - $result = db_query('SELECT v.*, n.type FROM {vocabulary} v LEFT JOIN {vocabulary_node_types} n ON v.vid = n.vid WHERE v.vid = %d ORDER BY v.weight, v.name', $vid); - $node_types = array(); - while ($voc = db_fetch_object($result)) { - $node_types[] = $voc->type; - unset($voc->type); - $voc->nodes = $node_types; - $vocabularies[$vid] = $voc; + if ($cache = cache_get('vocabulary::'. $vid, 'cache_taxonomy')) { + $vocabularies[$vid] = unserialize($cache->data); + } + else { + $result = db_query('SELECT v.*, n.type FROM {vocabulary} v LEFT JOIN {vocabulary_node_types} n ON v.vid = n.vid WHERE v.vid = %d ORDER BY v.weight, v.name', $vid); + $node_types = array(); + while ($voc = db_fetch_object($result)) { + $node_types[] = $voc->type; + unset($voc->type); + $voc->nodes = $node_types; + $vocabularies[$vid] = $voc; + cache_set('vocabulary::'. $vid, 'cache_taxonomy', serialize($voc)); + } } } @@ -1170,7 +1200,13 @@ static $terms = array(); if (!isset($terms[$tid])) { - $terms[$tid] = db_fetch_object(db_query('SELECT * FROM {term_data} WHERE tid = %d', $tid)); + if ($cache = cache_get('term::'. $tid, 'cache_taxonomy')) { + $terms[$tid] = unserialize($cache->data); + } + else { + $terms[$tid] = db_fetch_object(db_query('SELECT * FROM {term_data} WHERE tid = %d', $tid)); + cache_set('term::'. $tid, 'cache_taxonomy', serialize($terms[$tid])); + } } return $terms[$tid]; @@ -1299,8 +1335,8 @@ function taxonomy_nodeapi($node, $op, $arg = 0) { switch ($op) { case 'load': - $output['taxonomy'] = taxonomy_node_get_terms($node->nid); - return $output; + $output['taxonomy'] = taxonomy_node_get_terms($node->nid); + return $output; case 'insert': taxonomy_node_save($node->nid, $node->taxonomy); break;