X-Git-Url: https://git.cyclocoop.org/%27.WWW_URL.%27admin/?a=blobdiff_plain;f=includes%2FGlobalFunctions.php;h=d636b4439739bbe210b8b2cdfe08aeff496dcae3;hb=c510db2665c0f580d636f4c3aab72ac20722262b;hp=4a714d19f33e84c0e21a87ba493a0fbec7dba7cf;hpb=8843ebacb1cb0d3a560ddf9a9ff8ec82ae96243d;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/GlobalFunctions.php b/includes/GlobalFunctions.php index 4a714d19f3..d636b44397 100644 --- a/includes/GlobalFunctions.php +++ b/includes/GlobalFunctions.php @@ -214,7 +214,7 @@ function wfArrayDiff2_cmp( $a, $b ) { } else { reset( $a ); reset( $b ); - while( ( list( $keyA, $valueA ) = each( $a ) ) && ( list( $keyB, $valueB ) = each( $b ) ) ) { + while( ( list( , $valueA ) = each( $a ) ) && ( list( , $valueB ) = each( $b ) ) ) { $cmp = strcmp( $valueA, $valueB ); if ( $cmp !== 0 ) { return $cmp; @@ -224,15 +224,6 @@ function wfArrayDiff2_cmp( $a, $b ) { } } -/** - * Seed Mersenne Twister - * No-op for compatibility; only necessary in PHP < 4.2.0 - * @deprecated. Remove in 1.18 - */ -function wfSeedRandom() { - wfDeprecated(__FUNCTION__); -} - /** * Get a random decimal value between 0 and 1, in a way * not likely to give duplicate values for any realistic @@ -306,7 +297,6 @@ function wfUrlencode( $s ) { function wfDebug( $text, $logonly = false ) { global $wgOut, $wgDebugLogFile, $wgDebugComments, $wgProfileOnly, $wgDebugRawPage; global $wgDebugLogPrefix, $wgShowDebug; - static $recursion = 0; static $cache = array(); // Cache of unoutputted messages $text = wfDebugTimer() . $text; @@ -319,21 +309,11 @@ function wfDebug( $text, $logonly = false ) { if ( ( $wgDebugComments || $wgShowDebug ) && !$logonly ) { $cache[] = $text; - if ( !isset( $wgOut ) ) { - return; - } - if ( !StubObject::isRealObject( $wgOut ) ) { - if ( $recursion ) { - return; - } - $recursion++; - $wgOut->_unstub(); - $recursion--; + if ( isset( $wgOut ) && StubObject::isRealObject( $wgOut ) ) { + // add the message and any cached messages to the output + array_map( array( $wgOut, 'debug' ), $cache ); + $cache = array(); } - - // add the message and possible cached ones to the output - array_map( array( $wgOut, 'debug' ), $cache ); - $cache = array(); } if ( $wgDebugLogFile != '' && !$wgProfileOnly ) { # Strip unprintables; they can switch terminal modes when binary data @@ -615,6 +595,26 @@ function wfMessage( $key /*...*/) { return new Message( $key, $params ); } +/** + * This function accepts multiple message keys and returns a message instance + * for the first message which is non-empty. If all messages are empty then an + * instance of the first message key is returned. + * Varargs: message keys + * @return \type{Message} + * @since 1.18 + */ +function wfMessageFallback( /*...*/ ) { + $keys = func_get_args(); + $first = $keys[0]; + foreach ( $keys as $key ) { + if ( wfEmptyMsg( $key ) ) { + continue; + } + return wfMessage( $key ); + } + return wfMessage( $first ); +} + /** * Get a message from anywhere, for the current user language. * @@ -854,7 +854,7 @@ function wfMsgWikiHtml( $key ) { * content: fetch message for content language instead of interface * Also can accept a single associative argument, of the form 'language' => 'xx': * language: Language object or language code to fetch message for - * (overriden by content), its behaviour with parser, parseinline + * (overriden by content), its behaviour with parse, parseinline * and parsemag is undefined. * Behavior for conflicting options (e.g., parse+parseinline) is undefined. */ @@ -1287,37 +1287,15 @@ function wfCheckLimits( $deflimit = 50, $optionname = 'rclimit' ) { */ function wfEscapeWikiText( $text ) { $text = str_replace( - array( '[', '|', ']', '\'', 'ISBN ', 'RFC ', '://', "\n=", '{{' ), # }} - array( '[', '|', ']', ''', 'ISBN ', 'RFC ', '://', "\n=", '{{' ), + array( '[', '|', ']', '\'', 'ISBN ', + 'RFC ', '://', "\n=", '{{', '}}' ), + array( '[', '|', ']', ''', 'ISBN ', + 'RFC ', '://', "\n=", '{{', '}}' ), htmlspecialchars( $text ) ); return $text; } -/** - * @todo document - */ -function wfQuotedPrintable( $string, $charset = '' ) { - # Probably incomplete; see RFC 2045 - if( empty( $charset ) ) { - global $wgInputEncoding; - $charset = $wgInputEncoding; - } - $charset = strtoupper( $charset ); - $charset = str_replace( 'ISO-8859', 'ISO8859', $charset ); // ? - - $illegal = '\x00-\x08\x0b\x0c\x0e-\x1f\x7f-\xff='; - $replace = $illegal . '\t ?_'; - if( !preg_match( "/[$illegal]/", $string ) ) { - return $string; - } - $out = "=?$charset?Q?"; - $out .= preg_replace( "/([$replace])/e", 'sprintf("=%02X",ord("$1"))', $string ); - $out .= '?='; - return $out; -} - - /** * @todo document * @return float @@ -1329,10 +1307,11 @@ function wfTime() { /** * Sets dest to source and returns the original value of dest * If source is NULL, it just returns the value, it doesn't set the variable + * If force is true, it will set the value even if source is NULL */ -function wfSetVar( &$dest, $source ) { +function wfSetVar( &$dest, $source, $force = false ) { $temp = $dest; - if ( !is_null( $source ) ) { + if ( !is_null( $source ) || $force ) { $dest = $source; } return $temp; @@ -1484,8 +1463,12 @@ function wfEscapeShellArg( ) { } if ( wfIsWindows() ) { - // Escaping for an MSVC-style command line parser - // Ref: http://mailman.lyra.org/pipermail/scite-interest/2002-March/000436.html + // 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 = ''; @@ -1979,13 +1962,16 @@ define( 'TS_ISO_8601_BASIC', 9 ); * function will autodetect which format is supplied and act * accordingly. * @param $ts Mixed: the timestamp to convert or 0 for the current timestamp - * @return String: in the format specified in $outputtype + * @return Mixed: String / false The same date in the format specified in $outputtype or false */ function wfTimestamp( $outputtype = TS_UNIX, $ts = 0 ) { $uts = 0; $da = array(); - if ( $ts === 0 ) { + $strtime = ''; + + if ( !$ts ) { // We want to catch 0, '', null... but not date strings starting with a letter. $uts = time(); + $strtime = "@$uts"; } elseif ( preg_match( '/^(\d{4})\-(\d\d)\-(\d\d) (\d\d):(\d\d):(\d\d)$/D', $ts, $da ) ) { # TS_DB } elseif ( preg_match( '/^(\d{4}):(\d\d):(\d\d) (\d\d):(\d\d):(\d\d)$/D', $ts, $da ) ) { @@ -1995,10 +1981,11 @@ function wfTimestamp( $outputtype = TS_UNIX, $ts = 0 ) { } elseif ( preg_match( '/^-?\d{1,13}$/D', $ts ) ) { # TS_UNIX $uts = $ts; + $strtime = "@$ts"; // Undocumented? } 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 - $uts = strtotime( preg_replace( '/(\d\d)\.(\d\d)\.(\d\d)(\.(\d+))?/', "$1:$2:$3", - str_replace( '+00:00', 'UTC', $ts ) ) ); + $strtime = preg_replace( '/(\d\d)\.(\d\d)\.(\d\d)(\.(\d+))?/', "$1:$2:$3", + str_replace( '+00:00', 'UTC', $ts ) ); } elseif ( preg_match( '/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.*\d*)?Z$/', $ts, $da ) ) { # TS_ISO_8601 } elseif ( preg_match( '/^(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})(?:\.*\d*)?Z$/', $ts, $da ) ) { @@ -2009,22 +1996,27 @@ 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\d\d$/',$ts,$da)) { # TS_DB2 - } elseif ( preg_match( '/^[A-Z][a-z]{2}, \d\d [A-Z][a-z]{2} \d{4} \d\d:\d\d:\d\d/', $ts ) ) { - # TS_RFC2822 - $uts = strtotime( $ts ); + } 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 + '[ \t\r\n]*\d\d[ \t\r\n]*:[ \t\r\n]*\d\d[ \t\r\n]*:[ \t\r\n]*\d\d/S', $ts ) ) { # hh:mm:ss + # TS_RFC2822, accepting a trailing comment. See http://www.squid-cache.org/mail-archive/squid-users/200307/0122.html / r77171 + # The regex is a superset of rfc2822 for readability + $strtime = strtok( $ts, ';' ); + } elseif ( preg_match( '/^[A-Z][a-z]{5,8}, \d\d-[A-Z][a-z]{2}-\d{2} \d\d:\d\d:\d\d/', $ts ) ) { + # TS_RFC850 + $strtime = $ts; + } elseif ( preg_match( '/^[A-Z][a-z]{2} [A-Z][a-z]{2} +\d{1,2} \d\d:\d\d:\d\d \d{4}/', $ts ) ) { + # asctime + $strtime = $ts; } else { - # Bogus value; fall back to the epoch... - wfDebug("wfTimestamp() fed bogus time value: $outputtype; $ts\n"); - $uts = 0; - } + # Bogus value... + wfDebug("wfTimestamp() fed bogus time value: TYPE=$outputtype; VALUE=$ts\n"); - if (count( $da ) ) { - // Warning! gmmktime() acts oddly if the month or day is set to 0 - // We may want to handle that explicitly at some point - $uts = gmmktime( (int)$da[4], (int)$da[5], (int)$da[6], - (int)$da[2], (int)$da[3], (int)$da[1] ); + return false; } + + static $formats = array( TS_UNIX => 'U', TS_MW => 'YmdHis', @@ -2042,11 +2034,45 @@ function wfTimestamp( $outputtype = TS_UNIX, $ts = 0 ) { throw new MWException( 'wfTimestamp() called with illegal output type.' ); } - if ( TS_UNIX == $outputtype ) { - return $uts; - } + if ( function_exists( "date_create" ) ) { + if ( count( $da ) ) { + $ds = sprintf("%04d-%02d-%02dT%02d:%02d:%02d.00+00:00", + (int)$da[1], (int)$da[2], (int)$da[3], + (int)$da[4], (int)$da[5], (int)$da[6]); + + $d = date_create( $ds, new DateTimeZone( 'GMT' ) ); + } elseif ( $strtime ) { + $d = date_create( $strtime, new DateTimeZone( 'GMT' ) ); + } else { + return false; + } + + if ( !$d ) { + wfDebug("wfTimestamp() fed bogus time value: $outputtype; $ts\n"); + return false; + } + + $output = $d->format( $formats[$outputtype] ); + } else { + if ( count( $da ) ) { + // Warning! gmmktime() acts oddly if the month or day is set to 0 + // We may want to handle that explicitly at some point + $uts = gmmktime( (int)$da[4], (int)$da[5], (int)$da[6], + (int)$da[2], (int)$da[3], (int)$da[1] ); + } elseif ( $strtime ) { + $uts = strtotime( $strtime ); + } - $output = gmdate( $formats[$outputtype], $uts ); + if ( $uts === false ) { + wfDebug("wfTimestamp() can't parse the timestamp (non 32-bit time? Update php): $outputtype; $ts\n"); + return false; + } + + if ( TS_UNIX == $outputtype ) { + return $uts; + } + $output = gmdate( $formats[$outputtype], $uts ); + } if ( ( $outputtype == TS_RFC2822 ) || ( $outputtype == TS_POSTGRES ) ) { $output .= ' GMT'; @@ -2195,7 +2221,7 @@ function wfGetSiteNotice() { /** * BC wrapper for MimeMagic::singleton() - * @deprecated No longer needed as of 1.17 (r68836). + * @deprecated No longer needed as of 1.17 (r68836). Remove in 1.19. */ function &wfGetMimeMagic() { wfDeprecated( __FUNCTION__ ); @@ -2465,7 +2491,7 @@ function wfDl( $extension ) { * @param $cmd String Command line, properly escaped for shell. * @param &$retval optional, will receive the program's exit code. * (non-zero is usually failure) - * @param $environ Array optional environment variables which should be + * @param $environ Array optional environment variables which should be * added to the executed command environment. * @return collected stdout as a string (trailing newlines stripped) */ @@ -2500,22 +2526,22 @@ function wfShellExec( $cmd, &$retval = null, $environ = array() ) { $envcmd = ''; foreach( $environ as $k => $v ) { if ( wfIsWindows() ) { - /* Surrounding a set in quotes (method used by wfEscapeShellArg) makes the quotes themselves - * appear in the environment variable, so we must use carat escaping as documented in - * http://technet.microsoft.com/en-us/library/cc723564.aspx - * Note however that the quote isn't listed there, but is needed, and the parentheses + /* Surrounding a set in quotes (method used by wfEscapeShellArg) makes the quotes themselves + * appear in the environment variable, so we must use carat escaping as documented in + * http://technet.microsoft.com/en-us/library/cc723564.aspx + * Note however that the quote isn't listed there, but is needed, and the parentheses * are listed there but doesn't appear to need it. */ - $envcmd .= "set $k=" . preg_replace( '/([&|()<>^"])/', '^\\1', $v ) . ' && '; + $envcmd .= "set $k=" . preg_replace( '/([&|()<>^"])/', '^\\1', $v ) . '&& '; } else { - /* Assume this is a POSIX shell, thus required to accept variable assignments before the command + /* Assume this is a POSIX shell, thus required to accept variable assignments before the command * http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_09_01 */ $envcmd .= "$k=" . escapeshellarg( $v ) . ' '; } } $cmd = $envcmd . $cmd; - + if ( wfIsWindows() ) { if ( version_compare( PHP_VERSION, '5.3.0', '<' ) && /* Fixed in 5.3.0 :) */ ( version_compare( PHP_VERSION, '5.2.1', '>=' ) || php_uname( 's' ) == 'Windows NT' ) ) @@ -2814,18 +2840,36 @@ function wfMakeUrlIndex( $url ) { /** * Do any deferred updates and clear the list - * TODO: This could be in Wiki.php if that class made any sense at all + * + * @param $commit String: set to 'commit' to commit after every update to + * prevent lock contention */ -function wfDoUpdates() { - global $wgPostCommitUpdateList, $wgDeferredUpdateList; - foreach ( $wgDeferredUpdateList as $update ) { - $update->doUpdate(); +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; } - foreach ( $wgPostCommitUpdateList as $update ) { + + $doCommit = $commit == 'commit'; + if ( $doCommit ) { + $dbw = wfGetDB( DB_MASTER ); + } + + foreach ( $wgDeferredUpdateList as $update ) { $update->doUpdate(); + + if ( $doCommit && $dbw->trxLevel() ) { + $dbw->commit(); + } } + $wgDeferredUpdateList = array(); - $wgPostCommitUpdateList = array(); + wfProfileOut( __METHOD__ ); } /** @@ -3130,6 +3174,7 @@ function wfGetLB( $wiki = false ) { /** * Get the load balancer factory object + * @return LBFactory */ function &wfGetLBFactory() { return LBFactory::singleton(); @@ -3161,7 +3206,7 @@ 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 Either a string or Title object + * @param $title Title or String * @return File, or null if passed an invalid Title */ function wfLocalFile( $title ) { @@ -3229,9 +3274,10 @@ function wfBoolToStr( $value ) { /** * Load an extension messages file - * @deprecated in 1.16 (warnings in 1.18, removed in ?) + * @deprecated in 1.16, warnings in 1.18, remove in 1.20 */ function wfLoadExtensionMessages( $extensionName, $langcode = false ) { + wfDeprecated( __FUNCTION__ ); } /** @@ -3350,8 +3396,8 @@ function wfWaitForSlaves( $maxLag, $wiki = false ) { } /** - * Output some plain text in command-line mode or in the installer (updaters.inc). - * Do not use it in any other context, its behaviour is subject to change. + * Used to be used for outputting text in the installer/updater + * @deprecated Warnings in 1.19, removal in 1.20 */ function wfOut( $s ) { global $wgCommandLineMode; @@ -3537,23 +3583,3 @@ function wfArrayMap( $function, $input ) { } return $ret; } - -/** - * Returns the PackageRepository object for interaction with the package repository. - * - * TODO: Make the repository type also configurable. - * - * @since 1.17 - * - * @return PackageRepository - */ -function wfGetRepository() { - global $wgRepositoryApiLocation; - static $repository = false; - - if ( $repository === false ) { - $repository = new DistributionRepository( $wgRepositoryApiLocation ); - } - - return $repository; -}