block.module 19 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':
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>
17
18
19
20
21
22
23
24
25
26
27
28
29
<p>The sidebar each block appears in depends on both which theme you are using (some are left-only, some right, some both), and on the settings in block management.</p>
<p>The block management screen lets you specify the vertical sort-order of the blocks within a sidebar. You do this by assigning a weight 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>
<p>A block\'s visibility depends on:</p>
<ul>
<li>Its enabled checkbox. Disabled blocks are never shown.</li>
<li>Its throttle checkbox. Throttled blocks are hidden during high server loads.</li>
<li>Its path options. Blocks can be configured to only show/hide on certain pages</li>.
<li>User settings. You can choose to let your users decide whether to show/hide certain blocks.</li>
<li>Its function. Dynamic blocks (such as those defined by modules) may be empty on certain pages and will not be shown.</li>
</ul>

<h3>Administrator defined blocks</h3>
<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>');
Dries Buytaert's avatar
   
Dries Buytaert committed
30
    case 'admin/modules#description':
Dries Buytaert's avatar
   
Dries Buytaert committed
31
      return t('Controls the boxes that are displayed around the main content.');
Dries Buytaert's avatar
   
Dries Buytaert committed
32
    case 'admin/block':
33
34
35
      return t("
<p>Blocks are the boxes in the left and right side bars of the web site. They are made available by modules or created manually.</p>
<p>Only enabled blocks are shown. You can position the blocks by deciding which side of the page they will show up on (region) and in which order they appear (weight).</p>
36
<p>If you want certain blocks to disable themselves temporarily during high server loads, check the 'Throttle' box. You can configure the auto-throttle on the <a href=\"%throttle\">throttle configuration page</a> after having enabled the throttle module.
37
", array('%throttle' => url('admin/settings/throttle')));
Dries Buytaert's avatar
   
Dries Buytaert committed
38
    case 'admin/block/add':
39
      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.", array('%overview' => url('admin/block')));
Dries Buytaert's avatar
   
Dries Buytaert committed
40
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
41
42
}

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

Dries Buytaert's avatar
   
Dries Buytaert committed
50
/**
Dries Buytaert's avatar
   
Dries Buytaert committed
51
 * Implementation of hook_menu().
Dries Buytaert's avatar
   
Dries Buytaert committed
52
 */
Dries Buytaert's avatar
   
Dries Buytaert committed
53
function block_menu($may_cache) {
Dries Buytaert's avatar
   
Dries Buytaert committed
54
  $items = array();
Dries Buytaert's avatar
   
Dries Buytaert committed
55
56
57
58
59
60
61

  if ($may_cache) {
    $items[] = array('path' => 'admin/block', 'title' => t('blocks'),
      'access' => user_access('administer blocks'),
      'callback' => 'block_admin');
    $items[] = array('path' => 'admin/block/list', 'title' => t('list'),
      'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
62
    $items[] = array('path' => 'admin/block/configure', 'title' => t('configure block'),
Dries Buytaert's avatar
   
Dries Buytaert committed
63
      'access' => user_access('administer blocks'),
64
65
66
67
68
      'callback' => 'block_admin_configure',
      'type' => MENU_CALLBACK);
    $items[] = array('path' => 'admin/block/delete', 'title' => t('delete block'),
      'access' => user_access('administer blocks'),
      'callback' => 'block_box_delete',
Dries Buytaert's avatar
   
Dries Buytaert committed
69
      'type' => MENU_CALLBACK);
Dries Buytaert's avatar
   
Dries Buytaert committed
70
    $items[] = array('path' => 'admin/block/add', 'title' => t('add block'),
Dries Buytaert's avatar
   
Dries Buytaert committed
71
      'access' => user_access('administer blocks'),
72
      'callback' => 'block_box_add',
Dries Buytaert's avatar
   
Dries Buytaert committed
73
74
75
      'type' => MENU_LOCAL_TASK);
  }

Dries Buytaert's avatar
   
Dries Buytaert committed
76
  return $items;
Dries Buytaert's avatar
   
Dries Buytaert committed
77
78
}

Dries Buytaert's avatar
   
Dries Buytaert committed
79
80
81
82
83
/**
 * Implementation of hook_block().
 *
 * Generates the administrator-defined blocks for display.
 */
84
85
86
87
88
function block_block($op = 'list', $delta = 0, $edit = array()) {
  switch ($op) {
    case 'list':
      $result = db_query('SELECT bid, title, info FROM {boxes} ORDER BY title');
      while ($block = db_fetch_object($result)) {
89
        $blocks[$block->bid]['info'] = $block->info ? $block->info : $block->title;
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
      }
      return $blocks;

    case 'configure':
      $box = block_box_get($delta);
      if (filter_access($box['format'])) {
        return block_box_form($box);
      }
      break;

    case 'save':
      block_box_save($edit, $delta);
      break;

    case 'view':
      $block = db_fetch_object(db_query('SELECT * FROM {boxes} WHERE bid = %d', $delta));
      $data['subject'] = $block->title;
      $data['content'] = check_output($block->body, $block->format);
      return $data;
109
110
111
  }
}

Dries Buytaert's avatar
 
Dries Buytaert committed
112
function block_admin_save($edit) {
Dries Buytaert's avatar
   
Dries Buytaert committed
113
114
  foreach ($edit as $module => $blocks) {
    foreach ($blocks as $delta => $block) {
115
116
      db_query("UPDATE {blocks} SET region = %d, status = %d, weight = %d, throttle = %d WHERE module = '%s' AND delta = '%s'",
                $block['region'], $block['status'], $block['weight'], $block['throttle'], $module, $delta);
Dries Buytaert's avatar
   
Dries Buytaert committed
117
    }
Dries Buytaert's avatar
 
Dries Buytaert committed
118
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
119

120
  return t('The block settings have been updated.');
Dries Buytaert's avatar
 
Dries Buytaert committed
121
122
}

Dries Buytaert's avatar
   
Dries Buytaert committed
123
/**
Dries Buytaert's avatar
   
Dries Buytaert committed
124
 * Update the 'blocks' DB table with the blocks currently exported by modules.
Dries Buytaert's avatar
   
Dries Buytaert committed
125
 *
Dries Buytaert's avatar
   
Dries Buytaert committed
126
127
128
 * @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.
129
 *
Dries Buytaert's avatar
   
Dries Buytaert committed
130
131
 * @return
 *   Blocks currently exported by modules, sorted by $order_by.
Dries Buytaert's avatar
   
Dries Buytaert committed
132
 */
Dries Buytaert's avatar
   
Dries Buytaert committed
133
134
function _block_rehash($order_by = array('weight')) {
  $result = db_query('SELECT * FROM {blocks} ');
Dries Buytaert's avatar
   
Dries Buytaert committed
135
136
137
138
  while ($old_block = db_fetch_object($result)) {
    $old_blocks[$old_block->module][$old_block->delta] = $old_block;
  }

Dries Buytaert's avatar
   
Dries Buytaert committed
139
  db_query('DELETE FROM {blocks} ');
Dries Buytaert's avatar
   
Dries Buytaert committed
140
141

  foreach (module_list() as $module) {
Dries Buytaert's avatar
   
Dries Buytaert committed
142
    $module_blocks = module_invoke($module, 'block', 'list');
Dries Buytaert's avatar
   
Dries Buytaert committed
143
144
    if ($module_blocks) {
      foreach ($module_blocks as $delta => $block) {
Dries Buytaert's avatar
   
Dries Buytaert committed
145
146
        $block['module'] = $module;
        $block['delta']  = $delta;
Dries Buytaert's avatar
   
Dries Buytaert committed
147
        if ($old_blocks[$module][$delta]) {
Dries Buytaert's avatar
   
Dries Buytaert committed
148
149
150
          $block['status'] = $old_blocks[$module][$delta]->status;
          $block['weight'] = $old_blocks[$module][$delta]->weight;
          $block['region'] = $old_blocks[$module][$delta]->region;
151
152
          $block['visibility'] = $old_blocks[$module][$delta]->visibility;
          $block['pages'] = $old_blocks[$module][$delta]->pages;
Dries Buytaert's avatar
   
Dries Buytaert committed
153
154
          $block['custom'] = $old_blocks[$module][$delta]->custom;
          $block['throttle'] = $old_blocks[$module][$delta]->throttle;
155
          $block['types'] = $old_blocks[$module][$delta]->types;
Dries Buytaert's avatar
   
Dries Buytaert committed
156
157
        }
        else {
Dries Buytaert's avatar
   
Dries Buytaert committed
158
          $block['status'] = $block['weight'] = $block['region'] = $block['custom'] = 0;
159
          $block['pages'] = $block['types'] = '';
Dries Buytaert's avatar
   
Dries Buytaert committed
160
161
162
        }

        // reinsert blocks into table
163
164
        db_query("INSERT INTO {blocks} (module, delta, status, weight, region, visibility, pages, custom, throttle, types) VALUES ('%s', '%s', %d, %d, %d, %d, '%s', %d, %d, '%s')",
          $block['module'], $block['delta'], $block['status'], $block['weight'], $block['region'], $block['visibility'], $block['pages'], $block['custom'], $block['throttle'], $block['types']);
Dries Buytaert's avatar
   
Dries Buytaert committed
165
166

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

Dries Buytaert's avatar
   
Dries Buytaert committed
168
169
        // build array to sort on
        $order[$order_by[0]][] = $block[$order_by[0]];
Dries Buytaert's avatar
   
Dries Buytaert committed
170
171
172
173
      }
    }
  }

Dries Buytaert's avatar
   
Dries Buytaert committed
174
175
176
  // 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
177
178
  return $blocks;
}
Dries Buytaert's avatar
   
Dries Buytaert committed
179

Dries Buytaert's avatar
   
Dries Buytaert committed
180
181
182
/**
 * Prepare the main block administration form.
 */
Dries Buytaert's avatar
   
Dries Buytaert committed
183
function block_admin_display() {
Dries Buytaert's avatar
   
Dries Buytaert committed
184
  $blocks = _block_rehash();
Dries Buytaert's avatar
   
Dries Buytaert committed
185

Dries Buytaert's avatar
   
Dries Buytaert committed
186
187
188
189
190
191
  $header = array(t('Block'), t('Enabled'), t('Weight'), t('Region'));
  if (module_exist('throttle')) {
    $header[] = t('Throttle');
  }
  $header[] = array('data' => t('Operations'), 'colspan' => 2);

Dries Buytaert's avatar
   
Dries Buytaert committed
192

Dries Buytaert's avatar
   
Dries Buytaert committed
193
  foreach ($blocks as $block) {
194
    if ($block['module'] == 'block') {
195
      $delete = l(t('delete'), 'admin/block/delete/'. $block['delta']);
196
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
197
    else {
198
      $delete = '';
Dries Buytaert's avatar
   
Dries Buytaert committed
199
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
200

201
202
203
204
205
206
207
208
209
210
211
    $row = array($block['info'],
      form_checkbox(NULL, $block['module'] .']['. $block['delta'] .'][status', 1, $block['status']),
      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'))));

    $row = array($block['info'],
      form_checkbox(NULL, $block['module'] .']['. $block['delta'] .'][status', 1, $block['status']),
      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'))));
Dries Buytaert's avatar
   
Dries Buytaert committed
212
213

    if (module_exist('throttle')) {
214
      $row[] = form_checkbox(NULL, $block['module'] .']['. $block['delta'] .'][throttle', 1, $block['throttle']);
Dries Buytaert's avatar
   
Dries Buytaert committed
215
    }
216
217
    $row[] = l(t('configure'), 'admin/block/configure/'. $block['module'] .'/'. $block['delta']);
    $row[] = $delete;
Dries Buytaert's avatar
   
Dries Buytaert committed
218
    $rows[] = $row;
Dries Buytaert's avatar
 
Dries Buytaert committed
219
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
220

Dries Buytaert's avatar
   
Dries Buytaert committed
221
222
  $output = theme('table', $header, $rows);
  $output .= form_submit(t('Save blocks'));
Dries Buytaert's avatar
 
Dries Buytaert committed
223

Dries Buytaert's avatar
   
Dries Buytaert committed
224
  return form($output, 'post', url('admin/block'));
Dries Buytaert's avatar
 
Dries Buytaert committed
225
226
}

227
function block_box_get($bid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
228
229
230
231
  return db_fetch_array(db_query('SELECT * FROM {boxes} WHERE bid = %d', $bid));
}

/**
232
 * Menu callback; displays the block configuration form.
Dries Buytaert's avatar
   
Dries Buytaert committed
233
 */
234
function block_admin_configure($module = NULL, $delta = 0) {
Dries Buytaert's avatar
   
Dries Buytaert committed
235
236
237
  $edit = $_POST['edit'];
  $op = $_POST['op'];

238
239
  switch ($op) {
    case t('Save block'):
240
241
242
243
244
245
246
      if ($edit['types']) {
        $types = implode(',', $edit['types']);
      }
      else {
        $types = '';
      }
      db_query("UPDATE {blocks} SET visibility = %d, pages = '%s', custom = %d, types = '%s' WHERE module = '%s' AND delta = '%s'", $edit['visibility'], $edit['pages'], $edit['custom'], $types, $module, $delta);
247
248
      module_invoke($module, 'block', 'save', $delta, $edit);
      drupal_set_message('The block configuration has been saved.');
249
250
251
      cache_clear_all();
      drupal_goto('admin/block');

252
253
254
    default:
      // Always evaluates to TRUE, but a validation step may be added later.
      if (!$edit) {
255
        $edit = db_fetch_array(db_query("SELECT pages, visibility, custom, types FROM {blocks} WHERE module = '%s' AND delta = '%s'", $module, $delta));
256
257
258
259
260
261
262
      }

      // Module-specific block configurations.
      if ($settings = module_invoke($module, 'block', 'configure', $delta)) {
        $form = form_group(t('Block-specific settings'), $settings);
      }

263
264
265
      foreach (node_list() as $type) {
        $content_types[$type] = node_invoke($type, 'node_name');
      }
266
267
268
      // Get the block subject for the page title.
      $info = module_invoke($module, 'block', 'list');
      drupal_set_title(t("'%name' block", array('%name' => $info[$delta]['info'])));
269

270
      // Standard block configurations.
271
272
      $group_1 = form_radios(t('Custom visibility settings'), 'custom', $edit['custom'], array(t('Users cannot control whether or not they see this block.'), t('Show this block by default, but let individual users hide it.'), t('Hide this block by default but let individual users show it.')), t('Allow individual users to customize the visibility of this block in their account settings.'));
      $group_2 = form_radios(t('Show block on specific pages'), 'visibility', $edit['visibility'], array(t('Show on every page except the listed pages.'), t('Show on only the listed pages.')));
Steven Wittens's avatar
Typos.    
Steven Wittens committed
273
274
      $group_2 .= form_textarea(t('Pages'), 'pages', $edit['pages'], 40, 5, t("Enter one page per line as Drupal paths. The '*' character is a wildcard. Example paths are '<em>blog</em>' for the blog page and '<em>blog/*</em>' for every personal blog. '<em>&lt;front&gt;</em>' is the front page."));
      $group_3 = form_checkboxes(t('Restrict block to specific content types'), 'types', explode(',', $edit['types']), $content_types, t('Selecting one or more content types will cause this block to only be shown on pages of the selected types. This feature works alone or in conjunction with page specific visibility settings. For example, you can specify that a block only appear on book pages in the \'FAQ\' path.'), NULL, FALSE);
275

276
      $form .= form_group(t('User specific visibility settings'), $group_1);
277
278
      $form .= form_group(t('Page specific visibility settings'), $group_2);
      $form .= form_group(t('Content specific visibility settings'), $group_3);
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314


      $form .= form_submit(t('Save block'));

      print theme('page', form($form));
  }
}

/**
 * Menu callback; displays the block creation form.
 */
function block_box_add() {
  $edit = $_POST['edit'];
  $op = $_POST['op'];

  switch ($op) {
    case t('Save block'):
      block_box_save($edit);
      drupal_set_message(t('The new block has been added.'));
      drupal_goto('admin/block');

    default:
      $form = block_box_form();
      $form .= form_submit(t('Save block'));
      $output .= form($form);
  }

  print theme('page', $output);
}

/**
 * Menu callback; confirm and delete custom blocks.
 */
function block_box_delete($bid = 0) {
  $op = $_POST['op'];
  $box = block_box_get($bid);
315
  $info = $box['info'] ? $box['info'] : $box['title'];
316

317
318
319
320
321
322
323
324
325
326
327
328
  if ($_POST['edit']['confirm']) {
    db_query('DELETE FROM {boxes} WHERE bid = %d', $bid);
    drupal_set_message(t('The block %name has been deleted.', array('%name' => '<em>'. $info .'</em>')));
    cache_clear_all();
    drupal_goto('admin/block');
  }
  else {
    $output = theme('confirm',
                    t('Are you sure you want to delete the block %name?', array('%name' => '<em>'. $info .'</em>')),
                    'admin/block',
                    NULL,
                    t('Delete'));
Dries Buytaert's avatar
   
Dries Buytaert committed
329
330
331
  }

  print theme('page', $output);
332
333
334
}

function block_box_form($edit = array()) {
335
336
337
  $output = form_textfield(t('Block title'), 'title', $edit['title'], 50, 64, t('The title of the block as shown to the user.'));
  $output .= filter_form('format', $edit['format']);
  $output .= form_textarea(t('Block body'), 'body', $edit['body'], 70, 10, t('The content of the block as shown to the user.'));
338
  $output .= 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'))));
339

340
  return $output;
341
342
}

343
function block_box_save($edit, $delta = NULL) {
344
345
  if (!filter_access($edit['format'])) {
    $edit['format'] = FILTER_FORMAT_DEFAULT;
Dries Buytaert's avatar
   
Dries Buytaert committed
346
347
  }

348
349
  if (isset($delta)) {
    db_query("UPDATE {boxes} SET title = '%s', body = '%s', info = '%s', format = %d WHERE bid = %d", $edit['title'], $edit['body'], $edit['info'], $edit['format'], $delta);
350
351
  }
  else {
352
    db_query("INSERT INTO {boxes} (title, body, info, format) VALUES  ('%s', '%s', '%s', %d)", $edit['title'], $edit['body'], $edit['info'], $edit['format']);
353
354
355
  }
}

Dries Buytaert's avatar
   
Dries Buytaert committed
356
/**
357
 * Menu callback; displays the block overview page.
Dries Buytaert's avatar
   
Dries Buytaert committed
358
 */
Dries Buytaert's avatar
 
Dries Buytaert committed
359
function block_admin() {
Dries Buytaert's avatar
   
Dries Buytaert committed
360
361
  $edit = $_POST['edit'];
  $op = $_POST['op'];
Dries Buytaert's avatar
   
Dries Buytaert committed
362

Dries Buytaert's avatar
   
Dries Buytaert committed
363
364
365
  if ($op == t('Save blocks')) {
    drupal_set_message(block_admin_save($edit));
    cache_clear_all();
366
    drupal_goto($_GET['q']);
Dries Buytaert's avatar
   
Dries Buytaert committed
367
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
368
  print theme('page', block_admin_display());
Dries Buytaert's avatar
 
Dries Buytaert committed
369
}
Dries Buytaert's avatar
   
Dries Buytaert committed
370

Dries Buytaert's avatar
   
Dries Buytaert committed
371
372
373
374
375
376
/**
 * Implementation of hook_user().
 *
 * Allow users to decide which custom blocks to display when they visit
 * the site.
 */
377
function block_user($type, $edit, &$user, $category = NULL) {
378
  switch ($type) {
379
    case 'form':
380
      if ($category == 'account') {
381
        $result = db_query('SELECT * FROM {blocks} WHERE status = 1 AND custom != 0 ORDER BY weight, module, delta');
382
383
384
385

        while ($block = db_fetch_object($result)) {
          $data = module_invoke($block->module, 'block', 'list');
          if ($data[$block->delta]['info']) {
386
            $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->custom == 1));
387
          }
Kjartan Mannes's avatar
Kjartan Mannes committed
388
389
        }

390
391
392
        if (isset($form)) {
          return array(array('title' => t('Block configuration'), 'data' => $form, 'weight' => 2));
        }
393
      }
Dries Buytaert's avatar
   
Dries Buytaert committed
394
395

      break;
Dries Buytaert's avatar
   
Dries Buytaert committed
396
397
398
    case 'validate':
      if (!$edit['block']) {
        $edit['block'] = array();
399
400
      }
      return $edit;
401
402
403
  }
}

404
405
406
/**
 * Return blocks available for current $user at $region.
 *
Dries Buytaert's avatar
   
Dries Buytaert committed
407
 * @param $region main|left|right
408
 *
Dries Buytaert's avatar
   
Dries Buytaert committed
409
 * @return array of block objects, indexed with <i>module</i>_<i>delta</i>
410
 *
Dries Buytaert's avatar
   
Dries Buytaert committed
411
 * @see <a href="http://drupal.org/node/1042" target="_top">[feature]
412
 *   Generic template design difficult w/o block region "look-ahead"</a>
Dries Buytaert's avatar
   
Dries Buytaert committed
413
 * @todo add a proper primary key (bid) to the blocks table so we don't have
414
415
416
417
 *   to mess around with this <i>module</i>_<i>delta</i> construct. currently,
 *   "blocks" has no primary key defined (bad)!
 */
function block_list($region) {
418
  global $user;
419
420
421
422
  static $blocks = array();

  if (!isset($blocks[$region])) {
    $blocks[$region] = array();
423
    $result = db_query('SELECT * FROM {blocks} WHERE status = 1 '. ($region != 'all' ? 'AND region = %d ' : '') .'ORDER BY weight, module', $region == 'left' ? 0 : 1);
424
425

    while ($result && ($block = db_fetch_array($result))) {
426
427
428
429
430
431
432
433
434
435
436
      // 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 = TRUE;
437
      }
438
439

      // Match path if necessary
440
      if ($block['pages']) {
441
        $path = drupal_get_path_alias($_GET['q']);
442
        $regexp = '/^('. preg_replace(array('/(\r\n?|\n)/', '/\\\\\*/', '/(^|\|)\\\\<front\\\\>($|\|)/'), array('|', '.*', '\1'. variable_get('site_frontpage', 'node') .'\2'), preg_quote($block['pages'], '/')) .')$/';
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
        $page_match = !($block['visibility'] xor preg_match($regexp, $path));
      }
      else {
        $page_match = TRUE;
      }
      // Match node type if necessary
      $type_match = FALSE;
      if ($block['types'] != '') {
        if (arg(0) == 'node' && is_numeric(arg(1))) {
          $node = node_load(array('nid' => arg(1)));
          $types = explode(',', $block['types']);
          //Match on any one selected type
          foreach ($types as $type) {
            if ($node->type == $type) {
              $type_match = TRUE;
              break;
            }
          }
        }
462
463
      }
      else {
464
        $type_match = TRUE;
465
466
      }

467
      if ($enabled && $page_match && $type_match) {
468
469
        // Check the current throttle status and see if block should be displayed
        // based on server load.
470
        if (!($block['throttle'] && (module_invoke('throttle', 'status') > 0))) {
471
          $array = module_invoke($block['module'], 'block', 'view', $block['delta']);
Dries Buytaert's avatar
   
Dries Buytaert committed
472
          if (is_array($array)) {
473
474
            $block = array_merge($block, $array);
          }
Dries Buytaert's avatar
   
Dries Buytaert committed
475
        }
Dries Buytaert's avatar
   
Dries Buytaert committed
476
        if (isset($block['content']) && $block['content']) {
477
478
479
480
481
482
483
484
          $blocks[$region]["$block[module]_$block[delta]"] = (object) $block;
        }
      }
    }
  }
  return $blocks[$region];
}

485
?>