00001 <?php
00002
00003 if ( !defined( 'MEDIAWIKI' ) ) {
00004 die( "This file is part of MediaWiki, it is not a valid entry point" );
00005 }
00006
00011 require_once dirname(__FILE__) . '/normal/UtfNormalUtil.php';
00012 require_once dirname(__FILE__) . '/XmlFunctions.php';
00013
00014
00016
00024 if( !function_exists('iconv') ) {
00025 # iconv support is not in the default configuration and so may not be present.
00026 # Assume will only ever use utf-8 and iso-8859-1.
00027 # This will *not* work in all circumstances.
00028 function iconv( $from, $to, $string ) {
00029 if(strcasecmp( $from, $to ) == 0) return $string;
00030 if(strcasecmp( $from, 'utf-8' ) == 0) return utf8_decode( $string );
00031 if(strcasecmp( $to, 'utf-8' ) == 0) return utf8_encode( $string );
00032 return $string;
00033 }
00034 }
00035
00036 if ( !function_exists( 'mb_substr' ) ) {
00047 function mb_substr( $str, $start, $count='end' ) {
00048 if( $start != 0 ) {
00049 $split = mb_substr_split_unicode( $str, intval( $start ) );
00050 $str = substr( $str, $split );
00051 }
00052
00053 if( $count !== 'end' ) {
00054 $split = mb_substr_split_unicode( $str, intval( $count ) );
00055 $str = substr( $str, 0, $split );
00056 }
00057
00058 return $str;
00059 }
00060
00061 function mb_substr_split_unicode( $str, $splitPos ) {
00062 if( $splitPos == 0 ) {
00063 return 0;
00064 }
00065
00066 $byteLen = strlen( $str );
00067
00068 if( $splitPos > 0 ) {
00069 if( $splitPos > 256 ) {
00070
00071
00072
00073 $bytePos = $splitPos;
00074 while ($bytePos < $byteLen && $str{$bytePos} >= "\x80" && $str{$bytePos} < "\xc0")
00075 ++$bytePos;
00076 $charPos = mb_strlen( substr( $str, 0, $bytePos ) );
00077 } else {
00078 $charPos = 0;
00079 $bytePos = 0;
00080 }
00081
00082 while( $charPos++ < $splitPos ) {
00083 ++$bytePos;
00084
00085 while ($bytePos < $byteLen && $str{$bytePos} >= "\x80" && $str{$bytePos} < "\xc0")
00086 ++$bytePos;
00087 }
00088 } else {
00089 $splitPosX = $splitPos + 1;
00090 $charPos = 0;
00091 $bytePos = $byteLen;
00092 while( $bytePos > 0 && $charPos-- >= $splitPosX ) {
00093 --$bytePos;
00094
00095 while ($bytePos > 0 && $str{$bytePos} >= "\x80" && $str{$bytePos} < "\xc0")
00096 --$bytePos;
00097 }
00098 }
00099
00100 return $bytePos;
00101 }
00102 }
00103
00104 if ( !function_exists( 'mb_strlen' ) ) {
00111 function mb_strlen( $str, $enc="" ) {
00112 $counts = count_chars( $str );
00113 $total = 0;
00114
00115
00116 for( $i = 0; $i < 0x80; $i++ ) {
00117 $total += $counts[$i];
00118 }
00119
00120
00121 for( $i = 0xc0; $i < 0xff; $i++ ) {
00122 $total += $counts[$i];
00123 }
00124 return $total;
00125 }
00126 }
00127
00128
00129 if( !function_exists( 'mb_strpos' ) ) {
00138 function mb_strpos( $haystack, $needle, $offset = 0, $encoding="" ) {
00139 $needle = preg_quote( $needle, '/' );
00140
00141 $ar = array();
00142 preg_match( '/'.$needle.'/u', $haystack, $ar, PREG_OFFSET_CAPTURE, $offset );
00143
00144 if( isset( $ar[0][1] ) ) {
00145 return $ar[0][1];
00146 } else {
00147 return false;
00148 }
00149 }
00150 }
00151
00152 if( !function_exists( 'mb_strrpos' ) ) {
00161 function mb_strrpos( $haystack, $needle, $offset = 0, $encoding = "" ) {
00162 $needle = preg_quote( $needle, '/' );
00163
00164 $ar = array();
00165 preg_match_all( '/'.$needle.'/u', $haystack, $ar, PREG_OFFSET_CAPTURE, $offset );
00166
00167 if( isset( $ar[0] ) && count( $ar[0] ) > 0 &&
00168 isset( $ar[0][count($ar[0])-1][1] ) ) {
00169 return $ar[0][count($ar[0])-1][1];
00170 } else {
00171 return false;
00172 }
00173 }
00174 }
00175
00176 if ( !function_exists( 'array_diff_key' ) ) {
00182 function array_diff_key( $left, $right ) {
00183 $result = $left;
00184 foreach ( $left as $key => $unused ) {
00185 if ( isset( $right[$key] ) ) {
00186 unset( $result[$key] );
00187 }
00188 }
00189 return $result;
00190 }
00191 }
00192
00193 if ( !function_exists( 'array_intersect_key' ) ) {
00198 function array_intersect_key( $isec, $keys ) {
00199 $argc = func_num_args();
00200
00201 if ( $argc > 2 ) {
00202 for ( $i = 1; $isec && $i < $argc; $i++ ) {
00203 $arr = func_get_arg( $i );
00204
00205 foreach ( array_keys( $isec ) as $key ) {
00206 if ( !isset( $arr[$key] ) )
00207 unset( $isec[$key] );
00208 }
00209 }
00210
00211 return $isec;
00212 } else {
00213 $res = array();
00214 foreach ( array_keys( $isec ) as $key ) {
00215 if ( isset( $keys[$key] ) )
00216 $res[$key] = $isec[$key];
00217 }
00218
00219 return $res;
00220 }
00221 }
00222 }
00223
00224
00225 if ( !function_exists( 'istainted' ) ) {
00226 function istainted( $var ) {
00227 return 0;
00228 }
00229 function taint( $var, $level = 0 ) {}
00230 function untaint( $var, $level = 0 ) {}
00231 define( 'TC_HTML', 1 );
00232 define( 'TC_SHELL', 1 );
00233 define( 'TC_MYSQL', 1 );
00234 define( 'TC_PCRE', 1 );
00235 define( 'TC_SELF', 1 );
00236 }
00238
00239
00243 function wfArrayDiff2( $a, $b ) {
00244 return array_udiff( $a, $b, 'wfArrayDiff2_cmp' );
00245 }
00246 function wfArrayDiff2_cmp( $a, $b ) {
00247 if ( !is_array( $a ) ) {
00248 return strcmp( $a, $b );
00249 } elseif ( count( $a ) !== count( $b ) ) {
00250 return count( $a ) < count( $b ) ? -1 : 1;
00251 } else {
00252 reset( $a );
00253 reset( $b );
00254 while( ( list( $keyA, $valueA ) = each( $a ) ) && ( list( $keyB, $valueB ) = each( $b ) ) ) {
00255 $cmp = strcmp( $valueA, $valueB );
00256 if ( $cmp !== 0 ) {
00257 return $cmp;
00258 }
00259 }
00260 return 0;
00261 }
00262 }
00263
00268 function wfSeedRandom() {
00269
00270 }
00271
00279 function wfRandom() {
00280 # The maximum random value is "only" 2^31-1, so get two random
00281 # values to reduce the chance of dupes
00282 $max = mt_getrandmax() + 1;
00283 $rand = number_format( (mt_rand() * $max + mt_rand())
00284 / $max / $max, 12, '.', '' );
00285 return $rand;
00286 }
00287
00307 function wfUrlencode( $s ) {
00308 $s = urlencode( $s );
00309 $s = str_ireplace(
00310 array( '%3B','%3A','%40','%24','%21','%2A','%28','%29','%2C','%2F' ),
00311 array( ';', ':', '@', '$', '!', '*', '(', ')', ',', '/' ),
00312 $s
00313 );
00314
00315 return $s;
00316 }
00317
00331 function wfDebug( $text, $logonly = false ) {
00332 global $wgOut, $wgDebugLogFile, $wgDebugComments, $wgProfileOnly, $wgDebugRawPage;
00333 global $wgDebugLogPrefix, $wgShowDebug;
00334 static $recursion = 0;
00335
00336 static $cache = array();
00337 $text = wfDebugTimer() . $text;
00338
00339 # Check for raw action using $_GET not $wgRequest, since the latter might not be initialised yet
00340 if ( isset( $_GET['action'] ) && $_GET['action'] == 'raw' && !$wgDebugRawPage ) {
00341 return;
00342 }
00343
00344 if ( ( $wgDebugComments || $wgShowDebug ) && !$logonly ) {
00345 $cache[] = $text;
00346
00347 if ( !isset( $wgOut ) ) {
00348 return;
00349 }
00350 if ( !StubObject::isRealObject( $wgOut ) ) {
00351 if ( $recursion ) {
00352 return;
00353 }
00354 $recursion++;
00355 $wgOut->_unstub();
00356 $recursion--;
00357 }
00358
00359
00360 array_map( array( $wgOut, 'debug' ), $cache );
00361 $cache = array();
00362 }
00363 if ( $wgDebugLogFile != '' && !$wgProfileOnly ) {
00364 # Strip unprintables; they can switch terminal modes when binary data
00365 # gets dumped, which is pretty annoying.
00366 $text = preg_replace( '![\x00-\x08\x0b\x0c\x0e-\x1f]!', ' ', $text );
00367 $text = $wgDebugLogPrefix . $text;
00368 wfErrorLog( $text, $wgDebugLogFile );
00369 }
00370 }
00371
00372 function wfDebugTimer() {
00373 global $wgDebugTimestamps;
00374 if ( !$wgDebugTimestamps ) return '';
00375 static $start = null;
00376
00377 if ( $start === null ) {
00378 $start = microtime( true );
00379 $prefix = "\n$start";
00380 } else {
00381 $prefix = sprintf( "%6.4f", microtime( true ) - $start );
00382 }
00383
00384 return $prefix . ' ';
00385 }
00386
00391 function wfDebugMem( $exact = false ) {
00392 $mem = memory_get_usage();
00393 if( !$exact ) {
00394 $mem = floor( $mem / 1024 ) . ' kilobytes';
00395 } else {
00396 $mem .= ' bytes';
00397 }
00398 wfDebug( "Memory usage: $mem\n" );
00399 }
00400
00410 function wfDebugLog( $logGroup, $text, $public = true ) {
00411 global $wgDebugLogGroups, $wgShowHostnames;
00412 $text = trim($text)."\n";
00413 if( isset( $wgDebugLogGroups[$logGroup] ) ) {
00414 $time = wfTimestamp( TS_DB );
00415 $wiki = wfWikiID();
00416 if ( $wgShowHostnames ) {
00417 $host = wfHostname();
00418 } else {
00419 $host = '';
00420 }
00421 wfErrorLog( "$time $host $wiki: $text", $wgDebugLogGroups[$logGroup] );
00422 } else if ( $public === true ) {
00423 wfDebug( $text, true );
00424 }
00425 }
00426
00431 function wfLogDBError( $text ) {
00432 global $wgDBerrorLog, $wgDBname;
00433 if ( $wgDBerrorLog ) {
00434 $host = trim(`hostname`);
00435 $text = date('D M j G:i:s T Y') . "\t$host\t$wgDBname\t$text";
00436 wfErrorLog( $text, $wgDBerrorLog );
00437 }
00438 }
00439
00446 function wfErrorLog( $text, $file ) {
00447 if ( substr( $file, 0, 4 ) == 'udp:' ) {
00448 if ( preg_match( '!^(tcp|udp):(?://)?\[([0-9a-fA-F:]+)\]:(\d+)(?:/(.*))?$!', $file, $m ) ) {
00449
00450 $protocol = $m[1];
00451 $host = $m[2];
00452 $port = intval( $m[3] );
00453 $prefix = isset( $m[4] ) ? $m[4] : false;
00454 $domain = AF_INET6;
00455 } elseif ( preg_match( '!^(tcp|udp):(?://)?([a-zA-Z0-9.-]+):(\d+)(?:/(.*))?$!', $file, $m ) ) {
00456 $protocol = $m[1];
00457 $host = $m[2];
00458 if ( !IP::isIPv4( $host ) ) {
00459 $host = gethostbyname( $host );
00460 }
00461 $port = intval( $m[3] );
00462 $prefix = isset( $m[4] ) ? $m[4] : false;
00463 $domain = AF_INET;
00464 } else {
00465 throw new MWException( __METHOD__.": Invalid UDP specification" );
00466 }
00467
00468 if ( strval( $prefix ) !== '' ) {
00469 $text = preg_replace( '/^/m', $prefix . ' ', $text );
00470 if ( substr( $text, -1 ) != "\n" ) {
00471 $text .= "\n";
00472 }
00473 }
00474
00475 $sock = socket_create( $domain, SOCK_DGRAM, SOL_UDP );
00476 if ( !$sock ) {
00477 return;
00478 }
00479 socket_sendto( $sock, $text, strlen( $text ), 0, $host, $port );
00480 socket_close( $sock );
00481 } else {
00482 wfSuppressWarnings();
00483 $exists = file_exists( $file );
00484 $size = $exists ? filesize( $file ) : false;
00485 if ( !$exists || ( $size !== false && $size + strlen( $text ) < 0x7fffffff ) ) {
00486 error_log( $text, 3, $file );
00487 }
00488 wfRestoreWarnings();
00489 }
00490 }
00491
00495 function wfLogProfilingData() {
00496 global $wgRequestTime, $wgDebugLogFile, $wgDebugRawPage, $wgRequest;
00497 global $wgProfiler, $wgProfileLimit, $wgUser;
00498 # Profiling must actually be enabled...
00499 if( !isset( $wgProfiler ) ) return;
00500 # Get total page request time
00501 $now = wfTime();
00502 $elapsed = $now - $wgRequestTime;
00503 # Only show pages that longer than $wgProfileLimit time (default is 0)
00504 if( $elapsed <= $wgProfileLimit ) return;
00505 $prof = wfGetProfilingOutput( $wgRequestTime, $elapsed );
00506 $forward = '';
00507 if( !empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) )
00508 $forward = ' forwarded for ' . $_SERVER['HTTP_X_FORWARDED_FOR'];
00509 if( !empty( $_SERVER['HTTP_CLIENT_IP'] ) )
00510 $forward .= ' client IP ' . $_SERVER['HTTP_CLIENT_IP'];
00511 if( !empty( $_SERVER['HTTP_FROM'] ) )
00512 $forward .= ' from ' . $_SERVER['HTTP_FROM'];
00513 if( $forward )
00514 $forward = "\t(proxied via {$_SERVER['REMOTE_ADDR']}{$forward})";
00515
00516 if( StubObject::isRealObject($wgUser) && $wgUser->isAnon() )
00517 $forward .= ' anon';
00518 $log = sprintf( "%s\t%04.3f\t%s\n",
00519 gmdate( 'YmdHis' ), $elapsed,
00520 urldecode( $wgRequest->getRequestURL() . $forward ) );
00521 if ( $wgDebugLogFile != '' && ( $wgRequest->getVal('action') != 'raw' || $wgDebugRawPage ) ) {
00522 wfErrorLog( $log . $prof, $wgDebugLogFile );
00523 }
00524 }
00525
00532 function wfReadOnly() {
00533 global $wgReadOnlyFile, $wgReadOnly;
00534
00535 if ( !is_null( $wgReadOnly ) ) {
00536 return (bool)$wgReadOnly;
00537 }
00538 if ( $wgReadOnlyFile == '' ) {
00539 return false;
00540 }
00541
00542 if ( is_file( $wgReadOnlyFile ) ) {
00543 $wgReadOnly = file_get_contents( $wgReadOnlyFile );
00544 } else {
00545 $wgReadOnly = false;
00546 }
00547 return (bool)$wgReadOnly;
00548 }
00549
00550 function wfReadOnlyReason() {
00551 global $wgReadOnly;
00552 wfReadOnly();
00553 return $wgReadOnly;
00554 }
00555
00569 function wfGetLangObj( $langcode = false ){
00570 # Identify which language to get or create a language object for.
00571 if( $langcode instanceof Language )
00572 # Great, we already have the object!
00573 return $langcode;
00574
00575 global $wgContLang;
00576 if( $langcode === $wgContLang->getCode() || $langcode === true )
00577 # $langcode is the language code of the wikis content language object.
00578 # or it is a boolean and value is true
00579 return $wgContLang;
00580
00581 global $wgLang;
00582 if( $langcode === $wgLang->getCode() || $langcode === false )
00583 # $langcode is the language code of user language object.
00584 # or it was a boolean and value is false
00585 return $wgLang;
00586
00587 $validCodes = array_keys( Language::getLanguageNames() );
00588 if( in_array( $langcode, $validCodes ) )
00589 # $langcode corresponds to a valid language.
00590 return Language::factory( $langcode );
00591
00592 # $langcode is a string, but not a valid language code; use content language.
00593 wfDebug( "Invalid language code passed to wfGetLangObj, falling back to content language.\n" );
00594 return $wgContLang;
00595 }
00596
00610 function wfMsg( $key ) {
00611 $args = func_get_args();
00612 array_shift( $args );
00613 return wfMsgReal( $key, $args, true );
00614 }
00615
00619 function wfMsgNoTrans( $key ) {
00620 $args = func_get_args();
00621 array_shift( $args );
00622 return wfMsgReal( $key, $args, true, false, false );
00623 }
00624
00647 function wfMsgForContent( $key ) {
00648 global $wgForceUIMsgAsContentMsg;
00649 $args = func_get_args();
00650 array_shift( $args );
00651 $forcontent = true;
00652 if( is_array( $wgForceUIMsgAsContentMsg ) &&
00653 in_array( $key, $wgForceUIMsgAsContentMsg ) )
00654 $forcontent = false;
00655 return wfMsgReal( $key, $args, true, $forcontent );
00656 }
00657
00661 function wfMsgForContentNoTrans( $key ) {
00662 global $wgForceUIMsgAsContentMsg;
00663 $args = func_get_args();
00664 array_shift( $args );
00665 $forcontent = true;
00666 if( is_array( $wgForceUIMsgAsContentMsg ) &&
00667 in_array( $key, $wgForceUIMsgAsContentMsg ) )
00668 $forcontent = false;
00669 return wfMsgReal( $key, $args, true, $forcontent, false );
00670 }
00671
00675 function wfMsgNoDB( $key ) {
00676 $args = func_get_args();
00677 array_shift( $args );
00678 return wfMsgReal( $key, $args, false );
00679 }
00680
00684 function wfMsgNoDBForContent( $key ) {
00685 global $wgForceUIMsgAsContentMsg;
00686 $args = func_get_args();
00687 array_shift( $args );
00688 $forcontent = true;
00689 if( is_array( $wgForceUIMsgAsContentMsg ) &&
00690 in_array( $key, $wgForceUIMsgAsContentMsg ) )
00691 $forcontent = false;
00692 return wfMsgReal( $key, $args, false, $forcontent );
00693 }
00694
00695
00705 function wfMsgReal( $key, $args, $useDB = true, $forContent = false, $transform = true ) {
00706 wfProfileIn( __METHOD__ );
00707 $message = wfMsgGetKey( $key, $useDB, $forContent, $transform );
00708 $message = wfMsgReplaceArgs( $message, $args );
00709 wfProfileOut( __METHOD__ );
00710 return $message;
00711 }
00712
00717 function wfMsgWeirdKey( $key ) {
00718 $source = wfMsgGetKey( $key, false, true, false );
00719 if ( wfEmptyMsg( $key, $source ) )
00720 return "";
00721 else
00722 return $source;
00723 }
00724
00735 function wfMsgGetKey( $key, $useDB, $langCode = false, $transform = true ) {
00736 global $wgContLang, $wgMessageCache;
00737
00738 wfRunHooks('NormalizeMessageKey', array(&$key, &$useDB, &$langCode, &$transform));
00739
00740 # If $wgMessageCache isn't initialised yet, try to return something sensible.
00741 if( is_object( $wgMessageCache ) ) {
00742 $message = $wgMessageCache->get( $key, $useDB, $langCode );
00743 if ( $transform ) {
00744 $message = $wgMessageCache->transform( $message );
00745 }
00746 } else {
00747 $lang = wfGetLangObj( $langCode );
00748
00749 # MessageCache::get() does this already, Language::getMessage() doesn't
00750 # ISSUE: Should we try to handle "message/lang" here too?
00751 $key = str_replace( ' ' , '_' , $wgContLang->lcfirst( $key ) );
00752
00753 if( is_object( $lang ) ) {
00754 $message = $lang->getMessage( $key );
00755 } else {
00756 $message = false;
00757 }
00758 }
00759
00760 return $message;
00761 }
00762
00771 function wfMsgReplaceArgs( $message, $args ) {
00772 # Fix windows line-endings
00773 # Some messages are split with explode("\n", $msg)
00774 $message = str_replace( "\r", '', $message );
00775
00776
00777 if ( count( $args ) ) {
00778 if ( is_array( $args[0] ) ) {
00779 $args = array_values( $args[0] );
00780 }
00781 $replacementKeys = array();
00782 foreach( $args as $n => $param ) {
00783 $replacementKeys['$' . ($n + 1)] = $param;
00784 }
00785 $message = strtr( $message, $replacementKeys );
00786 }
00787
00788 return $message;
00789 }
00790
00802 function wfMsgHtml( $key ) {
00803 $args = func_get_args();
00804 array_shift( $args );
00805 return wfMsgReplaceArgs( htmlspecialchars( wfMsgGetKey( $key, true ) ), $args );
00806 }
00807
00819 function wfMsgWikiHtml( $key ) {
00820 global $wgOut;
00821 $args = func_get_args();
00822 array_shift( $args );
00823 return wfMsgReplaceArgs( $wgOut->parse( wfMsgGetKey( $key, true ), true ), $args );
00824 }
00825
00844 function wfMsgExt( $key, $options ) {
00845 global $wgOut;
00846
00847 $args = func_get_args();
00848 array_shift( $args );
00849 array_shift( $args );
00850 $options = (array)$options;
00851
00852 foreach( $options as $arrayKey => $option ) {
00853 if( !preg_match( '/^[0-9]+|language$/', $arrayKey ) ) {
00854 # An unknown index, neither numeric nor "language"
00855 wfWarn( "wfMsgExt called with incorrect parameter key $arrayKey", 1, E_USER_WARNING );
00856 } elseif( preg_match( '/^[0-9]+$/', $arrayKey ) && !in_array( $option,
00857 array( 'parse', 'parseinline', 'escape', 'escapenoentities',
00858 'replaceafter', 'parsemag', 'content' ) ) ) {
00859 # A numeric index with unknown value
00860 wfWarn( "wfMsgExt called with incorrect parameter $option", 1, E_USER_WARNING );
00861 }
00862 }
00863
00864 if( in_array('content', $options, true ) ) {
00865 $forContent = true;
00866 $langCode = true;
00867 } elseif( array_key_exists('language', $options) ) {
00868 $forContent = false;
00869 $langCode = wfGetLangObj( $options['language'] );
00870 } else {
00871 $forContent = false;
00872 $langCode = false;
00873 }
00874
00875 $string = wfMsgGetKey( $key, true, $langCode, false );
00876
00877 if( !in_array('replaceafter', $options, true ) ) {
00878 $string = wfMsgReplaceArgs( $string, $args );
00879 }
00880
00881 if( in_array('parse', $options, true ) ) {
00882 $string = $wgOut->parse( $string, true, !$forContent );
00883 } elseif ( in_array('parseinline', $options, true ) ) {
00884 $string = $wgOut->parse( $string, true, !$forContent );
00885 $m = array();
00886 if( preg_match( '/^<p>(.*)\n?<\/p>\n?$/sU', $string, $m ) ) {
00887 $string = $m[1];
00888 }
00889 } elseif ( in_array('parsemag', $options, true ) ) {
00890 global $wgMessageCache;
00891 if ( isset( $wgMessageCache ) ) {
00892 $string = $wgMessageCache->transform( $string,
00893 !$forContent,
00894 is_object( $langCode ) ? $langCode : null );
00895 }
00896 }
00897
00898 if ( in_array('escape', $options, true ) ) {
00899 $string = htmlspecialchars ( $string );
00900 } elseif ( in_array( 'escapenoentities', $options, true ) ) {
00901 $string = Sanitizer::escapeHtmlAllowEntities( $string );
00902 }
00903
00904 if( in_array('replaceafter', $options, true ) ) {
00905 $string = wfMsgReplaceArgs( $string, $args );
00906 }
00907
00908 return $string;
00909 }
00910
00911
00918 function wfAbruptExit( $error = false ){
00919 static $called = false;
00920 if ( $called ){
00921 exit( -1 );
00922 }
00923 $called = true;
00924
00925 $bt = wfDebugBacktrace();
00926 if( $bt ) {
00927 for($i = 0; $i < count($bt) ; $i++){
00928 $file = isset($bt[$i]['file']) ? $bt[$i]['file'] : "unknown";
00929 $line = isset($bt[$i]['line']) ? $bt[$i]['line'] : "unknown";
00930 wfDebug("WARNING: Abrupt exit in $file at line $line\n");
00931 }
00932 } else {
00933 wfDebug("WARNING: Abrupt exit\n");
00934 }
00935
00936 wfLogProfilingData();
00937
00938 if ( !$error ) {
00939 wfGetLB()->closeAll();
00940 }
00941 exit( -1 );
00942 }
00943
00947 function wfErrorExit() {
00948 wfAbruptExit( true );
00949 }
00950
00956 function wfDie( $msg='' ) {
00957 echo $msg;
00958 die( 1 );
00959 }
00960
00967 function wfDebugDieBacktrace( $msg = '' ) {
00968 throw new MWException( $msg );
00969 }
00970
00977 function wfHostname() {
00978 static $host;
00979 if ( is_null( $host ) ) {
00980 if ( function_exists( 'posix_uname' ) ) {
00981
00982 $uname = @posix_uname();
00983 } else {
00984 $uname = false;
00985 }
00986 if( is_array( $uname ) && isset( $uname['nodename'] ) ) {
00987 $host = $uname['nodename'];
00988 } elseif ( getenv( 'COMPUTERNAME' ) ) {
00989 # Windows computer name
00990 $host = getenv( 'COMPUTERNAME' );
00991 } else {
00992 # This may be a virtual server.
00993 $host = $_SERVER['SERVER_NAME'];
00994 }
00995 }
00996 return $host;
00997 }
00998
01004 function wfReportTime() {
01005 global $wgRequestTime, $wgShowHostnames;
01006
01007 $now = wfTime();
01008 $elapsed = $now - $wgRequestTime;
01009
01010 return $wgShowHostnames
01011 ? sprintf( "<!-- Served by %s in %01.3f secs. -->", wfHostname(), $elapsed )
01012 : sprintf( "<!-- Served in %01.3f secs. -->", $elapsed );
01013 }
01014
01028 function wfDebugBacktrace() {
01029 static $disabled = null;
01030
01031 if( extension_loaded( 'Zend Optimizer' ) ) {
01032 wfDebug( "Zend Optimizer detected; skipping debug_backtrace for safety.\n" );
01033 return array();
01034 }
01035
01036 if ( is_null( $disabled ) ) {
01037 $disabled = false;
01038 $functions = explode( ',', ini_get( 'disable_functions' ) );
01039 $functions = array_map( 'trim', $functions );
01040 $functions = array_map( 'strtolower', $functions );
01041 if ( in_array( 'debug_backtrace', $functions ) ) {
01042 wfDebug( "debug_backtrace is in disabled_functions\n" );
01043 $disabled = true;
01044 }
01045 }
01046 if ( $disabled ) {
01047 return array();
01048 }
01049
01050 return array_slice( debug_backtrace(), 1 );
01051 }
01052
01053 function wfBacktrace() {
01054 global $wgCommandLineMode;
01055
01056 if ( $wgCommandLineMode ) {
01057 $msg = '';
01058 } else {
01059 $msg = "<ul>\n";
01060 }
01061 $backtrace = wfDebugBacktrace();
01062 foreach( $backtrace as $call ) {
01063 if( isset( $call['file'] ) ) {
01064 $f = explode( DIRECTORY_SEPARATOR, $call['file'] );
01065 $file = $f[count($f)-1];
01066 } else {
01067 $file = '-';
01068 }
01069 if( isset( $call['line'] ) ) {
01070 $line = $call['line'];
01071 } else {
01072 $line = '-';
01073 }
01074 if ( $wgCommandLineMode ) {
01075 $msg .= "$file line $line calls ";
01076 } else {
01077 $msg .= '<li>' . $file . ' line ' . $line . ' calls ';
01078 }
01079 if( !empty( $call['class'] ) ) $msg .= $call['class'] . '::';
01080 $msg .= $call['function'] . '()';
01081
01082 if ( $wgCommandLineMode ) {
01083 $msg .= "\n";
01084 } else {
01085 $msg .= "</li>\n";
01086 }
01087 }
01088 if ( $wgCommandLineMode ) {
01089 $msg .= "\n";
01090 } else {
01091 $msg .= "</ul>\n";
01092 }
01093
01094 return $msg;
01095 }
01096
01097
01098
01099
01100
01104 function wfShowingResults( $offset, $limit ) {
01105 global $wgLang;
01106 return wfMsgExt( 'showingresults', array( 'parseinline' ), $wgLang->formatNum( $limit ),
01107 $wgLang->formatNum( $offset+1 ) );
01108 }
01109
01113 function wfShowingResultsNum( $offset, $limit, $num ) {
01114 global $wgLang;
01115 return wfMsgExt( 'showingresultsnum', array( 'parseinline' ), $wgLang->formatNum( $limit ),
01116 $wgLang->formatNum( $offset+1 ), $wgLang->formatNum( $num ) );
01117 }
01118
01127 function wfViewPrevNext( $offset, $limit, $link, $query = '', $atend = false ) {
01128 global $wgLang;
01129 $fmtLimit = $wgLang->formatNum( $limit );
01130
01131 # Get prev/next link display text
01132 $prev = wfMsgExt( 'prevn', array('parsemag','escape'), $fmtLimit );
01133 $next = wfMsgExt( 'nextn', array('parsemag','escape'), $fmtLimit );
01134 # Get prev/next link title text
01135 $pTitle = wfMsgExt( 'prevn-title', array('parsemag','escape'), $fmtLimit );
01136 $nTitle = wfMsgExt( 'nextn-title', array('parsemag','escape'), $fmtLimit );
01137 # Fetch the title object
01138 if( is_object( $link ) ) {
01139 $title =& $link;
01140 } else {
01141 $title = Title::newFromText( $link );
01142 if( is_null( $title ) ) {
01143 return false;
01144 }
01145 }
01146 # Make 'previous' link
01147 if( 0 != $offset ) {
01148 $po = $offset - $limit;
01149 $po = max($po,0);
01150 $q = "limit={$limit}&offset={$po}";
01151 if( $query != '' ) {
01152 $q .= '&'.$query;
01153 }
01154 $plink = '<a href="' . $title->escapeLocalUrl( $q ) . "\" title=\"{$pTitle}\" class=\"mw-prevlink\">{$prev}</a>";
01155 } else {
01156 $plink = $prev;
01157 }
01158 # Make 'next' link
01159 $no = $offset + $limit;
01160 $q = "limit={$limit}&offset={$no}";
01161 if( $query != '' ) {
01162 $q .= '&'.$query;
01163 }
01164 if( $atend ) {
01165 $nlink = $next;
01166 } else {
01167 $nlink = '<a href="' . $title->escapeLocalUrl( $q ) . "\" title=\"{$nTitle}\" class=\"mw-nextlink\">{$next}</a>";
01168 }
01169 # Make links to set number of items per page
01170 $nums = $wgLang->pipeList( array(
01171 wfNumLink( $offset, 20, $title, $query ),
01172 wfNumLink( $offset, 50, $title, $query ),
01173 wfNumLink( $offset, 100, $title, $query ),
01174 wfNumLink( $offset, 250, $title, $query ),
01175 wfNumLink( $offset, 500, $title, $query )
01176 ) );
01177 return wfMsgHtml( 'viewprevnext', $plink, $nlink, $nums );
01178 }
01179
01187 function wfNumLink( $offset, $limit, $title, $query = '' ) {
01188 global $wgLang;
01189 if( $query == '' ) {
01190 $q = '';
01191 } else {
01192 $q = $query.'&';
01193 }
01194 $q .= "limit={$limit}&offset={$offset}";
01195 $fmtLimit = $wgLang->formatNum( $limit );
01196 $lTitle = wfMsgExt('shown-title',array('parsemag','escape'),$limit);
01197 $s = '<a href="' . $title->escapeLocalUrl( $q ) . "\" title=\"{$lTitle}\" class=\"mw-numlink\">{$fmtLimit}</a>";
01198 return $s;
01199 }
01200
01207 function wfClientAcceptsGzip() {
01208 if( isset( $_SERVER['HTTP_ACCEPT_ENCODING'] ) ) {
01209 # FIXME: we may want to blacklist some broken browsers
01210 $m = array();
01211 if( preg_match(
01212 '/\bgzip(?:;(q)=([0-9]+(?:\.[0-9]+)))?\b/',
01213 $_SERVER['HTTP_ACCEPT_ENCODING'],
01214 $m ) ) {
01215 if( isset( $m[2] ) && ( $m[1] == 'q' ) && ( $m[2] == 0 ) ) return false;
01216 wfDebug( " accepts gzip\n" );
01217 return true;
01218 }
01219 }
01220 return false;
01221 }
01222
01232 function wfCheckLimits( $deflimit = 50, $optionname = 'rclimit' ) {
01233 global $wgRequest;
01234 return $wgRequest->getLimitOffset( $deflimit, $optionname );
01235 }
01236
01247 function wfEscapeWikiText( $text ) {
01248 $text = str_replace(
01249 array( '[', '|', ']', '\'', 'ISBN ', 'RFC ', '://', "\n=", '{{' ), # }}
01250 array( '[', '|', ']', ''', 'ISBN ', 'RFC ', '://', "\n=", '{{' ),
01251 htmlspecialchars($text) );
01252 return $text;
01253 }
01254
01258 function wfQuotedPrintable( $string, $charset = '' ) {
01259 # Probably incomplete; see RFC 2045
01260 if( empty( $charset ) ) {
01261 global $wgInputEncoding;
01262 $charset = $wgInputEncoding;
01263 }
01264 $charset = strtoupper( $charset );
01265 $charset = str_replace( 'ISO-8859', 'ISO8859', $charset );
01266
01267 $illegal = '\x00-\x08\x0b\x0c\x0e-\x1f\x7f-\xff=';
01268 $replace = $illegal . '\t ?_';
01269 if( !preg_match( "/[$illegal]/", $string ) ) return $string;
01270 $out = "=?$charset?Q?";
01271 $out .= preg_replace( "/([$replace])/e", 'sprintf("=%02X",ord("$1"))', $string );
01272 $out .= '?=';
01273 return $out;
01274 }
01275
01276
01281 function wfTime() {
01282 return microtime(true);
01283 }
01284
01289 function wfSetVar( &$dest, $source ) {
01290 $temp = $dest;
01291 if ( !is_null( $source ) ) {
01292 $dest = $source;
01293 }
01294 return $temp;
01295 }
01296
01300 function wfSetBit( &$dest, $bit, $state = true ) {
01301 $temp = (bool)($dest & $bit );
01302 if ( !is_null( $state ) ) {
01303 if ( $state ) {
01304 $dest |= $bit;
01305 } else {
01306 $dest &= ~$bit;
01307 }
01308 }
01309 return $temp;
01310 }
01311
01317 function wfArrayToCGI( $array1, $array2 = null )
01318 {
01319 if ( !is_null( $array2 ) ) {
01320 $array1 = $array1 + $array2;
01321 }
01322
01323 $cgi = '';
01324 foreach ( $array1 as $key => $value ) {
01325 if ( $value !== '' ) {
01326 if ( $cgi != '' ) {
01327 $cgi .= '&';
01328 }
01329 if ( is_array( $value ) ) {
01330 $firstTime = true;
01331 foreach ( $value as $v ) {
01332 $cgi .= ( $firstTime ? '' : '&') .
01333 urlencode( $key . '[]' ) . '=' .
01334 urlencode( $v );
01335 $firstTime = false;
01336 }
01337 } else {
01338 if ( is_object( $value ) ) {
01339 $value = $value->__toString();
01340 }
01341 $cgi .= urlencode( $key ) . '=' .
01342 urlencode( $value );
01343 }
01344 }
01345 }
01346 return $cgi;
01347 }
01348
01359 function wfCgiToArray( $query ) {
01360 if( isset( $query[0] ) and $query[0] == '?' ) {
01361 $query = substr( $query, 1 );
01362 }
01363 $bits = explode( '&', $query );
01364 $ret = array();
01365 foreach( $bits as $bit ) {
01366 if( $bit === '' ) {
01367 continue;
01368 }
01369 list( $key, $value ) = explode( '=', $bit );
01370 $key = urldecode( $key );
01371 $value = urldecode( $value );
01372 $ret[$key] = $value;
01373 }
01374 return $ret;
01375 }
01376
01385 function wfAppendQuery( $url, $query ) {
01386 if ( is_array( $query ) ) {
01387 $query = wfArrayToCGI( $query );
01388 }
01389 if( $query != '' ) {
01390 if( false === strpos( $url, '?' ) ) {
01391 $url .= '?';
01392 } else {
01393 $url .= '&';
01394 }
01395 $url .= $query;
01396 }
01397 return $url;
01398 }
01399
01410 function wfExpandUrl( $url ) {
01411 if( substr( $url, 0, 1 ) == '/' ) {
01412 global $wgServer;
01413 return $wgServer . $url;
01414 } else {
01415 return $url;
01416 }
01417 }
01418
01423 function wfPurgeSquidServers ($urlArr) {
01424 SquidUpdate::purge( $urlArr );
01425 }
01426
01435 function wfEscapeShellArg( ) {
01436 wfInitShellLocale();
01437
01438 $args = func_get_args();
01439 $first = true;
01440 $retVal = '';
01441 foreach ( $args as $arg ) {
01442 if ( !$first ) {
01443 $retVal .= ' ';
01444 } else {
01445 $first = false;
01446 }
01447
01448 if ( wfIsWindows() ) {
01449
01450
01451
01452 $tokens = preg_split( '/(\\\\*")/', $arg, -1, PREG_SPLIT_DELIM_CAPTURE );
01453 $arg = '';
01454 $delim = false;
01455 foreach ( $tokens as $token ) {
01456 if ( $delim ) {
01457 $arg .= str_replace( '\\', '\\\\', substr( $token, 0, -1 ) ) . '\\"';
01458 } else {
01459 $arg .= $token;
01460 }
01461 $delim = !$delim;
01462 }
01463
01464
01465 $m = array();
01466 if ( preg_match( '/^(.*?)(\\\\+)$/', $arg, $m ) ) {
01467 $arg = $m[1] . str_replace( '\\', '\\\\', $m[2] );
01468 }
01469
01470
01471 $retVal .= '"' . $arg . '"';
01472 } else {
01473 $retVal .= escapeshellarg( $arg );
01474 }
01475 }
01476 return $retVal;
01477 }
01478
01483 function wfMerge( $old, $mine, $yours, &$result ){
01484 global $wgDiff3;
01485
01486 # This check may also protect against code injection in
01487 # case of broken installations.
01488 if( !$wgDiff3 || !file_exists( $wgDiff3 ) ) {
01489 wfDebug( "diff3 not found\n" );
01490 return false;
01491 }
01492
01493 # Make temporary files
01494 $td = wfTempDir();
01495 $oldtextFile = fopen( $oldtextName = tempnam( $td, 'merge-old-' ), 'w' );
01496 $mytextFile = fopen( $mytextName = tempnam( $td, 'merge-mine-' ), 'w' );
01497 $yourtextFile = fopen( $yourtextName = tempnam( $td, 'merge-your-' ), 'w' );
01498
01499 fwrite( $oldtextFile, $old ); fclose( $oldtextFile );
01500 fwrite( $mytextFile, $mine ); fclose( $mytextFile );
01501 fwrite( $yourtextFile, $yours ); fclose( $yourtextFile );
01502
01503 # Check for a conflict
01504 $cmd = $wgDiff3 . ' -a --overlap-only ' .
01505 wfEscapeShellArg( $mytextName ) . ' ' .
01506 wfEscapeShellArg( $oldtextName ) . ' ' .
01507 wfEscapeShellArg( $yourtextName );
01508 $handle = popen( $cmd, 'r' );
01509
01510 if( fgets( $handle, 1024 ) ){
01511 $conflict = true;
01512 } else {
01513 $conflict = false;
01514 }
01515 pclose( $handle );
01516
01517 # Merge differences
01518 $cmd = $wgDiff3 . ' -a -e --merge ' .
01519 wfEscapeShellArg( $mytextName, $oldtextName, $yourtextName );
01520 $handle = popen( $cmd, 'r' );
01521 $result = '';
01522 do {
01523 $data = fread( $handle, 8192 );
01524 if ( strlen( $data ) == 0 ) {
01525 break;
01526 }
01527 $result .= $data;
01528 } while ( true );
01529 pclose( $handle );
01530 unlink( $mytextName ); unlink( $oldtextName ); unlink( $yourtextName );
01531
01532 if ( $result === '' && $old !== '' && $conflict == false ) {
01533 wfDebug( "Unexpected null result from diff3. Command: $cmd\n" );
01534 $conflict = true;
01535 }
01536 return ! $conflict;
01537 }
01538
01547 function wfDiff( $before, $after, $params = '-u' ) {
01548 if ($before == $after) {
01549 return '';
01550 }
01551
01552 global $wgDiff;
01553
01554 # This check may also protect against code injection in
01555 # case of broken installations.
01556 if( !file_exists( $wgDiff ) ){
01557 wfDebug( "diff executable not found\n" );
01558 $diffs = new Diff( explode( "\n", $before ), explode( "\n", $after ) );
01559 $format = new UnifiedDiffFormatter();
01560 return $format->format( $diffs );
01561 }
01562
01563 # Make temporary files
01564 $td = wfTempDir();
01565 $oldtextFile = fopen( $oldtextName = tempnam( $td, 'merge-old-' ), 'w' );
01566 $newtextFile = fopen( $newtextName = tempnam( $td, 'merge-your-' ), 'w' );
01567
01568 fwrite( $oldtextFile, $before ); fclose( $oldtextFile );
01569 fwrite( $newtextFile, $after ); fclose( $newtextFile );
01570
01571
01572 $cmd = "$wgDiff " . $params . ' ' .wfEscapeShellArg( $oldtextName, $newtextName );
01573
01574 $h = popen( $cmd, 'r' );
01575
01576 $diff = '';
01577
01578 do {
01579 $data = fread( $h, 8192 );
01580 if ( strlen( $data ) == 0 ) {
01581 break;
01582 }
01583 $diff .= $data;
01584 } while ( true );
01585
01586
01587 pclose( $h );
01588 unlink( $oldtextName );
01589 unlink( $newtextName );
01590
01591
01592 $diff_lines = explode( "\n", $diff );
01593 if (strpos( $diff_lines[0], '---' ) === 0) {
01594 unset($diff_lines[0]);
01595 }
01596 if (strpos( $diff_lines[1], '+++' ) === 0) {
01597 unset($diff_lines[1]);
01598 }
01599
01600 $diff = implode( "\n", $diff_lines );
01601
01602 return $diff;
01603 }
01604
01611 function wfVarDump( $var ) {
01612 global $wgOut;
01613 $s = str_replace("\n","<br />\n", var_export( $var, true ) . "\n");
01614 if ( headers_sent() || !@is_object( $wgOut ) ) {
01615 print $s;
01616 } else {
01617 $wgOut->addHTML( $s );
01618 }
01619 }
01620
01624 function wfHttpError( $code, $label, $desc ) {
01625 global $wgOut;
01626 $wgOut->disable();
01627 header( "HTTP/1.0 $code $label" );
01628 header( "Status: $code $label" );
01629 $wgOut->sendCacheControl();
01630
01631 header( 'Content-type: text/html; charset=utf-8' );
01632 print "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">".
01633 "<html><head><title>" .
01634 htmlspecialchars( $label ) .
01635 "</title></head><body><h1>" .
01636 htmlspecialchars( $label ) .
01637 "</h1><p>" .
01638 nl2br( htmlspecialchars( $desc ) ) .
01639 "</p></body></html>\n";
01640 }
01641
01659 function wfResetOutputBuffers( $resetGzipEncoding=true ) {
01660 if( $resetGzipEncoding ) {
01661
01662
01663 global $wgDisableOutputCompression;
01664 $wgDisableOutputCompression = true;
01665 }
01666 while( $status = ob_get_status() ) {
01667 if( $status['type'] == 0 ) {
01668
01669
01670
01671
01672
01673 break;
01674 }
01675 if( !ob_end_clean() ) {
01676
01677
01678 break;
01679 }
01680 if( $resetGzipEncoding ) {
01681 if( $status['name'] == 'ob_gzhandler' ) {
01682
01683
01684 header( 'Content-Encoding:' );
01685 break;
01686 }
01687 }
01688 }
01689 }
01690
01703 function wfClearOutputBuffers() {
01704 wfResetOutputBuffers( false );
01705 }
01706
01711 function wfAcceptToPrefs( $accept, $def = '*/*' ) {
01712 # No arg means accept anything (per HTTP spec)
01713 if( !$accept ) {
01714 return array( $def => 1.0 );
01715 }
01716
01717 $prefs = array();
01718
01719 $parts = explode( ',', $accept );
01720
01721 foreach( $parts as $part ) {
01722 # FIXME: doesn't deal with params like 'text/html; level=1'
01723 @list( $value, $qpart ) = explode( ';', trim( $part ) );
01724 $match = array();
01725 if( !isset( $qpart ) ) {
01726 $prefs[$value] = 1.0;
01727 } elseif( preg_match( '/q\s*=\s*(\d*\.\d+)/', $qpart, $match ) ) {
01728 $prefs[$value] = floatval($match[1]);
01729 }
01730 }
01731
01732 return $prefs;
01733 }
01734
01747 function mimeTypeMatch( $type, $avail ) {
01748 if( array_key_exists($type, $avail) ) {
01749 return $type;
01750 } else {
01751 $parts = explode( '/', $type );
01752 if( array_key_exists( $parts[0] . '/*', $avail ) ) {
01753 return $parts[0] . '/*';
01754 } elseif( array_key_exists( '*/*', $avail ) ) {
01755 return '*/*';
01756 } else {
01757 return null;
01758 }
01759 }
01760 }
01761
01775 function wfNegotiateType( $cprefs, $sprefs ) {
01776 $combine = array();
01777
01778 foreach( array_keys($sprefs) as $type ) {
01779 $parts = explode( '/', $type );
01780 if( $parts[1] != '*' ) {
01781 $ckey = mimeTypeMatch( $type, $cprefs );
01782 if( $ckey ) {
01783 $combine[$type] = $sprefs[$type] * $cprefs[$ckey];
01784 }
01785 }
01786 }
01787
01788 foreach( array_keys( $cprefs ) as $type ) {
01789 $parts = explode( '/', $type );
01790 if( $parts[1] != '*' && !array_key_exists( $type, $sprefs ) ) {
01791 $skey = mimeTypeMatch( $type, $sprefs );
01792 if( $skey ) {
01793 $combine[$type] = $sprefs[$skey] * $cprefs[$type];
01794 }
01795 }
01796 }
01797
01798 $bestq = 0;
01799 $besttype = null;
01800
01801 foreach( array_keys( $combine ) as $type ) {
01802 if( $combine[$type] > $bestq ) {
01803 $besttype = $type;
01804 $bestq = $combine[$type];
01805 }
01806 }
01807
01808 return $besttype;
01809 }
01810
01818 function wfArrayLookup( $a, $b ) {
01819 return array_flip( array_intersect( array_flip( $a ), array_keys( $b ) ) );
01820 }
01821
01826 function wfTimestampNow() {
01827 # return NOW
01828 return wfTimestamp( TS_MW, time() );
01829 }
01830
01834 function wfSuppressWarnings( $end = false ) {
01835 static $suppressCount = 0;
01836 static $originalLevel = false;
01837
01838 if ( $end ) {
01839 if ( $suppressCount ) {
01840 --$suppressCount;
01841 if ( !$suppressCount ) {
01842 error_reporting( $originalLevel );
01843 }
01844 }
01845 } else {
01846 if ( !$suppressCount ) {
01847 $originalLevel = error_reporting( E_ALL & ~( E_WARNING | E_NOTICE ) );
01848 }
01849 ++$suppressCount;
01850 }
01851 }
01852
01856 function wfRestoreWarnings() {
01857 wfSuppressWarnings( true );
01858 }
01859
01860 # Autodetect, convert and provide timestamps of various types
01861
01865 define('TS_UNIX', 0);
01866
01870 define('TS_MW', 1);
01871
01875 define('TS_DB', 2);
01876
01880 define('TS_RFC2822', 3);
01881
01887 define('TS_ISO_8601', 4);
01888
01896 define('TS_EXIF', 5);
01897
01901 define('TS_ORACLE', 6);
01902
01906 define('TS_POSTGRES', 7);
01907
01911 define('TS_DB2', 8);
01912
01920 function wfTimestamp( $outputtype = TS_UNIX, $ts = 0 ) {
01921 $uts = 0;
01922 $da = array();
01923 if ($ts==0) {
01924 $uts=time();
01925 } elseif (preg_match('/^(\d{4})\-(\d\d)\-(\d\d) (\d\d):(\d\d):(\d\d)$/D',$ts,$da)) {
01926 # TS_DB
01927 } elseif (preg_match('/^(\d{4}):(\d\d):(\d\d) (\d\d):(\d\d):(\d\d)$/D',$ts,$da)) {
01928 # TS_EXIF
01929 } elseif (preg_match('/^(\d{4})(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)$/D',$ts,$da)) {
01930 # TS_MW
01931 } elseif (preg_match('/^\d{1,13}$/D',$ts)) {
01932 # TS_UNIX
01933 $uts = $ts;
01934 } elseif (preg_match('/^\d{2}-\d{2}-\d{4} \d{2}:\d{2}:\d{2}.\d{6}$/', $ts)) {
01935 # TS_ORACLE // session altered to DD-MM-YYYY HH24:MI:SS.FF6
01936 $uts = strtotime(preg_replace('/(\d\d)\.(\d\d)\.(\d\d)(\.(\d+))?/', "$1:$2:$3",
01937 str_replace("+00:00", "UTC", $ts)));
01938 } elseif (preg_match('/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.*\d*)?Z$/', $ts, $da)) {
01939 # TS_ISO_8601
01940 } elseif (preg_match('/^(\d{4})\-(\d\d)\-(\d\d) (\d\d):(\d\d):(\d\d)\.*\d*[\+\- ](\d\d)$/',$ts,$da)) {
01941 # TS_POSTGRES
01942 } elseif (preg_match('/^(\d{4})\-(\d\d)\-(\d\d) (\d\d):(\d\d):(\d\d)\.*\d* GMT$/',$ts,$da)) {
01943 # TS_POSTGRES
01944 } else {
01945 # Bogus value; fall back to the epoch...
01946 wfDebug("wfTimestamp() fed bogus time value: $outputtype; $ts\n");
01947 $uts = 0;
01948 }
01949
01950 if (count( $da ) ) {
01951
01952
01953 $uts=gmmktime((int)$da[4],(int)$da[5],(int)$da[6],
01954 (int)$da[2],(int)$da[3],(int)$da[1]);
01955 }
01956
01957 switch($outputtype) {
01958 case TS_UNIX:
01959 return $uts;
01960 case TS_MW:
01961 return gmdate( 'YmdHis', $uts );
01962 case TS_DB:
01963 return gmdate( 'Y-m-d H:i:s', $uts );
01964 case TS_ISO_8601:
01965 return gmdate( 'Y-m-d\TH:i:s\Z', $uts );
01966
01967 case TS_EXIF:
01968 return gmdate( 'Y:m:d H:i:s', $uts );
01969 case TS_RFC2822:
01970 return gmdate( 'D, d M Y H:i:s', $uts ) . ' GMT';
01971 case TS_ORACLE:
01972 return gmdate( 'd-m-Y H:i:s.000000', $uts);
01973
01974 case TS_POSTGRES:
01975 return gmdate( 'Y-m-d H:i:s', $uts) . ' GMT';
01976 case TS_DB2:
01977 return gmdate( 'Y-m-d H:i:s', $uts);
01978 default:
01979 throw new MWException( 'wfTimestamp() called with illegal output type.');
01980 }
01981 }
01982
01990 function wfTimestampOrNull( $outputtype = TS_UNIX, $ts = null ) {
01991 if( is_null( $ts ) ) {
01992 return null;
01993 } else {
01994 return wfTimestamp( $outputtype, $ts );
01995 }
01996 }
01997
02003 function wfIsWindows() {
02004 if (substr(php_uname(), 0, 7) == 'Windows') {
02005 return true;
02006 } else {
02007 return false;
02008 }
02009 }
02010
02014 function swap( &$x, &$y ) {
02015 $z = $x;
02016 $x = $y;
02017 $y = $z;
02018 }
02019
02020 function wfGetCachedNotice( $name ) {
02021 global $wgOut, $wgRenderHashAppend, $parserMemc;
02022 $fname = 'wfGetCachedNotice';
02023 wfProfileIn( $fname );
02024
02025 $needParse = false;
02026
02027 if( $name === 'default' ) {
02028
02029 global $wgSiteNotice;
02030 $notice = $wgSiteNotice;
02031 if( empty( $notice ) ) {
02032 wfProfileOut( $fname );
02033 return false;
02034 }
02035 } else {
02036 $notice = wfMsgForContentNoTrans( $name );
02037 if( wfEmptyMsg( $name, $notice ) || $notice == '-' ) {
02038 wfProfileOut( $fname );
02039 return( false );
02040 }
02041 }
02042
02043
02044 $key = wfMemcKey( $name . $wgRenderHashAppend );
02045 $cachedNotice = $parserMemc->get( $key );
02046 if( is_array( $cachedNotice ) ) {
02047 if( md5( $notice ) == $cachedNotice['hash'] ) {
02048 $notice = $cachedNotice['html'];
02049 } else {
02050 $needParse = true;
02051 }
02052 } else {
02053 $needParse = true;
02054 }
02055
02056 if( $needParse ) {
02057 if( is_object( $wgOut ) ) {
02058 $parsed = $wgOut->parse( $notice );
02059 $parserMemc->set( $key, array( 'html' => $parsed, 'hash' => md5( $notice ) ), 600 );
02060 $notice = $parsed;
02061 } else {
02062 wfDebug( 'wfGetCachedNotice called for ' . $name . ' with no $wgOut available'."\n" );
02063 $notice = '';
02064 }
02065 }
02066
02067 wfProfileOut( $fname );
02068 return $notice;
02069 }
02070
02071 function wfGetNamespaceNotice() {
02072 global $wgTitle;
02073
02074 # Paranoia
02075 if ( !isset( $wgTitle ) || !is_object( $wgTitle ) )
02076 return "";
02077
02078 $fname = 'wfGetNamespaceNotice';
02079 wfProfileIn( $fname );
02080
02081 $key = "namespacenotice-" . $wgTitle->getNsText();
02082 $namespaceNotice = wfGetCachedNotice( $key );
02083 if ( $namespaceNotice && substr ( $namespaceNotice , 0 ,7 ) != "<p><" ) {
02084 $namespaceNotice = '<div id="namespacebanner">' . $namespaceNotice . "</div>";
02085 } else {
02086 $namespaceNotice = "";
02087 }
02088
02089 wfProfileOut( $fname );
02090 return $namespaceNotice;
02091 }
02092
02093 function wfGetSiteNotice() {
02094 global $wgUser, $wgSiteNotice;
02095 $fname = 'wfGetSiteNotice';
02096 wfProfileIn( $fname );
02097 $siteNotice = '';
02098
02099 if( wfRunHooks( 'SiteNoticeBefore', array( &$siteNotice ) ) ) {
02100 if( is_object( $wgUser ) && $wgUser->isLoggedIn() ) {
02101 $siteNotice = wfGetCachedNotice( 'sitenotice' );
02102 } else {
02103 $anonNotice = wfGetCachedNotice( 'anonnotice' );
02104 if( !$anonNotice ) {
02105 $siteNotice = wfGetCachedNotice( 'sitenotice' );
02106 } else {
02107 $siteNotice = $anonNotice;
02108 }
02109 }
02110 if( !$siteNotice ) {
02111 $siteNotice = wfGetCachedNotice( 'default' );
02112 }
02113 }
02114
02115 wfRunHooks( 'SiteNoticeAfter', array( &$siteNotice ) );
02116 wfProfileOut( $fname );
02117 return $siteNotice;
02118 }
02119
02124 function &wfGetMimeMagic() {
02125 return MimeMagic::singleton();
02126 }
02127
02139 function wfTempDir() {
02140 if( function_exists( 'sys_get_temp_dir' ) ) {
02141 return sys_get_temp_dir();
02142 }
02143 foreach( array( 'TMPDIR', 'TMP', 'TEMP' ) as $var ) {
02144 $tmp = getenv( $var );
02145 if( $tmp && file_exists( $tmp ) && is_dir( $tmp ) && is_writable( $tmp ) ) {
02146 return $tmp;
02147 }
02148 }
02149 # Hope this is Unix of some kind!
02150 return '/tmp';
02151 }
02152
02161 function wfMkdirParents( $dir, $mode = null, $caller = null ) {
02162 global $wgDirectoryMode;
02163
02164 if ( !is_null( $caller ) ) {
02165 wfDebug( "$caller: called wfMkdirParents($dir)" );
02166 }
02167
02168 if( strval( $dir ) === '' || file_exists( $dir ) )
02169 return true;
02170
02171 $dir = str_replace( array( '\\', '/' ), DIRECTORY_SEPARATOR, $dir );
02172
02173 if ( is_null( $mode ) )
02174 $mode = $wgDirectoryMode;
02175
02176 $ok = mkdir( $dir, $mode, true );
02177 if( !$ok ) {
02178
02179 trigger_error( __FUNCTION__ . ": failed to mkdir \"$dir\" mode $mode", E_USER_WARNING );
02180 }
02181 return $ok;
02182 }
02183
02187 function wfIncrStats( $key ) {
02188 global $wgStatsMethod;
02189
02190 if( $wgStatsMethod == 'udp' ) {
02191 global $wgUDPProfilerHost, $wgUDPProfilerPort, $wgDBname;
02192 static $socket;
02193 if (!$socket) {
02194 $socket=socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
02195 $statline="stats/{$wgDBname} - 1 1 1 1 1 -total\n";
02196 socket_sendto($socket,$statline,strlen($statline),0,$wgUDPProfilerHost,$wgUDPProfilerPort);
02197 }
02198 $statline="stats/{$wgDBname} - 1 1 1 1 1 {$key}\n";
02199 @socket_sendto($socket,$statline,strlen($statline),0,$wgUDPProfilerHost,$wgUDPProfilerPort);
02200 } elseif( $wgStatsMethod == 'cache' ) {
02201 global $wgMemc;
02202 $key = wfMemcKey( 'stats', $key );
02203 if ( is_null( $wgMemc->incr( $key ) ) ) {
02204 $wgMemc->add( $key, 1 );
02205 }
02206 } else {
02207
02208 }
02209 }
02210
02217 function wfPercent( $nr, $acc = 2, $round = true ) {
02218 $ret = sprintf( "%.${acc}f", $nr );
02219 return $round ? round( $ret, $acc ) . '%' : "$ret%";
02220 }
02221
02230 function wfEncryptPassword( $userid, $password ) {
02231 wfDeprecated(__FUNCTION__);
02232 # Just wrap around User::oldCrypt()
02233 return User::oldCrypt($password, $userid);
02234 }
02235
02239 function wfAppendToArrayIfNotDefault( $key, $value, $default, &$changed ) {
02240 if ( is_null( $changed ) ) {
02241 throw new MWException('GlobalFunctions::wfAppendToArrayIfNotDefault got null');
02242 }
02243 if ( $default[$key] !== $value ) {
02244 $changed[$key] = $value;
02245 }
02246 }
02247
02257 function wfEmptyMsg( $msg, $wfMsgOut ) {
02258 return $wfMsgOut === htmlspecialchars( "<$msg>" );
02259 }
02260
02268 function in_string( $needle, $str ) {
02269 return strpos( $str, $needle ) !== false;
02270 }
02271
02272 function wfSpecialList( $page, $details ) {
02273 global $wgContLang;
02274 $details = $details ? ' ' . $wgContLang->getDirMark() . "($details)" : "";
02275 return $page . $details;
02276 }
02277
02283 function wfUrlProtocols() {
02284 global $wgUrlProtocols;
02285
02286 static $retval = null;
02287 if ( !is_null( $retval ) )
02288 return $retval;
02289
02290
02291
02292 if ( is_array( $wgUrlProtocols ) ) {
02293 $protocols = array();
02294 foreach ($wgUrlProtocols as $protocol)
02295 $protocols[] = preg_quote( $protocol, '/' );
02296
02297 $retval = implode( '|', $protocols );
02298 } else {
02299 $retval = $wgUrlProtocols;
02300 }
02301 return $retval;
02302 }
02303
02327 function wfIniGetBool( $setting ) {
02328 $val = ini_get( $setting );
02329
02330 return strtolower( $val ) == 'on'
02331 || strtolower( $val ) == 'true'
02332 || strtolower( $val ) == 'yes'
02333 || preg_match( "/^\s*[+-]?0*[1-9]/", $val );
02334 }
02335
02344 function wfShellExec( $cmd, &$retval=null ) {
02345 global $IP, $wgMaxShellMemory, $wgMaxShellFileSize, $wgMaxShellTime;
02346
02347 static $disabled;
02348 if ( is_null( $disabled ) ) {
02349 $disabled = false;
02350 if( wfIniGetBool( 'safe_mode' ) ) {
02351 wfDebug( "wfShellExec can't run in safe_mode, PHP's exec functions are too broken.\n" );
02352 $disabled = true;
02353 }
02354 $functions = explode( ',', ini_get( 'disable_functions' ) );
02355 $functions = array_map( 'trim', $functions );
02356 $functions = array_map( 'strtolower', $functions );
02357 if ( in_array( 'passthru', $functions ) ) {
02358 wfDebug( "passthru is in disabled_functions\n" );
02359 $disabled = true;
02360 }
02361 }
02362 if ( $disabled ) {
02363 $retval = 1;
02364 return "Unable to run external programs in safe mode.";
02365 }
02366
02367 wfInitShellLocale();
02368
02369 if ( php_uname( 's' ) == 'Linux' ) {
02370 $time = intval( $wgMaxShellTime );
02371 $mem = intval( $wgMaxShellMemory );
02372 $filesize = intval( $wgMaxShellFileSize );
02373
02374 if ( $time > 0 && $mem > 0 ) {
02375 $script = "$IP/bin/ulimit4.sh";
02376 if ( is_executable( $script ) ) {
02377 $cmd = escapeshellarg( $script ) . " $time $mem $filesize " . escapeshellarg( $cmd );
02378 }
02379 }
02380 } elseif ( php_uname( 's' ) == 'Windows NT' &&
02381 version_compare( PHP_VERSION, '5.3.0', '<' ) )
02382 {
02383 # This is a hack to work around PHP's flawed invocation of cmd.exe
02384 # http://news.php.net/php.internals/21796
02385 # Which is fixed in 5.3.0 :)
02386 $cmd = '"' . $cmd . '"';
02387 }
02388 wfDebug( "wfShellExec: $cmd\n" );
02389
02390 $retval = 1;
02391 ob_start();
02392 passthru( $cmd, $retval );
02393 $output = ob_get_contents();
02394 ob_end_clean();
02395
02396 if ( $retval == 127 ) {
02397 wfDebugLog( 'exec', "Possibly missing executable file: $cmd\n" );
02398 }
02399 return $output;
02400 }
02401
02406 function wfInitShellLocale() {
02407 static $done = false;
02408 if ( $done ) return;
02409 $done = true;
02410 global $wgShellLocale;
02411 if ( !wfIniGetBool( 'safe_mode' ) ) {
02412 putenv( "LC_CTYPE=$wgShellLocale" );
02413 setlocale( LC_CTYPE, $wgShellLocale );
02414 }
02415 }
02416
02432 function wfUsePHP( $req_ver ) {
02433 $php_ver = PHP_VERSION;
02434
02435 if ( version_compare( $php_ver, (string)$req_ver, '<' ) )
02436 throw new MWException( "PHP $req_ver required--this is only $php_ver" );
02437 }
02438
02452 function wfUseMW( $req_ver ) {
02453 global $wgVersion;
02454
02455 if ( version_compare( $wgVersion, (string)$req_ver, '<' ) )
02456 throw new MWException( "MediaWiki $req_ver required--this is only $wgVersion" );
02457 }
02458
02462 function wfRegexReplacement( $string ) {
02463 return StringUtils::escapeRegexReplacement( $string );
02464 }
02465
02478 function wfBaseName( $path, $suffix='' ) {
02479 $encSuffix = ($suffix == '')
02480 ? ''
02481 : ( '(?:' . preg_quote( $suffix, '#' ) . ')?' );
02482 $matches = array();
02483 if( preg_match( "#([^/\\\\]*?){$encSuffix}[/\\\\]*$#", $path, $matches ) ) {
02484 return $matches[1];
02485 } else {
02486 return '';
02487 }
02488 }
02489
02499 function wfRelativePath( $path, $from ) {
02500
02501 $path = str_replace( '/', DIRECTORY_SEPARATOR, $path );
02502 $from = str_replace( '/', DIRECTORY_SEPARATOR, $from );
02503
02504
02505 $path = rtrim( $path, DIRECTORY_SEPARATOR );
02506 $from = rtrim( $from, DIRECTORY_SEPARATOR );
02507
02508 $pieces = explode( DIRECTORY_SEPARATOR, dirname( $path ) );
02509 $against = explode( DIRECTORY_SEPARATOR, $from );
02510
02511 if( $pieces[0] !== $against[0] ) {
02512
02513
02514 return $path;
02515 }
02516
02517
02518 while( count( $pieces ) && count( $against )
02519 && $pieces[0] == $against[0] ) {
02520 array_shift( $pieces );
02521 array_shift( $against );
02522 }
02523
02524
02525 while( count( $against ) ) {
02526 array_unshift( $pieces, '..' );
02527 array_shift( $against );
02528 }
02529
02530 array_push( $pieces, wfBaseName( $path ) );
02531
02532 return implode( DIRECTORY_SEPARATOR, $pieces );
02533 }
02534
02543 function wfArrayMerge( $array1 ) {
02544 $args = func_get_args();
02545 $args = array_reverse( $args, true );
02546 $out = array();
02547 foreach ( $args as $arg ) {
02548 $out += $arg;
02549 }
02550 return $out;
02551 }
02552
02569 function wfMergeErrorArrays() {
02570 $args = func_get_args();
02571 $out = array();
02572 foreach ( $args as $errors ) {
02573 foreach ( $errors as $params ) {
02574 $spec = implode( "\t", $params );
02575 $out[$spec] = $params;
02576 }
02577 }
02578 return array_values( $out );
02579 }
02580
02591 function wfParseUrl( $url ) {
02592 global $wgUrlProtocols;
02593 wfSuppressWarnings();
02594 $bits = parse_url( $url );
02595 wfRestoreWarnings();
02596 if ( !$bits ) {
02597 return false;
02598 }
02599
02600
02601 if ( in_array( $bits['scheme'] . '://', $wgUrlProtocols ) ) {
02602 $bits['delimiter'] = '://';
02603 } elseif ( in_array( $bits['scheme'] . ':', $wgUrlProtocols ) ) {
02604 $bits['delimiter'] = ':';
02605
02606
02607 if ( isset ( $bits['path'] ) ) {
02608 $bits['host'] = $bits['path'];
02609 $bits['path'] = '';
02610 }
02611 } else {
02612 return false;
02613 }
02614
02615 return $bits;
02616 }
02617
02621 function wfMakeUrlIndex( $url ) {
02622 $bits = wfParseUrl( $url );
02623
02624
02625
02626 if ( $bits['scheme'] == 'mailto' ) {
02627 $mailparts = explode( '@', $bits['host'], 2 );
02628 if ( count($mailparts) === 2 ) {
02629 $domainpart = strtolower( implode( '.', array_reverse( explode( '.', $mailparts[1] ) ) ) );
02630 } else {
02631
02632 $domainpart = '';
02633 }
02634 $reversedHost = $domainpart . '@' . $mailparts[0];
02635 } else {
02636 $reversedHost = strtolower( implode( '.', array_reverse( explode( '.', $bits['host'] ) ) ) );
02637 }
02638
02639
02640 if ( substr( $reversedHost, -1, 1 ) !== '.' ) {
02641 $reversedHost .= '.';
02642 }
02643
02644 $prot = $bits['scheme'];
02645 $index = $prot . $bits['delimiter'] . $reversedHost;
02646
02647 if ( isset( $bits['port'] ) ) $index .= ':' . $bits['port'];
02648 if ( isset( $bits['path'] ) ) {
02649 $index .= $bits['path'];
02650 } else {
02651 $index .= '/';
02652 }
02653 if ( isset( $bits['query'] ) ) $index .= '?' . $bits['query'];
02654 if ( isset( $bits['fragment'] ) ) $index .= '#' . $bits['fragment'];
02655 return $index;
02656 }
02657
02662 function wfDoUpdates()
02663 {
02664 global $wgPostCommitUpdateList, $wgDeferredUpdateList;
02665 foreach ( $wgDeferredUpdateList as $update ) {
02666 $update->doUpdate();
02667 }
02668 foreach ( $wgPostCommitUpdateList as $update ) {
02669 $update->doUpdate();
02670 }
02671 $wgDeferredUpdateList = array();
02672 $wgPostCommitUpdateList = array();
02673 }
02674
02678 function wfExplodeMarkup( $separator, $text ) {
02679 return StringUtils::explodeMarkup( $separator, $text );
02680 }
02681
02696 function wfBaseConvert( $input, $sourceBase, $destBase, $pad=1, $lowercase=true ) {
02697 $input = strval( $input );
02698 if( $sourceBase < 2 ||
02699 $sourceBase > 36 ||
02700 $destBase < 2 ||
02701 $destBase > 36 ||
02702 $pad < 1 ||
02703 $sourceBase != intval( $sourceBase ) ||
02704 $destBase != intval( $destBase ) ||
02705 $pad != intval( $pad ) ||
02706 !is_string( $input ) ||
02707 $input == '' ) {
02708 return false;
02709 }
02710 $digitChars = ( $lowercase ) ? '0123456789abcdefghijklmnopqrstuvwxyz' : '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
02711 $inDigits = array();
02712 $outChars = '';
02713
02714
02715 $input = strtolower( $input );
02716 for( $i = 0; $i < strlen( $input ); $i++ ) {
02717 $n = strpos( $digitChars, $input{$i} );
02718 if( $n === false || $n > $sourceBase ) {
02719 return false;
02720 }
02721 $inDigits[] = $n;
02722 }
02723
02724
02725
02726 while( count( $inDigits ) ) {
02727 $work = 0;
02728 $workDigits = array();
02729
02730
02731 foreach( $inDigits as $digit ) {
02732 $work *= $sourceBase;
02733 $work += $digit;
02734
02735 if( $work < $destBase ) {
02736
02737 if( count( $workDigits ) ) {
02738
02739
02740
02741 $workDigits[] = 0;
02742 }
02743 } else {
02744
02745 $workDigits[] = intval( $work / $destBase );
02746
02747
02748
02749
02750 $work = $work % $destBase;
02751 }
02752 }
02753
02754
02755
02756 $outChars .= $digitChars[$work];
02757
02758
02759 $inDigits = $workDigits;
02760 }
02761
02762 while( strlen( $outChars ) < $pad ) {
02763 $outChars .= '0';
02764 }
02765
02766 return strrev( $outChars );
02767 }
02768
02774 function wfCreateObject( $name, $p ){
02775 $p = array_values( $p );
02776 switch ( count( $p ) ) {
02777 case 0:
02778 return new $name;
02779 case 1:
02780 return new $name( $p[0] );
02781 case 2:
02782 return new $name( $p[0], $p[1] );
02783 case 3:
02784 return new $name( $p[0], $p[1], $p[2] );
02785 case 4:
02786 return new $name( $p[0], $p[1], $p[2], $p[3] );
02787 case 5:
02788 return new $name( $p[0], $p[1], $p[2], $p[3], $p[4] );
02789 case 6:
02790 return new $name( $p[0], $p[1], $p[2], $p[3], $p[4], $p[5] );
02791 default:
02792 throw new MWException( "Too many arguments to construtor in wfCreateObject" );
02793 }
02794 }
02795
02800 function wfGetHTTP( $url ) {
02801 wfDeprecated(__FUNCTION__);
02802 return Http::get( $url );
02803 }
02804
02809 function wfIsLocalURL( $url ) {
02810 wfDeprecated(__FUNCTION__);
02811 return Http::isLocalURL( $url );
02812 }
02813
02814 function wfHttpOnlySafe() {
02815 global $wgHttpOnlyBlacklist;
02816 if( !version_compare("5.2", PHP_VERSION, "<") )
02817 return false;
02818
02819 if( isset( $_SERVER['HTTP_USER_AGENT'] ) ) {
02820 foreach( $wgHttpOnlyBlacklist as $regex ) {
02821 if( preg_match( $regex, $_SERVER['HTTP_USER_AGENT'] ) ) {
02822 return false;
02823 }
02824 }
02825 }
02826
02827 return true;
02828 }
02829
02833 function wfSetupSession() {
02834 global $wgSessionsInMemcached, $wgCookiePath, $wgCookieDomain,
02835 $wgCookieSecure, $wgCookieHttpOnly, $wgSessionHandler;
02836 if( $wgSessionsInMemcached ) {
02837 require_once( 'MemcachedSessions.php' );
02838 } elseif( $wgSessionHandler && $wgSessionHandler != ini_get( 'session.save_handler' ) ) {
02839 # Only set this if $wgSessionHandler isn't null and session.save_handler
02840 # hasn't already been set to the desired value (that causes errors)
02841 ini_set ( 'session.save_handler', $wgSessionHandler );
02842 }
02843 $httpOnlySafe = wfHttpOnlySafe();
02844 wfDebugLog( 'cookie',
02845 'session_set_cookie_params: "' . implode( '", "',
02846 array(
02847 0,
02848 $wgCookiePath,
02849 $wgCookieDomain,
02850 $wgCookieSecure,
02851 $httpOnlySafe && $wgCookieHttpOnly ) ) . '"' );
02852 if( $httpOnlySafe && $wgCookieHttpOnly ) {
02853 session_set_cookie_params( 0, $wgCookiePath, $wgCookieDomain, $wgCookieSecure, $wgCookieHttpOnly );
02854 } else {
02855
02856 session_set_cookie_params( 0, $wgCookiePath, $wgCookieDomain, $wgCookieSecure );
02857 }
02858 session_cache_limiter( 'private, must-revalidate' );
02859 wfSuppressWarnings();
02860 session_start();
02861 wfRestoreWarnings();
02862 }
02863
02869 function wfGetPrecompiledData( $name ) {
02870 global $IP;
02871
02872 $file = "$IP/serialized/$name";
02873 if ( file_exists( $file ) ) {
02874 $blob = file_get_contents( $file );
02875 if ( $blob ) {
02876 return unserialize( $blob );
02877 }
02878 }
02879 return false;
02880 }
02881
02882 function wfGetCaller( $level = 2 ) {
02883 $backtrace = wfDebugBacktrace();
02884 if ( isset( $backtrace[$level] ) ) {
02885 return wfFormatStackFrame($backtrace[$level]);
02886 } else {
02887 $caller = 'unknown';
02888 }
02889 return $caller;
02890 }
02891
02896 function wfGetAllCallers() {
02897 return implode('/', array_map('wfFormatStackFrame',array_reverse(wfDebugBacktrace())));
02898 }
02899
02903 function wfFormatStackFrame($frame) {
02904 return isset( $frame["class"] )?
02905 $frame["class"]."::".$frame["function"]:
02906 $frame["function"];
02907 }
02908
02912 function wfMemcKey( ) {
02913 $args = func_get_args();
02914 $key = wfWikiID() . ':' . implode( ':', $args );
02915 $key = str_replace( ' ', '_', $key );
02916 return $key;
02917 }
02918
02922 function wfForeignMemcKey( $db, $prefix ) {
02923 $args = array_slice( func_get_args(), 2 );
02924 if ( $prefix ) {
02925 $key = "$db-$prefix:" . implode( ':', $args );
02926 } else {
02927 $key = $db . ':' . implode( ':', $args );
02928 }
02929 return $key;
02930 }
02931
02936 function wfWikiID() {
02937 global $wgDBprefix, $wgDBname;
02938 if ( $wgDBprefix ) {
02939 return "$wgDBname-$wgDBprefix";
02940 } else {
02941 return $wgDBname;
02942 }
02943 }
02944
02948 function wfSplitWikiID( $wiki ) {
02949 $bits = explode( '-', $wiki, 2 );
02950 if ( count( $bits ) < 2 ) {
02951 $bits[] = '';
02952 }
02953 return $bits;
02954 }
02955
02956
02957
02958
02959
02960
02961
02962
02963
02964
02965
02966
02967
02968
02969
02970
02971
02972 function &wfGetDB( $db, $groups = array(), $wiki = false ) {
02973 return wfGetLB( $wiki )->getConnection( $db, $groups, $wiki );
02974 }
02975
02982 function wfGetLB( $wiki = false ) {
02983 return wfGetLBFactory()->getMainLB( $wiki );
02984 }
02985
02989 function &wfGetLBFactory() {
02990 return LBFactory::singleton();
02991 }
02992
03012 function wfFindFile( $title, $options = array() ) {
03013 return RepoGroup::singleton()->findFile( $title, $options );
03014 }
03015
03022 function wfLocalFile( $title ) {
03023 return RepoGroup::singleton()->getLocalRepo()->newFile( $title );
03024 }
03025
03031 function wfQueriesMustScale() {
03032 global $wgMiserMode;
03033 return $wgMiserMode
03034 || ( SiteStats::pages() > 100000
03035 && SiteStats::edits() > 1000000
03036 && SiteStats::users() > 10000 );
03037 }
03038
03046 function wfScript( $script = 'index' ) {
03047 global $wgScriptPath, $wgScriptExtension;
03048 return "{$wgScriptPath}/{$script}{$wgScriptExtension}";
03049 }
03055 function wfGetScriptUrl(){
03056 if( isset( $_SERVER['SCRIPT_NAME'] ) ) {
03057 #
03058 # as it was called, minus the query string.
03059 #
03060 # Some sites use Apache rewrite rules to handle subdomains,
03061 # and have PHP set up in a weird way that causes PHP_SELF
03062 # to contain the rewritten URL instead of the one that the
03063 # outside world sees.
03064 #
03065 # If in this mode, use SCRIPT_URL instead, which mod_rewrite
03066 # provides containing the "before" URL.
03067 return $_SERVER['SCRIPT_NAME'];
03068 } else {
03069 return $_SERVER['URL'];
03070 }
03071 }
03072
03080 function wfBoolToStr( $value ) {
03081 return $value ? 'true' : 'false';
03082 }
03083
03088 function wfLoadExtensionMessages( $extensionName, $langcode = false ) {
03089 }
03090
03097 function wfGetNull() {
03098 return wfIsWindows()
03099 ? 'NUL'
03100 : '/dev/null';
03101 }
03102
03110 function wfMaxlagError( $host, $lag, $maxLag ) {
03111 global $wgShowHostnames;
03112 header( 'HTTP/1.1 503 Service Unavailable' );
03113 header( 'Retry-After: ' . max( intval( $maxLag ), 5 ) );
03114 header( 'X-Database-Lag: ' . intval( $lag ) );
03115 header( 'Content-Type: text/plain' );
03116 if( $wgShowHostnames ) {
03117 echo "Waiting for $host: $lag seconds lagged\n";
03118 } else {
03119 echo "Waiting for a database server: $lag seconds lagged\n";
03120 }
03121 }
03122
03128 function wfDeprecated( $function ) {
03129 static $functionsWarned = array();
03130 if ( !isset( $functionsWarned[$function] ) ) {
03131 $functionsWarned[$function] = true;
03132 wfWarn( "Use of $function is deprecated.", 2 );
03133 }
03134 }
03135
03146 function wfWarn( $msg, $callerOffset = 1, $level = E_USER_NOTICE ) {
03147 $callers = wfDebugBacktrace();
03148 if( isset( $callers[$callerOffset+1] ) ){
03149 $callerfunc = $callers[$callerOffset+1];
03150 $callerfile = $callers[$callerOffset];
03151 if( isset( $callerfile['file'] ) && isset( $callerfile['line'] ) ){
03152 $file = $callerfile['file'] . ' at line ' . $callerfile['line'];
03153 } else {
03154 $file = '(internal function)';
03155 }
03156 $func = '';
03157 if( isset( $callerfunc['class'] ) )
03158 $func .= $callerfunc['class'] . '::';
03159 $func .= @$callerfunc['function'];
03160 $msg .= " [Called from $func in $file]";
03161 }
03162
03163 global $wgDevelopmentWarnings;
03164 if ( $wgDevelopmentWarnings ) {
03165 trigger_error( $msg, $level );
03166 } else {
03167 wfDebug( "$msg\n" );
03168 }
03169 }
03170
03185 function wfWaitForSlaves( $maxLag, $wiki = false ) {
03186 if( $maxLag ) {
03187 $lb = wfGetLB( $wiki );
03188 list( $host, $lag ) = $lb->getMaxLag( $wiki );
03189 while( $lag > $maxLag ) {
03190 $name = @gethostbyaddr( $host );
03191 if( $name !== false ) {
03192 $host = $name;
03193 }
03194 print "Waiting for $host (lagged $lag seconds)...\n";
03195 sleep($maxLag);
03196 list( $host, $lag ) = $lb->getMaxLag();
03197 }
03198 }
03199 }
03200
03205 function wfOut( $s ) {
03206 static $lineStarted = false;
03207 global $wgCommandLineMode;
03208 if ( $wgCommandLineMode && !defined( 'MEDIAWIKI_INSTALL' ) ) {
03209 echo $s;
03210 } else {
03211 echo htmlspecialchars( $s );
03212 }
03213 flush();
03214 }
03215
03220 function wfCountDown( $n ) {
03221 for ( $i = $n; $i >= 0; $i-- ) {
03222 if ( $i != $n ) {
03223 echo str_repeat( "\x08", strlen( $i + 1 ) );
03224 }
03225 echo $i;
03226 flush();
03227 if ( $i ) {
03228 sleep( 1 );
03229 }
03230 }
03231 echo "\n";
03232 }
03233
03238 function wfGenerateToken( $salt = '' ) {
03239 $salt = serialize($salt);
03240
03241 return md5( mt_rand( 0, 0x7fffffff ) . $salt );
03242 }
03243
03248 function wfStripIllegalFilenameChars( $name ) {
03249 global $wgIllegalFileChars;
03250 $name = wfBaseName( $name );
03251 $name = preg_replace("/[^".Title::legalChars()."]".($wgIllegalFileChars ? "|[".$wgIllegalFileChars."]":"")."/",'-',$name);
03252 return $name;
03253 }
03254
03261 function wfArrayInsertAfter( $array, $insert, $after ) {
03262
03263 $keys = array_keys($array);
03264 $offsetByKey = array_flip( $keys );
03265
03266 $offset = $offsetByKey[$after];
03267
03268
03269 $before = array_slice( $array, 0, $offset + 1, true );
03270 $after = array_slice( $array, $offset + 1, count($array)-$offset, true );
03271
03272 $output = $before + $insert + $after;
03273
03274 return $output;
03275 }
03276
03277
03278 function wfObjectToArray( $object, $recursive = true ) {
03279 $array = array();
03280 foreach ( get_object_vars($object) as $key => $value ) {
03281 if ( is_object($value) && $recursive ) {
03282 $value = wfObjectToArray( $value );
03283 }
03284
03285 $array[$key] = $value;
03286 }
03287
03288 return $array;
03289 }
03290
03296 function wfMemoryLimit () {
03297 global $wgMemoryLimit;
03298 $memlimit = wfShorthandToInteger( ini_get( "memory_limit" ) );
03299 $conflimit = wfShorthandToInteger( $wgMemoryLimit );
03300 if( $memlimit != -1 ) {
03301 if( $conflimit == -1 ) {
03302 wfDebug( "Removing PHP's memory limit\n" );
03303 wfSuppressWarnings();
03304 ini_set( "memory_limit", $conflimit );
03305 wfRestoreWarnings();
03306 return $conflimit;
03307 } elseif ( $conflimit > $memlimit ) {
03308 wfDebug( "Raising PHP's memory limit to $conflimit bytes\n" );
03309 wfSuppressWarnings();
03310 ini_set( "memory_limit", $conflimit );
03311 wfRestoreWarnings();
03312 return $conflimit;
03313 }
03314 }
03315 return $memlimit;
03316 }
03317
03323 function wfShorthandToInteger ( $string = '' ) {
03324 $string = trim($string);
03325 if( empty($string) ) { return -1; }
03326 $last = strtolower($string[strlen($string)-1]);
03327 $val = intval($string);
03328 switch($last) {
03329 case 'g':
03330 $val *= 1024;
03331 case 'm':
03332 $val *= 1024;
03333 case 'k':
03334 $val *= 1024;
03335 }
03336
03337 return $val;
03338 }
03339
03340
03341
03342
03343
03344 function wfBCP47( $code ) {
03345 $codeSegment = explode( '-', $code );
03346 foreach ( $codeSegment as $segNo => $seg ) {
03347 if ( count( $codeSegment ) > 0 ) {
03348
03349 if ( ( strlen( $seg ) == 2 ) && ( $segNo > 0 ) )
03350 $codeBCP[$segNo] = strtoupper( $seg );
03351
03352 else if ( ( strlen( $seg ) == 4 ) && ( $segNo > 0 ) )
03353 $codeBCP[$segNo] = ucfirst( $seg );
03354
03355 else
03356 $codeBCP[$segNo] = strtolower( $seg );
03357 } else {
03358
03359 $codeBCP[$segNo] = strtolower( $seg );
03360 }
03361 }
03362 $langCode = implode ( '-' , $codeBCP );
03363 return $langCode;
03364 }