X-Git-Url: http://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FGlobalFunctions.php;h=f50ce44ed518e77e99c71bd6bd9f1369bb3dee89;hb=f8923e57dbb1cd2cc43b130002e0a6a4fe0a2621;hp=a54497188a0668892cc8e5de01fa46c154fdda5e;hpb=35c74af604ec69beb06e25ed2de7098ee5884993;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/GlobalFunctions.php b/includes/GlobalFunctions.php index a54497188a..f50ce44ed5 100644 --- a/includes/GlobalFunctions.php +++ b/includes/GlobalFunctions.php @@ -1,23 +1,42 @@ = 3 ) { + $end = func_get_arg( 2 ); + return join( '', array_slice( $ar[0], $start, $end ) ); + } else { + return join( '', array_slice( $ar[0], $start ) ); + } + } +} + +/** + * html_entity_decode exists in PHP 4.3.0+ but is FATALLY BROKEN even then, + * with no UTF-8 support. + * + * @param string $string String having html entities + * @param $quote_style + * @param string $charset Encoding set to use (default 'ISO-8859-1') + */ function do_html_entity_decode( $string, $quote_style=ENT_COMPAT, $charset='ISO-8859-1' ) { + $fname = 'do_html_entity_decode'; + wfProfileIn( $fname ); + static $trans; - if( !isset( $trans ) ) { + static $savedCharset; + static $regexp; + if( !isset( $trans ) || $savedCharset != $charset ) { $trans = array_flip( get_html_translation_table( HTML_ENTITIES, $quote_style ) ); - # Assumes $charset will always be the same through a run, and only understands - # utf-8 or default. Note - mixing latin1 named entities and unicode numbered + $savedCharset = $charset; + + # Note - mixing latin1 named entities and unicode numbered # ones will result in a bad link. if( strcasecmp( 'utf-8', $charset ) == 0 ) { $trans = array_map( 'utf8_encode', $trans ); } + + /** + * Most links will _not_ contain these fun guys, + * and on long pages with many links we can get + * called a lot. + * + * A regular expression search is faster than + * a strtr or str_replace with a hundred-ish + * entries, though it may be slower to actually + * replace things. + * + * They all look like '&xxxx;'... + */ + foreach( $trans as $key => $val ) { + $snip[] = substr( $key, 1, -1 ); + } + $regexp = '/(&(?:' . implode( '|', $snip ) . ');)/e'; } - return strtr( $string, $trans ); + + $out = preg_replace( $regexp, '$trans["$1"]', $string ); + wfProfileOut( $fname ); + return $out; } + +/** + * Where as we got a random seed + * @var bool $wgTotalViews + */ $wgRandomSeeded = false; -# Seed Mersenne Twister -# Only necessary in PHP < 4.2.0 -function wfSeedRandom() -{ +/** + * Seed Mersenne Twister + * Only necessary in PHP < 4.2.0 + * + * @return bool + */ +function wfSeedRandom() { global $wgRandomSeeded; if ( ! $wgRandomSeeded && version_compare( phpversion(), '4.2.0' ) < 0 ) { @@ -77,42 +150,30 @@ function wfSeedRandom() } } -# Generates a URL from a URL-encoded title and a query string -# Title::getLocalURL() is preferred in most cases -# -function wfLocalUrl( $a, $q = '' ) -{ - global $wgServer, $wgScript, $wgArticlePath; - - $a = str_replace( ' ', '_', $a ); - - if ( '' == $a ) { - if( '' == $q ) { - $a = $wgScript; - } else { - $a = $wgScript.'?'.$q; - } - } else if ( '' == $q ) { - $a = str_replace( '$1', $a, $wgArticlePath ); - } else if ($wgScript != '' ) { - $a = "{$wgScript}?title={$a}&{$q}"; - } else { //XXX hackish solution for toplevel wikis - $a = "/{$a}?{$q}"; - } - return $a; -} - -function wfLocalUrlE( $a, $q = '' ) -{ - return htmlspecialchars( wfLocalUrl( $a, $q ) ); - # die( "Call to obsolete function wfLocalUrlE()" ); +/** + * Get a random decimal value between 0 and 1, in a way + * not likely to give duplicate values for any realistic + * number of articles. + * + * @return string + */ +function wfRandom() { + # The maximum random value is "only" 2^31-1, so get two random + # values to reduce the chance of dupes + $max = mt_getrandmax(); + $rand = number_format( mt_rand() * mt_rand() + / $max / $max, 12, '.', '' ); + return $rand; } -# We want / and : to be included as literal characters in our title URLs. -# %2F in the page titles seems to fatally break for some reason. -# -function wfUrlencode ( $s ) -{ +/** + * We want / and : to be included as literal characters in our title URLs. + * %2F in the page titles seems to fatally break for some reason. + * + * @param string $s + * @return string +*/ +function wfUrlencode ( $s ) { $s = urlencode( $s ); $s = preg_replace( '/%3[Aa]/', ':', $s ); $s = preg_replace( '/%2[Ff]/', '/', $s ); @@ -120,9 +181,13 @@ function wfUrlencode ( $s ) return $s; } -# Return the UTF-8 sequence for a given Unicode code point. -# Currently doesn't work for values outside the Basic Multilingual Plane. -# +/** + * Return the UTF-8 sequence for a given Unicode code point. + * Currently doesn't work for values outside the Basic Multilingual Plane. + * + * @param string $codepoint UTF-8 code point. + * @return string HTML UTF-8 Entitie such as 'Ӓ'. + */ function wfUtf8Sequence( $codepoint ) { if($codepoint < 0x80) return chr($codepoint); if($codepoint < 0x800) return chr($codepoint >> 6 & 0x3f | 0xc0) . @@ -130,68 +195,64 @@ function wfUtf8Sequence( $codepoint ) { if($codepoint < 0x10000) return chr($codepoint >> 12 & 0x0f | 0xe0) . chr($codepoint >> 6 & 0x3f | 0x80) . chr($codepoint & 0x3f | 0x80); - if($codepoint < 0x100000) return chr($codepoint >> 18 & 0x07 | 0xf0) . # Double-check this + if($codepoint < 0x110000) return chr($codepoint >> 18 & 0x07 | 0xf0) . chr($codepoint >> 12 & 0x3f | 0x80) . chr($codepoint >> 6 & 0x3f | 0x80) . chr($codepoint & 0x3f | 0x80); - # Doesn't yet handle outside the BMP + + # There should be no assigned code points outside this range, but... return "&#$codepoint;"; } -# Converts numeric character entities to UTF-8 +/** + * Converts numeric character entities to UTF-8 + * + * @param string $string String to convert. + * @return string Converted string. + */ function wfMungeToUtf8( $string ) { global $wgInputEncoding; # This is debatable #$string = iconv($wgInputEncoding, "UTF-8", $string); - $string = preg_replace ( '/&#([0-9]+);/e', 'wfUtf8Sequence($1)', $string ); + $string = preg_replace ( '/�*([0-9]+);/e', 'wfUtf8Sequence($1)', $string ); $string = preg_replace ( '/&#x([0-9a-f]+);/ie', 'wfUtf8Sequence(0x$1)', $string ); # Should also do named entities here return $string; } -# Converts a single UTF-8 character into the corresponding HTML character entity -# (for use with preg_replace_callback) +/** + * Converts a single UTF-8 character into the corresponding HTML character + * entity (for use with preg_replace_callback) + * + * @param array $matches + * + */ function wfUtf8Entity( $matches ) { - $char = $matches[0]; - # Find the length - $z = ord( $char{0} ); - if ( $z & 0x80 ) { - $length = 0; - while ( $z & 0x80 ) { - $length++; - $z <<= 1; - } - } else { - $length = 1; - } - - if ( $length != strlen( $char ) ) { - return ''; - } - if ( $length == 1 ) { - return $char; - } - - # Mask off the length-determining bits and shift back to the original location - $z &= 0xff; - $z >>= $length; - - # Add in the free bits from subsequent bytes - for ( $i=1; $i<$length; $i++ ) { - $z <<= 6; - $z |= ord( $char{$i} ) & 0x3f; - } - - # Make entity - return "&#$z;"; + $codepoint = utf8ToCodepoint( $matches[0] ); + return "&#$codepoint;"; } -# Converts all multi-byte characters in a UTF-8 string into the appropriate character entity +/** + * Converts all multi-byte characters in a UTF-8 string into the appropriate + * character entity + */ function wfUtf8ToHTML($string) { return preg_replace_callback( '/[\\xc0-\\xfd][\\x80-\\xbf]*/', 'wfUtf8Entity', $string ); } -function wfDebug( $text, $logonly = false ) -{ +/** + * Sends a line to the debug log if enabled or, optionally, to a comment in output. + * In normal operation this is a NOP. + * + * Controlling globals: + * $wgDebugLogFile - points to the log file + * $wgProfileOnly - if set, normal debug messages will not be recorded. + * $wgDebugRawPage - if false, 'action=raw' hits will not result in debug output. + * $wgDebugComments - if on, some debug items may appear in comments in the HTML output. + * + * @param string $text + * @param bool $logonly Set true to avoid appearing in HTML when $wgDebugComments is set + */ +function wfDebug( $text, $logonly = false ) { global $wgOut, $wgDebugLogFile, $wgDebugComments, $wgProfileOnly, $wgDebugRawPage; # Check for raw action using $_GET not $wgRequest, since the latter might not be initialised yet @@ -207,7 +268,10 @@ function wfDebug( $text, $logonly = false ) } } -# Log for database errors +/** + * Log for database errors + * @param string $text Database error message. + */ function wfLogDBError( $text ) { global $wgDBerrorLog; if ( $wgDBerrorLog ) { @@ -216,8 +280,10 @@ function wfLogDBError( $text ) { } } -function logProfilingData() -{ +/** + * @todo document + */ +function logProfilingData() { global $wgRequestTime, $wgDebugLogFile, $wgDebugRawPage, $wgRequest; global $wgProfiling, $wgProfileStack, $wgProfileLimit, $wgUser; $now = wfTime(); @@ -236,7 +302,7 @@ function logProfilingData() $forward .= ' from ' . $_SERVER['HTTP_FROM']; if( $forward ) $forward = "\t(proxied via {$_SERVER['REMOTE_ADDR']}{$forward})"; - if($wgUser->getId() == 0) + if( $wgUser->isAnon() ) $forward .= ' anon'; $log = sprintf( "%s\t%04.3f\t%s\n", gmdate( 'YmdHis' ), $elapsed, @@ -247,8 +313,12 @@ function logProfilingData() } } -# Check if the wiki read-only lock file is present. This can be used to lock off -# editing functions, but doesn't guarantee that the database will not be modified. +/** + * Check if the wiki read-only lock file is present. This can be used to lock + * off editing functions, but doesn't guarantee that the database will not be + * modified. + * @return bool + */ function wfReadOnly() { global $wgReadOnlyFile; @@ -258,58 +328,104 @@ function wfReadOnly() { return is_file( $wgReadOnlyFile ); } -$wgReplacementKeys = array( '$1', '$2', '$3', '$4', '$5', '$6', '$7', '$8', '$9' ); -# Get a message from anywhere +/** + * Get a message from anywhere, for the UI elements + */ function wfMsg( $key ) { - global $wgRequest; - if ( $wgRequest->getVal( 'debugmsg' ) ) { - if ( $key == 'linktrail' /* a special case where we want to return something specific */ ) - return "/^()(.*)$/sD"; - else - return $key; - } $args = func_get_args(); - if ( count( $args ) ) { - array_shift( $args ); - } + array_shift( $args ); return wfMsgReal( $key, $args, true ); } -# Get a message from the language file +/** + * Get a message from anywhere, for the content + */ +function wfMsgForContent( $key ) { + global $wgForceUIMsgAsContentMsg; + $args = func_get_args(); + array_shift( $args ); + $forcontent = true; + if( is_array( $wgForceUIMsgAsContentMsg ) && + in_array( $key, $wgForceUIMsgAsContentMsg ) ) + $forcontent = false; + return wfMsgReal( $key, $args, true, $forcontent ); +} + +/** + * Get a message from the language file, for the UI elements + */ function wfMsgNoDB( $key ) { $args = func_get_args(); - if ( count( $args ) ) { - array_shift( $args ); - } + array_shift( $args ); return wfMsgReal( $key, $args, false ); } -# Really get a message -function wfMsgReal( $key, $args, $useDB ) { - global $wgReplacementKeys, $wgMessageCache, $wgLang; +/** + * Get a message from the language file, for the content + */ +function wfMsgNoDBForContent( $key ) { + global $wgForceUIMsgAsContentMsg; + $args = func_get_args(); + array_shift( $args ); + $forcontent = true; + if( is_array( $wgForceUIMsgAsContentMsg ) && + in_array( $key, $wgForceUIMsgAsContentMsg ) ) + $forcontent = false; + return wfMsgReal( $key, $args, false, $forcontent ); +} - $fname = 'wfMsg'; + +/** + * Really get a message + */ +function wfMsgReal( $key, $args, $useDB, $forContent=false ) { + static $replacementKeys = array( '$1', '$2', '$3', '$4', '$5', '$6', '$7', '$8', '$9' ); + global $wgParser, $wgMsgParserOptions; + global $wgContLang, $wgLanguageCode; + global $wgMessageCache, $wgLang; + + $fname = 'wfMsgReal'; wfProfileIn( $fname ); - if ( $wgMessageCache ) { - $message = $wgMessageCache->get( $key, $useDB ); - } elseif ( $wgLang ) { - $message = $wgLang->getMessage( $key ); + + if( is_object( $wgMessageCache ) ) { + $message = $wgMessageCache->get( $key, $useDB, $forContent ); } else { - wfDebug( "No language object when getting $key\n" ); - $message = "<$key>"; + if( $forContent ) { + $lang = &$wgContLang; + } else { + $lang = &$wgLang; + } + + wfSuppressWarnings(); + + if( is_object( $lang ) ) { + $message = $lang->getMessage( $key ); + } else { + $message = ''; + } + wfRestoreWarnings(); + if(!$message) + $message = Language::getMessage($key); + if(strstr($message, '{{' ) !== false) { + $message = $wgParser->transformMsg($message, $wgMsgParserOptions); + } } # Replace arguments if( count( $args ) ) { - $message = str_replace( $wgReplacementKeys, $args, $message ); + $message = str_replace( $replacementKeys, $args, $message ); } wfProfileOut( $fname ); return $message; } -# Just like exit() but makes a note of it. -# Commits open transactions except if the error parameter is set + + +/** + * Just like exit() but makes a note of it. + * Commits open transactions except if the error parameter is set + */ function wfAbruptExit( $error = false ){ global $wgLoadBalancer; static $called = false; @@ -334,13 +450,20 @@ function wfAbruptExit( $error = false ){ exit(); } +/** + * @todo document + */ function wfErrorExit() { wfAbruptExit( true ); } -# This is meant as a debugging aid to track down where bad data comes from. -# Shouldn't be used in production code except maybe in "shouldn't happen" areas. -# +/** + * Die with a backtrace + * This is meant as a debugging aid to track down where bad data comes from. + * Shouldn't be used in production code except maybe in "shouldn't happen" areas. + * + * @param string $msg Message shown when dieing. + */ function wfDebugDieBacktrace( $msg = '' ) { global $wgCommandLineMode; @@ -352,12 +475,21 @@ function wfDebugDieBacktrace( $msg = '' ) { } $backtrace = debug_backtrace(); foreach( $backtrace as $call ) { - $f = explode( DIRECTORY_SEPARATOR, $call['file'] ); - $file = $f[count($f)-1]; + if( isset( $call['file'] ) ) { + $f = explode( DIRECTORY_SEPARATOR, $call['file'] ); + $file = $f[count($f)-1]; + } else { + $file = '-'; + } + if( isset( $call['line'] ) ) { + $line = $call['line']; + } else { + $line = '-'; + } if ( $wgCommandLineMode ) { - $msg .= "$file line {$call['line']} calls "; + $msg .= "$file line $line calls "; } else { - $msg .= '
  • ' . $file . ' line ' . $call['line'] . ' calls '; + $msg .= '
  • ' . $file . ' line ' . $line . ' calls '; } if( !empty( $call['class'] ) ) $msg .= $call['class'] . '::'; $msg .= $call['function'] . '()'; @@ -375,33 +507,48 @@ function wfDebugDieBacktrace( $msg = '' ) { /* Some generic result counters, pulled out of SearchEngine */ -function wfShowingResults( $offset, $limit ) -{ + +/** + * @todo document + */ +function wfShowingResults( $offset, $limit ) { global $wgLang; return wfMsg( 'showingresults', $wgLang->formatNum( $limit ), $wgLang->formatNum( $offset+1 ) ); } -function wfShowingResultsNum( $offset, $limit, $num ) -{ +/** + * @todo document + */ +function wfShowingResultsNum( $offset, $limit, $num ) { global $wgLang; return wfMsg( 'showingresultsnum', $wgLang->formatNum( $limit ), $wgLang->formatNum( $offset+1 ), $wgLang->formatNum( $num ) ); } -function wfViewPrevNext( $offset, $limit, $link, $query = '', $atend = false ) -{ +/** + * @todo document + */ +function wfViewPrevNext( $offset, $limit, $link, $query = '', $atend = false ) { global $wgUser, $wgLang; $fmtLimit = $wgLang->formatNum( $limit ); $prev = wfMsg( 'prevn', $fmtLimit ); $next = wfMsg( 'nextn', $fmtLimit ); - $link = wfUrlencode( $link ); - + + if( is_object( $link ) ) { + $title =& $link; + } else { + $title =& Title::newFromText( $link ); + if( is_null( $title ) ) { + return false; + } + } + $sk = $wgUser->getSkin(); if ( 0 != $offset ) { $po = $offset - $limit; if ( $po < 0 ) { $po = 0; } $q = "limit={$limit}&offset={$po}"; if ( '' != $query ) { $q .= '&'.$query; } - $plink = '{$prev}"; + $plink = '{$prev}"; } else { $plink = $prev; } $no = $offset + $limit; @@ -411,29 +558,37 @@ function wfViewPrevNext( $offset, $limit, $link, $query = '', $atend = false ) if ( $atend ) { $nlink = $next; } else { - $nlink = '{$next}"; + $nlink = '{$next}"; } - $nums = wfNumLink( $offset, 20, $link , $query ) . ' | ' . - wfNumLink( $offset, 50, $link, $query ) . ' | ' . - wfNumLink( $offset, 100, $link, $query ) . ' | ' . - wfNumLink( $offset, 250, $link, $query ) . ' | ' . - wfNumLink( $offset, 500, $link, $query ); + $nums = wfNumLink( $offset, 20, $title, $query ) . ' | ' . + wfNumLink( $offset, 50, $title, $query ) . ' | ' . + wfNumLink( $offset, 100, $title, $query ) . ' | ' . + wfNumLink( $offset, 250, $title, $query ) . ' | ' . + wfNumLink( $offset, 500, $title, $query ); return wfMsg( 'viewprevnext', $plink, $nlink, $nums ); } -function wfNumLink( $offset, $limit, $link, $query = '' ) -{ +/** + * @todo document + */ +function wfNumLink( $offset, $limit, &$title, $query = '' ) { global $wgUser, $wgLang; if ( '' == $query ) { $q = ''; } else { $q = $query.'&'; } $q .= 'limit='.$limit.'&offset='.$offset; $fmtLimit = $wgLang->formatNum( $limit ); - $s = '{$fmtLimit}"; + $s = '{$fmtLimit}"; return $s; } +/** + * @todo document + * @todo FIXME: we may want to blacklist some broken browsers + * + * @return bool Whereas client accept gzip compression + */ function wfClientAcceptsGzip() { global $wgUseGzip; if( $wgUseGzip ) { @@ -450,29 +605,36 @@ function wfClientAcceptsGzip() { return false; } -# Yay, more global functions! +/** + * Yay, more global functions! + */ function wfCheckLimits( $deflimit = 50, $optionname = 'rclimit' ) { global $wgRequest; return $wgRequest->getLimitOffset( $deflimit, $optionname ); } -# Escapes the given text so that it may be output using addWikiText() -# without any linking, formatting, etc. making its way through. This -# is achieved by substituting certain characters with HTML entities. -# As required by the callers, is not used. It currently does -# not filter out characters which have special meaning only at the -# start of a line, such as "*". -function wfEscapeWikiText( $text ) -{ +/** + * Escapes the given text so that it may be output using addWikiText() + * without any linking, formatting, etc. making its way through. This + * is achieved by substituting certain characters with HTML entities. + * As required by the callers, is not used. It currently does + * not filter out characters which have special meaning only at the + * start of a line, such as "*". + * + * @param string $text Text to be escaped + */ +function wfEscapeWikiText( $text ) { $text = str_replace( - array( '[', '|', "'", 'ISBN ' , '://' , "\n=", '{{' ), + array( '[', '|', '\'', 'ISBN ' , '://' , "\n=", '{{' ), array( '[', '|', ''', 'ISBN ', '://' , "\n=", '{{' ), htmlspecialchars($text) ); return $text; } -function wfQuotedPrintable( $string, $charset = '' ) -{ +/** + * @todo document + */ +function wfQuotedPrintable( $string, $charset = '' ) { # Probably incomplete; see RFC 2045 if( empty( $charset ) ) { global $wgInputEncoding; @@ -490,22 +652,29 @@ function wfQuotedPrintable( $string, $charset = '' ) return $out; } -function wfTime(){ +/** + * @todo document + * @return float + */ +function wfTime() { $st = explode( ' ', microtime() ); return (float)$st[0] + (float)$st[1]; } -# Changes the first character to an HTML entity +/** + * Changes the first character to an HTML entity + */ function wfHtmlEscapeFirst( $text ) { $ord = ord($text); $newText = substr($text, 1); return "&#$ord;$newText"; } -# Sets dest to source and returns the original value of dest -# If source is NULL, it just returns the value, it doesn't set the variable -function wfSetVar( &$dest, $source ) -{ +/** + * Sets dest to source and returns the original value of dest + * If source is NULL, it just returns the value, it doesn't set the variable + */ +function wfSetVar( &$dest, $source ) { $temp = $dest; if ( !is_null( $source ) ) { $dest = $source; @@ -513,7 +682,9 @@ function wfSetVar( &$dest, $source ) return $temp; } -# As for wfSetVar except setting a bit +/** + * As for wfSetVar except setting a bit + */ function wfSetBit( &$dest, $bit, $state = true ) { $temp = (bool)($dest & $bit ); if ( !is_null( $state ) ) { @@ -526,9 +697,11 @@ function wfSetBit( &$dest, $bit, $state = true ) { return $temp; } -# This function takes two arrays as input, and returns a CGI-style string, e.g. -# "days=7&limit=100". Options in the first array override options in the second. -# Options set to "" will not be output. +/** + * This function takes two arrays as input, and returns a CGI-style string, e.g. + * "days=7&limit=100". Options in the first array override options in the second. + * Options set to "" will not be output. + */ function wfArrayToCGI( $array1, $array2 = NULL ) { if ( !is_null( $array2 ) ) { @@ -541,22 +714,26 @@ function wfArrayToCGI( $array1, $array2 = NULL ) if ( '' != $cgi ) { $cgi .= '&'; } - $cgi .= $key.'='.$value; + $cgi .= urlencode( $key ) . '=' . urlencode( $value ); } } return $cgi; } -# This is obsolete, use SquidUpdate::purge() +/** + * This is obsolete, use SquidUpdate::purge() + * @deprecated + */ function wfPurgeSquidServers ($urlArr) { SquidUpdate::purge( $urlArr ); } -# Windows-compatible version of escapeshellarg() -# Windows doesn't recognise single-quotes in the shell, but the escapeshellarg() -# function puts single quotes in regardless of OS -function wfEscapeShellArg( ) -{ +/** + * Windows-compatible version of escapeshellarg() + * Windows doesn't recognise single-quotes in the shell, but the escapeshellarg() + * function puts single quotes in regardless of OS + */ +function wfEscapeShellArg( ) { $args = func_get_args(); $first = true; $retVal = ''; @@ -576,9 +753,10 @@ function wfEscapeShellArg( ) return $retVal; } -# wfMerge attempts to merge differences between three texts. -# Returns true for a clean merge and false for failure or a conflict. - +/** + * wfMerge attempts to merge differences between three texts. + * Returns true for a clean merge and false for failure or a conflict. + */ function wfMerge( $old, $mine, $yours, &$result ){ global $wgDiff3; @@ -605,7 +783,7 @@ function wfMerge( $old, $mine, $yours, &$result ){ wfEscapeShellArg( $yourtextName ); $handle = popen( $cmd, 'r' ); - if( fgets( $handle ) ){ + if( fgets( $handle, 1024 ) ){ $conflict = true; } else { $conflict = false; @@ -629,10 +807,12 @@ function wfMerge( $old, $mine, $yours, &$result ){ return ! $conflict; } -function wfVarDump( $var ) -{ +/** + * @todo document + */ +function wfVarDump( $var ) { global $wgOut; - $s = str_replace("\n","
    \n", var_export( $var, true ) . "\n"); + $s = str_replace("\n","
    \n", var_export( $var, true ) . "\n"); if ( headers_sent() || !@is_object( $wgOut ) ) { print $s; } else { @@ -640,7 +820,9 @@ function wfVarDump( $var ) } } -# Provide a simple HTTP error. +/** + * Provide a simple HTTP error. + */ function wfHttpError( $code, $label, $desc ) { global $wgOut; $wgOut->disable(); @@ -651,11 +833,14 @@ function wfHttpError( $code, $label, $desc ) { # Don't send content if it's a HEAD request. if( $_SERVER['REQUEST_METHOD'] == 'HEAD' ) { header( 'Content-type: text/plain' ); - print "$desc\n"; + print $desc."\n"; } } -# Converts an Accept-* header into an array mapping string values to quality factors +/** + * Converts an Accept-* header into an array mapping string values to quality + * factors + */ function wfAcceptToPrefs( $accept, $def = '*/*' ) { # No arg means accept anything (per HTTP spec) if( !$accept ) { @@ -679,7 +864,19 @@ function wfAcceptToPrefs( $accept, $def = '*/*' ) { return $prefs; } -/* private */ function mimeTypeMatch( $type, $avail ) { +/** + * Checks if a given MIME type matches any of the keys in the given + * array. Basic wildcards are accepted in the array keys. + * + * Returns the matching MIME type (or wildcard) if a match, otherwise + * NULL if no match. + * + * @param string $type + * @param array $avail + * @return string + * @access private + */ +function mimeTypeMatch( $type, $avail ) { if( array_key_exists($type, $avail) ) { return $type; } else { @@ -694,8 +891,19 @@ function wfAcceptToPrefs( $accept, $def = '*/*' ) { } } -# FIXME: doesn't handle params like 'text/plain; charset=UTF-8' -# XXX: generalize to negotiate other stuff +/** + * Returns the 'best' match between a client's requested internet media types + * and the server's list of available types. Each list should be an associative + * array of type to preference (preference is a float between 0.0 and 1.0). + * Wildcards in the types are acceptable. + * + * @param array $cprefs Client's acceptable type list + * @param array $sprefs Server's offered types + * @return string + * + * @todo FIXME: doesn't handle params like 'text/plain; charset=UTF-8' + * XXX: generalize to negotiate other stuff + */ function wfNegotiateType( $cprefs, $sprefs ) { $combine = array(); @@ -732,42 +940,29 @@ function wfNegotiateType( $cprefs, $sprefs ) { return $besttype; } -# Array lookup -# Returns an array where the values in the first array are replaced by the -# values in the second array with the corresponding keys -function wfArrayLookup( $a, $b ) -{ +/** + * Array lookup + * Returns an array where the values in the first array are replaced by the + * values in the second array with the corresponding keys + * + * @return array + */ +function wfArrayLookup( $a, $b ) { return array_flip( array_intersect( array_flip( $a ), array_keys( $b ) ) ); } - -# Ideally we'd be using actual time fields in the db -function wfTimestamp2Unix( $ts ) { - return gmmktime( ( (int)substr( $ts, 8, 2) ), - (int)substr( $ts, 10, 2 ), (int)substr( $ts, 12, 2 ), - (int)substr( $ts, 4, 2 ), (int)substr( $ts, 6, 2 ), - (int)substr( $ts, 0, 4 ) ); -} - -function wfUnix2Timestamp( $unixtime ) { - return gmdate( 'YmdHis', $unixtime ); -} - +/** + * Convenience function; returns MediaWiki timestamp for the present time. + * @return string + */ function wfTimestampNow() { # return NOW - return gmdate( 'YmdHis' ); -} - -# Sorting hack for MySQL 3, which doesn't use index sorts for DESC -function wfInvertTimestamp( $ts ) { - return strtr( - $ts, - '0123456789', - '9876543210' - ); + return wfTimestamp( TS_MW, time() ); } -# Reference-counted warning suppression +/** + * Reference-counted warning suppression + */ function wfSuppressWarnings( $end = false ) { static $suppressCount = 0; static $originalLevel = false; @@ -787,16 +982,27 @@ function wfSuppressWarnings( $end = false ) { } } -# Restore error level to previous value +/** + * Restore error level to previous value + */ function wfRestoreWarnings() { wfSuppressWarnings( true ); } # Autodetect, convert and provide timestamps of various types -define('TS_UNIX',0); # Standard unix timestamp (number of seconds since 1 Jan 1970) -define('TS_MW',1); # Mediawiki concatenated string timestamp (yyyymmddhhmmss) -define('TS_DB',2); # Standard database timestamp (yyyy-mm-dd hh:mm:ss) +/** Standard unix timestamp (number of seconds since 1 Jan 1970) */ +define('TS_UNIX',0); +/** MediaWiki concatenated string timestamp (yyyymmddhhmmss) */ +define('TS_MW',1); +/** Standard database timestamp (yyyy-mm-dd hh:mm:ss) */ +define('TS_DB',2); +/** For HTTP and e-mail headers -- output only */ +define('TS_RFC2822', 3 ); + +/** + * @todo document + */ function wfTimestamp($outputtype=TS_UNIX,$ts=0) { if (preg_match("/^(\d{4})\-(\d\d)\-(\d\d) (\d\d):(\d\d):(\d\d)$/",$ts,$da)) { # TS_DB @@ -809,25 +1015,33 @@ function wfTimestamp($outputtype=TS_UNIX,$ts=0) { } elseif (preg_match("/^(\d{1,13})$/",$ts,$datearray)) { # TS_UNIX $uts=$ts; + } else { + # Bogus value; fall back to the epoch... + wfDebug("wfTimestamp() fed bogus time value: $outputtype; $ts\n"); + $uts = 0; } - if ($ts==0) - $uts=time(); + if ($ts==0) { $uts=time(); } + switch($outputtype) { - case TS_UNIX: - return $uts; - break; - case TS_MW: - return gmdate( 'YmdHis', $uts ); - break; - case TS_DB: - return gmdate( 'Y-m-d H:i:s', $uts ); - break; - default: - return; + case TS_UNIX: + return $uts; + case TS_MW: + return gmdate( 'YmdHis', $uts ); + case TS_DB: + return gmdate( 'Y-m-d H:i:s', $uts ); + case TS_RFC2822: + return gmdate( 'D, d M Y H:i:s', $uts ) . ' GMT'; + default: + wfDebugDieBacktrace( 'wfTimestamp() called with illegal output type.'); } } +/** + * Check where as the operating system is Windows + * + * @return bool True if it's windows, False otherwise. + */ function wfIsWindows() { if (substr(php_uname(), 0, 7) == 'Windows') { return true; @@ -836,4 +1050,67 @@ function wfIsWindows() { } } +/** + * Swap two variables + */ +function swap( &$x, &$y ) { + $z = $x; + $x = $y; + $y = $z; +} + +function wfGetSiteNotice() { + global $wgSiteNotice, $wgTitle, $wgOut; + $fname = 'wfGetSiteNotice'; + wfProfileIn( $fname ); + + $notice = wfMsg( 'sitenotice' ); + if($notice == '<sitenotice>') $notice = ''; + # Allow individual wikis to turn it off + if ( $notice == '-' ) { + $notice = ''; + } else { + if ($notice == '') { + $notice = $wgSiteNotice; + } + if($notice != '-' && $notice != '') { + $specialparser = new Parser(); + $parserOutput = $specialparser->parse( $notice, $wgTitle, $wgOut->mParserOptions, false ); + $notice = $parserOutput->getText(); + } + } + wfProfileOut( $fname ); + return $notice; +} + +/** + * Format an XML element with given attributes and, optionally, text content. + * Element and attribute names are assumed to be ready for literal inclusion. + * Strings are assumed to not contain XML-illegal characters; special + * characters (<, >, &) are escaped but illegals are not touched. + * + * @param string $element + * @param array $attribs Name=>value pairs. Values will be escaped. + * @param bool $contents NULL to make an open tag only; '' for a contentless closed tag (default) + * @return string + */ +function wfElement( $element, $attribs = array(), $contents = '') { + $out = '<' . $element; + foreach( $attribs as $name => $val ) { + $out .= ' ' . $name . '="' . htmlspecialchars( $val ) . '"'; + } + if( is_null( $contents ) ) { + $out .= '>'; + } else { + if( $contents == '' ) { + $out .= ' />'; + } else { + $out .= '>'; + $out .= htmlspecialchars( $contents ); + $out .= ""; + } + } + return $out; +} + ?>