common.inc 25.9 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;
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
  $file = strtolower(strtr($HTTP_HOST . substr(request_uri(), 0, strrpos(request_uri(), "/")), "/:", ".."));
Dries's avatar
 
Dries committed
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29

  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
30
  if (($errno == 1 || $errno == 2 || $errno == 4 || $errno == 256) && error_reporting()) {
Dries's avatar
 
Dries committed
31
    watchdog("error", $types[$errno] .": $message in $filename on line $line.");
32
    print "<pre>$entry</pre>";
Dries's avatar
 
Dries committed
33 34 35 36 37
  }
}

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

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
53 54 55 56 57 58
function check_php_setting($name, $value) {
  if (ini_get($name) != $value) {
    print "<p>Note tat 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 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
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
87
function path_uri($brief = 0) {
Dries's avatar
 
Dries committed
88 89
  global $HTTP_HOST;
  $path = $HTTP_HOST . substr(request_uri(), 0, strrpos(request_uri(), "/")) ."/";
Dries's avatar
 
Dries committed
90 91 92 93
  if (!$brief) {
    $path = "http://". $path;
  }
  return $path;
Dries's avatar
 
Dries committed
94 95
}

Dries's avatar
 
Dries committed
96
function request_uri() {
Dries's avatar
 
Dries committed
97 98 99 100 101 102 103 104
  // since request_uri() is only available on apache, we generate equivalent using other environment vars.

  global $REQUEST_URI, $PATH_INFO, $QUERY_STRING;

  if ($REQUEST_URI) {
    return $REQUEST_URI;
  }
  else {
105
    return $PATH_INFO ."?". $QUERY_STRING;
Dries's avatar
 
Dries committed
106
  }
Dries's avatar
 
Dries committed
107 108
}

Dries's avatar
 
Dries committed
109
function message_access() {
Dries's avatar
 
Dries committed
110
  return t("You are not authorized to access this page.");
Dries's avatar
 
Dries committed
111 112 113 114 115 116 117 118 119 120
}

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
121 122 123 124 125
function locale_init() {
  global $languages, $user;
  return ($languages ? (($user->uid && $user->language) ? $user->language : key($languages)) : 0);
}

Dries's avatar
 
Dries committed
126
function t($string, $args = 0) {
Dries's avatar
 
Dries committed
127
  global $languages;
128

Dries's avatar
 
Dries committed
129 130 131 132 133 134 135 136 137 138 139 140
  /*
  ** 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
  **           account</a> before viewing the next page.", array ("%url"
  **           => drupal_url(array ("mod" => "user", "op" => "register"),
  **           "module")));
  */

141 142
  $string = ($languages && function_exists("locale") ? locale($string) : $string);

Dries's avatar
 
Dries committed
143 144
  if (!$args) {
    return $string;
Kjartan's avatar
Kjartan committed
145 146
  }
  else {
Dries's avatar
 
Dries committed
147 148
    return strtr($string, $args);
  }
Dries's avatar
 
Dries committed
149 150 151 152 153 154
}

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
155
      $conf[$variable->name] = unserialize($variable->value);
Dries's avatar
 
Dries committed
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
    }
  }

  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
171
  db_query("DELETE FROM variable WHERE name = '%s'", $name);
Dries's avatar
 
Dries committed
172
  db_query("INSERT INTO variable (name, value) VALUES ('%s', '%s')", $name, serialize($value));
Dries's avatar
 
Dries committed
173 174 175 176 177 178 179

  $conf[$name] = $value;
}

function variable_del($name) {
  global $conf;

Dries's avatar
 
Dries committed
180
  db_query("DELETE FROM variable WHERE name = '%s'", $name);
Dries's avatar
 
Dries committed
181 182 183 184

  unset($conf[$name]);
}

Dries's avatar
 
Dries committed
185
function table_cell($cell, $header = 0) {
Dries's avatar
 
Dries committed
186
  if (is_array($cell)) {
Dries's avatar
 
Dries committed
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
    $data = $cell["data"];
    foreach ($cell as $key => $value) {
      if ($key != "data")  {
        $attributes .= " $key=\"$value\"";
      }
    }
  }
  else {
    $data = $cell;
  }

  if ($header) {
    $output = "<th$attributes>$data</th>";
  }
  else {
    $output = "<td$attributes>$data</td>";
  }

  return $output;
}

function table($header, $rows) {

  $output .= "<table>";

  /*
  ** Emit the table header:
  */

Dries's avatar
 
Dries committed
216 217 218 219 220 221
  if (is_array($header)) {
    $output .= " <tr>";
    foreach ($header as $cell) {
      $output .= table_cell($cell, 1);
    }
    $output .= " </tr>";
Dries's avatar
 
Dries committed
222 223 224 225 226 227
  }

  /*
  ** Emit the table rows:
  */

Dries's avatar
 
Dries committed
228 229 230 231 232 233 234 235
  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
236

Dries's avatar
 
Dries committed
237 238 239 240
      foreach ($row as $cell) {
        $output .= table_cell($cell, 0);
      }
      $output .= " </tr>";
Dries's avatar
 
Dries committed
241 242 243 244 245 246 247 248
    }
  }

  $output .= "</table>";

  return $output;
}

Kjartan's avatar
Kjartan committed
249 250 251 252
/**
 * 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
253
 *               array("count" => ..., "link" => ..., "title" => ...,
Kjartan's avatar
Kjartan committed
254 255 256
 *               "user" => ..., "date" => ..., "keywords" => ...)
 * @param $type  module type of this item
 */
Dries's avatar
 
Dries committed
257
function search_item($item, $type) {
Dries's avatar
 
Dries committed
258 259 260 261 262 263 264 265 266 267 268 269 270 271

  /*
  ** 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
272 273 274 275

  return $output;
}

Kjartan's avatar
Kjartan committed
276 277 278 279
/**
 * Render a generic search form.
 *
 * "Generic" means "universal usable" - that is, usable not only from
Dries's avatar
 
Dries committed
280 281 282
 * module.php?mod=search, but also as a simple seach box (without
 * "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
283 284 285 286
 * parts of this form.
 *
 * @param $action  Form action. Defaults to module.php?mod=search.
 * @param $query   Query string. Defaults to global $keys.
Dries's avatar
 
Dries committed
287
 * @param $options != 0: Render additional form fields/text
Kjartan's avatar
Kjartan committed
288 289
 *                 ("Restrict search to", help text, etc).
 */
Dries's avatar
 
Dries committed
290 291 292 293
function search_form($action = 0, $query = 0, $options = 0) {
  global $keys;

  if (!$action) {
Dries's avatar
 
Dries committed
294
    $action = drupal_url(array("mod" => "search"), "module");
Dries's avatar
 
Dries committed
295 296 297 298 299 300
  }

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

Kjartan's avatar
Kjartan committed
301 302
  $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
303 304 305 306 307 308 309

  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
310
        $output .= " <input type=\"checkbox\" name=\"edit[type][$name]\" ". ($edit["type"][$name] ? " checked=\"checked\"" : "") ." /> ". t($name);
Dries's avatar
 
Dries committed
311 312
      }
    }
Kjartan's avatar
Kjartan committed
313 314

    // TODO: (link to) search hints
Dries's avatar
 
Dries committed
315 316
  }

Kjartan's avatar
Kjartan committed
317 318
  $form .= "<br />";

Dries's avatar
 
Dries committed
319 320 321 322
  return form($output, "post", $action);
}

/*
Kjartan's avatar
Kjartan committed
323 324
 * Collect the search results:
 */
Dries's avatar
 
Dries committed
325 326 327 328 329 330 331 332
function search_data() {
  global $keys, $edit;

  $keys = check_input($keys);

  if ($keys) {
    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
333
        if ($name == "node" || $name == "comment") {
Dries's avatar
 
Dries committed
334
          $output .= "<p><b>". t("Matching ". $name ."s ranked in order of relevance") .":</b></p>";
Kjartan's avatar
Kjartan committed
335 336
        }
        else {
Dries's avatar
 
Dries committed
337
          $output .= "<p><b>". t("Matching ". $name ."s") .":</b></p>";
Kjartan's avatar
Kjartan committed
338
        }
Dries's avatar
 
Dries committed
339 340 341 342 343
        foreach ($result as $entry) {
          $output .= search_item($entry, $name);
        }
      }
    }
Kjartan's avatar
Kjartan committed
344
    if (!$output) {
Dries's avatar
 
Dries committed
345 346 347 348 349 350 351
      $output .= t("Your search yielded no results.");
    }
  }

  return $output;
}

Kjartan's avatar
Kjartan committed
352 353 354
/**
 * Display the search form and the resulting data.
 *
Dries's avatar
 
Dries committed
355
 * @param $type    If set, search only nodes of this type.
Kjartan's avatar
Kjartan committed
356 357 358
 *                 Otherwise, search all types.
 * @param $action  Form action. Defaults to module.php?mod=search.
 * @param $query   Query string. Defaults to global $keys.
Dries's avatar
 
Dries committed
359
 * @param $options != 0: Render additional form fields/text
Kjartan's avatar
Kjartan committed
360 361
 *                 ("Restrict search to", help text, etc).
 */
Dries's avatar
 
Dries committed
362 363 364 365 366 367 368 369 370 371
function search_type($type = 0, $action = 0, $query = 0, $options = 0) {
  global $edit;

  if ($type) {
    $edit["type"][$type] = "on";
  }

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

Dries's avatar
 
Dries committed
372

Dries's avatar
 
Dries committed
373 374
function drupal_goto($url) {

Dries's avatar
 
Dries committed
375 376 377
  /*
  ** Translate &amp; to simply &
  */
Dries's avatar
 
Dries committed
378

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

Dries's avatar
 
Dries committed
381 382 383 384 385 386
  /*
  ** 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
387
  if (!ini_get("session.use_trans_sid") || !session_id() || strstr($url, $sid)) {
Dries's avatar
 
Dries committed
388 389 390
    header("Location: $url");
  }
  else {
Dries's avatar
 
Dries committed
391 392 393 394 395 396 397 398
    $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
399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414
  }

  /*
  ** 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
415
  global $referer, $HTTP_REFERER;
Dries's avatar
 
Dries committed
416

Dries's avatar
 
Dries committed
417
  if (!strstr($HTTP_REFERER, request_uri())) {
Dries's avatar
 
Dries committed
418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441
    $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) {
  return htmlspecialchars(stripslashes($text));
}

Dries's avatar
 
Dries committed
442 443
function check_query($text) {
  return addslashes(stripslashes($text));
Dries's avatar
 
Dries committed
444 445
}

Dries's avatar
 
Dries committed
446
function check_input($text) {
Dries's avatar
 
Dries committed
447 448 449 450 451
  return addslashes(stripslashes($text));
}

function filter($text) {
  foreach (module_list() as $name) {
Kjartan's avatar
Kjartan committed
452 453 454
    if (module_hook($name, "filter")) {
      $text = module_invoke($name, "filter", $text);
    }
Dries's avatar
 
Dries committed
455 456 457 458 459 460
  }

  return $text;
}

function check_output($text, $nl2br = 0) {
Dries's avatar
 
Dries committed
461 462 463
  if ($text) {
    $text = stripslashes($text);

Dries's avatar
 
Dries committed
464
    if (strip_tags($text, "<a><i><b><u><tt><code><cite><strong><img>") == $text) {
Dries's avatar
 
Dries committed
465 466 467 468 469 470 471 472
      $text = nl2br($text);
    }
  }
  else {
    $text = message_na();
  }

  return $text;
Dries's avatar
 
Dries committed
473 474 475 476 477 478 479 480 481 482 483
}

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

Dries's avatar
 
Dries committed
484 485 486
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
487 488 489 490 491
  $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
492
  foreach ($args as $key => $value) {
493
    $output .= "<$key>". htmlentities(strip_tags($value)) ."</$key>";
Dries's avatar
 
Dries committed
494
  }
Dries's avatar
 
Dries committed
495 496 497 498 499 500
  $output .= $items;
  $output .= "</channel>\n";

  return $output;
}

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

Dries's avatar
 
Dries committed
504 505 506
  $output .= "<item>\n";
  $output .= " <title>". htmlentities(strip_tags($title)) ."</title>\n";
  $output .= " <link>". htmlentities(strip_tags($link)) ."</link>\n";
Dries's avatar
 
Dries committed
507
  $output .= " <description>". htmlentities(check_output($description)) ."</description>\n";
Dries's avatar
 
Dries committed
508
  foreach ($args as $key => $value) {
509
    $output .= "<$key>". htmlentities(strip_tags($value)) ."</$key>";
Dries's avatar
 
Dries committed
510
  }
Dries's avatar
 
Dries committed
511 512 513 514 515 516 517 518 519 520
  $output .= "</item>\n";

  return $output;
}

function format_plural($count, $singular, $plural) {
  return ($count == 1) ? "$count ". t($singular) : "$count ". t($plural);
}

function format_size($size) {
Dries's avatar
 
Dries committed
521
  $suffix = t("bytes");
Dries's avatar
 
Dries committed
522 523
  if ($size > 1024) {
    $size = round($size / 1024, 2);
Dries's avatar
 
Dries committed
524
    $suffix = t("KB");
Dries's avatar
 
Dries committed
525 526 527
  }
  if ($size > 1024) {
    $size = round($size / 1024, 2);
Dries's avatar
 
Dries committed
528
    $suffix = t("MB");
Dries's avatar
 
Dries committed
529
  }
Dries's avatar
 
Dries committed
530
  return t("%size %suffix", array("%size" => $size, "%suffix" => $suffix));
Dries's avatar
 
Dries committed
531 532
}

Dries's avatar
 
Dries committed
533
function cache_get($key) {
Dries's avatar
 
Dries committed
534 535 536
  $cache = db_fetch_object(db_query("SELECT data, created FROM cache WHERE cid = '%s'", $key));
  $created = $cache->created;
  return $cache->data ? $cache : 0;
Dries's avatar
 
Dries committed
537 538 539
}

function cache_set($cid, $data, $expire = 0) {
Dries's avatar
 
Dries committed
540
  if (db_fetch_object(db_query("SELECT cid FROM cache WHERE cid = '%s'", $cid))) {
Dries's avatar
 
Dries committed
541
    db_query("UPDATE cache SET data = '%s', created = %d, expire = %d WHERE cid = '%s'", $data, time(), $expire, $cid);
Dries's avatar
 
Dries committed
542 543
  }
  else {
Dries's avatar
 
Dries committed
544
    db_query("INSERT INTO cache (cid, data, created, expire) VALUES('%s', '%s', %d, %d)", $cid, $data, time(), $expire);
Dries's avatar
 
Dries committed
545
  }
Dries's avatar
 
Dries committed
546 547
}

Dries's avatar
 
Dries committed
548 549
function cache_clear_all($cid = NULL) {
  if (empty($cid)) {
Dries's avatar
 
Dries committed
550
    db_query("DELETE FROM cache WHERE expire <> 0");
Dries's avatar
 
Dries committed
551 552 553 554
  }
  else {
    db_query("DELETE FROM cache WHERE cid = '%s'", $cid);
  }
Dries's avatar
 
Dries committed
555 556
}

Dries's avatar
 
Dries committed
557 558 559 560 561 562 563
function cache_clear_old($cid = NULL) {
  if (empty($cid)) {
    db_query("DELETE FROM cache WHERE expire < ". time() ." AND expire > 0");
  }
  else {
    db_query("DELETE FROM cache WHERE cid = '%s' AND expire < %s AND expire > 0", $cid, time());
  }
Dries's avatar
 
Dries committed
564 565 566
}

function page_set_cache() {
Dries's avatar
 
Dries committed
567
  global $user, $REQUEST_METHOD;
Dries's avatar
 
Dries committed
568 569

  if (!$user->uid && $REQUEST_METHOD == "GET") {
Dries's avatar
 
Dries committed
570
    if ($data = ob_get_contents()) {
Dries's avatar
 
Dries committed
571
      cache_set(request_uri(), $data, (time() + variable_get("cache_clear", 120)));
Dries's avatar
 
Dries committed
572 573 574 575
    }
  }
}

Dries's avatar
 
Dries committed
576
function page_get_cache() {
Dries's avatar
 
Dries committed
577
  global $user, $REQUEST_METHOD;
Dries's avatar
 
Dries committed
578 579

  if (!$user->uid && $REQUEST_METHOD == "GET") {
Dries's avatar
 
Dries committed
580
    if ($cache = cache_get(request_uri())) {
Dries's avatar
 
Dries committed
581
      cache_clear_old();
Dries's avatar
 
Dries committed
582 583 584
    }
    else {
      ob_start();
Dries's avatar
 
Dries committed
585 586
    }
  }
Dries's avatar
 
Dries committed
587

Dries's avatar
 
Dries committed
588
  return $cache;
Dries's avatar
 
Dries committed
589 590 591 592
}

function format_interval($timestamp) {
  $units = array("year|years" => 31536000, "week|weeks" => 604800, "day|days" => 86400, "hour|hours" => 3600, "min|min" => 60, "sec|sec" => 1);
Kjartan's avatar
Kjartan committed
593
  foreach ($units as $key=>$value) {
Dries's avatar
 
Dries committed
594 595 596 597 598 599
    $key = explode("|", $key);
    if ($timestamp >= $value) {
      $output .= ($output ? " " : "") . format_plural(floor($timestamp / $value), $key[0], $key[1]);
      $timestamp %= $value;
    }
  }
Dries's avatar
 
Dries committed
600
  return ($output) ? $output : t("0 sec");
Dries's avatar
 
Dries committed
601 602 603 604 605
}

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

Kjartan's avatar
Kjartan committed
606
  $timestamp += ($user->timezone) ? $user->timezone - date("Z") : 0;
Dries's avatar
 
Dries committed
607 608 609

  switch ($type) {
    case "small":
Dries's avatar
 
Dries committed
610
      $date = date(variable_get("date_format", "m/d/Y - H:i"), $timestamp);
Dries's avatar
 
Dries committed
611 612
      break;
    case "medium":
Dries's avatar
 
Dries committed
613
      $date = t(date("l", $timestamp)) .", ". date(variable_get("date_format", "m/d/Y - H:i"), $timestamp);
Dries's avatar
 
Dries committed
614 615 616 617 618 619 620
      break;
    case "large":
      $date = t(date("l", $timestamp)) .", ". t(date("F", $timestamp)) ." ". date("d, Y - H:i", $timestamp);
      break;
    case "custom":
      for ($i = strlen($format); $i >= 0; $c = $format[--$i]) {
        if (strstr("DFlMSw", $c)) {
621
          $date = t(date($c, $timestamp)) . $date;
Dries's avatar
 
Dries committed
622
        }
623 624
        else if (strstr("AaBdgGhHiIjLmnrstTUWYyZz", $c)) {
          $date = date($c, $timestamp) . $date;
Dries's avatar
 
Dries committed
625 626
        }
        else {
Kjartan's avatar
Kjartan committed
627
          $date = $c.$date;
Dries's avatar
 
Dries committed
628 629 630 631
        }
      }
      break;
    default:
Dries's avatar
 
Dries committed
632
      $date = t(date("l", $timestamp)) .", ". date(variable_get("date_format", "m/d/Y - H:i"), $timestamp);
Dries's avatar
 
Dries committed
633 634 635 636 637
  }
  return $date;
}

function format_name($object) {
Dries's avatar
 
Dries committed
638
  global $PHP_SELF;
Dries's avatar
 
Dries committed
639 640

  if ($object->uid && $object->name) {
Dries's avatar
 
Dries committed
641
    if (strstr($PHP_SELF, "admin.php")) {
642
      $output = la($object->name, array("mod" => "user", "op" => "edit", "id" => $object->uid), "", array("title" => t("Administer user profile.")));
Dries's avatar
 
Dries committed
643 644
    }
    else {
645
      $output = lm($object->name, array("mod" => "user", "op" => "view", "id" => $object->uid), "", array("title" => t("View user profile.")));
Dries's avatar
 
Dries committed
646
    }
Dries's avatar
 
Dries committed
647 648
  }
  else {
Dries's avatar
 
Dries committed
649
    $output = t(variable_get(anonymous, "Anonymous"));
Dries's avatar
 
Dries committed
650 651
  }

Dries's avatar
 
Dries committed
652
  return $output;
Dries's avatar
 
Dries committed
653 654 655
}

function format_tag($link, $text) {
656
  return l(($text ? $text : $link), array("title" => $link));
Dries's avatar
 
Dries committed
657 658 659
}

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

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

667 668
function form_checkbox($title, $name, $value = 1, $checked = 0, $description = 0) {
  return form_item(0, "<input type=\"checkbox\" name=\"edit[$name]\" value=\"". $value ."\"". ($checked ? " checked=\"checked\"" : "") ." /> $title", $description);
Dries's avatar
 
Dries committed
669 670 671 672 673 674 675 676 677 678 679 680 681 682
}

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) {
  return form_item($title, "<textarea wrap=\"virtual\" cols=\"$cols\" rows=\"$rows\" name=\"edit[$name]\">". check_form($value) ."</textarea>", $description);
}

Dries's avatar
 
Dries committed
683
function form_select($title, $name, $value, $options, $description = 0, $extra = 0, $multiple = 0) {
Dries's avatar
 
Dries committed
684
  if (count($options) > 0) {
Kjartan's avatar
Kjartan committed
685
    foreach ($options as $key=>$choice) {
Dries's avatar
 
Dries committed
686 687
      $select .= "<option value=\"$key\"". (is_array($value) ? (in_array($key, $value) ? " selected=\"selected\"" : "") : ($key == $value ? " selected=\"selected\"" : "")) .">". check_form($choice) ."</option>";
    }
Kjartan's avatar
Kjartan committed
688
    return form_item($title, "<select name=\"edit[$name]". ($multiple ? "[]" : "") ."\"". ($multiple ? " multiple " : "") . ($extra ? " $extra" : "") .">$select</select>", $description);
Dries's avatar
 
Dries committed
689 690 691 692 693 694 695 696 697 698 699 700 701 702 703
  }
}

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
704 705 706 707 708 709 710 711
function form_weight($title = NULL, $name = "weight", $value = 0, $delta = 10, $description = 0, $extra = 0) {
  for ($n = (-1*$delta); $n <= $delta; $n++) {
    $weights[$n] = $n;
  }

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

Dries's avatar
 
Dries committed
712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739
/**
 * Parse an URL; this function must be follow the changes of a clean url implementation
 *
 * @param   string  $url     optional, url to parse; default to request_uri()
 * @return  array   $result  associative array:
 *                             script => index/node/module/admin
 *                             query => GET variables
 *
 */
function drupal_parse_url($url = NULL) {
  global $PHP_SELF;
  static $cache;

  if ($url == NULL) {
    $url = $PHP_SELF ."?". getenv("QUERY_STRING");
  }

  if (!$cache[$url]) {
    $parts = parse_url($url);
    preg_match("/(\w+?)\.php/", $parts["path"], $found);
    $cache[$url]["script"] = $found[1];
    parse_str($parts["query"], $cache[$url]["query"]);
    $cache[$url]["anchor"] = $parts["fragment"];
  }

  return $cache[$url];
}

Dries's avatar
 
Dries committed
740
/**
Dries's avatar
 
Dries committed
741 742
 * Build an URL; use this functions when you must write an URL
 * for example in a form or a redirect.
Dries's avatar
 
Dries committed
743 744 745
 *
 * @param $args    dictionary of arguments to be passed to the script
 * @param $script  script to be invoked; optional, defaults to node
Kjartan's avatar
Kjartan committed
746
 * @param $anchor  optional, anchor name
Dries's avatar
 
Dries committed
747
 */
Kjartan's avatar
Kjartan committed
748
function drupal_url($args = array(), $script = "node", $anchor = 0) {
Dries's avatar
 
Dries committed
749 750 751 752 753 754 755 756 757 758 759
  static $search, $replace;

  if (!$search) {
    /*
      According to RFC 1738 [3] the special characters "$-_.+!*'()," and the
      reserved characters "/:@#?&=" can be used unencoded within an URL
    */
    $search = array("%24", "%2B", "%21", "%2A", "%27", "%28", "%29", "%2C", "%2F", "%3A", "%40", "%23", "%3F", "%26", "%3D");
    $replace = array("$", "+", "!", "*", "'", "(", ")", ",", "/", ":", "@", "#", "?", "&", "=");
  }

Dries's avatar
 
Dries committed
760
  $t = array();
Dries's avatar
 
Dries committed
761
  foreach ($args as $key => $value) {
Dries's avatar
 
Dries committed
762
    $t[] = "$key=". str_replace($search, $replace, urlencode($value));
Dries's avatar
 
Dries committed
763
  }
Dries's avatar
 
Dries committed
764 765 766 767 768 769
  if (count($t)) {
    return "$script.php?". implode("&amp;", $t) . ($anchor ? "#$anchor" : "");
  }
  else {
    return "$script.php". ($anchor ? "#$anchor" : "");
  }
Dries's avatar
 
Dries committed
770 771 772
}

/**
Dries's avatar
 
Dries committed
773
 * Build a HTML link; use this functions when you must write a link
Dries's avatar
 
Dries committed
774 775 776
 * to another drupal page
 *
 * @param $args        dictionary of arguments to be passed to the script
Dries's avatar
 
Dries committed
777
 * @param $text        text of the link
Kjartan's avatar
Kjartan committed
778
 * @param $anchor      optional, anchor name
Dries's avatar
 
Dries committed
779
 * @param $script      script to be invoked; optional, defaults to node
Dries's avatar
 
Dries committed
780
 * @param $attributes  optional, dictionary of attributes for the <a> tag such as 'target', 'name', 'class', etc.
Dries's avatar
 
Dries committed
781
 */
Kjartan's avatar
Kjartan committed
782
function l($text, $args = array(), $script = "node", $anchor = "", $attributes = array()) {
Dries's avatar
 
Dries committed
783 784 785 786
  $t = array();
  foreach ($attributes as $key => $value) {
    $t[] = "$key=\"$value\"";
  }
Kjartan's avatar
Kjartan committed
787
  return "<a href=\"". drupal_url($args, $script, $anchor) ."\" ". implode($t, " ")  .">$text</a>";
Dries's avatar
 
Dries committed
788 789
}

Kjartan's avatar
Kjartan committed
790
function la($text, $args = array(), $anchor = "", $attributes = array()) {
Dries's avatar
 
Dries committed
791
  // we don't call l() to avoid another duplication of the array
Dries's avatar
 
Dries committed
792 793 794 795
  $t = array();
  foreach ($attributes as $key => $value) {
    $t[] = "$key=\"$value\"";
  }
Kjartan's avatar
Kjartan committed
796
  return "<a href=\"". drupal_url($args, "admin", $anchor) ."\" ". implode($t, " ")  .">$text</a>";
Dries's avatar
 
Dries committed
797 798
}

Kjartan's avatar
Kjartan committed
799
function lm($text, $args = array(), $anchor = "", $attributes = array()) {
Dries's avatar
 
Dries committed
800
  // we don't call l() to avoid another duplication of the array
Dries's avatar
 
Dries committed
801 802 803 804
  $t = array();
  foreach ($attributes as $key => $value) {
    $t[] = "$key=\"$value\"";
  }
Kjartan's avatar
Kjartan committed
805
  return "<a href=\"". drupal_url($args, "module", $anchor) ."\" ". implode($t, " ")  .">$text</a>";
Dries's avatar
 
Dries committed
806 807
}

Dries's avatar
 
Dries committed
808
function field_get($string, $name) {
Kjartan's avatar
Kjartan committed
809
  ereg(",$name=([^,]+)", ",$string", $regs);
Dries's avatar
 
Dries committed
810 811 812 813 814
  return $regs[1];
}

function field_set($string, $name, $value) {
  $rval = ereg_replace(",$name=[^,]+", "", ",$string");
Kjartan's avatar
Kjartan committed
815 816 817
  if ($value) {
    $rval .= ($rval == "," ? "" : ",") ."$name=$value";
  }
Dries's avatar
 
Dries committed
818 819 820 821
  return substr($rval, 1);
}

function link_page() {
822
  global $custom_links;
Dries's avatar
 
Dries committed
823

824 825 826 827
  if (is_array($custom_links)) {
    return $custom_links;
  }
  else {
Dries's avatar
 
Dries committed
828
    $links[] = l(t("home"), array(), "index", "", array("title" => t("Return to the main page.")));
Dries's avatar
 
Dries committed
829
    foreach (module_list() as $name) {
830 831
      if (module_hook($name, "link")) {
        $links = array_merge($links, module_invoke($name, "link", "page"));
Dries's avatar
 
Dries committed
832
      }
Dries's avatar
 
Dries committed
833
    }
Dries's avatar
 
Dries committed
834

835
    return $links;
Dries's avatar
 
Dries committed
836
  }
Dries's avatar
 
Dries committed
837
}
Dries's avatar
 
Dries committed
838 839 840 841 842 843 844 845 846 847 848 849 850

function link_node($node, $main = 0) {
  foreach (module_list() as $name) {
    if (module_hook($name, "link")) {
      $links = array_merge($links, module_invoke($name, "link", "node", $node, $main));
    }
  }

  return $links ? $links : array();
}

function timer_start() {
  global $timer;
Dries's avatar
 
Dries committed
851 852
  list($usec, $sec) = explode(" ", microtime());
  $timer = (float)$usec + (float)$sec;
Dries's avatar
 
Dries committed
853 854 855 856
}

function timer_print() {
  global $timer;
Dries's avatar
 
Dries committed
857 858 859 860
  list($usec, $sec) = explode(" ", microtime());
  $stop = (float)$usec + (float)$sec;
  $diff = $stop - $timer;
  print "<pre>execution time: $diff sec</pre>";
Dries's avatar
 
Dries committed
861 862 863 864 865 866 867
}

function query_print() {
  global $queries;
  print "<pre>";
  print_r($queries);
  print "</pre>";
Dries's avatar
 
Dries committed
868 869 870 871 872 873 874 875
}

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

  if (variable_get("cache", 0)) {
Dries's avatar
 
Dries committed
876 877 878 879 880 881 882 883 884 885 886 887
    if ($cache = page_get_cache()) {
      $date = gmdate("D, d M Y H:i:s", $cache->created) ." GMT";
      header("Last-Modified: $date");
      header("ETag: \"$date\"");
      if ($headers = getallheaders()) {
        // NOTE: the above is an Apache-ism so for the time being we don't send 304 headers to IIS servers.
        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
888 889 890 891 892 893 894 895 896 897
      exit();
    }
  }
}

function page_footer() {
  if (variable_get("dev_timer", 0)) {
    timer_print();
  }

Dries's avatar
 
Dries committed
898 899 900 901
  if (variable_get("dev_query", 0)) {
    query_print();
  }

Dries's avatar
 
Dries committed
902
  if (variable_get("cache", 0)) {
Dries's avatar
 
Dries committed
903
    page_set_cache();
Dries's avatar
 
Dries committed
904 905 906 907
  }
}

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

909 910
$config = conf_init();

Dries's avatar
 
Dries committed
911 912 913 914 915
include_once "includes/$config.php";
include_once "includes/database.inc";
include_once "includes/xmlrpc.inc";
include_once "includes/module.inc";
include_once "includes/theme.inc";
Dries's avatar
 
Dries committed
916
include_once "includes/pager.inc";
Dries's avatar
 
Dries committed
917
include_once "includes/menu.inc";
Dries's avatar
 
Dries committed
918

919 920
// initialize configuration variables, using values from conf.php if available:
$conf = variable_init(isset($conf) ? $conf : array());
Dries's avatar
 
Dries committed
921 922 923 924 925 926 927 928 929 930 931 932 933 934

// initialize installed modules:
module_init();

// initialize localization system:
$locale = locale_init();

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

// set error handler:
set_error_handler("error_handler");

?>