common.inc 27.8 KB
Newer Older
Dries's avatar
 
Dries committed
1 2 3 4
<?php
// $Id$

function conf_init() {
Dries's avatar
 
Dries committed
5
  global $HTTP_HOST, $PHP_SELF;
Dries's avatar
 
Dries committed
6 7 8 9 10 11 12

  /*
  ** 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
13 14 15
  $uri = $PHP_SELF;

  $file = strtolower(strtr($HTTP_HOST . substr($uri, 0, strrpos($uri, "/")), "/:", ".."));
Dries's avatar
 
Dries committed
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31

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

  return "conf";
}

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
32 33

  if ($errno & E_ALL ^ E_NOTICE) {
Dries's avatar
 
Dries committed
34
    watchdog("error", $types[$errno] .": $message in $filename on line $line.");
35
    print "<pre>$entry</pre>";
Dries's avatar
 
Dries committed
36 37 38
  }
}

Dries's avatar
 
Dries committed
39
function watchdog($type, $message, $link = NULL) {
Dries's avatar
 
Dries committed
40
  global $user;
Dries's avatar
Dries committed
41
  db_query("INSERT INTO watchdog (uid, type, message, link, location, hostname, timestamp) VALUES ('%d', '%s', '%s', '%s', '%s', '%s', '%s')", $user->uid, $type, $message, $link, request_uri(), getenv("REMOTE_ADDR"), time());
Dries's avatar
 
Dries committed
42 43 44 45 46 47 48 49 50 51 52 53 54 55
}

function throttle($type, $rate) {
  if (!user_access("access administration pages")) {
    if ($throttle = db_fetch_object(db_query("SELECT * FROM watchdog WHERE type = '$type' AND hostname = '". getenv("REMOTE_ADDR") ."' AND ". time() ." - timestamp < $rate"))) {
      watchdog("warning", "throttle: '". getenv("REMOTE_ADDR") ."' exceeded submission rate - $throttle->type");
      die(message_throttle());
    }
    else {
      watchdog($type, "throttle");
    }
  }
}

Dries's avatar
 
Dries committed
56 57
function check_php_setting($name, $value) {
  if (ini_get($name) != $value) {
Steven Wittens's avatar
Steven Wittens committed
58
    print "<p>Note that the value of PHP's configuration option <code><b>$name</b></code> is incorrect.  It should be set to '$value' for Drupal to work properly.  Either configure your webserver to support <code>.htaccess</code> files so Drupal's <code>.htaccess</code> file can set it to the proper value, or edit your <code>php.ini</code> file directly.  This message will automatically dissapear when the problem has been fixed.</p>";
Dries's avatar
 
Dries committed
59 60 61
  }
}

Dries's avatar
 
Dries committed
62 63 64 65 66 67 68 69 70 71 72 73
function arg($index) {

  global $q;
  static $arguments;

  if (empty($arguments)) {
    $arguments = explode("/", $q);
  }

  return $arguments[$index];
}

Dries's avatar
 
Dries committed
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
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
102
function request_uri() {
Dries's avatar
 
Dries committed
103 104 105 106
  // since request_uri() is only available on apache, we generate equivalent using other environment vars.

  global $REQUEST_URI, $PATH_INFO, $QUERY_STRING;

Dries's avatar
 
Dries committed
107
  if (isset($REQUEST_URI)) {
Dries's avatar
 
Dries committed
108 109 110
    return $REQUEST_URI;
  }
  else {
111
    return $PATH_INFO ."?". $QUERY_STRING;
Dries's avatar
 
Dries committed
112
  }
Dries's avatar
 
Dries committed
113 114
}

Dries's avatar
 
Dries committed
115
function message_access() {
Dries's avatar
 
Dries committed
116
  return t("You are not authorized to access this page.");
Dries's avatar
 
Dries committed
117 118 119 120 121 122 123 124 125 126
}

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
127 128
function locale_init() {
  global $languages, $user;
Dries's avatar
 
Dries committed
129 130 131 132 133 134
  if ($user->uid && $languages[$user->language]) {
    return $user->language;
  }
  else {
    return key($languages);
  }
Dries's avatar
 
Dries committed
135 136
}

Dries's avatar
 
Dries committed
137
function t($string, $args = 0) {
Dries's avatar
 
Dries committed
138
  global $languages;
139

Dries's avatar
 
Dries committed
140 141 142 143 144 145 146
  /*
  ** 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
147 148
  **           account</a> before viewing the next page.", array("%url"
  **           => url("user/register")));
Dries's avatar
 
Dries committed
149 150
  */

151
  $string = ($languages && module_exist("locale") ? locale($string) : $string);
152

Dries's avatar
 
Dries committed
153 154
  if (!$args) {
    return $string;
Kjartan's avatar
Kjartan committed
155 156
  }
  else {
Dries's avatar
 
Dries committed
157 158
    return strtr($string, $args);
  }
Dries's avatar
 
Dries committed
159 160 161 162 163 164
}

function variable_init($conf = array()) {
  $result = db_query("SELECT * FROM variable");
  while ($variable = db_fetch_object($result)) {
    if (!isset($conf[$variable->name])) {
Dries's avatar
 
Dries committed
165
      $conf[$variable->name] = unserialize($variable->value);
Dries's avatar
 
Dries committed
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
    }
  }

  return $conf;
}

function variable_get($name, $default, $object = 0) {
  global $conf;

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

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

Dries's avatar
 
Dries committed
181
  db_query("DELETE FROM variable WHERE name = '%s'", $name);
Dries's avatar
 
Dries committed
182
  db_query("INSERT INTO variable (name, value) VALUES ('%s', '%s')", $name, serialize($value));
Dries's avatar
 
Dries committed
183 184 185 186 187 188 189

  $conf[$name] = $value;
}

function variable_del($name) {
  global $conf;

Dries's avatar
 
Dries committed
190
  db_query("DELETE FROM variable WHERE name = '%s'", $name);
Dries's avatar
 
Dries committed
191 192 193 194

  unset($conf[$name]);
}

Dries's avatar
 
Dries committed
195
function table_cell($cell, $header = 0) {
Dries's avatar
 
Dries committed
196
  if (is_array($cell)) {
Dries's avatar
 
Dries committed
197 198 199 200 201 202 203 204 205 206 207
    $data = $cell["data"];
    foreach ($cell as $key => $value) {
      if ($key != "data")  {
        $attributes .= " $key=\"$value\"";
      }
    }
  }
  else {
    $data = $cell;
  }

Dries's avatar
 
Dries committed
208
  if ($header) {
Dries's avatar
 
Dries committed
209 210 211 212 213 214 215 216 217 218 219
    $output = "<th$attributes>$data</th>";
  }
  else {
    $output = "<td$attributes>$data</td>";
  }

  return $output;
}

function table($header, $rows) {

220
  $output = "<table>\n";
Dries's avatar
 
Dries committed
221 222 223 224 225

  /*
  ** Emit the table header:
  */

Dries's avatar
 
Dries committed
226 227 228 229 230
  if (is_array($header)) {
    $output .= " <tr>";
    foreach ($header as $cell) {
      $output .= table_cell($cell, 1);
    }
Dries's avatar
 
Dries committed
231
    $output .= " </tr>\n";
Dries's avatar
 
Dries committed
232 233 234 235 236 237
  }

  /*
  ** Emit the table rows:
  */

Dries's avatar
 
Dries committed
238 239 240 241 242 243 244 245
  if (is_array($rows)) {
    foreach ($rows as $number => $row) {
      if ($number % 2 == 1) {
        $output .= " <tr class=\"light\">";
      }
      else {
        $output .= " <tr class=\"dark\">";
      }
Dries's avatar
 
Dries committed
246

Dries's avatar
 
Dries committed
247 248 249
      foreach ($row as $cell) {
        $output .= table_cell($cell, 0);
      }
Dries's avatar
 
Dries committed
250
      $output .= " </tr>\n";
Dries's avatar
 
Dries committed
251 252 253
    }
  }

Dries's avatar
 
Dries committed
254
  $output .= "</table>\n";
Dries's avatar
 
Dries committed
255 256 257 258

  return $output;
}

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;
  }
}

Kjartan's avatar
Kjartan committed
279 280 281 282
/**
 * 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
283
 *               array("count" => ..., "link" => ..., "title" => ...,
Kjartan's avatar
Kjartan committed
284 285 286
 *               "user" => ..., "date" => ..., "keywords" => ...)
 * @param $type  module type of this item
 */
Dries's avatar
 
Dries committed
287
function search_item($item, $type) {
Dries's avatar
 
Dries committed
288 289 290 291 292 293 294 295 296 297 298 299 300 301

  /*
  ** 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 {
    $output .= " <b>". $item["count"] ."&nbsp;&nbsp;<u><a href=\"". $item["link"] ."\">". $item["title"] ."</a></u></b><br />";
    $output .= " <small>$type ". ($item["user"] ? " - ". $item["user"] : "") ."". ($item["date"] ? " - ". format_date($item["date"], "small") : "") ."</small>";
    $output .= "<br /><br />";
  }
Dries's avatar
 
Dries committed
302 303 304 305

  return $output;
}

Kjartan's avatar
Kjartan committed
306 307 308 309
/**
 * Render a generic search form.
 *
 * "Generic" means "universal usable" - that is, usable not only from
Dries's avatar
 
Dries committed
310
 * 'site.com/search', but also as a simple seach box (without
Dries's avatar
 
Dries committed
311 312
 * "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
313 314
 * parts of this form.
 *
Dries's avatar
 
Dries committed
315
 * @param $action  Form action. Defaults to 'site.com/search'.
Kjartan's avatar
Kjartan committed
316
 * @param $query   Query string. Defaults to global $keys.
Dries's avatar
 
Dries committed
317
 * @param $options != 0: Render additional form fields/text
Kjartan's avatar
Kjartan committed
318 319
 *                 ("Restrict search to", help text, etc).
 */
Dries's avatar
 
Dries committed
320 321 322 323
function search_form($action = 0, $query = 0, $options = 0) {
  global $keys;

  if (!$action) {
Dries's avatar
 
Dries committed
324
    $action = url("search");
Dries's avatar
 
Dries committed
325 326 327 328 329 330
  }

  if (!$query) {
    $query = $keys;
  }

Kjartan's avatar
Kjartan committed
331 332
  $output .= " <br /><input type=\"text\" size=\"50\" value=\"". check_form($keys) ."\" name=\"keys\" />";
  $output .= " <input type=\"submit\" value=\"". t("Search") ."\" />\n";
Dries's avatar
 
Dries committed
333 334 335 336 337 338 339

  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
340
        $output .= " <input type=\"checkbox\" name=\"edit[type][$name]\" ". ($edit["type"][$name] ? " checked=\"checked\"" : "") ." /> ". t($name);
Dries's avatar
 
Dries committed
341 342 343 344
      }
    }
  }

Kjartan's avatar
Kjartan committed
345 346
  $form .= "<br />";

Dries's avatar
 
Dries committed
347 348 349 350
  return form($output, "post", $action);
}

/*
Kjartan's avatar
Kjartan committed
351 352
 * Collect the search results:
 */
Dries's avatar
 
Dries committed
353 354 355
function search_data() {
  global $keys, $edit;

Dries's avatar
 
Dries committed
356
  if (isset($keys)) {
Dries's avatar
 
Dries committed
357 358
    foreach (module_list() as $name) {
      if (module_hook($name, "search") && (!$edit["type"] || $edit["type"][$name]) && ($result = module_invoke($name, "search", check_query($keys)))) {
Kjartan's avatar
Kjartan committed
359
        if ($name == "node" || $name == "comment") {
Dries's avatar
 
Dries committed
360
          $output .= "<p><b>". t("Matching ". $name ."s ranked in order of relevance") .":</b></p>";
Kjartan's avatar
Kjartan committed
361 362
        }
        else {
Dries's avatar
 
Dries committed
363
          $output .= "<p><b>". t("Matching ". $name ."s") .":</b></p>";
Kjartan's avatar
Kjartan committed
364
        }
Dries's avatar
 
Dries committed
365 366 367 368 369
        foreach ($result as $entry) {
          $output .= search_item($entry, $name);
        }
      }
    }
Kjartan's avatar
Kjartan committed
370
    if (!$output) {
Dries's avatar
 
Dries committed
371 372 373 374 375 376 377
      $output .= t("Your search yielded no results.");
    }
  }

  return $output;
}

Kjartan's avatar
Kjartan committed
378 379 380
/**
 * Display the search form and the resulting data.
 *
Dries's avatar
 
Dries committed
381
 * @param $type    If set, search only nodes of this type.
Kjartan's avatar
Kjartan committed
382
 *                 Otherwise, search all types.
Dries's avatar
 
Dries committed
383
 * @param $action  Form action. Defaults to 'site.com/search'.
Kjartan's avatar
Kjartan committed
384
 * @param $query   Query string. Defaults to global $keys.
Dries's avatar
 
Dries committed
385
 * @param $options != 0: Render additional form fields/text
Kjartan's avatar
Kjartan committed
386 387
 *                 ("Restrict search to", help text, etc).
 */
Dries's avatar
 
Dries committed
388 389 390
function search_type($type = 0, $action = 0, $query = 0, $options = 0) {
  global $edit;

Dries's avatar
 
Dries committed
391
  if (isset($type)) {
Dries's avatar
 
Dries committed
392 393 394 395 396 397
    $edit["type"][$type] = "on";
  }

  return search_form($action, $query, $options) . search_data();
}

Dries's avatar
 
Dries committed
398

Dries's avatar
 
Dries committed
399 400
function drupal_goto($url) {

Dries's avatar
 
Dries committed
401 402 403
  /*
  ** Translate &amp; to simply &
  */
Dries's avatar
 
Dries committed
404

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

Dries's avatar
 
Dries committed
407 408 409 410 411
  /*
  ** 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
412
  if (!ini_get("session.use_trans_sid") || !session_id() || strstr($url, session_id())) {
Dries's avatar
 
Dries committed
413 414 415
    header("Location: $url");
  }
  else {
Dries's avatar
 
Dries committed
416 417 418 419 420 421 422 423
    $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
424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439
  }

  /*
  ** The "Location" header sends a REDIRECT status code to the http
  ** deamon.  In some cases this can go wrong, so we make sure none
  ** of the code /below/ gets executed when we redirect.
  */

  exit();
}

/*
** Stores the referer in a persistent variable:
*/

function referer_save() {
Dries's avatar
 
Dries committed
440
  global $referer, $HTTP_REFERER;
Dries's avatar
 
Dries committed
441

Dries's avatar
 
Dries committed
442
  if (!strstr($HTTP_REFERER, request_uri())) {
Dries's avatar
 
Dries committed
443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463
    $referer = $HTTP_REFERER;
    session_register("referer");
  }
}

/*
** Restores the referer from a persistent variable:
*/

function referer_load() {
  global $referer;

  if (session_is_registered("referer")) {
    return $referer;
  }
  else {
    return 0;
  }
}

function check_form($text) {
Dries's avatar
 
Dries committed
464
  return htmlspecialchars($text);
Dries's avatar
 
Dries committed
465 466
}

Dries's avatar
 
Dries committed
467
function check_query($text) {
Dries's avatar
 
Dries committed
468
  return addslashes($text);
Dries's avatar
 
Dries committed
469 470
}

Dries's avatar
 
Dries committed
471
function check_input($text) {
Dries's avatar
 
Dries committed
472
  return addslashes($text);
Dries's avatar
 
Dries committed
473 474 475
}

function filter($text) {
Dries's avatar
 
Dries committed
476 477 478 479 480 481 482 483

  foreach (module_list() as $name) {
    if (module_hook($name, "filter")) {
      $text = module_invoke($name, "filter", $text);
    }
  }

  return $text;
Dries's avatar
 
Dries committed
484 485
}

Dries's avatar
 
Dries committed
486 487
function rewrite_old_urls($text) {

Dries's avatar
 
Dries committed
488 489 490 491
  global $base_url;

  $end = substr($base_url, 12);

Dries's avatar
 
Dries committed
492 493 494
  /*
  ** 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
495 496
  ** (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
497 498 499
  ** and comment bodies.
  */

Dries's avatar
 
Dries committed
500
  if (variable_get("clean_url", "0") == "0") {
Dries's avatar
 
Dries committed
501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516
    /*
    ** 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
517
    // rewrite 'node.php?id=<number>[&cid=<number>]' style URLs:
Dries's avatar
 
Dries committed
518
    $text = eregi_replace("$end/(node)\.php\?id=([[:digit:]]+)(&cid=)?([[:digit:]]*)", "$end/?q=\\1/view/\\2/\\4", $text);
Dries's avatar
 
Dries committed
519

Dries's avatar
 
Dries committed
520
    // rewrite 'module.php?mod=<name>{&<op>=<value>}' style URLs:
Dries's avatar
 
Dries committed
521 522 523
    $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
524 525
  }
  else {
Dries's avatar
 
Dries committed
526 527 528 529
    /*
    ** Relative URLs:
    */

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

    // rewrite 'module.php?mod=<name>{&<op>=<value>}' style URLs:
Dries's avatar
 
Dries committed
534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549
    $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
550

Dries's avatar
 
Dries committed
551 552 553
  return $text;
}

Dries's avatar
 
Dries committed
554
function check_output($text) {
Dries's avatar
 
Dries committed
555
  if (isset($text)) {
Dries's avatar
 
Dries committed
556 557 558 559

    // temporary: for development purpose
    $text = rewrite_old_urls($text);

Dries's avatar
 
Dries committed
560
    if (strip_tags($text, "<a><i><b><u><tt><code><cite><strong><img>") == $text) {
Dries's avatar
 
Dries committed
561 562 563 564 565 566 567 568
      $text = nl2br($text);
    }
  }
  else {
    $text = message_na();
  }

  return $text;
Dries's avatar
 
Dries committed
569 570 571 572 573 574 575 576 577 578 579
}

function check_file($filename) {
  if (is_uploaded_file($filename)) {
    return 1;
  }
  else {
    return 0;
  }
}

Dries's avatar
 
Dries committed
580 581 582
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
583 584 585 586 587
  $output .= "<channel>\n";
  $output .= " <title>". htmlentities(strip_tags($title)) ."</title>\n";
  $output .= " <link>". htmlentities(strip_tags($link)) ."</link>\n";
  $output .= " <description>". htmlentities($description) ."</description>\n";
  $output .= " <language>". htmlentities(strip_tags($language)) ."</language>\n";
Dries's avatar
 
Dries committed
588
  foreach ($args as $key => $value) {
589
    $output .= "<$key>". htmlentities(strip_tags($value)) ."</$key>";
Dries's avatar
 
Dries committed
590
  }
Dries's avatar
 
Dries committed
591 592 593 594 595 596
  $output .= $items;
  $output .= "</channel>\n";

  return $output;
}

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

Dries's avatar
 
Dries committed
600 601 602
  $output .= "<item>\n";
  $output .= " <title>". htmlentities(strip_tags($title)) ."</title>\n";
  $output .= " <link>". htmlentities(strip_tags($link)) ."</link>\n";
Dries's avatar
 
Dries committed
603
  $output .= " <description>". htmlentities(check_output($description)) ."</description>\n";
Dries's avatar
 
Dries committed
604
  foreach ($args as $key => $value) {
605
    $output .= "<$key>". htmlentities(strip_tags($value)) ."</$key>";
Dries's avatar
 
Dries committed
606
  }
Dries's avatar
 
Dries committed
607 608 609 610 611
  $output .= "</item>\n";

  return $output;
}

Dries's avatar
 
Dries committed
612 613 614 615 616 617 618 619 620 621 622 623 624 625
/**
 * 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
626
function format_plural($count, $singular, $plural) {
Dries's avatar
 
Dries committed
627
  return t($count == 1 ? $singular : $plural, array("%count" => $count));
Dries's avatar
 
Dries committed
628 629 630
}

function format_size($size) {
Dries's avatar
 
Dries committed
631
  $suffix = t("bytes");
Dries's avatar
 
Dries committed
632 633
  if ($size > 1024) {
    $size = round($size / 1024, 2);
Dries's avatar
 
Dries committed
634
    $suffix = t("KB");
Dries's avatar
 
Dries committed
635 636 637
  }
  if ($size > 1024) {
    $size = round($size / 1024, 2);
Dries's avatar
 
Dries committed
638
    $suffix = t("MB");
Dries's avatar
 
Dries committed
639
  }
Dries's avatar
 
Dries committed
640
  return t("%size %suffix", array("%size" => $size, "%suffix" => $suffix));
Dries's avatar
 
Dries committed
641 642
}

Dries's avatar
 
Dries committed
643
function cache_get($key) {
Dries's avatar
 
Dries committed
644
  $cache = db_fetch_object(db_query("SELECT data, created FROM cache WHERE cid = '%s'", $key));
Dries's avatar
 
Dries committed
645
  return $cache->data ? $cache : 0;
Dries's avatar
 
Dries committed
646 647 648
}

function cache_set($cid, $data, $expire = 0) {
649 650
  if (db_fetch_object(db_query("SELECT cid FROM cache WHERE cid = '%s'", $cid))) {
    db_query("UPDATE cache SET data = '%s', created = %d, expire = %d WHERE cid = '%s'", $data, time(), $expire, $cid);
Dries's avatar
 
Dries committed
651 652
  }
  else {
Dries's avatar
 
Dries committed
653
    db_query("INSERT INTO cache (cid, data, created, expire) VALUES('%s', '%s', %d, %d)", $cid, $data, time(), $expire);
Dries's avatar
 
Dries committed
654
  }
Dries's avatar
 
Dries committed
655 656
}

Dries's avatar
 
Dries committed
657 658
function cache_clear_all($cid = NULL) {
  if (empty($cid)) {
Dries's avatar
 
Dries committed
659
    db_query("DELETE FROM cache WHERE expire <> 0");
Dries's avatar
 
Dries committed
660 661
  }
  else {
Dries's avatar
 
Dries committed
662
    db_query("DELETE FROM cache WHERE cid = '%d'", $cid);
Dries's avatar
 
Dries committed
663
  }
Dries's avatar
 
Dries committed
664 665 666
}

function page_set_cache() {
Dries's avatar
 
Dries committed
667
  global $user, $REQUEST_METHOD;
Dries's avatar
 
Dries committed
668 669

  if (!$user->uid && $REQUEST_METHOD == "GET") {
Dries's avatar
 
Dries committed
670
    if ($data = ob_get_contents()) {
Dries's avatar
 
Dries committed
671
      cache_set(request_uri(), $data, (time() + variable_get("cache_clear", 120)));
Dries's avatar
 
Dries committed
672 673 674 675
    }
  }
}

Dries's avatar
 
Dries committed
676
function page_get_cache() {
Dries's avatar
 
Dries committed
677
  global $user, $REQUEST_METHOD;
Dries's avatar
 
Dries committed
678

Dries's avatar
 
Dries committed
679 680
  $cache = NULL;

Dries's avatar
 
Dries committed
681
  if (!$user->uid && $REQUEST_METHOD == "GET") {
Dries's avatar
 
Dries committed
682 683 684
    $cache = cache_get(request_uri());

    if (empty($cache)) {
Dries's avatar
 
Dries committed
685
      ob_start();
Dries's avatar
 
Dries committed
686 687
    }
  }
Dries's avatar
 
Dries committed
688

Dries's avatar
 
Dries committed
689
  return $cache;
Dries's avatar
 
Dries committed
690 691 692
}

function format_interval($timestamp) {
Dries's avatar
 
Dries committed
693
  $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
694
  foreach ($units as $key=>$value) {
Dries's avatar
 
Dries committed
695 696 697 698 699 700
    $key = explode("|", $key);
    if ($timestamp >= $value) {
      $output .= ($output ? " " : "") . format_plural(floor($timestamp / $value), $key[0], $key[1]);
      $timestamp %= $value;
    }
  }
Dries's avatar
 
Dries committed
701
  return ($output) ? $output : t("0 sec");
Dries's avatar
 
Dries committed
702 703 704 705 706
}

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

Kjartan's avatar
Kjartan committed
707
  $timestamp += ($user->timezone) ? $user->timezone - date("Z") : 0;
Dries's avatar
 
Dries committed
708 709 710

  switch ($type) {
    case "small":
Dries's avatar
 
Dries committed
711
      $date = date(variable_get("date_format_short", "m/d/Y - H:i"), $timestamp);
Dries's avatar
 
Dries committed
712 713
      break;
    case "medium":
714
      $date = date(variable_get("date_format_medium", "D, m/d/Y - H:i"), $timestamp);
Dries's avatar
 
Dries committed
715 716
      break;
    case "large":
717
      $date = date(variable_get("date_format_long", "l, F j, Y - H:i"), $timestamp);
Dries's avatar
 
Dries committed
718 719 720 721
      break;
    case "custom":
      for ($i = strlen($format); $i >= 0; $c = $format[--$i]) {
        if (strstr("DFlMSw", $c)) {
722
          $date = t(date($c, $timestamp)) . $date;
Dries's avatar
 
Dries committed
723
        }
Kjartan's avatar
Kjartan committed
724
        else if (strstr("AaBdgGhHiIjLmnOrstTUWYyZz", $c)) {
725
          $date = date($c, $timestamp) . $date;
Dries's avatar
 
Dries committed
726 727
        }
        else {
Kjartan's avatar
Kjartan committed
728
          $date = $c.$date;
Dries's avatar
 
Dries committed
729 730 731 732
        }
      }
      break;
    default:
733
      $date = date(variable_get("date_format_medium", "l, m/d/Y - H:i"), $timestamp);
Dries's avatar
 
Dries committed
734 735 736 737 738 739 740
  }
  return $date;
}

function format_name($object) {

  if ($object->uid && $object->name) {
Dries's avatar
 
Dries committed
741
    if (arg(0) == "admin") {
Dries's avatar
 
Dries committed
742
      $output = l($object->name, "admin/user/edit/$object->uid", array("title" => t("Administer user profile.")));
Dries's avatar
 
Dries committed
743 744
    }
    else {
Dries's avatar
 
Dries committed
745
      $output = l($object->name, "user/view/$object->uid", array("title" => t("View user profile.")));
Dries's avatar
 
Dries committed
746
    }
Dries's avatar
 
Dries committed
747
  }
Dries's avatar
 
Dries committed
748 749 750 751 752 753 754 755 756 757
  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
758
  else {
Dries's avatar
 
Dries committed
759
    $output = t(variable_get("anonymous", "Anonymous"));
Dries's avatar
 
Dries committed
760 761
  }

Dries's avatar
 
Dries committed
762
  return $output;
Dries's avatar
 
Dries committed
763 764 765
}

function form($form, $method = "post", $action = 0, $options = 0) {
766
  return "<form action=\"". ($action ? $action : htmlentities(request_uri())) ."\" method=\"$method\"". ($options ? " $options" : "") .">\n$form</form>\n";
Dries's avatar
 
Dries committed
767 768 769
}

function form_item($title, $value, $description = 0) {
770
  return "<p>". ($title ? "<b>$title:</b><br />" : "") . $value . ($description ? "<br /><small><i>$description</i></small>" : "") ."</p>\n";
Dries's avatar
 
Dries committed
771 772
}

Dries's avatar
 
Dries committed
773 774 775 776
function form_radio($title, $name, $value = 1, $checked = 0, $description = 0) {
  return form_item(0, "<input type=\"radio\" name=\"edit[$name]\" value=\"". $value ."\"". ($checked ? " checked=\"checked\"" : "") ." /> $title", $description);
}

777
function form_checkbox($title, $name, $value = 1, $checked = 0, $description = 0) {
778
  return form_hidden($name, 0) . form_item(0, "<input type=\"checkbox\" name=\"edit[$name]\" value=\"". $value ."\"". ($checked ? " checked=\"checked\"" : "") ." /> $title", $description);
Dries's avatar
 
Dries committed
779 780 781 782 783 784 785 786 787 788 789
}

function form_textfield($title, $name, $value, $size, $maxlength, $description = 0) {
  return form_item($title, "<input maxlength=\"$maxlength\" name=\"edit[$name]\" size=\"$size\" value=\"". check_form($value) ."\" />", $description);
}

function form_password($title, $name, $value, $size, $maxlength, $description = 0) {
  return form_item($title, "<input type=\"password\" maxlength=\"$maxlength\" name=\"edit[$name]\" size=\"$size\" value=\"". check_form($value) ."\" />", $description);
}

function form_textarea($title, $name, $value, $cols, $rows, $description = 0) {
Dries's avatar
 
Dries committed
790 791
  module_invoke_all("textarea", $name);  // eg. optionally plug in a WYSIWYG editor
  return form_item($title, "<textarea wrap=\"virtual\" cols=\"$cols\" rows=\"$rows\" name=\"edit[$name]\" id=\"edit[$name]\">". check_form($value) ."</textarea>", $description);
Dries's avatar
 
Dries committed
792 793
}

Dries's avatar
 
Dries committed
794
function form_select($title, $name, $value, $options, $description = 0, $extra = 0, $multiple = 0) {
Dries's avatar
 
Dries committed
795
  if (count($options) > 0) {
Kjartan's avatar
Kjartan committed
796
    foreach ($options as $key=>$choice) {
797
      $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
798
    }
Kjartan's avatar
Kjartan committed
799
    return form_item($title, "<select name=\"edit[$name]". ($multiple ? "[]" : "") ."\"". ($multiple ? " multiple " : "") . ($extra ? " $extra" : "") .">$select</select>", $description);
Dries's avatar
 
Dries committed
800 801 802 803 804 805 806 807 808 809 810 811 812 813 814
  }
}

function form_file($title, $name, $size, $description = 0) {
  return form_item($title, "<input type=\"file\" name=\"edit[$name]\" size=\"$size\" />\n", $description);
}

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

function form_submit($value) {
  return "<input type=\"submit\" name=\"op\" value=\"". check_form($value) ."\" />\n";
}

Dries's avatar
 
Dries committed
815
function form_weight($title = NULL, $name = "weight", $value = 0, $delta = 10, $description = 0, $extra = 0) {
Dries's avatar
 
Dries committed
816
  for ($n = (-1 * $delta); $n <= $delta; $n++) {
Dries's avatar
 
Dries committed
817 818 819 820 821 822
    $weights[$n] = $n;
  }

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

Dries's avatar
 
Dries committed
823
function url($url = NULL, $query = NULL) {
Dries's avatar
 
Dries committed
824
  global $base_url;
Dries's avatar
 
Dries committed
825

Dries's avatar
 
Dries committed
826
  if (variable_get("clean_url", "0") == "0") {
Dries's avatar
 
Dries committed
827 828
    if (isset($url)) {
      if (isset($query)) {
Dries's avatar
 
Dries committed
829
        return "$base_url/?q=$url&amp;$query";
Dries's avatar
 
Dries committed
830 831
      }
      else {
Dries's avatar
 
Dries committed
832
        return "$base_url/?q=$url";
Dries's avatar
 
Dries committed
833
      }
Dries's avatar
 
Dries committed
834 835
    }
    else {
Dries's avatar
 
Dries committed
836
      if (isset($query)) {
Dries's avatar
 
Dries committed
837
        return "$base_url/?$query";
Dries's avatar
 
Dries committed
838 839
      }
      else {
Dries's avatar
 
Dries committed
840
        return "$base_url/";
Dries's avatar
 
Dries committed
841
      }
Dries's avatar
 
Dries committed
842 843 844
    }
  }
  else {
Dries's avatar
 
Dries committed
845 846
    if (isset($url)) {
      if (isset($query)) {
Dries's avatar
 
Dries committed
847
        return "$base_url/$url?$query";
Dries's avatar
 
Dries committed
848 849
      }
      else {
Dries's avatar
 
Dries committed
850
        return "$base_url/$url";
Dries's avatar
 
Dries committed
851
      }
Dries's avatar
 
Dries committed
852
    }
Dries's avatar
 
Dries committed
853
    else {
Dries's avatar
 
Dries committed
854
      if (isset($query)) {
Dries's avatar
 
Dries committed
855
        return "$base_url/?$query";
Dries's avatar
 
Dries committed
856 857
      }
      else {
Dries's avatar
 
Dries committed
858
        return "$base_url/";
Dries's avatar
 
Dries committed
859
      }
Dries's avatar
 
Dries committed
860
    }
Dries's avatar
 
Dries committed
861
  }
Dries's avatar
 
Dries committed
862 863
}

Dries's avatar
 
Dries committed
864
function l($text, $url, $attributes = array(), $query = NULL) {
Dries's avatar
 
Dries committed
865

Dries's avatar
 
Dries committed
866 867 868 869
  $t = array();
  foreach ($attributes as $key => $value) {
    $t[] = "$key=\"$value\"";
  }
Dries's avatar
 
Dries committed
870 871

  return "<a href=\"". url($url, $query) ."\" ". implode($t, " ") .">$text</a>";
Dries's avatar
 
Dries committed
872 873
}

Dries's avatar
 
Dries committed
874
function field_get($string, $name) {
875
  ereg(",?$name=([^,]+)", ", $string", $regs);
Dries's avatar
 
Dries committed
876 877 878 879 880
  return $regs[1];
}

function field_set($string, $name, $value) {
  $rval = ereg_replace(",$name=[^,]+", "", ",$string");
Dries's avatar
 
Dries committed
881
  if (isset($value)) {
Kjartan's avatar
Kjartan committed
882 883
    $rval .= ($rval == "," ? "" : ",") ."$name=$value";
  }
Dries's avatar
 
Dries committed
884 885 886 887
  return substr($rval, 1);
}

function link_page() {
Dries's avatar
 
Dries committed
888
  global $custom_links, $base_url;
Dries's avatar
 
Dries committed
889

890 891 892 893
  if (is_array($custom_links)) {
    return $custom_links;
  }
  else {
Dries's avatar
 
Dries committed
894
    $links = module_invoke_all("link", "page");
895
    array_unshift($links, "<a href=\"$base_url/\" title=\"". t("Return to the main page.") ."\">". t("home") ."</a>");
896
    return $links;
Dries's avatar
 
Dries committed
897
  }
Dries's avatar
 
Dries committed
898
}
Dries's avatar
 
Dries committed
899 900

function link_node($node, $main = 0) {
Dries's avatar
 
Dries committed
901
  return module_invoke_all("link", "node", $node, $main);
Dries's avatar
 
Dries committed
902 903 904 905
}

function timer_start() {
  global $timer;
Dries's avatar
 
Dries committed
906 907
  list($usec, $sec) = explode(" ", microtime());
  $timer = (float)$usec + (float)$sec;
Dries's avatar
 
Dries committed
908 909
}

Dries's avatar
 
Dries committed
910 911 912 913 914
function query_print() {
  global $queries;
  print "<pre>";
  print_r($queries);
  print "</pre>";
Dries's avatar
 
Dries committed
915 916 917 918 919 920 921 922
}

function page_header() {
  if (variable_get("dev_timer", 0)) {
    timer_start();
  }

  if (variable_get("cache", 0)) {
Dries's avatar
 
Dries committed
923 924 925 926
    if ($cache = page_get_cache()) {
      $date = gmdate("D, d M Y H:i:s", $cache->created) ." GMT";
      header("Last-Modified: $date");
      header("ETag: \"$date\"");
927 928 929 930 931 932
      if (function_exists("getallheaders") && $headers = getallheaders()) {
        /*
        ** Notice that the above is an optional Apache-ism so for the
        ** time being we don't send 304 headers when "getallheaders()"
        ** is not supported (eg. on IIS webservers).
        */
Dries's avatar
 
Dries committed
933 934 935 936 937 938
        if ($headers["If-Modified-Since"] == $date && $headers["If-None-Match"] == "\"$date\"") {
          header("HTTP/1.0 304 Not Modified");
          exit();
        }
      }
      print $cache->data;
Dries's avatar
 
Dries committed
939 940 941 942 943 944
      exit();
    }
  }
}

function page_footer() {
Dries's avatar
 
Dries committed
945

Dries's avatar
 
Dries committed
946
  if (variable_get("cache", 0)) {
Dries's avatar
 
Dries committed
947
    page_set_cache();
Dries's avatar
 
Dries committed
948
  }
Dries's avatar
 
Dries committed
949 950 951 952

  // 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
953 954 955
}

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

957 958
$config = conf_init();

Dries's avatar
 
Dries committed
959 960 961 962
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
963
include_once "includes/pager.inc";
Dries's avatar
 
Dries committed
964
include_once "includes/menu.inc";
Dries's avatar
 
Dries committed
965
include_once "includes/xmlrpc.inc";
966

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

Dries's avatar
 
Dries committed
970 971 972
// set error handler:
set_error_handler("error_handler");

Dries's avatar
 
Dries committed
973 974 975
// initialize installed modules:
module_init();

Dries's avatar
 
Dries committed
976 977 978 979 980 981
// initialize localization system:
$locale = locale_init();

// initialize theme:
$theme = theme_init();

Dries's avatar
 
Dries committed
982
?>