block.module 17.2 KB
Newer Older
Dries Buytaert's avatar
   
Dries Buytaert committed
1
<?php
2
// $Id$
Dries Buytaert's avatar
 
Dries Buytaert committed
3

Dries Buytaert's avatar
   
Dries Buytaert committed
4
5
6
7
8
/**
 * @file
 * Controls the boxes that are displayed around the main content.
 */

Dries Buytaert's avatar
   
Dries Buytaert committed
9
10
11
12
/**
 * Implementation of hook_help().
 */
function block_help($section) {
Dries Buytaert's avatar
   
Dries Buytaert committed
13
  switch ($section) {
Dries Buytaert's avatar
   
Dries Buytaert committed
14
    case 'admin/help#block':
Dries Buytaert's avatar
   
Dries Buytaert committed
15
      return t("
16
<p>Blocks are the boxes visible in the sidebar(s) of your web site. These are usually generated automatically by modules (e.g. recent forum topics), but you can also create your own blocks.</p>
Dries Buytaert's avatar
   
Dries Buytaert committed
17
<p>The sidebar each block appears in depends on both which theme you're using (some are left-only, some right, some both), and on the settings in block management.</p><p>Whether a block is visible in the first place depends on four things:</p><ul><li>It must have its \"enabled\" box checked in block management.</li><li>If it has its \"custom\" box checked in block management, the user must have chosen to display it in their user preferences.</li><li>If the \"path\" field in block management is set, the visitor must be on a page that matches the path specification (more on this later).</li><li>If the block has its throttle box checked, the user will only see the block if the site throttle level is low.</li></ul>
Dries Buytaert's avatar
   
Dries Buytaert committed
18
<p>The block management screen also lets you specify the vertical sort-order of the blocks within a sidebar. You do this by assigning a <strong>weight</strong> to each block. Lighter blocks (smaller weight) \"float up\" towards the top of the sidebar. Heavier ones \"sink down\" towards the bottom of it.</p>
Dries Buytaert's avatar
   
Dries Buytaert committed
19
<p>The path setting lets you define the pages on which a specific block is visible. If you leave the path blank it will appear on all pages. The path uses a regular expression syntax so remember to escape special characters! The path expression is matched against the relative URL of a Drupal page, e.g. <code>book</code>, <code>node/12</code>, <code>admin</code>.</p>
Dries Buytaert's avatar
   
Dries Buytaert committed
20
21
<p>In case you do not know what a regular expression is, you should read about them in the PHP manual. The chapter to look at is the one on <a href=\"%pcre\">Perl-Compatible Regular Expressions (PCRE)</a>.</p>
<p>However, for basic tasks it is sufficient to look at the following examples:</p>
Dries Buytaert's avatar
   
Dries Buytaert committed
22
<p>If the block should only show up on blog pages, use &lt;^blog&gt;.  To display on all node views use &lt;^node&gt;.  The angular brackets are used as delimiters of the regular expression.  To show up on either forum or book pages use &lt;^(forum|book)&gt;.  The round brackets form a group of expressions, divided by the | character. It matches if any of the expressions in it match.  A more complicated example is &lt;^node/add/(story|blog|image)&gt;. Blocks which have their paths set to this expression will show up on story, block, or image composition pages.  If you want to show a block an all pages, but not the search page, use &lt;^(?!search)&gt;.</p>
Dries Buytaert's avatar
   
Dries Buytaert committed
23
<h3>Administrator Defined Blocks</h3>
24
<p>An administrator defined block contains content supplied by you (as opposed to being generated automatically by a module). Each admin-defined block consists of a title, a description, and a body which can be as long as you wish. The Drupal engine will 'render' the content of the block.</p>", array('%pcre' => 'http://php.net/pcre/'));
Dries Buytaert's avatar
   
Dries Buytaert committed
25
    case 'admin/modules#description':
Dries Buytaert's avatar
   
Dries Buytaert committed
26
      return t('Controls the boxes that are displayed around the main content.');
Dries Buytaert's avatar
   
Dries Buytaert committed
27
    case 'admin/block':
Dries Buytaert's avatar
   
Dries Buytaert committed
28
      return t("Blocks are the boxes in the left- and right- side bars of the web site, depending on the chosen theme.  They are made available active modules or created manually. The \"enabled\" checkbox sets the default status of the block. Only enabled blocks are shown. When the \"custom\" checkbox is checked, your users can show or hide the block using their account settings. In that case, the 'enabled' checkbox signifies the block's default status. You can assign the block's placement by giving it a region and a weight. The region specifies which side of the page the block is on, and the weight sorts blocks within a region. Lighter (smaller weight value) blocks \"float up\" towards the top of the page. The path setting lets you define which pages you want a block to be shown on.  Blocks can automatically be temporarily disabled to reduce server load when your site becomes extremely busy by checking throttle.  The auto-throttle functionality must be enabled on the <a href=\"%throttle\">throttle configuration page</a> after having enabled the throttle module.", array('%throttle' => url('admin/settings/throttle')));
Dries Buytaert's avatar
   
Dries Buytaert committed
29
    case 'admin/block/add':
30
      return t("Here you can create a new block. Once you have created this block you must make it active and give it a place on the page using <a href=\"%overview\">blocks</a>. The title is used when displaying the block. The description is used in the \"block\" column on the <a href=\"%overview\">blocks</a> page. If you are going to place PHP code in the block, and you have the <em>create php content</em> permission (see the <a href=\"%permission\">permissions</a> page), you <em>must</em> change the type to PHP to make your code active.", array('%overview' => url('admin/block'), '%permission' => url('admin/user/configure/permission')));
Dries Buytaert's avatar
   
Dries Buytaert committed
31
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
32
33
}

Dries Buytaert's avatar
   
Dries Buytaert committed
34
/**
35
 * Menu callback; presents the block-specific information from admin/help.
Dries Buytaert's avatar
   
Dries Buytaert committed
36
 */
Dries Buytaert's avatar
   
Dries Buytaert committed
37
function block_help_page() {
Dries Buytaert's avatar
   
Dries Buytaert committed
38
  print theme('page', block_help('admin/help#block'));
Dries Buytaert's avatar
   
Dries Buytaert committed
39
40
}

Dries Buytaert's avatar
   
Dries Buytaert committed
41
42
43
/**
 * Implementation of hook_perm().
 */
Dries Buytaert's avatar
   
Dries Buytaert committed
44
function block_perm() {
Dries Buytaert's avatar
   
Dries Buytaert committed
45
  return array('administer blocks');
Dries Buytaert's avatar
   
Dries Buytaert committed
46
47
}

Dries Buytaert's avatar
   
Dries Buytaert committed
48
/**
Dries Buytaert's avatar
   
Dries Buytaert committed
49
 * Implementation of hook_menu().
Dries Buytaert's avatar
   
Dries Buytaert committed
50
 */
Dries Buytaert's avatar
   
Dries Buytaert committed
51
52
53
54
55
function block_menu() {
  $items = array();
  $items[] = array('path' => 'admin/block', 'title' => t('blocks'),
    'access' => user_access('administer blocks'),
    'callback' => 'block_admin');
Dries Buytaert's avatar
   
Dries Buytaert committed
56
57
  $items[] = array('path' => 'admin/block/list', 'title' => t('list'),
    'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
Dries Buytaert's avatar
   
Dries Buytaert committed
58
59
60
61
62
63
64
65
66
  $items[] = array('path' => 'admin/block/edit', 'title' => t('edit block'),
    'access' => user_access('administer blocks'),
    'callback' => 'block_box_edit',
    'type' => MENU_CALLBACK);
  $items[] = array('path' => 'admin/block/delete', 'title' => t('delete block'),
    'access' => user_access('administer blocks'),
    'callback' => 'block_box_delete',
    'type' => MENU_CALLBACK);
  // Tabs:
Dries Buytaert's avatar
Dries Buytaert committed
67
  $items[] = array('path' => 'admin/block/add', 'title' => t('add'),
Dries Buytaert's avatar
   
Dries Buytaert committed
68
69
70
71
    'access' => user_access('administer blocks'),
    'callback' => 'block_box_edit',
    'type' => MENU_LOCAL_TASK);
  return $items;
Dries Buytaert's avatar
   
Dries Buytaert committed
72
73
}

Dries Buytaert's avatar
   
Dries Buytaert committed
74
75
76
77
78
79
80
81
/**
 * Implementation of hook_block().
 *
 * Generates the administrator-defined blocks for display.
 */
function block_block($op = 'list', $delta = 0) {
  if ($op == 'list') {
    $result = db_query('SELECT bid, title, info FROM {boxes} ORDER BY title');
Dries Buytaert's avatar
   
Dries Buytaert committed
82
    while ($block = db_fetch_object($result)) {
Dries Buytaert's avatar
   
Dries Buytaert committed
83
      $blocks[$block->bid]['info'] = $block->info;
Dries Buytaert's avatar
   
Dries Buytaert committed
84
85
86
87
    }
    return $blocks;
  }
  else {
Dries Buytaert's avatar
   
Dries Buytaert committed
88
89
    $block = db_fetch_object(db_query('SELECT * FROM {boxes} WHERE bid = %d', $delta));
    $data['subject'] = $block->title;
90
    $data['content'] = check_output($block->body, $block->format);
Dries Buytaert's avatar
   
Dries Buytaert committed
91
    return $data;
92
93
94
  }
}

Dries Buytaert's avatar
 
Dries Buytaert committed
95
function block_admin_save($edit) {
Dries Buytaert's avatar
   
Dries Buytaert committed
96
97
  foreach ($edit as $module => $blocks) {
    foreach ($blocks as $delta => $block) {
Dries Buytaert's avatar
   
Dries Buytaert committed
98
      db_query("UPDATE {blocks} SET region = %d, status = %d, custom = %d, path = '%s', weight = %d, throttle = %d WHERE module = '%s' AND delta = '%s'",
Dries Buytaert's avatar
   
Dries Buytaert committed
99
                $block['region'], $block['status'], $block['custom'], $block['path'], $block['weight'], $block['throttle'], $module, $delta);
Dries Buytaert's avatar
   
Dries Buytaert committed
100
    }
Dries Buytaert's avatar
 
Dries Buytaert committed
101
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
102

Dries Buytaert's avatar
   
Dries Buytaert committed
103
  return t('the block settings have been updated.');
Dries Buytaert's avatar
 
Dries Buytaert committed
104
105
}

Dries Buytaert's avatar
   
Dries Buytaert committed
106
/**
Dries Buytaert's avatar
   
Dries Buytaert committed
107
 * Update the 'blocks' DB table with the blocks currently exported by modules.
Dries Buytaert's avatar
   
Dries Buytaert committed
108
 *
Dries Buytaert's avatar
   
Dries Buytaert committed
109
110
111
 * @param $order_by php <a
 *   href="http://www.php.net/manual/en/function.array-multisort.php">array_multisort()</a>
 *   style sort ordering, eg. "weight", SORT_ASC, SORT_STRING.
112
 *
Dries Buytaert's avatar
   
Dries Buytaert committed
113
114
 * @return
 *   Blocks currently exported by modules, sorted by $order_by.
Dries Buytaert's avatar
   
Dries Buytaert committed
115
 */
Dries Buytaert's avatar
   
Dries Buytaert committed
116
117
function _block_rehash($order_by = array('weight')) {
  $result = db_query('SELECT * FROM {blocks} ');
Dries Buytaert's avatar
   
Dries Buytaert committed
118
119
120
121
  while ($old_block = db_fetch_object($result)) {
    $old_blocks[$old_block->module][$old_block->delta] = $old_block;
  }

Dries Buytaert's avatar
   
Dries Buytaert committed
122
  db_query('DELETE FROM {blocks} ');
Dries Buytaert's avatar
   
Dries Buytaert committed
123
124

  foreach (module_list() as $module) {
Dries Buytaert's avatar
   
Dries Buytaert committed
125
    $module_blocks = module_invoke($module, 'block', 'list');
Dries Buytaert's avatar
   
Dries Buytaert committed
126
127
    if ($module_blocks) {
      foreach ($module_blocks as $delta => $block) {
Dries Buytaert's avatar
   
Dries Buytaert committed
128
129
        $block['module'] = $module;
        $block['delta']  = $delta;
Dries Buytaert's avatar
   
Dries Buytaert committed
130
        if ($old_blocks[$module][$delta]) {
Dries Buytaert's avatar
   
Dries Buytaert committed
131
132
133
134
135
136
          $block['status'] = $old_blocks[$module][$delta]->status;
          $block['weight'] = $old_blocks[$module][$delta]->weight;
          $block['region'] = $old_blocks[$module][$delta]->region;
          $block['path']   = $old_blocks[$module][$delta]->path;
          $block['custom'] = $old_blocks[$module][$delta]->custom;
          $block['throttle'] = $old_blocks[$module][$delta]->throttle;
Dries Buytaert's avatar
   
Dries Buytaert committed
137
138
        }
        else {
Dries Buytaert's avatar
   
Dries Buytaert committed
139
140
          $block['status'] = $block['weight'] = $block['region'] = $block['custom'] = 0;
          $block['path']   = '';
Dries Buytaert's avatar
   
Dries Buytaert committed
141
142
143
        }

        // reinsert blocks into table
Dries Buytaert's avatar
   
Dries Buytaert committed
144
        db_query("INSERT INTO {blocks} (module, delta, status, weight, region, path, custom, throttle) VALUES ('%s', '%s', %d, %d, %d, '%s', %d, %d)",
Dries Buytaert's avatar
   
Dries Buytaert committed
145
                  $block['module'], $block['delta'], $block['status'], $block['weight'], $block['region'], $block['path'], $block['custom'], $block['throttle']);
Dries Buytaert's avatar
   
Dries Buytaert committed
146
147

        $blocks[] = $block;
Dries Buytaert's avatar
   
Dries Buytaert committed
148

Dries Buytaert's avatar
   
Dries Buytaert committed
149
150
        // build array to sort on
        $order[$order_by[0]][] = $block[$order_by[0]];
Dries Buytaert's avatar
   
Dries Buytaert committed
151
152
153
154
      }
    }
  }

Dries Buytaert's avatar
   
Dries Buytaert committed
155
156
157
  // sort
  array_multisort($order[$order_by[0]], $order_by[1] ? $order_by[1] : SORT_ASC, $order_by[2] ? $order_by[2] : SORT_REGULAR, $blocks);

Dries Buytaert's avatar
   
Dries Buytaert committed
158
159
  return $blocks;
}
Dries Buytaert's avatar
   
Dries Buytaert committed
160

Dries Buytaert's avatar
   
Dries Buytaert committed
161
162
163
/**
 * Prepare the main block administration form.
 */
Dries Buytaert's avatar
   
Dries Buytaert committed
164
function block_admin_display() {
Dries Buytaert's avatar
   
Dries Buytaert committed
165

Dries Buytaert's avatar
   
Dries Buytaert committed
166
  $blocks = _block_rehash();
Dries Buytaert's avatar
   
Dries Buytaert committed
167

168
169
170
171
172
173
174
  // Fetch input formats used by admin-defined boxes.
  $formats = array();
  $result = db_query('SELECT bid, format FROM {boxes}');
  while ($box = db_fetch_object($result)) {
    $formats[$box->bid] = $box->format;
  }

Dries Buytaert's avatar
   
Dries Buytaert committed
175
  $header = array(t('Block'), t('Enabled'), t('Custom'), t('Throttle'), t('Weight'), t('Region'), t('Path'), array('data' => t('Operations'), 'colspan' => 2));
Dries Buytaert's avatar
   
Dries Buytaert committed
176

Dries Buytaert's avatar
   
Dries Buytaert committed
177
  foreach ($blocks as $block) {
Dries Buytaert's avatar
   
Dries Buytaert committed
178
    if ($block['module'] == 'block') {
179
180
181
      if (filter_access($formats[$block['delta']])) {
        $edit = l(t('edit'), 'admin/block/edit/'. $block['delta']);
      }
Dries Buytaert's avatar
   
Dries Buytaert committed
182
      $delete = l(t('delete'), 'admin/block/delete/'. $block['delta']);
183
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
184
    else {
Dries Buytaert's avatar
   
Dries Buytaert committed
185
186
      $edit = '';
      $delete = '';
Dries Buytaert's avatar
   
Dries Buytaert committed
187
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
188

Dries Buytaert's avatar
   
Dries Buytaert committed
189
    $rows[] = array($block['info'], array('data' => form_checkbox(NULL, $block['module'] .']['. $block['delta'] .'][status', 1, $block['status']), 'align' => 'center'), array('data' => form_checkbox(NULL, $block['module'] .']['. $block['delta'] .'][custom', 1, $block['custom']), 'align' => 'center'), array('data' => form_checkbox(NULL, $block['module'] .']['. $block['delta'] .'][throttle', 1, $block['throttle'], NULL, module_exist('throttle') ? NULL : array('disabled' => 'disabled')), 'align' => 'center'), form_weight(NULL, $block['module'] .']['. $block['delta'] .'][weight', $block['weight']), form_radios(NULL, $block['module'] .']['. $block['delta'] .'][region', $block['region'], array(t('left'), t('right'))), form_textfield(NULL, $block['module'] .']['. $block['delta'] .'][path', $block['path'], 10, 255),
Dries Buytaert's avatar
   
Dries Buytaert committed
190
    $edit, $delete);
Dries Buytaert's avatar
 
Dries Buytaert committed
191
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
192

Dries Buytaert's avatar
   
Dries Buytaert committed
193
194
  $output = theme('table', $header, $rows);
  $output .= form_submit(t('Save blocks'));
Dries Buytaert's avatar
 
Dries Buytaert committed
195

Dries Buytaert's avatar
   
Dries Buytaert committed
196
  return form($output, 'post', url('admin/block'));
Dries Buytaert's avatar
 
Dries Buytaert committed
197
198
}

199
function block_box_get($bid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
200
201
202
203
  return db_fetch_array(db_query('SELECT * FROM {boxes} WHERE bid = %d', $bid));
}

/**
204
205
206
 * Menu callback; displays the block editing form.
 *
 * On edit, saves changes and displays the block overview.
Dries Buytaert's avatar
   
Dries Buytaert committed
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
 */
function block_box_edit($bid = 0) {
  $edit = $_POST['edit'];
  $op = $_POST['op'];

  if ($op == t('Save block')) {
    drupal_set_message(block_box_save($edit));
    cache_clear_all();
    $output = block_admin_display();
  }
  else {
    if ($bid) {
      $output = block_box_form(block_box_get($bid));
    }
    else {
      $output = block_box_form();
    }
  }

  print theme('page', $output);
227
228
229
}

function block_box_form($edit = array()) {
230
  $group = form_textfield(t('Block title'), 'title', $edit['title'], 50, 64, t('The title of the block as shown to the user.'));
231
  $group .= filter_form('format', $edit['format']);
232
233
  $group .= form_textarea(t('Block body'), 'body', $edit['body'], 70, 10, t('The content of the block as shown to the user.'));
  $group .= form_textfield(t('Block description'), 'info', $edit['info'], 50, 64, t('A brief description of your block.  Used on the <a href="%overview">block overview page</a>.', array('%overview' => url('admin/block'))));
234

Dries Buytaert's avatar
   
Dries Buytaert committed
235
  if ($edit['bid']) {
236
    $group .= form_hidden('bid', $edit['bid']);
237
238
  }

239
  $group .= form_submit(t('Save block'));
240

241
242
  $output = form_group(t('Add a new block'), $group);
  return form($output);
243
244
245
}

function block_box_save($edit) {
246
247
  if (!filter_access($edit['format'])) {
    $edit['format'] = FILTER_FORMAT_DEFAULT;
Dries Buytaert's avatar
   
Dries Buytaert committed
248
249
  }

Dries Buytaert's avatar
   
Dries Buytaert committed
250
  if ($edit['bid']) {
251
    db_query("UPDATE {boxes} SET title = '%s', body = '%s', info = '%s', format = %d WHERE bid = %d", $edit['title'], $edit['body'], $edit['info'], $edit['format'], $edit['bid']);
Dries Buytaert's avatar
   
Dries Buytaert committed
252
    return t('The block has been updated.');
253
254
  }
  else {
255
    db_query("INSERT INTO {boxes} (title, body, info, format) VALUES  ('%s', '%s', '%s', %d)", $edit['title'], $edit['body'], $edit['info'], $edit['format']);
Dries Buytaert's avatar
   
Dries Buytaert committed
256
    return t('The new block has been added.');
257
258
259
  }
}

Dries Buytaert's avatar
   
Dries Buytaert committed
260
/**
261
 * Menu callback; deletes a custom box, then displays the overview page.
Dries Buytaert's avatar
   
Dries Buytaert committed
262
263
 */
function block_box_delete($bid = 0) {
264
  if ($bid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
265
    db_query('DELETE FROM {boxes} WHERE bid = %d', $bid);
Dries Buytaert's avatar
   
Dries Buytaert committed
266
    drupal_set_message(t('The block has been deleted.'));
Dries Buytaert's avatar
   
Dries Buytaert committed
267
    cache_clear_all();
268
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
269
  print theme('page', block_admin_display());
270
271
}

Dries Buytaert's avatar
   
Dries Buytaert committed
272
/**
273
 * Menu callback; displays the block overview page.
Dries Buytaert's avatar
   
Dries Buytaert committed
274
 */
Dries Buytaert's avatar
 
Dries Buytaert committed
275
function block_admin() {
Dries Buytaert's avatar
   
Dries Buytaert committed
276
277
  $edit = $_POST['edit'];
  $op = $_POST['op'];
Dries Buytaert's avatar
   
Dries Buytaert committed
278

Dries Buytaert's avatar
   
Dries Buytaert committed
279
280
281
  if ($op == t('Save blocks')) {
    drupal_set_message(block_admin_save($edit));
    cache_clear_all();
Dries Buytaert's avatar
   
Dries Buytaert committed
282
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
283
  print theme('page', block_admin_display());
Dries Buytaert's avatar
 
Dries Buytaert committed
284
}
Dries Buytaert's avatar
   
Dries Buytaert committed
285

Dries Buytaert's avatar
   
Dries Buytaert committed
286
287
288
289
290
291
/**
 * Implementation of hook_user().
 *
 * Allow users to decide which custom blocks to display when they visit
 * the site.
 */
292
function block_user($type, $edit, &$user, $category = NULL) {
293
  switch ($type) {
294
    case 'form':
295
296
297
298
299
300
301
302
      if ($category == 'account') {
        $result = db_query('SELECT * FROM {blocks} WHERE custom = %d ORDER BY module, delta', 1);

        while ($block = db_fetch_object($result)) {
          $data = module_invoke($block->module, 'block', 'list');
          if ($data[$block->delta]['info']) {
            $form .= form_checkbox($data[$block->delta]['info'], "block][$block->module][$block->delta", 1, isset($user->block[$block->module][$block->delta]) ? $user->block[$block->module][$block->delta] : $block->status);
          }
Kjartan Mannes's avatar
Kjartan Mannes committed
303
304
        }

305
306
307
        if (isset($form)) {
          return array(array('title' => t('Block configuration'), 'data' => $form, 'weight' => 2));
        }
308
      }
Dries Buytaert's avatar
   
Dries Buytaert committed
309
310

      break;
Dries Buytaert's avatar
   
Dries Buytaert committed
311
312
313
    case 'validate':
      if (!$edit['block']) {
        $edit['block'] = array();
314
315
      }
      return $edit;
316
317
318
  }
}

319
320
321
/**
 * Return blocks available for current $user at $region.
 *
Dries Buytaert's avatar
   
Dries Buytaert committed
322
 * @param $region main|left|right
323
 *
Dries Buytaert's avatar
   
Dries Buytaert committed
324
 * @return array of block objects, indexed with <i>module</i>_<i>delta</i>
325
 *
Dries Buytaert's avatar
   
Dries Buytaert committed
326
 * @see <a href="http://drupal.org/node/1042" target="_top">[feature]
327
 *   Generic template design difficult w/o block region "look-ahead"</a>
Dries Buytaert's avatar
   
Dries Buytaert committed
328
 * @todo add a proper primary key (bid) to the blocks table so we don't have
329
330
331
332
 *   to mess around with this <i>module</i>_<i>delta</i> construct. currently,
 *   "blocks" has no primary key defined (bad)!
 */
function block_list($region) {
333
  global $user, $base_url;
334
335
336
337
  static $blocks = array();

  if (!isset($blocks[$region])) {
    $blocks[$region] = array();
Dries Buytaert's avatar
   
Dries Buytaert committed
338
    $result = db_query('SELECT * FROM {blocks} WHERE (status = 1 OR custom = 1) '. ($region != 'all' ? 'AND region = %d ' : '') .'ORDER BY weight, module', $region == 'left' ? 0 : 1);
339
340

    while ($result && ($block = db_fetch_array($result))) {
341
342
343
344
      // When the user's account setting is empty, we use the block's regular 'status' (which is the default)
      if ($block['custom'] && $user->uid && !isset($user->block[$block['module']][$block['delta']])) {
        $user->block[$block['module']][$block['delta']] = $block['status'];
      }
Dries Buytaert's avatar
   
Dries Buytaert committed
345

346
347
348
349
350
351
352
353
      // Determine block visibility
      $enabled = $block['status'] && (!$user->uid || !$block['custom']);
      $custom = $block['custom'] && $user->block[$block['module']][$block['delta']];

      // Match path if necessary
      if ($block['path']) {
        $base = parse_url($base_url);
        $session = session_name() .'='. session_id();
Steven Wittens's avatar
Steven Wittens committed
354
        $url = str_replace(array($base['path'], '?'. $session), '', request_uri());
Dries Buytaert's avatar
   
Dries Buytaert committed
355
        $url = ereg_replace('^/(\?q=)?', '', $url);
Steven Wittens's avatar
Steven Wittens committed
356
        $matched = preg_match($block['path'], $url);
357
358
359
360
361
362
      }
      else {
        $matched = true;
      }

      if (($enabled || $custom) && $matched) {
Dries Buytaert's avatar
   
Dries Buytaert committed
363
        /*
364
365
        ** Check the current throttle status and see if block should be displayed
        ** based on server load.
Dries Buytaert's avatar
   
Dries Buytaert committed
366
        */
Dries Buytaert's avatar
   
Dries Buytaert committed
367
        if (!($block['throttle'] && (module_invoke('throttle', 'status') > 4))) {
368
369
370
371
          $array = module_invoke($block['module'], 'block', 'view', $block['delta']);
          if (is_array($array)) { 
            $block = array_merge($block, $array);
          }
Dries Buytaert's avatar
   
Dries Buytaert committed
372
        }
Dries Buytaert's avatar
   
Dries Buytaert committed
373
        if (isset($block['content']) && $block['content']) {
374
375
376
377
378
379
380
381
          $blocks[$region]["$block[module]_$block[delta]"] = (object) $block;
        }
      }
    }
  }
  return $blocks[$region];
}

382
?>