23 if ( !defined(
'MEDIAWIKI' ) ) {
24 die(
"This file is part of MediaWiki, it is not a valid entry point" );
38 if ( !function_exists(
'iconv' ) ) {
43 function iconv(
$from, $to, $string ) {
48 if ( !function_exists(
'mb_substr' ) ) {
53 function mb_substr( $str, $start,
$count =
'end' ) {
61 function mb_substr_split_unicode( $str, $splitPos ) {
66 if ( !function_exists(
'mb_strlen' ) ) {
71 function mb_strlen( $str, $enc =
'' ) {
76 if ( !function_exists(
'mb_strpos' ) ) {
81 function mb_strpos( $haystack, $needle, $offset = 0, $encoding =
'' ) {
86 if ( !function_exists(
'mb_strrpos' ) ) {
91 function mb_strrpos( $haystack, $needle, $offset = 0, $encoding =
'' ) {
98 if ( !function_exists(
'gzdecode' ) ) {
103 function gzdecode( $data ) {
104 return gzinflate( substr( $data, 10, -8 ) );
109 if ( !function_exists(
'hash_equals' ) ) {
125 function hash_equals( $known_string, $user_string ) {
127 if ( !is_string( $known_string ) ) {
128 trigger_error(
'hash_equals(): Expected known_string to be a string, ' .
129 gettype( $known_string ) .
' given', E_USER_WARNING );
134 if ( !is_string( $user_string ) ) {
135 trigger_error(
'hash_equals(): Expected user_string to be a string, ' .
136 gettype( $user_string ) .
' given', E_USER_WARNING );
144 $known_string_len = strlen( $known_string );
145 $user_string_len = strlen( $user_string );
146 $result = $known_string_len ^ $user_string_len;
147 for ( $i = 0; $i < $user_string_len; $i++ ) {
148 $result |= ord( $known_string[$i % $known_string_len] ) ^ ord( $user_string[$i] );
163 return array_udiff( $a, $b,
'wfArrayDiff2_cmp' );
172 if ( is_string( $a ) && is_string( $b ) ) {
173 return strcmp( $a, $b );
174 } elseif ( count( $a ) !== count( $b ) ) {
175 return count( $a ) < count( $b ) ? -1 : 1;
179 while ( (
list( , $valueA ) = each( $a ) ) && (
list( , $valueB ) = each( $b ) ) ) {
180 $cmp = strcmp( $valueA, $valueB );
201 return array_flip( array_intersect( array_flip( $a ), array_keys( $b ) ) );
215 throw new MWException(
'GlobalFunctions::wfAppendToArrayIfNotDefault got null' );
217 if ( $default[$key] !==
$value ) {
234 $args = func_get_args();
263 $args = func_get_args();
267 # @todo FIXME: Sometimes get nested arrays for $params,
268 # which leads to E_NOTICEs
269 $spec = implode(
"\t",
$params );
273 return array_values(
$out );
286 $keys = array_keys( $array );
287 $offsetByKey = array_flip(
$keys );
289 $offset = $offsetByKey[$after];
292 $before = array_slice( $array, 0, $offset + 1,
true );
293 $after = array_slice( $array, $offset + 1, count( $array ) - $offset,
true );
295 $output = $before + $insert + $after;
309 if ( is_object( $objOrArray ) ) {
310 $objOrArray = get_object_vars( $objOrArray );
312 foreach ( $objOrArray
as $key =>
$value ) {
313 if ( $recursive && ( is_object(
$value ) || is_array(
$value ) ) ) {
331 # The maximum random value is "only" 2^31-1, so get two random
332 # values to reduce the chance of dupes
333 $max = mt_getrandmax() + 1;
334 $rand = number_format( ( mt_rand() * $max + mt_rand() ) / $max / $max, 12,
'.',
'' );
351 for (
$n = 0;
$n < $length;
$n += 7 ) {
352 $str .= sprintf(
'%07x', mt_rand() & 0xfffffff );
354 return substr( $str, 0, $length );
382 if ( is_null(
$s ) ) {
387 if ( is_null( $needle ) ) {
388 $needle =
array(
'%3B',
'%40',
'%24',
'%21',
'%2A',
'%28',
'%29',
'%2C',
'%2F' );
389 if ( !isset( $_SERVER[
'SERVER_SOFTWARE'] ) ||
390 ( strpos( $_SERVER[
'SERVER_SOFTWARE'],
'Microsoft-IIS/7' ) ===
false )
396 $s = urlencode(
$s );
399 array(
';',
'@',
'$',
'!',
'*',
'(',
')',
',',
'/',
':' ),
416 function wfArrayToCgi( $array1, $array2 =
null, $prefix =
'' ) {
417 if ( !is_null( $array2 ) ) {
418 $array1 = $array1 + $array2;
422 foreach ( $array1
as $key =>
$value ) {
427 if ( $prefix !==
'' ) {
428 $key = $prefix .
"[$key]";
430 if ( is_array(
$value ) ) {
433 $cgi .= $firstTime ?
'' :
'&';
434 if ( is_array( $v ) ) {
437 $cgi .= urlencode( $key .
"[$k]" ) .
'=' . urlencode( $v );
442 if ( is_object(
$value ) ) {
445 $cgi .= urlencode( $key ) .
'=' . urlencode(
$value );
465 $bits = explode(
'&',
$query );
467 foreach ( $bits
as $bit ) {
471 if ( strpos( $bit,
'=' ) ===
false ) {
478 $key = urldecode( $key );
480 if ( strpos( $key,
'[' ) !==
false ) {
481 $keys = array_reverse( explode(
'[', $key ) );
482 $key = array_pop(
$keys );
485 $k = substr( $k, 0, -1 );
486 $temp =
array( $k => $temp );
488 if ( isset(
$ret[$key] ) ) {
489 $ret[$key] = array_merge(
$ret[$key], $temp );
509 if ( is_array(
$query ) ) {
513 if (
false === strpos( $url,
'?' ) ) {
547 global $wgServer, $wgCanonicalServer, $wgInternalServer, $wgRequest;
549 $serverUrl = $wgCanonicalServer;
550 } elseif ( $defaultProto ===
PROTO_INTERNAL && $wgInternalServer !==
false ) {
552 $serverUrl = $wgInternalServer;
554 $serverUrl = $wgServer;
556 $defaultProto = $wgRequest->getProtocol() .
'://';
562 $serverHasProto = $bits && $bits[
'scheme'] !=
'';
565 if ( $serverHasProto ) {
566 $defaultProto = $bits[
'scheme'] .
'://';
575 $defaultProtoWithoutSlashes = substr( $defaultProto, 0, -2 );
577 if ( substr( $url, 0, 2 ) ==
'//' ) {
578 $url = $defaultProtoWithoutSlashes . $url;
579 } elseif ( substr( $url, 0, 1 ) ==
'/' ) {
582 $url = ( $serverHasProto ?
'' : $defaultProtoWithoutSlashes ) . $serverUrl . $url;
586 if ( $bits && isset( $bits[
'path'] ) ) {
592 } elseif ( substr( $url, 0, 1 ) !=
'/' ) {
593 # URL is a relative path
597 # Expanded URL is not valid.
617 if ( isset( $urlParts[
'delimiter'] ) ) {
618 if ( isset( $urlParts[
'scheme'] ) ) {
619 $result .= $urlParts[
'scheme'];
622 $result .= $urlParts[
'delimiter'];
625 if ( isset( $urlParts[
'host'] ) ) {
626 if ( isset( $urlParts[
'user'] ) ) {
628 if ( isset( $urlParts[
'pass'] ) ) {
629 $result .=
':' . $urlParts[
'pass'];
636 if ( isset( $urlParts[
'port'] ) ) {
637 $result .=
':' . $urlParts[
'port'];
641 if ( isset( $urlParts[
'path'] ) ) {
645 if ( isset( $urlParts[
'query'] ) ) {
646 $result .=
'?' . $urlParts[
'query'];
649 if ( isset( $urlParts[
'fragment'] ) ) {
650 $result .=
'#' . $urlParts[
'fragment'];
669 $inputLength = strlen( $urlPath );
671 while ( $inputOffset < $inputLength ) {
672 $prefixLengthOne = substr( $urlPath, $inputOffset, 1 );
673 $prefixLengthTwo = substr( $urlPath, $inputOffset, 2 );
674 $prefixLengthThree = substr( $urlPath, $inputOffset, 3 );
675 $prefixLengthFour = substr( $urlPath, $inputOffset, 4 );
678 if ( $prefixLengthTwo ==
'./' ) {
679 # Step A, remove leading "./"
681 } elseif ( $prefixLengthThree ==
'../' ) {
682 # Step A, remove leading "../"
684 } elseif ( ( $prefixLengthTwo ==
'/.' ) && ( $inputOffset + 2 == $inputLength ) ) {
685 # Step B, replace leading "/.$" with "/"
687 $urlPath[$inputOffset] =
'/';
688 } elseif ( $prefixLengthThree ==
'/./' ) {
689 # Step B, replace leading "/./" with "/"
691 } elseif ( $prefixLengthThree ==
'/..' && ( $inputOffset + 3 == $inputLength ) ) {
692 # Step C, replace leading "/..$" with "/" and
693 # remove last path component in output
695 $urlPath[$inputOffset] =
'/';
697 } elseif ( $prefixLengthFour ==
'/../' ) {
698 # Step C, replace leading "/../" with "/" and
699 # remove last path component in output
702 } elseif ( ( $prefixLengthOne ==
'.' ) && ( $inputOffset + 1 == $inputLength ) ) {
703 # Step D, remove "^.$"
705 } elseif ( ( $prefixLengthTwo ==
'..' ) && ( $inputOffset + 2 == $inputLength ) ) {
706 # Step D, remove "^..$"
709 # Step E, move leading path segment to output
710 if ( $prefixLengthOne ==
'/' ) {
711 $slashPos = strpos( $urlPath,
'/', $inputOffset + 1 );
713 $slashPos = strpos( $urlPath,
'/', $inputOffset );
715 if ( $slashPos ===
false ) {
716 $output .= substr( $urlPath, $inputOffset );
717 $inputOffset = $inputLength;
719 $output .= substr( $urlPath, $inputOffset, $slashPos - $inputOffset );
720 $inputOffset += $slashPos - $inputOffset;
725 $slashPos = strrpos(
$output,
'/' );
726 if ( $slashPos ===
false ) {
748 static $withProtRel =
null, $withoutProtRel =
null;
749 $cachedValue = $includeProtocolRelative ? $withProtRel : $withoutProtRel;
750 if ( !is_null( $cachedValue ) ) {
756 if ( is_array( $wgUrlProtocols ) ) {
757 $protocols =
array();
758 foreach ( $wgUrlProtocols
as $protocol ) {
760 if ( $includeProtocolRelative || $protocol !==
'//' ) {
761 $protocols[] = preg_quote( $protocol,
'/' );
765 $retval = implode(
'|', $protocols );
775 if ( $includeProtocolRelative ) {
810 $wasRelative = substr( $url, 0, 2 ) ==
'//';
811 if ( $wasRelative ) {
815 $bits = parse_url( $url );
819 if ( !$bits || !isset( $bits[
'scheme'] ) ) {
824 $bits[
'scheme'] = strtolower( $bits[
'scheme'] );
827 if ( in_array( $bits[
'scheme'] .
'://', $wgUrlProtocols ) ) {
828 $bits[
'delimiter'] =
'://';
829 } elseif ( in_array( $bits[
'scheme'] .
':', $wgUrlProtocols ) ) {
830 $bits[
'delimiter'] =
':';
833 if ( isset( $bits[
'path'] ) ) {
834 $bits[
'host'] = $bits[
'path'];
842 if ( !isset( $bits[
'host'] ) ) {
846 if ( isset( $bits[
'path'] ) ) {
848 if ( substr( $bits[
'path'], 0, 1 ) !==
'/' ) {
849 $bits[
'path'] =
'/' . $bits[
'path'];
857 if ( $wasRelative ) {
858 $bits[
'scheme'] =
'';
859 $bits[
'delimiter'] =
'//';
875 return preg_replace_callback(
876 '/((?:%[89A-F][0-9A-F])+)/i',
877 'wfExpandIRI_callback',
902 if ( $bits[
'scheme'] ==
'mailto' ) {
903 $mailparts = explode(
'@', $bits[
'host'], 2 );
904 if ( count( $mailparts ) === 2 ) {
905 $domainpart = strtolower( implode(
'.', array_reverse( explode(
'.', $mailparts[1] ) ) ) );
910 $reversedHost = $domainpart .
'@' . $mailparts[0];
912 $reversedHost = strtolower( implode(
'.', array_reverse( explode(
'.', $bits[
'host'] ) ) ) );
916 if ( substr( $reversedHost, -1, 1 ) !==
'.' ) {
917 $reversedHost .=
'.';
920 $prot = $bits[
'scheme'];
921 $index = $prot . $bits[
'delimiter'] . $reversedHost;
923 if ( isset( $bits[
'port'] ) ) {
924 $index .=
':' . $bits[
'port'];
926 if ( isset( $bits[
'path'] ) ) {
927 $index .= $bits[
'path'];
931 if ( isset( $bits[
'query'] ) ) {
932 $index .=
'?' . $bits[
'query'];
934 if ( isset( $bits[
'fragment'] ) ) {
935 $index .=
'#' . $bits[
'fragment'];
939 return array(
"http:$index",
"https:$index" );
941 return array( $index );
953 if ( is_array( $bits ) && isset( $bits[
'host'] ) ) {
954 $host =
'.' . $bits[
'host'];
955 foreach ( (
array)$domains
as $domain ) {
956 $domain =
'.' . $domain;
957 if ( substr( $host, -strlen( $domain ) ) === $domain ) {
982 function wfDebug( $text, $dest =
'all' ) {
983 global $wgDebugLogFile, $wgDebugRawPage, $wgDebugLogPrefix;
990 if ( $dest ===
true ) {
992 } elseif ( $dest ===
false ) {
997 if ( $timer !==
'' ) {
998 $text = preg_replace(
'/[^\n]/', $timer .
'\0', $text, 1 );
1001 if ( $dest ===
'all' ) {
1005 if ( $wgDebugLogFile !=
'' ) {
1006 # Strip unprintables; they can switch terminal modes when binary data
1007 # gets dumped, which is pretty annoying.
1008 $text = preg_replace(
'![\x00-\x08\x0b\x0c\x0e-\x1f]!',
' ', $text );
1009 $text = $wgDebugLogPrefix . $text;
1023 # Check for raw action using $_GET not $wgRequest, since the latter might not be initialised yet
1024 if ( ( isset( $_GET[
'action'] ) && $_GET[
'action'] ==
'raw' )
1026 isset( $_SERVER[
'SCRIPT_NAME'] )
1027 && substr( $_SERVER[
'SCRIPT_NAME'], -8 ) ==
'load.php'
1045 if ( !$wgDebugTimestamps ) {
1049 $prefix = sprintf(
"%6.4f", microtime(
true ) -
$wgRequestTime );
1050 $mem = sprintf(
"%5.1fM", ( memory_get_usage(
true ) / ( 1024 * 1024 ) ) );
1051 return "$prefix $mem ";
1060 $mem = memory_get_usage();
1062 $mem = floor( $mem / 1024 ) .
' kilobytes';
1066 wfDebug(
"Memory usage: $mem\n" );
1089 function wfDebugLog( $logGroup, $text, $dest =
'all' ) {
1090 global $wgDebugLogGroups;
1092 $text = trim( $text ) .
"\n";
1095 if ( $dest ===
true ) {
1097 } elseif ( $dest ===
false ) {
1101 if ( !isset( $wgDebugLogGroups[$logGroup] ) ) {
1102 if ( $dest !==
'private' ) {
1103 wfDebug(
"[$logGroup] $text", $dest );
1108 if ( $dest ===
'all' ) {
1112 $logConfig = $wgDebugLogGroups[$logGroup];
1113 if ( $logConfig ===
false ) {
1116 if ( is_array( $logConfig ) ) {
1117 if ( isset( $logConfig[
'sample'] ) && mt_rand( 1, $logConfig[
'sample'] ) !== 1 ) {
1120 $destination = $logConfig[
'destination'];
1122 $destination = strval( $logConfig );
1128 wfErrorLog(
"$time $host $wiki: $text", $destination );
1137 global $wgDBerrorLog, $wgDBerrorLogTZ;
1138 static $logDBErrorTimeZoneObject =
null;
1140 if ( $wgDBerrorLog ) {
1144 if ( $wgDBerrorLogTZ && !$logDBErrorTimeZoneObject ) {
1145 $logDBErrorTimeZoneObject =
new DateTimeZone( $wgDBerrorLogTZ );
1150 if ( $logDBErrorTimeZoneObject ===
null ) {
1151 $d = date_create(
"now" );
1153 $d = date_create(
"now", $logDBErrorTimeZoneObject );
1156 $date = $d->format(
'D M j G:i:s T Y' );
1158 $text =
"$date\t$host\t$wiki\t" . trim( $text ) .
"\n";
1190 function wfWarn( $msg, $callerOffset = 1, $level = E_USER_NOTICE ) {
1203 function wfLogWarning( $msg, $callerOffset = 1, $level = E_USER_WARNING ) {
1218 if ( substr(
$file, 0, 4 ) ==
'udp:' ) {
1219 # Needs the sockets extension
1220 if ( preg_match(
'!^(tcp|udp):(?://)?\[([0-9a-fA-F:]+)\]:(\d+)(?:/(.*))?$!',
$file, $m ) ) {
1223 $port = intval( $m[3] );
1224 $prefix = isset( $m[4] ) ? $m[4] :
false;
1226 } elseif ( preg_match(
'!^(tcp|udp):(?://)?([a-zA-Z0-9.-]+):(\d+)(?:/(.*))?$!',
$file, $m ) ) {
1229 $host = gethostbyname( $host );
1231 $port = intval( $m[3] );
1232 $prefix = isset( $m[4] ) ? $m[4] :
false;
1235 throw new MWException( __METHOD__ .
': Invalid UDP specification' );
1239 if ( strval( $prefix ) !==
'' ) {
1240 $text = preg_replace(
'/^/m', $prefix .
' ', $text );
1243 if ( strlen( $text ) > 65506 ) {
1244 $text = substr( $text, 0, 65506 );
1247 if ( substr( $text, -1 ) !=
"\n" ) {
1250 } elseif ( strlen( $text ) > 65507 ) {
1251 $text = substr( $text, 0, 65507 );
1254 $sock = socket_create( $domain, SOCK_DGRAM, SOL_UDP );
1259 socket_sendto( $sock, $text, strlen( $text ), 0, $host, $port );
1260 socket_close( $sock );
1263 $exists = file_exists(
$file );
1265 if ( !$exists || (
$size !==
false &&
$size + strlen( $text ) < 0x7fffffff ) ) {
1266 file_put_contents(
$file, $text, FILE_APPEND );
1283 # Profiling must actually be enabled...
1284 if ( $profiler->isStub() ) {
1291 if ( $elapsed <= $wgProfileLimit ) {
1295 $profiler->logData();
1298 if ( isset( $wgDebugLogGroups[
'profileoutput'] )
1299 && $wgDebugLogGroups[
'profileoutput'] ===
false
1304 if ( !isset( $wgDebugLogGroups[
'profileoutput'] ) && $wgDebugLogFile ==
'' ) {
1313 if ( !empty( $_SERVER[
'HTTP_X_FORWARDED_FOR'] ) ) {
1314 $forward =
' forwarded for ' . $_SERVER[
'HTTP_X_FORWARDED_FOR'];
1316 if ( !empty( $_SERVER[
'HTTP_CLIENT_IP'] ) ) {
1317 $forward .=
' client IP ' . $_SERVER[
'HTTP_CLIENT_IP'];
1319 if ( !empty( $_SERVER[
'HTTP_FROM'] ) ) {
1320 $forward .=
' from ' . $_SERVER[
'HTTP_FROM'];
1323 $forward =
"\t(proxied via {$_SERVER['REMOTE_ADDR']}{$forward})";
1328 $forward .=
' anon';
1334 $requestUrl = $wgRequest->getRequestURL();
1336 $requestUrl =
'n/a';
1339 $log = sprintf(
"%s\t%04.3f\t%s\n",
1340 gmdate(
'YmdHis' ), $elapsed,
1341 urldecode( $requestUrl . $forward ) );
1343 wfDebugLog(
'profileoutput', $log . $profiler->getOutput() );
1372 global $wgReadOnly, $wgReadOnlyFile;
1374 if ( $wgReadOnly ===
null ) {
1376 if ( is_file( $wgReadOnlyFile ) && filesize( $wgReadOnlyFile ) > 0 ) {
1377 $wgReadOnly = file_get_contents( $wgReadOnlyFile );
1379 $wgReadOnly =
false;
1402 # Identify which language to get or create a language object for.
1403 # Using is_object here due to Stub objects.
1404 if ( is_object( $langcode ) ) {
1405 # Great, we already have the object (hopefully)!
1410 if ( $langcode ===
true || $langcode === $wgLanguageCode ) {
1411 # $langcode is the language code of the wikis content language object.
1412 # or it is a boolean and value is true
1417 if ( $langcode ===
false || $langcode ===
$wgLang->getCode() ) {
1418 # $langcode is the language code of user language object.
1419 # or it was a boolean and value is false
1424 if ( in_array( $langcode, $validCodes ) ) {
1425 # $langcode corresponds to a valid language.
1429 # $langcode is a string, but not a valid language code; use content language.
1430 wfDebug(
"Invalid language code passed to wfGetLangObj, falling back to content language.\n" );
1456 return new Message( $key,
$params );
1472 $args = func_get_args();
1473 return call_user_func_array(
'Message::newFallbackSequence',
$args );
1495 function wfMsg( $key ) {
1498 $args = func_get_args();
1499 array_shift(
$args );
1514 $args = func_get_args();
1515 array_shift(
$args );
1547 global $wgForceUIMsgAsContentMsg;
1548 $args = func_get_args();
1549 array_shift(
$args );
1551 if ( is_array( $wgForceUIMsgAsContentMsg )
1552 && in_array( $key, $wgForceUIMsgAsContentMsg )
1554 $forcontent =
false;
1570 global $wgForceUIMsgAsContentMsg;
1571 $args = func_get_args();
1572 array_shift(
$args );
1574 if ( is_array( $wgForceUIMsgAsContentMsg )
1575 && in_array( $key, $wgForceUIMsgAsContentMsg )
1577 $forcontent =
false;
1594 function wfMsgReal( $key,
$args, $useDB =
true, $forContent =
false, $transform =
true ) {
1598 $message =
wfMsgGetKey( $key, $useDB, $forContent, $transform );
1616 function wfMsgGetKey( $key, $useDB =
true, $langCode =
false, $transform =
true ) {
1619 wfRunHooks(
'NormalizeMessageKey',
array( &$key, &$useDB, &$langCode, &$transform ) );
1622 $message =
$cache->get( $key, $useDB, $langCode );
1623 if ( $message ===
false ) {
1624 $message =
'<' . htmlspecialchars( $key ) .
'>';
1625 } elseif ( $transform ) {
1626 $message =
$cache->transform( $message );
1640 # Fix windows line-endings
1641 # Some messages are split with explode("\n", $msg)
1642 $message = str_replace(
"\r",
'', $message );
1645 if ( count(
$args ) ) {
1646 if ( is_array(
$args[0] ) ) {
1649 $replacementKeys =
array();
1651 $replacementKeys[
'$' . (
$n + 1 )] = $param;
1653 $message = strtr( $message, $replacementKeys );
1675 $args = func_get_args();
1676 array_shift(
$args );
1696 $args = func_get_args();
1697 array_shift(
$args );
1700 true,
true )->getText(),
1730 $args = func_get_args();
1731 array_shift(
$args );
1732 array_shift(
$args );
1735 foreach (
$options as $arrayKey => $option ) {
1736 if ( !preg_match(
'/^[0-9]+|language$/', $arrayKey ) ) {
1737 # An unknown index, neither numeric nor "language"
1738 wfWarn(
"wfMsgExt called with incorrect parameter key $arrayKey", 1, E_USER_WARNING );
1739 } elseif ( preg_match(
'/^[0-9]+$/', $arrayKey ) && !in_array( $option,
1740 array(
'parse',
'parseinline',
'escape',
'escapenoentities',
1741 'replaceafter',
'parsemag',
'content' ) ) ) {
1742 # A numeric index with unknown value
1743 wfWarn(
"wfMsgExt called with incorrect parameter $option", 1, E_USER_WARNING );
1747 if ( in_array(
'content',
$options,
true ) ) {
1750 $langCodeObj =
null;
1751 } elseif ( array_key_exists(
'language',
$options ) ) {
1752 $forContent =
false;
1754 $langCodeObj = $langCode;
1756 $forContent =
false;
1758 $langCodeObj =
null;
1761 $string =
wfMsgGetKey( $key,
true, $langCode,
false );
1763 if ( !in_array(
'replaceafter',
$options,
true ) ) {
1768 $parseInline = in_array(
'parseinline',
$options,
true );
1769 if ( in_array(
'parse',
$options,
true ) || $parseInline ) {
1770 $string = $messageCache->parse( $string,
null,
true, !$forContent, $langCodeObj );
1772 $string = $string->getText();
1775 if ( $parseInline ) {
1777 if ( preg_match(
'/^<p>(.*)\n?<\/p>\n?$/sU', $string, $m ) ) {
1781 } elseif ( in_array(
'parsemag',
$options,
true ) ) {
1782 $string = $messageCache->transform( $string,
1783 !$forContent, $langCodeObj );
1786 if ( in_array(
'escape',
$options,
true ) ) {
1787 $string = htmlspecialchars ( $string );
1788 } elseif ( in_array(
'escapenoentities',
$options,
true ) ) {
1792 if ( in_array(
'replaceafter',
$options,
true ) ) {
1837 if ( is_null( $host ) ) {
1839 # Hostname overriding
1840 global $wgOverrideHostname;
1841 if ( $wgOverrideHostname !==
false ) {
1842 # Set static and skip any detection
1843 $host = $wgOverrideHostname;
1847 if ( function_exists(
'posix_uname' ) ) {
1849 $uname = posix_uname();
1853 if ( is_array( $uname ) && isset( $uname[
'nodename'] ) ) {
1854 $host = $uname[
'nodename'];
1855 } elseif ( getenv(
'COMPUTERNAME' ) ) {
1856 # Windows computer name
1857 $host = getenv(
'COMPUTERNAME' );
1859 # This may be a virtual server.
1860 $host = $_SERVER[
'SERVER_NAME'];
1878 $responseTime = round( ( microtime(
true ) -
$wgRequestTime ) * 1000 );
1879 $reportVars =
array(
'wgBackendResponseTime' => $responseTime );
1880 if ( $wgShowHostnames ) {
1902 static $disabled =
null;
1904 if ( extension_loaded(
'Zend Optimizer' ) ) {
1905 wfDebug(
"Zend Optimizer detected; skipping debug_backtrace for safety.\n" );
1909 if ( is_null( $disabled ) ) {
1911 $functions = explode(
',', ini_get(
'disable_functions' ) );
1912 $functions = array_map(
'trim', $functions );
1913 $functions = array_map(
'strtolower', $functions );
1914 if ( in_array(
'debug_backtrace', $functions ) ) {
1915 wfDebug(
"debug_backtrace is in disabled_functions\n" );
1923 if (
$limit && version_compare( PHP_VERSION,
'5.4.0',
'>=' ) ) {
1924 return array_slice( debug_backtrace( DEBUG_BACKTRACE_PROVIDE_OBJECT,
$limit + 1 ), 1 );
1926 return array_slice( debug_backtrace(), 1 );
1944 foreach ( $backtrace
as $call ) {
1945 if ( isset( $call[
'file'] ) ) {
1946 $f = explode( DIRECTORY_SEPARATOR, $call[
'file'] );
1951 if ( isset( $call[
'line'] ) ) {
1952 $line = $call[
'line'];
1957 $msg .=
"$file line $line calls ";
1959 $msg .=
'<li>' .
$file .
' line ' .
$line .
' calls ';
1961 if ( !empty( $call[
'class'] ) ) {
1962 $msg .= $call[
'class'] . $call[
'type'];
1964 $msg .= $call[
'function'] .
'()';
1992 if ( isset( $backtrace[$level] ) ) {
2010 $limit = count( $trace ) - 1;
2013 return implode(
'/', array_map(
'wfFormatStackFrame', $trace ) );
2023 return isset( $frame[
'class'] ) ?
2024 $frame[
'class'] .
'::' . $frame[
'function'] :
2038 return wfMessage(
'showingresults' )->numParams(
$limit, $offset + 1 )->parse();
2059 if ( is_object(
$link ) ) {
2063 if ( is_null(
$title ) ) {
2080 if (
$result ===
null || $force ) {
2082 if ( isset( $_SERVER[
'HTTP_ACCEPT_ENCODING'] ) ) {
2083 # @todo FIXME: We may want to blacklist some broken browsers
2086 '/\bgzip(?:;(q)=([0-9]+(?:\.[0-9]+)))?\b/',
2087 $_SERVER[
'HTTP_ACCEPT_ENCODING'],
2091 if ( isset( $m[2] ) && ( $m[1] ==
'q' ) && ( $m[2] == 0 ) ) {
2095 wfDebug(
"wfClientAcceptsGzip: client accepts gzip.\n" );
2112 function wfCheckLimits( $deflimit = 50, $optionname =
'rclimit' ) {
2114 return $wgRequest->getLimitOffset( $deflimit, $optionname );
2127 static $repl =
null, $repl2 =
null;
2128 if ( $repl ===
null ) {
2130 '"' =>
'"',
'&' =>
'&',
"'" =>
''',
'<' =>
'<',
2131 '=' =>
'=',
'>' =>
'>',
'[' =>
'[',
']' =>
']',
2132 '{' =>
'{',
'|' =>
'|',
'}' =>
'}',
';' =>
';',
2133 "\n#" =>
"\n#",
"\r#" =>
"\r#",
2134 "\n*" =>
"\n*",
"\r*" =>
"\r*",
2135 "\n:" =>
"\n:",
"\r:" =>
"\r:",
2136 "\n " =>
"\n ",
"\r " =>
"\r ",
2137 "\n\n" =>
"\n ",
"\r\n" =>
" \n",
2138 "\n\r" =>
"\n ",
"\r\r" =>
"\r ",
2139 "\n\t" =>
"\n	",
"\r\t" =>
"\r	",
2140 "\n----" =>
"\n----",
"\r----" =>
"\r----",
2141 '__' =>
'__',
'://' =>
'://',
2145 foreach (
array(
'ISBN',
'RFC',
'PMID' )
as $magic ) {
2146 $repl[
"$magic "] =
"$magic ";
2147 $repl[
"$magic\t"] =
"$magic	";
2148 $repl[
"$magic\r"] =
"$magic ";
2149 $repl[
"$magic\n"] =
"$magic ";
2150 $repl[
"$magic\f"] =
"$magic";
2156 foreach ( $wgUrlProtocols
as $prot ) {
2157 if ( substr( $prot, -1 ) ===
':' ) {
2158 $repl2[] = preg_quote( substr( $prot, 0, -1 ),
'/' );
2161 $repl2 = $repl2 ?
'/\b(' . join(
'|', $repl2 ) .
'):/i' :
'/^(?!)/';
2163 $text = substr( strtr(
"\n$text", $repl ), 1 );
2164 $text = preg_replace( $repl2,
'$1:', $text );
2175 return microtime(
true );
2190 if ( !is_null(
$source ) || $force ) {
2205 function wfSetBit( &$dest, $bit, $state =
true ) {
2206 $temp = (bool)( $dest & $bit );
2207 if ( !is_null( $state ) ) {
2225 $s = str_replace(
"\n",
"<br />\n", var_export( $var,
true ) .
"\n" );
2226 if ( headers_sent() || !isset(
$wgOut ) || !is_object(
$wgOut ) ) {
2243 header(
"HTTP/1.0 $code $label" );
2244 header(
"Status: $code $label" );
2245 $wgOut->sendCacheControl();
2247 header(
'Content-type: text/html; charset=utf-8' );
2248 print
"<!doctype html>" .
2249 '<html><head><title>' .
2250 htmlspecialchars( $label ) .
2251 '</title></head><body><h1>' .
2252 htmlspecialchars( $label ) .
2254 nl2br( htmlspecialchars( $desc ) ) .
2255 "</p></body></html>\n";
2276 if ( $resetGzipEncoding ) {
2279 global $wgDisableOutputCompression;
2280 $wgDisableOutputCompression =
true;
2282 while ( $status = ob_get_status() ) {
2283 if ( $status[
'type'] == 0 ) {
2291 if ( !ob_end_clean() ) {
2296 if ( $resetGzipEncoding ) {
2297 if ( $status[
'name'] ==
'ob_gzhandler' ) {
2300 header_remove(
'Content-Encoding' );
2332 # No arg means accept anything (per HTTP spec)
2334 return array( $def => 1.0 );
2339 $parts = explode(
',', $accept );
2341 foreach ( $parts
as $part ) {
2342 # @todo FIXME: Doesn't deal with params like 'text/html; level=1'
2343 $values = explode(
';', trim( $part ) );
2345 if ( count( $values ) == 1 ) {
2346 $prefs[$values[0]] = 1.0;
2347 } elseif ( preg_match(
'/q\s*=\s*(\d*\.\d+)/', $values[1], $match ) ) {
2348 $prefs[$values[0]] = floatval( $match[1] );
2368 if ( array_key_exists(
$type, $avail ) ) {
2371 $parts = explode(
'/',
$type );
2372 if ( array_key_exists( $parts[0] .
'/*', $avail ) ) {
2373 return $parts[0] .
'/*';
2374 } elseif ( array_key_exists(
'*/*', $avail ) ) {
2398 foreach ( array_keys( $sprefs )
as $type ) {
2399 $parts = explode(
'/',
$type );
2400 if ( $parts[1] !=
'*' ) {
2403 $combine[
$type] = $sprefs[
$type] * $cprefs[$ckey];
2408 foreach ( array_keys( $cprefs )
as $type ) {
2409 $parts = explode(
'/',
$type );
2410 if ( $parts[1] !=
'*' && !array_key_exists(
$type, $sprefs ) ) {
2413 $combine[
$type] = $sprefs[$skey] * $cprefs[
$type];
2421 foreach ( array_keys( $combine )
as $type ) {
2422 if ( $combine[
$type] > $bestq ) {
2424 $bestq = $combine[
$type];
2437 static $suppressCount = 0;
2438 static $originalLevel =
false;
2441 if ( $suppressCount ) {
2443 if ( !$suppressCount ) {
2444 error_reporting( $originalLevel );
2448 if ( !$suppressCount ) {
2449 $originalLevel = error_reporting( E_ALL & ~(
2470 # Autodetect, convert and provide timestamps of various types
2475 define(
'TS_UNIX', 0 );
2480 define(
'TS_MW', 1 );
2485 define(
'TS_DB', 2 );
2490 define(
'TS_RFC2822', 3 );
2497 define(
'TS_ISO_8601', 4 );
2506 define(
'TS_EXIF', 5 );
2511 define(
'TS_ORACLE', 6 );
2516 define(
'TS_POSTGRES', 7 );
2521 define(
'TS_ISO_8601_BASIC', 9 );
2535 return $timestamp->getTimestamp( $outputtype );
2537 wfDebug(
"wfTimestamp() fed bogus time value: TYPE=$outputtype; VALUE=$ts\n" );
2551 if ( is_null( $ts ) ) {
2574 static $isWindows =
null;
2575 if ( $isWindows ===
null ) {
2576 $isWindows = substr( php_uname(), 0, 7 ) ==
'Windows';
2587 return defined(
'HHVM_VERSION' );
2596 function swap( &$x, &$y ) {
2616 if ( $wgTmpDirectory !==
false ) {
2617 return $wgTmpDirectory;
2620 $tmpDir = array_map(
"getenv",
array(
'TMPDIR',
'TMP',
'TEMP' ) );
2622 foreach ( $tmpDir
as $tmp ) {
2623 if ( $tmp && file_exists( $tmp ) && is_dir( $tmp ) && is_writable( $tmp ) ) {
2627 return sys_get_temp_dir();
2643 throw new MWException( __FUNCTION__ .
" given storage path '$dir'." );
2646 if ( !is_null( $caller ) ) {
2647 wfDebug(
"$caller: called wfMkdirParents($dir)\n" );
2650 if ( strval(
$dir ) ===
'' || ( file_exists(
$dir ) && is_dir(
$dir ) ) ) {
2654 $dir = str_replace(
array(
'\\',
'/' ), DIRECTORY_SEPARATOR,
$dir );
2656 if ( is_null( $mode ) ) {
2657 $mode = $wgDirectoryMode;
2662 $ok = mkdir(
$dir, $mode,
true );
2667 if ( is_dir(
$dir ) ) {
2682 wfDebug( __FUNCTION__ .
"( $dir )\n" );
2684 if ( is_dir(
$dir ) ) {
2685 $objects = scandir(
$dir );
2686 foreach ( $objects
as $object ) {
2687 if ( $object !=
"." && $object !=
".." ) {
2688 if ( filetype(
$dir .
'/' . $object ) ==
"dir" ) {
2691 unlink(
$dir .
'/' . $object );
2706 function wfPercent( $nr, $acc = 2, $round =
true ) {
2707 $ret = sprintf(
"%.${acc}f", $nr );
2708 return $round ? round(
$ret, $acc ) .
'%' :
"$ret%";
2735 $val = strtolower( ini_get( $setting ) );
2740 || preg_match(
"/^\s*[+-]?0*[1-9]/", $val );
2757 $args = func_get_args();
2777 $tokens = preg_split(
'/(\\\\*")/', $arg, -1, PREG_SPLIT_DELIM_CAPTURE );
2780 foreach ( $tokens
as $token ) {
2781 if ( $iteration % 2 == 1 ) {
2783 $arg .= str_replace(
'\\',
'\\\\', substr( $token, 0, -1 ) ) .
'\\"';
2784 } elseif ( $iteration % 4 == 2 ) {
2786 $arg .= str_replace(
'^',
'^^', $token );
2796 if ( preg_match(
'/^(.*?)(\\\\+)$/', $arg, $m ) ) {
2797 $arg = $m[1] . str_replace(
'\\',
'\\\\', $m[2] );
2801 $retVal .=
'"' . $arg .
'"';
2803 $retVal .= escapeshellarg( $arg );
2816 static $disabled =
null;
2817 if ( is_null( $disabled ) ) {
2820 wfDebug(
"wfShellExec can't run in safe_mode, PHP's exec functions are too broken.\n" );
2821 $disabled =
'safemode';
2823 $functions = explode(
',', ini_get(
'disable_functions' ) );
2824 $functions = array_map(
'trim', $functions );
2825 $functions = array_map(
'strtolower', $functions );
2826 if ( in_array(
'proc_open', $functions ) ) {
2827 wfDebug(
"proc_open is in disabled_functions\n" );
2828 $disabled =
'disabled';
2856 global $IP, $wgMaxShellMemory, $wgMaxShellFileSize, $wgMaxShellTime,
2857 $wgMaxShellWallClockTime, $wgShellCgroup;
2862 return $disabled ==
'safemode' ?
2863 'Unable to run external programs in safe mode.' :
2864 'Unable to run external programs, proc_open() is disabled.';
2867 $includeStderr = isset(
$options[
'duplicateStderr'] ) &&
$options[
'duplicateStderr'];
2872 foreach ( $environ
as $k => $v ) {
2880 $envcmd .=
"set $k=" . preg_replace(
'/([&|()<>^"])/',
'^\\1', $v ) .
'&& ';
2885 $envcmd .=
"$k=" . escapeshellarg( $v ) .
' ';
2888 $cmd = $envcmd . $cmd;
2890 $useLogPipe =
false;
2891 if ( php_uname(
's' ) ==
'Linux' ) {
2892 $time = intval ( isset( $limits[
'time'] ) ? $limits[
'time'] : $wgMaxShellTime );
2893 if ( isset( $limits[
'walltime'] ) ) {
2894 $wallTime = intval( $limits[
'walltime'] );
2895 } elseif ( isset( $limits[
'time'] ) ) {
2898 $wallTime = intval( $wgMaxShellWallClockTime );
2900 $mem = intval ( isset( $limits[
'memory'] ) ? $limits[
'memory'] : $wgMaxShellMemory );
2901 $filesize = intval ( isset( $limits[
'filesize'] ) ? $limits[
'filesize'] : $wgMaxShellFileSize );
2903 if (
$time > 0 || $mem > 0 || $filesize > 0 || $wallTime > 0 ) {
2904 $cmd =
'/bin/bash ' . escapeshellarg(
"$IP/includes/limit.sh" ) .
' ' .
2905 escapeshellarg( $cmd ) .
' ' .
2907 "MW_INCLUDE_STDERR=" . ( $includeStderr ?
'1' :
'' ) .
';' .
2908 "MW_CPU_LIMIT=$time; " .
2909 'MW_CGROUP=' . escapeshellarg( $wgShellCgroup ) .
'; ' .
2910 "MW_MEM_LIMIT=$mem; " .
2911 "MW_FILE_SIZE_LIMIT=$filesize; " .
2912 "MW_WALL_CLOCK_LIMIT=$wallTime; " .
2913 "MW_USE_LOG_PIPE=yes"
2916 } elseif ( $includeStderr ) {
2919 } elseif ( $includeStderr ) {
2922 wfDebug(
"wfShellExec: $cmd\n" );
2925 0 =>
array(
'file',
'php://stdin',
'r' ),
2926 1 =>
array(
'pipe',
'w' ),
2927 2 =>
array(
'file',
'php://stderr',
'w' ) );
2928 if ( $useLogPipe ) {
2929 $desc[3] =
array(
'pipe',
'w' );
2932 $proc = proc_open( $cmd, $desc, $pipes );
2934 wfDebugLog(
'exec',
"proc_open() failed: $cmd" );
2938 $outBuffer = $logBuffer =
'';
2939 $emptyArray =
array();
2953 $eintr = defined(
'SOCKET_EINTR' ) ? SOCKET_EINTR : 4;
2954 $eintrMessage =
"stream_select(): unable to select [$eintr]";
2960 foreach ( $pipes
as $fd => $pipe ) {
2961 $fds[(int)$pipe] = $fd;
2968 while ( $running ===
true || $numReadyPipes !== 0 ) {
2970 $status = proc_get_status( $proc );
2973 if ( !$status[
'running'] ) {
2979 $readyPipes = $pipes;
2982 @trigger_error(
'' );
2983 $numReadyPipes = @stream_select( $readyPipes, $emptyArray, $emptyArray, $timeout );
2984 if ( $numReadyPipes ===
false ) {
2985 $error = error_get_last();
2986 if ( strncmp(
$error[
'message'], $eintrMessage, strlen( $eintrMessage ) ) == 0 ) {
2989 trigger_error(
$error[
'message'], E_USER_WARNING );
2990 $logMsg =
$error[
'message'];
2994 foreach ( $readyPipes
as $pipe ) {
2995 $block = fread( $pipe, 65536 );
2996 $fd = $fds[(int)$pipe];
2997 if ( $block ===
'' ) {
2999 fclose( $pipes[$fd] );
3000 unset( $pipes[$fd] );
3004 } elseif ( $block ===
false ) {
3006 $logMsg =
"Error reading from pipe";
3008 } elseif ( $fd == 1 ) {
3010 $outBuffer .= $block;
3011 } elseif ( $fd == 3 ) {
3013 $logBuffer .= $block;
3014 if ( strpos( $block,
"\n" ) !==
false ) {
3015 $lines = explode(
"\n", $logBuffer );
3016 $logBuffer = array_pop(
$lines );
3025 foreach ( $pipes
as $pipe ) {
3032 $status = proc_get_status( $proc );
3035 if ( $logMsg !==
false ) {
3038 proc_close( $proc );
3039 } elseif ( $status[
'signaled'] ) {
3040 $logMsg =
"Exited with signal {$status['termsig']}";
3041 $retval = 128 + $status[
'termsig'];
3042 proc_close( $proc );
3044 if ( $status[
'running'] ) {
3045 $retval = proc_close( $proc );
3047 $retval = $status[
'exitcode'];
3048 proc_close( $proc );
3051 $logMsg =
"Possibly missing executable file";
3053 $logMsg =
"Probably exited with signal " . (
$retval - 128 );
3057 if ( $logMsg !==
false ) {
3087 static $done =
false;
3094 putenv(
"LC_CTYPE=$wgShellLocale" );
3095 setlocale( LC_CTYPE, $wgShellLocale );
3126 if ( isset(
$options[
'wrapper'] ) ) {
3131 return implode(
" ", array_map(
'wfEscapeShellArg', array_merge( $cmd, $parameters ) ) );
3147 # This check may also protect against code injection in
3148 # case of broken installations.
3150 $haveDiff3 = $wgDiff3 && file_exists( $wgDiff3 );
3153 if ( !$haveDiff3 ) {
3154 wfDebug(
"diff3 not found\n" );
3158 # Make temporary files
3160 $oldtextFile = fopen( $oldtextName = tempnam( $td,
'merge-old-' ),
'w' );
3161 $mytextFile = fopen( $mytextName = tempnam( $td,
'merge-mine-' ),
'w' );
3162 $yourtextFile = fopen( $yourtextName = tempnam( $td,
'merge-your-' ),
'w' );
3164 # NOTE: diff3 issues a warning to stderr if any of the files does not end with
3165 # a newline character. To avoid this, we normalize the trailing whitespace before
3166 # creating the diff.
3168 fwrite( $oldtextFile, rtrim( $old ) .
"\n" );
3169 fclose( $oldtextFile );
3170 fwrite( $mytextFile, rtrim( $mine ) .
"\n" );
3171 fclose( $mytextFile );
3172 fwrite( $yourtextFile, rtrim( $yours ) .
"\n" );
3173 fclose( $yourtextFile );
3175 # Check for a conflict
3180 $handle = popen( $cmd,
'r' );
3182 if ( fgets( $handle, 1024 ) ) {
3192 $handle = popen( $cmd,
'r' );
3195 $data = fread( $handle, 8192 );
3196 if ( strlen( $data ) == 0 ) {
3202 unlink( $mytextName );
3203 unlink( $oldtextName );
3204 unlink( $yourtextName );
3206 if (
$result ===
'' && $old !==
'' && !$conflict ) {
3207 wfDebug(
"Unexpected null result from diff3. Command: $cmd\n" );
3223 if ( $before == $after ) {
3229 $haveDiff = $wgDiff && file_exists( $wgDiff );
3232 # This check may also protect against code injection in
3233 # case of broken installations.
3235 wfDebug(
"diff executable not found\n" );
3236 $diffs =
new Diff( explode(
"\n", $before ), explode(
"\n", $after ) );
3238 return $format->format( $diffs );
3241 # Make temporary files
3243 $oldtextFile = fopen( $oldtextName = tempnam( $td,
'merge-old-' ),
'w' );
3244 $newtextFile = fopen( $newtextName = tempnam( $td,
'merge-your-' ),
'w' );
3246 fwrite( $oldtextFile, $before );
3247 fclose( $oldtextFile );
3248 fwrite( $newtextFile, $after );
3249 fclose( $newtextFile );
3254 $h = popen( $cmd,
'r' );
3259 $data = fread( $h, 8192 );
3260 if ( strlen( $data ) == 0 ) {
3268 unlink( $oldtextName );
3269 unlink( $newtextName );
3272 $diff_lines = explode(
"\n", $diff );
3273 if ( strpos( $diff_lines[0],
'---' ) === 0 ) {
3274 unset( $diff_lines[0] );
3276 if ( strpos( $diff_lines[1],
'+++' ) === 0 ) {
3277 unset( $diff_lines[1] );
3280 $diff = implode(
"\n", $diff_lines );
3302 $php_ver = PHP_VERSION;
3304 if ( version_compare( $php_ver, (
string)$req_ver,
'<' ) ) {
3305 throw new MWException(
"PHP $req_ver required--this is only $php_ver" );
3331 function wfUseMW( $req_ver ) {
3334 if ( version_compare( $wgVersion, (
string)$req_ver,
'<' ) ) {
3335 throw new MWException(
"MediaWiki $req_ver required--this is only $wgVersion" );
3352 if ( $suffix ==
'' ) {
3355 $encSuffix =
'(?:' . preg_quote( $suffix,
'#' ) .
')?';
3359 if ( preg_match(
"#([^/\\\\]*?){$encSuffix}[/\\\\]*$#",
$path,
$matches ) ) {
3377 $path = str_replace(
'/', DIRECTORY_SEPARATOR,
$path );
3378 $from = str_replace(
'/', DIRECTORY_SEPARATOR,
$from );
3384 $pieces = explode( DIRECTORY_SEPARATOR, dirname(
$path ) );
3385 $against = explode( DIRECTORY_SEPARATOR,
$from );
3387 if ( $pieces[0] !== $against[0] ) {
3394 while ( count( $pieces ) && count( $against )
3395 && $pieces[0] == $against[0] ) {
3396 array_shift( $pieces );
3397 array_shift( $against );
3401 while ( count( $against ) ) {
3402 array_unshift( $pieces,
'..' );
3403 array_shift( $against );
3408 return implode( DIRECTORY_SEPARATOR, $pieces );
3426 function wfBaseConvert( $input, $sourceBase, $destBase, $pad = 1,
3427 $lowercase =
true, $engine =
'auto'
3429 $input = (string)$input;
3435 $sourceBase != (
int)$sourceBase ||
3436 $destBase != (int)$destBase ||
3437 $pad != (
int)$pad ||
3439 "/^[" . substr(
'0123456789abcdefghijklmnopqrstuvwxyz', 0, $sourceBase ) .
"]+$/i",
3446 static $baseChars =
array(
3447 10 =>
'a', 11 =>
'b', 12 =>
'c', 13 =>
'd', 14 =>
'e', 15 =>
'f',
3448 16 =>
'g', 17 =>
'h', 18 =>
'i', 19 =>
'j', 20 =>
'k', 21 =>
'l',
3449 22 =>
'm', 23 =>
'n', 24 =>
'o', 25 =>
'p', 26 =>
'q', 27 =>
'r',
3450 28 =>
's', 29 =>
't', 30 =>
'u', 31 =>
'v', 32 =>
'w', 33 =>
'x',
3451 34 =>
'y', 35 =>
'z',
3453 '0' => 0,
'1' => 1,
'2' => 2,
'3' => 3,
'4' => 4,
'5' => 5,
3454 '6' => 6,
'7' => 7,
'8' => 8,
'9' => 9,
'a' => 10,
'b' => 11,
3455 'c' => 12,
'd' => 13,
'e' => 14,
'f' => 15,
'g' => 16,
'h' => 17,
3456 'i' => 18,
'j' => 19,
'k' => 20,
'l' => 21,
'm' => 22,
'n' => 23,
3457 'o' => 24,
'p' => 25,
'q' => 26,
'r' => 27,
's' => 28,
't' => 29,
3458 'u' => 30,
'v' => 31,
'w' => 32,
'x' => 33,
'y' => 34,
'z' => 35
3461 if ( extension_loaded(
'gmp' ) && ( $engine ==
'auto' || $engine ==
'gmp' ) ) {
3462 $result = gmp_strval( gmp_init( $input, $sourceBase ), $destBase );
3463 } elseif ( extension_loaded(
'bcmath' ) && ( $engine ==
'auto' || $engine ==
'bcmath' ) ) {
3465 foreach ( str_split( strtolower( $input ) )
as $char ) {
3466 $decimal = bcmul( $decimal, $sourceBase );
3467 $decimal = bcadd( $decimal, $baseChars[$char] );
3470 for (
$result =
''; bccomp( $decimal, 0 ); $decimal = bcdiv( $decimal, $destBase, 0 ) ) {
3471 $result .= $baseChars[bcmod( $decimal, $destBase )];
3476 $inDigits =
array();
3477 foreach ( str_split( strtolower( $input ) )
as $char ) {
3478 $inDigits[] = $baseChars[$char];
3484 while ( $inDigits ) {
3486 $workDigits =
array();
3489 foreach ( $inDigits
as $digit ) {
3490 $work *= $sourceBase;
3493 if ( $workDigits || $work >= $destBase ) {
3494 $workDigits[] = (int)( $work / $destBase );
3504 $inDigits = $workDigits;
3510 if ( !$lowercase ) {
3514 return str_pad(
$result, $pad,
'0', STR_PAD_LEFT );
3524 (
wfIsWindows() && version_compare( PHP_VERSION,
'5.3.3',
'>=' ) )
3525 || ini_get(
'session.entropy_file' )
3527 && intval( ini_get(
'session.entropy_length' ) ) >= 32;
3536 if ( isset( $_COOKIE[session_name()] ) || session_id() ) {
3548 if ( !$entropyEnabled ) {
3549 wfDebug( __METHOD__ .
": PHP's built in entropy is disabled or not sufficient, " .
3550 "overriding session id generation using our cryptrand source.\n" );
3562 $oldSessionId = session_id();
3563 $cookieParams = session_get_cookie_params();
3564 if (
wfCheckEntropy() && $wgCookieSecure == $cookieParams[
'secure'] ) {
3565 session_regenerate_id(
false );
3572 $newSessionId = session_id();
3573 wfRunHooks(
'ResetSessionID',
array( $oldSessionId, $newSessionId ) );
3582 global $wgSessionsInMemcached, $wgSessionsInObjectCache, $wgCookiePath, $wgCookieDomain,
3583 $wgCookieSecure, $wgCookieHttpOnly, $wgSessionHandler;
3584 if ( $wgSessionsInObjectCache || $wgSessionsInMemcached ) {
3586 } elseif ( $wgSessionHandler && $wgSessionHandler != ini_get(
'session.save_handler' ) ) {
3587 # Only set this if $wgSessionHandler isn't null and session.save_handler
3588 # hasn't already been set to the desired value (that causes errors)
3589 ini_set(
'session.save_handler', $wgSessionHandler );
3591 session_set_cookie_params(
3592 0, $wgCookiePath, $wgCookieDomain, $wgCookieSecure, $wgCookieHttpOnly );
3593 session_cache_limiter(
'private, must-revalidate' );
3595 session_id( $sessionId );
3613 $file =
"$IP/serialized/$name";
3614 if ( file_exists(
$file ) ) {
3617 return unserialize(
$blob );
3631 $prefix = $wgCachePrefix ===
false ?
wfWikiID() : $wgCachePrefix;
3632 $args = func_get_args();
3633 $key = $prefix .
':' . implode(
':',
$args );
3634 $key = str_replace(
' ',
'_', $key );
3647 $args = array_slice( func_get_args(), 2 );
3649 $key =
"$db-$prefix:" . implode(
':',
$args );
3651 $key = $db .
':' . implode(
':',
$args );
3653 return str_replace(
' ',
'_', $key );
3664 if ( $wgDBprefix ) {
3665 return "$wgDBname-$wgDBprefix";
3679 $bits = explode(
'-', $wiki, 2 );
3680 if ( count( $bits ) < 2 ) {
3708 function &
wfGetDB( $db, $groups =
array(), $wiki =
false ) {
3709 return wfGetLB( $wiki )->getConnection( $db, $groups, $wiki );
3718 function wfGetLB( $wiki =
false ) {
3788 function wfScript( $script =
'index' ) {
3789 global $wgScriptPath, $wgScriptExtension, $wgScript, $wgLoadScript;
3790 if ( $script ===
'index' ) {
3792 } elseif ( $script ===
'load' ) {
3793 return $wgLoadScript;
3795 return "{$wgScriptPath}/{$script}{$wgScriptExtension}";
3805 if ( isset( $_SERVER[
'SCRIPT_NAME'] ) ) {
3807 # as it was called, minus the query string.
3809 # Some sites use Apache rewrite rules to handle subdomains,
3810 # and have PHP set up in a weird way that causes PHP_SELF
3811 # to contain the rewritten URL instead of the one that the
3812 # outside world sees.
3814 # If in this mode, use SCRIPT_URL instead, which mod_rewrite
3815 # provides containing the "before" URL.
3816 return $_SERVER[
'SCRIPT_NAME'];
3818 return $_SERVER[
'URL'];
3830 return $value ?
'true' :
'false';
3853 function wfWaitForSlaves( $maxLag =
false, $wiki =
false, $cluster =
false ) {
3854 if ( $cluster !==
false ) {
3862 if (
$lb->getServerCount() > 1 ) {
3864 $pos = $dbw->getMasterPos();
3867 if ( $pos !==
false ) {
3868 $lb->waitForAll( $pos );
3881 for ( $i = $seconds; $i >= 0; $i-- ) {
3882 if ( $i != $seconds ) {
3883 echo str_repeat(
"\x08", strlen( $i + 1 ) );
3903 global $wgIllegalFileChars;
3904 $illegalFileChars = $wgIllegalFileChars ?
"|[" . $wgIllegalFileChars .
"]" :
'';
3906 $name = preg_replace(
3922 if ( $memlimit != -1 ) {
3924 if ( $conflimit == -1 ) {
3925 wfDebug(
"Removing PHP's memory limit\n" );
3927 ini_set(
'memory_limit', $conflimit );
3930 } elseif ( $conflimit > $memlimit ) {
3931 wfDebug(
"Raising PHP's memory limit to $conflimit bytes\n" );
3933 ini_set(
'memory_limit', $conflimit );
3948 $string = trim( $string );
3949 if ( $string ===
'' ) {
3952 $last = $string[strlen( $string ) - 1];
3953 $val = intval( $string );
3979 $codeSegment = explode(
'-', $code );
3981 foreach ( $codeSegment
as $segNo => $seg ) {
3983 if ( $segNo > 0 && strtolower( $codeSegment[( $segNo - 1 )] ) ==
'x' ) {
3984 $codeBCP[$segNo] = strtolower( $seg );
3986 } elseif ( ( strlen( $seg ) == 2 ) && ( $segNo > 0 ) ) {
3987 $codeBCP[$segNo] = strtoupper( $seg );
3989 } elseif ( ( strlen( $seg ) == 4 ) && ( $segNo > 0 ) ) {
3990 $codeBCP[$segNo] = ucfirst( strtolower( $seg ) );
3993 $codeBCP[$segNo] = strtolower( $seg );
3996 $langCode = implode(
'-', $codeBCP );
4026 global $wgMessageCacheType;
4036 global $wgParserCacheType;
4046 global $wgLanguageConverterCacheType;
4077 function wfUnpack( $format, $data, $length =
false ) {
4078 if ( $length !==
false ) {
4079 $realLen = strlen( $data );
4080 if ( $realLen < $length ) {
4081 throw new MWException(
"Tried to use wfUnpack on a "
4082 .
"string of length $realLen, but needed one "
4083 .
"of at least length $length."
4089 $result = unpack( $format, $data );
4094 throw new MWException(
"unpack could not unpack binary data" );
4114 static $badImageCache =
null;
4119 if ( $redirectTitle ) {
4120 $name = $redirectTitle->getDBkey();
4123 # Run the extension hook
4130 $cacheable = ( $blacklist === null );
4131 if ( $cacheable && $badImageCache !==
null ) {
4132 $badImages = $badImageCache;
4134 if ( $blacklist ===
null ) {
4135 $blacklist =
wfMessage(
'bad_image_list' )->inContentLanguage()->plain();
4137 # Build the list now
4138 $badImages =
array();
4139 $lines = explode(
"\n", $blacklist );
4142 if ( substr(
$line, 0, 1 ) !==
'*' ) {
4148 if ( !preg_match_all(
'/\[\[:?(.*?)\]\]/',
$line, $m ) ) {
4153 $imageDBkey =
false;
4154 foreach ( $m[1]
as $i => $titleText ) {
4156 if ( !is_null(
$title ) ) {
4158 $imageDBkey =
$title->getDBkey();
4165 if ( $imageDBkey !==
false ) {
4170 $badImageCache = $badImages;
4174 $contextKey = $contextTitle ? $contextTitle->getPrefixedDBkey() :
false;
4175 $bad = isset( $badImages[
$name] ) && !isset( $badImages[
$name][$contextKey] );
4203 return $wgRequest->getIP();
4228 global $wgSquidServers, $wgSquidServersNoPurge;
4231 $trusted = in_array( $ip, $wgSquidServers )
4232 || in_array( $ip, $wgSquidServersNoPurge );
4237 foreach ( $wgSquidServersNoPurge
as $block ) {
4238 if ( strpos( $block,
'/' ) !==
false &&
IP::isInRange( $ip, $block ) ) {