common.inc 31.8 KB
Newer Older
Dries's avatar
 
Dries committed
1 2 3 4 5 6 7 8 9 10 11
<?php
// $Id$

function conf_init() {

  /*
  ** Try finding a matching configuration file by stripping the website's
  ** URI from left to right.  If no configuration file is found, return a
  ** default value 'conf'.
  */

Dries's avatar
 
Dries committed
12
  $uri = $_SERVER["PHP_SELF"];
Dries's avatar
 
Dries committed
13

Dries's avatar
 
Dries committed
14
  $file = strtolower(strtr($_SERVER["HTTP_HOST"] . substr($uri, 0, strrpos($uri, "/")), "/:", ".."));
Dries's avatar
 
Dries committed
15 16 17 18 19 20 21 22 23 24 25 26 27

  while (strlen($file) > 4) {
    if (file_exists("includes/$file.php")) {
      return $file;
    }
    else {
      $file = substr($file, strpos($file, ".") + 1);
    }
  }

  return "conf";
}

Dries's avatar
 
Dries committed
28 29 30
/**
 * Build the alias/path array
 */
Dries's avatar
 
Dries committed
31
function drupal_get_path_map($action = "") {
Dries's avatar
 
Dries committed
32 33

  static $cache;
Dries's avatar
 
Dries committed
34 35
  static $map;

Dries's avatar
 
Dries committed
36 37
  if ($action == "rebuild") {
    $map = NULL;
Dries's avatar
 
Dries committed
38
    $cache = 0;
Dries's avatar
 
Dries committed
39 40
  }

Dries's avatar
 
Dries committed
41
  if (!$cache) {
Dries's avatar
 
Dries committed
42
    $result = db_query("SELECT * FROM {url_alias}");
Dries's avatar
 
Dries committed
43
    while ($data = db_fetch_object($result)) {
Dries's avatar
 
Dries committed
44
      $map[$data->dst] = $data->src;
Dries's avatar
 
Dries committed
45
    }
Dries's avatar
 
Dries committed
46 47

    $cache = 1;
Dries's avatar
 
Dries committed
48 49 50 51 52
  }

  return $map;
}

Dries's avatar
 
Dries committed
53 54 55 56
function drupal_rebuild_path_map() {
  drupal_get_path_map("rebuild");
}

Dries's avatar
 
Dries committed
57 58 59
function error_handler($errno, $message, $filename, $line, $variables) {
  $types = array(1 => "error", 2 => "warning", 4 => "parse error", 8 => "notice", 16 => "core error", 32 => "core warning", 64 => "compile error", 128 => "compile warning", 256 => "user error", 512 => "user warning", 1024 => "user notice");
  $entry = $types[$errno] .": $message in $filename on line $line.";
Dries's avatar
 
Dries committed
60 61

  if ($errno & E_ALL ^ E_NOTICE) {
Dries's avatar
 
Dries committed
62
    watchdog("error", $types[$errno] .": $message in $filename on line $line.");
63
    print "<pre>$entry</pre>";
Dries's avatar
 
Dries committed
64 65 66
  }
}

Dries's avatar
 
Dries committed
67
function watchdog($type, $message, $link = NULL) {
Dries's avatar
 
Dries committed
68
  global $user;
Dries's avatar
 
Dries committed
69
  db_query("INSERT INTO {watchdog} (uid, type, message, link, location, hostname, timestamp) VALUES (%d, '%s', '%s', '%s', '%s', '%s', %d)", $user->uid, $type, $message, $link, request_uri(), getenv("REMOTE_ADDR"), time());
Dries's avatar
 
Dries committed
70 71 72 73
}

function throttle($type, $rate) {
  if (!user_access("access administration pages")) {
Dries's avatar
 
Dries committed
74
    if ($throttle = db_fetch_object(db_query("SELECT * FROM {watchdog} WHERE type = '$type' AND hostname = '". getenv("REMOTE_ADDR") ."' AND ". time() ." - timestamp < $rate"))) {
Dries's avatar
 
Dries committed
75 76 77 78 79 80 81 82 83
      watchdog("warning", "throttle: '". getenv("REMOTE_ADDR") ."' exceeded submission rate - $throttle->type");
      die(message_throttle());
    }
    else {
      watchdog($type, "throttle");
    }
  }
}

Dries's avatar
 
Dries committed
84 85 86 87
function _fix_gpc_magic_array(&$items) {
  foreach ($items as $k => $i) {
    if (is_array($i)) _fix_gpc_magic_array($items[$k]);
    else $items[$k] = stripslashes($i);
Dries's avatar
 
Dries committed
88 89 90
  }
}

Dries's avatar
 
Dries committed
91 92 93 94 95 96 97 98 99 100 101 102
function fix_gpc_magic() {
  static $fixed = false;
  if ($fixed) return;
  if (ini_get("magic_quotes_gpc") == 0) return;

  _fix_gpc_magic_array($_GET);
  _fix_gpc_magic_array($_POST);
  _fix_gpc_magic_array($_COOKIE);

  $fixed = true;
}

Dries's avatar
 
Dries committed
103 104 105 106 107
function arg($index) {

  static $arguments;

  if (empty($arguments)) {
Dries's avatar
 
Dries committed
108
    $arguments = explode("/", $_GET["q"]);
Dries's avatar
 
Dries committed
109 110 111 112 113
  }

  return $arguments[$index];
}

Dries's avatar
 
Dries committed
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
function array2object($node) {

  if (is_array($node)) {
    foreach ($node as $key => $value) {
      $object->$key = $value;
    }
  }
  else {
    $object = $node;
  }

  return $object;
}

function object2array($node) {

  if (is_object($node)) {
    foreach ($node as $key => $value) {
      $array[$key] = $value;
    }
  }
  else {
    $array = $node;
  }

  return $array;
}

Dries's avatar
 
Dries committed
142 143 144 145 146 147 148 149 150
function referer_uri() {

  if (isset($_SERVER["HTTP_REFERER"])) {
    $uri = $_SERVER["HTTP_REFERER"];

    return check_url($uri);
  }
}

Dries's avatar
 
Dries committed
151
function request_uri() {
Dries's avatar
 
Dries committed
152 153 154 155
  /*
  ** Since request_uri() is only available on Apache, we generate
  ** equivalent using other environment vars.
  */
Dries's avatar
 
Dries committed
156

Dries's avatar
 
Dries committed
157
  if (isset($_SERVER["REQUEST_URI"])) {
158
    $uri = $_SERVER["REQUEST_URI"];
Dries's avatar
 
Dries committed
159 160
  }
  else {
161
    $uri = $_SERVER["PHP_SELF"] ."?". $_SERVER["QUERY_STRING"];
Dries's avatar
 
Dries committed
162
  }
163

Dries's avatar
 
Dries committed
164
  return check_url($uri);
Dries's avatar
 
Dries committed
165 166
}

Dries's avatar
 
Dries committed
167
function message_access() {
Dries's avatar
 
Dries committed
168
  return t("You are not authorized to access this page.");
Dries's avatar
 
Dries committed
169 170 171 172 173 174 175 176 177 178
}

function message_na() {
  return t("n/a");
}

function message_throttle() {
  return t("You exceeded the maximum submission rate.  Please wait a few minutes and try again.");
}

Dries's avatar
 
Dries committed
179 180
function locale_init() {
  global $languages, $user;
Dries's avatar
 
Dries committed
181 182 183 184 185 186
  if ($user->uid && $languages[$user->language]) {
    return $user->language;
  }
  else {
    return key($languages);
  }
Dries's avatar
 
Dries committed
187 188
}

Dries's avatar
 
Dries committed
189
function t($string, $args = 0) {
Dries's avatar
 
Dries committed
190
  global $languages;
191

Dries's avatar
 
Dries committed
192 193 194 195 196 197 198
  /*
  ** About the usage of t().  We try to keep strings whole as much as
  ** possible and are unafraid of HTML markup within translation strings
  ** if necessary.  The suggested syntax for a link embedded within a
  ** translation string is for example:
  **
  ** $msg = t("You must login below or <a href=\"%url\">create a new
Dries's avatar
 
Dries committed
199 200
  **           account</a> before viewing the next page.", array("%url"
  **           => url("user/register")));
Dries's avatar
 
Dries committed
201 202
  */

203
  $string = ($languages && module_exist("locale") ? locale($string) : $string);
204

Dries's avatar
 
Dries committed
205 206
  if (!$args) {
    return $string;
Kjartan's avatar
Kjartan committed
207 208
  }
  else {
Dries's avatar
 
Dries committed
209 210
    return strtr($string, $args);
  }
Dries's avatar
 
Dries committed
211 212 213
}

function variable_init($conf = array()) {
Dries's avatar
 
Dries committed
214
  $result = db_query("SELECT * FROM {variable} ");
Dries's avatar
 
Dries committed
215 216
  while ($variable = db_fetch_object($result)) {
    if (!isset($conf[$variable->name])) {
Dries's avatar
 
Dries committed
217
      $conf[$variable->name] = unserialize($variable->value);
Dries's avatar
 
Dries committed
218 219 220 221 222 223
    }
  }

  return $conf;
}

224
function variable_get($name, $default) {
Dries's avatar
 
Dries committed
225 226 227 228 229 230 231 232
  global $conf;

  return isset($conf[$name]) ? $conf[$name] : $default;
}

function variable_set($name, $value) {
  global $conf;

Dries's avatar
 
Dries committed
233 234
  db_query("DELETE FROM {variable} WHERE name = '%s'", $name);
  db_query("INSERT INTO {variable} (name, value) VALUES ('%s', '%s')", $name, serialize($value));
Dries's avatar
 
Dries committed
235 236 237 238 239 240 241

  $conf[$name] = $value;
}

function variable_del($name) {
  global $conf;

Dries's avatar
 
Dries committed
242
  db_query("DELETE FROM {variable} WHERE name = '%s'", $name);
Dries's avatar
 
Dries committed
243 244 245 246

  unset($conf[$name]);
}

Dries's avatar
 
Dries committed
247
function drupal_specialchars($input, $quotes = ENT_NOQUOTES) {
Dries's avatar
 
Dries committed
248 249 250 251 252 253 254 255 256

  /*
  ** Note that we'd like to go 'htmlspecialchars($input, $quotes, "utf-8")'
  ** like the PHP manual tells us to, but we can't because there's a bug in
  ** PHP <4.3 that makes it mess up multibyte charsets if we specify the
  ** charset.  Change this later once we make PHP 4.3 a requirement.
  */

  return htmlspecialchars($input, $quotes);
Dries's avatar
 
Dries committed
257 258
}

259 260 261 262 263 264
/**
 * Verify the syntax of the given e-mail address.  Empty e-mail addresses
 * are allowed.  See RFC 2822 for details.
 *
 * @param $mail  a email address
 */
Dries's avatar
 
Dries committed
265
function valid_email_address($mail) {
266 267 268 269 270 271 272 273 274 275 276 277 278
  $user = '[a-zA-Z0-9_\-\.\+\^!#\$%&*+\/\=\?\`\|\{\}~\']+';
  $domain = '(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9]\.?)+';
  $ipv4 = '[0-9]{1,3}(\.[0-9]{1,3}){3}';
  $ipv6 = '[0-9a-fA-F]{1,4}(\:[0-9a-fA-F]{1,4}){7}';

  if (preg_match("/^$user@($domain|(\[($ipv4|$ipv6)\]))$/", $mail)) {
    return 1;
  }
  else {
    return 0;
  }
}

Dries's avatar
 
Dries committed
279 280 281 282 283 284 285
/**
 * Verify the syntax of the given URL.
 *
 * @param $url  an URL
 */
function valid_url($url) {

Dries's avatar
 
Dries committed
286
  if (preg_match("/^[a-zA-z0-9\/:_\-_\.,]+$/", $url)) {
Dries's avatar
 
Dries committed
287 288 289 290 291 292 293
    return 1;
  }
  else {
    return 0;
  }
}

Kjartan's avatar
Kjartan committed
294 295 296 297
/**
 * Format a single result entry of a search query:
 *
 * @param $item  a single search result as returned by <module>_search of type
Dries's avatar
 
Dries committed
298
 *               array("count" => ..., "link" => ..., "title" => ...,
Kjartan's avatar
Kjartan committed
299 300 301
 *               "user" => ..., "date" => ..., "keywords" => ...)
 * @param $type  module type of this item
 */
Dries's avatar
 
Dries committed
302
function search_item($item, $type) {
Dries's avatar
 
Dries committed
303 304 305 306 307 308 309 310 311 312

  /*
  ** Modules may implement the "search_item" hook in order to overwrite
  ** the default function to display search results.
  */

  if (module_hook($type, "search_item")) {
    $output = module_invoke($type, "search_item", $item);
  }
  else {
Dries's avatar
 
Dries committed
313
    $output .= " <b><u><a href=\"". $item["link"] ."\">". $item["title"] ."</a></u></b><br />";
Dries's avatar
 
Dries committed
314
    $output .= " <small>" . t($type) . ($item["user"] ? " - ". $item["user"] : "") ."". ($item["date"] ? " - ". format_date($item["date"], "small") : "") ."</small>";
Dries's avatar
 
Dries committed
315 316
    $output .= "<br /><br />";
  }
Dries's avatar
 
Dries committed
317 318 319 320

  return $output;
}

Kjartan's avatar
Kjartan committed
321 322 323 324
/**
 * Render a generic search form.
 *
 * "Generic" means "universal usable" - that is, usable not only from
Dries's avatar
 
Dries committed
325
 * 'site.com/search', but also as a simple seach box (without
Dries's avatar
 
Dries committed
326 327
 * "Restrict search to", help text, etc) from theme's header etc.
 * This means: provide options to only conditionally render certain
Kjartan's avatar
Kjartan committed
328 329
 * parts of this form.
 *
Dries's avatar
 
Dries committed
330
 * @param $action  Form action. Defaults to 'site.com/search'.
Dries's avatar
 
Dries committed
331
 * @param $keys   string containing keywords for the search.
Dries's avatar
 
Dries committed
332
 * @param $options != 0: Render additional form fields/text
Kjartan's avatar
Kjartan committed
333 334
 *                 ("Restrict search to", help text, etc).
 */
Dries's avatar
 
Dries committed
335
function search_form($action = NULL, $keys = NULL, $options = NULL) {
Dries's avatar
 
Dries committed
336 337

  if (!$action) {
Dries's avatar
 
Dries committed
338
    $action = url("search");
Dries's avatar
 
Dries committed
339 340
  }

Dries's avatar
 
Dries committed
341 342
  $output .= " <br /><input type=\"text\" class=\"form-text\" size=\"50\" value=\"". check_form($keys) ."\" name=\"keys\" />";
  $output .= " <input type=\"submit\" class=\"form-submit\" value=\"". t("Search") ."\" />\n";
Dries's avatar
 
Dries committed
343 344 345 346 347 348 349

  if ($options != 0) {
    $output .= "<br />";
    $output .= t("Restrict search to") .": ";

    foreach (module_list() as $name) {
      if (module_hook($name, "search")) {
Kjartan's avatar
Kjartan committed
350
        $output .= " <input type=\"checkbox\" name=\"edit[type][$name]\" ". ($edit["type"][$name] ? " checked=\"checked\"" : "") ." /> ". t($name);
Dries's avatar
 
Dries committed
351 352 353 354
      }
    }
  }

Kjartan's avatar
Kjartan committed
355 356
  $form .= "<br />";

Dries's avatar
 
Dries committed
357 358 359 360
  return form($output, "post", $action);
}

/*
Kjartan's avatar
Kjartan committed
361 362
 * Collect the search results:
 */
Dries's avatar
 
Dries committed
363
function search_data($keys = NULL) {
Dries's avatar
 
Dries committed
364 365

  $edit = $_POST["edit"];
Dries's avatar
 
Dries committed
366

Dries's avatar
 
Dries committed
367
  if (isset($keys)) {
Dries's avatar
 
Dries committed
368
    foreach (module_list() as $name) {
Dries's avatar
 
Dries committed
369
      if (module_hook($name, "search") && (!$edit["type"] || $edit["type"][$name]) && ($result = module_invoke($name, "search", $keys))) {
Kjartan's avatar
Kjartan committed
370
        if ($name == "node" || $name == "comment") {
Dries's avatar
 
Dries committed
371
          $output .= "<p><b>". t("Matching ". $name ."s ranked in order of relevance") .":</b></p>";
Kjartan's avatar
Kjartan committed
372 373
        }
        else {
Dries's avatar
 
Dries committed
374
          $output .= "<p><b>". t("Matching ". $name ."s") .":</b></p>";
Kjartan's avatar
Kjartan committed
375
        }
Dries's avatar
 
Dries committed
376 377 378 379 380 381 382 383 384 385
        foreach ($result as $entry) {
          $output .= search_item($entry, $name);
        }
      }
    }
  }

  return $output;
}

Kjartan's avatar
Kjartan committed
386 387 388
/**
 * Display the search form and the resulting data.
 *
Dries's avatar
 
Dries committed
389
 * @param $type    If set, search only nodes of this type.
Kjartan's avatar
Kjartan committed
390
 *                 Otherwise, search all types.
Dries's avatar
 
Dries committed
391
 * @param $action  Form action. Defaults to 'site.com/search'.
Kjartan's avatar
Kjartan committed
392
 * @param $query   Query string. Defaults to global $keys.
Dries's avatar
 
Dries committed
393
 * @param $options != 0: Render additional form fields/text
Kjartan's avatar
Kjartan committed
394 395
 *                 ("Restrict search to", help text, etc).
 */
Dries's avatar
 
Dries committed
396
function search_type($type, $action = NULL, $keys = NULL, $options = NULL) {
Dries's avatar
 
Dries committed
397

Dries's avatar
 
Dries committed
398
  $_POST["edit"]["type"][$type] = "on";
Dries's avatar
 
Dries committed
399

Dries's avatar
 
Dries committed
400
  return search_form($action, $keys, $options) . "<br />". search_data($keys);
Dries's avatar
 
Dries committed
401 402
}

Dries's avatar
 
Dries committed
403

Dries's avatar
 
Dries committed
404 405
function drupal_goto($url) {

Dries's avatar
 
Dries committed
406 407 408
  /*
  ** Translate &amp; to simply &
  */
Dries's avatar
 
Dries committed
409

Dries's avatar
 
Dries committed
410
  $url = str_replace("&amp;", "&", $url);
Dries's avatar
 
Dries committed
411

Dries's avatar
 
Dries committed
412 413 414 415 416
  /*
  ** It is advised to use "drupal_goto()" instead of PHP's "header()" as
  ** "drupal_goto()" will append the user's session ID to the URI when PHP
  ** is compiled with "--enable-trans-sid".
  */
Dries's avatar
 
Dries committed
417
  if (!ini_get("session.use_trans_sid") || !session_id() || strstr($url, session_id())) {
Dries's avatar
 
Dries committed
418 419 420
    header("Location: $url");
  }
  else {
Dries's avatar
 
Dries committed
421 422 423 424 425 426 427 428
    $sid = session_name() . "=" . session_id();

    if (strstr($url, "?") && !strstr($url, $sid)) {
      header("Location: $url&". $sid);
    }
    else {
      header("Location: $url?". $sid);
    }
Dries's avatar
 
Dries committed
429 430 431 432
  }

  /*
  ** The "Location" header sends a REDIRECT status code to the http
Dries's avatar
 
Dries committed
433
  ** daemon.  In some cases this can go wrong, so we make sure none
Dries's avatar
 
Dries committed
434 435 436 437 438 439
  ** of the code /below/ gets executed when we redirect.
  */

  exit();
}

Dries's avatar
 
Dries committed
440
function valid_input_data($data) {
441

442
  if (is_array($data) || is_object($data)) {
443 444 445 446 447
    /*
    ** Form data can contain a number of nested arrays.
    */

    foreach ($data as $key => $value) {
Dries's avatar
 
Dries committed
448 449 450
      if (!valid_input_data($value)) {
        return 0;
      }
451 452 453 454 455 456 457
    }
  }
  else {
    /*
    ** Detect evil input data.
    */

Dries's avatar
Dries committed
458
    // check strings:
Dries's avatar
Dries committed
459
    $match  = preg_match("/\Wjavascript\s*:/i", $data);
Dries's avatar
Dries committed
460 461 462
    $match += preg_match("/\Wexpression\s*\(/i", $data);
    $match += preg_match("/\Walert\s*\(/i", $data);

463
    // check attributes:
Dries's avatar
Dries committed
464
    $match += preg_match("/\W(dynsrc|datasrc|data|lowsrc|on[a-z]+)\s*=[^>]+?>/i", $data);
Dries's avatar
 
Dries committed
465

466 467

    // check tags:
Dries's avatar
 
Dries committed
468
    $match += preg_match("/<\s*(applet|script|object|style|embed|form|blink|meta|html|frame|iframe|layer|ilayer|head|frameset|xml)/i", $data);
469 470 471

    if ($match) {
      watchdog("warning", "terminated request because of suspicious input data: ". drupal_specialchars($data));
Dries's avatar
 
Dries committed
472
      return 0;
473 474
    }
  }
Dries's avatar
 
Dries committed
475 476

  return 1;
477
}
Dries's avatar
 
Dries committed
478

479
function check_url($uri) {
Dries's avatar
 
Dries committed
480 481 482 483 484 485 486 487 488 489 490 491
  $uri = htmlspecialchars($uri, ENT_QUOTES);

  /*
  ** We replace ( and ) with their entity equivalents to prevent XSS
  ** attacks.
  */

  $uri = strtr($uri, array("(" => "&040;", ")" => "&041;"));

  return $uri;
}

Dries's avatar
 
Dries committed
492
function check_form($text) {
Dries's avatar
 
Dries committed
493
  return drupal_specialchars($text, ENT_QUOTES);
Dries's avatar
 
Dries committed
494 495
}

Dries's avatar
 
Dries committed
496
function check_query($text) {
Dries's avatar
 
Dries committed
497
  return addslashes($text);
Dries's avatar
 
Dries committed
498 499 500
}

function filter($text) {
Dries's avatar
 
Dries committed
501

Dries's avatar
 
Dries committed
502 503 504 505 506 507 508 509 510 511 512 513 514
  $modules = module_list();

  /*
  ** Make sure the HTML filters that are part of the node module
  ** are run first.
  */

  if (in_array("node", $modules)) {
    $text = module_invoke("node", "filter", $text);
  }

  foreach ($modules as $name) {
    if (module_hook($name, "filter") && $name != "node") {
Dries's avatar
 
Dries committed
515 516 517 518 519
      $text = module_invoke($name, "filter", $text);
    }
  }

  return $text;
Dries's avatar
 
Dries committed
520 521
}

Dries's avatar
 
Dries committed
522 523
function rewrite_old_urls($text) {

Dries's avatar
 
Dries committed
524 525 526 527
  global $base_url;

  $end = substr($base_url, 12);

Dries's avatar
 
Dries committed
528 529 530
  /*
  ** This is a *temporary* filter to rewrite old-style URLs to new-style
  ** URLs (clean URLs).  Currently, URLs are being rewritten dynamically
Dries's avatar
 
Dries committed
531 532
  ** (ie. "on output"), however when these rewrite rules have been tested
  ** enough, we will use them to permanently rewrite the links in node
Dries's avatar
 
Dries committed
533 534 535
  ** and comment bodies.
  */

Dries's avatar
 
Dries committed
536
  if (variable_get("clean_url", "0") == "0") {
Dries's avatar
 
Dries committed
537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552
    /*
    ** Relative URLs:
    */

    // rewrite 'node.php?id=<number>[&cid=<number>]' style URLs:
    $text = eregi_replace("\"(node)\.php\?id=([[:digit:]]+)(&cid=)?([[:digit:]]*)", "\"?q=\\1/view/\\2/\\4", $text);

    // rewrite 'module.php?mod=<name>{&<op>=<value>}' style URLs:
    $text = ereg_replace("\"module\.php\?(&?[[:alpha:]]+=([[:alnum:]]+))(&?[[:alpha:]]+=([[:alnum:]]+))(&?[[:alpha:]]+=([[:alnum:]]+))", "\"?q=\\2/\\4/\\6" , $text);
    $text = ereg_replace("\"module\.php\?(&?[[:alpha:]]+=([[:alnum:]]+))(&?[[:alpha:]]+=([[:alnum:]]+))", "\"?q=\\2/\\4", $text);
    $text = ereg_replace("\"module\.php\?(&?[[:alpha:]]+=([[:alnum:]]+))", "\"?q=\\2", $text);

    /*
    ** Absolute URLs:
    */

Dries's avatar
 
Dries committed
553
    // rewrite 'node.php?id=<number>[&cid=<number>]' style URLs:
Dries's avatar
 
Dries committed
554
    $text = eregi_replace("$end/(node)\.php\?id=([[:digit:]]+)(&cid=)?([[:digit:]]*)", "$end/?q=\\1/view/\\2/\\4", $text);
Dries's avatar
 
Dries committed
555

Dries's avatar
 
Dries committed
556
    // rewrite 'module.php?mod=<name>{&<op>=<value>}' style URLs:
Dries's avatar
 
Dries committed
557 558 559
    $text = ereg_replace("$end/module\.php\?(&?[[:alpha:]]+=([[:alnum:]]+))(&?[[:alpha:]]+=([[:alnum:]]+))(&?[[:alpha:]]+=([[:alnum:]]+))", "$end/?q=\\2/\\4/\\6" , $text);
    $text = ereg_replace("$end/module\.php\?(&?[[:alpha:]]+=([[:alnum:]]+))(&?[[:alpha:]]+=([[:alnum:]]+))", "$end/?q=\\2/\\4", $text);
    $text = ereg_replace("$end/module\.php\?(&?[[:alpha:]]+=([[:alnum:]]+))", "\"$end/?q=\\2", $text);
Dries's avatar
 
Dries committed
560 561
  }
  else {
Dries's avatar
 
Dries committed
562 563 564 565
    /*
    ** Relative URLs:
    */

Dries's avatar
 
Dries committed
566
    // rewrite 'node.php?id=<number>[&cid=<number>]' style URLs:
Dries's avatar
 
Dries committed
567
    $text = eregi_replace("\"(node)\.php\?id=([[:digit:]]+)(&cid=)?([[:digit:]]*)", "\"\\1/view/\\2/\\4", $text);
Dries's avatar
 
Dries committed
568 569

    // rewrite 'module.php?mod=<name>{&<op>=<value>}' style URLs:
Dries's avatar
 
Dries committed
570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585
    $text = ereg_replace("\"module\.php\?(&?[[:alpha:]]+=([[:alnum:]]+))(&?[[:alpha:]]+=([[:alnum:]]+))(&?[[:alpha:]]+=([[:alnum:]]+))", "\"\\2/\\4/\\6", $text);
    $text = ereg_replace("\"module\.php\?(&?[[:alpha:]]+=([[:alnum:]]+))(&?[[:alpha:]]+=([[:alnum:]]+))", "\"\\2/\\4", $text);
    $text = ereg_replace("\"module\.php\?(&?[[:alpha:]]+=([[:alnum:]]+))", "\"\\2", $text);

    /*
    ** Absolute URLs:
    */

    // rewrite 'node.php?id=<number>[&cid=<number>]' style URLs:
    $text = eregi_replace("$end/(node)\.php\?id=([[:digit:]]+)(&cid=)?([[:digit:]]*)", "$end/\\1/view/\\2/\\4", $text);

    // rewrite 'module.php?mod=<name>{&<op>=<value>}' style URLs:
    $text = ereg_replace("$end/module\.php\?(&?[[:alpha:]]+=([[:alnum:]]+))(&?[[:alpha:]]+=([[:alnum:]]+))(&?[[:alpha:]]+=([[:alnum:]]+))", "$end/\\2/\\4/\\6", $text);
    $text = ereg_replace("$end/module\.php\?(&?[[:alpha:]]+=([[:alnum:]]+))(&?[[:alpha:]]+=([[:alnum:]]+))", "$end/\\2/\\4", $text);
    $text = ereg_replace("$end/module\.php\?(&?[[:alpha:]]+=([[:alnum:]]+))", "$end/\\2", $text);
}
Dries's avatar
 
Dries committed
586

Dries's avatar
 
Dries committed
587 588 589
  return $text;
}

Dries's avatar
 
Dries committed
590
function check_output($text) {
Dries's avatar
 
Dries committed
591
  if (isset($text)) {
Dries's avatar
 
Dries committed
592 593 594 595
    // filter content on output:
    $text = filter($text);

    // get the line breaks right:
Dries's avatar
 
Dries committed
596
    if (strip_tags($text, "<a><i><b><u><tt><code><cite><strong><img>") == $text) {
Dries's avatar
 
Dries committed
597 598 599 600 601 602 603 604
      $text = nl2br($text);
    }
  }
  else {
    $text = message_na();
  }

  return $text;
Dries's avatar
 
Dries committed
605 606
}

607

608 609
function check_file($filename) {
  return is_uploaded_file($filename);
Dries's avatar
 
Dries committed
610 611
}

Dries's avatar
 
Dries committed
612 613 614
function format_rss_channel($title, $link, $description, $items, $language = "en", $args = array()) {
  // arbitrary elements may be added using the $args associative array

Dries's avatar
 
Dries committed
615
  $output .= "<channel>\n";
Dries's avatar
 
Dries committed
616 617 618 619
  $output .= " <title>". drupal_specialchars(strip_tags($title)) ."</title>\n";
  $output .= " <link>". drupal_specialchars(strip_tags($link)) ."</link>\n";
  $output .= " <description>". drupal_specialchars($description) ."</description>\n";
  $output .= " <language>". drupal_specialchars(strip_tags($language)) ."</language>\n";
Dries's avatar
 
Dries committed
620
  foreach ($args as $key => $value) {
Dries's avatar
 
Dries committed
621
    $output .= " <$key>". drupal_specialchars(strip_tags($value)) ."</$key>\n";
Dries's avatar
 
Dries committed
622
  }
Dries's avatar
 
Dries committed
623 624 625 626 627 628
  $output .= $items;
  $output .= "</channel>\n";

  return $output;
}

Dries's avatar
 
Dries committed
629 630 631
function format_rss_item($title, $link, $description, $args = array()) {
  // arbitrary elements may be added using the $args associative array

Dries's avatar
 
Dries committed
632
  $output .= "<item>\n";
Dries's avatar
 
Dries committed
633 634 635
  $output .= " <title>". drupal_specialchars(strip_tags($title)) ."</title>\n";
  $output .= " <link>". drupal_specialchars(strip_tags($link)) ."</link>\n";
  $output .= " <description>". drupal_specialchars(check_output($description)) ."</description>\n";
Dries's avatar
 
Dries committed
636
  foreach ($args as $key => $value) {
Dries's avatar
 
Dries committed
637
    $output .= "<$key>". drupal_specialchars(strip_tags($value)) ."</$key>";
Dries's avatar
 
Dries committed
638
  }
Dries's avatar
 
Dries committed
639 640 641 642 643
  $output .= "</item>\n";

  return $output;
}

Dries's avatar
 
Dries committed
644 645 646 647 648 649 650 651 652 653 654 655 656 657
/**
 * Formats a string with a count of items so that the string is pluralized
 * correctly.
 * format_plural calls t() by itself, make sure not to pass already localized
 * strings to it.
 *
 * @param $count    The item count to display.
 * @param $singular The string for the singular case. Please make sure it's clear
 *                  this is singular, to ease translation. ("1 new comment" instead of
 *                  "1 new").
 * @param $plural   The string for the plrual case. Please make sure it's clear
 *                  this is plural, to ease translation. Use %count in places of the
 *                  item count, as in "%count new comments".
 */
Dries's avatar
 
Dries committed
658
function format_plural($count, $singular, $plural) {
Dries's avatar
 
Dries committed
659
  return t($count == 1 ? $singular : $plural, array("%count" => $count));
Dries's avatar
 
Dries committed
660 661 662
}

function format_size($size) {
Dries's avatar
 
Dries committed
663
  $suffix = t("bytes");
Dries's avatar
 
Dries committed
664 665
  if ($size > 1024) {
    $size = round($size / 1024, 2);
Dries's avatar
 
Dries committed
666
    $suffix = t("KB");
Dries's avatar
 
Dries committed
667 668 669
  }
  if ($size > 1024) {
    $size = round($size / 1024, 2);
Dries's avatar
 
Dries committed
670
    $suffix = t("MB");
Dries's avatar
 
Dries committed
671
  }
Dries's avatar
 
Dries committed
672
  return t("%size %suffix", array("%size" => $size, "%suffix" => $suffix));
Dries's avatar
 
Dries committed
673 674
}

Dries's avatar
 
Dries committed
675
function cache_get($key) {
Dries's avatar
 
Dries committed
676
  $cache = db_fetch_object(db_query("SELECT data, created FROM {cache} WHERE cid = '%s'", $key));
Dries's avatar
 
Dries committed
677
  return $cache->data ? $cache : 0;
Dries's avatar
 
Dries committed
678 679 680
}

function cache_set($cid, $data, $expire = 0) {
Dries's avatar
 
Dries committed
681 682
  db_query("UPDATE {cache} SET data = '%s', created = %d, expire = %d WHERE cid = '%s'", $data, time(), $expire, $cid);
  if (!db_affected_rows()) {
Dries's avatar
 
Dries committed
683
    db_query("INSERT INTO {cache} (cid, data, created, expire) VALUES('%s', '%s', %d, %d)", $cid, $data, time(), $expire);
Dries's avatar
 
Dries committed
684
  }
Dries's avatar
 
Dries committed
685 686
}

Dries's avatar
 
Dries committed
687 688
function cache_clear_all($cid = NULL) {
  if (empty($cid)) {
Dries's avatar
 
Dries committed
689
    db_query("DELETE FROM {cache} WHERE expire <> 0");
Dries's avatar
 
Dries committed
690 691
  }
  else {
Dries's avatar
 
Dries committed
692
    db_query("DELETE FROM {cache} WHERE cid = '%s'", $cid);
Dries's avatar
 
Dries committed
693
  }
Dries's avatar
 
Dries committed
694 695 696
}

function page_set_cache() {
Dries's avatar
 
Dries committed
697
  global $user;
Dries's avatar
 
Dries committed
698

Dries's avatar
 
Dries committed
699
  if (!$user->uid && $_SERVER["REQUEST_METHOD"] == "GET") {
Dries's avatar
 
Dries committed
700
    if ($data = ob_get_contents()) {
Dries's avatar
 
Dries committed
701
      cache_set(request_uri(), $data, 1);
Dries's avatar
 
Dries committed
702 703 704 705
    }
  }
}

Dries's avatar
 
Dries committed
706
function page_get_cache() {
Dries's avatar
 
Dries committed
707
  global $user;
Dries's avatar
 
Dries committed
708

Dries's avatar
 
Dries committed
709 710
  $cache = NULL;

Dries's avatar
 
Dries committed
711
  if (!$user->uid && $_SERVER["REQUEST_METHOD"] == "GET") {
Dries's avatar
 
Dries committed
712 713 714
    $cache = cache_get(request_uri());

    if (empty($cache)) {
Dries's avatar
 
Dries committed
715
      ob_start();
Dries's avatar
 
Dries committed
716 717
    }
  }
Dries's avatar
 
Dries committed
718

Dries's avatar
 
Dries committed
719
  return $cache;
Dries's avatar
 
Dries committed
720 721 722
}

function format_interval($timestamp) {
Dries's avatar
 
Dries committed
723
  $units = array("1 year|%count years" => 31536000, "1 week|%count weeks" => 604800, "1 day|%count days" => 86400, "1 hour|%count hours" => 3600, "1 min|%count min" => 60, "1 sec|%count sec" => 1);
Kjartan's avatar
Kjartan committed
724
  foreach ($units as $key=>$value) {
Dries's avatar
 
Dries committed
725 726 727 728 729 730
    $key = explode("|", $key);
    if ($timestamp >= $value) {
      $output .= ($output ? " " : "") . format_plural(floor($timestamp / $value), $key[0], $key[1]);
      $timestamp %= $value;
    }
  }
Dries's avatar
 
Dries committed
731
  return ($output) ? $output : t("0 sec");
Dries's avatar
 
Dries committed
732 733 734 735 736
}

function format_date($timestamp, $type = "medium", $format = "") {
  global $user;

Kjartan's avatar
Kjartan committed
737
  $timestamp += ($user->timezone) ? $user->timezone - date("Z") : 0;
Dries's avatar
 
Dries committed
738 739 740

  switch ($type) {
    case "small":
Dries's avatar
 
Dries committed
741
      $format = variable_get("date_format_short", "m/d/Y - H:i");
Dries's avatar
 
Dries committed
742 743
      break;
    case "large":
Dries's avatar
 
Dries committed
744
      $format = variable_get("date_format_long", "l, F j, Y - H:i");
Dries's avatar
 
Dries committed
745 746
      break;
    case "custom":
Dries's avatar
 
Dries committed
747
      // No change to format
Dries's avatar
 
Dries committed
748
      break;
Dries's avatar
 
Dries committed
749
    case "medium":
Dries's avatar
 
Dries committed
750
    default:
Dries's avatar
 
Dries committed
751 752 753 754 755 756 757 758 759 760 761 762 763
      $format = variable_get("date_format_medium", "D, m/d/Y - H:i");
  }

  for ($i = strlen($format); $i >= 0; $c = $format[--$i]) {
    if (strstr("DFlMSw", $c)) {
      $date = t(date($c, $timestamp)) . $date;
    }
    else if (strstr("AaBdgGhHiIjLmnOrstTUWYyZz", $c)) {
      $date = date($c, $timestamp) . $date;
    }
    else {
      $date = $c.$date;
    }
Dries's avatar
 
Dries committed
764 765 766 767 768 769 770
  }
  return $date;
}

function format_name($object) {

  if ($object->uid && $object->name) {
Dries's avatar
Dries committed
771 772 773 774 775 776 777 778 779 780 781 782
    /*
    ** Shorten the name when it is too long or it will break many
    ** tables.
    */

    if (strlen($object->name) > 20) {
      $name = substr($object->name, 0, 15) ."...";
    }
    else {
      $name = $object->name;
    }

Dries's avatar
 
Dries committed
783
    if (arg(0) == "admin") {
Dries's avatar
Dries committed
784
      $output = l($name, "admin/user/edit/$object->uid", array("title" => t("Administer user profile.")));
Dries's avatar
 
Dries committed
785 786
    }
    else {
Dries's avatar
Dries committed
787
      $output = l($name, "user/view/$object->uid", array("title" => t("View user profile.")));
Dries's avatar
 
Dries committed
788
    }
Dries's avatar
 
Dries committed
789
  }
Dries's avatar
 
Dries committed
790 791 792 793 794 795 796 797 798 799
  else if ($object->name) {
    /*
    ** Sometimes modules display content composed by people who are
    ** not registers members of the site (i.e. mailing list or news
    ** aggregator modules).  This clause enables modules to display
    ** the true author of the content.
    */

    $output = $object->name;
  }
Dries's avatar
 
Dries committed
800
  else {
Dries's avatar
 
Dries committed
801
    $output = t(variable_get("anonymous", "Anonymous"));
Dries's avatar
 
Dries committed
802 803
  }

Dries's avatar
 
Dries committed
804
  return $output;
Dries's avatar
 
Dries committed
805 806 807
}

function form($form, $method = "post", $action = 0, $options = 0) {
Dries's avatar
 
Dries committed
808 809

  if (!$action) {
810
    $action = request_uri();
Dries's avatar
 
Dries committed
811
  }
812
  return "<form action=\"$action\" method=\"$method\"". drupal_attributes($options) .">\n$form\n</form>\n";
Dries's avatar
 
Dries committed
813 814 815
}

function form_item($title, $value, $description = 0) {
Dries's avatar
 
Dries committed
816
  return "<div class=\"form-item\">". ($title ? "<div class=\"title\">$title:</div>" : "") . $value . ($description ? "<div class=\"description\">$description</div>" : "") ."</div>\n";
Dries's avatar
 
Dries committed
817
}
Dries's avatar
 
Dries committed
818 819 820
function form_group($legend, $group, $description = 0) {
  return "<fieldset>" . ($legend ? "<legend>$legend</legend>" : "") . $group . ($description ? "<div class=\"description\">$description</div>" : "") . "</fieldset>\n";
}
Dries's avatar
 
Dries committed
821

822 823
function form_radio($title, $name, $value = 1, $checked = 0, $description = 0, $attributes = 0) {
  return form_item(0, "<input type=\"radio\" class=\"form-radio\" name=\"edit[$name]\" value=\"". $value ."\"". ($checked ? " checked=\"checked\"" : "") . drupal_attributes($attributes) ." /> $title", $description);
Dries's avatar
 
Dries committed
824 825
}

826 827
function form_checkbox($title, $name, $value = 1, $checked = 0, $description = 0, $attributes = 0) {
  return form_hidden($name, 0) . form_item(0, "<input type=\"checkbox\" class=\"form-checkbox\" name=\"edit[$name]\" value=\"". $value ."\"". ($checked ? " checked=\"checked\"" : "") . drupal_attributes($attributes) ." /> $title", $description);
Dries's avatar
 
Dries committed
828 829
}

830
function form_textfield($title, $name, $value, $size, $maxlength, $description = 0, $attributes = 0) {
Dries's avatar
 
Dries committed
831
  $size = $size ? " size=\"$size\"" : "";
832
  return form_item($title, "<input type=\"text\" maxlength=\"$maxlength\" class=\"form-text\" name=\"edit[$name]\"$size value=\"". check_form($value) ."\"". drupal_attributes($attributes) ." />", $description);
Dries's avatar
 
Dries committed
833 834
}

835
function form_password($title, $name, $value, $size, $maxlength, $description = 0, $attributes = 0) {
Dries's avatar
 
Dries committed
836
  $size = $size ? " size=\"$size\"" : "";
837
  return form_item($title, "<input type=\"password\" class=\"form-password\" maxlength=\"$maxlength\" name=\"edit[$name]\"$size value=\"". check_form($value) ."\"". drupal_attributes($attributes) ." />", $description);
Dries's avatar
 
Dries committed
838 839
}

840
function form_textarea($title, $name, $value, $cols, $rows, $description = 0, $attributes = 0) {
Dries's avatar
 
Dries committed
841
  $cols = $cols ? " cols=\"$cols\"" : "";
Dries's avatar
 
Dries committed
842
  module_invoke_all("textarea", $name);  // eg. optionally plug in a WYSIWYG editor
843
  return form_item($title, "<textarea wrap=\"virtual\"$cols rows=\"$rows\" name=\"edit[$name]\" id=\"edit[$name]\"". drupal_attributes($attributes) .">". check_form($value) ."</textarea>", $description);
Dries's avatar
 
Dries committed
844 845
}

Dries's avatar
 
Dries committed
846
function form_select($title, $name, $value, $options, $description = 0, $extra = 0, $multiple = 0) {
Dries's avatar
 
Dries committed
847
  if (count($options) > 0) {
Kjartan's avatar
Kjartan committed
848
    foreach ($options as $key=>$choice) {
849
      $select .= "<option value=\"$key\"". (is_array($value) ? (in_array($key, $value) ? " selected=\"selected\"" : "") : ($value == $key ? " selected=\"selected\"" : "")) .">". check_form($choice) ."</option>";
Dries's avatar
 
Dries committed
850
    }
Kjartan's avatar
Kjartan committed
851
    return form_item($title, "<select name=\"edit[$name]". ($multiple ? "[]" : "") ."\"". ($multiple ? " multiple " : "") . ($extra ? " $extra" : "") .">$select</select>", $description);
Dries's avatar
 
Dries committed
852 853 854
  }
}

Dries's avatar
 
Dries committed
855 856 857 858 859 860 861 862 863
function form_radios($title, $name, $value, $options, $description = 0) {
  if (count($options) > 0) {
    foreach ($options as $key=>$choice) {
      $output .= form_radio($choice, $name, $key, ($key == $value));
    }
    return form_item($title, $output, $description);
  }
}

864 865
function form_file($title, $name, $size, $description = 0) {
  return form_item($title, "<input type=\"file\" class=\"form-file\" name=\"edit[$name]\" size=\"$size\" />\n", $description);
Dries's avatar
 
Dries committed
866 867 868 869 870 871
}

function form_hidden($name, $value) {
  return "<input type=\"hidden\" name=\"edit[$name]\" value=\"". check_form($value) ."\" />\n";
}

872
function form_submit($value, $name = "op", $attributes = 0) {
Dries's avatar
 
Dries committed
873
  return "<input type=\"submit\" class=\"form-submit\" name=\"$name\" value=\"". check_form($value) ."\" />\n";
Dries's avatar
 
Dries committed
874 875
}

Dries's avatar
 
Dries committed
876
function form_weight($title = NULL, $name = "weight", $value = 0, $delta = 10, $description = 0, $extra = 0) {
Dries's avatar
 
Dries committed
877
  for ($n = (-1 * $delta); $n <= $delta; $n++) {
Dries's avatar
 
Dries committed
878 879 880 881 882 883
    $weights[$n] = $n;
  }

  return form_select($title, $name, $value, $weights, $description, $extra);
}

Dries's avatar
 
Dries committed
884 885 886 887
function form_allowed_tags_text() {
  return variable_get("allowed_html", "") ? (t("Allowed HTML tags") .": ". htmlspecialchars(variable_get("allowed_html", ""))) : "";
}

Dries's avatar
 
Dries committed
888 889 890
/**
 * Given an old url, return the alias.
 */
Dries's avatar
 
Dries committed
891 892
function drupal_get_path_alias($path) {
  $map = drupal_get_path_map();
Dries's avatar
 
Dries committed
893

Dries's avatar
 
Dries committed
894 895 896
  if ($map) {
    return array_search($path, $map);
  }
Dries's avatar
 
Dries committed
897 898 899
}

/**
Dries's avatar
 
Dries committed
900
 * Given an alias, return the default url.
Dries's avatar
 
Dries committed
901
 */
Dries's avatar
 
Dries committed
902 903
function drupal_get_normal_path($path) {
  $map = drupal_get_path_map();
Dries's avatar
 
Dries committed
904 905 906
  return $map[$path];
}

Dries's avatar
 
Dries committed
907
function url($url = NULL, $query = NULL) {
Dries's avatar
 
Dries committed
908
  global $base_url;
Dries's avatar
 
Dries committed
909

Dries's avatar
 
Dries committed
910 911 912 913 914 915 916 917 918 919 920
  static $script;

  if (empty($script)) {
    /*
    ** On some webservers such as IIS we can't omit "index.php".  As such we
    ** generate "index.php?q=foo" instead of "?q=foo" on anything that is not
    ** Apache.
    */
    $script = (strpos($_SERVER["SERVER_SOFTWARE"], "Apache") === false) ? "index.php" : "";
  }

Dries's avatar
 
Dries committed
921
  if ($alias = drupal_get_path_alias($url)) {
Dries's avatar
 
Dries committed
922 923 924
    $url = $alias;
  }

Dries's avatar
 
Dries committed
925
  if (variable_get("clean_url", "0") == "0") {
Dries's avatar
 
Dries committed
926 927
    if (isset($url)) {
      if (isset($query)) {
Dries's avatar
 
Dries committed
928
        return "$base_url/$script?q=$url&amp;$query";
Dries's avatar
 
Dries committed
929 930
      }
      else {
Dries's avatar
 
Dries committed
931
        return "$base_url/$script?q=$url";
Dries's avatar
 
Dries committed
932
      }
Dries's avatar
 
Dries committed
933 934
    }
    else {
Dries's avatar
 
Dries committed
935
      if (isset($query)) {
Dries's avatar
 
Dries committed
936
        return "$base_url/$script?$query";
Dries's avatar
 
Dries committed
937 938
      }
      else {
Dries's avatar
 
Dries committed
939
        return "$base_url/";
Dries's avatar
 
Dries committed
940
      }
Dries's avatar
 
Dries committed
941 942 943
    }
  }
  else {
Dries's avatar
 
Dries committed
944 945
    if (isset($url)) {
      if (isset($query)) {
Dries's avatar
 
Dries committed
946
        return "$base_url/$url?$query";
Dries's avatar
 
Dries committed
947 948
      }
      else {
Dries's avatar
 
Dries committed
949
        return "$base_url/$url";
Dries's avatar
 
Dries committed
950
      }
Dries's avatar
 
Dries committed
951
    }
Dries's avatar
 
Dries committed
952
    else {
Dries's avatar
 
Dries committed
953
      if (isset($query)) {
Dries's avatar
 
Dries committed
954
        return "$base_url/$script?$query";
Dries's avatar
 
Dries committed
955 956
      }
      else {
Dries's avatar
 
Dries committed
957
        return "$base_url/";
Dries's avatar
 
Dries committed
958
      }
Dries's avatar
 
Dries committed
959
    }
Dries's avatar
 
Dries committed
960
  }
Dries's avatar
 
Dries committed
961 962
}

963 964 965 966 967 968 969
function drupal_attributes($attributes = 0) {
  if (is_array($attributes)) {
    $t = array();
    foreach ($attributes as $key => $value) {
      $t[] = "$key=\"$value\"";
    }
    return " ". implode($t, " ");
Dries's avatar
 
Dries committed
970
  }
971
}
Dries's avatar
 
Dries committed
972

973 974
function l($text, $url, $attributes = array(), $query = NULL) {
  return "<a href=\"". url($url, $query) ."\"". drupal_attributes($attributes) .">$text</a>";
Dries's avatar
 
Dries committed
975 976
}

Dries's avatar
 
Dries committed
977
function field_get($string, $name) {
978
  ereg(",?$name=([^,]+)", ", $string", $regs);
Dries's avatar
 
Dries committed
979 980 981 982 983
  return $regs[1];
}

function field_set($string, $name, $value) {
  $rval = ereg_replace(",$name=[^,]+", "", ",$string");
Dries's avatar
 
Dries committed
984
  if (isset($value)) {
Kjartan's avatar
Kjartan committed
985 986
    $rval .= ($rval == "," ? "" : ",") ."$name=$value";
  }
Dries's avatar
 
Dries committed
987 988 989 990
  return substr($rval, 1);
}

function link_page() {
991
  global $custom_links;
Dries's avatar
 
Dries committed
992

993
  if (is_array($custom_links)) {
994 995 996
    return $custom_links;
  }
  else {
Dries's avatar
 
Dries committed
997
    $links = module_invoke_all("link", "page");
998
    array_unshift($links, l(t("home"), "", array("title" => t("Return to the main page."))));
999
    return $links;
Dries's avatar
 
Dries committed
1000
  }
Dries's avatar
 
Dries committed
1001
}
Dries's avatar
 
Dries committed
1002 1003

function link_node($node, $main = 0) {
Dries's avatar
 
Dries committed
1004
  return module_invoke_all("link", "node", $node, $main);
Dries's avatar
 
Dries committed
1005 1006 1007 1008
}

function timer_start() {
  global $timer;
Dries's avatar
 
Dries committed
1009 1010
  list($usec, $sec) = explode(" ", microtime());
  $timer = (float)$usec + (float)$sec;
Dries's avatar
 
Dries committed
1011 1012
}

Dries's avatar
 
Dries committed
1013
function drupal_page_header() {
1014

Dries's avatar
 
Dries committed
1015 1016 1017 1018 1019
  if (variable_get("dev_timer", 0)) {
    timer_start();
  }

  if (variable_get("cache", 0)) {
Dries's avatar
 
Dries committed
1020
    if ($cache = page_get_cache()) {
Dries's avatar
 
Dries committed
1021 1022

      // Set default values:
Dries's avatar
 
Dries committed
1023
      $date = gmdate("D, d M Y H:i:s", $cache->created) ." GMT";
Dries's avatar
 
Dries committed
1024 1025 1026
      $etag = '"'. md5($date) .'"';

      // Check http headers:
1027
      $modified_since = isset($_SERVER["HTTP_IF_MODIFIED_SINCE"]) ? $_SERVER["HTTP_IF_MODIFIED_SINCE"] == $date : NULL;
1028
      $none_match = isset($_SERVER["HTTP_IF_NONE_MATCH"]) ? $_SERVER["HTTP_IF_NONE_MATCH"] == $etag : NULL;
Dries's avatar
 
Dries committed
1029

1030 1031
      // The type checking here is very important, be careful when changing entries.
      if (($modified_since !== NULL || $none_match !== NULL) && $modified_since !== false && $none_match !== false) {
Dries's avatar
 
Dries committed
1032 1033
        header("HTTP/1.0 304 Not Modified");
        exit();
Dries's avatar
 
Dries committed
1034
      }
Dries's avatar
 
Dries committed
1035

1036 1037 1038
      // Send appropriate response:
      header("Last-Modified: $date");
      header("ETag: $etag");
Dries's avatar
 
Dries committed
1039
      print $cache->data;
Dries's avatar
 
Dries committed
1040 1041 1042 1043 1044 1045 1046 1047

      /*
      ** A hook for modules where modules may take action at the end of a
      ** request good uses include setting a cache, page logging, etc.
      */

      module_invoke_all("exit");

Dries's avatar
 
Dries committed
1048 1049 1050
      exit();
    }
  }
Dries's avatar
 
Dries committed
1051 1052 1053 1054 1055 1056 1057 1058

  /*
  ** Putting the check here avoids SQL query overhead in case we are
  ** serving cached pages.  The downside, however, is that the init
  ** hooks might use unchecked data.
  */

  if (!user_access("bypass input data check")) {
Dries's avatar
 
Dries committed
1059 1060 1061
    if (!valid_input_data($_REQUEST)) {
      die("terminated request because of suspicious input data");
    }
Dries's avatar
 
Dries committed
1062
  }
Dries's avatar
 
Dries committed
1063 1064
}

Dries's avatar
 
Dries committed
1065
function drupal_page_footer() {
Dries's avatar
 
Dries committed
1066
  if (variable_get("cache", 0)) {
Dries's avatar
 
Dries committed
1067
    page_set_cache();
Dries's avatar
 
Dries committed
1068
  }
Dries's avatar
 
Dries committed
1069

Dries's avatar
 
Dries committed
1070 1071 1072 1073 1074
  /*
  ** A hook for modules where modules may take action at the end of a
  ** request good uses include setting a cache, page logging, etc.
  */

Dries's avatar
 
Dries committed
1075
  module_invoke_all("exit");
Dries's avatar
 
Dries committed
1076 1077 1078
}

unset($conf);
Dries's avatar
 
Dries committed
1079

1080 1081
$config = conf_init();

Dries's avatar
 
Dries committed
1082 1083 1084 1085
include_once "includes/$config.php";
include_once "includes/database.inc";
include_once "includes/module.inc";
include_once "includes/theme.inc";
Dries's avatar
 
Dries committed
1086
include_once "includes/pager.inc";
Dries's avatar
 
Dries committed
1087
include_once "includes/menu.inc";
Dries's avatar
 
Dries committed
1088
include_once "includes/xmlrpc.inc";
Dries's avatar
 
Dries committed
1089
include_once "includes/tablesort.inc";
1090

1091 1092
// initialize configuration variables, using values from conf.php if available:
$conf = variable_init(isset($conf) ? $conf : array());
Dries's avatar
 
Dries committed
1093

Dries's avatar
 
Dries committed
1094 1095 1096
// set error handler:
set_error_handler("error_handler");

Dries's avatar
 
Dries committed
1097
// spit out the correct charset http header
Dries's avatar
 
Dries committed
1098
header("Content-Type: text/html; charset=utf-8");
Dries's avatar
 
Dries committed
1099

Dries's avatar
 
Dries committed
1100 1101
// initialize the _GET["q"] prior to loading the modules and invoking their 'init' hook:
if (!empty($_GET["q"])) {
Dries's avatar
 
Dries committed
1102
  if ($path = drupal_get_normal_path(trim($_GET["q"], "/"))) {
Dries's avatar
 
Dries committed
1103 1104 1105 1106
    $_GET["q"] = $path;
  }
}
else {
Dries's avatar
 
Dries committed
1107 1108 1109 1110 1111 1112
  if ($path = drupal_get_normal_path(variable_get("site_frontpage", "node"))) {
    $_GET["q"] = $path;
  }
  else {
    $_GET["q"] = variable_get("site_frontpage", "node");
  }
Dries's avatar
 
Dries committed
1113 1114
}

Dries's avatar
 
Dries committed
1115 1116 1117
// initialize installed modules:
module_init();

Dries's avatar
 
Dries committed
1118 1119 1120 1121
// initialize localization system:
$locale = locale_init();

// initialize theme:
Dries's avatar
 
Dries committed
1122
$theme = init_theme();
Dries's avatar
 
Dries committed
1123
?>