block.module 19.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
/**
 * Implementation of hook_help().
 */
function block_help($section) {
Dries Buytaert's avatar
   
Dries Buytaert committed
8
  switch ($section) {
Dries Buytaert's avatar
   
Dries Buytaert committed
9
    case 'admin/help#block':
Dries Buytaert's avatar
   
Dries Buytaert committed
10
      return t("
Dries Buytaert's avatar
   
Dries Buytaert committed
11
<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 using either static HTML or dynamic PHP content.</p>
Dries Buytaert's avatar
   
Dries Buytaert committed
12
<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
13
<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
14
<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
15
16
<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
17
<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
18
19
20
21
22
<h3>Administrator Defined Blocks</h3>
<p>An administrator defined block contains HTML, text or PHP 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 containing text, HTML, or PHP code which can be as long as you wish. The Drupal engine will 'render' the content of the block.</p>
<h4>PHP in admin-defined blocks</h4>
<p>If you know how to script in PHP, Drupal gives you the power to embed any script you like inside a block. It will be executed when the page is viewed and dynamically embedded into the page. This gives you amazing flexibility and power, but of course with that comes danger and insecurity if you don't write good code. If you are not familiar with PHP, SQL or with the site engine, avoid experimenting with PHP blocks because you can corrupt your database or render your site insecure or even unusable! If you don't plan to do fancy stuff with your blocks then you're probably better off with straight HTML.</p>
<p>Remember that the code within each PHP block must be valid PHP code - including things like correctly terminating statements with a semicolon so that the parser won't die. It is highly recommended that you develop your blocks separately using a simple test script on top of a test database before migrating to your production environment.</p>
23
<p>Notes:</p><ul><li>You can use global variables, such as configuration parameters, within the scope of a PHP box but remember that variables which have been given values in a PHP box will retain these values in the engine or module afterwards.</li><li>register_globals is now set to <strong>off</strong> by default. If you need form information you need to get it from the \"superglobals\" \$_POST, \$_GET, etc.</li><li>You should use the <code>return</code> statement to return the actual content for your block.</li></ul>
Dries Buytaert's avatar
   
Dries Buytaert committed
24
25
26
<p>A basic example:</p>
<blockquote><p>You want to have a box with the title \"Welcome\" that you use to greet your visitors. The content for this box could be created by going:</p>
<pre>
Dries Buytaert's avatar
   
Dries Buytaert committed
27
  return t(\"Welcome visitor, ... welcome message goes here ...\");
Dries Buytaert's avatar
   
Dries Buytaert committed
28
29
30
</pre>
<p>If we are however dealing with a registered user, we can customize the message by using:</p>
<pre>
Dries Buytaert's avatar
   
Dries Buytaert committed
31
32
33
34
35
  if (\$user->uid) {
    return t(\"Welcome \$user->name, ... welcome message goes here ...\");
  }
  else {
    return t(\"Welcome visitor, ... welcome message goes here ...\");
Dries Buytaert's avatar
   
Dries Buytaert committed
36
37
  }
</pre></blockquote>
Dries Buytaert's avatar
   
Dries Buytaert committed
38
<p>For more in-depth examples, we recommend that you check the existing boxes and use them as a starting point.</p>", array('%pcre' => 'http://php.net/pcre/'));
Dries Buytaert's avatar
   
Dries Buytaert committed
39
    case 'admin/modules#description':
Dries Buytaert's avatar
   
Dries Buytaert committed
40
      return t('Controls the boxes that are displayed around the main content.');
Dries Buytaert's avatar
   
Dries Buytaert committed
41
42
43
    case 'admin/block':
      return t("Blocks are the boxes in the left- and right- side bars of the web site, depending on the chosen theme.  They are created by <strong>active</strong> Drupal modules. 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. You can also create your own blocks, where you specify the content of the block rather than its being generated by a module (you can even use PHP in these). You can create one of these by clicking the <a href=\"%createblock\">add block</a> tab in the menu to the left. Edit and delete links will become active below for these admin-defined blocks.  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('%createblock' => url('admin/block/add'), '%throttle' => url('admin/settings/throttle')));
    case 'admin/block/add':
44
      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
45
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
46
47
}

Dries Buytaert's avatar
   
Dries Buytaert committed
48
/**
49
 * Menu callback; presents the block-specific information from admin/help.
Dries Buytaert's avatar
   
Dries Buytaert committed
50
 */
Dries Buytaert's avatar
   
Dries Buytaert committed
51
function block_help_page() {
Dries Buytaert's avatar
   
Dries Buytaert committed
52
  print theme('page', block_help('admin/help#block'));
Dries Buytaert's avatar
   
Dries Buytaert committed
53
54
}

Dries Buytaert's avatar
   
Dries Buytaert committed
55
56
57
/**
 * Implementation of hook_perm().
 */
Dries Buytaert's avatar
   
Dries Buytaert committed
58
function block_perm() {
Dries Buytaert's avatar
   
Dries Buytaert committed
59
  return array('administer blocks');
Dries Buytaert's avatar
   
Dries Buytaert committed
60
61
}

Dries Buytaert's avatar
   
Dries Buytaert committed
62
/**
Dries Buytaert's avatar
   
Dries Buytaert committed
63
 * Implementation of hook_menu().
Dries Buytaert's avatar
   
Dries Buytaert committed
64
 */
Dries Buytaert's avatar
   
Dries Buytaert committed
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
function block_menu() {
  $items = array();
  $items[] = array('path' => 'admin/block', 'title' => t('blocks'),
    'access' => user_access('administer blocks'),
    'callback' => 'block_admin');
  $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:
  $items[] = array('path' => 'admin/block/add', 'title' => t('add block'),
    'access' => user_access('administer blocks'),
    'callback' => 'block_box_edit',
    'type' => MENU_LOCAL_TASK);
  return $items;
Dries Buytaert's avatar
   
Dries Buytaert committed
84
85
}

Dries Buytaert's avatar
   
Dries Buytaert committed
86
87
88
89
90
91
92
93
/**
 * 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
94
    while ($block = db_fetch_object($result)) {
Dries Buytaert's avatar
   
Dries Buytaert committed
95
      $blocks[$block->bid]['info'] = $block->info;
Dries Buytaert's avatar
   
Dries Buytaert committed
96
97
98
99
    }
    return $blocks;
  }
  else {
Dries Buytaert's avatar
   
Dries Buytaert committed
100
101
102
    $block = db_fetch_object(db_query('SELECT * FROM {boxes} WHERE bid = %d', $delta));
    $data['subject'] = $block->title;
    $data['content'] = ($block->type == 1) ? eval($block->body) : $block->body;
Dries Buytaert's avatar
   
Dries Buytaert committed
103
    return $data;
104
105
106
  }
}

Dries Buytaert's avatar
 
Dries Buytaert committed
107
function block_admin_save($edit) {
Dries Buytaert's avatar
   
Dries Buytaert committed
108
109
  foreach ($edit as $module => $blocks) {
    foreach ($blocks as $delta => $block) {
Dries Buytaert's avatar
   
Dries Buytaert committed
110
      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
111
                $block['region'], $block['status'], $block['custom'], $block['path'], $block['weight'], $block['throttle'], $module, $delta);
Dries Buytaert's avatar
   
Dries Buytaert committed
112
    }
Dries Buytaert's avatar
 
Dries Buytaert committed
113
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
114

Dries Buytaert's avatar
   
Dries Buytaert committed
115
  return t('the block settings have been updated.');
Dries Buytaert's avatar
 
Dries Buytaert committed
116
117
}

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

Dries Buytaert's avatar
   
Dries Buytaert committed
134
  db_query('DELETE FROM {blocks} ');
Dries Buytaert's avatar
   
Dries Buytaert committed
135
136

  foreach (module_list() as $module) {
Dries Buytaert's avatar
   
Dries Buytaert committed
137
    $module_blocks = module_invoke($module, 'block', 'list');
Dries Buytaert's avatar
   
Dries Buytaert committed
138
139
    if ($module_blocks) {
      foreach ($module_blocks as $delta => $block) {
Dries Buytaert's avatar
   
Dries Buytaert committed
140
141
        $block['module'] = $module;
        $block['delta']  = $delta;
Dries Buytaert's avatar
   
Dries Buytaert committed
142
        if ($old_blocks[$module][$delta]) {
Dries Buytaert's avatar
   
Dries Buytaert committed
143
144
145
146
147
148
          $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
149
150
        }
        else {
Dries Buytaert's avatar
   
Dries Buytaert committed
151
152
          $block['status'] = $block['weight'] = $block['region'] = $block['custom'] = 0;
          $block['path']   = '';
Dries Buytaert's avatar
   
Dries Buytaert committed
153
154
155
        }

        // reinsert blocks into table
Dries Buytaert's avatar
   
Dries Buytaert committed
156
        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
157
                  $block['module'], $block['delta'], $block['status'], $block['weight'], $block['region'], $block['path'], $block['custom'], $block['throttle']);
Dries Buytaert's avatar
   
Dries Buytaert committed
158
159

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

Dries Buytaert's avatar
   
Dries Buytaert committed
161
162
        // build array to sort on
        $order[$order_by[0]][] = $block[$order_by[0]];
Dries Buytaert's avatar
   
Dries Buytaert committed
163
164
165
166
      }
    }
  }

Dries Buytaert's avatar
   
Dries Buytaert committed
167
168
169
  // 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
170
171
  return $blocks;
}
Dries Buytaert's avatar
   
Dries Buytaert committed
172

Dries Buytaert's avatar
   
Dries Buytaert committed
173
174
175
/**
 * Prepare the main block administration form.
 */
Dries Buytaert's avatar
   
Dries Buytaert committed
176
function block_admin_display() {
Dries Buytaert's avatar
   
Dries Buytaert committed
177

Dries Buytaert's avatar
   
Dries Buytaert committed
178
  $blocks = _block_rehash();
Dries Buytaert's avatar
   
Dries Buytaert committed
179

Dries Buytaert's avatar
   
Dries Buytaert committed
180
  $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
181

Dries Buytaert's avatar
   
Dries Buytaert committed
182
  foreach ($blocks as $block) {
Dries Buytaert's avatar
   
Dries Buytaert committed
183
    if ($block['module'] == 'block') {
184
185
      $edit = l(t('edit block'), 'admin/block/edit/'. $block['delta']);
      $delete = l(t('delete block'), 'admin/block/delete/'. $block['delta']);
186
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
187
    else {
Dries Buytaert's avatar
   
Dries Buytaert committed
188
189
      $edit = '';
      $delete = '';
Dries Buytaert's avatar
   
Dries Buytaert committed
190
    }
Dries Buytaert's avatar
   
Dries Buytaert committed
191

Dries Buytaert's avatar
   
Dries Buytaert committed
192
    $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
193
    $edit, $delete);
Dries Buytaert's avatar
 
Dries Buytaert committed
194
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
195

Dries Buytaert's avatar
   
Dries Buytaert committed
196
197
  $output = theme('table', $header, $rows);
  $output .= form_submit(t('Save blocks'));
Dries Buytaert's avatar
 
Dries Buytaert committed
198

Dries Buytaert's avatar
   
Dries Buytaert committed
199
  return form($output, 'post', url('admin/block'));
Dries Buytaert's avatar
 
Dries Buytaert committed
200
201
}

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

/**
207
208
209
 * Menu callback; displays the block editing form.
 *
 * On edit, saves changes and displays the block overview.
Dries Buytaert's avatar
   
Dries Buytaert committed
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
 */
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);
230
231
232
}

function block_box_form($edit = array()) {
Dries Buytaert's avatar
   
Dries Buytaert committed
233
  $type = array(0 => 'HTML', 1 => 'PHP');
234

235
236
237
  $group = form_textfield(t('Block title'), 'title', $edit['title'], 50, 64, t('The title of the block as shown to the user.'));
  $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'))));
Dries Buytaert's avatar
   
Dries Buytaert committed
238
  if (user_access('create php content')) {
239
    $group .= form_radios(t('Block type'), 'type', $edit['type'], $type, t("If you would like to use PHP code inside your block, set the above option to 'PHP' instead of 'HTML'."));
Dries Buytaert's avatar
   
Dries Buytaert committed
240
  }
241

Dries Buytaert's avatar
   
Dries Buytaert committed
242
  if ($edit['bid']) {
243
    $group .= form_hidden('bid', $edit['bid']);
244
245
  }

246
  $group .= form_submit(t('Save block'));
247

248
249
  $output = form_group(t('Add a new block'), $group);
  return form($output);
250
251
252
}

function block_box_save($edit) {
Dries Buytaert's avatar
   
Dries Buytaert committed
253
254
  if (!user_access('create php content')) {
    $edit['type'] = 0;
Dries Buytaert's avatar
   
Dries Buytaert committed
255
256
  }

Dries Buytaert's avatar
   
Dries Buytaert committed
257
258
259
  if ($edit['bid']) {
    db_query("UPDATE {boxes} SET title = '%s', body = '%s', info = '%s', type = %d WHERE bid = %d", $edit['title'], $edit['body'], $edit['info'], $edit['type'], $edit['bid']);
    return t('the block has been updated.');
260
261
  }
  else {
Dries Buytaert's avatar
   
Dries Buytaert committed
262
263
    db_query("INSERT INTO {boxes} (title, body, info, type) VALUES  ('%s', '%s', '%s', %d)", $edit['title'], $edit['body'], $edit['info'], $edit['type']);
    return t('the new block has been added.');
264
265
266
  }
}

Dries Buytaert's avatar
   
Dries Buytaert committed
267
/**
268
 * Menu callback; deletes a custom box, then displays the overview page.
Dries Buytaert's avatar
   
Dries Buytaert committed
269
270
 */
function block_box_delete($bid = 0) {
271
  if ($bid) {
Dries Buytaert's avatar
   
Dries Buytaert committed
272
273
274
    db_query('DELETE FROM {boxes} WHERE bid = %d', $bid);
    drupal_set_message(t('the block has been deleted.'));
    cache_clear_all();
275
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
276
  print theme('page', block_admin_display());
277
278
}

Dries Buytaert's avatar
   
Dries Buytaert committed
279
/**
280
 * Menu callback; displays the block overview page.
Dries Buytaert's avatar
   
Dries Buytaert committed
281
 */
Dries Buytaert's avatar
 
Dries Buytaert committed
282
function block_admin() {
Dries Buytaert's avatar
   
Dries Buytaert committed
283
284
  $edit = $_POST['edit'];
  $op = $_POST['op'];
Dries Buytaert's avatar
   
Dries Buytaert committed
285

Dries Buytaert's avatar
   
Dries Buytaert committed
286
287
288
  if ($op == t('Save blocks')) {
    drupal_set_message(block_admin_save($edit));
    cache_clear_all();
Dries Buytaert's avatar
   
Dries Buytaert committed
289
  }
Dries Buytaert's avatar
   
Dries Buytaert committed
290
  print theme('page', block_admin_display());
Dries Buytaert's avatar
 
Dries Buytaert committed
291
}
Dries Buytaert's avatar
   
Dries Buytaert committed
292

Dries Buytaert's avatar
   
Dries Buytaert committed
293
294
295
296
297
298
/**
 * Implementation of hook_user().
 *
 * Allow users to decide which custom blocks to display when they visit
 * the site.
 */
299
function block_user($type, $edit, &$user, $category = NULL) {
300
  switch ($type) {
301
    case 'form':
302
303
304
305
306
307
308
309
      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
310
311
        }

312
313
314
        if (isset($form)) {
          return array(array('title' => t('Block configuration'), 'data' => $form, 'weight' => 2));
        }
315
      }
Dries Buytaert's avatar
   
Dries Buytaert committed
316
317

      break;
Dries Buytaert's avatar
   
Dries Buytaert committed
318
319
320
    case 'validate':
      if (!$edit['block']) {
        $edit['block'] = array();
321
322
      }
      return $edit;
323
324
325
  }
}

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

  if (!isset($blocks[$region])) {
    $blocks[$region] = array();
Dries Buytaert's avatar
   
Dries Buytaert committed
345
    $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);
346
347

    while ($result && ($block = db_fetch_array($result))) {
348
349
350
351
      // 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'];
      }
352
353
      $base = parse_url($base_url);
      if ((($block['status'] && (!$user->uid || !$block['custom'])) || ($block['custom'] && $user->block[$block['module']][$block['delta']])) && (!$block['path'] || preg_match($block['path'], ereg_replace('^/(\?q=)?', '', str_replace($base['path'], '', request_uri()))))) {
Dries Buytaert's avatar
   
Dries Buytaert committed
354
355

        /*
356
357
        ** Check the current throttle status and see if block should be displayed
        ** based on server load.
Dries Buytaert's avatar
   
Dries Buytaert committed
358
        */
Dries Buytaert's avatar
   
Dries Buytaert committed
359
        if (!($block['throttle'] && (module_invoke('throttle', 'status') > 4))) {
Dries Buytaert's avatar
   
Dries Buytaert committed
360
361
          $block = array_merge($block, module_invoke($block['module'], 'block', 'view', $block['delta']));
        }
Dries Buytaert's avatar
   
Dries Buytaert committed
362
        if (isset($block['content']) && $block['content']) {
363
364
365
366
367
368
369
370
          $blocks[$region]["$block[module]_$block[delta]"] = (object) $block;
        }
      }
    }
  }
  return $blocks[$region];
}

371
?>