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
?>