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

Dries's avatar
   
Dries committed
4
function block_help() {
Steven Wittens's avatar
Steven Wittens committed
5
  $output .= "<p>Blocks are the boxes visible in the side bars on the left- and/or right-hand side of the web site, depending on the chosen theme.  They are either exported by the Drupal engine or by any of the active modules.  To really get your teeth into a Drupal web site, you are going to have to deal with blocks and administering blocks in a fairly sophisticated fashion.  This means you will need to understand how the block placement strategy works.</p>";
Dries's avatar
   
Dries committed
6
7
  $output .= "<p>The placement of blocks is delegated to the administrator. In most cases (i.e., the ". l("\"custom\" blocks","admin/block/add") ."), the user has complete control -- using preferences -- over whether or not they are enabled.</p>";
  $output .= "<p>An administrator can lay out and arrange the available blocks to fit in two regions: \"left\" and \"right\".  Regions simply contain blocks.  In addition, an administrator can assign each block (within a region) a weight to sort them vertically.  The heavier blocks will \"sink\" towards the bottom of the column while the lighter blocks will \"float\" towards the top.</p>";
Steven Wittens's avatar
Steven Wittens committed
8
9
  $output .= "<p>As mentioned, blocks may be arranged to fit in two regions: left and right.  For theme builders, each region is identified by a corresponding constant: \"left\" and \"right\", though some themes may be written to contain only one column \"all\". In this case, all the blocks are sorted by weight and the region setting is ignored.</p>";
  $output .= "<p>The path setting lets you define which pages you want the specific block to be shown. If you leave the path blank it will show on all pages. The path uses a regular expression syntax so remember to escape special characters!<br />Examples:<ul><li>Only show the block on node pages: ^/node\\.php</li><li>Only show the block on the user page: ^/module\\.php\\?mod=user</li><li>Show the block in main and blog pages: ^/(index\\.php|module\\.php\\?mod=blog)</li></ul></p>";
Dries's avatar
   
Dries committed
10
11
12
13
14
  $output .= "<p>The content of the site can be almost entirely altered through ". l("<i>custom blocks</i>", "admin/block/add") .".  Simply put, custom blocks are small bits of text, HTML or PHP code which will get plugged into the site just like any other block.</p>";
  $output .= "<p>Each custom block consists of a title, a description, and a body of text, HTML, or PHP code which can be as long as you wish. The Drupal engine will 'render' the content of the custom block.</p>";
  $output .= "<h3>PHP in custom blocks</h3><p>If you know how to script in PHP, PHP custom blocks are easy to create.  But don't worry if you're no PHP-wizard: simply use HTML instead.</p>";
  $output .= "<p>You can use any piece of PHP code to make up the content of a PHP custom block: this implies that you can declare and use functions, consult the SQL database, access configuration settings and much more.  A PHP custom blocks' code is stored in the database and the engine will dynamically embed the PHP code just-in-time for execution.</p>";
  $output .= "<p>There are however some factors to keep in mind when using and creating PHP custom blocks: PHP custom blocks can be extremely useful and flexible, yet they can be dangerous and insecure if not properly used.  If you are not familiar with PHP, SQL or with the site engine, avoid experimenting with PHP custom blocks because you can - and probably will - corrupt your database or render your site unusable!  If you don't plan to do fancy stuff with custom blocks then you're probably better off with HTML.</p>";
Steven Wittens's avatar
Steven Wittens committed
15
  $output .= "<p>Remember that the code within each PHP custom 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 custom blocks separately using a simple test script on top of a test database before migrating to your production environment.</p>";
Dries's avatar
   
Dries committed
16
  $output .= "<p>Note:<br /><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 <b>off</b>. If you need form information you need to get it from the \"superglobals\" \$_POST, \$_GET, etc.</li></ul></p>";
Steven Wittens's avatar
Steven Wittens committed
17
  $output .= "<p>You <b>have</b> to use the <code>return</code> statement to return the actual content for your block. You <b>may not</b> <code>print</code> or <code>echo</code> it.</p>";
Dries's avatar
   
Dries committed
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
  $output .= "<p><u>A basic example:</u></p>";
  $output .= "<p>Given the box with title \"Welcome\", used to create a \"<i>Welcome</i>\" box.  The content for this box could be created by using:</p>";
  $output .= "<pre>
  return t(\"Welcome visitor, ... welcome message goes here ...\");
</pre>";
  $output .= "<p>If we are however dealing with a registered user, we can customize the message by using:</p>";
  $output .= "<pre>
  if (\$user->uid) {
    return t(\"Welcome \$user->name, ... welcome message goes here ...\");
  }
  else {
    return t(\"Welcome visitor, ... welcome message goes here ...\");
  }
</pre>";
  $output .= "<p>For more in-depth examples, we recommend that you check the existing boxes and use them as a starting point.</p>";
  return t($output);
34

Dries's avatar
   
Dries committed
35
36
}

37
function block_system($field){
Kjartan's avatar
Kjartan committed
38
  $system["description"] = t("Controls the boxes that are displayed around the main content.");
39
40
41
  return $system[$field];
}

Dries's avatar
   
Dries committed
42
function block_perm() {
Dries's avatar
   
Dries committed
43
44
45
46
  return array("administer blocks");
}

function block_link($type) {
Dries's avatar
Dries committed
47
  if ($type == "admin" && user_access("administer blocks")) {
Steven Wittens's avatar
Steven Wittens committed
48
49
   $help["block"] = t("Blocks are the boxes visible in the side bars on the left- and right-hand side of the web site, depending on the chosen theme.  They are created by <b>active</b> Drupal modules.  In order to view a block it must be enabled, then you can assign the block's placement by giving it a region and/or a weight within that region. This sorts them vertically, the smaller the weight, the lighter the block and it will \"float\" towards the top of the page. The path setting is a mask which lets you define on which pages you want the specific block to be shown. The custom checkbox tells Drupal to use a custom designed block, see both <a href=\"%help\">help</a> and <a href=\"%block\">create new block</a> for more information on custom blocks. If you have a custom block then the \"edit\" and \"delete\" operations will be displayed to edit/delete your custom block.", array("%help" => url("admin/block/help"), "%block" => url("admin/block/add")));
    $help["create"] = t("Below you can create a block to be used in the side bars. Once you have created this block you must make it active, and give it a place on the page by using <a href=\"%overview\">block management</a>. The title is used when displaying the block. The description is used in the \"block\" column on the <a href=\"%overview\">block management</a> page. If you are going to place PHP code in the block, and you have <b>create PHP content</b> permission (see <a href=\"%permission\">user management >> user permissions</a>) you <b>must</b> change the type to PHP to make your code active.", array("%overview" => url("admin/block"), "%permission" => url("admin/user/permission")));
Dries's avatar
   
Dries committed
50
    $help["preview"] = t("This page shows you the placement of your blocks. Each block is represented by its block name, and it's weight. <b>Layout scheme #1</b> is a layout with both left and right columns. <b>Layout scheme #2</b> has only a right column. And <b>layout scheme #3</b> only a left column.");
Dries's avatar
   
Dries committed
51

Dries's avatar
   
Dries committed
52
    menu("admin/block", "block management", "block_admin", $help["block"], 3);
Dries's avatar
   
Dries committed
53
54
    menu("admin/block/add", "create new block", "block_admin", $help["create"], 2);
    menu("admin/block/preview", "preview placement", "block_admin", $help["preview"], 3);
Dries's avatar
   
Dries committed
55
    menu("admin/block/help", "help", "block_help", NULL, 9);
Dries's avatar
   
Dries committed
56
  }
Dries's avatar
   
Dries committed
57
58
}

Dries's avatar
   
Dries committed
59
60
61
62
function block_block($op = "list", $delta = 0) {
  if ($op == "list") {
    $result = db_query("SELECT bid, title, info FROM boxes ORDER BY title");
    while ($block = db_fetch_object($result)) {
Dries's avatar
   
Dries committed
63
      $blocks[$block->bid]["info"] = $block->info;
Dries's avatar
   
Dries committed
64
65
66
67
    }
    return $blocks;
  }
  else {
Dries's avatar
   
Dries committed
68
    $block = db_fetch_object(db_query("SELECT * FROM boxes WHERE bid = %d", $delta));
Dries's avatar
   
Dries committed
69
    $data["subject"] = $block->title;
Dries's avatar
   
Dries committed
70
71
    $data["content"] = ($block->type == 1) ? eval($block->body) : $block->body;
    return $data;
72
73
74
  }
}

Dries's avatar
 
Dries committed
75
function block_admin_save($edit) {
Dries's avatar
   
Dries committed
76
77
  foreach ($edit as $module => $blocks) {
    foreach ($blocks as $delta => $block) {
Dries's avatar
   
Dries committed
78
      db_query("UPDATE blocks SET region = %d, status = %d, custom = %d, path = '%s', weight = %d WHERE module = '%s' AND delta = '%s'",
Dries's avatar
   
Dries committed
79
                $block["region"], $block["status"], $block["custom"], $block["path"], $block["weight"], $module, $delta);
Dries's avatar
   
Dries committed
80
    }
Dries's avatar
 
Dries committed
81
  }
Dries's avatar
   
Dries committed
82

Dries's avatar
   
Dries committed
83
  return t("the block settings have been updated.");
Dries's avatar
 
Dries committed
84
85
}

Dries's avatar
   
Dries committed
86
87
/**
 * update blocks db table with blocks currently exported by modules
Dries's avatar
   
Dries committed
88
 *
Dries's avatar
   
Dries committed
89
90
91
92
93
94
 * @param   array   $order_by   php array_multisort() style sort ordering, eg. "weight", SORT_ASC, SORT_STRING. see {@link http://www.php.net/manual/en/function.array-multisort.php}
 * @return  array   blocks currently exported by modules, sorted by $order_by
 * @access  private
 */
function _block_rehash($order_by = array("weight")) {
  $result = db_query("SELECT * FROM blocks");
Dries's avatar
   
Dries committed
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
  while ($old_block = db_fetch_object($result)) {
    $old_blocks[$old_block->module][$old_block->delta] = $old_block;
  }

  db_query("DELETE FROM blocks");

  foreach (module_list() as $module) {
    $module_blocks = module_invoke($module, "block", "list");
    if ($module_blocks) {
      foreach ($module_blocks as $delta => $block) {
        $block["module"] = $module;
        $block["delta"]  = $delta;
        if ($old_blocks[$module][$delta]) {
          $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;
        }
        else {
          $block["status"] = $block["weight"] = $block["region"] = $block["custom"] = 0;
          $block["path"]   = "";
        }

        // reinsert blocks into table
Dries's avatar
   
Dries committed
120
        db_query("INSERT INTO blocks (module, delta, status, weight, region, path, custom) VALUES ('%s', '%s', %d, %d, %d, '%s', %d)",
Dries's avatar
   
Dries committed
121
                  $block["module"], $block["delta"], $block["status"], $block["weight"], $block["region"], $block["path"], $block["custom"]);
Dries's avatar
   
Dries committed
122
123

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

Dries's avatar
   
Dries committed
125
126
        // build array to sort on
        $order[$order_by[0]][] = $block[$order_by[0]];
Dries's avatar
   
Dries committed
127
128
129
130
      }
    }
  }

Dries's avatar
   
Dries committed
131
132
133
  // 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's avatar
   
Dries committed
134
135
  return $blocks;
}
Dries's avatar
   
Dries committed
136

Dries's avatar
   
Dries committed
137
function block_admin_display() {
Dries's avatar
   
Dries committed
138

Dries's avatar
   
Dries committed
139
  $blocks = _block_rehash();
Dries's avatar
   
Dries committed
140

Dries's avatar
   
Dries committed
141
142
  $header = array(t("block"), t("enabled"), t("custom"), t("weight"), t("region"), t("path"), array("data" => "operations", "colspan" => 2));

Dries's avatar
   
Dries committed
143
  foreach ($blocks as $block) {
Dries's avatar
   
Dries committed
144
    if ($block["module"] == "block") {
Dries's avatar
   
Dries committed
145
      $edit = l(t("edit"), "admin/block/edit/". $block["delta"]);
Dries's avatar
   
Dries committed
146
      $delete = l(t("delete"), "admin/block/delete/". $block["delta"]);
147
    }
Dries's avatar
   
Dries committed
148
149
150
151
    else {
      $edit = "";
      $delete = "";
    }
Dries's avatar
   
Dries committed
152
153

    $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"), form_weight(NULL, $block["module"]."][".$block["delta"]."][weight", $block["weight"]), form_select(NULL, $block["module"]."][".$block["delta"]."][region", $block["region"], array("left", "right")), form_textfield(NULL, $block["module"]."][".$block["delta"]."][path", $block["path"], 10, 255), $edit, $delete);
Dries's avatar
 
Dries committed
154
  }
Dries's avatar
   
Dries committed
155

Dries's avatar
   
Dries committed
156
  $output = table($header, $rows);
157
  $output .= form_submit("Save blocks");
Dries's avatar
 
Dries committed
158

159
  print form($output);
Dries's avatar
 
Dries committed
160
161
}

Dries's avatar
   
Dries committed
162
function block_admin_preview() {
Dries's avatar
   
Dries committed
163
164

  $result = db_query("SELECT * FROM blocks WHERE status > 0 AND region = 0 ORDER BY weight");
Dries's avatar
   
Dries committed
165
  $lblocks .= "<table border=\"0\" cellpadding=\"2\" cellspacing=\"2\">\n";
Dries's avatar
   
Dries committed
166
167
168
169
170
  while ($block = db_fetch_object($result)) {
    $block_data = module_invoke($block->module, "block", "list");
    $name = $block_data[$block->delta]["info"];
    $lblocks .= " <tr><td nowrap=\"nowrap\">". ($block->status == 2 ? "<b>$name</b>" : $name) ."</td><td>$block->weight</td></tr>\n";
  }
Dries's avatar
   
Dries committed
171
  $lblocks .= "</table>\n";
Dries's avatar
   
Dries committed
172
173

  $result = db_query("SELECT * FROM blocks WHERE status > 0 AND region = 1 ORDER BY weight");
Dries's avatar
   
Dries committed
174
  $rblocks .= "<table border=\"0\" cellpadding=\"2\" cellspacing=\"2\">\n";
Dries's avatar
   
Dries committed
175
176
177
178
179
  while ($block = db_fetch_object($result)) {
    $block_data = module_invoke($block->module, "block", "list");
    $name = $block_data[$block->delta]["info"];
    $rblocks .= " <tr><td nowrap=\"nowrap\">". ($block->status == 2 ? "<b>$name</b>" : $name) ."</td><td>$block->weight</td></tr>\n";
  }
Dries's avatar
   
Dries committed
180
  $rblocks .= "</table>\n";
Dries's avatar
   
Dries committed
181

Dries's avatar
   
Dries committed
182
183
184
185
186
187
  $output .= "<h3>layout scheme #1:</h3>\n";
  $output .= "<table border=\"1\" cellpadding=\"2\" cellspacing=\"2\">\n";
  $output .= " <tr><td align=\"center\" colspan=\"3\">header</td></tr>\n";
  $output .= " <tr><td>\n". ($lblocks ? $lblocks : "&nbsp;") ."</td><td width=\"300\">&nbsp;</td><td>\n". ($rblocks ? $rblocks : "&nbsp;") ."</td></tr>\n";
  $output .= " <tr><td align=\"center\" colspan=\"3\">footer</td></tr>\n";
  $output .= "</table>\n";
Dries's avatar
   
Dries committed
188
189

  $result = db_query("SELECT * FROM blocks WHERE status > 0 ORDER BY weight");
Dries's avatar
   
Dries committed
190
  $blocks .= "<table border=\"0\" cellpadding=\"2\" cellspacing=\"2\">\n";
Dries's avatar
   
Dries committed
191
192
193
194
195
  while ($block = db_fetch_object($result)) {
    $block_data = module_invoke($block->module, "block", "list");
    $name = $block_data[$block->delta]["info"];
    $blocks .= " <tr><td nowrap=\"nowrap\">". ($block->status == 2 ? "<b>$name</b>" : $name) ."</td><td>$block->weight</td></tr>\n";
  }
Dries's avatar
   
Dries committed
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
  $blocks .= "</table>\n";

  $output .= "<h3>layout scheme #2:</h3>\n";
  $output .= "<table border=\"1\" cellpadding=\"2\" cellspacing=\"2\">\n";
  $output .= " <tr><td align=\"center\" colspan=\"2\">header</td></tr>\n";
  $output .= " <tr><td width=\"400\">&nbsp;</td><td>\n". ($blocks ? $blocks : "&nbsp;") ."</td></tr>\n";
  $output .= " <tr><td align=\"center\" colspan=\"2\">footer</td></tr>\n";
  $output .= "</table>\n";

  $output .= "<h3>layout scheme #3:</h3>\n";
  $output .= "<table border=\"1\" cellpadding=\"2\" cellspacing=\"2\">\n";
  $output .= " <tr><td align=\"center\" colspan=\"2\">header</td></tr>\n";
  $output .= " <tr><td>\n". ($blocks ? $blocks : "&nbsp;") ."</td><td width=\"400\">&nbsp;</td></tr>\n";
  $output .= " <tr><td align=\"center\" colspan=\"2\">footer</td></tr>\n";
  $output .= "</table>\n";
Dries's avatar
   
Dries committed
211
212
213
214

  print $output;
}

215
function block_box_get($bid) {
Dries's avatar
   
Dries committed
216
  return db_fetch_array(db_query("SELECT * FROM boxes WHERE bid = %d", $bid));
217
218
219
}

function block_box_form($edit = array()) {
Dries's avatar
   
Dries committed
220
  $type = array(0 => "HTML", 1 => "PHP");
221

Dries's avatar
   
Dries committed
222
  $form = form_textfield("Title", "title", $edit["title"], 50, 64);
223
224
  $form .= form_textfield("Description", "info", $edit["info"], 50, 64);
  $form .= form_textarea("Body", "body", $edit["body"], 70, 10);
Kjartan's avatar
Kjartan committed
225
  if (user_access("create php content")) {
Dries's avatar
   
Dries committed
226
227
    $form .= form_select("Type", "type", $edit["type"], $type);
  }
228
229
230
231
232
233
234
235
236
237
238

  if ($edit["bid"]) {
    $form .= form_hidden("bid", $edit["bid"]);
  }

  $form .= form_submit("Save block");

  print form($form);
}

function block_box_save($edit) {
Dries's avatar
   
Dries committed
239
240
241
242
  if (!user_access("create PHP content")) {
    $edit["type"] = 0;
  }

243
  if ($edit["bid"]) {
Dries's avatar
   
Dries committed
244
    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"]);
Dries's avatar
   
Dries committed
245
    return t("the block has been updated.");
246
247
  }
  else {
Dries's avatar
   
Dries committed
248
    db_query("INSERT INTO boxes (title, body, info, type) VALUES  ('%s', '%s', '%s', %d)", $edit["title"], $edit["body"], $edit["info"], $edit["type"]);
Dries's avatar
   
Dries committed
249
    return t("the new block has been added.");
250
251
252
253
254
  }
}

function block_box_delete($bid) {
  if ($bid) {
Dries's avatar
   
Dries committed
255
    db_query("DELETE FROM boxes WHERE bid = %d", $bid);
Dries's avatar
   
Dries committed
256
    return t("the block has been deleted.");
257
258
259
  }
}

Dries's avatar
 
Dries committed
260
function block_admin() {
Dries's avatar
   
Dries committed
261
262
  $op = $_POST["op"];
  $edit = $_POST["edit"];
Dries's avatar
   
Dries committed
263

Dries's avatar
   
Dries committed
264
  if (user_access("administer blocks")) {
Dries's avatar
   
Dries committed
265

Dries's avatar
   
Dries committed
266
267
268
269
    if (empty($op)) {
      $op = arg(2);
    }

Dries's avatar
   
Dries committed
270
271
272
273
    switch ($op) {
      case "preview":
        block_admin_preview();
        break;
274
275
276
277
      case "add":
        block_box_form();
        break;
      case "edit":
Dries's avatar
   
Dries committed
278
        block_box_form(block_box_get(arg(3)));
279
280
        break;
      case "delete":
Dries's avatar
   
Dries committed
281
        print status(block_box_delete(arg(3)));
Dries's avatar
   
Dries committed
282
        cache_clear_all();
283
284
285
286
        block_admin_display();
        break;
      case "Save block":
        print status(block_box_save($edit));
Dries's avatar
   
Dries committed
287
        cache_clear_all();
288
289
        block_admin_display();
        break;
Dries's avatar
   
Dries committed
290
      case "Save blocks":
Dries's avatar
   
Dries committed
291
292
        print status(block_admin_save($edit));
        cache_clear_all();
Dries's avatar
   
Dries committed
293
294
295
296
297
298
299
        // fall through
      default:
        block_admin_display();
    }
  }
  else {
    print message_access();
Dries's avatar
 
Dries committed
300
301
  }
}
Dries's avatar
   
Dries committed
302

303
304
function block_user($type, &$edit, &$user) {
  switch ($type) {
305
    case "register_form":
Dries's avatar
   
Dries committed
306
      $result = db_query("SELECT * FROM blocks WHERE custom = %d ORDER BY module, delta", 1);
307
308

      while ($block = db_fetch_object($result)) {
Dries's avatar
   
Dries committed
309
        $form .= form_hidden("block][$block->module][$block->delta", $block->status);
310
311
312
      }

      return $form;
313
    case "edit_form":
Dries's avatar
   
Dries committed
314
      $result = db_query("SELECT * FROM blocks WHERE custom = %d ORDER BY module, delta", 1);
315
316

      while ($block = db_fetch_object($result)) {
Dries's avatar
   
Dries committed
317
318
319
        $data = module_invoke($block->module, "block", "list");
        if ($data[$block->delta]["info"]) {
          $form .= "<tr><td>".$data[$block->delta]["info"]."</td><td>". form_checkbox(NULL, "block][$block->module][$block->delta", 1, $user->block[$block->module][$block->delta]) ."</td></tr>\n";
Kjartan's avatar
Kjartan committed
320
321
322
323
        }
      }

      if (isset($form)) {
Dries's avatar
   
Dries committed
324
        return form_item(t("Block configuration"), "<table border=\"0\" cellpadding=\"2\" cellspacing=\"2\">". $form ."</table>", t("Enable the blocks you would like to see displayed in the side bars."));
325
      }
Dries's avatar
   
Dries committed
326
327

      break;
328
329
330
331
332
    case "edit_validate":
      if (!$edit["block"]) {
        $edit["block"] = array();
      }
      return $edit;
333
334
335
  }
}

Dries's avatar
   
Dries committed
336
?>