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 ) );
116 return array_udiff( $a, $b,
'wfArrayDiff2_cmp' );
125 if ( is_string( $a ) && is_string( $b ) ) {
126 return strcmp( $a, $b );
127 } elseif ( count( $a ) !== count( $b ) ) {
128 return count( $a ) < count( $b ) ? -1 : 1;
132 while ( (
list( , $valueA ) = each( $a ) ) && (
list( , $valueB ) = each( $b ) ) ) {
133 $cmp = strcmp( $valueA, $valueB );
154 return array_flip( array_intersect( array_flip( $a ), array_keys( $b ) ) );
168 throw new MWException(
'GlobalFunctions::wfAppendToArrayIfNotDefault got null' );
170 if ( $default[$key] !==
$value ) {
187 $args = func_get_args();
216 $args = func_get_args();
220 # @todo FIXME: Sometimes get nested arrays for $params,
221 # which leads to E_NOTICEs
222 $spec = implode(
"\t",
$params );
226 return array_values(
$out );
239 $keys = array_keys( $array );
240 $offsetByKey = array_flip(
$keys );
242 $offset = $offsetByKey[$after];
245 $before = array_slice( $array, 0, $offset + 1,
true );
246 $after = array_slice( $array, $offset + 1, count( $array ) - $offset,
true );
248 $output = $before + $insert + $after;
262 if ( is_object( $objOrArray ) ) {
263 $objOrArray = get_object_vars( $objOrArray );
265 foreach ( $objOrArray
as $key =>
$value ) {
266 if ( $recursive && ( is_object(
$value ) || is_array(
$value ) ) ) {
284 # The maximum random value is "only" 2^31-1, so get two random
285 # values to reduce the chance of dupes
286 $max = mt_getrandmax() + 1;
287 $rand = number_format( ( mt_rand() * $max + mt_rand() ) / $max / $max, 12,
'.',
'' );
304 for (
$n = 0;
$n < $length;
$n += 7 ) {
305 $str .= sprintf(
'%07x', mt_rand() & 0xfffffff );
307 return substr( $str, 0, $length );
335 if ( is_null(
$s ) ) {
340 if ( is_null( $needle ) ) {
341 $needle =
array(
'%3B',
'%40',
'%24',
'%21',
'%2A',
'%28',
'%29',
'%2C',
'%2F' );
342 if ( !isset( $_SERVER[
'SERVER_SOFTWARE'] ) ||
343 ( strpos( $_SERVER[
'SERVER_SOFTWARE'],
'Microsoft-IIS/7' ) ===
false )
349 $s = urlencode(
$s );
352 array(
';',
'@',
'$',
'!',
'*',
'(',
')',
',',
'/',
':' ),
369 function wfArrayToCgi( $array1, $array2 =
null, $prefix =
'' ) {
370 if ( !is_null( $array2 ) ) {
371 $array1 = $array1 + $array2;
375 foreach ( $array1
as $key =>
$value ) {
380 if ( $prefix !==
'' ) {
381 $key = $prefix .
"[$key]";
383 if ( is_array(
$value ) ) {
386 $cgi .= $firstTime ?
'' :
'&';
387 if ( is_array( $v ) ) {
390 $cgi .= urlencode( $key .
"[$k]" ) .
'=' . urlencode( $v );
395 if ( is_object(
$value ) ) {
398 $cgi .= urlencode( $key ) .
'=' . urlencode(
$value );
418 $bits = explode(
'&',
$query );
420 foreach ( $bits
as $bit ) {
424 if ( strpos( $bit,
'=' ) ===
false ) {
431 $key = urldecode( $key );
433 if ( strpos( $key,
'[' ) !==
false ) {
434 $keys = array_reverse( explode(
'[', $key ) );
435 $key = array_pop(
$keys );
438 $k = substr( $k, 0, -1 );
439 $temp =
array( $k => $temp );
441 if ( isset(
$ret[$key] ) ) {
442 $ret[$key] = array_merge(
$ret[$key], $temp );
462 if ( is_array(
$query ) ) {
466 if (
false === strpos( $url,
'?' ) ) {
500 global $wgServer, $wgCanonicalServer, $wgInternalServer, $wgRequest;
502 $serverUrl = $wgCanonicalServer;
503 } elseif ( $defaultProto ===
PROTO_INTERNAL && $wgInternalServer !==
false ) {
505 $serverUrl = $wgInternalServer;
507 $serverUrl = $wgServer;
509 $defaultProto = $wgRequest->getProtocol() .
'://';
515 $serverHasProto = $bits && $bits[
'scheme'] !=
'';
518 if ( $serverHasProto ) {
519 $defaultProto = $bits[
'scheme'] .
'://';
528 $defaultProtoWithoutSlashes = substr( $defaultProto, 0, -2 );
530 if ( substr( $url, 0, 2 ) ==
'//' ) {
531 $url = $defaultProtoWithoutSlashes . $url;
532 } elseif ( substr( $url, 0, 1 ) ==
'/' ) {
535 $url = ( $serverHasProto ?
'' : $defaultProtoWithoutSlashes ) . $serverUrl . $url;
539 if ( $bits && isset( $bits[
'path'] ) ) {
545 } elseif ( substr( $url, 0, 1 ) !=
'/' ) {
546 # URL is a relative path
550 # Expanded URL is not valid.
570 if ( isset( $urlParts[
'delimiter'] ) ) {
571 if ( isset( $urlParts[
'scheme'] ) ) {
572 $result .= $urlParts[
'scheme'];
575 $result .= $urlParts[
'delimiter'];
578 if ( isset( $urlParts[
'host'] ) ) {
579 if ( isset( $urlParts[
'user'] ) ) {
581 if ( isset( $urlParts[
'pass'] ) ) {
582 $result .=
':' . $urlParts[
'pass'];
589 if ( isset( $urlParts[
'port'] ) ) {
590 $result .=
':' . $urlParts[
'port'];
594 if ( isset( $urlParts[
'path'] ) ) {
598 if ( isset( $urlParts[
'query'] ) ) {
599 $result .=
'?' . $urlParts[
'query'];
602 if ( isset( $urlParts[
'fragment'] ) ) {
603 $result .=
'#' . $urlParts[
'fragment'];
622 $inputLength = strlen( $urlPath );
624 while ( $inputOffset < $inputLength ) {
625 $prefixLengthOne = substr( $urlPath, $inputOffset, 1 );
626 $prefixLengthTwo = substr( $urlPath, $inputOffset, 2 );
627 $prefixLengthThree = substr( $urlPath, $inputOffset, 3 );
628 $prefixLengthFour = substr( $urlPath, $inputOffset, 4 );
631 if ( $prefixLengthTwo ==
'./' ) {
632 # Step A, remove leading "./"
634 } elseif ( $prefixLengthThree ==
'../' ) {
635 # Step A, remove leading "../"
637 } elseif ( ( $prefixLengthTwo ==
'/.' ) && ( $inputOffset + 2 == $inputLength ) ) {
638 # Step B, replace leading "/.$" with "/"
640 $urlPath[$inputOffset] =
'/';
641 } elseif ( $prefixLengthThree ==
'/./' ) {
642 # Step B, replace leading "/./" with "/"
644 } elseif ( $prefixLengthThree ==
'/..' && ( $inputOffset + 3 == $inputLength ) ) {
645 # Step C, replace leading "/..$" with "/" and
646 # remove last path component in output
648 $urlPath[$inputOffset] =
'/';
650 } elseif ( $prefixLengthFour ==
'/../' ) {
651 # Step C, replace leading "/../" with "/" and
652 # remove last path component in output
655 } elseif ( ( $prefixLengthOne ==
'.' ) && ( $inputOffset + 1 == $inputLength ) ) {
656 # Step D, remove "^.$"
658 } elseif ( ( $prefixLengthTwo ==
'..' ) && ( $inputOffset + 2 == $inputLength ) ) {
659 # Step D, remove "^..$"
662 # Step E, move leading path segment to output
663 if ( $prefixLengthOne ==
'/' ) {
664 $slashPos = strpos( $urlPath,
'/', $inputOffset + 1 );
666 $slashPos = strpos( $urlPath,
'/', $inputOffset );
668 if ( $slashPos ===
false ) {
669 $output .= substr( $urlPath, $inputOffset );
670 $inputOffset = $inputLength;
672 $output .= substr( $urlPath, $inputOffset, $slashPos - $inputOffset );
673 $inputOffset += $slashPos - $inputOffset;
678 $slashPos = strrpos(
$output,
'/' );
679 if ( $slashPos ===
false ) {
701 static $withProtRel =
null, $withoutProtRel =
null;
702 $cachedValue = $includeProtocolRelative ? $withProtRel : $withoutProtRel;
703 if ( !is_null( $cachedValue ) ) {
709 if ( is_array( $wgUrlProtocols ) ) {
710 $protocols =
array();
711 foreach ( $wgUrlProtocols
as $protocol ) {
713 if ( $includeProtocolRelative || $protocol !==
'//' ) {
714 $protocols[] = preg_quote( $protocol,
'/' );
718 $retval = implode(
'|', $protocols );
728 if ( $includeProtocolRelative ) {
763 $wasRelative = substr( $url, 0, 2 ) ==
'//';
764 if ( $wasRelative ) {
768 $bits = parse_url( $url );
772 if ( !$bits || !isset( $bits[
'scheme'] ) ) {
777 $bits[
'scheme'] = strtolower( $bits[
'scheme'] );
780 if ( in_array( $bits[
'scheme'] .
'://', $wgUrlProtocols ) ) {
781 $bits[
'delimiter'] =
'://';
782 } elseif ( in_array( $bits[
'scheme'] .
':', $wgUrlProtocols ) ) {
783 $bits[
'delimiter'] =
':';
786 if ( isset( $bits[
'path'] ) ) {
787 $bits[
'host'] = $bits[
'path'];
795 if ( !isset( $bits[
'host'] ) ) {
799 if ( isset( $bits[
'path'] ) ) {
801 if ( substr( $bits[
'path'], 0, 1 ) !==
'/' ) {
802 $bits[
'path'] =
'/' . $bits[
'path'];
810 if ( $wasRelative ) {
811 $bits[
'scheme'] =
'';
812 $bits[
'delimiter'] =
'//';
828 return preg_replace_callback(
829 '/((?:%[89A-F][0-9A-F])+)/i',
830 'wfExpandIRI_callback',
855 if ( $bits[
'scheme'] ==
'mailto' ) {
856 $mailparts = explode(
'@', $bits[
'host'], 2 );
857 if ( count( $mailparts ) === 2 ) {
858 $domainpart = strtolower( implode(
'.', array_reverse( explode(
'.', $mailparts[1] ) ) ) );
863 $reversedHost = $domainpart .
'@' . $mailparts[0];
865 $reversedHost = strtolower( implode(
'.', array_reverse( explode(
'.', $bits[
'host'] ) ) ) );
869 if ( substr( $reversedHost, -1, 1 ) !==
'.' ) {
870 $reversedHost .=
'.';
873 $prot = $bits[
'scheme'];
874 $index = $prot . $bits[
'delimiter'] . $reversedHost;
876 if ( isset( $bits[
'port'] ) ) {
877 $index .=
':' . $bits[
'port'];
879 if ( isset( $bits[
'path'] ) ) {
880 $index .= $bits[
'path'];
884 if ( isset( $bits[
'query'] ) ) {
885 $index .=
'?' . $bits[
'query'];
887 if ( isset( $bits[
'fragment'] ) ) {
888 $index .=
'#' . $bits[
'fragment'];
892 return array(
"http:$index",
"https:$index" );
894 return array( $index );
906 if ( is_array( $bits ) && isset( $bits[
'host'] ) ) {
907 $host =
'.' . $bits[
'host'];
908 foreach ( (
array)$domains
as $domain ) {
909 $domain =
'.' . $domain;
910 if ( substr( $host, -strlen( $domain ) ) === $domain ) {
935 function wfDebug( $text, $dest =
'all' ) {
936 global $wgDebugLogFile, $wgDebugRawPage, $wgDebugLogPrefix;
943 if ( $dest ===
true ) {
945 } elseif ( $dest ===
false ) {
950 if ( $timer !==
'' ) {
951 $text = preg_replace(
'/[^\n]/', $timer .
'\0', $text, 1 );
954 if ( $dest ===
'all' ) {
958 if ( $wgDebugLogFile !=
'' ) {
959 # Strip unprintables; they can switch terminal modes when binary data
960 # gets dumped, which is pretty annoying.
961 $text = preg_replace(
'![\x00-\x08\x0b\x0c\x0e-\x1f]!',
' ', $text );
962 $text = $wgDebugLogPrefix . $text;
976 # Check for raw action using $_GET not $wgRequest, since the latter might not be initialised yet
977 if ( ( isset( $_GET[
'action'] ) && $_GET[
'action'] ==
'raw' )
979 isset( $_SERVER[
'SCRIPT_NAME'] )
980 && substr( $_SERVER[
'SCRIPT_NAME'], -8 ) ==
'load.php'
998 if ( !$wgDebugTimestamps ) {
1002 $prefix = sprintf(
"%6.4f", microtime(
true ) -
$wgRequestTime );
1003 $mem = sprintf(
"%5.1fM", ( memory_get_usage(
true ) / ( 1024 * 1024 ) ) );
1004 return "$prefix $mem ";
1013 $mem = memory_get_usage();
1015 $mem = floor( $mem / 1024 ) .
' kilobytes';
1019 wfDebug(
"Memory usage: $mem\n" );
1042 function wfDebugLog( $logGroup, $text, $dest =
'all' ) {
1043 global $wgDebugLogGroups;
1045 $text = trim( $text ) .
"\n";
1048 if ( $dest ===
true ) {
1050 } elseif ( $dest ===
false ) {
1054 if ( !isset( $wgDebugLogGroups[$logGroup] ) ) {
1055 if ( $dest !==
'private' ) {
1056 wfDebug(
"[$logGroup] $text", $dest );
1061 if ( $dest ===
'all' ) {
1065 $logConfig = $wgDebugLogGroups[$logGroup];
1066 if ( $logConfig ===
false ) {
1069 if ( is_array( $logConfig ) ) {
1070 if ( isset( $logConfig[
'sample'] ) && mt_rand( 1, $logConfig[
'sample'] ) !== 1 ) {
1073 $destination = $logConfig[
'destination'];
1075 $destination = strval( $logConfig );
1081 wfErrorLog(
"$time $host $wiki: $text", $destination );
1090 global $wgDBerrorLog, $wgDBerrorLogTZ;
1091 static $logDBErrorTimeZoneObject =
null;
1093 if ( $wgDBerrorLog ) {
1097 if ( $wgDBerrorLogTZ && !$logDBErrorTimeZoneObject ) {
1098 $logDBErrorTimeZoneObject =
new DateTimeZone( $wgDBerrorLogTZ );
1103 if ( $logDBErrorTimeZoneObject ===
null ) {
1104 $d = date_create(
"now" );
1106 $d = date_create(
"now", $logDBErrorTimeZoneObject );
1109 $date = $d->format(
'D M j G:i:s T Y' );
1111 $text =
"$date\t$host\t$wiki\t" . trim( $text ) .
"\n";
1143 function wfWarn( $msg, $callerOffset = 1, $level = E_USER_NOTICE ) {
1156 function wfLogWarning( $msg, $callerOffset = 1, $level = E_USER_WARNING ) {
1171 if ( substr(
$file, 0, 4 ) ==
'udp:' ) {
1172 # Needs the sockets extension
1173 if ( preg_match(
'!^(tcp|udp):(?://)?\[([0-9a-fA-F:]+)\]:(\d+)(?:/(.*))?$!',
$file, $m ) ) {
1176 $port = intval( $m[3] );
1177 $prefix = isset( $m[4] ) ? $m[4] :
false;
1179 } elseif ( preg_match(
'!^(tcp|udp):(?://)?([a-zA-Z0-9.-]+):(\d+)(?:/(.*))?$!',
$file, $m ) ) {
1182 $host = gethostbyname( $host );
1184 $port = intval( $m[3] );
1185 $prefix = isset( $m[4] ) ? $m[4] :
false;
1188 throw new MWException( __METHOD__ .
': Invalid UDP specification' );
1192 if ( strval( $prefix ) !==
'' ) {
1193 $text = preg_replace(
'/^/m', $prefix .
' ', $text );
1196 if ( strlen( $text ) > 65506 ) {
1197 $text = substr( $text, 0, 65506 );
1200 if ( substr( $text, -1 ) !=
"\n" ) {
1203 } elseif ( strlen( $text ) > 65507 ) {
1204 $text = substr( $text, 0, 65507 );
1207 $sock = socket_create( $domain, SOCK_DGRAM, SOL_UDP );
1212 socket_sendto( $sock, $text, strlen( $text ), 0, $host, $port );
1213 socket_close( $sock );
1216 $exists = file_exists(
$file );
1218 if ( !$exists || (
$size !==
false &&
$size + strlen( $text ) < 0x7fffffff ) ) {
1219 file_put_contents(
$file, $text, FILE_APPEND );
1236 # Profiling must actually be enabled...
1237 if ( $profiler->isStub() ) {
1244 if ( $elapsed <= $wgProfileLimit ) {
1248 $profiler->logData();
1251 if ( isset( $wgDebugLogGroups[
'profileoutput'] )
1252 && $wgDebugLogGroups[
'profileoutput'] ===
false
1257 if ( !isset( $wgDebugLogGroups[
'profileoutput'] ) && $wgDebugLogFile ==
'' ) {
1266 if ( !empty( $_SERVER[
'HTTP_X_FORWARDED_FOR'] ) ) {
1267 $forward =
' forwarded for ' . $_SERVER[
'HTTP_X_FORWARDED_FOR'];
1269 if ( !empty( $_SERVER[
'HTTP_CLIENT_IP'] ) ) {
1270 $forward .=
' client IP ' . $_SERVER[
'HTTP_CLIENT_IP'];
1272 if ( !empty( $_SERVER[
'HTTP_FROM'] ) ) {
1273 $forward .=
' from ' . $_SERVER[
'HTTP_FROM'];
1276 $forward =
"\t(proxied via {$_SERVER['REMOTE_ADDR']}{$forward})";
1281 $forward .=
' anon';
1287 $requestUrl = $wgRequest->getRequestURL();
1289 $requestUrl =
'n/a';
1292 $log = sprintf(
"%s\t%04.3f\t%s\n",
1293 gmdate(
'YmdHis' ), $elapsed,
1294 urldecode( $requestUrl . $forward ) );
1296 wfDebugLog(
'profileoutput', $log . $profiler->getOutput() );
1325 global $wgReadOnly, $wgReadOnlyFile;
1327 if ( $wgReadOnly ===
null ) {
1329 if ( is_file( $wgReadOnlyFile ) && filesize( $wgReadOnlyFile ) > 0 ) {
1330 $wgReadOnly = file_get_contents( $wgReadOnlyFile );
1332 $wgReadOnly =
false;
1355 # Identify which language to get or create a language object for.
1356 # Using is_object here due to Stub objects.
1357 if ( is_object( $langcode ) ) {
1358 # Great, we already have the object (hopefully)!
1363 if ( $langcode ===
true || $langcode === $wgLanguageCode ) {
1364 # $langcode is the language code of the wikis content language object.
1365 # or it is a boolean and value is true
1370 if ( $langcode ===
false || $langcode ===
$wgLang->getCode() ) {
1371 # $langcode is the language code of user language object.
1372 # or it was a boolean and value is false
1377 if ( in_array( $langcode, $validCodes ) ) {
1378 # $langcode corresponds to a valid language.
1382 # $langcode is a string, but not a valid language code; use content language.
1383 wfDebug(
"Invalid language code passed to wfGetLangObj, falling back to content language.\n" );
1409 return new Message( $key,
$params );
1425 $args = func_get_args();
1426 return call_user_func_array(
'Message::newFallbackSequence',
$args );
1448 function wfMsg( $key ) {
1451 $args = func_get_args();
1452 array_shift(
$args );
1467 $args = func_get_args();
1468 array_shift(
$args );
1500 global $wgForceUIMsgAsContentMsg;
1501 $args = func_get_args();
1502 array_shift(
$args );
1504 if ( is_array( $wgForceUIMsgAsContentMsg )
1505 && in_array( $key, $wgForceUIMsgAsContentMsg )
1507 $forcontent =
false;
1523 global $wgForceUIMsgAsContentMsg;
1524 $args = func_get_args();
1525 array_shift(
$args );
1527 if ( is_array( $wgForceUIMsgAsContentMsg )
1528 && in_array( $key, $wgForceUIMsgAsContentMsg )
1530 $forcontent =
false;
1547 function wfMsgReal( $key,
$args, $useDB =
true, $forContent =
false, $transform =
true ) {
1551 $message =
wfMsgGetKey( $key, $useDB, $forContent, $transform );
1569 function wfMsgGetKey( $key, $useDB =
true, $langCode =
false, $transform =
true ) {
1572 wfRunHooks(
'NormalizeMessageKey',
array( &$key, &$useDB, &$langCode, &$transform ) );
1575 $message =
$cache->get( $key, $useDB, $langCode );
1576 if ( $message ===
false ) {
1577 $message =
'<' . htmlspecialchars( $key ) .
'>';
1578 } elseif ( $transform ) {
1579 $message =
$cache->transform( $message );
1593 # Fix windows line-endings
1594 # Some messages are split with explode("\n", $msg)
1595 $message = str_replace(
"\r",
'', $message );
1598 if ( count(
$args ) ) {
1599 if ( is_array(
$args[0] ) ) {
1602 $replacementKeys =
array();
1604 $replacementKeys[
'$' . (
$n + 1 )] = $param;
1606 $message = strtr( $message, $replacementKeys );
1628 $args = func_get_args();
1629 array_shift(
$args );
1649 $args = func_get_args();
1650 array_shift(
$args );
1653 true,
true )->getText(),
1683 $args = func_get_args();
1684 array_shift(
$args );
1685 array_shift(
$args );
1688 foreach (
$options as $arrayKey => $option ) {
1689 if ( !preg_match(
'/^[0-9]+|language$/', $arrayKey ) ) {
1690 # An unknown index, neither numeric nor "language"
1691 wfWarn(
"wfMsgExt called with incorrect parameter key $arrayKey", 1, E_USER_WARNING );
1692 } elseif ( preg_match(
'/^[0-9]+$/', $arrayKey ) && !in_array( $option,
1693 array(
'parse',
'parseinline',
'escape',
'escapenoentities',
1694 'replaceafter',
'parsemag',
'content' ) ) ) {
1695 # A numeric index with unknown value
1696 wfWarn(
"wfMsgExt called with incorrect parameter $option", 1, E_USER_WARNING );
1700 if ( in_array(
'content',
$options,
true ) ) {
1703 $langCodeObj =
null;
1704 } elseif ( array_key_exists(
'language',
$options ) ) {
1705 $forContent =
false;
1707 $langCodeObj = $langCode;
1709 $forContent =
false;
1711 $langCodeObj =
null;
1714 $string =
wfMsgGetKey( $key,
true, $langCode,
false );
1716 if ( !in_array(
'replaceafter',
$options,
true ) ) {
1721 $parseInline = in_array(
'parseinline',
$options,
true );
1722 if ( in_array(
'parse',
$options,
true ) || $parseInline ) {
1723 $string = $messageCache->parse( $string,
null,
true, !$forContent, $langCodeObj );
1725 $string = $string->getText();
1728 if ( $parseInline ) {
1730 if ( preg_match(
'/^<p>(.*)\n?<\/p>\n?$/sU', $string, $m ) ) {
1734 } elseif ( in_array(
'parsemag',
$options,
true ) ) {
1735 $string = $messageCache->transform( $string,
1736 !$forContent, $langCodeObj );
1739 if ( in_array(
'escape',
$options,
true ) ) {
1740 $string = htmlspecialchars ( $string );
1741 } elseif ( in_array(
'escapenoentities',
$options,
true ) ) {
1745 if ( in_array(
'replaceafter',
$options,
true ) ) {
1790 if ( is_null( $host ) ) {
1792 # Hostname overriding
1793 global $wgOverrideHostname;
1794 if ( $wgOverrideHostname !==
false ) {
1795 # Set static and skip any detection
1796 $host = $wgOverrideHostname;
1800 if ( function_exists(
'posix_uname' ) ) {
1802 $uname = posix_uname();
1806 if ( is_array( $uname ) && isset( $uname[
'nodename'] ) ) {
1807 $host = $uname[
'nodename'];
1808 } elseif ( getenv(
'COMPUTERNAME' ) ) {
1809 # Windows computer name
1810 $host = getenv(
'COMPUTERNAME' );
1812 # This may be a virtual server.
1813 $host = $_SERVER[
'SERVER_NAME'];
1831 $responseTime = round( ( microtime(
true ) -
$wgRequestTime ) * 1000 );
1832 $reportVars =
array(
'wgBackendResponseTime' => $responseTime );
1833 if ( $wgShowHostnames ) {
1855 static $disabled =
null;
1857 if ( extension_loaded(
'Zend Optimizer' ) ) {
1858 wfDebug(
"Zend Optimizer detected; skipping debug_backtrace for safety.\n" );
1862 if ( is_null( $disabled ) ) {
1864 $functions = explode(
',', ini_get(
'disable_functions' ) );
1865 $functions = array_map(
'trim', $functions );
1866 $functions = array_map(
'strtolower', $functions );
1867 if ( in_array(
'debug_backtrace', $functions ) ) {
1868 wfDebug(
"debug_backtrace is in disabled_functions\n" );
1876 if (
$limit && version_compare( PHP_VERSION,
'5.4.0',
'>=' ) ) {
1877 return array_slice( debug_backtrace( DEBUG_BACKTRACE_PROVIDE_OBJECT,
$limit + 1 ), 1 );
1879 return array_slice( debug_backtrace(), 1 );
1897 foreach ( $backtrace
as $call ) {
1898 if ( isset( $call[
'file'] ) ) {
1899 $f = explode( DIRECTORY_SEPARATOR, $call[
'file'] );
1904 if ( isset( $call[
'line'] ) ) {
1905 $line = $call[
'line'];
1910 $msg .=
"$file line $line calls ";
1912 $msg .=
'<li>' .
$file .
' line ' .
$line .
' calls ';
1914 if ( !empty( $call[
'class'] ) ) {
1915 $msg .= $call[
'class'] . $call[
'type'];
1917 $msg .= $call[
'function'] .
'()';
1945 if ( isset( $backtrace[$level] ) ) {
1963 $limit = count( $trace ) - 1;
1966 return implode(
'/', array_map(
'wfFormatStackFrame', $trace ) );
1976 return isset( $frame[
'class'] ) ?
1977 $frame[
'class'] .
'::' . $frame[
'function'] :
1991 return wfMessage(
'showingresults' )->numParams(
$limit, $offset + 1 )->parse();
2012 if ( is_object(
$link ) ) {
2016 if ( is_null(
$title ) ) {
2033 if (
$result ===
null || $force ) {
2035 if ( isset( $_SERVER[
'HTTP_ACCEPT_ENCODING'] ) ) {
2036 # @todo FIXME: We may want to blacklist some broken browsers
2039 '/\bgzip(?:;(q)=([0-9]+(?:\.[0-9]+)))?\b/',
2040 $_SERVER[
'HTTP_ACCEPT_ENCODING'],
2044 if ( isset( $m[2] ) && ( $m[1] ==
'q' ) && ( $m[2] == 0 ) ) {
2048 wfDebug(
"wfClientAcceptsGzip: client accepts gzip.\n" );
2065 function wfCheckLimits( $deflimit = 50, $optionname =
'rclimit' ) {
2067 return $wgRequest->getLimitOffset( $deflimit, $optionname );
2080 static $repl =
null, $repl2 =
null;
2081 if ( $repl ===
null ) {
2083 '"' =>
'"',
'&' =>
'&',
"'" =>
''',
'<' =>
'<',
2084 '=' =>
'=',
'>' =>
'>',
'[' =>
'[',
']' =>
']',
2085 '{' =>
'{',
'|' =>
'|',
'}' =>
'}',
';' =>
';',
2086 "\n#" =>
"\n#",
"\r#" =>
"\r#",
2087 "\n*" =>
"\n*",
"\r*" =>
"\r*",
2088 "\n:" =>
"\n:",
"\r:" =>
"\r:",
2089 "\n " =>
"\n ",
"\r " =>
"\r ",
2090 "\n\n" =>
"\n ",
"\r\n" =>
" \n",
2091 "\n\r" =>
"\n ",
"\r\r" =>
"\r ",
2092 "\n\t" =>
"\n	",
"\r\t" =>
"\r	",
2093 "\n----" =>
"\n----",
"\r----" =>
"\r----",
2094 '__' =>
'__',
'://' =>
'://',
2098 foreach (
array(
'ISBN',
'RFC',
'PMID' )
as $magic ) {
2099 $repl[
"$magic "] =
"$magic ";
2100 $repl[
"$magic\t"] =
"$magic	";
2101 $repl[
"$magic\r"] =
"$magic ";
2102 $repl[
"$magic\n"] =
"$magic ";
2103 $repl[
"$magic\f"] =
"$magic";
2109 foreach ( $wgUrlProtocols
as $prot ) {
2110 if ( substr( $prot, -1 ) ===
':' ) {
2111 $repl2[] = preg_quote( substr( $prot, 0, -1 ),
'/' );
2114 $repl2 = $repl2 ?
'/\b(' . join(
'|', $repl2 ) .
'):/i' :
'/^(?!)/';
2116 $text = substr( strtr(
"\n$text", $repl ), 1 );
2117 $text = preg_replace( $repl2,
'$1:', $text );
2128 return microtime(
true );
2143 if ( !is_null(
$source ) || $force ) {
2158 function wfSetBit( &$dest, $bit, $state =
true ) {
2159 $temp = (bool)( $dest & $bit );
2160 if ( !is_null( $state ) ) {
2178 $s = str_replace(
"\n",
"<br />\n", var_export( $var,
true ) .
"\n" );
2179 if ( headers_sent() || !isset(
$wgOut ) || !is_object(
$wgOut ) ) {
2196 header(
"HTTP/1.0 $code $label" );
2197 header(
"Status: $code $label" );
2198 $wgOut->sendCacheControl();
2200 header(
'Content-type: text/html; charset=utf-8' );
2201 print
"<!doctype html>" .
2202 '<html><head><title>' .
2203 htmlspecialchars( $label ) .
2204 '</title></head><body><h1>' .
2205 htmlspecialchars( $label ) .
2207 nl2br( htmlspecialchars( $desc ) ) .
2208 "</p></body></html>\n";
2229 if ( $resetGzipEncoding ) {
2232 global $wgDisableOutputCompression;
2233 $wgDisableOutputCompression =
true;
2235 while ( $status = ob_get_status() ) {
2236 if ( $status[
'type'] == 0 ) {
2244 if ( !ob_end_clean() ) {
2249 if ( $resetGzipEncoding ) {
2250 if ( $status[
'name'] ==
'ob_gzhandler' ) {
2253 header_remove(
'Content-Encoding' );
2285 # No arg means accept anything (per HTTP spec)
2287 return array( $def => 1.0 );
2292 $parts = explode(
',', $accept );
2294 foreach ( $parts
as $part ) {
2295 # @todo FIXME: Doesn't deal with params like 'text/html; level=1'
2296 $values = explode(
';', trim( $part ) );
2298 if ( count( $values ) == 1 ) {
2299 $prefs[$values[0]] = 1.0;
2300 } elseif ( preg_match(
'/q\s*=\s*(\d*\.\d+)/', $values[1], $match ) ) {
2301 $prefs[$values[0]] = floatval( $match[1] );
2321 if ( array_key_exists(
$type, $avail ) ) {
2324 $parts = explode(
'/',
$type );
2325 if ( array_key_exists( $parts[0] .
'/*', $avail ) ) {
2326 return $parts[0] .
'/*';
2327 } elseif ( array_key_exists(
'*/*', $avail ) ) {
2351 foreach ( array_keys( $sprefs )
as $type ) {
2352 $parts = explode(
'/',
$type );
2353 if ( $parts[1] !=
'*' ) {
2356 $combine[
$type] = $sprefs[
$type] * $cprefs[$ckey];
2361 foreach ( array_keys( $cprefs )
as $type ) {
2362 $parts = explode(
'/',
$type );
2363 if ( $parts[1] !=
'*' && !array_key_exists(
$type, $sprefs ) ) {
2366 $combine[
$type] = $sprefs[$skey] * $cprefs[
$type];
2374 foreach ( array_keys( $combine )
as $type ) {
2375 if ( $combine[
$type] > $bestq ) {
2377 $bestq = $combine[
$type];
2390 static $suppressCount = 0;
2391 static $originalLevel =
false;
2394 if ( $suppressCount ) {
2396 if ( !$suppressCount ) {
2397 error_reporting( $originalLevel );
2401 if ( !$suppressCount ) {
2402 $originalLevel = error_reporting( E_ALL & ~(
2423 # Autodetect, convert and provide timestamps of various types
2428 define(
'TS_UNIX', 0 );
2433 define(
'TS_MW', 1 );
2438 define(
'TS_DB', 2 );
2443 define(
'TS_RFC2822', 3 );
2450 define(
'TS_ISO_8601', 4 );
2459 define(
'TS_EXIF', 5 );
2464 define(
'TS_ORACLE', 6 );
2469 define(
'TS_POSTGRES', 7 );
2474 define(
'TS_ISO_8601_BASIC', 9 );
2488 return $timestamp->getTimestamp( $outputtype );
2490 wfDebug(
"wfTimestamp() fed bogus time value: TYPE=$outputtype; VALUE=$ts\n" );
2504 if ( is_null( $ts ) ) {
2527 static $isWindows =
null;
2528 if ( $isWindows ===
null ) {
2529 $isWindows = substr( php_uname(), 0, 7 ) ==
'Windows';
2540 return defined(
'HHVM_VERSION' );
2549 function swap( &$x, &$y ) {
2569 if ( $wgTmpDirectory !==
false ) {
2570 return $wgTmpDirectory;
2573 $tmpDir = array_map(
"getenv",
array(
'TMPDIR',
'TMP',
'TEMP' ) );
2575 foreach ( $tmpDir
as $tmp ) {
2576 if ( $tmp && file_exists( $tmp ) && is_dir( $tmp ) && is_writable( $tmp ) ) {
2580 return sys_get_temp_dir();
2596 throw new MWException( __FUNCTION__ .
" given storage path '$dir'." );
2599 if ( !is_null( $caller ) ) {
2600 wfDebug(
"$caller: called wfMkdirParents($dir)\n" );
2603 if ( strval(
$dir ) ===
'' || ( file_exists(
$dir ) && is_dir(
$dir ) ) ) {
2607 $dir = str_replace(
array(
'\\',
'/' ), DIRECTORY_SEPARATOR,
$dir );
2609 if ( is_null( $mode ) ) {
2610 $mode = $wgDirectoryMode;
2615 $ok = mkdir(
$dir, $mode,
true );
2620 if ( is_dir(
$dir ) ) {
2635 wfDebug( __FUNCTION__ .
"( $dir )\n" );
2637 if ( is_dir(
$dir ) ) {
2638 $objects = scandir(
$dir );
2639 foreach ( $objects
as $object ) {
2640 if ( $object !=
"." && $object !=
".." ) {
2641 if ( filetype(
$dir .
'/' . $object ) ==
"dir" ) {
2644 unlink(
$dir .
'/' . $object );
2659 function wfPercent( $nr, $acc = 2, $round =
true ) {
2660 $ret = sprintf(
"%.${acc}f", $nr );
2661 return $round ? round(
$ret, $acc ) .
'%' :
"$ret%";
2688 $val = strtolower( ini_get( $setting ) );
2693 || preg_match(
"/^\s*[+-]?0*[1-9]/", $val );
2710 $args = func_get_args();
2730 $tokens = preg_split(
'/(\\\\*")/', $arg, -1, PREG_SPLIT_DELIM_CAPTURE );
2733 foreach ( $tokens
as $token ) {
2734 if ( $iteration % 2 == 1 ) {
2736 $arg .= str_replace(
'\\',
'\\\\', substr( $token, 0, -1 ) ) .
'\\"';
2737 } elseif ( $iteration % 4 == 2 ) {
2739 $arg .= str_replace(
'^',
'^^', $token );
2749 if ( preg_match(
'/^(.*?)(\\\\+)$/', $arg, $m ) ) {
2750 $arg = $m[1] . str_replace(
'\\',
'\\\\', $m[2] );
2754 $retVal .=
'"' . $arg .
'"';
2756 $retVal .= escapeshellarg( $arg );
2769 static $disabled =
null;
2770 if ( is_null( $disabled ) ) {
2773 wfDebug(
"wfShellExec can't run in safe_mode, PHP's exec functions are too broken.\n" );
2774 $disabled =
'safemode';
2776 $functions = explode(
',', ini_get(
'disable_functions' ) );
2777 $functions = array_map(
'trim', $functions );
2778 $functions = array_map(
'strtolower', $functions );
2779 if ( in_array(
'proc_open', $functions ) ) {
2780 wfDebug(
"proc_open is in disabled_functions\n" );
2781 $disabled =
'disabled';
2809 global $IP, $wgMaxShellMemory, $wgMaxShellFileSize, $wgMaxShellTime,
2810 $wgMaxShellWallClockTime, $wgShellCgroup;
2815 return $disabled ==
'safemode' ?
2816 'Unable to run external programs in safe mode.' :
2817 'Unable to run external programs, proc_open() is disabled.';
2820 $includeStderr = isset(
$options[
'duplicateStderr'] ) &&
$options[
'duplicateStderr'];
2825 foreach ( $environ
as $k => $v ) {
2833 $envcmd .=
"set $k=" . preg_replace(
'/([&|()<>^"])/',
'^\\1', $v ) .
'&& ';
2838 $envcmd .=
"$k=" . escapeshellarg( $v ) .
' ';
2841 $cmd = $envcmd . $cmd;
2843 $useLogPipe =
false;
2844 if ( php_uname(
's' ) ==
'Linux' ) {
2845 $time = intval ( isset( $limits[
'time'] ) ? $limits[
'time'] : $wgMaxShellTime );
2846 if ( isset( $limits[
'walltime'] ) ) {
2847 $wallTime = intval( $limits[
'walltime'] );
2848 } elseif ( isset( $limits[
'time'] ) ) {
2851 $wallTime = intval( $wgMaxShellWallClockTime );
2853 $mem = intval ( isset( $limits[
'memory'] ) ? $limits[
'memory'] : $wgMaxShellMemory );
2854 $filesize = intval ( isset( $limits[
'filesize'] ) ? $limits[
'filesize'] : $wgMaxShellFileSize );
2856 if (
$time > 0 || $mem > 0 || $filesize > 0 || $wallTime > 0 ) {
2857 $cmd =
'/bin/bash ' . escapeshellarg(
"$IP/includes/limit.sh" ) .
' ' .
2858 escapeshellarg( $cmd ) .
' ' .
2860 "MW_INCLUDE_STDERR=" . ( $includeStderr ?
'1' :
'' ) .
';' .
2861 "MW_CPU_LIMIT=$time; " .
2862 'MW_CGROUP=' . escapeshellarg( $wgShellCgroup ) .
'; ' .
2863 "MW_MEM_LIMIT=$mem; " .
2864 "MW_FILE_SIZE_LIMIT=$filesize; " .
2865 "MW_WALL_CLOCK_LIMIT=$wallTime; " .
2866 "MW_USE_LOG_PIPE=yes"
2869 } elseif ( $includeStderr ) {
2872 } elseif ( $includeStderr ) {
2875 wfDebug(
"wfShellExec: $cmd\n" );
2878 0 =>
array(
'file',
'php://stdin',
'r' ),
2879 1 =>
array(
'pipe',
'w' ),
2880 2 =>
array(
'file',
'php://stderr',
'w' ) );
2881 if ( $useLogPipe ) {
2882 $desc[3] =
array(
'pipe',
'w' );
2885 $proc = proc_open( $cmd, $desc, $pipes );
2887 wfDebugLog(
'exec',
"proc_open() failed: $cmd" );
2891 $outBuffer = $logBuffer =
'';
2892 $emptyArray =
array();
2906 $eintr = defined(
'SOCKET_EINTR' ) ? SOCKET_EINTR : 4;
2907 $eintrMessage =
"stream_select(): unable to select [$eintr]";
2913 foreach ( $pipes
as $fd => $pipe ) {
2914 $fds[(int)$pipe] = $fd;
2918 $status = proc_get_status( $proc );
2919 if ( !$status[
'running'] ) {
2924 $readyPipes = $pipes;
2927 @trigger_error(
'' );
2928 if ( @stream_select( $readyPipes, $emptyArray, $emptyArray,
null ) ===
false ) {
2929 $error = error_get_last();
2930 if ( strncmp(
$error[
'message'], $eintrMessage, strlen( $eintrMessage ) ) == 0 ) {
2933 trigger_error(
$error[
'message'], E_USER_WARNING );
2934 $logMsg =
$error[
'message'];
2938 foreach ( $readyPipes
as $pipe ) {
2939 $block = fread( $pipe, 65536 );
2940 $fd = $fds[(int)$pipe];
2941 if ( $block ===
'' ) {
2943 fclose( $pipes[$fd] );
2944 unset( $pipes[$fd] );
2948 } elseif ( $block ===
false ) {
2950 $logMsg =
"Error reading from pipe";
2952 } elseif ( $fd == 1 ) {
2954 $outBuffer .= $block;
2955 } elseif ( $fd == 3 ) {
2957 $logBuffer .= $block;
2958 if ( strpos( $block,
"\n" ) !==
false ) {
2959 $lines = explode(
"\n", $logBuffer );
2960 $logBuffer = array_pop(
$lines );
2969 foreach ( $pipes
as $pipe ) {
2975 if ( $status ===
false ) {
2976 $status = proc_get_status( $proc );
2979 if ( $logMsg !==
false ) {
2982 proc_close( $proc );
2983 } elseif ( $status[
'signaled'] ) {
2984 $logMsg =
"Exited with signal {$status['termsig']}";
2985 $retval = 128 + $status[
'termsig'];
2986 proc_close( $proc );
2988 if ( $status[
'running'] ) {
2989 $retval = proc_close( $proc );
2991 $retval = $status[
'exitcode'];
2992 proc_close( $proc );
2995 $logMsg =
"Possibly missing executable file";
2997 $logMsg =
"Probably exited with signal " . (
$retval - 128 );
3001 if ( $logMsg !==
false ) {
3031 static $done =
false;
3038 putenv(
"LC_CTYPE=$wgShellLocale" );
3039 setlocale( LC_CTYPE, $wgShellLocale );
3070 if ( isset(
$options[
'wrapper'] ) ) {
3075 return implode(
" ", array_map(
'wfEscapeShellArg', array_merge( $cmd, $parameters ) ) );
3091 # This check may also protect against code injection in
3092 # case of broken installations.
3094 $haveDiff3 = $wgDiff3 && file_exists( $wgDiff3 );
3097 if ( !$haveDiff3 ) {
3098 wfDebug(
"diff3 not found\n" );
3102 # Make temporary files
3104 $oldtextFile = fopen( $oldtextName = tempnam( $td,
'merge-old-' ),
'w' );
3105 $mytextFile = fopen( $mytextName = tempnam( $td,
'merge-mine-' ),
'w' );
3106 $yourtextFile = fopen( $yourtextName = tempnam( $td,
'merge-your-' ),
'w' );
3108 # NOTE: diff3 issues a warning to stderr if any of the files does not end with
3109 # a newline character. To avoid this, we normalize the trailing whitespace before
3110 # creating the diff.
3112 fwrite( $oldtextFile, rtrim( $old ) .
"\n" );
3113 fclose( $oldtextFile );
3114 fwrite( $mytextFile, rtrim( $mine ) .
"\n" );
3115 fclose( $mytextFile );
3116 fwrite( $yourtextFile, rtrim( $yours ) .
"\n" );
3117 fclose( $yourtextFile );
3119 # Check for a conflict
3124 $handle = popen( $cmd,
'r' );
3126 if ( fgets( $handle, 1024 ) ) {
3136 $handle = popen( $cmd,
'r' );
3139 $data = fread( $handle, 8192 );
3140 if ( strlen( $data ) == 0 ) {
3146 unlink( $mytextName );
3147 unlink( $oldtextName );
3148 unlink( $yourtextName );
3150 if (
$result ===
'' && $old !==
'' && !$conflict ) {
3151 wfDebug(
"Unexpected null result from diff3. Command: $cmd\n" );
3167 if ( $before == $after ) {
3173 $haveDiff = $wgDiff && file_exists( $wgDiff );
3176 # This check may also protect against code injection in
3177 # case of broken installations.
3179 wfDebug(
"diff executable not found\n" );
3180 $diffs =
new Diff( explode(
"\n", $before ), explode(
"\n", $after ) );
3182 return $format->format( $diffs );
3185 # Make temporary files
3187 $oldtextFile = fopen( $oldtextName = tempnam( $td,
'merge-old-' ),
'w' );
3188 $newtextFile = fopen( $newtextName = tempnam( $td,
'merge-your-' ),
'w' );
3190 fwrite( $oldtextFile, $before );
3191 fclose( $oldtextFile );
3192 fwrite( $newtextFile, $after );
3193 fclose( $newtextFile );
3198 $h = popen( $cmd,
'r' );
3203 $data = fread( $h, 8192 );
3204 if ( strlen( $data ) == 0 ) {
3212 unlink( $oldtextName );
3213 unlink( $newtextName );
3216 $diff_lines = explode(
"\n", $diff );
3217 if ( strpos( $diff_lines[0],
'---' ) === 0 ) {
3218 unset( $diff_lines[0] );
3220 if ( strpos( $diff_lines[1],
'+++' ) === 0 ) {
3221 unset( $diff_lines[1] );
3224 $diff = implode(
"\n", $diff_lines );
3246 $php_ver = PHP_VERSION;
3248 if ( version_compare( $php_ver, (
string)$req_ver,
'<' ) ) {
3249 throw new MWException(
"PHP $req_ver required--this is only $php_ver" );
3275 function wfUseMW( $req_ver ) {
3278 if ( version_compare( $wgVersion, (
string)$req_ver,
'<' ) ) {
3279 throw new MWException(
"MediaWiki $req_ver required--this is only $wgVersion" );
3296 if ( $suffix ==
'' ) {
3299 $encSuffix =
'(?:' . preg_quote( $suffix,
'#' ) .
')?';
3303 if ( preg_match(
"#([^/\\\\]*?){$encSuffix}[/\\\\]*$#",
$path,
$matches ) ) {
3321 $path = str_replace(
'/', DIRECTORY_SEPARATOR,
$path );
3322 $from = str_replace(
'/', DIRECTORY_SEPARATOR,
$from );
3328 $pieces = explode( DIRECTORY_SEPARATOR, dirname(
$path ) );
3329 $against = explode( DIRECTORY_SEPARATOR,
$from );
3331 if ( $pieces[0] !== $against[0] ) {
3338 while ( count( $pieces ) && count( $against )
3339 && $pieces[0] == $against[0] ) {
3340 array_shift( $pieces );
3341 array_shift( $against );
3345 while ( count( $against ) ) {
3346 array_unshift( $pieces,
'..' );
3347 array_shift( $against );
3352 return implode( DIRECTORY_SEPARATOR, $pieces );
3370 function wfBaseConvert( $input, $sourceBase, $destBase, $pad = 1,
3371 $lowercase =
true, $engine =
'auto'
3373 $input = (string)$input;
3379 $sourceBase != (
int)$sourceBase ||
3380 $destBase != (int)$destBase ||
3381 $pad != (
int)$pad ||
3383 "/^[" . substr(
'0123456789abcdefghijklmnopqrstuvwxyz', 0, $sourceBase ) .
"]+$/i",
3390 static $baseChars =
array(
3391 10 =>
'a', 11 =>
'b', 12 =>
'c', 13 =>
'd', 14 =>
'e', 15 =>
'f',
3392 16 =>
'g', 17 =>
'h', 18 =>
'i', 19 =>
'j', 20 =>
'k', 21 =>
'l',
3393 22 =>
'm', 23 =>
'n', 24 =>
'o', 25 =>
'p', 26 =>
'q', 27 =>
'r',
3394 28 =>
's', 29 =>
't', 30 =>
'u', 31 =>
'v', 32 =>
'w', 33 =>
'x',
3395 34 =>
'y', 35 =>
'z',
3397 '0' => 0,
'1' => 1,
'2' => 2,
'3' => 3,
'4' => 4,
'5' => 5,
3398 '6' => 6,
'7' => 7,
'8' => 8,
'9' => 9,
'a' => 10,
'b' => 11,
3399 'c' => 12,
'd' => 13,
'e' => 14,
'f' => 15,
'g' => 16,
'h' => 17,
3400 'i' => 18,
'j' => 19,
'k' => 20,
'l' => 21,
'm' => 22,
'n' => 23,
3401 'o' => 24,
'p' => 25,
'q' => 26,
'r' => 27,
's' => 28,
't' => 29,
3402 'u' => 30,
'v' => 31,
'w' => 32,
'x' => 33,
'y' => 34,
'z' => 35
3405 if ( extension_loaded(
'gmp' ) && ( $engine ==
'auto' || $engine ==
'gmp' ) ) {
3406 $result = gmp_strval( gmp_init( $input, $sourceBase ), $destBase );
3407 } elseif ( extension_loaded(
'bcmath' ) && ( $engine ==
'auto' || $engine ==
'bcmath' ) ) {
3409 foreach ( str_split( strtolower( $input ) )
as $char ) {
3410 $decimal = bcmul( $decimal, $sourceBase );
3411 $decimal = bcadd( $decimal, $baseChars[$char] );
3414 for (
$result =
''; bccomp( $decimal, 0 ); $decimal = bcdiv( $decimal, $destBase, 0 ) ) {
3415 $result .= $baseChars[bcmod( $decimal, $destBase )];
3420 $inDigits =
array();
3421 foreach ( str_split( strtolower( $input ) )
as $char ) {
3422 $inDigits[] = $baseChars[$char];
3428 while ( $inDigits ) {
3430 $workDigits =
array();
3433 foreach ( $inDigits
as $digit ) {
3434 $work *= $sourceBase;
3437 if ( $workDigits || $work >= $destBase ) {
3438 $workDigits[] = (int)( $work / $destBase );
3448 $inDigits = $workDigits;
3454 if ( !$lowercase ) {
3458 return str_pad(
$result, $pad,
'0', STR_PAD_LEFT );
3468 (
wfIsWindows() && version_compare( PHP_VERSION,
'5.3.3',
'>=' ) )
3469 || ini_get(
'session.entropy_file' )
3471 && intval( ini_get(
'session.entropy_length' ) ) >= 32;
3480 if ( isset( $_COOKIE[session_name()] ) || session_id() ) {
3492 if ( !$entropyEnabled ) {
3493 wfDebug( __METHOD__ .
": PHP's built in entropy is disabled or not sufficient, " .
3494 "overriding session id generation using our cryptrand source.\n" );
3506 $oldSessionId = session_id();
3507 $cookieParams = session_get_cookie_params();
3508 if (
wfCheckEntropy() && $wgCookieSecure == $cookieParams[
'secure'] ) {
3509 session_regenerate_id(
false );
3516 $newSessionId = session_id();
3517 wfRunHooks(
'ResetSessionID',
array( $oldSessionId, $newSessionId ) );
3526 global $wgSessionsInMemcached, $wgSessionsInObjectCache, $wgCookiePath, $wgCookieDomain,
3527 $wgCookieSecure, $wgCookieHttpOnly, $wgSessionHandler;
3528 if ( $wgSessionsInObjectCache || $wgSessionsInMemcached ) {
3530 } elseif ( $wgSessionHandler && $wgSessionHandler != ini_get(
'session.save_handler' ) ) {
3531 # Only set this if $wgSessionHandler isn't null and session.save_handler
3532 # hasn't already been set to the desired value (that causes errors)
3533 ini_set(
'session.save_handler', $wgSessionHandler );
3535 session_set_cookie_params(
3536 0, $wgCookiePath, $wgCookieDomain, $wgCookieSecure, $wgCookieHttpOnly );
3537 session_cache_limiter(
'private, must-revalidate' );
3539 session_id( $sessionId );
3557 $file =
"$IP/serialized/$name";
3558 if ( file_exists(
$file ) ) {
3561 return unserialize(
$blob );
3575 $prefix = $wgCachePrefix ===
false ?
wfWikiID() : $wgCachePrefix;
3576 $args = func_get_args();
3577 $key = $prefix .
':' . implode(
':',
$args );
3578 $key = str_replace(
' ',
'_', $key );
3591 $args = array_slice( func_get_args(), 2 );
3593 $key =
"$db-$prefix:" . implode(
':',
$args );
3595 $key = $db .
':' . implode(
':',
$args );
3597 return str_replace(
' ',
'_', $key );
3608 if ( $wgDBprefix ) {
3609 return "$wgDBname-$wgDBprefix";
3623 $bits = explode(
'-', $wiki, 2 );
3624 if ( count( $bits ) < 2 ) {
3652 function &
wfGetDB( $db, $groups =
array(), $wiki =
false ) {
3653 return wfGetLB( $wiki )->getConnection( $db, $groups, $wiki );
3662 function wfGetLB( $wiki =
false ) {
3732 function wfScript( $script =
'index' ) {
3733 global $wgScriptPath, $wgScriptExtension, $wgScript, $wgLoadScript;
3734 if ( $script ===
'index' ) {
3736 } elseif ( $script ===
'load' ) {
3737 return $wgLoadScript;
3739 return "{$wgScriptPath}/{$script}{$wgScriptExtension}";
3749 if ( isset( $_SERVER[
'SCRIPT_NAME'] ) ) {
3751 # as it was called, minus the query string.
3753 # Some sites use Apache rewrite rules to handle subdomains,
3754 # and have PHP set up in a weird way that causes PHP_SELF
3755 # to contain the rewritten URL instead of the one that the
3756 # outside world sees.
3758 # If in this mode, use SCRIPT_URL instead, which mod_rewrite
3759 # provides containing the "before" URL.
3760 return $_SERVER[
'SCRIPT_NAME'];
3762 return $_SERVER[
'URL'];
3774 return $value ?
'true' :
'false';
3797 function wfWaitForSlaves( $maxLag =
false, $wiki =
false, $cluster =
false ) {
3798 if ( $cluster !==
false ) {
3806 if (
$lb->getServerCount() > 1 ) {
3808 $pos = $dbw->getMasterPos();
3811 if ( $pos !==
false ) {
3812 $lb->waitForAll( $pos );
3825 for ( $i = $seconds; $i >= 0; $i-- ) {
3826 if ( $i != $seconds ) {
3827 echo str_repeat(
"\x08", strlen( $i + 1 ) );
3847 global $wgIllegalFileChars;
3848 $illegalFileChars = $wgIllegalFileChars ?
"|[" . $wgIllegalFileChars .
"]" :
'';
3850 $name = preg_replace(
3866 if ( $memlimit != -1 ) {
3868 if ( $conflimit == -1 ) {
3869 wfDebug(
"Removing PHP's memory limit\n" );
3871 ini_set(
'memory_limit', $conflimit );
3874 } elseif ( $conflimit > $memlimit ) {
3875 wfDebug(
"Raising PHP's memory limit to $conflimit bytes\n" );
3877 ini_set(
'memory_limit', $conflimit );
3892 $string = trim( $string );
3893 if ( $string ===
'' ) {
3896 $last = $string[strlen( $string ) - 1];
3897 $val = intval( $string );
3923 $codeSegment = explode(
'-', $code );
3925 foreach ( $codeSegment
as $segNo => $seg ) {
3927 if ( $segNo > 0 && strtolower( $codeSegment[( $segNo - 1 )] ) ==
'x' ) {
3928 $codeBCP[$segNo] = strtolower( $seg );
3930 } elseif ( ( strlen( $seg ) == 2 ) && ( $segNo > 0 ) ) {
3931 $codeBCP[$segNo] = strtoupper( $seg );
3933 } elseif ( ( strlen( $seg ) == 4 ) && ( $segNo > 0 ) ) {
3934 $codeBCP[$segNo] = ucfirst( strtolower( $seg ) );
3937 $codeBCP[$segNo] = strtolower( $seg );
3940 $langCode = implode(
'-', $codeBCP );
3970 global $wgMessageCacheType;
3980 global $wgParserCacheType;
3990 global $wgLanguageConverterCacheType;
4021 function wfUnpack( $format, $data, $length =
false ) {
4022 if ( $length !==
false ) {
4023 $realLen = strlen( $data );
4024 if ( $realLen < $length ) {
4025 throw new MWException(
"Tried to use wfUnpack on a "
4026 .
"string of length $realLen, but needed one "
4027 .
"of at least length $length."
4033 $result = unpack( $format, $data );
4038 throw new MWException(
"unpack could not unpack binary data" );
4058 static $badImageCache =
null;
4063 if ( $redirectTitle ) {
4064 $name = $redirectTitle->getDBkey();
4067 # Run the extension hook
4074 $cacheable = ( $blacklist === null );
4075 if ( $cacheable && $badImageCache !==
null ) {
4076 $badImages = $badImageCache;
4078 if ( $blacklist ===
null ) {
4079 $blacklist =
wfMessage(
'bad_image_list' )->inContentLanguage()->plain();
4081 # Build the list now
4082 $badImages =
array();
4083 $lines = explode(
"\n", $blacklist );
4086 if ( substr(
$line, 0, 1 ) !==
'*' ) {
4092 if ( !preg_match_all(
'/\[\[:?(.*?)\]\]/',
$line, $m ) ) {
4097 $imageDBkey =
false;
4098 foreach ( $m[1]
as $i => $titleText ) {
4100 if ( !is_null(
$title ) ) {
4102 $imageDBkey =
$title->getDBkey();
4109 if ( $imageDBkey !==
false ) {
4114 $badImageCache = $badImages;
4118 $contextKey = $contextTitle ? $contextTitle->getPrefixedDBkey() :
false;
4119 $bad = isset( $badImages[
$name] ) && !isset( $badImages[
$name][$contextKey] );
4147 return $wgRequest->getIP();
4172 global $wgSquidServers, $wgSquidServersNoPurge;
4175 $trusted = in_array( $ip, $wgSquidServers )
4176 || in_array( $ip, $wgSquidServersNoPurge );
4181 foreach ( $wgSquidServersNoPurge
as $block ) {
4182 if ( strpos( $block,
'/' ) !==
false &&
IP::isInRange( $ip, $block ) ) {