* in_string() function, for us strpos haters
[lhc/web/wiklou.git] / includes / GlobalFunctions.php
index a0cee45..50f6302 100644 (file)
@@ -175,6 +175,25 @@ function wfDebug( $text, $logonly = false ) {
        }
 }
 
+/**
+ * Send a line to a supplementary debug log file, if configured, or main debug log if not.
+ * $wgDebugLogGroups[$logGroup] should be set to a filename to send to a separate log.
+ *
+ * @param string $logGroup
+ * @param string $text
+ * @param bool $public Whether to log the event in the public log if no private
+ *                     log file is specified, (default true)
+ */
+function wfDebugLog( $logGroup, $text, $public = true ) {
+       global $wgDebugLogGroups, $wgDBname;
+       if( $text{strlen( $text ) - 1} != "\n" ) $text .= "\n";
+       if( isset( $wgDebugLogGroups[$logGroup] ) ) {
+               @error_log( "$wgDBname: $text", 3, $wgDebugLogGroups[$logGroup] );
+       } else if ( $public === true ) {
+               wfDebug( $text, true );
+       }
+}
+
 /**
  * Log for database errors
  * @param string $text Database error message.
@@ -238,7 +257,7 @@ function wfReadOnly() {
 
        // Set $wgReadOnly and unset $wgReadOnlyFile, for faster access next time
        if ( is_file( $wgReadOnlyFile ) ) {
-               $wgReadOnly = true;
+               $wgReadOnly = file_get_contents( $wgReadOnlyFile );
        } else {
                $wgReadOnly = false;
        }
@@ -248,9 +267,18 @@ function wfReadOnly() {
 
 
 /**
- * Get a message from anywhere, for the current user language
+ * Get a message from anywhere, for the current user language.
  *
- * @param string
+ * Use wfMsgForContent() instead if the message should NOT 
+ * change depending on the user preferences.
+ *
+ * Note that the message may contain HTML, and is therefore
+ * not safe for insertion anywhere. Some functions such as
+ * addWikiText will do the escaping for you. Use wfMsgHtml()
+ * if you need an escaped message.
+ *
+ * @param string lookup key for the message, usually 
+ *    defined in languages/Language.php
  */
 function wfMsg( $key ) {
        $args = func_get_args();
@@ -260,6 +288,25 @@ function wfMsg( $key ) {
 
 /**
  * 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 
+ * 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 
+ * 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 
+ * customize over 70 messages in order to, e.g., fix a link in every
+ * possible language.
+ *
+ * @param string lookup key for the message, usually 
+ *    defined in languages/Language.php
  */
 function wfMsgForContent( $key ) {
        global $wgForceUIMsgAsContentMsg;
@@ -336,10 +383,10 @@ function wfMsgGetKey( $key, $useDB, $forContent = false ) {
                if( is_object( $lang ) ) {
                        $message = $lang->getMessage( $key );
                } else {
-                       $message = '';
+                       $message = false;
                }
                wfRestoreWarnings();
-               if(!$message)
+               if($message === false)
                        $message = Language::getMessage($key);
                if(strstr($message, '{{' ) !== false) {
                        $message = $wgParser->transformMsg($message, $wgMsgParserOptions);
@@ -387,6 +434,24 @@ function wfMsgHtml( $key ) {
        return wfMsgReplaceArgs( htmlspecialchars( wfMsgGetKey( $key, true ) ), $args );
 }
 
+/**
+ * Return an HTML version of message
+ * Parameter replacements, if any, are done *after* parsing the wiki-text message,
+ * so parameters may contain HTML (eg links or form controls). Be sure
+ * to pre-escape them if you really do want plaintext, or just wrap
+ * the whole thing in htmlspecialchars().
+ *
+ * @param string $key
+ * @param string ... parameters
+ * @return string
+ */
+function wfMsgWikiHtml( $key ) {
+       global $wgOut;
+       $args = func_get_args();
+       array_shift( $args );
+       return wfMsgReplaceArgs( $wgOut->parse( wfMsgGetKey( $key, true ), /* can't be set to false */ true ), $args );
+}
+
 /**
  * Just like exit() but makes a note of it.
  * Commits open transactions except if the error parameter is set
@@ -439,11 +504,43 @@ function wfDebugDieBacktrace( $msg = '' ) {
                } else {
                        $msg .= "\n<p>Backtrace:</p>\n$backtrace";
                }
-        }
-        echo $msg;
-        die( -1 );
+       }
+       echo $msg;
+       echo wfReportTime()."\n";
+       die( -1 );
 }
 
+       /**
+        * Returns a HTML comment with the elapsed time since request.
+        * This method has no side effects.
+        * @return string
+        */
+       function wfReportTime() {
+               global $wgRequestTime;
+
+               $now = wfTime();
+               list( $usec, $sec ) = explode( ' ', $wgRequestTime );
+               $start = (float)$sec + (float)$usec;
+               $elapsed = $now - $start;
+
+               # Use real server name if available, so we know which machine
+               # in a server farm generated the current page.
+               if ( function_exists( 'posix_uname' ) ) {
+                       $uname = @posix_uname();
+               } else {
+                       $uname = false;
+               }
+               if( is_array( $uname ) && isset( $uname['nodename'] ) ) {
+                       $hostname = $uname['nodename'];
+               } else {
+                       # This may be a virtual server.
+                       $hostname = $_SERVER['SERVER_NAME'];
+               }
+               $com = sprintf( "<!-- Served by %s in %01.2f secs. -->",
+                 $hostname, $elapsed );
+               return $com;
+       }
+
 function wfBacktrace() {
        global $wgCommandLineMode;
        if ( !function_exists( 'debug_backtrace' ) ) {
@@ -774,6 +871,7 @@ function wfMerge( $old, $mine, $yours, &$result ){
        # This check may also protect against code injection in
        # case of broken installations.
        if(! file_exists( $wgDiff3 ) ){
+               wfDebug( "diff3 not found\n" );
                return false;
        }
 
@@ -788,7 +886,7 @@ function wfMerge( $old, $mine, $yours, &$result ){
        fwrite( $yourtextFile, $yours ); fclose( $yourtextFile );
 
        # Check for a conflict
-       $cmd = wfEscapeShellArg( $wgDiff3 ) . ' -a --overlap-only ' .
+       $cmd = $wgDiff3 . ' -a --overlap-only ' .
          wfEscapeShellArg( $mytextName ) . ' ' .
          wfEscapeShellArg( $oldtextName ) . ' ' .
          wfEscapeShellArg( $yourtextName );
@@ -802,7 +900,7 @@ function wfMerge( $old, $mine, $yours, &$result ){
        pclose( $handle );
 
        # Merge differences
-       $cmd = wfEscapeShellArg( $wgDiff3 ) . ' -a -e --merge ' .
+       $cmd = $wgDiff3 . ' -a -e --merge ' .
          wfEscapeShellArg( $mytextName, $oldtextName, $yourtextName );
        $handle = popen( $cmd, 'r' );
        $result = '';
@@ -815,6 +913,11 @@ function wfMerge( $old, $mine, $yours, &$result ){
        } while ( true );
        pclose( $handle );
        unlink( $mytextName ); unlink( $oldtextName ); unlink( $yourtextName );
+
+       if ( $result === '' && $old !== '' && $conflict == false ) {
+               wfDebug( "Unexpected null result from diff3.\nCommand: $cmd\nOutput: " . `$cmd 2>&1` . "\n" );
+               $conflict = true;
+       }
        return ! $conflict;
 }
 
@@ -983,7 +1086,7 @@ function wfSuppressWarnings( $end = false ) {
 
        if ( $end ) {
                if ( $suppressCount ) {
-                       $suppressCount --;
+                       --$suppressCount;
                        if ( !$suppressCount ) {
                                error_reporting( $originalLevel );
                        }
@@ -992,7 +1095,7 @@ function wfSuppressWarnings( $end = false ) {
                if ( !$suppressCount ) {
                        $originalLevel = error_reporting( E_ALL & ~( E_WARNING | E_NOTICE ) );
                }
-               $suppressCount++;
+               ++$suppressCount;
        }
 }
 
@@ -1046,7 +1149,7 @@ define('TS_ORACLE', 5);
  * @return string Time in the format specified in $outputtype
  */
 function wfTimestamp($outputtype=TS_UNIX,$ts=0) {
-wfdebug("ts: $ts\n");
+       $uts = 0;
        if ($ts==0) {
                $uts=time();
        } elseif (preg_match("/^(\d{4})\-(\d\d)\-(\d\d) (\d\d):(\d\d):(\d\d)$/",$ts,$da)) {
@@ -1206,6 +1309,10 @@ function wfElementClean( $element, $attribs = array(), $contents = '') {
        return wfElement( $element, $attribs, $contents );
 }
 
+// Shortcuts
+function wfOpenElement( $element ) { return "<$element>"; }
+function wfCloseElement( $element ) { return "</$element>"; }
+
 /**
  * Create a namespace selector
  *
@@ -1215,7 +1322,7 @@ function wfElementClean( $element, $attribs = array(), $contents = '') {
  */
 function &HTMLnamespaceselector($selected = '', $allnamespaces = null) {
        global $wgContLang;
-       $s = "<select name='namespace' class='namespaceselector'>\n";
+       $s = "<select name='namespace' class='namespaceselector'>\n\t";
        $arr = $wgContLang->getFormattedNamespaces();
        if( !is_null($allnamespaces) ) {
                $arr = array($allnamespaces => wfMsgHtml('namespacesall')) + $arr;
@@ -1233,7 +1340,7 @@ function &HTMLnamespaceselector($selected = '', $allnamespaces = null) {
                        $s .= wfElement("option", array("value" => $index), $name);
                }
        }
-       $s .= "</select>\n";
+       $s .= "\n</select>\n";
        return $s;
 }
 
@@ -1358,4 +1465,27 @@ function wfAppendToArrayIfNotDefault( $key, $value, $default, &$changed ) {
        }
 }
 
+/**
+ * Since wfMsg() and co suck, they don't return false if the message key they
+ * looked up didn't exist but a XHTML string, this function checks for the
+ * nonexistance of messages by looking at wfMsg() output
+ *
+ * @param $msg      The message key looked up
+ * @param $wfMsgOut The output of wfMsg*()
+ * @return bool
+ */
+function wfEmptyMsg( $msg, $wfMsgOut ) {
+       return $wfMsgOut === "&lt;$msg&gt;";
+}
+
+/**
+ * Find out whether or not a mixed variable exists in a string
+ *
+ * @param mixed  needle
+ * @param string haystack
+ * @return bool
+ */
+function in_string( $needle, $str ) {
+       return strpos( $str, $needle ) !== false;
+}
 ?>