23 if ( !defined(
'MEDIAWIKI' ) ) {
24 die(
"This file is part of MediaWiki, it is not a valid entry point" );
37 if ( !function_exists(
'iconv' ) ) {
42 function iconv(
$from, $to, $string ) {
47 if ( !function_exists(
'mb_substr' ) ) {
52 function mb_substr( $str, $start,
$count =
'end' ) {
60 function mb_substr_split_unicode( $str, $splitPos ) {
65 if ( !function_exists(
'mb_strlen' ) ) {
70 function mb_strlen( $str, $enc =
'' ) {
75 if ( !function_exists(
'mb_strpos' ) ) {
80 function mb_strpos( $haystack, $needle, $offset = 0, $encoding =
'' ) {
85 if ( !function_exists(
'mb_strrpos' ) ) {
90 function mb_strrpos( $haystack, $needle, $offset = 0, $encoding =
'' ) {
97 if ( !function_exists(
'gzdecode' ) ) {
102 function gzdecode( $data ) {
103 return gzinflate( substr( $data, 10, -8 ) );
108 if ( !function_exists(
'hash_equals' ) ) {
124 function hash_equals( $known_string, $user_string ) {
126 if ( !is_string( $known_string ) ) {
127 trigger_error(
'hash_equals(): Expected known_string to be a string, ' .
128 gettype( $known_string ) .
' given', E_USER_WARNING );
133 if ( !is_string( $user_string ) ) {
134 trigger_error(
'hash_equals(): Expected user_string to be a string, ' .
135 gettype( $user_string ) .
' given', E_USER_WARNING );
143 $known_string_len = strlen( $known_string );
144 $user_string_len = strlen( $user_string );
145 $result = $known_string_len ^ $user_string_len;
146 for ( $i = 0; $i < $user_string_len; $i++ ) {
147 $result |= ord( $known_string[$i % $known_string_len] ) ^ ord( $user_string[$i] );
162 return array_udiff( $a, $b,
'wfArrayDiff2_cmp' );
171 if ( is_string( $a ) && is_string( $b ) ) {
172 return strcmp( $a, $b );
173 } elseif ( count( $a ) !== count( $b ) ) {
174 return count( $a ) < count( $b ) ? -1 : 1;
178 while ( (
list( , $valueA ) = each( $a ) ) && (
list( , $valueB ) = each( $b ) ) ) {
179 $cmp = strcmp( $valueA, $valueB );
200 return array_flip( array_intersect( array_flip( $a ), array_keys( $b ) ) );
214 throw new MWException(
'GlobalFunctions::wfAppendToArrayIfNotDefault got null' );
216 if ( $default[$key] !==
$value ) {
233 $args = func_get_args();
262 $args = func_get_args();
266 # @todo FIXME: Sometimes get nested arrays for $params,
267 # which leads to E_NOTICEs
268 $spec = implode(
"\t",
$params );
272 return array_values(
$out );
285 $keys = array_keys( $array );
286 $offsetByKey = array_flip(
$keys );
288 $offset = $offsetByKey[$after];
291 $before = array_slice( $array, 0, $offset + 1,
true );
292 $after = array_slice( $array, $offset + 1, count( $array ) - $offset,
true );
294 $output = $before + $insert + $after;
308 if ( is_object( $objOrArray ) ) {
309 $objOrArray = get_object_vars( $objOrArray );
311 foreach ( $objOrArray
as $key =>
$value ) {
312 if ( $recursive && ( is_object(
$value ) || is_array(
$value ) ) ) {
330 # The maximum random value is "only" 2^31-1, so get two random
331 # values to reduce the chance of dupes
332 $max = mt_getrandmax() + 1;
333 $rand = number_format( ( mt_rand() * $max + mt_rand() ) / $max / $max, 12,
'.',
'' );
350 for (
$n = 0;
$n < $length;
$n += 7 ) {
351 $str .= sprintf(
'%07x', mt_rand() & 0xfffffff );
353 return substr( $str, 0, $length );
381 if ( is_null(
$s ) ) {
386 if ( is_null( $needle ) ) {
387 $needle =
array(
'%3B',
'%40',
'%24',
'%21',
'%2A',
'%28',
'%29',
'%2C',
'%2F' );
388 if ( !isset( $_SERVER[
'SERVER_SOFTWARE'] ) ||
389 ( strpos( $_SERVER[
'SERVER_SOFTWARE'],
'Microsoft-IIS/7' ) ===
false )
395 $s = urlencode(
$s );
398 array(
';',
'@',
'$',
'!',
'*',
'(',
')',
',',
'/',
':' ),
415 function wfArrayToCgi( $array1, $array2 =
null, $prefix =
'' ) {
416 if ( !is_null( $array2 ) ) {
417 $array1 = $array1 + $array2;
421 foreach ( $array1
as $key =>
$value ) {
426 if ( $prefix !==
'' ) {
427 $key = $prefix .
"[$key]";
429 if ( is_array(
$value ) ) {
432 $cgi .= $firstTime ?
'' :
'&';
433 if ( is_array( $v ) ) {
436 $cgi .= urlencode( $key .
"[$k]" ) .
'=' . urlencode( $v );
441 if ( is_object(
$value ) ) {
444 $cgi .= urlencode( $key ) .
'=' . urlencode(
$value );
464 $bits = explode(
'&',
$query );
466 foreach ( $bits
as $bit ) {
470 if ( strpos( $bit,
'=' ) ===
false ) {
477 $key = urldecode( $key );
479 if ( strpos( $key,
'[' ) !==
false ) {
480 $keys = array_reverse( explode(
'[', $key ) );
481 $key = array_pop(
$keys );
484 $k = substr( $k, 0, -1 );
485 $temp =
array( $k => $temp );
487 if ( isset(
$ret[$key] ) ) {
488 $ret[$key] = array_merge(
$ret[$key], $temp );
508 if ( is_array(
$query ) ) {
512 if (
false === strpos( $url,
'?' ) ) {
546 global $wgServer, $wgCanonicalServer, $wgInternalServer, $wgRequest;
548 $serverUrl = $wgCanonicalServer;
549 } elseif ( $defaultProto ===
PROTO_INTERNAL && $wgInternalServer !==
false ) {
551 $serverUrl = $wgInternalServer;
553 $serverUrl = $wgServer;
555 $defaultProto = $wgRequest->getProtocol() .
'://';
561 $serverHasProto = $bits && $bits[
'scheme'] !=
'';
564 if ( $serverHasProto ) {
565 $defaultProto = $bits[
'scheme'] .
'://';
574 $defaultProtoWithoutSlashes = substr( $defaultProto, 0, -2 );
576 if ( substr( $url, 0, 2 ) ==
'//' ) {
577 $url = $defaultProtoWithoutSlashes . $url;
578 } elseif ( substr( $url, 0, 1 ) ==
'/' ) {
581 $url = ( $serverHasProto ?
'' : $defaultProtoWithoutSlashes ) . $serverUrl . $url;
585 if ( $bits && isset( $bits[
'path'] ) ) {
591 } elseif ( substr( $url, 0, 1 ) !=
'/' ) {
592 # URL is a relative path
596 # Expanded URL is not valid.
616 if ( isset( $urlParts[
'delimiter'] ) ) {
617 if ( isset( $urlParts[
'scheme'] ) ) {
618 $result .= $urlParts[
'scheme'];
621 $result .= $urlParts[
'delimiter'];
624 if ( isset( $urlParts[
'host'] ) ) {
625 if ( isset( $urlParts[
'user'] ) ) {
627 if ( isset( $urlParts[
'pass'] ) ) {
628 $result .=
':' . $urlParts[
'pass'];
635 if ( isset( $urlParts[
'port'] ) ) {
636 $result .=
':' . $urlParts[
'port'];
640 if ( isset( $urlParts[
'path'] ) ) {
644 if ( isset( $urlParts[
'query'] ) ) {
645 $result .=
'?' . $urlParts[
'query'];
648 if ( isset( $urlParts[
'fragment'] ) ) {
649 $result .=
'#' . $urlParts[
'fragment'];
668 $inputLength = strlen( $urlPath );
670 while ( $inputOffset < $inputLength ) {
671 $prefixLengthOne = substr( $urlPath, $inputOffset, 1 );
672 $prefixLengthTwo = substr( $urlPath, $inputOffset, 2 );
673 $prefixLengthThree = substr( $urlPath, $inputOffset, 3 );
674 $prefixLengthFour = substr( $urlPath, $inputOffset, 4 );
677 if ( $prefixLengthTwo ==
'./' ) {
678 # Step A, remove leading "./"
680 } elseif ( $prefixLengthThree ==
'../' ) {
681 # Step A, remove leading "../"
683 } elseif ( ( $prefixLengthTwo ==
'/.' ) && ( $inputOffset + 2 == $inputLength ) ) {
684 # Step B, replace leading "/.$" with "/"
686 $urlPath[$inputOffset] =
'/';
687 } elseif ( $prefixLengthThree ==
'/./' ) {
688 # Step B, replace leading "/./" with "/"
690 } elseif ( $prefixLengthThree ==
'/..' && ( $inputOffset + 3 == $inputLength ) ) {
691 # Step C, replace leading "/..$" with "/" and
692 # remove last path component in output
694 $urlPath[$inputOffset] =
'/';
696 } elseif ( $prefixLengthFour ==
'/../' ) {
697 # Step C, replace leading "/../" with "/" and
698 # remove last path component in output
701 } elseif ( ( $prefixLengthOne ==
'.' ) && ( $inputOffset + 1 == $inputLength ) ) {
702 # Step D, remove "^.$"
704 } elseif ( ( $prefixLengthTwo ==
'..' ) && ( $inputOffset + 2 == $inputLength ) ) {
705 # Step D, remove "^..$"
708 # Step E, move leading path segment to output
709 if ( $prefixLengthOne ==
'/' ) {
710 $slashPos = strpos( $urlPath,
'/', $inputOffset + 1 );
712 $slashPos = strpos( $urlPath,
'/', $inputOffset );
714 if ( $slashPos ===
false ) {
715 $output .= substr( $urlPath, $inputOffset );
716 $inputOffset = $inputLength;
718 $output .= substr( $urlPath, $inputOffset, $slashPos - $inputOffset );
719 $inputOffset += $slashPos - $inputOffset;
724 $slashPos = strrpos(
$output,
'/' );
725 if ( $slashPos ===
false ) {
747 static $withProtRel =
null, $withoutProtRel =
null;
748 $cachedValue = $includeProtocolRelative ? $withProtRel : $withoutProtRel;
749 if ( !is_null( $cachedValue ) ) {
755 if ( is_array( $wgUrlProtocols ) ) {
756 $protocols =
array();
757 foreach ( $wgUrlProtocols
as $protocol ) {
759 if ( $includeProtocolRelative || $protocol !==
'//' ) {
760 $protocols[] = preg_quote( $protocol,
'/' );
764 $retval = implode(
'|', $protocols );
774 if ( $includeProtocolRelative ) {
809 $wasRelative = substr( $url, 0, 2 ) ==
'//';
810 if ( $wasRelative ) {
814 $bits = parse_url( $url );
818 if ( !$bits || !isset( $bits[
'scheme'] ) ) {
823 $bits[
'scheme'] = strtolower( $bits[
'scheme'] );
826 if ( in_array( $bits[
'scheme'] .
'://', $wgUrlProtocols ) ) {
827 $bits[
'delimiter'] =
'://';
828 } elseif ( in_array( $bits[
'scheme'] .
':', $wgUrlProtocols ) ) {
829 $bits[
'delimiter'] =
':';
832 if ( isset( $bits[
'path'] ) ) {
833 $bits[
'host'] = $bits[
'path'];
841 if ( !isset( $bits[
'host'] ) ) {
845 if ( isset( $bits[
'path'] ) ) {
847 if ( substr( $bits[
'path'], 0, 1 ) !==
'/' ) {
848 $bits[
'path'] =
'/' . $bits[
'path'];
856 if ( $wasRelative ) {
857 $bits[
'scheme'] =
'';
858 $bits[
'delimiter'] =
'//';
874 return preg_replace_callback(
875 '/((?:%[89A-F][0-9A-F])+)/i',
876 'wfExpandIRI_callback',
901 if ( $bits[
'scheme'] ==
'mailto' ) {
902 $mailparts = explode(
'@', $bits[
'host'], 2 );
903 if ( count( $mailparts ) === 2 ) {
904 $domainpart = strtolower( implode(
'.', array_reverse( explode(
'.', $mailparts[1] ) ) ) );
909 $reversedHost = $domainpart .
'@' . $mailparts[0];
911 $reversedHost = strtolower( implode(
'.', array_reverse( explode(
'.', $bits[
'host'] ) ) ) );
915 if ( substr( $reversedHost, -1, 1 ) !==
'.' ) {
916 $reversedHost .=
'.';
919 $prot = $bits[
'scheme'];
920 $index = $prot . $bits[
'delimiter'] . $reversedHost;
922 if ( isset( $bits[
'port'] ) ) {
923 $index .=
':' . $bits[
'port'];
925 if ( isset( $bits[
'path'] ) ) {
926 $index .= $bits[
'path'];
930 if ( isset( $bits[
'query'] ) ) {
931 $index .=
'?' . $bits[
'query'];
933 if ( isset( $bits[
'fragment'] ) ) {
934 $index .=
'#' . $bits[
'fragment'];
938 return array(
"http:$index",
"https:$index" );
940 return array( $index );
952 if ( is_array( $bits ) && isset( $bits[
'host'] ) ) {
953 $host =
'.' . $bits[
'host'];
954 foreach ( (
array)$domains
as $domain ) {
955 $domain =
'.' . $domain;
956 if ( substr( $host, -strlen( $domain ) ) === $domain ) {
981 function wfDebug( $text, $dest =
'all' ) {
982 global $wgDebugLogFile, $wgDebugRawPage, $wgDebugLogPrefix;
989 if ( $dest ===
true ) {
991 } elseif ( $dest ===
false ) {
996 if ( $timer !==
'' ) {
997 $text = preg_replace(
'/[^\n]/', $timer .
'\0', $text, 1 );
1000 if ( $dest ===
'all' ) {
1004 if ( $wgDebugLogFile !=
'' ) {
1005 # Strip unprintables; they can switch terminal modes when binary data
1006 # gets dumped, which is pretty annoying.
1007 $text = preg_replace(
'![\x00-\x08\x0b\x0c\x0e-\x1f]!',
' ', $text );
1008 $text = $wgDebugLogPrefix . $text;
1022 # Check for raw action using $_GET not $wgRequest, since the latter might not be initialised yet
1023 if ( ( isset( $_GET[
'action'] ) && $_GET[
'action'] ==
'raw' )
1025 isset( $_SERVER[
'SCRIPT_NAME'] )
1026 && substr( $_SERVER[
'SCRIPT_NAME'], -8 ) ==
'load.php'
1044 if ( !$wgDebugTimestamps ) {
1048 $prefix = sprintf(
"%6.4f", microtime(
true ) -
$wgRequestTime );
1049 $mem = sprintf(
"%5.1fM", ( memory_get_usage(
true ) / ( 1024 * 1024 ) ) );
1050 return "$prefix $mem ";
1059 $mem = memory_get_usage();
1061 $mem = floor( $mem / 1024 ) .
' kilobytes';
1065 wfDebug(
"Memory usage: $mem\n" );
1088 function wfDebugLog( $logGroup, $text, $dest =
'all' ) {
1089 global $wgDebugLogGroups;
1091 $text = trim( $text ) .
"\n";
1094 if ( $dest ===
true ) {
1096 } elseif ( $dest ===
false ) {
1100 if ( !isset( $wgDebugLogGroups[$logGroup] ) ) {
1101 if ( $dest !==
'private' ) {
1102 wfDebug(
"[$logGroup] $text", $dest );
1107 if ( $dest ===
'all' ) {
1111 $logConfig = $wgDebugLogGroups[$logGroup];
1112 if ( $logConfig ===
false ) {
1115 if ( is_array( $logConfig ) ) {
1116 if ( isset( $logConfig[
'sample'] ) && mt_rand( 1, $logConfig[
'sample'] ) !== 1 ) {
1119 $destination = $logConfig[
'destination'];
1121 $destination = strval( $logConfig );
1127 wfErrorLog(
"$time $host $wiki: $text", $destination );
1136 global $wgDBerrorLog, $wgDBerrorLogTZ;
1137 static $logDBErrorTimeZoneObject =
null;
1139 if ( $wgDBerrorLog ) {
1143 if ( $wgDBerrorLogTZ && !$logDBErrorTimeZoneObject ) {
1144 $logDBErrorTimeZoneObject =
new DateTimeZone( $wgDBerrorLogTZ );
1149 if ( $logDBErrorTimeZoneObject ===
null ) {
1150 $d = date_create(
"now" );
1152 $d = date_create(
"now", $logDBErrorTimeZoneObject );
1155 $date = $d->format(
'D M j G:i:s T Y' );
1157 $text =
"$date\t$host\t$wiki\t" . trim( $text ) .
"\n";
1189 function wfWarn( $msg, $callerOffset = 1, $level = E_USER_NOTICE ) {
1202 function wfLogWarning( $msg, $callerOffset = 1, $level = E_USER_WARNING ) {
1217 if ( substr(
$file, 0, 4 ) ==
'udp:' ) {
1218 # Needs the sockets extension
1219 if ( preg_match(
'!^(tcp|udp):(?://)?\[([0-9a-fA-F:]+)\]:(\d+)(?:/(.*))?$!',
$file, $m ) ) {
1222 $port = intval( $m[3] );
1223 $prefix = isset( $m[4] ) ? $m[4] :
false;
1225 } elseif ( preg_match(
'!^(tcp|udp):(?://)?([a-zA-Z0-9.-]+):(\d+)(?:/(.*))?$!',
$file, $m ) ) {
1228 $host = gethostbyname( $host );
1230 $port = intval( $m[3] );
1231 $prefix = isset( $m[4] ) ? $m[4] :
false;
1234 throw new MWException( __METHOD__ .
': Invalid UDP specification' );
1238 if ( strval( $prefix ) !==
'' ) {
1239 $text = preg_replace(
'/^/m', $prefix .
' ', $text );
1242 if ( strlen( $text ) > 65506 ) {
1243 $text = substr( $text, 0, 65506 );
1246 if ( substr( $text, -1 ) !=
"\n" ) {
1249 } elseif ( strlen( $text ) > 65507 ) {
1250 $text = substr( $text, 0, 65507 );
1253 $sock = socket_create( $domain, SOCK_DGRAM, SOL_UDP );
1258 socket_sendto( $sock, $text, strlen( $text ), 0, $host, $port );
1259 socket_close( $sock );
1262 $exists = file_exists(
$file );
1264 if ( !$exists || (
$size !==
false &&
$size + strlen( $text ) < 0x7fffffff ) ) {
1265 file_put_contents(
$file, $text, FILE_APPEND );
1282 # Profiling must actually be enabled...
1283 if ( $profiler->isStub() ) {
1290 if ( $elapsed <= $wgProfileLimit ) {
1294 $profiler->logData();
1297 if ( isset( $wgDebugLogGroups[
'profileoutput'] )
1298 && $wgDebugLogGroups[
'profileoutput'] ===
false
1303 if ( !isset( $wgDebugLogGroups[
'profileoutput'] ) && $wgDebugLogFile ==
'' ) {
1312 if ( !empty( $_SERVER[
'HTTP_X_FORWARDED_FOR'] ) ) {
1313 $forward =
' forwarded for ' . $_SERVER[
'HTTP_X_FORWARDED_FOR'];
1315 if ( !empty( $_SERVER[
'HTTP_CLIENT_IP'] ) ) {
1316 $forward .=
' client IP ' . $_SERVER[
'HTTP_CLIENT_IP'];
1318 if ( !empty( $_SERVER[
'HTTP_FROM'] ) ) {
1319 $forward .=
' from ' . $_SERVER[
'HTTP_FROM'];
1322 $forward =
"\t(proxied via {$_SERVER['REMOTE_ADDR']}{$forward})";
1327 $forward .=
' anon';
1333 $requestUrl = $wgRequest->getRequestURL();
1335 $requestUrl =
'n/a';
1338 $log = sprintf(
"%s\t%04.3f\t%s\n",
1339 gmdate(
'YmdHis' ), $elapsed,
1340 urldecode( $requestUrl . $forward ) );
1342 wfDebugLog(
'profileoutput', $log . $profiler->getOutput() );
1371 global $wgReadOnly, $wgReadOnlyFile;
1373 if ( $wgReadOnly ===
null ) {
1375 if ( is_file( $wgReadOnlyFile ) && filesize( $wgReadOnlyFile ) > 0 ) {
1376 $wgReadOnly = file_get_contents( $wgReadOnlyFile );
1378 $wgReadOnly =
false;
1401 # Identify which language to get or create a language object for.
1402 # Using is_object here due to Stub objects.
1403 if ( is_object( $langcode ) ) {
1404 # Great, we already have the object (hopefully)!
1409 if ( $langcode ===
true || $langcode === $wgLanguageCode ) {
1410 # $langcode is the language code of the wikis content language object.
1411 # or it is a boolean and value is true
1416 if ( $langcode ===
false || $langcode ===
$wgLang->getCode() ) {
1417 # $langcode is the language code of user language object.
1418 # or it was a boolean and value is false
1423 if ( in_array( $langcode, $validCodes ) ) {
1424 # $langcode corresponds to a valid language.
1428 # $langcode is a string, but not a valid language code; use content language.
1429 wfDebug(
"Invalid language code passed to wfGetLangObj, falling back to content language.\n" );
1455 return new Message( $key,
$params );
1471 $args = func_get_args();
1472 return call_user_func_array(
'Message::newFallbackSequence',
$args );
1494 function wfMsg( $key ) {
1497 $args = func_get_args();
1498 array_shift(
$args );
1513 $args = func_get_args();
1514 array_shift(
$args );
1546 global $wgForceUIMsgAsContentMsg;
1547 $args = func_get_args();
1548 array_shift(
$args );
1550 if ( is_array( $wgForceUIMsgAsContentMsg )
1551 && in_array( $key, $wgForceUIMsgAsContentMsg )
1553 $forcontent =
false;
1569 global $wgForceUIMsgAsContentMsg;
1570 $args = func_get_args();
1571 array_shift(
$args );
1573 if ( is_array( $wgForceUIMsgAsContentMsg )
1574 && in_array( $key, $wgForceUIMsgAsContentMsg )
1576 $forcontent =
false;
1593 function wfMsgReal( $key,
$args, $useDB =
true, $forContent =
false, $transform =
true ) {
1597 $message =
wfMsgGetKey( $key, $useDB, $forContent, $transform );
1615 function wfMsgGetKey( $key, $useDB =
true, $langCode =
false, $transform =
true ) {
1618 wfRunHooks(
'NormalizeMessageKey',
array( &$key, &$useDB, &$langCode, &$transform ) );
1621 $message =
$cache->get( $key, $useDB, $langCode );
1622 if ( $message ===
false ) {
1623 $message =
'<' . htmlspecialchars( $key ) .
'>';
1624 } elseif ( $transform ) {
1625 $message =
$cache->transform( $message );
1639 # Fix windows line-endings
1640 # Some messages are split with explode("\n", $msg)
1641 $message = str_replace(
"\r",
'', $message );
1644 if ( count(
$args ) ) {
1645 if ( is_array(
$args[0] ) ) {
1648 $replacementKeys =
array();
1650 $replacementKeys[
'$' . (
$n + 1 )] = $param;
1652 $message = strtr( $message, $replacementKeys );
1674 $args = func_get_args();
1675 array_shift(
$args );
1695 $args = func_get_args();
1696 array_shift(
$args );
1699 true,
true )->getText(),
1729 $args = func_get_args();
1730 array_shift(
$args );
1731 array_shift(
$args );
1734 foreach (
$options as $arrayKey => $option ) {
1735 if ( !preg_match(
'/^[0-9]+|language$/', $arrayKey ) ) {
1736 # An unknown index, neither numeric nor "language"
1737 wfWarn(
"wfMsgExt called with incorrect parameter key $arrayKey", 1, E_USER_WARNING );
1738 } elseif ( preg_match(
'/^[0-9]+$/', $arrayKey ) && !in_array( $option,
1739 array(
'parse',
'parseinline',
'escape',
'escapenoentities',
1740 'replaceafter',
'parsemag',
'content' ) ) ) {
1741 # A numeric index with unknown value
1742 wfWarn(
"wfMsgExt called with incorrect parameter $option", 1, E_USER_WARNING );
1746 if ( in_array(
'content',
$options,
true ) ) {
1749 $langCodeObj =
null;
1750 } elseif ( array_key_exists(
'language',
$options ) ) {
1751 $forContent =
false;
1753 $langCodeObj = $langCode;
1755 $forContent =
false;
1757 $langCodeObj =
null;
1760 $string =
wfMsgGetKey( $key,
true, $langCode,
false );
1762 if ( !in_array(
'replaceafter',
$options,
true ) ) {
1767 $parseInline = in_array(
'parseinline',
$options,
true );
1768 if ( in_array(
'parse',
$options,
true ) || $parseInline ) {
1769 $string = $messageCache->parse( $string,
null,
true, !$forContent, $langCodeObj );
1771 $string = $string->getText();
1774 if ( $parseInline ) {
1776 if ( preg_match(
'/^<p>(.*)\n?<\/p>\n?$/sU', $string, $m ) ) {
1780 } elseif ( in_array(
'parsemag',
$options,
true ) ) {
1781 $string = $messageCache->transform( $string,
1782 !$forContent, $langCodeObj );
1785 if ( in_array(
'escape',
$options,
true ) ) {
1786 $string = htmlspecialchars ( $string );
1787 } elseif ( in_array(
'escapenoentities',
$options,
true ) ) {
1791 if ( in_array(
'replaceafter',
$options,
true ) ) {
1836 if ( is_null( $host ) ) {
1838 # Hostname overriding
1839 global $wgOverrideHostname;
1840 if ( $wgOverrideHostname !==
false ) {
1841 # Set static and skip any detection
1842 $host = $wgOverrideHostname;
1846 if ( function_exists(
'posix_uname' ) ) {
1848 $uname = posix_uname();
1852 if ( is_array( $uname ) && isset( $uname[
'nodename'] ) ) {
1853 $host = $uname[
'nodename'];
1854 } elseif ( getenv(
'COMPUTERNAME' ) ) {
1855 # Windows computer name
1856 $host = getenv(
'COMPUTERNAME' );
1858 # This may be a virtual server.
1859 $host = $_SERVER[
'SERVER_NAME'];
1877 $responseTime = round( ( microtime(
true ) -
$wgRequestTime ) * 1000 );
1878 $reportVars =
array(
'wgBackendResponseTime' => $responseTime );
1879 if ( $wgShowHostnames ) {
1901 static $disabled =
null;
1903 if ( extension_loaded(
'Zend Optimizer' ) ) {
1904 wfDebug(
"Zend Optimizer detected; skipping debug_backtrace for safety.\n" );
1908 if ( is_null( $disabled ) ) {
1910 $functions = explode(
',', ini_get(
'disable_functions' ) );
1911 $functions = array_map(
'trim', $functions );
1912 $functions = array_map(
'strtolower', $functions );
1913 if ( in_array(
'debug_backtrace', $functions ) ) {
1914 wfDebug(
"debug_backtrace is in disabled_functions\n" );
1922 if (
$limit && version_compare( PHP_VERSION,
'5.4.0',
'>=' ) ) {
1923 return array_slice( debug_backtrace( DEBUG_BACKTRACE_PROVIDE_OBJECT,
$limit + 1 ), 1 );
1925 return array_slice( debug_backtrace(), 1 );
1943 foreach ( $backtrace
as $call ) {
1944 if ( isset( $call[
'file'] ) ) {
1945 $f = explode( DIRECTORY_SEPARATOR, $call[
'file'] );
1950 if ( isset( $call[
'line'] ) ) {
1951 $line = $call[
'line'];
1956 $msg .=
"$file line $line calls ";
1958 $msg .=
'<li>' .
$file .
' line ' .
$line .
' calls ';
1960 if ( !empty( $call[
'class'] ) ) {
1961 $msg .= $call[
'class'] . $call[
'type'];
1963 $msg .= $call[
'function'] .
'()';
1991 if ( isset( $backtrace[$level] ) ) {
2009 $limit = count( $trace ) - 1;
2012 return implode(
'/', array_map(
'wfFormatStackFrame', $trace ) );
2022 return isset( $frame[
'class'] ) ?
2023 $frame[
'class'] .
'::' . $frame[
'function'] :
2037 return wfMessage(
'showingresults' )->numParams(
$limit, $offset + 1 )->parse();
2058 if ( is_object(
$link ) ) {
2062 if ( is_null(
$title ) ) {
2079 if (
$result ===
null || $force ) {
2081 if ( isset( $_SERVER[
'HTTP_ACCEPT_ENCODING'] ) ) {
2082 # @todo FIXME: We may want to blacklist some broken browsers
2085 '/\bgzip(?:;(q)=([0-9]+(?:\.[0-9]+)))?\b/',
2086 $_SERVER[
'HTTP_ACCEPT_ENCODING'],
2090 if ( isset( $m[2] ) && ( $m[1] ==
'q' ) && ( $m[2] == 0 ) ) {
2094 wfDebug(
"wfClientAcceptsGzip: client accepts gzip.\n" );
2111 function wfCheckLimits( $deflimit = 50, $optionname =
'rclimit' ) {
2113 return $wgRequest->getLimitOffset( $deflimit, $optionname );
2126 static $repl =
null, $repl2 =
null;
2127 if ( $repl ===
null ) {
2129 '"' =>
'"',
'&' =>
'&',
"'" =>
''',
'<' =>
'<',
2130 '=' =>
'=',
'>' =>
'>',
'[' =>
'[',
']' =>
']',
2131 '{' =>
'{',
'|' =>
'|',
'}' =>
'}',
';' =>
';',
2132 "\n#" =>
"\n#",
"\r#" =>
"\r#",
2133 "\n*" =>
"\n*",
"\r*" =>
"\r*",
2134 "\n:" =>
"\n:",
"\r:" =>
"\r:",
2135 "\n " =>
"\n ",
"\r " =>
"\r ",
2136 "\n\n" =>
"\n ",
"\r\n" =>
" \n",
2137 "\n\r" =>
"\n ",
"\r\r" =>
"\r ",
2138 "\n\t" =>
"\n	",
"\r\t" =>
"\r	",
2139 "\n----" =>
"\n----",
"\r----" =>
"\r----",
2140 '__' =>
'__',
'://' =>
'://',
2144 foreach (
array(
'ISBN',
'RFC',
'PMID' )
as $magic ) {
2145 $repl[
"$magic "] =
"$magic ";
2146 $repl[
"$magic\t"] =
"$magic	";
2147 $repl[
"$magic\r"] =
"$magic ";
2148 $repl[
"$magic\n"] =
"$magic ";
2149 $repl[
"$magic\f"] =
"$magic";
2155 foreach ( $wgUrlProtocols
as $prot ) {
2156 if ( substr( $prot, -1 ) ===
':' ) {
2157 $repl2[] = preg_quote( substr( $prot, 0, -1 ),
'/' );
2160 $repl2 = $repl2 ?
'/\b(' . join(
'|', $repl2 ) .
'):/i' :
'/^(?!)/';
2162 $text = substr( strtr(
"\n$text", $repl ), 1 );
2163 $text = preg_replace( $repl2,
'$1:', $text );
2174 return microtime(
true );
2189 if ( !is_null(
$source ) || $force ) {
2204 function wfSetBit( &$dest, $bit, $state =
true ) {
2205 $temp = (bool)( $dest & $bit );
2206 if ( !is_null( $state ) ) {
2224 $s = str_replace(
"\n",
"<br />\n", var_export( $var,
true ) .
"\n" );
2225 if ( headers_sent() || !isset(
$wgOut ) || !is_object(
$wgOut ) ) {
2242 header(
"HTTP/1.0 $code $label" );
2243 header(
"Status: $code $label" );
2244 $wgOut->sendCacheControl();
2246 header(
'Content-type: text/html; charset=utf-8' );
2247 print
"<!doctype html>" .
2248 '<html><head><title>' .
2249 htmlspecialchars( $label ) .
2250 '</title></head><body><h1>' .
2251 htmlspecialchars( $label ) .
2253 nl2br( htmlspecialchars( $desc ) ) .
2254 "</p></body></html>\n";
2275 if ( $resetGzipEncoding ) {
2278 global $wgDisableOutputCompression;
2279 $wgDisableOutputCompression =
true;
2281 while ( $status = ob_get_status() ) {
2282 if ( $status[
'type'] == 0 ) {
2290 if ( !ob_end_clean() ) {
2295 if ( $resetGzipEncoding ) {
2296 if ( $status[
'name'] ==
'ob_gzhandler' ) {
2299 header_remove(
'Content-Encoding' );
2331 # No arg means accept anything (per HTTP spec)
2333 return array( $def => 1.0 );
2338 $parts = explode(
',', $accept );
2340 foreach ( $parts
as $part ) {
2341 # @todo FIXME: Doesn't deal with params like 'text/html; level=1'
2342 $values = explode(
';', trim( $part ) );
2344 if ( count( $values ) == 1 ) {
2345 $prefs[$values[0]] = 1.0;
2346 } elseif ( preg_match(
'/q\s*=\s*(\d*\.\d+)/', $values[1], $match ) ) {
2347 $prefs[$values[0]] = floatval( $match[1] );
2367 if ( array_key_exists(
$type, $avail ) ) {
2370 $parts = explode(
'/',
$type );
2371 if ( array_key_exists( $parts[0] .
'/*', $avail ) ) {
2372 return $parts[0] .
'/*';
2373 } elseif ( array_key_exists(
'*/*', $avail ) ) {
2397 foreach ( array_keys( $sprefs )
as $type ) {
2398 $parts = explode(
'/',
$type );
2399 if ( $parts[1] !=
'*' ) {
2402 $combine[
$type] = $sprefs[
$type] * $cprefs[$ckey];
2407 foreach ( array_keys( $cprefs )
as $type ) {
2408 $parts = explode(
'/',
$type );
2409 if ( $parts[1] !=
'*' && !array_key_exists(
$type, $sprefs ) ) {
2412 $combine[
$type] = $sprefs[$skey] * $cprefs[
$type];
2420 foreach ( array_keys( $combine )
as $type ) {
2421 if ( $combine[
$type] > $bestq ) {
2423 $bestq = $combine[
$type];
2436 static $suppressCount = 0;
2437 static $originalLevel =
false;
2440 if ( $suppressCount ) {
2442 if ( !$suppressCount ) {
2443 error_reporting( $originalLevel );
2447 if ( !$suppressCount ) {
2448 $originalLevel = error_reporting( E_ALL & ~(
2469 # Autodetect, convert and provide timestamps of various types
2474 define(
'TS_UNIX', 0 );
2479 define(
'TS_MW', 1 );
2484 define(
'TS_DB', 2 );
2489 define(
'TS_RFC2822', 3 );
2496 define(
'TS_ISO_8601', 4 );
2505 define(
'TS_EXIF', 5 );
2510 define(
'TS_ORACLE', 6 );
2515 define(
'TS_POSTGRES', 7 );
2520 define(
'TS_ISO_8601_BASIC', 9 );
2534 return $timestamp->getTimestamp( $outputtype );
2536 wfDebug(
"wfTimestamp() fed bogus time value: TYPE=$outputtype; VALUE=$ts\n" );
2550 if ( is_null( $ts ) ) {
2573 static $isWindows =
null;
2574 if ( $isWindows ===
null ) {
2575 $isWindows = substr( php_uname(), 0, 7 ) ==
'Windows';
2586 return defined(
'HHVM_VERSION' );
2595 function swap( &$x, &$y ) {
2615 if ( $wgTmpDirectory !==
false ) {
2616 return $wgTmpDirectory;
2619 $tmpDir = array_map(
"getenv",
array(
'TMPDIR',
'TMP',
'TEMP' ) );
2621 foreach ( $tmpDir
as $tmp ) {
2622 if ( $tmp && file_exists( $tmp ) && is_dir( $tmp ) && is_writable( $tmp ) ) {
2626 return sys_get_temp_dir();
2642 throw new MWException( __FUNCTION__ .
" given storage path '$dir'." );
2645 if ( !is_null( $caller ) ) {
2646 wfDebug(
"$caller: called wfMkdirParents($dir)\n" );
2649 if ( strval(
$dir ) ===
'' || ( file_exists(
$dir ) && is_dir(
$dir ) ) ) {
2653 $dir = str_replace(
array(
'\\',
'/' ), DIRECTORY_SEPARATOR,
$dir );
2655 if ( is_null( $mode ) ) {
2656 $mode = $wgDirectoryMode;
2661 $ok = mkdir(
$dir, $mode,
true );
2666 if ( is_dir(
$dir ) ) {
2681 wfDebug( __FUNCTION__ .
"( $dir )\n" );
2683 if ( is_dir(
$dir ) ) {
2684 $objects = scandir(
$dir );
2685 foreach ( $objects
as $object ) {
2686 if ( $object !=
"." && $object !=
".." ) {
2687 if ( filetype(
$dir .
'/' . $object ) ==
"dir" ) {
2690 unlink(
$dir .
'/' . $object );
2705 function wfPercent( $nr, $acc = 2, $round =
true ) {
2706 $ret = sprintf(
"%.${acc}f", $nr );
2707 return $round ? round(
$ret, $acc ) .
'%' :
"$ret%";
2734 $val = strtolower( ini_get( $setting ) );
2739 || preg_match(
"/^\s*[+-]?0*[1-9]/", $val );
2756 $args = func_get_args();
2776 $tokens = preg_split(
'/(\\\\*")/', $arg, -1, PREG_SPLIT_DELIM_CAPTURE );
2779 foreach ( $tokens
as $token ) {
2780 if ( $iteration % 2 == 1 ) {
2782 $arg .= str_replace(
'\\',
'\\\\', substr( $token, 0, -1 ) ) .
'\\"';
2783 } elseif ( $iteration % 4 == 2 ) {
2785 $arg .= str_replace(
'^',
'^^', $token );
2795 if ( preg_match(
'/^(.*?)(\\\\+)$/', $arg, $m ) ) {
2796 $arg = $m[1] . str_replace(
'\\',
'\\\\', $m[2] );
2800 $retVal .=
'"' . $arg .
'"';
2802 $retVal .= escapeshellarg( $arg );
2815 static $disabled =
null;
2816 if ( is_null( $disabled ) ) {
2819 wfDebug(
"wfShellExec can't run in safe_mode, PHP's exec functions are too broken.\n" );
2820 $disabled =
'safemode';
2822 $functions = explode(
',', ini_get(
'disable_functions' ) );
2823 $functions = array_map(
'trim', $functions );
2824 $functions = array_map(
'strtolower', $functions );
2825 if ( in_array(
'proc_open', $functions ) ) {
2826 wfDebug(
"proc_open is in disabled_functions\n" );
2827 $disabled =
'disabled';
2855 global $IP, $wgMaxShellMemory, $wgMaxShellFileSize, $wgMaxShellTime,
2856 $wgMaxShellWallClockTime, $wgShellCgroup;
2861 return $disabled ==
'safemode' ?
2862 'Unable to run external programs in safe mode.' :
2863 'Unable to run external programs, proc_open() is disabled.';
2866 $includeStderr = isset(
$options[
'duplicateStderr'] ) &&
$options[
'duplicateStderr'];
2871 foreach ( $environ
as $k => $v ) {
2879 $envcmd .=
"set $k=" . preg_replace(
'/([&|()<>^"])/',
'^\\1', $v ) .
'&& ';
2884 $envcmd .=
"$k=" . escapeshellarg( $v ) .
' ';
2887 $cmd = $envcmd . $cmd;
2889 $useLogPipe =
false;
2890 if ( php_uname(
's' ) ==
'Linux' ) {
2891 $time = intval ( isset( $limits[
'time'] ) ? $limits[
'time'] : $wgMaxShellTime );
2892 if ( isset( $limits[
'walltime'] ) ) {
2893 $wallTime = intval( $limits[
'walltime'] );
2894 } elseif ( isset( $limits[
'time'] ) ) {
2897 $wallTime = intval( $wgMaxShellWallClockTime );
2899 $mem = intval ( isset( $limits[
'memory'] ) ? $limits[
'memory'] : $wgMaxShellMemory );
2900 $filesize = intval ( isset( $limits[
'filesize'] ) ? $limits[
'filesize'] : $wgMaxShellFileSize );
2902 if (
$time > 0 || $mem > 0 || $filesize > 0 || $wallTime > 0 ) {
2903 $cmd =
'/bin/bash ' . escapeshellarg(
"$IP/includes/limit.sh" ) .
' ' .
2904 escapeshellarg( $cmd ) .
' ' .
2906 "MW_INCLUDE_STDERR=" . ( $includeStderr ?
'1' :
'' ) .
';' .
2907 "MW_CPU_LIMIT=$time; " .
2908 'MW_CGROUP=' . escapeshellarg( $wgShellCgroup ) .
'; ' .
2909 "MW_MEM_LIMIT=$mem; " .
2910 "MW_FILE_SIZE_LIMIT=$filesize; " .
2911 "MW_WALL_CLOCK_LIMIT=$wallTime; " .
2912 "MW_USE_LOG_PIPE=yes"
2915 } elseif ( $includeStderr ) {
2918 } elseif ( $includeStderr ) {
2921 wfDebug(
"wfShellExec: $cmd\n" );
2928 throw new Exception( __METHOD__ .
'(): total length of $cmd must not exceed SHELL_MAX_ARG_STRLEN' );
2932 0 =>
array(
'file',
'php://stdin',
'r' ),
2933 1 =>
array(
'pipe',
'w' ),
2934 2 =>
array(
'file',
'php://stderr',
'w' ) );
2935 if ( $useLogPipe ) {
2936 $desc[3] =
array(
'pipe',
'w' );
2939 $proc = proc_open( $cmd, $desc, $pipes );
2941 wfDebugLog(
'exec',
"proc_open() failed: $cmd" );
2945 $outBuffer = $logBuffer =
'';
2946 $emptyArray =
array();
2960 $eintr = defined(
'SOCKET_EINTR' ) ? SOCKET_EINTR : 4;
2961 $eintrMessage =
"stream_select(): unable to select [$eintr]";
2967 foreach ( $pipes
as $fd => $pipe ) {
2968 $fds[(int)$pipe] = $fd;
2975 while ( $running ===
true || $numReadyPipes !== 0 ) {
2977 $status = proc_get_status( $proc );
2980 if ( !$status[
'running'] ) {
2986 $readyPipes = $pipes;
2989 @trigger_error(
'' );
2990 $numReadyPipes = @stream_select( $readyPipes, $emptyArray, $emptyArray, $timeout );
2991 if ( $numReadyPipes ===
false ) {
2992 $error = error_get_last();
2993 if ( strncmp(
$error[
'message'], $eintrMessage, strlen( $eintrMessage ) ) == 0 ) {
2996 trigger_error(
$error[
'message'], E_USER_WARNING );
2997 $logMsg =
$error[
'message'];
3001 foreach ( $readyPipes
as $pipe ) {
3002 $block = fread( $pipe, 65536 );
3003 $fd = $fds[(int)$pipe];
3004 if ( $block ===
'' ) {
3006 fclose( $pipes[$fd] );
3007 unset( $pipes[$fd] );
3011 } elseif ( $block ===
false ) {
3013 $logMsg =
"Error reading from pipe";
3015 } elseif ( $fd == 1 ) {
3017 $outBuffer .= $block;
3018 } elseif ( $fd == 3 ) {
3020 $logBuffer .= $block;
3021 if ( strpos( $block,
"\n" ) !==
false ) {
3022 $lines = explode(
"\n", $logBuffer );
3023 $logBuffer = array_pop(
$lines );
3032 foreach ( $pipes
as $pipe ) {
3039 $status = proc_get_status( $proc );
3042 if ( $logMsg !==
false ) {
3045 proc_close( $proc );
3046 } elseif ( $status[
'signaled'] ) {
3047 $logMsg =
"Exited with signal {$status['termsig']}";
3048 $retval = 128 + $status[
'termsig'];
3049 proc_close( $proc );
3051 if ( $status[
'running'] ) {
3052 $retval = proc_close( $proc );
3054 $retval = $status[
'exitcode'];
3055 proc_close( $proc );
3058 $logMsg =
"Possibly missing executable file";
3060 $logMsg =
"Probably exited with signal " . (
$retval - 128 );
3064 if ( $logMsg !==
false ) {
3094 static $done =
false;
3101 putenv(
"LC_CTYPE=$wgShellLocale" );
3102 setlocale( LC_CTYPE, $wgShellLocale );
3133 if ( isset(
$options[
'wrapper'] ) ) {
3138 return implode(
" ", array_map(
'wfEscapeShellArg', array_merge( $cmd, $parameters ) ) );
3154 # This check may also protect against code injection in
3155 # case of broken installations.
3157 $haveDiff3 = $wgDiff3 && file_exists( $wgDiff3 );
3160 if ( !$haveDiff3 ) {
3161 wfDebug(
"diff3 not found\n" );
3165 # Make temporary files
3167 $oldtextFile = fopen( $oldtextName = tempnam( $td,
'merge-old-' ),
'w' );
3168 $mytextFile = fopen( $mytextName = tempnam( $td,
'merge-mine-' ),
'w' );
3169 $yourtextFile = fopen( $yourtextName = tempnam( $td,
'merge-your-' ),
'w' );
3171 # NOTE: diff3 issues a warning to stderr if any of the files does not end with
3172 # a newline character. To avoid this, we normalize the trailing whitespace before
3173 # creating the diff.
3175 fwrite( $oldtextFile, rtrim( $old ) .
"\n" );
3176 fclose( $oldtextFile );
3177 fwrite( $mytextFile, rtrim( $mine ) .
"\n" );
3178 fclose( $mytextFile );
3179 fwrite( $yourtextFile, rtrim( $yours ) .
"\n" );
3180 fclose( $yourtextFile );
3182 # Check for a conflict
3187 $handle = popen( $cmd,
'r' );
3189 if ( fgets( $handle, 1024 ) ) {
3199 $handle = popen( $cmd,
'r' );
3202 $data = fread( $handle, 8192 );
3203 if ( strlen( $data ) == 0 ) {
3209 unlink( $mytextName );
3210 unlink( $oldtextName );
3211 unlink( $yourtextName );
3213 if (
$result ===
'' && $old !==
'' && !$conflict ) {
3214 wfDebug(
"Unexpected null result from diff3. Command: $cmd\n" );
3230 if ( $before == $after ) {
3236 $haveDiff = $wgDiff && file_exists( $wgDiff );
3239 # This check may also protect against code injection in
3240 # case of broken installations.
3242 wfDebug(
"diff executable not found\n" );
3243 $diffs =
new Diff( explode(
"\n", $before ), explode(
"\n", $after ) );
3245 return $format->format( $diffs );
3248 # Make temporary files
3250 $oldtextFile = fopen( $oldtextName = tempnam( $td,
'merge-old-' ),
'w' );
3251 $newtextFile = fopen( $newtextName = tempnam( $td,
'merge-your-' ),
'w' );
3253 fwrite( $oldtextFile, $before );
3254 fclose( $oldtextFile );
3255 fwrite( $newtextFile, $after );
3256 fclose( $newtextFile );
3261 $h = popen( $cmd,
'r' );
3266 $data = fread( $h, 8192 );
3267 if ( strlen( $data ) == 0 ) {
3275 unlink( $oldtextName );
3276 unlink( $newtextName );
3279 $diff_lines = explode(
"\n", $diff );
3280 if ( strpos( $diff_lines[0],
'---' ) === 0 ) {
3281 unset( $diff_lines[0] );
3283 if ( strpos( $diff_lines[1],
'+++' ) === 0 ) {
3284 unset( $diff_lines[1] );
3287 $diff = implode(
"\n", $diff_lines );
3309 $php_ver = PHP_VERSION;
3311 if ( version_compare( $php_ver, (
string)$req_ver,
'<' ) ) {
3312 throw new MWException(
"PHP $req_ver required--this is only $php_ver" );
3338 function wfUseMW( $req_ver ) {
3341 if ( version_compare( $wgVersion, (
string)$req_ver,
'<' ) ) {
3342 throw new MWException(
"MediaWiki $req_ver required--this is only $wgVersion" );
3359 if ( $suffix ==
'' ) {
3362 $encSuffix =
'(?:' . preg_quote( $suffix,
'#' ) .
')?';
3366 if ( preg_match(
"#([^/\\\\]*?){$encSuffix}[/\\\\]*$#",
$path,
$matches ) ) {
3384 $path = str_replace(
'/', DIRECTORY_SEPARATOR,
$path );
3385 $from = str_replace(
'/', DIRECTORY_SEPARATOR,
$from );
3391 $pieces = explode( DIRECTORY_SEPARATOR, dirname(
$path ) );
3392 $against = explode( DIRECTORY_SEPARATOR,
$from );
3394 if ( $pieces[0] !== $against[0] ) {
3401 while ( count( $pieces ) && count( $against )
3402 && $pieces[0] == $against[0] ) {
3403 array_shift( $pieces );
3404 array_shift( $against );
3408 while ( count( $against ) ) {
3409 array_unshift( $pieces,
'..' );
3410 array_shift( $against );
3415 return implode( DIRECTORY_SEPARATOR, $pieces );
3433 function wfBaseConvert( $input, $sourceBase, $destBase, $pad = 1,
3434 $lowercase =
true, $engine =
'auto'
3436 $input = (string)$input;
3442 $sourceBase != (
int)$sourceBase ||
3443 $destBase != (int)$destBase ||
3444 $pad != (
int)$pad ||
3446 "/^[" . substr(
'0123456789abcdefghijklmnopqrstuvwxyz', 0, $sourceBase ) .
"]+$/i",
3453 static $baseChars =
array(
3454 10 =>
'a', 11 =>
'b', 12 =>
'c', 13 =>
'd', 14 =>
'e', 15 =>
'f',
3455 16 =>
'g', 17 =>
'h', 18 =>
'i', 19 =>
'j', 20 =>
'k', 21 =>
'l',
3456 22 =>
'm', 23 =>
'n', 24 =>
'o', 25 =>
'p', 26 =>
'q', 27 =>
'r',
3457 28 =>
's', 29 =>
't', 30 =>
'u', 31 =>
'v', 32 =>
'w', 33 =>
'x',
3458 34 =>
'y', 35 =>
'z',
3460 '0' => 0,
'1' => 1,
'2' => 2,
'3' => 3,
'4' => 4,
'5' => 5,
3461 '6' => 6,
'7' => 7,
'8' => 8,
'9' => 9,
'a' => 10,
'b' => 11,
3462 'c' => 12,
'd' => 13,
'e' => 14,
'f' => 15,
'g' => 16,
'h' => 17,
3463 'i' => 18,
'j' => 19,
'k' => 20,
'l' => 21,
'm' => 22,
'n' => 23,
3464 'o' => 24,
'p' => 25,
'q' => 26,
'r' => 27,
's' => 28,
't' => 29,
3465 'u' => 30,
'v' => 31,
'w' => 32,
'x' => 33,
'y' => 34,
'z' => 35
3468 if ( extension_loaded(
'gmp' ) && ( $engine ==
'auto' || $engine ==
'gmp' ) ) {
3469 $result = gmp_strval( gmp_init( $input, $sourceBase ), $destBase );
3470 } elseif ( extension_loaded(
'bcmath' ) && ( $engine ==
'auto' || $engine ==
'bcmath' ) ) {
3472 foreach ( str_split( strtolower( $input ) )
as $char ) {
3473 $decimal = bcmul( $decimal, $sourceBase );
3474 $decimal = bcadd( $decimal, $baseChars[$char] );
3477 for (
$result =
''; bccomp( $decimal, 0 ); $decimal = bcdiv( $decimal, $destBase, 0 ) ) {
3478 $result .= $baseChars[bcmod( $decimal, $destBase )];
3483 $inDigits =
array();
3484 foreach ( str_split( strtolower( $input ) )
as $char ) {
3485 $inDigits[] = $baseChars[$char];
3491 while ( $inDigits ) {
3493 $workDigits =
array();
3496 foreach ( $inDigits
as $digit ) {
3497 $work *= $sourceBase;
3500 if ( $workDigits || $work >= $destBase ) {
3501 $workDigits[] = (int)( $work / $destBase );
3511 $inDigits = $workDigits;
3517 if ( !$lowercase ) {
3521 return str_pad(
$result, $pad,
'0', STR_PAD_LEFT );
3531 (
wfIsWindows() && version_compare( PHP_VERSION,
'5.3.3',
'>=' ) )
3532 || ini_get(
'session.entropy_file' )
3534 && intval( ini_get(
'session.entropy_length' ) ) >= 32;
3543 if ( isset( $_COOKIE[session_name()] ) || session_id() ) {
3555 if ( !$entropyEnabled ) {
3556 wfDebug( __METHOD__ .
": PHP's built in entropy is disabled or not sufficient, " .
3557 "overriding session id generation using our cryptrand source.\n" );
3569 $oldSessionId = session_id();
3570 $cookieParams = session_get_cookie_params();
3571 if (
wfCheckEntropy() && $wgCookieSecure == $cookieParams[
'secure'] ) {
3572 session_regenerate_id(
false );
3579 $newSessionId = session_id();
3580 wfRunHooks(
'ResetSessionID',
array( $oldSessionId, $newSessionId ) );
3589 global $wgSessionsInMemcached, $wgSessionsInObjectCache, $wgCookiePath, $wgCookieDomain,
3590 $wgCookieSecure, $wgCookieHttpOnly, $wgSessionHandler;
3591 if ( $wgSessionsInObjectCache || $wgSessionsInMemcached ) {
3593 } elseif ( $wgSessionHandler && $wgSessionHandler != ini_get(
'session.save_handler' ) ) {
3594 # Only set this if $wgSessionHandler isn't null and session.save_handler
3595 # hasn't already been set to the desired value (that causes errors)
3596 ini_set(
'session.save_handler', $wgSessionHandler );
3598 session_set_cookie_params(
3599 0, $wgCookiePath, $wgCookieDomain, $wgCookieSecure, $wgCookieHttpOnly );
3600 session_cache_limiter(
'private, must-revalidate' );
3602 session_id( $sessionId );
3620 $file =
"$IP/serialized/$name";
3621 if ( file_exists(
$file ) ) {
3624 return unserialize(
$blob );
3638 $prefix = $wgCachePrefix ===
false ?
wfWikiID() : $wgCachePrefix;
3639 $args = func_get_args();
3640 $key = $prefix .
':' . implode(
':',
$args );
3641 $key = str_replace(
' ',
'_', $key );
3654 $args = array_slice( func_get_args(), 2 );
3656 $key =
"$db-$prefix:" . implode(
':',
$args );
3658 $key = $db .
':' . implode(
':',
$args );
3660 return str_replace(
' ',
'_', $key );
3671 if ( $wgDBprefix ) {
3672 return "$wgDBname-$wgDBprefix";
3686 $bits = explode(
'-', $wiki, 2 );
3687 if ( count( $bits ) < 2 ) {
3715 function &
wfGetDB( $db, $groups =
array(), $wiki =
false ) {
3716 return wfGetLB( $wiki )->getConnection( $db, $groups, $wiki );
3725 function wfGetLB( $wiki =
false ) {
3795 function wfScript( $script =
'index' ) {
3796 global $wgScriptPath, $wgScriptExtension, $wgScript, $wgLoadScript;
3797 if ( $script ===
'index' ) {
3799 } elseif ( $script ===
'load' ) {
3800 return $wgLoadScript;
3802 return "{$wgScriptPath}/{$script}{$wgScriptExtension}";
3812 if ( isset( $_SERVER[
'SCRIPT_NAME'] ) ) {
3814 # as it was called, minus the query string.
3816 # Some sites use Apache rewrite rules to handle subdomains,
3817 # and have PHP set up in a weird way that causes PHP_SELF
3818 # to contain the rewritten URL instead of the one that the
3819 # outside world sees.
3821 # If in this mode, use SCRIPT_URL instead, which mod_rewrite
3822 # provides containing the "before" URL.
3823 return $_SERVER[
'SCRIPT_NAME'];
3825 return $_SERVER[
'URL'];
3837 return $value ?
'true' :
'false';
3860 function wfWaitForSlaves( $maxLag =
false, $wiki =
false, $cluster =
false ) {
3861 if ( $cluster !==
false ) {
3869 if (
$lb->getServerCount() > 1 ) {
3871 $pos = $dbw->getMasterPos();
3874 if ( $pos !==
false ) {
3875 $lb->waitForAll( $pos );
3888 for ( $i = $seconds; $i >= 0; $i-- ) {
3889 if ( $i != $seconds ) {
3890 echo str_repeat(
"\x08", strlen( $i + 1 ) );
3910 global $wgIllegalFileChars;
3911 $illegalFileChars = $wgIllegalFileChars ?
"|[" . $wgIllegalFileChars .
"]" :
'';
3913 $name = preg_replace(
3929 if ( $memlimit != -1 ) {
3931 if ( $conflimit == -1 ) {
3932 wfDebug(
"Removing PHP's memory limit\n" );
3934 ini_set(
'memory_limit', $conflimit );
3937 } elseif ( $conflimit > $memlimit ) {
3938 wfDebug(
"Raising PHP's memory limit to $conflimit bytes\n" );
3940 ini_set(
'memory_limit', $conflimit );
3956 $string = trim( $string );
3957 if ( $string ===
'' ) {
3960 $last = $string[strlen( $string ) - 1];
3961 $val = intval( $string );
3987 $codeSegment = explode(
'-', $code );
3989 foreach ( $codeSegment
as $segNo => $seg ) {
3991 if ( $segNo > 0 && strtolower( $codeSegment[( $segNo - 1 )] ) ==
'x' ) {
3992 $codeBCP[$segNo] = strtolower( $seg );
3994 } elseif ( ( strlen( $seg ) == 2 ) && ( $segNo > 0 ) ) {
3995 $codeBCP[$segNo] = strtoupper( $seg );
3997 } elseif ( ( strlen( $seg ) == 4 ) && ( $segNo > 0 ) ) {
3998 $codeBCP[$segNo] = ucfirst( strtolower( $seg ) );
4001 $codeBCP[$segNo] = strtolower( $seg );
4004 $langCode = implode(
'-', $codeBCP );
4034 global $wgMessageCacheType;
4044 global $wgParserCacheType;
4054 global $wgLanguageConverterCacheType;
4085 function wfUnpack( $format, $data, $length =
false ) {
4086 if ( $length !==
false ) {
4087 $realLen = strlen( $data );
4088 if ( $realLen < $length ) {
4089 throw new MWException(
"Tried to use wfUnpack on a "
4090 .
"string of length $realLen, but needed one "
4091 .
"of at least length $length."
4097 $result = unpack( $format, $data );
4102 throw new MWException(
"unpack could not unpack binary data" );
4122 static $badImageCache =
null;
4127 if ( $redirectTitle ) {
4128 $name = $redirectTitle->getDBkey();
4131 # Run the extension hook
4138 $cacheable = ( $blacklist === null );
4139 if ( $cacheable && $badImageCache !==
null ) {
4140 $badImages = $badImageCache;
4142 if ( $blacklist ===
null ) {
4143 $blacklist =
wfMessage(
'bad_image_list' )->inContentLanguage()->plain();
4145 # Build the list now
4146 $badImages =
array();
4147 $lines = explode(
"\n", $blacklist );
4150 if ( substr(
$line, 0, 1 ) !==
'*' ) {
4156 if ( !preg_match_all(
'/\[\[:?(.*?)\]\]/',
$line, $m ) ) {
4161 $imageDBkey =
false;
4162 foreach ( $m[1]
as $i => $titleText ) {
4164 if ( !is_null(
$title ) ) {
4166 $imageDBkey =
$title->getDBkey();
4173 if ( $imageDBkey !==
false ) {
4178 $badImageCache = $badImages;
4182 $contextKey = $contextTitle ? $contextTitle->getPrefixedDBkey() :
false;
4183 $bad = isset( $badImages[
$name] ) && !isset( $badImages[
$name][$contextKey] );
4211 return $wgRequest->getIP();
4236 global $wgSquidServers, $wgSquidServersNoPurge;
4239 $trusted = in_array( $ip, $wgSquidServers )
4240 || in_array( $ip, $wgSquidServersNoPurge );
4245 foreach ( $wgSquidServersNoPurge
as $block ) {
4246 if ( strpos( $block,
'/' ) !==
false &&
IP::isInRange( $ip, $block ) ) {