summaryrefslogtreecommitdiff
path: root/includes/GlobalFunctions.php
diff options
context:
space:
mode:
Diffstat (limited to 'includes/GlobalFunctions.php')
-rw-r--r--includes/GlobalFunctions.php1071
1 files changed, 629 insertions, 442 deletions
diff --git a/includes/GlobalFunctions.php b/includes/GlobalFunctions.php
index 8ed79c40..52cd46a5 100644
--- a/includes/GlobalFunctions.php
+++ b/includes/GlobalFunctions.php
@@ -81,6 +81,9 @@ if ( !function_exists( 'istainted' ) ) {
/**
* Like array_diff( $a, $b ) except that it works with two-dimensional arrays.
+ * @param $a array
+ * @param $b array
+ * @return array
*/
function wfArrayDiff2( $a, $b ) {
return array_udiff( $a, $b, 'wfArrayDiff2_cmp' );
@@ -164,7 +167,7 @@ function wfArrayMerge( $array1/* ... */ ) {
* array( array( 'x' ) ),
* array( array( 'x', '2' ) ),
* array( array( 'x' ) ),
- * array( array( 'y') )
+ * array( array( 'y' ) )
* );
* returns:
* array(
@@ -296,9 +299,9 @@ function wfUrlencode( $s ) {
static $needle;
if ( is_null( $s ) ) {
$needle = null;
- return;
+ return '';
}
-
+
if ( is_null( $needle ) ) {
$needle = array( '%3B', '%40', '%24', '%21', '%2A', '%28', '%29', '%2C', '%2F' );
if ( !isset( $_SERVER['SERVER_SOFTWARE'] ) || ( strpos( $_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS/7' ) === false ) ) {
@@ -319,7 +322,7 @@ function wfUrlencode( $s ) {
/**
* This function takes two arrays as input, and returns a CGI-style string, e.g.
* "days=7&limit=100". Options in the first array override options in the second.
- * Options set to "" will not be output.
+ * Options set to null or false will not be output.
*
* @param $array1 Array ( String|Array )
* @param $array2 Array ( String|Array )
@@ -333,7 +336,7 @@ function wfArrayToCGI( $array1, $array2 = null, $prefix = '' ) {
$cgi = '';
foreach ( $array1 as $key => $value ) {
- if ( $value !== '' ) {
+ if ( !is_null($value) && $value !== false ) {
if ( $cgi != '' ) {
$cgi .= '&';
}
@@ -366,8 +369,7 @@ function wfArrayToCGI( $array1, $array2 = null, $prefix = '' ) {
* This is the logical opposite of wfArrayToCGI(): it accepts a query string as
* its argument and returns the same string in array form. This allows compa-
* tibility with legacy functions that accept raw query strings instead of nice
- * arrays. Of course, keys and values are urldecode()d. Don't try passing in-
- * valid query strings, or it will explode.
+ * arrays. Of course, keys and values are urldecode()d.
*
* @param $query String: query string
* @return array Array version of input
@@ -382,7 +384,13 @@ function wfCgiToArray( $query ) {
if ( $bit === '' ) {
continue;
}
- list( $key, $value ) = explode( '=', $bit );
+ if ( strpos( $bit, '=' ) === false ) {
+ // Pieces like &qwerty become 'qwerty' => '' (at least this is what php does)
+ $key = $bit;
+ $value = '';
+ } else {
+ list( $key, $value ) = explode( '=', $bit );
+ }
$key = urldecode( $key );
$value = urldecode( $value );
if ( strpos( $key, '[' ) !== false ) {
@@ -444,8 +452,11 @@ function wfAppendQuery( $url, $query ) {
* like "subdir/foo.html", etc.
*
* @param $url String: either fully-qualified or a local path + query
- * @param $defaultProto Mixed: one of the PROTO_* constants. Determines the protocol to use if $url or $wgServer is protocol-relative
- * @return string Fully-qualified URL
+ * @param $defaultProto Mixed: one of the PROTO_* constants. Determines the
+ * protocol to use if $url or $wgServer is
+ * protocol-relative
+ * @return string Fully-qualified URL, current-path-relative URL or false if
+ * no valid URL can be constructed
*/
function wfExpandUrl( $url, $defaultProto = PROTO_CURRENT ) {
global $wgServer, $wgCanonicalServer, $wgInternalServer;
@@ -477,21 +488,170 @@ function wfExpandUrl( $url, $defaultProto = PROTO_CURRENT ) {
$defaultProtoWithoutSlashes = substr( $defaultProto, 0, -2 );
- if( substr( $url, 0, 2 ) == '//' ) {
- return $defaultProtoWithoutSlashes . $url;
- } elseif( substr( $url, 0, 1 ) == '/' ) {
+ if ( substr( $url, 0, 2 ) == '//' ) {
+ $url = $defaultProtoWithoutSlashes . $url;
+ } elseif ( substr( $url, 0, 1 ) == '/' ) {
// If $serverUrl is protocol-relative, prepend $defaultProtoWithoutSlashes, otherwise leave it alone
- return ( $serverHasProto ? '' : $defaultProtoWithoutSlashes ) . $serverUrl . $url;
- } else {
+ $url = ( $serverHasProto ? '' : $defaultProtoWithoutSlashes ) . $serverUrl . $url;
+ }
+
+ $bits = wfParseUrl( $url );
+ if ( $bits && isset( $bits['path'] ) ) {
+ $bits['path'] = wfRemoveDotSegments( $bits['path'] );
+ return wfAssembleUrl( $bits );
+ } elseif ( $bits ) {
+ # No path to expand
return $url;
+ } elseif ( substr( $url, 0, 1 ) != '/' ) {
+ # URL is a relative path
+ return wfRemoveDotSegments( $url );
+ }
+
+ # Expanded URL is not valid.
+ return false;
+}
+
+/**
+ * This function will reassemble a URL parsed with wfParseURL. This is useful
+ * if you need to edit part of a URL and put it back together.
+ *
+ * This is the basic structure used (brackets contain keys for $urlParts):
+ * [scheme][delimiter][user]:[pass]@[host]:[port][path]?[query]#[fragment]
+ *
+ * @todo Need to integrate this into wfExpandUrl (bug 32168)
+ *
+ * @since 1.19
+ * @param $urlParts Array URL parts, as output from wfParseUrl
+ * @return string URL assembled from its component parts
+ */
+function wfAssembleUrl( $urlParts ) {
+ $result = '';
+
+ if ( isset( $urlParts['delimiter'] ) ) {
+ if ( isset( $urlParts['scheme'] ) ) {
+ $result .= $urlParts['scheme'];
+ }
+
+ $result .= $urlParts['delimiter'];
+ }
+
+ if ( isset( $urlParts['host'] ) ) {
+ if ( isset( $urlParts['user'] ) ) {
+ $result .= $urlParts['user'];
+ if ( isset( $urlParts['pass'] ) ) {
+ $result .= ':' . $urlParts['pass'];
+ }
+ $result .= '@';
+ }
+
+ $result .= $urlParts['host'];
+
+ if ( isset( $urlParts['port'] ) ) {
+ $result .= ':' . $urlParts['port'];
+ }
+ }
+
+ if ( isset( $urlParts['path'] ) ) {
+ $result .= $urlParts['path'];
+ }
+
+ if ( isset( $urlParts['query'] ) ) {
+ $result .= '?' . $urlParts['query'];
+ }
+
+ if ( isset( $urlParts['fragment'] ) ) {
+ $result .= '#' . $urlParts['fragment'];
+ }
+
+ return $result;
+}
+
+/**
+ * Remove all dot-segments in the provided URL path. For example,
+ * '/a/./b/../c/' becomes '/a/c/'. For details on the algorithm, please see
+ * RFC3986 section 5.2.4.
+ *
+ * @todo Need to integrate this into wfExpandUrl (bug 32168)
+ *
+ * @param $urlPath String URL path, potentially containing dot-segments
+ * @return string URL path with all dot-segments removed
+ */
+function wfRemoveDotSegments( $urlPath ) {
+ $output = '';
+ $inputOffset = 0;
+ $inputLength = strlen( $urlPath );
+
+ while ( $inputOffset < $inputLength ) {
+ $prefixLengthOne = substr( $urlPath, $inputOffset, 1 );
+ $prefixLengthTwo = substr( $urlPath, $inputOffset, 2 );
+ $prefixLengthThree = substr( $urlPath, $inputOffset, 3 );
+ $prefixLengthFour = substr( $urlPath, $inputOffset, 4 );
+ $trimOutput = false;
+
+ if ( $prefixLengthTwo == './' ) {
+ # Step A, remove leading "./"
+ $inputOffset += 2;
+ } elseif ( $prefixLengthThree == '../' ) {
+ # Step A, remove leading "../"
+ $inputOffset += 3;
+ } elseif ( ( $prefixLengthTwo == '/.' ) && ( $inputOffset + 2 == $inputLength ) ) {
+ # Step B, replace leading "/.$" with "/"
+ $inputOffset += 1;
+ $urlPath[$inputOffset] = '/';
+ } elseif ( $prefixLengthThree == '/./' ) {
+ # Step B, replace leading "/./" with "/"
+ $inputOffset += 2;
+ } elseif ( $prefixLengthThree == '/..' && ( $inputOffset + 3 == $inputLength ) ) {
+ # Step C, replace leading "/..$" with "/" and
+ # remove last path component in output
+ $inputOffset += 2;
+ $urlPath[$inputOffset] = '/';
+ $trimOutput = true;
+ } elseif ( $prefixLengthFour == '/../' ) {
+ # Step C, replace leading "/../" with "/" and
+ # remove last path component in output
+ $inputOffset += 3;
+ $trimOutput = true;
+ } elseif ( ( $prefixLengthOne == '.' ) && ( $inputOffset + 1 == $inputLength ) ) {
+ # Step D, remove "^.$"
+ $inputOffset += 1;
+ } elseif ( ( $prefixLengthTwo == '..' ) && ( $inputOffset + 2 == $inputLength ) ) {
+ # Step D, remove "^..$"
+ $inputOffset += 2;
+ } else {
+ # Step E, move leading path segment to output
+ if ( $prefixLengthOne == '/' ) {
+ $slashPos = strpos( $urlPath, '/', $inputOffset + 1 );
+ } else {
+ $slashPos = strpos( $urlPath, '/', $inputOffset );
+ }
+ if ( $slashPos === false ) {
+ $output .= substr( $urlPath, $inputOffset );
+ $inputOffset = $inputLength;
+ } else {
+ $output .= substr( $urlPath, $inputOffset, $slashPos - $inputOffset );
+ $inputOffset += $slashPos - $inputOffset;
+ }
+ }
+
+ if ( $trimOutput ) {
+ $slashPos = strrpos( $output, '/' );
+ if ( $slashPos === false ) {
+ $output = '';
+ } else {
+ $output = substr( $output, 0, $slashPos );
+ }
+ }
}
+
+ return $output;
}
/**
* Returns a regular expression of url protocols
*
* @param $includeProtocolRelative bool If false, remove '//' from the returned protocol list.
- * DO NOT USE this directy, use wfUrlProtocolsWithoutProtRel() instead
+ * DO NOT USE this directly, use wfUrlProtocolsWithoutProtRel() instead
* @return String
*/
function wfUrlProtocols( $includeProtocolRelative = true ) {
@@ -537,6 +697,7 @@ function wfUrlProtocols( $includeProtocolRelative = true ) {
* Like wfUrlProtocols(), but excludes '//' from the protocol list. Use this if
* you need a regex that matches all URL protocols but does not match protocol-
* relative URLs
+ * @return String
*/
function wfUrlProtocolsWithoutProtRel() {
return wfUrlProtocols( false );
@@ -554,7 +715,7 @@ function wfUrlProtocolsWithoutProtRel() {
*/
function wfParseUrl( $url ) {
global $wgUrlProtocols; // Allow all protocols defined in DefaultSettings/LocalSettings.php
-
+
// Protocol-relative URLs are handled really badly by parse_url(). It's so bad that the easiest
// way to handle them is to just prepend 'http:' and strip the protocol out later
$wasRelative = substr( $url, 0, 2 ) == '//';
@@ -564,7 +725,9 @@ function wfParseUrl( $url ) {
wfSuppressWarnings();
$bits = parse_url( $url );
wfRestoreWarnings();
- if ( !$bits ) {
+ // parse_url() returns an array without scheme for some invalid URLs, e.g.
+ // parse_url("%0Ahttp://example.com") == array( 'host' => '%0Ahttp', 'path' => 'example.com' )
+ if ( !$bits || !isset( $bits['scheme'] ) ) {
return false;
}
@@ -592,7 +755,7 @@ function wfParseUrl( $url ) {
$bits['path'] = '/' . $bits['path'];
}
}
-
+
// If the URL was protocol-relative, fix scheme and delimiter
if ( $wasRelative ) {
$bits['scheme'] = '';
@@ -717,6 +880,8 @@ function wfDebug( $text, $logonly = false ) {
wfErrorLog( $text, $wgDebugLogFile );
}
}
+
+ MWDebug::debugMsg( $text );
}
/**
@@ -747,20 +912,15 @@ function wfIsDebugRawPage() {
* @return string
*/
function wfDebugTimer() {
- global $wgDebugTimestamps;
+ global $wgDebugTimestamps, $wgRequestTime;
+
if ( !$wgDebugTimestamps ) {
return '';
}
- static $start = null;
- if ( $start === null ) {
- $start = microtime( true );
- $prefix = "\n$start";
- } else {
- $prefix = sprintf( "%6.4f", microtime( true ) - $start );
- }
-
- return $prefix . ' ';
+ $prefix = sprintf( "%6.4f", microtime( true ) - $wgRequestTime );
+ $mem = sprintf( "%5.1fM", ( memory_get_usage( true ) / ( 1024 * 1024 ) ) );
+ return "$prefix $mem ";
}
/**
@@ -788,16 +948,12 @@ function wfDebugMem( $exact = false ) {
* log file is specified, (default true)
*/
function wfDebugLog( $logGroup, $text, $public = true ) {
- global $wgDebugLogGroups, $wgShowHostnames;
+ global $wgDebugLogGroups;
$text = trim( $text ) . "\n";
if( isset( $wgDebugLogGroups[$logGroup] ) ) {
$time = wfTimestamp( TS_DB );
$wiki = wfWikiID();
- if ( $wgShowHostnames ) {
- $host = wfHostname();
- } else {
- $host = '';
- }
+ $host = wfHostname();
if ( wfRunHooks( 'Debug', array( $text, $logGroup ) ) ) {
wfErrorLog( "$time $host $wiki: $text", $wgDebugLogGroups[$logGroup] );
}
@@ -812,15 +968,98 @@ function wfDebugLog( $logGroup, $text, $public = true ) {
* @param $text String: database error message.
*/
function wfLogDBError( $text ) {
- global $wgDBerrorLog, $wgDBname;
+ global $wgDBerrorLog;
if ( $wgDBerrorLog ) {
- $host = trim(`hostname`);
- $text = date( 'D M j G:i:s T Y' ) . "\t$host\t$wgDBname\t$text";
+ $host = wfHostname();
+ $wiki = wfWikiID();
+ $text = date( 'D M j G:i:s T Y' ) . "\t$host\t$wiki\t$text";
wfErrorLog( $text, $wgDBerrorLog );
}
}
/**
+ * Throws a warning that $function is deprecated
+ *
+ * @param $function String
+ * @param $version String|false: Added in 1.19.
+ * @param $component String|false: Added in 1.19.
+ *
+ * @return null
+ */
+function wfDeprecated( $function, $version = false, $component = false ) {
+ static $functionsWarned = array();
+
+ MWDebug::deprecated( $function, $version, $component );
+
+ if ( !isset( $functionsWarned[$function] ) ) {
+ $functionsWarned[$function] = true;
+
+ if ( $version ) {
+ global $wgDeprecationReleaseLimit;
+
+ if ( $wgDeprecationReleaseLimit && $component === false ) {
+ # Strip -* off the end of $version so that branches can use the
+ # format #.##-branchname to avoid issues if the branch is merged into
+ # a version of MediaWiki later than what it was branched from
+ $comparableVersion = preg_replace( '/-.*$/', '', $version );
+
+ # If the comparableVersion is larger than our release limit then
+ # skip the warning message for the deprecation
+ if ( version_compare( $wgDeprecationReleaseLimit, $comparableVersion, '<' ) ) {
+ return;
+ }
+ }
+
+ $component = $component === false ? 'MediaWiki' : $component;
+ wfWarn( "Use of $function was deprecated in $component $version.", 2 );
+ } else {
+ wfWarn( "Use of $function is deprecated.", 2 );
+ }
+ }
+}
+
+/**
+ * Send a warning either to the debug log or in a PHP error depending on
+ * $wgDevelopmentWarnings
+ *
+ * @param $msg String: message to send
+ * @param $callerOffset Integer: number of items to go back in the backtrace to
+ * find the correct caller (1 = function calling wfWarn, ...)
+ * @param $level Integer: PHP error level; only used when $wgDevelopmentWarnings
+ * is true
+ */
+function wfWarn( $msg, $callerOffset = 1, $level = E_USER_NOTICE ) {
+ global $wgDevelopmentWarnings;
+
+ MWDebug::warning( $msg, $callerOffset + 2 );
+
+ $callers = wfDebugBacktrace();
+ if ( isset( $callers[$callerOffset + 1] ) ) {
+ $callerfunc = $callers[$callerOffset + 1];
+ $callerfile = $callers[$callerOffset];
+ if ( isset( $callerfile['file'] ) && isset( $callerfile['line'] ) ) {
+ $file = $callerfile['file'] . ' at line ' . $callerfile['line'];
+ } else {
+ $file = '(internal function)';
+ }
+ $func = '';
+ if ( isset( $callerfunc['class'] ) ) {
+ $func .= $callerfunc['class'] . '::';
+ }
+ if ( isset( $callerfunc['function'] ) ) {
+ $func .= $callerfunc['function'];
+ }
+ $msg .= " [Called from $func in $file]";
+ }
+
+ if ( $wgDevelopmentWarnings ) {
+ trigger_error( $msg, $level );
+ } else {
+ wfDebug( "$msg\n" );
+ }
+}
+
+/**
* Log to a file without getting "file size exceeded" signals.
*
* Can also log to TCP or UDP with the syntax udp://host:port/prefix. This will
@@ -855,21 +1094,22 @@ function wfErrorLog( $text, $file ) {
$text = preg_replace( '/^/m', $prefix . ' ', $text );
// Limit to 64KB
- if ( strlen( $text ) > 65534 ) {
- $text = substr( $text, 0, 65534 );
+ if ( strlen( $text ) > 65506 ) {
+ $text = substr( $text, 0, 65506 );
}
if ( substr( $text, -1 ) != "\n" ) {
$text .= "\n";
}
- } elseif ( strlen( $text ) > 65535 ) {
- $text = substr( $text, 0, 65535 );
+ } elseif ( strlen( $text ) > 65507 ) {
+ $text = substr( $text, 0, 65507 );
}
$sock = socket_create( $domain, SOCK_DGRAM, SOL_UDP );
if ( !$sock ) {
return;
}
+
socket_sendto( $sock, $text, strlen( $text ), 0, $host, $port );
socket_close( $sock );
} else {
@@ -899,8 +1139,7 @@ function wfLogProfilingData() {
// Get total page request time and only show pages that longer than
// $wgProfileLimit time (default is 0)
- $now = wfTime();
- $elapsed = $now - $wgRequestTime;
+ $elapsed = microtime( true ) - $wgRequestTime;
if ( $elapsed <= $wgProfileLimit ) {
return;
}
@@ -962,6 +1201,9 @@ function wfReadOnly() {
return (bool)$wgReadOnly;
}
+/**
+ * @return bool
+ */
function wfReadOnlyReason() {
global $wgReadOnly;
wfReadOnly();
@@ -977,9 +1219,10 @@ function wfReadOnlyReason() {
* a valid code create a language for that language, if
* it is a string but not a valid code then make a basic
* language object
- * - a boolean: if it's false then use the current users
- * language (as a fallback for the old parameter
- * functionality), or if it is true then use the wikis
+ * - a boolean: if it's false then use the global object for
+ * the current user's language (as a fallback for the old parameter
+ * functionality), or if it is true then use global object
+ * for the wiki's content language.
* @return Language object
*/
function wfGetLangObj( $langcode = false ) {
@@ -1023,6 +1266,7 @@ function wfGetLangObj( $langcode = false ) {
* @return Language
*/
function wfUILang() {
+ wfDeprecated( __METHOD__, '1.18' );
global $wgLang;
return $wgLang;
}
@@ -1249,7 +1493,8 @@ function wfMsgWikiHtml( $key ) {
$args = func_get_args();
array_shift( $args );
return wfMsgReplaceArgs(
- MessageCache::singleton()->parse( wfMsgGetKey( $key ), null, /* can't be set to false */ true )->getText(),
+ MessageCache::singleton()->parse( wfMsgGetKey( $key ), null,
+ /* can't be set to false */ true, /* interface */ true )->getText(),
$args );
}
@@ -1311,13 +1556,18 @@ function wfMsgExt( $key, $options ) {
}
$messageCache = MessageCache::singleton();
- if( in_array( 'parse', $options, true ) ) {
- $string = $messageCache->parse( $string, null, true, !$forContent, $langCodeObj )->getText();
- } elseif ( in_array( 'parseinline', $options, true ) ) {
- $string = $messageCache->parse( $string, null, true, !$forContent, $langCodeObj )->getText();
- $m = array();
- if( preg_match( '/^<p>(.*)\n?<\/p>\n?$/sU', $string, $m ) ) {
- $string = $m[1];
+ $parseInline = in_array( 'parseinline', $options, true );
+ if( in_array( 'parse', $options, true ) || $parseInline ) {
+ $string = $messageCache->parse( $string, null, true, !$forContent, $langCodeObj );
+ if ( $string instanceof ParserOutput ) {
+ $string = $string->getText();
+ }
+
+ if ( $parseInline ) {
+ $m = array();
+ if( preg_match( '/^<p>(.*)\n?<\/p>\n?$/sU', $string, $m ) ) {
+ $string = $m[1];
+ }
}
} elseif ( in_array( 'parsemag', $options, true ) ) {
$string = $messageCache->transform( $string,
@@ -1353,7 +1603,7 @@ function wfEmptyMsg( $key ) {
* Throw a debugging exception. This function previously once exited the process,
* but now throws an exception instead, with similar results.
*
- * @param $msg String: message shown when dieing.
+ * @param $msg String: message shown when dying.
*/
function wfDebugDieBacktrace( $msg = '' ) {
throw new MWException( $msg );
@@ -1397,8 +1647,7 @@ function wfHostname() {
function wfReportTime() {
global $wgRequestTime, $wgShowHostnames;
- $now = wfTime();
- $elapsed = $now - $wgRequestTime;
+ $elapsed = microtime( true ) - $wgRequestTime;
return $wgShowHostnames
? sprintf( '<!-- Served by %s in %01.3f secs. -->', wfHostname(), $elapsed )
@@ -1575,80 +1824,40 @@ function wfShowingResults( $offset, $limit ) {
* @param $query String: optional URL query parameter string
* @param $atend Bool: optional param for specified if this is the last page
* @return String
+ * @deprecated in 1.19; use Language::viewPrevNext() instead
*/
function wfViewPrevNext( $offset, $limit, $link, $query = '', $atend = false ) {
+ wfDeprecated( __METHOD__, '1.19' );
+
global $wgLang;
- $fmtLimit = $wgLang->formatNum( $limit );
- // @todo FIXME: Why on earth this needs one message for the text and another one for tooltip?
- # Get prev/next link display text
- $prev = wfMsgExt( 'prevn', array( 'parsemag', 'escape' ), $fmtLimit );
- $next = wfMsgExt( 'nextn', array( 'parsemag', 'escape' ), $fmtLimit );
- # Get prev/next link title text
- $pTitle = wfMsgExt( 'prevn-title', array( 'parsemag', 'escape' ), $fmtLimit );
- $nTitle = wfMsgExt( 'nextn-title', array( 'parsemag', 'escape' ), $fmtLimit );
- # Fetch the title object
+
+ $query = wfCgiToArray( $query );
+
if( is_object( $link ) ) {
- $title =& $link;
+ $title = $link;
} else {
$title = Title::newFromText( $link );
if( is_null( $title ) ) {
return false;
}
}
- # Make 'previous' link
- if( 0 != $offset ) {
- $po = $offset - $limit;
- $po = max( $po, 0 );
- $q = "limit={$limit}&offset={$po}";
- if( $query != '' ) {
- $q .= '&' . $query;
- }
- $plink = '<a href="' . $title->escapeLocalURL( $q ) . "\" title=\"{$pTitle}\" class=\"mw-prevlink\">{$prev}</a>";
- } else {
- $plink = $prev;
- }
- # Make 'next' link
- $no = $offset + $limit;
- $q = "limit={$limit}&offset={$no}";
- if( $query != '' ) {
- $q .= '&' . $query;
- }
- if( $atend ) {
- $nlink = $next;
- } else {
- $nlink = '<a href="' . $title->escapeLocalURL( $q ) . "\" title=\"{$nTitle}\" class=\"mw-nextlink\">{$next}</a>";
- }
- # Make links to set number of items per page
- $nums = $wgLang->pipeList( array(
- wfNumLink( $offset, 20, $title, $query ),
- wfNumLink( $offset, 50, $title, $query ),
- wfNumLink( $offset, 100, $title, $query ),
- wfNumLink( $offset, 250, $title, $query ),
- wfNumLink( $offset, 500, $title, $query )
- ) );
- return wfMsgHtml( 'viewprevnext', $plink, $nlink, $nums );
+
+ return $wgLang->viewPrevNext( $title, $offset, $limit, $query, $atend );
}
/**
- * Generate links for (20|50|100...) items-per-page links
+ * Make a list item, used by various special pages
*
- * @param $offset String
- * @param $limit Integer
- * @param $title Title
- * @param $query String: optional URL query parameter string
+ * @param $page String Page link
+ * @param $details String Text between brackets
+ * @param $oppositedm Boolean Add the direction mark opposite to your
+ * language, to display text properly
+ * @return String
+ * @deprecated since 1.19; use Language::specialList() instead
*/
-function wfNumLink( $offset, $limit, $title, $query = '' ) {
+function wfSpecialList( $page, $details, $oppositedm = true ) {
global $wgLang;
- if( $query == '' ) {
- $q = '';
- } else {
- $q = $query.'&';
- }
- $q .= "limit={$limit}&offset={$offset}";
- $fmtLimit = $wgLang->formatNum( $limit );
- $lTitle = wfMsgExt( 'shown-title', array( 'parsemag', 'escape' ), $limit );
- $s = '<a href="' . $title->escapeLocalURL( $q ) . "\" title=\"{$lTitle}\" class=\"mw-numlink\">{$fmtLimit}</a>";
- return $s;
+ return $wgLang->specialList( $page, $details, $oppositedm );
}
/**
@@ -1675,7 +1884,7 @@ function wfClientAcceptsGzip( $force = false ) {
$result = false;
return $result;
}
- wfDebug( " accepts gzip\n" );
+ wfDebug( "wfClientAcceptsGzip: client accepts gzip.\n" );
$result = true;
}
}
@@ -1750,6 +1959,8 @@ function wfSetVar( &$dest, $source, $force = false ) {
* @param $dest Int
* @param $bit Int
* @param $state Bool
+ *
+ * @return bool
*/
function wfSetBit( &$dest, $bit, $state = true ) {
$temp = (bool)( $dest & $bit );
@@ -1764,217 +1975,6 @@ function wfSetBit( &$dest, $bit, $state = true ) {
}
/**
- * Windows-compatible version of escapeshellarg()
- * Windows doesn't recognise single-quotes in the shell, but the escapeshellarg()
- * function puts single quotes in regardless of OS.
- *
- * Also fixes the locale problems on Linux in PHP 5.2.6+ (bug backported to
- * earlier distro releases of PHP)
- *
- * @param varargs
- * @return String
- */
-function wfEscapeShellArg( ) {
- wfInitShellLocale();
-
- $args = func_get_args();
- $first = true;
- $retVal = '';
- foreach ( $args as $arg ) {
- if ( !$first ) {
- $retVal .= ' ';
- } else {
- $first = false;
- }
-
- if ( wfIsWindows() ) {
- // Escaping for an MSVC-style command line parser and CMD.EXE
- // Refs:
- // * http://web.archive.org/web/20020708081031/http://mailman.lyra.org/pipermail/scite-interest/2002-March/000436.html
- // * http://technet.microsoft.com/en-us/library/cc723564.aspx
- // * Bug #13518
- // * CR r63214
- // Double the backslashes before any double quotes. Escape the double quotes.
- $tokens = preg_split( '/(\\\\*")/', $arg, -1, PREG_SPLIT_DELIM_CAPTURE );
- $arg = '';
- $iteration = 0;
- foreach ( $tokens as $token ) {
- if ( $iteration % 2 == 1 ) {
- // Delimiter, a double quote preceded by zero or more slashes
- $arg .= str_replace( '\\', '\\\\', substr( $token, 0, -1 ) ) . '\\"';
- } elseif ( $iteration % 4 == 2 ) {
- // ^ in $token will be outside quotes, need to be escaped
- $arg .= str_replace( '^', '^^', $token );
- } else { // $iteration % 4 == 0
- // ^ in $token will appear inside double quotes, so leave as is
- $arg .= $token;
- }
- $iteration++;
- }
- // Double the backslashes before the end of the string, because
- // we will soon add a quote
- $m = array();
- if ( preg_match( '/^(.*?)(\\\\+)$/', $arg, $m ) ) {
- $arg = $m[1] . str_replace( '\\', '\\\\', $m[2] );
- }
-
- // Add surrounding quotes
- $retVal .= '"' . $arg . '"';
- } else {
- $retVal .= escapeshellarg( $arg );
- }
- }
- return $retVal;
-}
-
-/**
- * wfMerge attempts to merge differences between three texts.
- * Returns true for a clean merge and false for failure or a conflict.
- *
- * @param $old String
- * @param $mine String
- * @param $yours String
- * @param $result String
- * @return Bool
- */
-function wfMerge( $old, $mine, $yours, &$result ) {
- global $wgDiff3;
-
- # This check may also protect against code injection in
- # case of broken installations.
- wfSuppressWarnings();
- $haveDiff3 = $wgDiff3 && file_exists( $wgDiff3 );
- wfRestoreWarnings();
-
- if( !$haveDiff3 ) {
- wfDebug( "diff3 not found\n" );
- return false;
- }
-
- # Make temporary files
- $td = wfTempDir();
- $oldtextFile = fopen( $oldtextName = tempnam( $td, 'merge-old-' ), 'w' );
- $mytextFile = fopen( $mytextName = tempnam( $td, 'merge-mine-' ), 'w' );
- $yourtextFile = fopen( $yourtextName = tempnam( $td, 'merge-your-' ), 'w' );
-
- fwrite( $oldtextFile, $old );
- fclose( $oldtextFile );
- fwrite( $mytextFile, $mine );
- fclose( $mytextFile );
- fwrite( $yourtextFile, $yours );
- fclose( $yourtextFile );
-
- # Check for a conflict
- $cmd = $wgDiff3 . ' -a --overlap-only ' .
- wfEscapeShellArg( $mytextName ) . ' ' .
- wfEscapeShellArg( $oldtextName ) . ' ' .
- wfEscapeShellArg( $yourtextName );
- $handle = popen( $cmd, 'r' );
-
- if( fgets( $handle, 1024 ) ) {
- $conflict = true;
- } else {
- $conflict = false;
- }
- pclose( $handle );
-
- # Merge differences
- $cmd = $wgDiff3 . ' -a -e --merge ' .
- wfEscapeShellArg( $mytextName, $oldtextName, $yourtextName );
- $handle = popen( $cmd, 'r' );
- $result = '';
- do {
- $data = fread( $handle, 8192 );
- if ( strlen( $data ) == 0 ) {
- break;
- }
- $result .= $data;
- } while ( true );
- pclose( $handle );
- unlink( $mytextName );
- unlink( $oldtextName );
- unlink( $yourtextName );
-
- if ( $result === '' && $old !== '' && !$conflict ) {
- wfDebug( "Unexpected null result from diff3. Command: $cmd\n" );
- $conflict = true;
- }
- return !$conflict;
-}
-
-/**
- * Returns unified plain-text diff of two texts.
- * Useful for machine processing of diffs.
- *
- * @param $before String: the text before the changes.
- * @param $after String: the text after the changes.
- * @param $params String: command-line options for the diff command.
- * @return String: unified diff of $before and $after
- */
-function wfDiff( $before, $after, $params = '-u' ) {
- if ( $before == $after ) {
- return '';
- }
-
- global $wgDiff;
- wfSuppressWarnings();
- $haveDiff = $wgDiff && file_exists( $wgDiff );
- wfRestoreWarnings();
-
- # This check may also protect against code injection in
- # case of broken installations.
- if( !$haveDiff ) {
- wfDebug( "diff executable not found\n" );
- $diffs = new Diff( explode( "\n", $before ), explode( "\n", $after ) );
- $format = new UnifiedDiffFormatter();
- return $format->format( $diffs );
- }
-
- # Make temporary files
- $td = wfTempDir();
- $oldtextFile = fopen( $oldtextName = tempnam( $td, 'merge-old-' ), 'w' );
- $newtextFile = fopen( $newtextName = tempnam( $td, 'merge-your-' ), 'w' );
-
- fwrite( $oldtextFile, $before );
- fclose( $oldtextFile );
- fwrite( $newtextFile, $after );
- fclose( $newtextFile );
-
- // Get the diff of the two files
- $cmd = "$wgDiff " . $params . ' ' . wfEscapeShellArg( $oldtextName, $newtextName );
-
- $h = popen( $cmd, 'r' );
-
- $diff = '';
-
- do {
- $data = fread( $h, 8192 );
- if ( strlen( $data ) == 0 ) {
- break;
- }
- $diff .= $data;
- } while ( true );
-
- // Clean up
- pclose( $h );
- unlink( $oldtextName );
- unlink( $newtextName );
-
- // Kill the --- and +++ lines. They're not useful.
- $diff_lines = explode( "\n", $diff );
- if ( strpos( $diff_lines[0], '---' ) === 0 ) {
- unset( $diff_lines[0] );
- }
- if ( strpos( $diff_lines[1], '+++' ) === 0 ) {
- unset( $diff_lines[1] );
- }
-
- $diff = implode( "\n", $diff_lines );
-
- return $diff;
-}
-
-/**
* A wrapper around the PHP function var_export().
* Either print it or add it to the regular output ($wgOut).
*
@@ -2005,7 +2005,7 @@ function wfHttpError( $code, $label, $desc ) {
$wgOut->sendCacheControl();
header( 'Content-type: text/html; charset=utf-8' );
- print "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">".
+ print "<!doctype html>" .
'<html><head><title>' .
htmlspecialchars( $label ) .
'</title></head><body><h1>' .
@@ -2161,7 +2161,7 @@ function mimeTypeMatch( $type, $avail ) {
function wfNegotiateType( $cprefs, $sprefs ) {
$combine = array();
- foreach( array_keys($sprefs) as $type ) {
+ foreach( array_keys( $sprefs ) as $type ) {
$parts = explode( '/', $type );
if( $parts[1] != '*' ) {
$ckey = mimeTypeMatch( $type, $cprefs );
@@ -2213,7 +2213,7 @@ function wfSuppressWarnings( $end = false ) {
} else {
if ( !$suppressCount ) {
// E_DEPRECATED is undefined in PHP 5.2
- if( !defined( 'E_DEPRECATED' ) ){
+ if( !defined( 'E_DEPRECATED' ) ) {
define( 'E_DEPRECATED', 8192 );
}
$originalLevel = error_reporting( E_ALL & ~( E_WARNING | E_NOTICE | E_USER_WARNING | E_USER_NOTICE | E_DEPRECATED ) );
@@ -2313,7 +2313,7 @@ function wfTimestamp( $outputtype = TS_UNIX, $ts = 0 ) {
} elseif ( preg_match( '/^-?\d{1,13}$/D', $ts ) ) {
# TS_UNIX
$uts = $ts;
- $strtime = "@$ts"; // Undocumented?
+ $strtime = "@$ts"; // http://php.net/manual/en/datetime.formats.compound.php
} elseif ( preg_match( '/^\d{2}-\d{2}-\d{4} \d{2}:\d{2}:\d{2}.\d{6}$/', $ts ) ) {
# TS_ORACLE // session altered to DD-MM-YYYY HH24:MI:SS.FF6
$strtime = preg_replace( '/(\d\d)\.(\d\d)\.(\d\d)(\.(\d+))?/', "$1:$2:$3",
@@ -2326,7 +2326,7 @@ function wfTimestamp( $outputtype = TS_UNIX, $ts = 0 ) {
# TS_POSTGRES
} elseif ( preg_match( '/^(\d{4})\-(\d\d)\-(\d\d) (\d\d):(\d\d):(\d\d)\.*\d* GMT$/', $ts, $da ) ) {
# TS_POSTGRES
- } elseif (preg_match('/^(\d{4})\-(\d\d)\-(\d\d) (\d\d):(\d\d):(\d\d)\.\d\d\d$/',$ts,$da)) {
+ } elseif (preg_match( '/^(\d{4})\-(\d\d)\-(\d\d) (\d\d):(\d\d):(\d\d)\.\d\d\d$/', $ts, $da ) ) {
# TS_DB2
} elseif ( preg_match( '/^[ \t\r\n]*([A-Z][a-z]{2},[ \t\r\n]*)?' . # Day of week
'\d\d?[ \t\r\n]*[A-Z][a-z]{2}[ \t\r\n]*\d{2}(?:\d{2})?' . # dd Mon yyyy
@@ -2508,8 +2508,12 @@ function wfTempDir() {
function wfMkdirParents( $dir, $mode = null, $caller = null ) {
global $wgDirectoryMode;
+ if ( FileBackend::isStoragePath( $dir ) ) { // sanity
+ throw new MWException( __FUNCTION__ . " given storage path `$dir`.");
+ }
+
if ( !is_null( $caller ) ) {
- wfDebug( "$caller: called wfMkdirParents($dir)" );
+ wfDebug( "$caller: called wfMkdirParents($dir)\n" );
}
if( strval( $dir ) === '' || file_exists( $dir ) ) {
@@ -2586,6 +2590,29 @@ function wfIncrStats( $key, $count = 1 ) {
}
/**
+ * Remove a directory and all its content.
+ * Does not hide error.
+ */
+function wfRecursiveRemoveDir( $dir ) {
+ wfDebug( __FUNCTION__ . "( $dir )\n" );
+ // taken from http://de3.php.net/manual/en/function.rmdir.php#98622
+ if ( is_dir( $dir ) ) {
+ $objects = scandir( $dir );
+ foreach ( $objects as $object ) {
+ if ( $object != "." && $object != ".." ) {
+ if ( filetype( $dir . '/' . $object ) == "dir" ) {
+ wfRecursiveRemoveDir( $dir . '/' . $object );
+ } else {
+ unlink( $dir . '/' . $object );
+ }
+ }
+ }
+ reset( $objects );
+ rmdir( $dir );
+ }
+}
+
+/**
* @param $nr Mixed: the number to format
* @param $acc Integer: the number of digits after the decimal point, default 2
* @param $round Boolean: whether or not to round the value, default true
@@ -2612,23 +2639,6 @@ function in_string( $needle, $str, $insensitive = false ) {
}
/**
- * Make a list item, used by various special pages
- *
- * @param $page String Page link
- * @param $details String Text between brackets
- * @param $oppositedm Boolean Add the direction mark opposite to your
- * language, to display text properly
- * @return String
- */
-function wfSpecialList( $page, $details, $oppositedm = true ) {
- global $wgLang;
- $dirmark = ( $oppositedm ? $wgLang->getDirMark( true ) : '' ) .
- $wgLang->getDirMark();
- $details = $details ? $dirmark . " ($details)" : '';
- return $page . $details;
-}
-
-/**
* Safety wrapper around ini_get() for boolean settings.
* The values returned from ini_get() are pre-normalized for settings
* set via php.ini or php_flag/php_admin_flag... but *not*
@@ -2696,6 +2706,70 @@ function wfDl( $extension, $fileName = null ) {
}
/**
+ * Windows-compatible version of escapeshellarg()
+ * Windows doesn't recognise single-quotes in the shell, but the escapeshellarg()
+ * function puts single quotes in regardless of OS.
+ *
+ * Also fixes the locale problems on Linux in PHP 5.2.6+ (bug backported to
+ * earlier distro releases of PHP)
+ *
+ * @param varargs
+ * @return String
+ */
+function wfEscapeShellArg( ) {
+ wfInitShellLocale();
+
+ $args = func_get_args();
+ $first = true;
+ $retVal = '';
+ foreach ( $args as $arg ) {
+ if ( !$first ) {
+ $retVal .= ' ';
+ } else {
+ $first = false;
+ }
+
+ if ( wfIsWindows() ) {
+ // Escaping for an MSVC-style command line parser and CMD.EXE
+ // Refs:
+ // * http://web.archive.org/web/20020708081031/http://mailman.lyra.org/pipermail/scite-interest/2002-March/000436.html
+ // * http://technet.microsoft.com/en-us/library/cc723564.aspx
+ // * Bug #13518
+ // * CR r63214
+ // Double the backslashes before any double quotes. Escape the double quotes.
+ $tokens = preg_split( '/(\\\\*")/', $arg, -1, PREG_SPLIT_DELIM_CAPTURE );
+ $arg = '';
+ $iteration = 0;
+ foreach ( $tokens as $token ) {
+ if ( $iteration % 2 == 1 ) {
+ // Delimiter, a double quote preceded by zero or more slashes
+ $arg .= str_replace( '\\', '\\\\', substr( $token, 0, -1 ) ) . '\\"';
+ } elseif ( $iteration % 4 == 2 ) {
+ // ^ in $token will be outside quotes, need to be escaped
+ $arg .= str_replace( '^', '^^', $token );
+ } else { // $iteration % 4 == 0
+ // ^ in $token will appear inside double quotes, so leave as is
+ $arg .= $token;
+ }
+ $iteration++;
+ }
+ // Double the backslashes before the end of the string, because
+ // we will soon add a quote
+ $m = array();
+ if ( preg_match( '/^(.*?)(\\\\+)$/', $arg, $m ) ) {
+ $arg = $m[1] . str_replace( '\\', '\\\\', $m[2] );
+ }
+
+ // Add surrounding quotes
+ $retVal .= '"' . $arg . '"';
+ } else {
+ $retVal .= escapeshellarg( $arg );
+ }
+ }
+ return $retVal;
+}
+
+/**
* Execute a shell command, with time and memory limits mirrored from the PHP
* configuration if supported.
* @param $cmd String Command line, properly escaped for shell.
@@ -2805,6 +2879,178 @@ function wfInitShellLocale() {
}
/**
+ * Generate a shell-escaped command line string to run a maintenance script.
+ * Note that $parameters should be a flat array and an option with an argument
+ * should consist of two consecutive items in the array (do not use "--option value").
+ * @param $script string MediaWiki maintenance script path
+ * @param $parameters Array Arguments and options to the script
+ * @param $options Array Associative array of options:
+ * 'php': The path to the php executable
+ * 'wrapper': Path to a PHP wrapper to handle the maintenance script
+ * @return Array
+ */
+function wfShellMaintenanceCmd( $script, array $parameters = array(), array $options = array() ) {
+ global $wgPhpCli;
+ // Give site config file a chance to run the script in a wrapper.
+ // The caller may likely want to call wfBasename() on $script.
+ wfRunHooks( 'wfShellMaintenanceCmd', array( &$script, &$parameters, &$options ) );
+ $cmd = isset( $options['php'] ) ? array( $options['php'] ) : array( $wgPhpCli );
+ if ( isset( $options['wrapper'] ) ) {
+ $cmd[] = $options['wrapper'];
+ }
+ $cmd[] = $script;
+ // Escape each parameter for shell
+ return implode( " ", array_map( 'wfEscapeShellArg', array_merge( $cmd, $parameters ) ) );
+}
+
+/**
+ * wfMerge attempts to merge differences between three texts.
+ * Returns true for a clean merge and false for failure or a conflict.
+ *
+ * @param $old String
+ * @param $mine String
+ * @param $yours String
+ * @param $result String
+ * @return Bool
+ */
+function wfMerge( $old, $mine, $yours, &$result ) {
+ global $wgDiff3;
+
+ # This check may also protect against code injection in
+ # case of broken installations.
+ wfSuppressWarnings();
+ $haveDiff3 = $wgDiff3 && file_exists( $wgDiff3 );
+ wfRestoreWarnings();
+
+ if( !$haveDiff3 ) {
+ wfDebug( "diff3 not found\n" );
+ return false;
+ }
+
+ # Make temporary files
+ $td = wfTempDir();
+ $oldtextFile = fopen( $oldtextName = tempnam( $td, 'merge-old-' ), 'w' );
+ $mytextFile = fopen( $mytextName = tempnam( $td, 'merge-mine-' ), 'w' );
+ $yourtextFile = fopen( $yourtextName = tempnam( $td, 'merge-your-' ), 'w' );
+
+ fwrite( $oldtextFile, $old );
+ fclose( $oldtextFile );
+ fwrite( $mytextFile, $mine );
+ fclose( $mytextFile );
+ fwrite( $yourtextFile, $yours );
+ fclose( $yourtextFile );
+
+ # Check for a conflict
+ $cmd = $wgDiff3 . ' -a --overlap-only ' .
+ wfEscapeShellArg( $mytextName ) . ' ' .
+ wfEscapeShellArg( $oldtextName ) . ' ' .
+ wfEscapeShellArg( $yourtextName );
+ $handle = popen( $cmd, 'r' );
+
+ if( fgets( $handle, 1024 ) ) {
+ $conflict = true;
+ } else {
+ $conflict = false;
+ }
+ pclose( $handle );
+
+ # Merge differences
+ $cmd = $wgDiff3 . ' -a -e --merge ' .
+ wfEscapeShellArg( $mytextName, $oldtextName, $yourtextName );
+ $handle = popen( $cmd, 'r' );
+ $result = '';
+ do {
+ $data = fread( $handle, 8192 );
+ if ( strlen( $data ) == 0 ) {
+ break;
+ }
+ $result .= $data;
+ } while ( true );
+ pclose( $handle );
+ unlink( $mytextName );
+ unlink( $oldtextName );
+ unlink( $yourtextName );
+
+ if ( $result === '' && $old !== '' && !$conflict ) {
+ wfDebug( "Unexpected null result from diff3. Command: $cmd\n" );
+ $conflict = true;
+ }
+ return !$conflict;
+}
+
+/**
+ * Returns unified plain-text diff of two texts.
+ * Useful for machine processing of diffs.
+ *
+ * @param $before String: the text before the changes.
+ * @param $after String: the text after the changes.
+ * @param $params String: command-line options for the diff command.
+ * @return String: unified diff of $before and $after
+ */
+function wfDiff( $before, $after, $params = '-u' ) {
+ if ( $before == $after ) {
+ return '';
+ }
+
+ global $wgDiff;
+ wfSuppressWarnings();
+ $haveDiff = $wgDiff && file_exists( $wgDiff );
+ wfRestoreWarnings();
+
+ # This check may also protect against code injection in
+ # case of broken installations.
+ if( !$haveDiff ) {
+ wfDebug( "diff executable not found\n" );
+ $diffs = new Diff( explode( "\n", $before ), explode( "\n", $after ) );
+ $format = new UnifiedDiffFormatter();
+ return $format->format( $diffs );
+ }
+
+ # Make temporary files
+ $td = wfTempDir();
+ $oldtextFile = fopen( $oldtextName = tempnam( $td, 'merge-old-' ), 'w' );
+ $newtextFile = fopen( $newtextName = tempnam( $td, 'merge-your-' ), 'w' );
+
+ fwrite( $oldtextFile, $before );
+ fclose( $oldtextFile );
+ fwrite( $newtextFile, $after );
+ fclose( $newtextFile );
+
+ // Get the diff of the two files
+ $cmd = "$wgDiff " . $params . ' ' . wfEscapeShellArg( $oldtextName, $newtextName );
+
+ $h = popen( $cmd, 'r' );
+
+ $diff = '';
+
+ do {
+ $data = fread( $h, 8192 );
+ if ( strlen( $data ) == 0 ) {
+ break;
+ }
+ $diff .= $data;
+ } while ( true );
+
+ // Clean up
+ pclose( $h );
+ unlink( $oldtextName );
+ unlink( $newtextName );
+
+ // Kill the --- and +++ lines. They're not useful.
+ $diff_lines = explode( "\n", $diff );
+ if ( strpos( $diff_lines[0], '---' ) === 0 ) {
+ unset( $diff_lines[0] );
+ }
+ if ( strpos( $diff_lines[1], '+++' ) === 0 ) {
+ unset( $diff_lines[1] );
+ }
+
+ $diff = implode( "\n", $diff_lines );
+
+ return $diff;
+}
+
+/**
* This function works like "use VERSION" in Perl, the program will die with a
* backtrace if the current version of PHP is less than the version provided
*
@@ -2920,35 +3166,13 @@ function wfRelativePath( $path, $from ) {
/**
* Do any deferred updates and clear the list
*
- * @param $commit String: set to 'commit' to commit after every update to
- * prevent lock contention
+ * @deprecated since 1.19
+ * @see DeferredUpdates::doUpdate()
+ * @param $commit string
*/
function wfDoUpdates( $commit = '' ) {
- global $wgDeferredUpdateList;
-
- wfProfileIn( __METHOD__ );
-
- // No need to get master connections in case of empty updates array
- if ( !count( $wgDeferredUpdateList ) ) {
- wfProfileOut( __METHOD__ );
- return;
- }
-
- $doCommit = $commit == 'commit';
- if ( $doCommit ) {
- $dbw = wfGetDB( DB_MASTER );
- }
-
- foreach ( $wgDeferredUpdateList as $update ) {
- $update->doUpdate();
-
- if ( $doCommit && $dbw->trxLevel() ) {
- $dbw->commit();
- }
- }
-
- $wgDeferredUpdateList = array();
- wfProfileOut( __METHOD__ );
+ wfDeprecated( __METHOD__, '1.19' );
+ DeferredUpdates::doUpdates( $commit );
}
/**
@@ -3043,13 +3267,17 @@ function wfBaseConvert( $input, $sourceBase, $destBase, $pad = 1, $lowercase = t
*
* @param $name String
* @param $p Array: parameters
+ * @return object
* @deprecated since 1.18, warnings in 1.18, removal in 1.20
*/
function wfCreateObject( $name, $p ) {
- wfDeprecated( __FUNCTION__ );
+ wfDeprecated( __FUNCTION__, '1.18' );
return MWFunction::newObj( $name, $p );
}
+/**
+ * @return bool
+ */
function wfHttpOnlySafe() {
global $wgHttpOnlyBlacklist;
@@ -3164,8 +3392,10 @@ function wfGetPrecompiledData( $name ) {
* @return String
*/
function wfMemcKey( /*... */ ) {
+ global $wgCachePrefix;
+ $prefix = $wgCachePrefix === false ? wfWikiID() : $wgCachePrefix;
$args = func_get_args();
- $key = wfWikiID() . ':' . implode( ':', $args );
+ $key = $prefix . ':' . implode( ':', $args );
$key = str_replace( ' ', '_', $key );
return $key;
}
@@ -3207,7 +3437,8 @@ function wfWikiID() {
* Split a wiki ID into DB name and table prefix
*
* @param $wiki String
- * @param $bits String
+ *
+ * @return array
*/
function wfSplitWikiID( $wiki ) {
$bits = explode( '-', $wiki, 2 );
@@ -3290,14 +3521,23 @@ function wfFindFile( $title, $options = array() ) {
* Get an object referring to a locally registered file.
* Returns a valid placeholder object if the file does not exist.
*
- * @param $title Title or String
- * @return File, or null if passed an invalid Title
+ * @param $title Title|String
+ * @return File|null A File, or null if passed an invalid Title
*/
function wfLocalFile( $title ) {
return RepoGroup::singleton()->getLocalRepo()->newFile( $title );
}
/**
+ * Stream a file to the browser. Back-compat alias for StreamFile::stream()
+ * @deprecated since 1.19
+ */
+function wfStreamFile( $fname, $headers = array() ) {
+ wfDeprecated( __FUNCTION__, '1.19' );
+ StreamFile::stream( $fname, $headers );
+}
+
+/**
* Should low-performance queries be disabled?
*
* @return Boolean
@@ -3364,7 +3604,7 @@ function wfBoolToStr( $value ) {
* @codeCoverageIgnore
*/
function wfLoadExtensionMessages() {
- wfDeprecated( __FUNCTION__ );
+ wfDeprecated( __FUNCTION__, '1.16' );
}
/**
@@ -3379,59 +3619,6 @@ function wfGetNull() {
}
/**
- * Throws a warning that $function is deprecated
- *
- * @param $function String
- * @return null
- */
-function wfDeprecated( $function ) {
- static $functionsWarned = array();
- if ( !isset( $functionsWarned[$function] ) ) {
- $functionsWarned[$function] = true;
- wfWarn( "Use of $function is deprecated.", 2 );
- }
-}
-
-/**
- * Send a warning either to the debug log or in a PHP error depending on
- * $wgDevelopmentWarnings
- *
- * @param $msg String: message to send
- * @param $callerOffset Integer: number of items to go back in the backtrace to
- * find the correct caller (1 = function calling wfWarn, ...)
- * @param $level Integer: PHP error level; only used when $wgDevelopmentWarnings
- * is true
- */
-function wfWarn( $msg, $callerOffset = 1, $level = E_USER_NOTICE ) {
- global $wgDevelopmentWarnings;
-
- $callers = wfDebugBacktrace();
- if ( isset( $callers[$callerOffset + 1] ) ) {
- $callerfunc = $callers[$callerOffset + 1];
- $callerfile = $callers[$callerOffset];
- if ( isset( $callerfile['file'] ) && isset( $callerfile['line'] ) ) {
- $file = $callerfile['file'] . ' at line ' . $callerfile['line'];
- } else {
- $file = '(internal function)';
- }
- $func = '';
- if ( isset( $callerfunc['class'] ) ) {
- $func .= $callerfunc['class'] . '::';
- }
- if ( isset( $callerfunc['function'] ) ) {
- $func .= $callerfunc['function'];
- }
- $msg .= " [Called from $func in $file]";
- }
-
- if ( $wgDevelopmentWarnings ) {
- trigger_error( $msg, $level );
- } else {
- wfDebug( "$msg\n" );
- }
-}
-
-/**
* Modern version of wfWaitForSlaves(). Instead of looking at replication lag
* and waiting for it to go down, this waits for the slaves to catch up to the
* master position. Use this when updating very large numbers of rows, as
@@ -3440,7 +3627,6 @@ function wfWarn( $msg, $callerOffset = 1, $level = E_USER_NOTICE ) {
*
* @param $maxLag Integer (deprecated)
* @param $wiki mixed Wiki identifier accepted by wfGetLB
- * @return null
*/
function wfWaitForSlaves( $maxLag = false, $wiki = false ) {
$lb = wfGetLB( $wiki );
@@ -3458,7 +3644,7 @@ function wfWaitForSlaves( $maxLag = false, $wiki = false ) {
* @deprecated since 1.18, warnings in 1.18, remove in 1.20
*/
function wfOut( $s ) {
- wfDeprecated( __METHOD__ );
+ wfDeprecated( __FUNCTION__, '1.18' );
global $wgCommandLineMode;
if ( $wgCommandLineMode ) {
echo $s;
@@ -3472,6 +3658,7 @@ function wfOut( $s ) {
* Count down from $n to zero on the terminal, with a one-second pause
* between showing each number. For use in command-line scripts.
* @codeCoverageIgnore
+ * @param $n int
*/
function wfCountDown( $n ) {
for ( $i = $n; $i >= 0; $i-- ) {
@@ -3580,7 +3767,7 @@ function wfShorthandToInteger( $string = '' ) {
* See unit test for examples.
*
* @param $code String: The language code.
- * @return $langCode String: The language code which complying with BCP 47 standards.
+ * @return String: The language code which complying with BCP 47 standards.
*/
function wfBCP47( $code ) {
$codeSegment = explode( '-', $code );
@@ -3588,7 +3775,7 @@ function wfBCP47( $code ) {
foreach ( $codeSegment as $segNo => $seg ) {
if ( count( $codeSegment ) > 0 ) {
// when previous segment is x, it is a private segment and should be lc
- if( $segNo > 0 && strtolower( $codeSegment[($segNo - 1)] ) == 'x') {
+ if( $segNo > 0 && strtolower( $codeSegment[( $segNo - 1 )] ) == 'x' ) {
$codeBCP[$segNo] = strtolower( $seg );
// ISO 3166 country code
} elseif ( ( strlen( $seg ) == 2 ) && ( $segNo > 0 ) ) {
@@ -3654,7 +3841,7 @@ function wfGetParserCacheStorage() {
*
* @param $event String: event name
* @param $args Array: parameters passed to hook functions
- * @return Boolean
+ * @return Boolean True if no handler aborted the hook
*/
function wfRunHooks( $event, $args = array() ) {
return Hooks::run( $event, $args );