X-Git-Url: http://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FGlobalFunctions.php;h=5b4d8bc869a29ae92b194a9ece0d38433b6cdb5a;hb=44d31b681fc83aecc819a78662a5d75a4a8655b7;hp=72d0d80c54e73b2db2103fdcc72c946be3fff82e;hpb=5536dcb1f7a553438dc249d9c7658f483c75c685;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/GlobalFunctions.php b/includes/GlobalFunctions.php index 72d0d80c54..5b4d8bc869 100644 --- a/includes/GlobalFunctions.php +++ b/includes/GlobalFunctions.php @@ -90,6 +90,41 @@ if( !function_exists( 'floatval' ) ) { } } +if ( !function_exists( 'array_diff_key' ) ) { + /** + * Exists in PHP 5.1.0+ + * Not quite compatible, two-argument version only + * Null values will cause problems due to this use of isset() + */ + function array_diff_key( $left, $right ) { + $result = $left; + foreach ( $left as $key => $value ) { + if ( isset( $right[$key] ) ) { + unset( $result[$key] ); + } + } + return $result; + } +} + +// If it doesn't exist no ctype_* stuff will +if ( ! function_exists( 'ctype_alnum' ) ) + require_once 'compatability/ctype.php'; + +/** + * Wrapper for clone() for PHP 4, for the moment. + * PHP 5 won't let you declare a 'clone' function, even conditionally, + * so it has to be a wrapper with a different name. + */ +function wfClone( $object ) { + // WARNING: clone() is not a function in PHP 5, so function_exists fails. + if( version_compare( PHP_VERSION, '5.0' ) < 0 ) { + return $object; + } else { + return clone( $object ); + } +} + /** * Where as we got a random seed * @var bool $wgTotalViews @@ -212,7 +247,7 @@ function wfLogDBError( $text ) { */ function logProfilingData() { global $wgRequestTime, $wgDebugLogFile, $wgDebugRawPage, $wgRequest; - global $wgProfiling, $wgProfileStack, $wgProfileLimit, $wgUser; + global $wgProfiling, $wgUser; $now = wfTime(); list( $usec, $sec ) = explode( ' ', $wgRequestTime ); @@ -229,7 +264,7 @@ function logProfilingData() { $forward .= ' from ' . $_SERVER['HTTP_FROM']; if( $forward ) $forward = "\t(proxied via {$_SERVER['REMOTE_ADDR']}{$forward})"; - if( $wgUser->isAnon() ) + if( is_object($wgUser) && $wgUser->isAnon() ) $forward .= ' anon'; $log = sprintf( "%s\t%04.3f\t%s\n", gmdate( 'YmdHis' ), $elapsed, @@ -270,7 +305,7 @@ function wfReadOnly() { /** * Get a message from anywhere, for the current user language. * - * Use wfMsgForContent() instead if the message should NOT + * Use wfMsgForContent() instead if the message should NOT * change depending on the user preferences. * * Note that the message may contain HTML, and is therefore @@ -278,7 +313,7 @@ function wfReadOnly() { * addWikiText will do the escaping for you. Use wfMsgHtml() * if you need an escaped message. * - * @param string lookup key for the message, usually + * @param string lookup key for the message, usually * defined in languages/Language.php */ function wfMsg( $key ) { @@ -287,26 +322,35 @@ function wfMsg( $key ) { return wfMsgReal( $key, $args, true ); } +/** + * Same as above except doesn't transform the message + */ +function wfMsgNoTrans( $key ) { + $args = func_get_args(); + array_shift( $args ); + return wfMsgReal( $key, $args, true, false ); +} + /** * Get a message from anywhere, for the current global language * set with $wgLanguageCode. - * - * Use this if the message should NOT change dependent on the - * language set in the user's preferences. This is the case for - * most text written into logs, as well as link targets (such as - * the name of the copyright policy page). Link titles, on the + * + * Use this if the message should NOT change dependent on the + * language set in the user's preferences. This is the case for + * most text written into logs, as well as link targets (such as + * the name of the copyright policy page). Link titles, on the * other hand, should be shown in the UI language. * - * Note that MediaWiki allows users to change the user interface - * language in their preferences, but a single installation + * Note that MediaWiki allows users to change the user interface + * language in their preferences, but a single installation * typically only contains content in one language. - * - * Be wary of this distinction: If you use wfMsg() where you should - * use wfMsgForContent(), a user of the software may have to + * + * Be wary of this distinction: If you use wfMsg() where you should + * use wfMsgForContent(), a user of the software may have to * customize over 70 messages in order to, e.g., fix a link in every * possible language. * - * @param string lookup key for the message, usually + * @param string lookup key for the message, usually * defined in languages/Language.php */ function wfMsgForContent( $key ) { @@ -320,6 +364,20 @@ function wfMsgForContent( $key ) { return wfMsgReal( $key, $args, true, $forcontent ); } +/** + * Same as above except doesn't transform the message + */ +function wfMsgForContentNoTrans( $key ) { + global $wgForceUIMsgAsContentMsg; + $args = func_get_args(); + array_shift( $args ); + $forcontent = true; + if( is_array( $wgForceUIMsgAsContentMsg ) && + in_array( $key, $wgForceUIMsgAsContentMsg ) ) + $forcontent = false; + return wfMsgReal( $key, $args, true, $forcontent, false ); +} + /** * Get a message from the language file, for the UI elements */ @@ -347,16 +405,35 @@ function wfMsgNoDBForContent( $key ) { /** * Really get a message */ -function wfMsgReal( $key, $args, $useDB, $forContent=false ) { +function wfMsgReal( $key, $args, $useDB, $forContent=false, $transform = true ) { $fname = 'wfMsgReal'; wfProfileIn( $fname ); - $message = wfMsgGetKey( $key, $useDB, $forContent ); + $message = wfMsgGetKey( $key, $useDB, $forContent, $transform ); $message = wfMsgReplaceArgs( $message, $args ); wfProfileOut( $fname ); return $message; } +/** + * This function provides the message source for messages to be edited which are *not* stored in the database +*/ + +function wfMsgWeirdKey ( $key ) { + $subsource = str_replace ( ' ' , '_' , $key ) ; + $source = wfMsg ( $subsource ) ; + if ( $source == "<{$subsource}>" ) { + # Try again with first char lower case + $subsource = strtolower ( substr ( $subsource , 0 , 1 ) ) . substr ( $subsource , 1 ) ; + $source = wfMsg ( $subsource ) ; + } + if ( $source == "<{$subsource}>" ) { + # Didn't work either, return blank text + $source = "" ; + } + return $source ; +} + /** * Fetch a message string value, but don't replace any keys yet. * @param string $key @@ -365,12 +442,15 @@ function wfMsgReal( $key, $args, $useDB, $forContent=false ) { * @return string * @access private */ -function wfMsgGetKey( $key, $useDB, $forContent = false ) { - global $wgParser, $wgMsgParserOptions; - global $wgContLang, $wgLanguageCode; - global $wgMessageCache, $wgLang; +function wfMsgGetKey( $key, $useDB, $forContent = false, $transform = true ) { + global $wgParser, $wgMsgParserOptions, $wgContLang, $wgMessageCache, $wgLang; + + if ( is_object( $wgMessageCache ) ) + $transstat = $wgMessageCache->getTransform(); if( is_object( $wgMessageCache ) ) { + if ( ! $transform ) + $wgMessageCache->disableTransform(); $message = $wgMessageCache->get( $key, $useDB, $forContent ); } else { if( $forContent ) { @@ -389,10 +469,14 @@ function wfMsgGetKey( $key, $useDB, $forContent = false ) { wfRestoreWarnings(); if($message === false) $message = Language::getMessage($key); - if(strstr($message, '{{' ) !== false) { + if ( $transform && strstr( $message, '{{' ) !== false ) { $message = $wgParser->transformMsg($message, $wgMsgParserOptions); } } + + if ( is_object( $wgMessageCache ) && ! $transform ) + $wgMessageCache->setTransform( $transstat ); + return $message; } @@ -410,16 +494,19 @@ function wfMsgReplaceArgs( $message, $args ) { $message = str_replace( "\r", '', $message ); // Replace arguments - if ( count( $args ) ) - if ( is_array( $args[0] ) ) - foreach ( $args[0] as $key => $val ) + if ( count( $args ) ) { + if ( is_array( $args[0] ) ) { + foreach ( $args[0] as $key => $val ) { $message = str_replace( '$' . $key, $val, $message ); - else { - foreach( $args as $n => $param ) - $replacementKeys['$' . ($n + 1)] = $param; - $message = strtr( $message, $replacementKeys ); + } + } else { + foreach( $args as $n => $param ) { + $replacementKeys['$' . ($n + 1)] = $param; + } + $message = strtr( $message, $replacementKeys ); + } } - + return $message; } @@ -466,7 +553,7 @@ function wfAbruptExit( $error = false ){ global $wgLoadBalancer; static $called = false; if ( $called ){ - exit(); + exit( -1 ); } $called = true; @@ -480,10 +567,14 @@ function wfAbruptExit( $error = false ){ } else { wfDebug('WARNING: Abrupt exit\n'); } + + wfProfileClose(); + logProfilingData(); + if ( !$error ) { $wgLoadBalancer->closeAll(); } - exit(); + exit( -1 ); } /** @@ -493,6 +584,16 @@ function wfErrorExit() { wfAbruptExit( true ); } +/** + * Print a simple message and die, returning nonzero to the shell if any. + * Plain die() fails to return nonzero to the shell if you pass a string. + * @param string $msg + */ +function wfDie( $msg='' ) { + echo $msg; + die( -1 ); +} + /** * Die with a backtrace * This is meant as a debugging aid to track down where bad data comes from. @@ -632,7 +733,6 @@ function wfViewPrevNext( $offset, $limit, $link, $query = '', $atend = false ) { } } - $sk = $wgUser->getSkin(); if ( 0 != $offset ) { $po = $offset - $limit; if ( $po < 0 ) { $po = 0; } @@ -1137,7 +1237,7 @@ define('TS_RFC2822', 3); /** * ISO 8601 format with no timezone: 1986-02-09T20:00:00Z * - * This is used by Special:Export + * This is used by Special:Export */ define('TS_ISO_8601', 4); @@ -1232,9 +1332,9 @@ function wfTimestampOrNull( $outputtype = TS_UNIX, $ts = null ) { } /** - * Check where as the operating system is Windows + * Check if the operating system is Windows * - * @return bool True if it's windows, False otherwise. + * @return bool True if it's Windows, False otherwise. */ function wfIsWindows() { if (substr(php_uname(), 0, 7) == 'Windows') { @@ -1253,29 +1353,66 @@ function swap( &$x, &$y ) { $y = $z; } -function wfGetSiteNotice() { - global $wgSiteNotice, $wgTitle, $wgOut; - $fname = 'wfGetSiteNotice'; +function wfGetCachedNotice( $name ) { + global $wgOut, $parserMemc, $wgDBname; + $fname = 'wfGetCachedNotice'; wfProfileIn( $fname ); - - $notice = wfMsg( 'sitenotice' ); - if( $notice == '<sitenotice>' || $notice == '-' ) { - $notice = ''; + + $needParse = false; + $notice = wfMsgForContent( $name ); + if( $notice == '<'. $name . ';>' || $notice == '-' ) { + wfProfileOut( $fname ); + return( false ); } - if( $notice == '' ) { - # We may also need to override a message with eg downtime info - # FIXME: make this work! - $notice = $wgSiteNotice; + + $cachedNotice = $parserMemc->get( $wgDBname . ':' . $name ); + if( is_array( $cachedNotice ) ) { + if( md5( $notice ) == $cachedNotice['hash'] ) { + $notice = $cachedNotice['html']; + } else { + $needParse = true; + } + } else { + $needParse = true; } - if($notice != '-' && $notice != '') { - $specialparser = new Parser(); - $parserOutput = $specialparser->parse( $notice, $wgTitle, $wgOut->mParserOptions, false ); - $notice = $parserOutput->getText(); + + if( $needParse ) { + if( is_object( $wgOut ) ) { + $parsed = $wgOut->parse( $notice ); + $parserMemc->set( $wgDBname . ':' . $name, array( 'html' => $parsed, 'hash' => md5( $notice ) ), 600 ); + $notice = $parsed; + } else { + wfDebug( 'wfGetCachedNotice called for ' . $name . ' with no $wgOut available' ); + $notice = ''; + } } + wfProfileOut( $fname ); return $notice; } +function wfGetSiteNotice() { + global $wgUser, $wgSiteNotice; + $fname = 'wfGetSiteNotice'; + wfProfileIn( $fname ); + + if( $wgUser->isLoggedIn() ) { + $siteNotice = wfGetCachedNotice( 'sitenotice' ); + $siteNotice = !$siteNotice ? $wgSiteNotice : $siteNotice; + } else { + $anonNotice = wfGetCachedNotice( 'anonnotice' ); + if( !$anonNotice ) { + $siteNotice = wfGetCachedNotice( 'sitenotice' ); + $siteNotice = !$siteNotice ? $wgSiteNotice : $siteNotice; + } else { + $siteNotice = $anonNotice; + } + } + + wfProfileOut( $fname ); + return( $siteNotice ); +} + /** * Format an XML element with given attributes and, optionally, text content. * Element and attribute names are assumed to be ready for literal inclusion. @@ -1300,9 +1437,7 @@ function wfElement( $element, $attribs = null, $contents = '') { if( $contents == '' ) { $out .= ' />'; } else { - $out .= '>'; - $out .= htmlspecialchars( $contents ); - $out .= ""; + $out .= '>' . htmlspecialchars( $contents ) . ""; } } return $out; @@ -1329,7 +1464,7 @@ function wfElementClean( $element, $attribs = array(), $contents = '') { } // Shortcuts -function wfOpenElement( $element ) { return "<$element>"; } +function wfOpenElement( $element, $attribs = null ) { return wfElement( $element, $attribs, null ); } function wfCloseElement( $element ) { return ""; } /** @@ -1375,7 +1510,7 @@ function &HTMLnamespaceselector($selected = '', $allnamespaces = null) { /** Global singleton instance of MimeMagic. This is initialized on demand, * please always use the wfGetMimeMagic() function to get the instance. * -* @private +* @access private */ $wgMimeMagic= NULL; @@ -1430,7 +1565,7 @@ function wfTempDir() { function wfMkdirParents( $fullDir, $mode ) { $parts = explode( '/', $fullDir ); $path = ''; - + foreach ( $parts as $dir ) { $path .= $dir . '/'; if ( !is_dir( $path ) ) { @@ -1525,11 +1660,11 @@ function in_string( $needle, $str ) { function wfUrlProtocols() { global $wgUrlProtocols; - $x = array(); + $protocols = array(); foreach ($wgUrlProtocols as $protocol) - $x[] = preg_quote( $protocol, '/' ); - - return implode( '|', $x ); + $protocols[] = preg_quote( $protocol, '/' ); + + return implode( '|', $protocols ); } /** @@ -1543,10 +1678,10 @@ function wfUrlProtocols() { */ function wfIsWellFormedXml( $text ) { $parser = xml_parser_create( "UTF-8" ); - + # case folding violates XML standard, turn it off xml_parser_set_option( $parser, XML_OPTION_CASE_FOLDING, false ); - + if( !xml_parse( $parser, $text, true ) ) { $err = xml_error_string( xml_get_error_code( $parser ) ); $position = xml_get_current_byte_index( $parser ); @@ -1568,9 +1703,8 @@ function wfIsWellFormedXml( $text ) { * @return bool */ function wfIsWellFormedXmlFragment( $text ) { - $html = - '' . + $html = + Sanitizer::hackDocType() . '' . $text . ''; @@ -1584,7 +1718,7 @@ function wfIsWellFormedXmlFragment( $text ) { function wfShellExec( $cmd ) { global $IP; - + if ( php_uname( 's' ) == 'Linux' ) { $time = ini_get( 'max_execution_time' ); $mem = ini_get( 'memory_limit' ); @@ -1602,4 +1736,78 @@ function wfShellExec( $cmd ) return shell_exec( $cmd ); } +/** + * 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 + * + * This is useful for extensions which due to their nature are not kept in sync + * with releases, and might depend on other versions of PHP than the main code + * + * Note: PHP might die due to parsing errors in some cases before it ever + * manages to call this function, such is life + * + * @see perldoc -f use + * + * @param mixed $version The version to check, can be a string, an integer, or + * a float + */ +function wfUsePHP( $req_ver ) { + $php_ver = PHP_VERSION; + + if ( version_compare( $php_ver, (string)$req_ver, '<' ) ) + wfDebugDieBacktrace( "PHP $req_ver required--this is only $php_ver" ); +} + +/** + * This function works like "use VERSION" in Perl except it checks the version + * of MediaWiki, the program will die with a backtrace if the current version + * of MediaWiki is less than the version provided. + * + * This is useful for extensions which due to their nature are not kept in sync + * with releases + * + * @see perldoc -f use + * + * @param mixed $version The version to check, can be a string, an integer, or + * a float + */ +function wfUseMW( $req_ver ) { + global $wgVersion; + + if ( version_compare( $wgVersion, (string)$req_ver, '<' ) ) + wfDebugDieBacktrace( "MediaWiki $req_ver required--this is only $wgVersion" ); +} + +/** + * Escape a string to make it suitable for inclusion in a preg_replace() + * replacement parameter. + * + * @param string $string + * @return string + */ +function wfRegexReplacement( $string ) { + $string = str_replace( '\\', '\\\\', $string ); + $string = str_replace( '$', '\\$', $string ); + return $string; +} + +/** + * Return the final portion of a pathname. + * Reimplemented because PHP5's basename() is buggy with multibyte text. + * http://bugs.php.net/bug.php?id=33898 + * + * PHP's basename() only considers '\' a pathchar on Windows and Netware. + * We'll consider it so always, as we don't want \s in our Unix paths either. + * + * @param string $path + * @return string + */ +function wfBaseName( $path ) { + if( preg_match( '#([^/\\\\]*)[/\\\\]*$#', $path, $matches ) ) { + return $matches[1]; + } else { + return ''; + } +} + ?>