/** * Finds the region in which block content is being rendered. * Caches node regions by url. Could cause problems if a node * is on a page twice * @param int $nid is a node id * return string of node region location */ function tnt_get_region_for_block_content($nid) { static $control; // create the cache name, be safe $cache_name = 'theme_regions_'. check_plain($_GET['q']); // retrieve cache object // $data = cache_get($cache_name, 'cache'); // get array data from the cache object $data = unserialize($data->data); // we don't have region data for this node // or we do, but it is the same node in a different region if ((!$data[$nid]) || ($control[$nid])) { if (! $control[$nid]) { $control[$nid] = TRUE; } // Get the function call stack and search it for block_list(). // Reverse it for speed-efficiency. // - There are usually only about 5 fns between block_list() and the bottom of the stack. // - With views there can be 20 fns between block_list() the top of the stack. // DON'T MODIFY $stack. Treat it as read-only. $stack = array_reverse(debug_backtrace()); // Search for block_list(). foreach ($stack as $i => $fn) { if ($fn['function'] == 'block_list') { // Unfortunately the first argument of block_list() is not the correct region, // because block_list() renders and stores all the blocks on it's first invocation. // So this doesn't work: //$vars['region'] = $fn['args'][0]; // block_list() calls module_invoke() to invoke hook_block() in each module. // So module_invoke() is the next function UP in the reversed stack. // ($i is 0 for the bottom of the reversed stack.) // Store the parameters that module_invoke() was called with. $module_invoke_args = $stack[$i + 1]['args']; // Precautionary measure to save on memory consumption. // Probably unnecessary. // DON'T MODIFY $stack. unset($stack); // The 1st parameter is the block's module. 4th (last) parameter is the block's delta. // Search block_list() for 'module_invoke'. // See http://api.drupal.org/api/function/block_list/5 $module = $module_invoke_args[0]; $delta = $module_invoke_args[3]; // Get and store the block regions from the database. // We'll reuse this data each time, so only do this on the first invocation. static $blocks; if (!isset($blocks)) { $blocks = array(); $result = db_query("SELECT module, delta, region FROM blocks WHERE theme = '%s'", $GLOBALS['theme_key']); while ($row = db_fetch_object($result)) { // Store region by module then delta. $blocks[$row->module][$row->delta] = $row->region; } } // Set the region, from the stored regions. $return_region = $blocks[$module][$delta]; } } // now join the region to the data $data = $data ? array_merge($data, array($nid => $return_region)) : array($nid => $return_region); // now cache the data cache_set($cache_name, 'cache', serialize($data), CACHE_TEMPORARY); } return $data[$nid]; }