2001-12-01 15:20:48 +00:00
< ? 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' .
*/
2003-05-13 18:36:38 +00:00
$uri = $_SERVER [ " PHP_SELF " ];
2003-01-06 19:51:01 +00:00
2003-05-13 18:36:38 +00:00
$file = strtolower ( strtr ( $_SERVER [ " HTTP_HOST " ] . substr ( $uri , 0 , strrpos ( $uri , " / " )), " /: " , " .. " ));
2001-12-01 15:20:48 +00:00
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 . " ;
2003-04-21 12:36:09 +00:00
if ( $errno & E_ALL ^ E_NOTICE ) {
2001-12-01 15:20:48 +00:00
watchdog ( " error " , $types [ $errno ] . " : $message in $filename on line $line . " );
2002-09-27 17:06:50 +00:00
print " <pre> $entry </pre> " ;
2001-12-01 15:20:48 +00:00
}
}
2003-01-04 11:03:15 +00:00
function watchdog ( $type , $message , $link = NULL ) {
2001-12-01 15:20:48 +00:00
global $user ;
2003-05-07 21:00:36 +00:00
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 ());
2001-12-01 15:20:48 +00:00
}
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 " );
}
}
}
2002-12-26 12:16:09 +00:00
function check_php_setting ( $name , $value ) {
if ( ini_get ( $name ) != $value ) {
2003-01-05 01:19:37 +00:00
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> " ;
2002-12-26 12:16:09 +00:00
}
}
2003-01-06 19:51:01 +00:00
function arg ( $index ) {
static $arguments ;
if ( empty ( $arguments )) {
2003-05-13 18:36:38 +00:00
$arguments = explode ( " / " , $_GET [ " q " ]);
2003-01-06 19:51:01 +00:00
}
return $arguments [ $index ];
}
2001-12-30 16:16:38 +00:00
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 ;
}
2002-04-20 11:52:50 +00:00
function request_uri () {
2003-05-20 04:41:36 +00:00
/*
** Since request_uri () is only available on Apache , we generate
** equivalent using other environment vars .
*/
2002-04-27 13:19:37 +00:00
2003-05-13 18:36:38 +00:00
if ( isset ( $_SERVER [ " REQUEST_URI " ])) {
return $_SERVER [ " REQUEST_URI " ];
2002-04-27 13:19:37 +00:00
}
else {
2003-05-20 04:41:36 +00:00
return $_SERVER [ " PHP_SELF " ] . " ? " . $_SERVER [ " QUERY_STRING " ];
2002-04-27 13:19:37 +00:00
}
2002-04-20 11:52:50 +00:00
}
2001-12-01 15:20:48 +00:00
function message_access () {
2002-12-11 20:21:04 +00:00
return t ( " You are not authorized to access this page. " );
2001-12-01 15:20:48 +00:00
}
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. " );
}
2001-12-27 15:27:44 +00:00
function locale_init () {
global $languages , $user ;
2003-03-04 15:10:37 +00:00
if ( $user -> uid && $languages [ $user -> language ]) {
return $user -> language ;
}
else {
return key ( $languages );
}
2001-12-27 15:27:44 +00:00
}
2002-04-20 11:52:50 +00:00
function t ( $string , $args = 0 ) {
2001-12-27 15:27:44 +00:00
global $languages ;
2002-04-24 20:55:20 +00:00
2002-05-02 18:47:35 +00:00
/*
** 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
2003-01-06 19:51:01 +00:00
** account </ a > before viewing the next page . " , array( " % url "
** => url ( " user/register " )));
2002-05-02 18:47:35 +00:00
*/
2003-04-01 06:05:15 +00:00
$string = ( $languages && module_exist ( " locale " ) ? locale ( $string ) : $string );
2002-04-24 20:55:20 +00:00
2002-04-20 11:52:50 +00:00
if ( ! $args ) {
return $string ;
2002-04-22 09:05:36 +00:00
}
else {
2002-04-20 11:52:50 +00:00
return strtr ( $string , $args );
}
2001-12-27 15:27:44 +00:00
}
function variable_init ( $conf = array ()) {
$result = db_query ( " SELECT * FROM variable " );
while ( $variable = db_fetch_object ( $result )) {
if ( ! isset ( $conf [ $variable -> name ])) {
2002-07-06 13:30:26 +00:00
$conf [ $variable -> name ] = unserialize ( $variable -> value );
2001-12-27 15:27:44 +00:00
}
}
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 ;
2002-04-20 11:52:50 +00:00
db_query ( " DELETE FROM variable WHERE name = '%s' " , $name );
2002-07-06 13:30:26 +00:00
db_query ( " INSERT INTO variable (name, value) VALUES ('%s', '%s') " , $name , serialize ( $value ));
2001-12-27 15:27:44 +00:00
$conf [ $name ] = $value ;
}
function variable_del ( $name ) {
global $conf ;
2002-04-20 11:52:50 +00:00
db_query ( " DELETE FROM variable WHERE name = '%s' " , $name );
2001-12-27 15:27:44 +00:00
unset ( $conf [ $name ]);
}
2002-12-29 12:03:08 +00:00
function table_cell ( $cell , $header = 0 ) {
2002-12-30 08:33:02 +00:00
if ( is_array ( $cell )) {
2002-12-29 12:03:08 +00:00
$data = $cell [ " data " ];
foreach ( $cell as $key => $value ) {
if ( $key != " data " ) {
$attributes .= " $key = \" $value\ " " ;
}
}
}
else {
$data = $cell ;
}
2003-01-15 05:56:50 +00:00
if ( $header ) {
2002-12-29 12:03:08 +00:00
$output = " <th $attributes > $data </th> " ;
}
else {
$output = " <td $attributes > $data </td> " ;
}
return $output ;
}
function table ( $header , $rows ) {
2003-03-08 14:35:42 +00:00
$output = " <table> \n " ;
2002-12-29 12:03:08 +00:00
/*
** Emit the table header :
*/
2002-12-30 08:33:02 +00:00
if ( is_array ( $header )) {
$output .= " <tr> " ;
foreach ( $header as $cell ) {
$output .= table_cell ( $cell , 1 );
}
2003-01-07 19:21:28 +00:00
$output .= " </tr> \n " ;
2002-12-29 12:03:08 +00:00
}
/*
** Emit the table rows :
*/
2002-12-30 08:33:02 +00:00
if ( is_array ( $rows )) {
foreach ( $rows as $number => $row ) {
if ( $number % 2 == 1 ) {
$output .= " <tr class= \" light \" > " ;
}
else {
$output .= " <tr class= \" dark \" > " ;
}
2002-12-29 12:03:08 +00:00
2002-12-30 08:33:02 +00:00
foreach ( $row as $cell ) {
$output .= table_cell ( $cell , 0 );
}
2003-01-07 19:21:28 +00:00
$output .= " </tr> \n " ;
2002-12-29 12:03:08 +00:00
}
}
2003-01-07 19:21:28 +00:00
$output .= " </table> \n " ;
2002-12-29 12:03:08 +00:00
return $output ;
}
2003-03-28 10:55:27 +00:00
/**
* 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
*/
2003-04-13 13:42:51 +00:00
function valid_email_address ( $mail ) {
2003-03-28 10:55:27 +00:00
$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 ;
}
}
2002-03-05 20:15:17 +00:00
/**
* Format a single result entry of a search query :
*
* @ param $item a single search result as returned by < module > _search of type
2002-04-14 20:46:41 +00:00
* array ( " count " => ... , " link " => ... , " title " => ... ,
2002-03-05 20:15:17 +00:00
* " user " => ... , " date " => ... , " keywords " => ... )
* @ param $type module type of this item
*/
2001-12-27 15:27:44 +00:00
function search_item ( $item , $type ) {
2002-04-27 13:19:37 +00:00
/*
** 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 " ] . " <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 /> " ;
}
2001-12-27 15:27:44 +00:00
return $output ;
}
2002-03-05 20:15:17 +00:00
/**
* Render a generic search form .
*
* " Generic " means " universal usable " - that is , usable not only from
2003-01-06 19:51:01 +00:00
* 'site.com/search' , but also as a simple seach box ( without
2002-04-14 20:46:41 +00:00
* " Restrict search to " , help text , etc ) from theme ' s header etc .
* This means : provide options to only conditionally render certain
2002-03-05 20:15:17 +00:00
* parts of this form .
*
2003-01-06 19:51:01 +00:00
* @ param $action Form action . Defaults to 'site.com/search' .
2002-03-05 20:15:17 +00:00
* @ param $query Query string . Defaults to global $keys .
2002-04-14 20:46:41 +00:00
* @ param $options != 0 : Render additional form fields / text
2002-03-05 20:15:17 +00:00
* ( " Restrict search to " , help text , etc ) .
*/
2001-12-27 15:27:44 +00:00
function search_form ( $action = 0 , $query = 0 , $options = 0 ) {
2003-05-23 17:59:25 +00:00
$keys = $_POST [ " keys " ];
2001-12-27 15:27:44 +00:00
if ( ! $action ) {
2003-01-06 19:51:01 +00:00
$action = url ( " search " );
2001-12-27 15:27:44 +00:00
}
if ( ! $query ) {
$query = $keys ;
}
2002-03-05 20:15:17 +00:00
$output .= " <br /><input type= \" text \" size= \" 50 \" value= \" " . check_form ( $keys ) . " \" name= \" keys \" /> " ;
$output .= " <input type= \" submit \" value= \" " . t ( " Search " ) . " \" /> \n " ;
2001-12-27 15:27:44 +00:00
if ( $options != 0 ) {
$output .= " <br /> " ;
$output .= t ( " Restrict search to " ) . " : " ;
foreach ( module_list () as $name ) {
if ( module_hook ( $name , " search " )) {
2002-03-05 20:15:17 +00:00
$output .= " <input type= \" checkbox \" name= \" edit[type][ $name ] \" " . ( $edit [ " type " ][ $name ] ? " checked= \" checked \" " : " " ) . " /> " . t ( $name );
2001-12-27 15:27:44 +00:00
}
}
}
2002-03-05 20:15:17 +00:00
$form .= " <br /> " ;
2001-12-27 15:27:44 +00:00
return form ( $output , " post " , $action );
}
/*
2002-03-05 20:15:17 +00:00
* Collect the search results :
*/
2001-12-27 15:27:44 +00:00
function search_data () {
2003-05-13 18:36:38 +00:00
2003-05-23 17:59:25 +00:00
$keys = $_POST [ " keys " ];
2003-05-13 18:36:38 +00:00
$edit = $_POST [ " edit " ];
2001-12-27 15:27:44 +00:00
2003-01-09 20:06:00 +00:00
if ( isset ( $keys )) {
2001-12-27 15:27:44 +00:00
foreach ( module_list () as $name ) {
if ( module_hook ( $name , " search " ) && ( ! $edit [ " type " ] || $edit [ " type " ][ $name ]) && ( $result = module_invoke ( $name , " search " , check_query ( $keys )))) {
2002-03-05 20:15:17 +00:00
if ( $name == " node " || $name == " comment " ) {
2002-05-31 20:29:30 +00:00
$output .= " <p><b> " . t ( " Matching " . $name . " s ranked in order of relevance " ) . " :</b></p> " ;
2002-03-05 20:15:17 +00:00
}
else {
2002-05-31 20:29:30 +00:00
$output .= " <p><b> " . t ( " Matching " . $name . " s " ) . " :</b></p> " ;
2002-03-05 20:15:17 +00:00
}
2001-12-27 15:27:44 +00:00
foreach ( $result as $entry ) {
$output .= search_item ( $entry , $name );
}
}
}
2002-03-05 20:15:17 +00:00
if ( ! $output ) {
2001-12-27 15:27:44 +00:00
$output .= t ( " Your search yielded no results. " );
}
}
return $output ;
}
2002-03-05 20:15:17 +00:00
/**
* Display the search form and the resulting data .
*
2002-04-14 20:46:41 +00:00
* @ param $type If set , search only nodes of this type .
2002-03-05 20:15:17 +00:00
* Otherwise , search all types .
2003-01-06 19:51:01 +00:00
* @ param $action Form action . Defaults to 'site.com/search' .
2002-03-05 20:15:17 +00:00
* @ param $query Query string . Defaults to global $keys .
2002-04-14 20:46:41 +00:00
* @ param $options != 0 : Render additional form fields / text
2002-03-05 20:15:17 +00:00
* ( " Restrict search to " , help text , etc ) .
*/
2001-12-27 15:27:44 +00:00
function search_type ( $type = 0 , $action = 0 , $query = 0 , $options = 0 ) {
2003-05-13 18:36:38 +00:00
$edit = $_POST [ " edit " ];
2001-12-27 15:27:44 +00:00
2003-01-09 20:06:00 +00:00
if ( isset ( $type )) {
2001-12-27 15:27:44 +00:00
$edit [ " type " ][ $type ] = " on " ;
}
return search_form ( $action , $query , $options ) . search_data ();
}
2002-04-14 20:46:41 +00:00
2001-12-01 15:20:48 +00:00
function drupal_goto ( $url ) {
2002-05-31 20:29:30 +00:00
/*
** Translate & amp ; to simply &
*/
2002-08-08 18:24:53 +00:00
2003-05-30 11:01:56 +00:00
$url = str_replace ( " & " , " & " , $url );
2002-05-31 20:29:30 +00:00
2001-12-01 15:20:48 +00:00
/*
** 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 " .
*/
2003-02-27 22:52:08 +00:00
if ( ! ini_get ( " session.use_trans_sid " ) || ! session_id () || strstr ( $url , session_id ())) {
2001-12-01 15:20:48 +00:00
header ( " Location: $url " );
}
else {
2002-11-29 05:45:57 +00:00
$sid = session_name () . " = " . session_id ();
if ( strstr ( $url , " ? " ) && ! strstr ( $url , $sid )) {
header ( " Location: $url & " . $sid );
}
else {
header ( " Location: $url ? " . $sid );
}
2001-12-01 15:20:48 +00:00
}
/*
** The " Location " header sends a REDIRECT status code to the http
2003-05-29 10:18:38 +00:00
** daemon . In some cases this can go wrong , so we make sure none
2001-12-01 15:20:48 +00:00
** of the code / below / gets executed when we redirect .
*/
exit ();
}
/*
** Stores the referer in a persistent variable :
*/
function referer_save () {
2003-05-13 18:36:38 +00:00
global $referer ;
2001-12-01 15:20:48 +00:00
2003-05-13 18:36:38 +00:00
if ( ! strstr ( $_SERVER [ " HTTP_REFERER " ], request_uri ())) {
$referer = $_SERVER [ " HTTP_REFERER " ];
2001-12-01 15:20:48 +00:00
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 ) {
2003-02-26 22:02:46 +00:00
return htmlspecialchars ( $text );
2001-12-01 15:20:48 +00:00
}
2002-12-14 11:55:54 +00:00
function check_query ( $text ) {
2003-02-26 22:02:46 +00:00
return addslashes ( $text );
2001-12-01 15:20:48 +00:00
}
2002-12-14 11:55:54 +00:00
function check_input ( $text ) {
2003-02-26 22:02:46 +00:00
return addslashes ( $text );
2001-12-01 15:20:48 +00:00
}
function filter ( $text ) {
2003-01-27 19:37:07 +00:00
2003-05-30 05:45:35 +00:00
$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 " ) {
2003-01-27 19:37:07 +00:00
$text = module_invoke ( $name , " filter " , $text );
}
}
return $text ;
2001-12-01 15:20:48 +00:00
}
2003-01-11 20:07:42 +00:00
function rewrite_old_urls ( $text ) {
2003-03-08 21:10:22 +00:00
global $base_url ;
$end = substr ( $base_url , 12 );
2003-01-11 20:07:42 +00:00
/*
** This is a * temporary * filter to rewrite old - style URLs to new - style
** URLs ( clean URLs ) . Currently , URLs are being rewritten dynamically
2003-01-12 11:53:31 +00:00
** ( ie . " on output " ), however when these rewrite rules have been tested
** enough , we will use them to permanently rewrite the links in node
2003-01-11 20:07:42 +00:00
** and comment bodies .
*/
2003-02-15 17:15:48 +00:00
if ( variable_get ( " clean_url " , " 0 " ) == " 0 " ) {
2003-03-08 21:10:22 +00:00
/*
** 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 :
*/
2003-02-14 19:52:45 +00:00
// rewrite 'node.php?id=<number>[&cid=<number>]' style URLs:
2003-03-08 21:10:22 +00:00
$text = eregi_replace ( " $end /(node) \ .php \ ?id=([[:digit:]]+)(&cid=)?([[:digit:]]*) " , " $end /?q= \\ 1/view/ \\ 2/ \\ 4 " , $text );
2003-01-15 05:56:50 +00:00
2003-02-14 19:52:45 +00:00
// rewrite 'module.php?mod=<name>{&<op>=<value>}' style URLs:
2003-03-08 21:10:22 +00:00
$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 );
2003-02-14 19:52:45 +00:00
}
else {
2003-03-08 21:10:22 +00:00
/*
** Relative URLs :
*/
2003-02-14 19:52:45 +00:00
// rewrite 'node.php?id=<number>[&cid=<number>]' style URLs:
2003-03-08 21:10:22 +00:00
$text = eregi_replace ( " \" (node) \ .php \ ?id=([[:digit:]]+)(&cid=)?([[:digit:]]*) " , " \" \\ 1/view/ \\ 2/ \\ 4 " , $text );
2003-02-14 19:52:45 +00:00
// rewrite 'module.php?mod=<name>{&<op>=<value>}' style URLs:
2003-03-08 21:10:22 +00:00
$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 );
}
2003-01-15 05:56:50 +00:00
2003-01-11 20:07:42 +00:00
return $text ;
}
2002-12-31 12:34:07 +00:00
function check_output ( $text ) {
2003-01-09 20:06:00 +00:00
if ( isset ( $text )) {
2003-05-24 16:26:13 +00:00
// filter content on output:
$text = filter ( $text );
// get the line breaks right:
2002-12-15 23:05:25 +00:00
if ( strip_tags ( $text , " <a><i><b><u><tt><code><cite><strong><img> " ) == $text ) {
2002-12-14 11:55:54 +00:00
$text = nl2br ( $text );
}
}
else {
$text = message_na ();
}
return $text ;
2001-12-01 15:20:48 +00:00
}
function check_file ( $filename ) {
if ( is_uploaded_file ( $filename )) {
return 1 ;
}
else {
return 0 ;
}
}
2002-04-27 13:19:37 +00:00
function format_rss_channel ( $title , $link , $description , $items , $language = " en " , $args = array ()) {
// arbitrary elements may be added using the $args associative array
2001-12-01 15:20:48 +00:00
$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 " ;
2002-04-27 13:19:37 +00:00
foreach ( $args as $key => $value ) {
2002-05-11 16:21:48 +00:00
$output .= " < $key > " . htmlentities ( strip_tags ( $value )) . " </ $key > " ;
2002-04-27 13:19:37 +00:00
}
2001-12-01 15:20:48 +00:00
$output .= $items ;
$output .= " </channel> \n " ;
return $output ;
}
2002-04-27 13:19:37 +00:00
function format_rss_item ( $title , $link , $description , $args = array ()) {
// arbitrary elements may be added using the $args associative array
2001-12-01 15:20:48 +00:00
$output .= " <item> \n " ;
$output .= " <title> " . htmlentities ( strip_tags ( $title )) . " </title> \n " ;
$output .= " <link> " . htmlentities ( strip_tags ( $link )) . " </link> \n " ;
2002-12-31 10:58:47 +00:00
$output .= " <description> " . htmlentities ( check_output ( $description )) . " </description> \n " ;
2002-04-27 13:19:37 +00:00
foreach ( $args as $key => $value ) {
2002-05-11 16:21:48 +00:00
$output .= " < $key > " . htmlentities ( strip_tags ( $value )) . " </ $key > " ;
2002-04-27 13:19:37 +00:00
}
2001-12-01 15:20:48 +00:00
$output .= " </item> \n " ;
return $output ;
}
2003-01-21 22:44:25 +00:00
/**
* 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 " .
*/
2001-12-01 15:20:48 +00:00
function format_plural ( $count , $singular , $plural ) {
2003-01-21 22:44:25 +00:00
return t ( $count == 1 ? $singular : $plural , array ( " %count " => $count ));
2001-12-01 15:20:48 +00:00
}
function format_size ( $size ) {
2002-07-05 18:28:02 +00:00
$suffix = t ( " bytes " );
2001-12-01 15:20:48 +00:00
if ( $size > 1024 ) {
$size = round ( $size / 1024 , 2 );
2002-07-05 18:28:02 +00:00
$suffix = t ( " KB " );
2001-12-01 15:20:48 +00:00
}
if ( $size > 1024 ) {
$size = round ( $size / 1024 , 2 );
2002-07-05 18:28:02 +00:00
$suffix = t ( " MB " );
2001-12-01 15:20:48 +00:00
}
2002-07-05 18:28:02 +00:00
return t ( " %size %suffix " , array ( " %size " => $size , " %suffix " => $suffix ));
2001-12-01 15:20:48 +00:00
}
2002-01-05 16:28:34 +00:00
function cache_get ( $key ) {
2003-04-13 14:12:43 +00:00
$cache = db_fetch_object ( db_query ( " SELECT data, created FROM cache WHERE cid = '%s' " , $key ));
2002-12-11 22:00:04 +00:00
return $cache -> data ? $cache : 0 ;
2002-01-05 16:28:34 +00:00
}
function cache_set ( $cid , $data , $expire = 0 ) {
2003-03-29 18:08:56 +00:00
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 );
2002-01-05 16:28:34 +00:00
}
else {
2002-12-11 22:00:04 +00:00
db_query ( " INSERT INTO cache (cid, data, created, expire) VALUES('%s', '%s', %d, %d) " , $cid , $data , time (), $expire );
2002-01-05 16:28:34 +00:00
}
2001-12-01 15:20:48 +00:00
}
2002-11-17 06:42:52 +00:00
function cache_clear_all ( $cid = NULL ) {
if ( empty ( $cid )) {
2002-12-16 16:42:49 +00:00
db_query ( " DELETE FROM cache WHERE expire <> 0 " );
2002-11-17 06:42:52 +00:00
}
else {
2003-05-07 21:00:36 +00:00
db_query ( " DELETE FROM cache WHERE cid = %d " , $cid );
2002-11-17 06:42:52 +00:00
}
2002-01-05 16:28:34 +00:00
}
function page_set_cache () {
2003-05-13 18:36:38 +00:00
global $user ;
2001-12-01 15:20:48 +00:00
2003-05-13 18:36:38 +00:00
if ( ! $user -> uid && $_SERVER [ " REQUEST_METHOD " ] == " GET " ) {
2002-01-05 16:28:34 +00:00
if ( $data = ob_get_contents ()) {
2002-11-17 06:42:52 +00:00
cache_set ( request_uri (), $data , ( time () + variable_get ( " cache_clear " , 120 )));
2001-12-01 15:20:48 +00:00
}
}
}
2002-01-05 16:28:34 +00:00
function page_get_cache () {
2003-05-13 18:36:38 +00:00
global $user ;
2001-12-01 15:20:48 +00:00
2003-04-21 12:36:09 +00:00
$cache = NULL ;
2003-05-13 18:36:38 +00:00
if ( ! $user -> uid && $_SERVER [ " REQUEST_METHOD " ] == " GET " ) {
2003-03-16 21:49:33 +00:00
$cache = cache_get ( request_uri ());
if ( empty ( $cache )) {
2002-01-05 16:28:34 +00:00
ob_start ();
2001-12-01 15:20:48 +00:00
}
}
2002-01-05 16:28:34 +00:00
2002-12-11 22:00:04 +00:00
return $cache ;
2001-12-01 15:20:48 +00:00
}
function format_interval ( $timestamp ) {
2003-01-21 22:44:25 +00:00
$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 );
2002-05-12 15:40:57 +00:00
foreach ( $units as $key => $value ) {
2001-12-01 15:20:48 +00:00
$key = explode ( " | " , $key );
if ( $timestamp >= $value ) {
$output .= ( $output ? " " : " " ) . format_plural ( floor ( $timestamp / $value ), $key [ 0 ], $key [ 1 ]);
$timestamp %= $value ;
}
}
2002-07-05 18:28:02 +00:00
return ( $output ) ? $output : t ( " 0 sec " );
2001-12-01 15:20:48 +00:00
}
function format_date ( $timestamp , $type = " medium " , $format = " " ) {
global $user ;
2002-05-13 18:59:53 +00:00
$timestamp += ( $user -> timezone ) ? $user -> timezone - date ( " Z " ) : 0 ;
2001-12-01 15:20:48 +00:00
switch ( $type ) {
case " small " :
2003-03-07 17:32:01 +00:00
$date = date ( variable_get ( " date_format_short " , " m/d/Y - H:i " ), $timestamp );
2001-12-01 15:20:48 +00:00
break ;
case " medium " :
2003-02-11 20:01:17 +00:00
$date = date ( variable_get ( " date_format_medium " , " D, m/d/Y - H:i " ), $timestamp );
2001-12-01 15:20:48 +00:00
break ;
case " large " :
2003-02-11 20:01:17 +00:00
$date = date ( variable_get ( " date_format_long " , " l, F j, Y - H:i " ), $timestamp );
2001-12-01 15:20:48 +00:00
break ;
case " custom " :
for ( $i = strlen ( $format ); $i >= 0 ; $c = $format [ -- $i ]) {
if ( strstr ( " DFlMSw " , $c )) {
2002-10-04 17:10:16 +00:00
$date = t ( date ( $c , $timestamp )) . $date ;
2001-12-01 15:20:48 +00:00
}
2003-03-09 16:55:07 +00:00
else if ( strstr ( " AaBdgGhHiIjLmnOrstTUWYyZz " , $c )) {
2002-10-04 17:10:16 +00:00
$date = date ( $c , $timestamp ) . $date ;
2001-12-01 15:20:48 +00:00
}
else {
2002-05-12 15:40:57 +00:00
$date = $c . $date ;
2001-12-01 15:20:48 +00:00
}
}
break ;
default :
2003-02-11 20:01:17 +00:00
$date = date ( variable_get ( " date_format_medium " , " l, m/d/Y - H:i " ), $timestamp );
2001-12-01 15:20:48 +00:00
}
return $date ;
}
function format_name ( $object ) {
if ( $object -> uid && $object -> name ) {
2003-02-02 10:13:13 +00:00
if ( arg ( 0 ) == " admin " ) {
2003-01-06 19:51:01 +00:00
$output = l ( $object -> name , " admin/user/edit/ $object->uid " , array ( " title " => t ( " Administer user profile. " )));
2001-12-05 18:54:14 +00:00
}
else {
2003-01-06 19:51:01 +00:00
$output = l ( $object -> name , " user/view/ $object->uid " , array ( " title " => t ( " View user profile. " )));
2001-12-05 18:54:14 +00:00
}
2001-12-01 15:20:48 +00:00
}
2003-02-02 10:13:13 +00:00
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 ;
}
2001-12-01 15:20:48 +00:00
else {
2003-04-21 12:36:09 +00:00
$output = t ( variable_get ( " anonymous " , " Anonymous " ));
2001-12-01 15:20:48 +00:00
}
2001-12-05 18:54:14 +00:00
return $output ;
2001-12-01 15:20:48 +00:00
}
function form ( $form , $method = " post " , $action = 0 , $options = 0 ) {
2003-05-19 18:26:49 +00:00
if ( ! $action ) {
$action = htmlentities ( request_uri ());
}
return " <form action= \" $action\ " method = \ " $method\ " " . ( $options ? " $options " : " " ) . " > \n $form </ form > \n " ;
2001-12-01 15:20:48 +00:00
}
function form_item ( $title , $value , $description = 0 ) {
2003-05-29 10:18:38 +00:00
return " <div class= \" form-item \" > " . ( $title ? " <div class= \" title \" > $title :</div> " : " " ) . $value . ( $description ? " <div class= \" description \" > $description </div> " : " " ) . " </div> \n " ;
2001-12-01 15:20:48 +00:00
}
2003-04-13 13:42:51 +00:00
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 );
}
2001-12-20 21:44:46 +00:00
function form_checkbox ( $title , $name , $value = 1 , $checked = 0 , $description = 0 ) {
2003-03-07 22:11:44 +00:00
return form_hidden ( $name , 0 ) . form_item ( 0 , " <input type= \" checkbox \" name= \" edit[ $name ] \" value= \" " . $value . " \" " . ( $checked ? " checked= \" checked \" " : " " ) . " /> $title " , $description );
2001-12-01 15:20:48 +00:00
}
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 ) {
2003-04-23 18:58:43 +00:00
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 );
2001-12-01 15:20:48 +00:00
}
2002-04-14 20:46:41 +00:00
function form_select ( $title , $name , $value , $options , $description = 0 , $extra = 0 , $multiple = 0 ) {
2001-12-01 15:20:48 +00:00
if ( count ( $options ) > 0 ) {
2002-05-12 15:40:57 +00:00
foreach ( $options as $key => $choice ) {
2003-02-12 21:37:56 +00:00
$select .= " <option value= \" $key\ " " . (is_array( $value ) ? (in_array( $key , $value ) ? " selected = \ " selected \" " : " " ) : ( $value == $key ? " selected= \" selected \" " : " " )) . " > " . check_form ( $choice ) . " </option> " ;
2002-01-27 14:58:45 +00:00
}
2002-04-22 09:05:36 +00:00
return form_item ( $title , " <select name= \" edit[ $name ] " . ( $multiple ? " [] " : " " ) . " \" " . ( $multiple ? " multiple " : " " ) . ( $extra ? " $extra " : " " ) . " > $select </select> " , $description );
2001-12-01 15:20:48 +00:00
}
}
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 " ;
}
2002-10-26 15:17:26 +00:00
function form_weight ( $title = NULL , $name = " weight " , $value = 0 , $delta = 10 , $description = 0 , $extra = 0 ) {
2003-04-03 22:18:27 +00:00
for ( $n = ( - 1 * $delta ); $n <= $delta ; $n ++ ) {
2002-10-26 15:17:26 +00:00
$weights [ $n ] = $n ;
}
return form_select ( $title , $name , $value , $weights , $description , $extra );
}
2003-01-11 10:46:11 +00:00
function url ( $url = NULL , $query = NULL ) {
2003-02-14 19:52:45 +00:00
global $base_url ;
2003-01-06 21:24:21 +00:00
2003-02-15 17:15:48 +00:00
if ( variable_get ( " clean_url " , " 0 " ) == " 0 " ) {
2003-02-14 19:52:45 +00:00
if ( isset ( $url )) {
if ( isset ( $query )) {
2003-05-19 18:26:49 +00:00
return " $base_url /index.php?q= $url & $query " ;
2003-02-14 19:52:45 +00:00
}
else {
2003-05-19 18:26:49 +00:00
return " $base_url /index.php?q= $url " ;
2003-02-14 19:52:45 +00:00
}
2003-01-06 21:24:21 +00:00
}
else {
2003-02-14 19:52:45 +00:00
if ( isset ( $query )) {
2003-05-19 18:26:49 +00:00
return " $base_url /index.php? $query " ;
2003-02-14 19:52:45 +00:00
}
else {
2003-03-07 06:37:30 +00:00
return " $base_url / " ;
2003-02-14 19:52:45 +00:00
}
2003-01-06 21:24:21 +00:00
}
}
else {
2003-02-14 19:52:45 +00:00
if ( isset ( $url )) {
if ( isset ( $query )) {
2003-02-15 17:15:48 +00:00
return " $base_url / $url ? $query " ;
2003-02-14 19:52:45 +00:00
}
else {
2003-02-15 17:15:48 +00:00
return " $base_url / $url " ;
2003-02-14 19:52:45 +00:00
}
2003-01-06 21:24:21 +00:00
}
2003-01-11 10:46:11 +00:00
else {
2003-02-14 19:52:45 +00:00
if ( isset ( $query )) {
2003-05-23 21:59:44 +00:00
return " $base_url /index.php? $query " ;
2003-02-14 19:52:45 +00:00
}
else {
2003-03-07 06:37:30 +00:00
return " $base_url / " ;
2003-02-14 19:52:45 +00:00
}
2003-01-11 10:46:11 +00:00
}
2003-01-06 21:24:21 +00:00
}
2002-04-20 11:52:50 +00:00
}
2003-01-06 19:51:01 +00:00
function l ( $text , $url , $attributes = array (), $query = NULL ) {
2002-04-20 11:52:50 +00:00
2002-04-27 13:19:37 +00:00
$t = array ();
foreach ( $attributes as $key => $value ) {
$t [] = " $key = \" $value\ " " ;
}
2003-01-06 19:51:01 +00:00
return " <a href= \" " . url ( $url , $query ) . " \" " . implode ( $t , " " ) . " > $text </a> " ;
2002-04-20 11:52:50 +00:00
}
2001-12-01 15:20:48 +00:00
function field_get ( $string , $name ) {
2003-03-07 22:11:44 +00:00
ereg ( " ,? $name =([^,]+) " , " , $string " , $regs );
2001-12-01 15:20:48 +00:00
return $regs [ 1 ];
}
function field_set ( $string , $name , $value ) {
$rval = ereg_replace ( " , $name =[^,]+ " , " " , " , $string " );
2003-01-09 20:06:00 +00:00
if ( isset ( $value )) {
2002-03-05 20:15:17 +00:00
$rval .= ( $rval == " , " ? " " : " , " ) . " $name = $value " ;
}
2001-12-01 15:20:48 +00:00
return substr ( $rval , 1 );
}
function link_page () {
2003-02-14 19:52:45 +00:00
global $custom_links , $base_url ;
2002-04-14 20:46:41 +00:00
2002-04-02 09:45:57 +00:00
if ( is_array ( $custom_links )) {
return $custom_links ;
}
else {
2003-01-26 13:22:02 +00:00
$links = module_invoke_all ( " link " , " page " );
2003-03-07 22:11:44 +00:00
array_unshift ( $links , " <a href= \" $base_url / \" title= \" " . t ( " Return to the main page. " ) . " \" > " . t ( " home " ) . " </a> " );
2002-04-02 09:45:57 +00:00
return $links ;
2001-12-01 15:20:48 +00:00
}
2002-04-14 20:46:41 +00:00
}
2001-12-01 15:20:48 +00:00
function link_node ( $node , $main = 0 ) {
2003-01-26 13:22:02 +00:00
return module_invoke_all ( " link " , " node " , $node , $main );
2001-12-01 15:20:48 +00:00
}
function timer_start () {
global $timer ;
2001-12-30 16:16:38 +00:00
list ( $usec , $sec ) = explode ( " " , microtime ());
$timer = ( float ) $usec + ( float ) $sec ;
2001-12-01 15:20:48 +00:00
}
2003-05-18 09:48:49 +00:00
function drupal_page_header () {
2001-12-01 15:20:48 +00:00
if ( variable_get ( " dev_timer " , 0 )) {
timer_start ();
}
if ( variable_get ( " cache " , 0 )) {
2002-12-11 22:00:04 +00:00
if ( $cache = page_get_cache ()) {
$date = gmdate ( " D, d M Y H:i:s " , $cache -> created ) . " GMT " ;
header ( " Last-Modified: $date " );
header ( " ETag: \" $date\ " " );
2003-01-31 08:32:41 +00:00
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 ) .
*/
2002-12-11 22:00:04 +00:00
if ( $headers [ " If-Modified-Since " ] == $date && $headers [ " If-None-Match " ] == " \" $date\ " " ) {
header ( " HTTP/1.0 304 Not Modified " );
exit ();
}
}
print $cache -> data ;
2001-12-01 15:20:48 +00:00
exit ();
}
}
}
2003-05-18 09:48:49 +00:00
function drupal_page_footer () {
2001-12-01 15:20:48 +00:00
if ( variable_get ( " cache " , 0 )) {
2002-01-05 16:28:34 +00:00
page_set_cache ();
2001-12-01 15:20:48 +00:00
}
2003-01-26 13:22:02 +00:00
// 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 " );
2001-12-01 15:20:48 +00:00
}
unset ( $conf );
2002-01-27 14:58:45 +00:00
2002-10-20 19:17:17 +00:00
$config = conf_init ();
2001-12-01 15:20:48 +00:00
include_once " includes/ $config .php " ;
include_once " includes/database.inc " ;
include_once " includes/module.inc " ;
include_once " includes/theme.inc " ;
2002-11-09 13:59:36 +00:00
include_once " includes/pager.inc " ;
2002-12-24 15:40:32 +00:00
include_once " includes/menu.inc " ;
2003-04-29 22:02:02 +00:00
include_once " includes/xmlrpc.inc " ;
2003-02-12 16:21:48 +00:00
2002-10-20 19:17:17 +00:00
// initialize configuration variables, using values from conf.php if available:
$conf = variable_init ( isset ( $conf ) ? $conf : array ());
2001-12-01 15:20:48 +00:00
2003-03-04 06:19:01 +00:00
// set error handler:
set_error_handler ( " error_handler " );
2003-03-17 07:01:12 +00:00
// initialize installed modules:
module_init ();
2001-12-01 15:20:48 +00:00
// initialize localization system:
$locale = locale_init ();
// initialize theme:
$theme = theme_init ();
2003-03-04 15:10:37 +00:00
?>