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

Diff of /contributions/modules/region_manager/region_manager.inc

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

revision 1.1 by q0rban, Fri Nov 20 21:55:47 2009 UTC revision 1.1.2.1 by q0rban, Fri Nov 20 21:55:47 2009 UTC
# Line 0  Line 1 
1    <?php
2    // $Id$
3    
4    /**
5     * @file
6     *   Holds all API functions for region_manager.module
7     */
8    
9    /**
10     * Retrieves a set of enabled Region Manager regions for the theme.
11     * If the variable has not been set for this particular theme, and
12     * the theme is a sub-theme, it will look to each base theme until
13     * it finds a setting. Returns an empty array if no settings found.
14     *
15     * @param $theme_key
16     *   String name of a theme.
17     * @return
18     *   An array of regions for the theme.
19     */
20    function region_manager_regions_variable_get($theme_key) {
21      $themes = list_themes();
22      $theme_info = $themes[$theme_key];
23    
24      $regions = variable_get('region_manager_regions_'. $theme_key, array());
25    
26      if (empty($regions) && isset($theme_info->info['base theme'])) {
27        $regions = region_manager_regions_variable_get($theme_info->info['base theme']);
28      }
29    
30      return $regions;
31    }
32    
33    /**
34     * Get a list of available regions from a specified theme.
35     *
36     * @param $theme_key
37     *   The name of a theme.
38     * @return
39     *   An array of regions in the form $region['name'] = 'description'.
40     */
41    function region_manager_region_list($theme_key) {
42      static $region_list = array();
43    
44      if (empty($region_list)) {
45        $settings = region_manager_regions_variable_get($theme_key);
46        if (!empty($settings)) {
47          $regions = system_region_list($theme_key);
48          $region_list = array_intersect_key($regions, array_filter($settings));
49        }
50      }
51    
52      return $region_list;
53    }
54    
55    /**
56     * Loader function for regions by theme or rid.
57     *
58     * @param $theme_key
59     *   A string containing the name of the theme.
60     * @param $reset
61     *   Boolean, if TRUE the cache will be flushed.
62     * @return
63     *   A single record in array format, or FALSE if none matched the incoming ID.
64     */
65    function region_manager_regions_load($theme_key, $reset = FALSE) {
66      static $records = array();
67    
68      $cache_key = 'region_manager:'. $theme_key;
69    
70      if ($reset) {
71        cache_clear_all($cache_key, 'cache');
72        $records = array();
73      }
74    
75      if (!empty($records)) {
76        return $records;
77      }
78    
79      if (($cache = cache_get($cache_key, 'cache')) && is_array($cache->data)) {
80        $records = $cache->data;
81      }
82      else {
83        $sql = "SELECT * FROM {region_manager_regions} WHERE theme_key = '%s'";
84        $result = db_query($sql, $theme_key);
85    
86        while ($record = db_fetch_array($result)) {
87          $record['modules'] = unserialize($record['modules']);
88          $record['blocked_blocks'] = explode(', ', $record['blocked_blocks']);
89          $record['storage'] = REGION_MANAGER_STORAGE_NORMAL;
90    
91          $records[$record['region']] = $record;
92        }
93    
94        // Call hook_region_manager_defaults().
95        foreach(module_invoke_all('region_manager_defaults', $theme_key) as $region => $record) {
96          if ($records[$region]) {
97            $records[$region]['storage'] = REGION_MANAGER_STORAGE_OVERRIDE;
98          }
99          else {
100            $record['storage'] = REGION_MANAGER_STORAGE_DEFAULT;
101            $records[$region] = $record;
102          }
103        }
104        cache_set($cache_key, $records);
105      }
106    
107      // If there are no records, look to the base theme and see if it has records.
108      if (empty($records)) {
109        $themes = list_themes();
110        $theme_info = $themes[$theme_key];
111    
112        if (isset($theme_info->info['base theme'])) {
113          $records = region_manager_regions_load($theme_info->info['base theme']);
114        }
115      }
116    
117      return $records;
118    }
119    
120    /**
121     * Public loader function for the full collection of records.
122     *
123     * @return
124     *   An array of all records, keyed by id.
125     */
126    function region_manager_regions_load_all() {
127      $sql = 'SELECT * FROM {region_manager_regions} ORDER BY rid ASC';
128      $result = db_query($sql);
129    
130      $records = array();
131      while ($record = db_fetch_array($result)) {
132        $record['modules'] = unserialize($record['modules']);
133        $record['blocked_blocks'] = explode(', ', $record['blocked_blocks']);
134        $record['storage'] = REGION_MANAGER_STORAGE_NORMAL;
135    
136        $records[$record['theme_key'] .':'. $record['region']] = $record;
137      }
138    
139      // Call hook_region_manager_defaults().
140      foreach(module_invoke_all('region_manager_defaults') as $theme_key => $theme) {
141        foreach($theme as $region => $record) {
142          $key = $theme_key .':'. $region;
143          if ($records[$key]) {
144            $records[$key]['storage'] = REGION_MANAGER_STORAGE_OVERRIDE;
145          }
146          else {
147            $record['storage'] = REGION_MANAGER_STORAGE_DEFAULT;
148            $records[$key] = $record;
149          }
150        }
151      }
152    
153      return $records;
154    }
155    
156    /**
157     * Inserts a new record, or updates an existing one.
158     *
159     * @param $region
160     *   A record to be saved.
161     * @return
162     *   The saved record.
163     */
164    function region_manager_region_save($region) {
165      if (isset($region['rid'])) {
166        drupal_write_record('region_manager_regions', $region, 'rid');
167      }
168      else {
169        drupal_write_record('region_manager_regions', $region);
170      }
171      return $region;
172    }
173    
174    /**
175     * Deletes a record, given its unique ID.
176     *
177     * @param $rid
178     *   An integer containing the ID of a record.
179     */
180    function region_manager_region_delete($rid) {
181      $sql = "DELETE FROM {region_manager_regions} WHERE rid = %d";
182      db_query($sql, $rid);
183    }
184    
185    /**
186     * Loads all available blocks organized by region.
187     */
188    function region_manager_blocks_load_all($theme_key, $region = NULL) {
189      static $all_blocks = NULL;
190      static $records = NULL;
191    
192      $blocks = array();
193    
194      // Load the blocks and regions if we haven't yet.
195      if (is_null($all_blocks)) {
196        $all_blocks = _region_manager_block_rehash($theme_key);
197      }
198      if (is_null($records)) {
199        // Load all regions for this theme, so we don't have to reload for each region.
200        $records = region_manager_regions_load($theme_key);
201      }
202    
203      // Might as well quit if we don't have any blocks.
204      if (empty($all_blocks)) {
205        return;
206      }
207    
208      if (is_null($region)) {
209        foreach(array_keys(region_manager_region_list($theme_key)) as $region) {
210          $blocks[$region] = _region_manager_blocks_filter($region, $all_blocks, $records[$region]);
211        }
212      }
213      else {
214        $blocks = _region_manager_blocks_filter($region, $all_blocks, $records[$region]);
215      }
216    
217      return $blocks;
218    }
219    
220    /**
221     * Returns an array of links to create new blocks in this region.
222     *
223     * @param $theme_key
224     *   A string containing the key of the active theme.
225     * @param $region
226     *   A string containing the region to be managed.
227     * @return
228     *   An array containing the links.
229     */
230    function region_manager_create_links($theme_key, $region) {
231      $links = $options = array();
232    
233      if ($path = $_REQUEST['destination']) {
234        $options['query'] = array(
235          'destination' => $path,
236          'theme_key' => $theme_key,
237          'region' => $region,
238        );
239      }
240    
241      foreach(region_manager_create_links_load($theme_key, $region) as $link) {
242        if ($link['options']) {
243          $options += $link['options'];
244        }
245        $links[] = l($link['title'], $link['path'], $options);
246      }
247      return $links;
248    }
249    
250    /**
251     * Retrieves an array of link items, invoking hook_region_manager_create_links()
252     * and hook_region_manager_create_links_alter().  The links are cached and
253     * static to ensure optimum performance.
254     *
255     * @param $theme_key
256     *   A string containing the key of the active theme.
257     * @param $region
258     *   A string containing the region to be managed.
259     * @param $reset
260     *   Boolean, if TRUE the cache will be flushed.
261     * @return
262     *   An array containing the links.
263     */
264    function region_manager_create_links_load($theme_key, $region, $reset = FALSE) {
265      static $links;
266    
267      if (is_null($links) || $reset) {
268        if ($reset) {
269          cache_clear_all('region_manager_create_links', 'cache');
270        }
271    
272        if ($cache = cache_get('region_manager_create_links')) {
273          $links = $cache->data;
274        }
275        else {
276          $links = module_invoke_all('region_manager_create_links', $theme_key, $region);
277          drupal_alter('region_manager_create_links', $links, $theme_key, $region);
278          cache_set('region_manager_create_links', $links, 'cache', CACHE_TEMPORARY);
279        }
280      }
281    
282      return $links;
283    }
284    
285    /**
286     * Helper function to filter all enabled and (available) disabled
287     * blocks for a particular region.
288     */
289    function _region_manager_blocks_filter($region, $blocks = array(), $record = array()) {
290      $output = array();
291    
292      foreach($blocks as $module => $modblocks) {
293        if (is_array($modblocks)) {
294    
295          // If they're all disabled for this module, go on to the next module.
296          if ($record['modules'][$module] == REGION_MANAGER_ALL_DISABLED) {
297            continue;
298          }
299    
300          // Otherwise, let's parse through each block.
301          else {
302            foreach($modblocks as $delta => $block) {
303              if ($block['status']) {
304                // Only add it to active if it's a part of this region.
305                if ($block['region'] == $region) {
306                  $output[] = $block;
307                }
308              }
309              else {
310                // Check to see if we're using custom availability for this module.
311                if ($record['modules'][$module] == REGION_MANAGER_CUSTOM) {
312                  $key = $module .':'. $delta;
313                  // Is this block 'blocked'?
314                  if (!in_array($key, $record['blocked_blocks'])) {
315                    $output[] = $block;
316                  }
317                }
318                // Otherwise add all blocks for this module.
319                else {
320                  $output[] = $block;
321                }
322              }
323            }
324          }
325        }
326      }
327    
328      return $output;
329    }
330    
331    /**
332     * Helper function to assemble the blocks.
333     */
334    function _region_manager_block_rehash($theme_key) {
335      $blocks = array();
336    
337      $result = db_query("SELECT * FROM {blocks} WHERE theme = '%s'", $theme_key);
338      $old_blocks = array();
339      while ($old_block = db_fetch_array($result)) {
340        $old_blocks[$old_block['module']][$old_block['delta']] = $old_block;
341      }
342    
343      $blocks = array();
344      // Valid region names for the theme.
345      $regions = system_region_list($theme_key);
346    
347      foreach (module_list() as $module) {
348        $module_blocks = module_invoke($module, 'block', 'list');
349        if ($module_blocks) {
350          foreach ($module_blocks as $delta => $block) {
351            if (empty($old_blocks[$module][$delta])) {
352              // If it's a new block, add identifiers.
353              $block['module'] = $module;
354              $block['delta']  = $delta;
355              $block['theme']  = $theme_key;
356              if (!isset($block['pages'])) {
357                // {block}.pages is type 'text', so it cannot have a
358                // default value, and not null, so we need to provide
359                // value if the module did not.
360                $block['pages']  = '';
361              }
362              // Add defaults and save it into the database.
363              drupal_write_record('blocks', $block);
364              // Set region to none if not enabled.
365              $block['region'] = $block['status'] ? $block['region'] : BLOCK_REGION_NONE;
366              // Add to the list of blocks we return.
367              $blocks[$module][$delta] = $block;
368            }
369            else {
370              // If it's an existing block, database settings should overwrite
371              // the code. But aside from 'info' everything that's definable in
372              // code is stored in the database and we do not store 'info', so we
373              // do not need to update the database here.
374              // Add 'info' to this block.
375              $old_blocks[$module][$delta]['info'] = $block['info'];
376              // If the region name does not exist, disable the block and assign it to none.
377              if (!empty($old_blocks[$module][$delta]['region']) && !isset($regions[$old_blocks[$module][$delta]['region']])) {
378                drupal_set_message(t('The @block %info was assigned to the invalid region %region and has been disabled.', array('@block' => _region_manager_block_name(), '%info' => $old_blocks[$module][$delta]['info'], '%region' => $old_blocks[$module][$delta]['region'])), 'warning');
379                $old_blocks[$module][$delta]['status'] = 0;
380                $old_blocks[$module][$delta]['region'] = BLOCK_REGION_NONE;
381              }
382              else {
383                $old_blocks[$module][$delta]['region'] = $old_blocks[$module][$delta]['status'] ? $old_blocks[$module][$delta]['region'] : BLOCK_REGION_NONE;
384              }
385              // Add this block to the list of blocks we return.
386              $blocks[$module][$delta] = $old_blocks[$module][$delta];
387              // Remove this block from the list of blocks to be deleted.
388              unset($old_blocks[$module][$delta]);
389            }
390          }
391        }
392      }
393    
394      // Remove blocks that are no longer defined by the code from the database.
395      foreach ($old_blocks as $module => $old_module_blocks) {
396        foreach ($old_module_blocks as $delta => $block) {
397          db_query("DELETE FROM {blocks} WHERE module = '%s' AND delta = '%s' AND theme = '%s'", $module, $delta, $theme_key);
398        }
399      }
400      return $blocks;
401    }
402    
403    /**
404     * Helper function to determine if the block is visible for a certain path.
405     *
406     * @return
407     *   Boolean FALSE if it's not visible, otherwise a string of the path.
408     */
409    function _region_manager_block_check_visibility($block, $path = NULL) {
410      if ($block['visibility'] == 1) {
411        $path = is_null($path) ? drupal_get_path_alias($_GET['q']) : $path;
412        // Compare with the internal and path alias (if any).
413        $page_match = drupal_match_path($path, $block['pages']);
414        if ($path != $_GET['q']) {
415          $page_match = $page_match || drupal_match_path($_GET['q'], $block['pages']);
416        }
417      }
418      return $page_match ? $path : FALSE;
419    }
420    
421    /**
422     * Helper function to display the custom block name.
423     *
424     * @param $name
425     *   String designating upper or lower case.
426     */
427    function _region_manager_block_name($case = 'lower') {
428      static $name;
429    
430      if (empty($name)) {
431        $name = variable_get('region_manager_block_name', 'Block');
432      }
433    
434      if ($case == 'lower') {
435        return strtolower($name);
436      }
437      return ucfirst($name);
438    }
439    
440    /**
441     * Helper function to output a path name or alias.
442     */
443    function _region_manager_path_name($path) {
444      $frontpage = variable_get('site_frontpage', 'node');
445      $alias = ($path == $frontpage) ? t('home page') : drupal_get_path_alias($path);
446    
447      return $alias;
448    }

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.1.2.1

  ViewVC Help
Powered by ViewVC 1.1.3