Merge "Make calling wfMangleFlashPolicy configurable"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Wed, 19 Nov 2014 20:14:03 +0000 (20:14 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Wed, 19 Nov 2014 20:14:03 +0000 (20:14 +0000)
40 files changed:
autoload.php
composer.json
includes/CdbCompat.php [new file with mode: 0644]
includes/DefaultSettings.php
includes/GlobalFunctions.php
includes/OutputPage.php
includes/Title.php
includes/User.php
includes/WebStart.php
includes/cache/LocalisationCache.php
includes/db/Database.php
includes/db/DatabaseMysqlBase.php
includes/db/LoadBalancer.php
includes/debug/logger/legacy/Logger.php
includes/installer/WebInstallerPage.php
includes/interwiki/Interwiki.php
includes/libs/cdb/CdbException.php [deleted file]
includes/libs/cdb/CdbFunctions.php [deleted file]
includes/libs/cdb/CdbReader.php [deleted file]
includes/libs/cdb/CdbReaderDBA.php [deleted file]
includes/libs/cdb/CdbReaderPHP.php [deleted file]
includes/libs/cdb/CdbWriter.php [deleted file]
includes/libs/cdb/CdbWriterDBA.php [deleted file]
includes/libs/cdb/CdbWriterPHP.php [deleted file]
includes/media/Bitmap.php
includes/media/TransformationalImageHandler.php
includes/parser/Parser.php
includes/poolcounter/PoolWorkArticleView.php
includes/profiler/ProfilerXhprof.php
includes/profiler/SectionProfiler.php
includes/utils/AutoloadGenerator.php
maintenance/Doxyfile
maintenance/cdb.php
resources/src/mediawiki.page/mediawiki.page.ready.js
resources/src/mediawiki.special/mediawiki.special.javaScriptTest.js
resources/src/mediawiki.special/mediawiki.special.preferences.js
resources/src/mediawiki/mediawiki.Uri.js
resources/src/mediawiki/mediawiki.util.js
tests/phpunit/includes/debug/logging/legacy/LoggerTest.php [new file with mode: 0644]
tests/phpunit/includes/libs/cdb/CdbTest.php [deleted file]

index bc039e9..5239edc 100644 (file)
@@ -189,14 +189,9 @@ $wgAutoloadLocalClasses = array(
        'CategoryPage' => __DIR__ . '/includes/page/CategoryPage.php',
        'CategoryPager' => __DIR__ . '/includes/specials/SpecialCategories.php',
        'CategoryViewer' => __DIR__ . '/includes/CategoryViewer.php',
-       'CdbException' => __DIR__ . '/includes/libs/cdb/CdbException.php',
-       'CdbFunctions' => __DIR__ . '/includes/libs/cdb/CdbFunctions.php',
-       'CdbReader' => __DIR__ . '/includes/libs/cdb/CdbReader.php',
-       'CdbReaderDBA' => __DIR__ . '/includes/libs/cdb/CdbReaderDBA.php',
-       'CdbReaderPHP' => __DIR__ . '/includes/libs/cdb/CdbReaderPHP.php',
-       'CdbWriter' => __DIR__ . '/includes/libs/cdb/CdbWriter.php',
-       'CdbWriterDBA' => __DIR__ . '/includes/libs/cdb/CdbWriterDBA.php',
-       'CdbWriterPHP' => __DIR__ . '/includes/libs/cdb/CdbWriterPHP.php',
+       'CdbException' => __DIR__ . '/includes/CdbCompat.php',
+       'CdbReader' => __DIR__ . '/includes/CdbCompat.php',
+       'CdbWriter' => __DIR__ . '/includes/CdbCompat.php',
        'CgzCopyTransaction' => __DIR__ . '/maintenance/storage/recompressTracked.php',
        'ChangePassword' => __DIR__ . '/maintenance/changePassword.php',
        'ChangeTags' => __DIR__ . '/includes/ChangeTags.php',
@@ -1316,4 +1311,4 @@ $wgAutoloadLocalClasses = array(
        'lessc_formatter_lessjs' => __DIR__ . '/includes/libs/lessc.inc.php',
        'lessc_parser' => __DIR__ . '/includes/libs/lessc.inc.php',
        'profile_point' => __DIR__ . '/profileinfo.php',
-);
\ No newline at end of file
+);
index 61f30ce..834e14f 100644 (file)
@@ -18,7 +18,8 @@
        "require": {
                "php": ">=5.3.3",
                "psr/log": "1.0.0",
-               "cssjanus/cssjanus": "1.1.0"
+               "cssjanus/cssjanus": "1.1.0",
+               "cdb/cdb": "1.0.0"
        },
        "require-dev": {
                "phpunit/phpunit": "*"
diff --git a/includes/CdbCompat.php b/includes/CdbCompat.php
new file mode 100644 (file)
index 0000000..0c00b39
--- /dev/null
@@ -0,0 +1,42 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/***
+ * This file contains a set of backwards-compatability class names
+ * after the cdb functions were moved out into a separate library
+ * and put under a proper namespace
+ *
+ * @since 1.25
+ */
+
+/**
+ * @deprecated since 1.25
+ */
+abstract class CdbReader extends \Cdb\Reader {}
+
+/**
+ * @deprecated since 1.25
+ */
+abstract class CdbWriter extends \Cdb\Writer {}
+
+/**
+ * @deprecated since 1.25
+ */
+class CdbException extends \Cdb\Exception {}
index d4efc60..f93737c 100644 (file)
@@ -1383,7 +1383,7 @@ $wgDjvuOutputExtension = 'jpg';
 /**
  * Site admin email address.
  *
- * Defaults to "wikiadmin@{$wgServerName}".
+ * Defaults to "wikiadmin@$wgServerName".
  */
 $wgEmergencyContact = false;
 
@@ -1392,7 +1392,7 @@ $wgEmergencyContact = false;
  *
  * The address we should use as sender when a user is requesting his password.
  *
- * Defaults to "apache@{$wgServerName}".
+ * Defaults to "apache@$wgServerName".
  */
 $wgPasswordSender = false;
 
index 71c3791..25b352b 100644 (file)
@@ -950,6 +950,8 @@ function wfMatchesDomainList( $url, $domains ) {
  * $wgDebugRawPage - if false, 'action=raw' hits will not result in debug output.
  * $wgDebugComments - if on, some debug items may appear in comments in the HTML output.
  *
+ * @since 1.25 support for additional context data
+ *
  * @param string $text
  * @param string|bool $dest Destination of the message:
  *     - 'all': both to the log and HTML (debug toolbar or HTML comments)
@@ -957,9 +959,11 @@ function wfMatchesDomainList( $url, $domains ) {
  *   For backward compatibility, it can also take a boolean:
  *     - true: same as 'all'
  *     - false: same as 'log'
+ * @param array $context Additional logging context data
  */
-function wfDebug( $text, $dest = 'all' ) {
+function wfDebug( $text, $dest = 'all', array $context = array() ) {
        global $wgDebugRawPage, $wgDebugLogPrefix;
+       global $wgDebugTimestamps, $wgRequestTime;
 
        if ( !$wgDebugRawPage && wfIsDebugRawPage() ) {
                return;
@@ -972,23 +976,36 @@ function wfDebug( $text, $dest = 'all' ) {
                $dest = 'log';
        }
 
-       $timer = wfDebugTimer();
-       if ( $timer !== '' ) {
-               // Prepend elapsed request time and real memory usage to each line
-               $text = preg_replace( '/[^\n]/', $timer . '\0', $text, 1 );
+       $text = trim( $text );
+
+       // Inline logic from deprecated wfDebugTimer()
+       if ( $wgDebugTimestamps ) {
+               $context['seconds_elapsed'] = sprintf(
+                       '%6.4f',
+                       microtime( true ) - $wgRequestTime
+               );
+               $context['memory_used'] = sprintf(
+                       '%5.1fM',
+                       ( memory_get_usage( true ) / ( 1024 * 1024 ) )
+               );
        }
 
        if ( $dest === 'all' ) {
-               MWDebug::debugMsg( $text );
+               $prefix = '';
+               if ( $wgDebugTimestamps ) {
+                       // Prepend elapsed request time and real memory usage with two
+                       // trailing spaces.
+                       $prefix = "{$context['seconds_elapsed']} {$context['memory_used']}  ";
+               }
+               MWDebug::debugMsg( "{$prefix}{$text}" );
        }
 
-       $ctx = array();
        if ( $wgDebugLogPrefix !== '' ) {
-               $ctx['prefix'] = $wgDebugLogPrefix;
+               $context['prefix'] = $wgDebugLogPrefix;
        }
 
        $logger = MWLogger::getInstance( 'wfDebug' );
-       $logger->debug( rtrim( $text, "\n" ), $ctx );
+       $logger->debug( $text, $context );
 }
 
 /**
@@ -1017,11 +1034,14 @@ function wfIsDebugRawPage() {
 /**
  * Get microsecond timestamps for debug logs
  *
+ * @deprecated since 1.25
  * @return string
  */
 function wfDebugTimer() {
        global $wgDebugTimestamps, $wgRequestTime;
 
+       wfDeprecated( __METHOD__, '1.25' );
+
        if ( !$wgDebugTimestamps ) {
                return '';
        }
@@ -1054,6 +1074,7 @@ function wfDebugMem( $exact = false ) {
  * a sampling factor.
  *
  * @since 1.23 support for sampling log messages via $wgDebugLogGroups.
+ * @since 1.25 support for additional context data
  *
  * @param string $logGroup
  * @param string $text
@@ -1065,8 +1086,11 @@ function wfDebugMem( $exact = false ) {
  *   For backward compatibility, it can also take a boolean:
  *     - true: same as 'all'
  *     - false: same as 'private'
+ * @param array $context Additional logging context data
  */
-function wfDebugLog( $logGroup, $text, $dest = 'all' ) {
+function wfDebugLog(
+       $logGroup, $text, $dest = 'all', array $context = array()
+) {
        // Turn $dest into a string if it's a boolean (for b/c)
        if ( $dest === true ) {
                $dest = 'all';
@@ -1081,19 +1105,21 @@ function wfDebugLog( $logGroup, $text, $dest = 'all' ) {
        }
 
        $logger = MWLogger::getInstance( $logGroup );
-       $logger->debug( $text, array(
-               'private' => ( $dest === 'private' ),
-       ) );
+       $context['private'] = ( $dest === 'private' );
+       $logger->debug( $text, $context );
 }
 
 /**
  * Log for database errors
  *
+ * @since 1.25 support for additional context data
+ *
  * @param string $text Database error message.
+ * @param array $context Additional logging context data
  */
-function wfLogDBError( $text ) {
+function wfLogDBError( $text, array $context = array() ) {
        $logger = MWLogger::getInstance( 'wfLogDBError' );
-       $logger->error( trim( $text ) );
+       $logger->error( trim( $text ), $context );
 }
 
 /**
@@ -1145,16 +1171,17 @@ function wfLogWarning( $msg, $callerOffset = 1, $level = E_USER_WARNING ) {
  *
  * Can also log to TCP or UDP with the syntax udp://host:port/prefix. This will
  * send lines to the specified port, prefixed by the specified prefix and a space.
+ * @since 1.25 support for additional context data
  *
  * @param string $text
  * @param string $file Filename
+ * @param array $context Additional logging context data
  * @throws MWException
  */
-function wfErrorLog( $text, $file ) {
+function wfErrorLog( $text, $file, array $context = array() ) {
        $logger = MWLogger::getInstance( 'wfErrorLog' );
-       $logger->info( trim( $text ), array(
-               'destination' => $file,
-       ) );
+       $context['destination'] = $file;
+       $logger->info( trim( $text ), $context );
 }
 
 /**
index a517788..2936ca3 100644 (file)
@@ -3163,6 +3163,7 @@ class OutputPage extends ContextSource {
                        'wgMonthNames' => $lang->getMonthNamesArray(),
                        'wgMonthNamesShort' => $lang->getMonthAbbreviationsArray(),
                        'wgRelevantPageName' => $relevantTitle->getPrefixedDBkey(),
+                       'wgRelevantArticleId' => $relevantTitle->getArticleId(),
                );
 
                if ( $user->isLoggedIn() ) {
index b97d36a..f913859 100644 (file)
@@ -503,7 +503,7 @@ class Title {
                }
 
                $t = new Title();
-               $t->mDbkeyform = Title::makeName( $ns, $title, $fragment, $interwiki );
+               $t->mDbkeyform = Title::makeName( $ns, $title, $fragment, $interwiki, true );
                if ( $t->secureAndSplit() ) {
                        return $t;
                } else {
@@ -747,12 +747,20 @@ class Title {
         * @param string $title The DB key form the title
         * @param string $fragment The link fragment (after the "#")
         * @param string $interwiki The interwiki prefix
+        * @param boolean $canoncialNamespace If true, use the canonical name for
+        *   $ns instead of the localized version.
         * @return string The prefixed form of the title
         */
-       public static function makeName( $ns, $title, $fragment = '', $interwiki = '' ) {
+       public static function makeName( $ns, $title, $fragment = '', $interwiki = '',
+               $canoncialNamespace = false
+       ) {
                global $wgContLang;
 
-               $namespace = $wgContLang->getNsText( $ns );
+               if ( $canoncialNamespace ) {
+                       $namespace = MWNamespace::getCanonicalName( $ns );
+               } else {
+                       $namespace = $wgContLang->getNsText( $ns );
+               }
                $name = $namespace == '' ? $title : "$namespace:$title";
                if ( strval( $interwiki ) != '' ) {
                        $name = "$interwiki:$name";
index f9f4b6a..8fcdab2 100644 (file)
@@ -565,10 +565,12 @@ class User implements IDBAccessObject {
         * @return int|null The corresponding user's ID, or null if user is nonexistent
         */
        public static function idFromName( $name ) {
-               // We don't want to call Title::makeTitleSafe yet, since that call path
-               // ends up needing the user language, which ends up trying to load the
-               // user object, which ends up back here (bug 54193).
-               $nt = Title::makeTitle( NS_USER, $name );
+               $nt = Title::makeTitleSafe( NS_USER, $name );
+               if ( is_null( $nt ) ) {
+                       // Illegal name
+                       return null;
+               }
+
                if ( isset( self::$idCacheByName[$name] ) ) {
                        return self::$idCacheByName[$name];
                }
index dd27f3d..217ba3f 100644 (file)
@@ -111,7 +111,7 @@ wfProfileIn( 'WebStart.php-ob_start' );
 # Check that there is no previous output or previously set up buffers, because
 # that would cause us to potentially mix gzip and non-gzip output, creating a
 # big mess.
-if ( !defined( 'MW_NO_OUTPUT_BUFFER' ) && ob_get_level() == 0 ) {
+if ( ob_get_level() == 0 ) {
        require_once "$IP/includes/OutputHandler.php";
        ob_start( 'wfOutputHandler' );
 }
index ae27fba..2a3cd38 100644 (file)
@@ -20,6 +20,9 @@
  * @file
  */
 
+use Cdb\Exception as CdbException;
+use Cdb\Reader as CdbReader;
+use Cdb\Writer as CdbWriter;
 /**
  * Class for caching the contents of localisation files, Messages*.php
  * and *.i18n.php.
index 18cd39f..aa0e4de 100644 (file)
@@ -798,6 +798,23 @@ abstract class DatabaseBase implements IDatabase {
                $this->mPHPError = $errstr;
        }
 
+       /**
+        * Create a log context to pass to wfLogDBError or other logging functions.
+        *
+        * @param array $extras Additional data to add to context
+        * @return array
+        */
+       protected function getLogContext( array $extras = array() ) {
+               return array_merge(
+                       array(
+                               'db_server' => $this->mServer,
+                               'db_name' => $this->mDBname,
+                               'db_user' => $this->mUser,
+                       ),
+                       $extras
+               );
+       }
+
        /**
         * Closes a database connection.
         * if it is open : commits any open transactions
@@ -983,12 +1000,14 @@ abstract class DatabaseBase implements IDatabase {
                }
 
                # Log the query time and feed it into the DB trx profiler
-               $queryStartTime = microtime( true );
-               $queryProfile = new ScopedCallback( function() use ( $queryStartTime, $queryProf ) {
-                       $elapsed = microtime( true ) - $queryStartTime;
-                       $trxProfiler = Profiler::instance()->getTransactionProfiler();
-                       $trxProfiler->recordFunctionCompletion( $queryProf, $elapsed );
-               } );
+               if ( $queryProf != '' ) {
+                       $queryStartTime = microtime( true );
+                       $queryProfile = new ScopedCallback( function() use ( $queryStartTime, $queryProf ) {
+                               $elapsed = microtime( true ) - $queryStartTime;
+                               $trxProfiler = Profiler::instance()->getTransactionProfiler();
+                               $trxProfiler->recordFunctionCompletion( $queryProf, $elapsed );
+                       } );
+               }
 
                # Do the query and handle errors
                $ret = $this->doQuery( $commentedSql );
@@ -1015,7 +1034,13 @@ abstract class DatabaseBase implements IDatabase {
                                $elapsed = round( microtime( true ) - $wgRequestTime, 3 );
                                if ( $elapsed < 300 ) {
                                        # Not a database error to lose a transaction after a minute or two
-                                       wfLogDBError( "Connection lost and reconnected after {$elapsed}s, query: $sqlx" );
+                                       wfLogDBError(
+                                               "Connection lost and reconnected after {$elapsed}s, query: $sqlx",
+                                               $this->getLogContext( array(
+                                                       'method' => __METHOD__,
+                                                       'query' => $sqlx,
+                                               ) )
+                                       );
                                }
                                if ( $hadTrx ) {
                                        # Leave $ret as false and let an error be reported.
@@ -1063,7 +1088,16 @@ abstract class DatabaseBase implements IDatabase {
                        $this->ignoreErrors( $ignore );
                } else {
                        $sql1line = mb_substr( str_replace( "\n", "\\n", $sql ), 0, 5 * 1024 );
-                       wfLogDBError( "$fname\t{$this->mServer}\t$errno\t$error\t$sql1line" );
+                       wfLogDBError(
+                               "{fname}\t{db_server}\t{errno}\t{error}\t{sql1line}",
+                               $this->getLogContext( array(
+                                       'method' => __METHOD__,
+                                       'errno' => $errno,
+                                       'error' => $error,
+                                       'sql1line' => $sql1line,
+                                       'fname' => $fname,
+                               ) )
+                       );
                        wfDebug( "SQL ERROR: " . $error . "\n" );
                        throw new DBQueryError( $this, $error, $errno, $sql, $fname );
                }
@@ -3338,7 +3372,12 @@ abstract class DatabaseBase implements IDatabase {
                                $msg = "$fname: Transaction already in progress (from {$this->mTrxFname}), " .
                                        " performing implicit commit!";
                                wfWarn( $msg );
-                               wfLogDBError( $msg );
+                               wfLogDBError( $msg,
+                                       $this->getLogContext( array(
+                                               'method' => __METHOD__,
+                                               'fname' => $fname,
+                                       ) )
+                               );
                        } else {
                                // if the transaction was automatic and has done write operations,
                                // log it if $wgDebugDBTransactions is enabled.
index 2008f4d..7dfae63 100644 (file)
@@ -96,7 +96,13 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                        if ( !$error ) {
                                $error = $this->lastError();
                        }
-                       wfLogDBError( "Error connecting to {$this->mServer}: $error" );
+                       wfLogDBError(
+                               "Error connecting to {db_server}: {error}",
+                               $this->getLogContext( array(
+                                       'method' => __METHOD__,
+                                       'error' => $error,
+                               ) )
+                       );
                        wfDebug( "DB connection error\n" .
                                "Server: $server, User: $user, Password: " .
                                substr( $password, 0, 3 ) . "..., error: " . $error . "\n" );
@@ -111,7 +117,12 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                        $success = $this->selectDB( $dbName );
                        wfRestoreWarnings();
                        if ( !$success ) {
-                               wfLogDBError( "Error selecting database $dbName on server {$this->mServer}" );
+                               wfLogDBError(
+                                       "Error selecting database {db_name} on server {db_server}",
+                                       $this->getLogContext( array(
+                                               'method' => __METHOD__,
+                                       ) )
+                               );
                                wfDebug( "Error selecting database $dbName on server {$this->mServer} " .
                                        "from client host " . wfHostname() . "\n" );
 
@@ -132,7 +143,12 @@ abstract class DatabaseMysqlBase extends DatabaseBase {
                        // Use doQuery() to avoid opening implicit transactions (DBO_TRX)
                        $success = $this->doQuery( "SET sql_mode = $mode", __METHOD__ );
                        if ( !$success ) {
-                               wfLogDBError( "Error setting sql_mode to $mode on server {$this->mServer}" );
+                               wfLogDBError(
+                                       "Error setting sql_mode to $mode on server {db_server}",
+                                       $this->getLogContext( array(
+                                               'method' => __METHOD__,
+                                       ) )
+                               );
                                wfProfileOut( __METHOD__ );
                                $this->reportConnectionError( "Error setting sql_mode to $mode" );
                        }
index 0fb2d09..233c92f 100644 (file)
@@ -760,17 +760,27 @@ class LoadBalancer {
         */
        private function reportConnectionError() {
                $conn = $this->mErrorConnection; // The connection which caused the error
+               $context = array(
+                       'method' => __METHOD__,
+                       'last_error' => $this->mLastError,
+               );
 
                if ( !is_object( $conn ) ) {
                        // No last connection, probably due to all servers being too busy
-                       wfLogDBError( "LB failure with no last connection. Connection error: {$this->mLastError}" );
+                       wfLogDBError(
+                               "LB failure with no last connection. Connection error: {last_error}",
+                               $context
+                       );
 
                        // If all servers were busy, mLastError will contain something sensible
                        throw new DBConnectionError( null, $this->mLastError );
                } else {
-                       $server = $conn->getProperty( 'mServer' );
-                       wfLogDBError( "Connection error: {$this->mLastError} ({$server})" );
-                       $conn->reportConnectionError( "{$this->mLastError} ({$server})" ); // throws DBConnectionError
+                       $context['db_server'] = $conn->getProperty( 'mServer' );
+                       wfLogDBError(
+                               "Connection error: {last_error} ({db_server})",
+                               $context
+                       );
+                       $conn->reportConnectionError( "{$this->mLastError} ({$context['db_server']})" ); // throws DBConnectionError
                }
 
                return false; /* not reached */
index daf3f51..c6d915e 100644 (file)
@@ -178,7 +178,8 @@ class MWLoggerLegacyLogger extends \Psr\Log\AbstractLogger {
                        // Default formatting is wfDebugLog's historic style
                        $text = self::formatAsWfDebugLog( $channel, $message, $context );
                }
-               return $text;
+
+               return self::interpolate( $text, $context );
        }
 
 
@@ -192,6 +193,11 @@ class MWLoggerLegacyLogger extends \Psr\Log\AbstractLogger {
         */
        protected static function formatAsWfDebug( $channel, $message, $context ) {
                $text = preg_replace( '![\x00-\x08\x0b\x0c\x0e-\x1f]!', ' ', $message );
+               if ( isset( $context['seconds_elapsed'] ) ) {
+                       // Prepend elapsed request time and real memory usage with two
+                       // trailing spaces.
+                       $text = "{$context['seconds_elapsed']} {$context['memory_used']}  {$text}";
+               }
                if ( isset( $context['prefix'] ) ) {
                        $text = "{$context['prefix']}{$text}";
                }
@@ -248,6 +254,24 @@ class MWLoggerLegacyLogger extends \Psr\Log\AbstractLogger {
        }
 
 
+       /**
+        * Interpolate placeholders in logging message.
+        *
+        * @param string $message
+        * @param array $context
+        */
+       public static function interpolate( $message, array $context ) {
+               if ( strpos( $message, '{' ) !== false ) {
+                       $replace = array();
+                       foreach ( $context as $key => $val ) {
+                               $replace['{' . $key . '}'] = $val;
+                       }
+                       $message = strtr( $message, $replace );
+               }
+               return $message;
+       }
+
+
        /**
         * Select the appropriate log output destination for the given log event.
         *
index d507303..9ecb24b 100644 (file)
@@ -1463,7 +1463,7 @@ class WebInstallerComplete extends WebInstallerPage {
                        strpos( $_SERVER['HTTP_USER_AGENT'], 'MSIE' ) !== false
                ) {
                        // JS appears to be the only method that works consistently with IE7+
-                       $this->addHtml( "\n<script>jQuery( function () { document.location = " .
+                       $this->addHtml( "\n<script>jQuery( function () { location.href = " .
                                Xml::encodeJsVar( $lsUrl ) . "; } );</script>\n" );
                } else {
                        $this->parent->request->response()->header( "Refresh: 0;url=$lsUrl" );
index 55b2506..37a9fcf 100644 (file)
@@ -19,6 +19,8 @@
  *
  * @file
  */
+use \Cdb\Exception as CdbException;
+use \Cdb\Reader as CdbReader;
 
 /**
  * The interwiki class
diff --git a/includes/libs/cdb/CdbException.php b/includes/libs/cdb/CdbException.php
deleted file mode 100644 (file)
index 6cda529..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-<?php
-/**
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- */
-
-/**
- * Exception for Cdb errors.
- * This explicitly doesn't subclass MWException to encourage reuse.
- */
-class CdbException extends Exception {
-}
diff --git a/includes/libs/cdb/CdbFunctions.php b/includes/libs/cdb/CdbFunctions.php
deleted file mode 100644 (file)
index e74924c..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-<?php
-/**
- * This is a port of D.J. Bernstein's CDB to PHP. It's based on the copy that
- * appears in PHP 5.3. Changes are:
- *    * Error returns replaced with exceptions
- *    * Exception thrown if sizes or offsets are between 2GB and 4GB
- *    * Some variables renamed
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- */
-
-/**
- * Common functions for readers and writers
- */
-class CdbFunctions {
-       /**
-        * Take a modulo of a signed integer as if it were an unsigned integer.
-        * $b must be less than 0x40000000 and greater than 0
-        *
-        * @param int $a
-        * @param int $b
-        *
-        * @return int
-        */
-       public static function unsignedMod( $a, $b ) {
-               if ( $a & 0x80000000 ) {
-                       $m = ( $a & 0x7fffffff ) % $b + 2 * ( 0x40000000 % $b );
-
-                       return $m % $b;
-               } else {
-                       return $a % $b;
-               }
-       }
-
-       /**
-        * Shift a signed integer right as if it were unsigned
-        * @param int $a
-        * @param int $b
-        * @return int
-        */
-       public static function unsignedShiftRight( $a, $b ) {
-               if ( $b == 0 ) {
-                       return $a;
-               }
-               if ( $a & 0x80000000 ) {
-                       return ( ( $a & 0x7fffffff ) >> $b ) | ( 0x40000000 >> ( $b - 1 ) );
-               } else {
-                       return $a >> $b;
-               }
-       }
-
-       /**
-        * The CDB hash function.
-        *
-        * @param string $s
-        *
-        * @return int
-        */
-       public static function hash( $s ) {
-               $h = 5381;
-               $len = strlen( $s );
-               for ( $i = 0; $i < $len; $i++ ) {
-                       $h5 = ( $h << 5 ) & 0xffffffff;
-                       // Do a 32-bit sum
-                       // Inlined here for speed
-                       $sum = ( $h & 0x3fffffff ) + ( $h5 & 0x3fffffff );
-                       $h =
-                               (
-                                       ( $sum & 0x40000000 ? 1 : 0 )
-                                       + ( $h & 0x80000000 ? 2 : 0 )
-                                       + ( $h & 0x40000000 ? 1 : 0 )
-                                       + ( $h5 & 0x80000000 ? 2 : 0 )
-                                       + ( $h5 & 0x40000000 ? 1 : 0 )
-                               ) << 30
-                               | ( $sum & 0x3fffffff );
-                       $h ^= ord( $s[$i] );
-                       $h &= 0xffffffff;
-               }
-
-               return $h;
-       }
-}
diff --git a/includes/libs/cdb/CdbReader.php b/includes/libs/cdb/CdbReader.php
deleted file mode 100644 (file)
index 0ca9b9d..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-<?php
-/**
- * Native CDB file reader and writer.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- */
-
-/**
- * Read from a CDB file.
- * Native and pure PHP implementations are provided.
- * http://cr.yp.to/cdb.html
- */
-abstract class CdbReader {
-       /**
-        * The file handle
-        */
-       protected $handle;
-
-       /**
-        * Open a file and return a subclass instance
-        *
-        * @param string $fileName
-        *
-        * @return CdbReader
-        */
-       public static function open( $fileName ) {
-               return self::haveExtension() ?
-                       new CdbReaderDBA( $fileName ) :
-                       new CdbReaderPHP( $fileName );
-       }
-
-       /**
-        * Returns true if the native extension is available
-        *
-        * @return bool
-        */
-       public static function haveExtension() {
-               if ( !function_exists( 'dba_handlers' ) ) {
-                       return false;
-               }
-               $handlers = dba_handlers();
-               if ( !in_array( 'cdb', $handlers ) || !in_array( 'cdb_make', $handlers ) ) {
-                       return false;
-               }
-
-               return true;
-       }
-
-       /**
-        * Create the object and open the file
-        *
-        * @param string $fileName
-        */
-       abstract public function __construct( $fileName );
-
-       /**
-        * Close the file. Optional, you can just let the variable go out of scope.
-        */
-       abstract public function close();
-
-       /**
-        * Get a value with a given key. Only string values are supported.
-        *
-        * @param string $key
-        */
-       abstract public function get( $key );
-}
diff --git a/includes/libs/cdb/CdbReaderDBA.php b/includes/libs/cdb/CdbReaderDBA.php
deleted file mode 100644 (file)
index e0cab73..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-<?php
-/**
- * DBA-based CDB reader/writer
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- */
-
-/**
- * Reader class which uses the DBA extension
- */
-class CdbReaderDBA extends CdbReader {
-       public function __construct( $fileName ) {
-               $this->handle = dba_open( $fileName, 'r-', 'cdb' );
-               if ( !$this->handle ) {
-                       throw new CdbException( 'Unable to open CDB file "' . $fileName . '"' );
-               }
-       }
-
-       public function close() {
-               if ( isset( $this->handle ) ) {
-                       dba_close( $this->handle );
-               }
-               unset( $this->handle );
-       }
-
-       public function get( $key ) {
-               return dba_fetch( $key, $this->handle );
-       }
-}
diff --git a/includes/libs/cdb/CdbReaderPHP.php b/includes/libs/cdb/CdbReaderPHP.php
deleted file mode 100644 (file)
index e448414..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-<?php
-/**
- * This is a port of D.J. Bernstein's CDB to PHP. It's based on the copy that
- * appears in PHP 5.3. Changes are:
- *    * Error returns replaced with exceptions
- *    * Exception thrown if sizes or offsets are between 2GB and 4GB
- *    * Some variables renamed
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- */
-
-/**
- * CDB reader class
- */
-class CdbReaderPHP extends CdbReader {
-       /** The filename */
-       protected $fileName;
-
-       /* number of hash slots searched under this key */
-       protected $loop;
-
-       /* initialized if loop is nonzero */
-       protected $khash;
-
-       /* initialized if loop is nonzero */
-       protected $kpos;
-
-       /* initialized if loop is nonzero */
-       protected $hpos;
-
-       /* initialized if loop is nonzero */
-       protected $hslots;
-
-       /* initialized if findNext() returns true */
-       protected $dpos;
-
-       /* initialized if cdb_findnext() returns 1 */
-       protected $dlen;
-
-       /**
-        * @param string $fileName
-        * @throws CdbException
-        */
-       public function __construct( $fileName ) {
-               $this->fileName = $fileName;
-               $this->handle = fopen( $fileName, 'rb' );
-               if ( !$this->handle ) {
-                       throw new CdbException( 'Unable to open CDB file "' . $this->fileName . '".' );
-               }
-               $this->findStart();
-       }
-
-       public function close() {
-               if ( isset( $this->handle ) ) {
-                       fclose( $this->handle );
-               }
-               unset( $this->handle );
-       }
-
-       /**
-        * @param mixed $key
-        * @return bool|string
-        */
-       public function get( $key ) {
-               // strval is required
-               if ( $this->find( strval( $key ) ) ) {
-                       return $this->read( $this->dlen, $this->dpos );
-               } else {
-                       return false;
-               }
-       }
-
-       /**
-        * @param string $key
-        * @param int $pos
-        * @return bool
-        */
-       protected function match( $key, $pos ) {
-               $buf = $this->read( strlen( $key ), $pos );
-
-               return $buf === $key;
-       }
-
-       protected function findStart() {
-               $this->loop = 0;
-       }
-
-       /**
-        * @throws CdbException
-        * @param int $length
-        * @param int $pos
-        * @return string
-        */
-       protected function read( $length, $pos ) {
-               if ( fseek( $this->handle, $pos ) == -1 ) {
-                       // This can easily happen if the internal pointers are incorrect
-                       throw new CdbException(
-                               'Seek failed, file "' . $this->fileName . '" may be corrupted.' );
-               }
-
-               if ( $length == 0 ) {
-                       return '';
-               }
-
-               $buf = fread( $this->handle, $length );
-               if ( $buf === false || strlen( $buf ) !== $length ) {
-                       throw new CdbException(
-                               'Read from CDB file failed, file "' . $this->fileName . '" may be corrupted.' );
-               }
-
-               return $buf;
-       }
-
-       /**
-        * Unpack an unsigned integer and throw an exception if it needs more than 31 bits
-        * @param string $s
-        * @throws CdbException
-        * @return mixed
-        */
-       protected function unpack31( $s ) {
-               $data = unpack( 'V', $s );
-               if ( $data[1] > 0x7fffffff ) {
-                       throw new CdbException(
-                               'Error in CDB file "' . $this->fileName . '", integer too big.' );
-               }
-
-               return $data[1];
-       }
-
-       /**
-        * Unpack a 32-bit signed integer
-        * @param string $s
-        * @return int
-        */
-       protected function unpackSigned( $s ) {
-               $data = unpack( 'va/vb', $s );
-
-               return $data['a'] | ( $data['b'] << 16 );
-       }
-
-       /**
-        * @param string $key
-        * @return bool
-        */
-       protected function findNext( $key ) {
-               if ( !$this->loop ) {
-                       $u = CdbFunctions::hash( $key );
-                       $buf = $this->read( 8, ( $u << 3 ) & 2047 );
-                       $this->hslots = $this->unpack31( substr( $buf, 4 ) );
-                       if ( !$this->hslots ) {
-                               return false;
-                       }
-                       $this->hpos = $this->unpack31( substr( $buf, 0, 4 ) );
-                       $this->khash = $u;
-                       $u = CdbFunctions::unsignedShiftRight( $u, 8 );
-                       $u = CdbFunctions::unsignedMod( $u, $this->hslots );
-                       $u <<= 3;
-                       $this->kpos = $this->hpos + $u;
-               }
-
-               while ( $this->loop < $this->hslots ) {
-                       $buf = $this->read( 8, $this->kpos );
-                       $pos = $this->unpack31( substr( $buf, 4 ) );
-                       if ( !$pos ) {
-                               return false;
-                       }
-                       $this->loop += 1;
-                       $this->kpos += 8;
-                       if ( $this->kpos == $this->hpos + ( $this->hslots << 3 ) ) {
-                               $this->kpos = $this->hpos;
-                       }
-                       $u = $this->unpackSigned( substr( $buf, 0, 4 ) );
-                       if ( $u === $this->khash ) {
-                               $buf = $this->read( 8, $pos );
-                               $keyLen = $this->unpack31( substr( $buf, 0, 4 ) );
-                               if ( $keyLen == strlen( $key ) && $this->match( $key, $pos + 8 ) ) {
-                                       // Found
-                                       $this->dlen = $this->unpack31( substr( $buf, 4 ) );
-                                       $this->dpos = $pos + 8 + $keyLen;
-
-                                       return true;
-                               }
-                       }
-               }
-
-               return false;
-       }
-
-       /**
-        * @param mixed $key
-        * @return bool
-        */
-       protected function find( $key ) {
-               $this->findStart();
-
-               return $this->findNext( $key );
-       }
-}
-
diff --git a/includes/libs/cdb/CdbWriter.php b/includes/libs/cdb/CdbWriter.php
deleted file mode 100644 (file)
index b0a90c3..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-<?php
-/**
- * Native CDB file reader and writer.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- */
-
-/**
- * Write to a CDB file.
- * Native and pure PHP implementations are provided.
- * http://cr.yp.to/cdb.html
- */
-abstract class CdbWriter {
-       /**
-        * The file handle
-        */
-       protected $handle;
-
-       /**
-        * File we'll be writing to when we're done
-        * @var string
-        */
-       protected $realFileName;
-
-       /**
-        * File we write to temporarily until we're done
-        * @var string
-        */
-       protected $tmpFileName;
-
-       /**
-        * Open a writer and return a subclass instance.
-        * The user must have write access to the directory, for temporary file creation.
-        *
-        * @param string $fileName
-        *
-        * @return CdbWriterDBA|CdbWriterPHP
-        */
-       public static function open( $fileName ) {
-               return CdbReader::haveExtension() ?
-                       new CdbWriterDBA( $fileName ) :
-                       new CdbWriterPHP( $fileName );
-       }
-
-       /**
-        * Create the object and open the file
-        *
-        * @param string $fileName
-        */
-       abstract public function __construct( $fileName );
-
-       /**
-        * Set a key to a given value. The value will be converted to string.
-        * @param string $key
-        * @param string $value
-        */
-       abstract public function set( $key, $value );
-
-       /**
-        * Close the writer object. You should call this function before the object
-        * goes out of scope, to write out the final hashtables.
-        */
-       abstract public function close();
-
-       /**
-        * If the object goes out of scope, close it for sanity
-        */
-       public function __destruct() {
-               if ( isset( $this->handle ) ) {
-                       $this->close();
-               }
-       }
-
-       /**
-        * Are we running on Windows?
-        * @return bool
-        */
-       protected function isWindows() {
-               return substr( php_uname(), 0, 7 ) == 'Windows';
-       }
-}
diff --git a/includes/libs/cdb/CdbWriterDBA.php b/includes/libs/cdb/CdbWriterDBA.php
deleted file mode 100644 (file)
index 1de371d..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-<?php
-/**
- * DBA-based CDB reader/writer
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- */
-
-/**
- * Writer class which uses the DBA extension
- */
-class CdbWriterDBA extends CdbWriter {
-       public function __construct( $fileName ) {
-               $this->realFileName = $fileName;
-               $this->tmpFileName = $fileName . '.tmp.' . mt_rand( 0, 0x7fffffff );
-               $this->handle = dba_open( $this->tmpFileName, 'n', 'cdb_make' );
-               if ( !$this->handle ) {
-                       throw new CdbException( 'Unable to open CDB file for write "' . $fileName . '"' );
-               }
-       }
-
-       public function set( $key, $value ) {
-               return dba_insert( $key, $value, $this->handle );
-       }
-
-       public function close() {
-               if ( isset( $this->handle ) ) {
-                       dba_close( $this->handle );
-               }
-               if ( $this->isWindows() ) {
-                       unlink( $this->realFileName );
-               }
-               if ( !rename( $this->tmpFileName, $this->realFileName ) ) {
-                       throw new CdbException( 'Unable to move the new CDB file into place.' );
-               }
-               unset( $this->handle );
-       }
-}
diff --git a/includes/libs/cdb/CdbWriterPHP.php b/includes/libs/cdb/CdbWriterPHP.php
deleted file mode 100644 (file)
index bfc0d87..0000000
+++ /dev/null
@@ -1,234 +0,0 @@
-<?php
-/**
- * This is a port of D.J. Bernstein's CDB to PHP. It's based on the copy that
- * appears in PHP 5.3. Changes are:
- *    * Error returns replaced with exceptions
- *    * Exception thrown if sizes or offsets are between 2GB and 4GB
- *    * Some variables renamed
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- */
-
-/**
- * CDB writer class
- */
-class CdbWriterPHP extends CdbWriter {
-       protected $hplist;
-
-       protected $numentries;
-
-       protected $pos;
-
-       /**
-        * @param string $fileName
-        */
-       public function __construct( $fileName ) {
-               $this->realFileName = $fileName;
-               $this->tmpFileName = $fileName . '.tmp.' . mt_rand( 0, 0x7fffffff );
-               $this->handle = fopen( $this->tmpFileName, 'wb' );
-               if ( !$this->handle ) {
-                       $this->throwException(
-                               'Unable to open CDB file "' . $this->tmpFileName . '" for write.' );
-               }
-               $this->hplist = array();
-               $this->numentries = 0;
-               $this->pos = 2048; // leaving space for the pointer array, 256 * 8
-               if ( fseek( $this->handle, $this->pos ) == -1 ) {
-                       $this->throwException( 'fseek failed in file "' . $this->tmpFileName . '".' );
-               }
-       }
-
-       /**
-        * @param string $key
-        * @param string $value
-        */
-       public function set( $key, $value ) {
-               if ( strval( $key ) === '' ) {
-                       // DBA cross-check hack
-                       return;
-               }
-               $this->addbegin( strlen( $key ), strlen( $value ) );
-               $this->write( $key );
-               $this->write( $value );
-               $this->addend( strlen( $key ), strlen( $value ), CdbFunctions::hash( $key ) );
-       }
-
-       /**
-        * @throws CdbException
-        */
-       public function close() {
-               $this->finish();
-               if ( isset( $this->handle ) ) {
-                       fclose( $this->handle );
-               }
-               if ( $this->isWindows() && file_exists( $this->realFileName ) ) {
-                       unlink( $this->realFileName );
-               }
-               if ( !rename( $this->tmpFileName, $this->realFileName ) ) {
-                       $this->throwException( 'Unable to move the new CDB file into place.' );
-               }
-               unset( $this->handle );
-       }
-
-       /**
-        * @throws CdbException
-        * @param string $buf
-        */
-       protected function write( $buf ) {
-               $len = fwrite( $this->handle, $buf );
-               if ( $len !== strlen( $buf ) ) {
-                       $this->throwException( 'Error writing to CDB file "' . $this->tmpFileName . '".' );
-               }
-       }
-
-       /**
-        * @throws CdbException
-        * @param int $len
-        */
-       protected function posplus( $len ) {
-               $newpos = $this->pos + $len;
-               if ( $newpos > 0x7fffffff ) {
-                       $this->throwException(
-                               'A value in the CDB file "' . $this->tmpFileName . '" is too large.' );
-               }
-               $this->pos = $newpos;
-       }
-
-       /**
-        * @param int $keylen
-        * @param int $datalen
-        * @param int $h
-        */
-       protected function addend( $keylen, $datalen, $h ) {
-               $this->hplist[] = array(
-                       'h' => $h,
-                       'p' => $this->pos
-               );
-
-               $this->numentries++;
-               $this->posplus( 8 );
-               $this->posplus( $keylen );
-               $this->posplus( $datalen );
-       }
-
-       /**
-        * @throws CdbException
-        * @param int $keylen
-        * @param int $datalen
-        */
-       protected function addbegin( $keylen, $datalen ) {
-               if ( $keylen > 0x7fffffff ) {
-                       $this->throwException( 'Key length too long in file "' . $this->tmpFileName . '".' );
-               }
-               if ( $datalen > 0x7fffffff ) {
-                       $this->throwException( 'Data length too long in file "' . $this->tmpFileName . '".' );
-               }
-               $buf = pack( 'VV', $keylen, $datalen );
-               $this->write( $buf );
-       }
-
-       /**
-        * @throws CdbException
-        */
-       protected function finish() {
-               // Hack for DBA cross-check
-               $this->hplist = array_reverse( $this->hplist );
-
-               // Calculate the number of items that will be in each hashtable
-               $counts = array_fill( 0, 256, 0 );
-               foreach ( $this->hplist as $item ) {
-                       ++$counts[255 & $item['h']];
-               }
-
-               // Fill in $starts with the *end* indexes
-               $starts = array();
-               $pos = 0;
-               for ( $i = 0; $i < 256; ++$i ) {
-                       $pos += $counts[$i];
-                       $starts[$i] = $pos;
-               }
-
-               // Excessively clever and indulgent code to simultaneously fill $packedTables
-               // with the packed hashtables, and adjust the elements of $starts
-               // to actually point to the starts instead of the ends.
-               $packedTables = array_fill( 0, $this->numentries, false );
-               foreach ( $this->hplist as $item ) {
-                       $packedTables[--$starts[255 & $item['h']]] = $item;
-               }
-
-               $final = '';
-               for ( $i = 0; $i < 256; ++$i ) {
-                       $count = $counts[$i];
-
-                       // The size of the hashtable will be double the item count.
-                       // The rest of the slots will be empty.
-                       $len = $count + $count;
-                       $final .= pack( 'VV', $this->pos, $len );
-
-                       $hashtable = array();
-                       for ( $u = 0; $u < $len; ++$u ) {
-                               $hashtable[$u] = array( 'h' => 0, 'p' => 0 );
-                       }
-
-                       // Fill the hashtable, using the next empty slot if the hashed slot
-                       // is taken.
-                       for ( $u = 0; $u < $count; ++$u ) {
-                               $hp = $packedTables[$starts[$i] + $u];
-                               $where = CdbFunctions::unsignedMod(
-                                       CdbFunctions::unsignedShiftRight( $hp['h'], 8 ), $len );
-                               while ( $hashtable[$where]['p'] ) {
-                                       if ( ++$where == $len ) {
-                                               $where = 0;
-                                       }
-                               }
-                               $hashtable[$where] = $hp;
-                       }
-
-                       // Write the hashtable
-                       for ( $u = 0; $u < $len; ++$u ) {
-                               $buf = pack( 'vvV',
-                                       $hashtable[$u]['h'] & 0xffff,
-                                       CdbFunctions::unsignedShiftRight( $hashtable[$u]['h'], 16 ),
-                                       $hashtable[$u]['p'] );
-                               $this->write( $buf );
-                               $this->posplus( 8 );
-                       }
-               }
-
-               // Write the pointer array at the start of the file
-               rewind( $this->handle );
-               if ( ftell( $this->handle ) != 0 ) {
-                       $this->throwException( 'Error rewinding to start of file "' . $this->tmpFileName . '".' );
-               }
-               $this->write( $final );
-       }
-
-       /**
-        * Clean up the temp file and throw an exception
-        *
-        * @param string $msg
-        * @throws CdbException
-        */
-       protected function throwException( $msg ) {
-               if ( $this->handle ) {
-                       fclose( $this->handle );
-                       unlink( $this->tmpFileName );
-               }
-               throw new CdbException( $msg );
-       }
-}
index e81b37d..0292af8 100644 (file)
@@ -142,7 +142,7 @@ class BitmapHandler extends TransformationalImageHandler {
                        $env['MAGICK_TMPDIR'] = $wgImageMagickTempDir;
                }
 
-               $rotation = $this->getRotation( $image );
+               $rotation = isset( $params['disableRotation'] ) ? 0 : $this->getRotation( $image );
                list( $width, $height ) = $this->extractPreRotationDimensions( $params, $rotation );
 
                $cmd = call_user_func_array( 'wfEscapeShellArg', array_merge(
@@ -223,7 +223,7 @@ class BitmapHandler extends TransformationalImageHandler {
                                }
                        }
 
-                       $rotation = $this->getRotation( $image );
+                       $rotation = isset( $params['disableRotation'] ) ? 0 : $this->getRotation( $image );
                        list( $width, $height ) = $this->extractPreRotationDimensions( $params, $rotation );
 
                        $im->setImageBackgroundColor( new ImagickPixel( 'white' ) );
@@ -344,7 +344,7 @@ class BitmapHandler extends TransformationalImageHandler {
 
                $src_image = call_user_func( $loader, $params['srcPath'] );
 
-               $rotation = function_exists( 'imagerotate' ) ? $this->getRotation( $image ) : 0;
+               $rotation = function_exists( 'imagerotate' ) && !isset( $params['disableRotation'] )  ? $this->getRotation( $image ) : 0;
                list( $width, $height ) = $this->extractPreRotationDimensions( $params, $rotation );
                $dst_image = imagecreatetruecolor( $width, $height );
 
index 3e3be3d..b3ae296 100644 (file)
@@ -216,6 +216,12 @@ abstract class TransformationalImageHandler extends ImageHandler {
                # Transform functions and binaries need a FS source file
                $thumbnailSource = $this->getThumbnailSource( $image, $params );
 
+               // If the source isn't the original, disable EXIF rotation because it's already been applied
+               if ( $scalerParams['srcWidth'] != $thumbnailSource['width']
+                       || $scalerParams['srcHeight'] != $thumbnailSource['height'] ) {
+                       $scalerParams['disableRotation'] = true;
+               }
+
                $scalerParams['srcPath'] = $thumbnailSource['path'];
                $scalerParams['srcWidth'] = $thumbnailSource['width'];
                $scalerParams['srcHeight'] = $thumbnailSource['height'];
index 14aad1a..07eb340 100644 (file)
@@ -536,9 +536,9 @@ class Parser {
                        uasort( $dataByFunc, function( $a, $b ) {
                                return $a['real'] < $b['real']; // descending order
                        } );
-                       $profileReport = "Top template expansion time report (%,ms,calls,template)\n";
+                       $profileReport = "Transclusion expansion time report (%,ms,calls,template)\n";
                        foreach ( array_slice( $dataByFunc, 0, 10 ) as $item ) {
-                               $profileReport .= sprintf( "%6.2f%% %3.6f %6d - %s\n",
+                               $profileReport .= sprintf( "%6.2f%% %8.3f %6d - %s\n",
                                        $item['%real'], $item['real'], $item['calls'],
                                        htmlspecialchars($item['name'] ) );
                        }
index 5e7e391..da20f94 100644 (file)
@@ -67,7 +67,8 @@ class PoolWorkArticleView extends PoolCounterWork {
                $this->parserOptions = $parserOptions;
                $this->content = $content;
                $this->cacheKey = ParserCache::singleton()->getKey( $page, $parserOptions );
-               parent::__construct( 'ArticleView', $this->cacheKey . ':revid:' . $revid );
+               $keyPrefix = $this->cacheKey ?: wfMemcKey( 'articleview', 'missingcachekey' );
+               parent::__construct( 'ArticleView', $keyPrefix . ':revid:' . $revid );
        }
 
        /**
index 9379379..d67806b 100644 (file)
@@ -109,10 +109,6 @@ class ProfilerXhprof extends Profiler {
         * @param string $functionname
         */
        public function profileIn( $functionname ) {
-               global $wgDebugFunctionEntry;
-               if ( $wgDebugFunctionEntry ) {
-                       $this->debug( "Entering {$functionname}" );
-               }
        }
 
        /**
@@ -124,10 +120,6 @@ class ProfilerXhprof extends Profiler {
         * @param string $functionname
         */
        public function profileOut( $functionname ) {
-               global $wgDebugFunctionEntry;
-               if ( $wgDebugFunctionEntry ) {
-                       $this->debug( "Exiting {$functionname}" );
-               }
        }
 
        /**
index 2d8a689..89eebbe 100644 (file)
 /**
  * Custom PHP profiler for parser/DB type section names that xhprof/xdebug can't handle
  *
- * @TODO: refactor implementation by moving Profiler code to here when non-automatic
- * profiler support is dropped.
- *
  * @since 1.25
  */
 class SectionProfiler {
-       /** @var ProfilerStandard */
-       protected $profiler;
+       /** @var array List of resolved profile calls with start/end data */
+       protected $stack = array();
+       /** @var array Queue of open profile calls with start data */
+       protected $workStack = array();
+
+       /** @var array Map of (function name => aggregate data array) */
+       protected $collated = array();
+       /** @var bool */
+       protected $collateDone = false;
+       /** @var bool Whether to collect the full stack trace or just aggregates */
+       protected $collateOnly = true;
 
-       public function __construct() {
-               // This does *not* care about PHP request start time
-               $this->profiler = new ProfilerStandard( array( 'initTotal' => false ) );
+       /** @var array Cache of a standard broken collation entry */
+       protected $errorEntry;
+
+       /**
+        * @param array $params
+        */
+       public function __construct( array $params = array() ) {
+               $this->errorEntry = $this->getErrorEntry();
+               $this->collateOnly = empty( $params['trace'] );
        }
 
        /**
@@ -44,13 +56,12 @@ class SectionProfiler {
         * @return ScopedCallback
         */
        public function scopedProfileIn( $section ) {
-               $profiler = $this->profiler;
-               $sc = new ScopedCallback( function() use ( $profiler, $section ) {
-                       $profiler->profileOut( $section );
-               } );
-               $profiler->profileIn( $section );
+               $this->profileInInternal( $section );
 
-               return $sc;
+               $that = $this;
+               return new ScopedCallback( function() use ( $that, $section ) {
+                       $that->profileOutInternal( $section );
+               } );
        }
 
        /**
@@ -80,33 +91,365 @@ class SectionProfiler {
         *   - %memory : percent memory used
         */
        public function getFunctionStats() {
-               $data = $this->profiler->getFunctionStats();
+               $this->collateData();
 
-               $cpuTotal = 0;
-               $memoryTotal = 0;
-               $elapsedTotal = 0;
-               foreach ( $data as $item ) {
-                       $memoryTotal += $item['memory'];
-                       $elapsedTotal += $item['real'];
-                       $cpuTotal += $item['cpu'];
+               $totalCpu = 0.0;
+               $totalReal = 0.0;
+               $totalMem = 0;
+               foreach ( $this->collated as $fname => $data ) {
+                       $totalCpu += $data['cpu'];
+                       $totalReal += $data['real'];
+                       $totalMem += $data['memory'];
                }
 
-               foreach ( $data as &$item ) {
-                       $item['%cpu'] = $item['cpu'] ? $item['cpu'] / $cpuTotal * 100 : 0;
-                       $item['%real'] = $elapsedTotal ? $item['real'] / $elapsedTotal * 100 : 0;
-                       $item['%memory'] = $item['memory'] ? $item['memory'] / $memoryTotal * 100 : 0;
+               $profile = array();
+               foreach ( $this->collated as $fname => $data ) {
+                       $profile[] = array(
+                               'name' => $fname,
+                               'calls' => $data['count'],
+                               'real' => $data['real'] * 1000,
+                               '%real' => $totalReal ? 100 * $data['real'] / $totalReal : 0,
+                               'cpu' => $data['cpu'] * 1000,
+                               '%cpu' => $totalCpu ? 100 * $data['cpu'] / $totalCpu : 0,
+                               'memory' => $data['memory'],
+                               '%memory' => $totalMem ? 100 * $data['memory'] / $totalMem : 0,
+                       );
                }
-               unset( $item );
 
-               $data[] = array(
+               $profile[] = array(
                        'name' => '-total',
                        'calls' => 1,
-                       'real' => $elapsedTotal,
+                       'real' => 1000 * $totalReal,
                        '%real' => 100,
-                       'memory' => $memoryTotal,
+                       'cpu' => 1000 * $totalCpu,
+                       '%cpu' => 100,
+                       'memory' => $totalMem,
                        '%memory' => 100,
                );
 
-               return $data;
+               return $profile;
+       }
+
+       /**
+        * @return array Initial collation entry
+        */
+       protected function getZeroEntry() {
+               return array(
+                       'cpu'      => 0.0,
+                       'real'     => 0.0,
+                       'memory'   => 0,
+                       'count'    => 0
+               );
+       }
+
+       /**
+        * @return array Initial collation entry for errors
+        */
+       protected function getErrorEntry() {
+               $entry = $this->getZeroEntry();
+               $entry['count'] = 1;
+               return $entry;
+       }
+
+       /**
+        * Update the collation entry for a given method name
+        *
+        * @param string $name
+        * @param float $elapsedCpu
+        * @param float $elapsedReal
+        * @param int $memChange
+        */
+       protected function updateEntry( $name, $elapsedCpu, $elapsedReal, $memChange ) {
+               $entry =& $this->collated[$name];
+               if ( !is_array( $entry ) ) {
+                       $entry = $this->getZeroEntry();
+                       $this->collated[$name] =& $entry;
+               }
+               $entry['cpu'] += $elapsedCpu;
+               $entry['real'] += $elapsedReal;
+               $entry['memory'] += $memChange > 0 ? $memChange : 0;
+               $entry['count']++;
+       }
+
+       /**
+        * This method should not be called outside SectionProfiler
+        *
+        * @param string $functionname
+        */
+       public function profileInInternal( $functionname ) {
+               $this->workStack[] = array(
+                       $functionname,
+                       count( $this->workStack ),
+                       $this->getTime( 'time' ),
+                       $this->getTime( 'cpu' ),
+                       memory_get_usage()
+               );
+       }
+
+       /**
+        * This method should not be called outside SectionProfiler
+        *
+        * @param string $functionname
+        */
+       public function profileOutInternal( $functionname ) {
+               $item = array_pop( $this->workStack );
+               if ( $item === null ) {
+                       $this->debugGroup( 'profileerror', "Profiling error: $functionname" );
+                       return;
+               }
+               list( $ofname, /* $ocount */, $ortime, $octime, $omem ) = $item;
+
+               if ( $functionname === 'close' ) {
+                       $message = "Profile section ended by close(): {$ofname}";
+                       $this->debugGroup( 'profileerror', $message );
+                       if ( $this->collateOnly ) {
+                               $this->collated[$message] = $this->errorEntry;
+                       } else {
+                               $this->stack[] = array( $message, 0, 0.0, 0.0, 0, 0.0, 0.0, 0 );
+                       }
+                       $functionname = $ofname;
+               } elseif ( $ofname !== $functionname ) {
+                       $message = "Profiling error: in({$ofname}), out($functionname)";
+                       $this->debugGroup( 'profileerror', $message );
+                       if ( $this->collateOnly ) {
+                               $this->collated[$message] = $this->errorEntry;
+                       } else {
+                               $this->stack[] = array( $message, 0, 0.0, 0.0, 0, 0.0, 0.0, 0 );
+                       }
+               }
+               $realTime = $this->getTime( 'wall' );
+               $cpuTime = $this->getTime( 'cpu' );
+               if ( $this->collateOnly ) {
+                       $elapsedcpu = $cpuTime - $octime;
+                       $elapsedreal = $realTime - $ortime;
+                       $memchange = memory_get_usage() - $omem;
+                       $this->updateEntry( $functionname, $elapsedcpu, $elapsedreal, $memchange );
+               } else {
+                       $this->stack[] = array_merge( $item,
+                               array( $realTime, $cpuTime,     memory_get_usage() ) );
+               }
+       }
+
+       /**
+        * Returns a tree of function calls with their real times
+        * @return string
+        */
+       public function getCallTreeReport() {
+               if ( $this->collateOnly ) {
+                       throw new Exception( "Tree is only available for trace profiling." );
+               }
+               return implode( '', array_map(
+                       array( $this, 'getCallTreeLine' ), $this->remapCallTree( $this->stack )
+               ) );
+       }
+
+       /**
+        * Recursive function the format the current profiling array into a tree
+        *
+        * @param array $stack Profiling array
+        * @return array
+        */
+       protected function remapCallTree( array $stack ) {
+               if ( count( $stack ) < 2 ) {
+                       return $stack;
+               }
+               $outputs = array();
+               for ( $max = count( $stack ) - 1; $max > 0; ) {
+                       /* Find all items under this entry */
+                       $level = $stack[$max][1];
+                       $working = array();
+                       for ( $i = $max -1; $i >= 0; $i-- ) {
+                               if ( $stack[$i][1] > $level ) {
+                                       $working[] = $stack[$i];
+                               } else {
+                                       break;
+                               }
+                       }
+                       $working = $this->remapCallTree( array_reverse( $working ) );
+                       $output = array();
+                       foreach ( $working as $item ) {
+                               array_push( $output, $item );
+                       }
+                       array_unshift( $output, $stack[$max] );
+                       $max = $i;
+
+                       array_unshift( $outputs, $output );
+               }
+               $final = array();
+               foreach ( $outputs as $output ) {
+                       foreach ( $output as $item ) {
+                               $final[] = $item;
+                       }
+               }
+               return $final;
+       }
+
+       /**
+        * Callback to get a formatted line for the call tree
+        * @param array $entry
+        * @return string
+        */
+       protected function getCallTreeLine( $entry ) {
+               // $entry has (name, level, stime, scpu, smem, etime, ecpu, emem)
+               list( $fname, $level, $startreal, , , $endreal ) = $entry;
+               $delta = $endreal - $startreal;
+               $space = str_repeat( ' ', $level );
+               # The ugly double sprintf is to work around a PHP bug,
+               # which has been fixed in recent releases.
+               return sprintf( "%10s %s %s\n",
+                       trim( sprintf( "%7.3f", $delta * 1000.0 ) ), $space, $fname );
+       }
+
+       /**
+        * Populate collated data
+        */
+       protected function collateData() {
+               if ( $this->collateDone ) {
+                       return;
+               }
+               $this->collateDone = true;
+               // Close opened profiling sections
+               while ( count( $this->workStack ) ) {
+                       $this->profileOutInternal( 'close' );
+               }
+
+               if ( $this->collateOnly ) {
+                       return; // already collated as methods exited
+               }
+
+               $this->collated = array();
+
+               # Estimate profiling overhead
+               $profileCount = count( $this->stack );
+               $this->calculateOverhead( $profileCount );
+
+               # First, subtract the overhead!
+               $overheadTotal = $overheadMemory = $overheadInternal = array();
+               foreach ( $this->stack as $entry ) {
+                       // $entry is (name,pos,rtime0,cputime0,mem0,rtime1,cputime1,mem1)
+                       $fname = $entry[0];
+                       $elapsed = $entry[5] - $entry[2];
+                       $memchange = $entry[7] - $entry[4];
+
+                       if ( $fname === '-overhead-total' ) {
+                               $overheadTotal[] = $elapsed;
+                               $overheadMemory[] = max( 0, $memchange );
+                       } elseif ( $fname === '-overhead-internal' ) {
+                               $overheadInternal[] = $elapsed;
+                       }
+               }
+               $overheadTotal = $overheadTotal ?
+                       array_sum( $overheadTotal ) / count( $overheadInternal ) : 0;
+               $overheadMemory = $overheadMemory ?
+                       array_sum( $overheadMemory ) / count( $overheadInternal ) : 0;
+               $overheadInternal = $overheadInternal ?
+                       array_sum( $overheadInternal ) / count( $overheadInternal ) : 0;
+
+               # Collate
+               foreach ( $this->stack as $index => $entry ) {
+                       // $entry is (name,pos,rtime0,cputime0,mem0,rtime1,cputime1,mem1)
+                       $fname = $entry[0];
+                       $elapsedCpu = $entry[6] - $entry[3];
+                       $elapsedReal = $entry[5] - $entry[2];
+                       $memchange = $entry[7] - $entry[4];
+                       $subcalls = $this->calltreeCount( $this->stack, $index );
+
+                       if ( substr( $fname, 0, 9 ) !== '-overhead' ) {
+                               # Adjust for profiling overhead (except special values with elapsed=0
+                               if ( $elapsed ) {
+                                       $elapsed -= $overheadInternal;
+                                       $elapsed -= ( $subcalls * $overheadTotal );
+                                       $memchange -= ( $subcalls * $overheadMemory );
+                               }
+                       }
+
+                       $this->updateEntry( $fname, $elapsedCpu, $elapsedReal, $memchange );
+               }
+
+               $this->collated['-overhead-total']['count'] = $profileCount;
+               arsort( $this->collated, SORT_NUMERIC );
+       }
+
+       /**
+        * Dummy calls to calculate profiling overhead
+        *
+        * @param int $profileCount
+        */
+       protected function calculateOverhead( $profileCount ) {
+               $this->profileInInternal( '-overhead-total' );
+               for ( $i = 0; $i < $profileCount; $i++ ) {
+                       $this->profileInInternal( '-overhead-internal' );
+                       $this->profileOutInternal( '-overhead-internal' );
+               }
+               $this->profileOutInternal( '-overhead-total' );
+       }
+
+       /**
+        * Counts the number of profiled function calls sitting under
+        * the given point in the call graph. Not the most efficient algo.
+        *
+        * @param array $stack
+        * @param int $start
+        * @return int
+        */
+       protected function calltreeCount( $stack, $start ) {
+               $level = $stack[$start][1];
+               $count = 0;
+               for ( $i = $start -1; $i >= 0 && $stack[$i][1] > $level; $i-- ) {
+                       $count ++;
+               }
+               return $count;
+       }
+
+       /**
+        * Get the initial time of the request, based either on $wgRequestTime or
+        * $wgRUstart. Will return null if not able to find data.
+        *
+        * @param string|bool $metric Metric to use, with the following possibilities:
+        *   - user: User CPU time (without system calls)
+        *   - cpu: Total CPU time (user and system calls)
+        *   - wall (or any other string): elapsed time
+        *   - false (default): will fall back to default metric
+        * @return float|null
+        */
+       protected function getTime( $metric = 'wall' ) {
+               if ( $metric === 'cpu' || $metric === 'user' ) {
+                       $ru = wfGetRusage();
+                       if ( !$ru ) {
+                               return 0;
+                       }
+                       $time = $ru['ru_utime.tv_sec'] + $ru['ru_utime.tv_usec'] / 1e6;
+                       if ( $metric === 'cpu' ) {
+                               # This is the time of system calls, added to the user time
+                               # it gives the total CPU time
+                               $time += $ru['ru_stime.tv_sec'] + $ru['ru_stime.tv_usec'] / 1e6;
+                       }
+                       return $time;
+               } else {
+                       return microtime( true );
+               }
+       }
+
+       /**
+        * Add an entry in the debug log file
+        *
+        * @param string $s String to output
+        */
+       protected function debug( $s ) {
+               if ( function_exists( 'wfDebug' ) ) {
+                       wfDebug( $s );
+               }
+       }
+
+       /**
+        * Add an entry in the debug log group
+        *
+        * @param string $group Group to send the message to
+        * @param string $s String to output
+        */
+       protected function debugGroup( $group, $s ) {
+               if ( function_exists( 'wfDebugLog' ) ) {
+                       wfDebugLog( $group, $s );
+               }
        }
 }
index 8952947..98efd27 100644 (file)
@@ -150,6 +150,14 @@ class AutoloadGenerator {
                // sort for stable output
                ksort( $content );
 
+               // extensions using this generator are appending to the existing
+               // autoload.
+               if ( $this->variableName === 'wgAutoloadClasses' ) {
+                       $op = '+=';
+               } else {
+                       $op = '=';
+               }
+
                $output = implode( "\n\t", $content );
                file_put_contents(
                        $this->basepath . '/autoload.php',
@@ -159,7 +167,7 @@ class AutoloadGenerator {
 
 global \${$this->variableName};
 
-\${$this->variableName} = array(
+\${$this->variableName} {$op} array(
        {$output}
 );
 
index f5141f6..0589009 100644 (file)
@@ -1,4 +1,4 @@
-# Doxyfile 1.7.6.1
+# Doxyfile 1.8.6
 
 # This file describes the settings to be used by the documentation system
 # doxygen (www.doxygen.org) for MediaWiki.
@@ -47,31 +47,33 @@ MULTILINE_CPP_IS_BRIEF = NO
 INHERIT_DOCS           = YES
 SEPARATE_MEMBER_PAGES  = NO
 TAB_SIZE               = 4
-ALIASES =      "type{1}=<b> \1 </b>:" \
-               "types{2}=<b> \1 </b> or <b> \2 </b>:" \
-               "types{3}=<b> \1 </b>, <b> \2 </b>, or <b> \3 </b>:" \
-               "arrayof{2}=<b> Array </b> of \2" \
-               "null=\type{Null}" \
-               "boolean=\type{Boolean}" \
-               "bool=\type{Boolean}" \
-               "integer=\type{Integer}" \
-               "int=\type{Integer}" \
-               "string=\type{String}" \
-               "str=\type{String}" \
-               "mixed=\type{Mixed}" \
-               "access=\par Access:\n" \
-               "private=\access private" \
-               "protected=\access protected" \
-               "public=\access public" \
-               "copyright=\note" \
-               "license=\note" \
-               "codeCoverageIgnore="
+ALIASES                = "type{1}=<b> \1 </b>:" \
+                         "types{2}=<b> \1 </b> or <b> \2 </b>:" \
+                         "types{3}=<b> \1 </b>, <b> \2 </b>, or <b> \3 </b>:" \
+                         "arrayof{2}=<b> Array </b> of \2" \
+                         "null=\type{Null}" \
+                         "boolean=\type{Boolean}" \
+                         "bool=\type{Boolean}" \
+                         "integer=\type{Integer}" \
+                         "int=\type{Integer}" \
+                         "string=\type{String}" \
+                         "str=\type{String}" \
+                         "mixed=\type{Mixed}" \
+                         "access=\par Access:\n" \
+                         "private=\access private" \
+                         "protected=\access protected" \
+                         "public=\access public" \
+                         "copyright=\note" \
+                         "license=\note" \
+                         "codeCoverageIgnore="
 TCL_SUBST              =
 OPTIMIZE_OUTPUT_FOR_C  = NO
 OPTIMIZE_OUTPUT_JAVA   = NO
 OPTIMIZE_FOR_FORTRAN   = NO
 OPTIMIZE_OUTPUT_VHDL   = NO
 EXTENSION_MAPPING      =
+MARKDOWN_SUPPORT       = YES
+AUTOLINK_SUPPORT       = YES
 BUILTIN_STL_SUPPORT    = NO
 CPP_CLI_SUPPORT        = NO
 SIP_SUPPORT            = NO
@@ -81,13 +83,13 @@ SUBGROUPING            = YES
 INLINE_GROUPED_CLASSES = NO
 INLINE_SIMPLE_STRUCTS  = NO
 TYPEDEF_HIDES_STRUCT   = NO
-SYMBOL_CACHE_SIZE      = 0
 LOOKUP_CACHE_SIZE      = 2
 #---------------------------------------------------------------------------
 # Build related configuration options
 #---------------------------------------------------------------------------
 EXTRACT_ALL            = YES
 EXTRACT_PRIVATE        = YES
+EXTRACT_PACKAGE        = NO
 EXTRACT_STATIC         = YES
 EXTRACT_LOCAL_CLASSES  = YES
 EXTRACT_LOCAL_METHODS  = NO
@@ -100,6 +102,7 @@ INTERNAL_DOCS          = NO
 CASE_SENSE_NAMES       = YES
 HIDE_SCOPE_NAMES       = NO
 SHOW_INCLUDE_FILES     = YES
+SHOW_GROUPED_MEMB_INC  = NO
 FORCE_LOCAL_INCLUDES   = NO
 INLINE_INFO            = YES
 SORT_MEMBER_DOCS       = YES
@@ -115,14 +118,13 @@ GENERATE_DEPRECATEDLIST= YES
 ENABLED_SECTIONS       =
 MAX_INITIALIZER_LINES  = 30
 SHOW_USED_FILES        = YES
-SHOW_DIRECTORIES       = YES
 SHOW_FILES             = YES
 SHOW_NAMESPACES        = NO
 FILE_VERSION_FILTER    =
 LAYOUT_FILE            =
 CITE_BIB_FILES         =
 #---------------------------------------------------------------------------
-# configuration options related to warning and progress messages
+# Configuration options related to warning and progress messages
 #---------------------------------------------------------------------------
 QUIET                  = NO
 WARNINGS               = YES
@@ -132,7 +134,7 @@ WARN_NO_PARAMDOC       = NO
 WARN_FORMAT            = "$file:$line: $text"
 WARN_LOGFILE           =
 #---------------------------------------------------------------------------
-# configuration options related to the input files
+# Configuration options related to the input files
 #---------------------------------------------------------------------------
 INPUT                  = {{INPUT}}
 INPUT_ENCODING         = UTF-8
@@ -182,7 +184,12 @@ FILE_PATTERNS          = *.c \
 RECURSIVE              = YES
 EXCLUDE                = {{EXCLUDE}}
 EXCLUDE_SYMLINKS       = YES
-EXCLUDE_PATTERNS       = LocalSettings.php AdminSettings.php StartProfiler.php .svn */.git/* {{EXCLUDE_PATTERNS}}
+EXCLUDE_PATTERNS       = LocalSettings.php \
+                         AdminSettings.php \
+                         StartProfiler.php \
+                         .svn \
+                         */.git/* \
+                         {{EXCLUDE_PATTERNS}}
 EXCLUDE_SYMBOLS        =
 EXAMPLE_PATH           =
 EXAMPLE_PATTERNS       = *
@@ -192,8 +199,9 @@ INPUT_FILTER           = "{{INPUT_FILTER}}"
 FILTER_PATTERNS        =
 FILTER_SOURCE_FILES    = NO
 FILTER_SOURCE_PATTERNS =
+USE_MDFILE_AS_MAINPAGE =
 #---------------------------------------------------------------------------
-# configuration options related to source browsing
+# Configuration options related to source browsing
 #---------------------------------------------------------------------------
 SOURCE_BROWSER         = YES
 INLINE_SOURCES         = NO
@@ -201,16 +209,17 @@ STRIP_CODE_COMMENTS    = YES
 REFERENCED_BY_RELATION = YES
 REFERENCES_RELATION    = YES
 REFERENCES_LINK_SOURCE = YES
+SOURCE_TOOLTIPS        = YES
 USE_HTAGS              = NO
 VERBATIM_HEADERS       = YES
 #---------------------------------------------------------------------------
-# configuration options related to the alphabetical class index
+# Configuration options related to the alphabetical class index
 #---------------------------------------------------------------------------
 ALPHABETICAL_INDEX     = NO
 COLS_IN_ALPHA_INDEX    = 5
 IGNORE_PREFIX          =
 #---------------------------------------------------------------------------
-# configuration options related to the HTML output
+# Configuration options related to the HTML output
 #---------------------------------------------------------------------------
 GENERATE_HTML          = YES
 HTML_OUTPUT            = html
@@ -218,13 +227,14 @@ HTML_FILE_EXTENSION    = .html
 HTML_HEADER            =
 HTML_FOOTER            =
 HTML_STYLESHEET        =
+HTML_EXTRA_STYLESHEET  =
 HTML_EXTRA_FILES       =
 HTML_COLORSTYLE_HUE    = 220
 HTML_COLORSTYLE_SAT    = 100
 HTML_COLORSTYLE_GAMMA  = 80
 HTML_TIMESTAMP         = YES
-HTML_ALIGN_MEMBERS     = YES
 HTML_DYNAMIC_SECTIONS  = NO
+HTML_INDEX_NUM_ENTRIES = 100
 GENERATE_DOCSET        = NO
 DOCSET_FEEDNAME        = "Doxygen generated docs"
 DOCSET_BUNDLE_ID       = org.doxygen.Project
@@ -248,20 +258,26 @@ QHG_LOCATION           =
 GENERATE_ECLIPSEHELP   = NO
 ECLIPSE_DOC_ID         = org.doxygen.Project
 DISABLE_INDEX          = NO
-ENUM_VALUES_PER_LINE   = 4
 GENERATE_TREEVIEW      = YES
-USE_INLINE_TREES       = YES
+ENUM_VALUES_PER_LINE   = 4
 TREEVIEW_WIDTH         = 250
 EXT_LINKS_IN_WINDOW    = NO
 FORMULA_FONTSIZE       = 10
 FORMULA_TRANSPARENT    = YES
 USE_MATHJAX            = NO
+MATHJAX_FORMAT         = HTML-CSS
 MATHJAX_RELPATH        = http://www.mathjax.org/mathjax
 MATHJAX_EXTENSIONS     =
+MATHJAX_CODEFILE       =
 SEARCHENGINE           = YES
 SERVER_BASED_SEARCH    = YES
+EXTERNAL_SEARCH        = NO
+SEARCHENGINE_URL       =
+SEARCHDATA_FILE        = searchdata.xml
+EXTERNAL_SEARCH_ID     =
+EXTRA_SEARCH_MAPPINGS  =
 #---------------------------------------------------------------------------
-# configuration options related to the LaTeX output
+# Configuration options related to the LaTeX output
 #---------------------------------------------------------------------------
 GENERATE_LATEX         = NO
 LATEX_OUTPUT           = latex
@@ -272,6 +288,7 @@ PAPER_TYPE             = a4wide
 EXTRA_PACKAGES         =
 LATEX_HEADER           =
 LATEX_FOOTER           =
+LATEX_EXTRA_FILES      =
 PDF_HYPERLINKS         = YES
 USE_PDFLATEX           = YES
 LATEX_BATCHMODE        = NO
@@ -279,7 +296,7 @@ LATEX_HIDE_INDICES     = NO
 LATEX_SOURCE_CODE      = NO
 LATEX_BIB_STYLE        = plain
 #---------------------------------------------------------------------------
-# configuration options related to the RTF output
+# Configuration options related to the RTF output
 #---------------------------------------------------------------------------
 GENERATE_RTF           = NO
 RTF_OUTPUT             = rtf
@@ -288,14 +305,14 @@ RTF_HYPERLINKS         = NO
 RTF_STYLESHEET_FILE    =
 RTF_EXTENSIONS_FILE    =
 #---------------------------------------------------------------------------
-# configuration options related to the man page output
+# Configuration options related to the man page output
 #---------------------------------------------------------------------------
 GENERATE_MAN           = {{GENERATE_MAN}}
 MAN_OUTPUT             = man
 MAN_EXTENSION          = .3
 MAN_LINKS              = NO
 #---------------------------------------------------------------------------
-# configuration options related to the XML output
+# Configuration options related to the XML output
 #---------------------------------------------------------------------------
 GENERATE_XML           = NO
 XML_OUTPUT             = xml
@@ -303,11 +320,16 @@ XML_SCHEMA             =
 XML_DTD                =
 XML_PROGRAMLISTING     = YES
 #---------------------------------------------------------------------------
-# configuration options for the AutoGen Definitions output
+# Configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+GENERATE_DOCBOOK       = NO
+DOCBOOK_OUTPUT         = docbook
+#---------------------------------------------------------------------------
+# Configuration options for the AutoGen Definitions output
 #---------------------------------------------------------------------------
 GENERATE_AUTOGEN_DEF   = NO
 #---------------------------------------------------------------------------
-# configuration options related to the Perl module output
+# Configuration options related to the Perl module output
 #---------------------------------------------------------------------------
 GENERATE_PERLMOD       = NO
 PERLMOD_LATEX          = NO
@@ -326,18 +348,20 @@ PREDEFINED             =
 EXPAND_AS_DEFINED      =
 SKIP_FUNCTION_MACROS   = YES
 #---------------------------------------------------------------------------
-# Configuration::additions related to external references
+# Configuration options related to external references
 #---------------------------------------------------------------------------
 TAGFILES               =
 GENERATE_TAGFILE       = {{OUTPUT_DIRECTORY}}/html/tagfile.xml
 ALLEXTERNALS           = NO
 EXTERNAL_GROUPS        = YES
+EXTERNAL_PAGES         = YES
 PERL_PATH              = /usr/bin/perl
 #---------------------------------------------------------------------------
 # Configuration options related to the dot tool
 #---------------------------------------------------------------------------
 CLASS_DIAGRAMS         = NO
 MSCGEN_PATH            =
+DIA_PATH               =
 HIDE_UNDOC_RELATIONS   = YES
 HAVE_DOT               = {{HAVE_DOT}}
 DOT_NUM_THREADS        = 0
@@ -348,6 +372,7 @@ CLASS_GRAPH            = YES
 COLLABORATION_GRAPH    = YES
 GROUP_GRAPHS           = YES
 UML_LOOK               = NO
+UML_LIMIT_NUM_FIELDS   = 10
 TEMPLATE_RELATIONS     = NO
 INCLUDE_GRAPH          = YES
 INCLUDED_BY_GRAPH      = YES
@@ -360,10 +385,10 @@ INTERACTIVE_SVG        = NO
 DOT_PATH               =
 DOTFILE_DIRS           =
 MSCFILE_DIRS           =
+DIAFILE_DIRS           =
 DOT_GRAPH_MAX_NODES    = 50
 MAX_DOT_GRAPH_DEPTH    = 1000
 DOT_TRANSPARENT        = NO
 DOT_MULTI_TARGETS      = YES
 GENERATE_LEGEND        = YES
 DOT_CLEANUP            = YES
-
index 86c686b..2e252ad 100644 (file)
@@ -21,6 +21,8 @@
  * @todo document
  * @ingroup Maintenance
  */
+use \Cdb\Exception as CdbException;
+use \Cdb\Reader as CdbReader;
 
 /** */
 require_once __DIR__ . '/commandLine.inc';
index 246cc81..36eb9d4 100644 (file)
@@ -7,7 +7,7 @@
                // it works only comparing to window.self or window.window (http://stackoverflow.com/q/4850978/319266)
                if ( window.top !== window.self ) {
                        // Un-trap us from framesets
-                       window.top.location = window.location;
+                       window.top.location.href = location.href;
                }
        }
 
index d3e8f29..3dd65fb 100644 (file)
@@ -25,7 +25,7 @@
                        // Bind onchange event handler and append to form
                        $html.append(
                                $( select ).change( function () {
-                                       window.location = QUnit.url( { useskin: $( this ).val() } );
+                                       location.href = QUnit.url( { useskin: $( this ).val() } );
                                } )
                        );
 
index 1f6429b..043d769 100644 (file)
@@ -57,7 +57,7 @@ jQuery( function ( $ ) {
                // therefore save and restore scrollTop to prevent jumping.
                scrollTop = $( window ).scrollTop();
                if ( mode !== 'noHash' ) {
-                       window.location.hash = '#mw-prefsection-' + name;
+                       location.hash = '#mw-prefsection-' + name;
                }
                $( window ).scrollTop( scrollTop );
 
@@ -127,7 +127,7 @@ jQuery( function ( $ ) {
 
        // If we've reloaded the page or followed an open-in-new-window,
        // make the selected tab visible.
-       hash = window.location.hash;
+       hash = location.hash;
        if ( hash.match( /^#mw-prefsection-[\w\-]+/ ) ) {
                switchPrefTab( hash.replace( '#mw-prefsection-', '' ) );
        }
@@ -142,7 +142,7 @@ jQuery( function ( $ ) {
                ( document.documentMode === undefined || document.documentMode >= 8 )
        ) {
                $( window ).on( 'hashchange', function () {
-                       var hash = window.location.hash;
+                       var hash = location.hash;
                        if ( hash.match( /^#mw-prefsection-[\w\-]+/ ) ) {
                                switchPrefTab( hash.replace( '#mw-prefsection-', '' ) );
                        } else if ( hash === '' ) {
index 5566312..bb5ddfc 100644 (file)
                 * @param {Object|string} [uri] URI string, or an Object with appropriate properties (especially
                 *  another URI object to clone). Object must have non-blank `protocol`, `host`, and `path`
                 *  properties. If omitted (or set to `undefined`, `null` or empty string), then an object
-                *  will be created for the default `uri` of this constructor (`document.location` for
-                *  mw.Uri, other values for other instances -- see mw.UriRelative for details).
+                *  will be created for the default `uri` of this constructor (`location.href` for mw.Uri,
+                *  other values for other instances -- see mw.UriRelative for details).
                 * @param {Object|boolean} [options] Object with options, or (backwards compatibility) a boolean
                 *  for strictMode
                 * @param {boolean} [options.strictMode=false] Trigger strict mode parsing of the url.
                return Uri;
        };
 
-       // If we are running in a browser, inject the current document location (for relative URLs).
-       if ( document && document.location && document.location.href ) {
-               mw.Uri = mw.UriRelative( document.location.href );
-       }
+       // Default to the current browsing location (for relative URLs).
+       mw.Uri = mw.UriRelative( location.href );
 
 }( mediaWiki, jQuery ) );
index a53cbcb..cf56f29 100644 (file)
                 * Returns null if not found.
                 *
                 * @param {string} param The parameter name.
-                * @param {string} [url=document.location.href] URL to search through, defaulting to the current document's URL.
+                * @param {string} [url=location.href] URL to search through, defaulting to the current browsing location.
                 * @return {Mixed} Parameter value or null.
                 */
                getParamValue: function ( param, url ) {
                        if ( url === undefined ) {
-                               url = document.location.href;
+                               url = location.href;
                        }
                        // Get last match, stop at hash
                        var     re = new RegExp( '^[^#]*[&?]' + $.escapeRE( param ) + '=([^&#]*)' ),
diff --git a/tests/phpunit/includes/debug/logging/legacy/LoggerTest.php b/tests/phpunit/includes/debug/logging/legacy/LoggerTest.php
new file mode 100644 (file)
index 0000000..bad8d8d
--- /dev/null
@@ -0,0 +1,70 @@
+<?php
+/**
+ * @section LICENSE
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+class MWLoggerLegacyLoggerTest extends MediaWikiTestCase {
+
+       /**
+        * @covers MWLoggerLegacyLogger::interpolate
+        * @dataProvider provideInterpolate
+        */
+       public function testInterpolate( $message, $context, $expect ) {
+               $this->assertEquals(
+                       $expect, MWLoggerLegacyLogger::interpolate( $message, $context ) );
+       }
+
+       public function provideInterpolate() {
+               return array(
+                       array(
+                               'no-op',
+                               array(),
+                               'no-op',
+                       ),
+                       array(
+                               'Hello {world}!',
+                               array(
+                                       'world' => 'World',
+                               ),
+                               'Hello World!',
+                       ),
+                       array(
+                               '{greeting} {user}',
+                               array(
+                                       'greeting' => 'Goodnight',
+                                       'user' => 'Moon',
+                               ),
+                               'Goodnight Moon',
+                       ),
+                       array(
+                               'Oops {key_not_set}',
+                               array(),
+                               'Oops {key_not_set}',
+                       ),
+                       array(
+                               '{ not interpolated }',
+                               array(
+                                       'not interpolated' => 'This should NOT show up in the message',
+                               ),
+                               '{ not interpolated }',
+                       ),
+               );
+       }
+
+}
diff --git a/tests/phpunit/includes/libs/cdb/CdbTest.php b/tests/phpunit/includes/libs/cdb/CdbTest.php
deleted file mode 100644 (file)
index 487ee1f..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-<?php
-
-/**
- * Test the CDB reader/writer
- * @covers CdbWriterPHP
- * @covers CdbWriterDBA
- */
-class CdbTest extends MediaWikiTestCase {
-
-       protected function setUp() {
-               parent::setUp();
-               if ( !CdbReader::haveExtension() ) {
-                       $this->markTestSkipped( 'Native CDB support is not available' );
-               }
-       }
-
-       /**
-        * @group medium
-        */
-       public function testCdb() {
-               $dir = wfTempDir();
-               if ( !is_writable( $dir ) ) {
-                       $this->markTestSkipped( "Temp dir isn't writable" );
-               }
-
-               $phpcdbfile = $this->getNewTempFile();
-               $dbacdbfile = $this->getNewTempFile();
-
-               $w1 = new CdbWriterPHP( $phpcdbfile );
-               $w2 = new CdbWriterDBA( $dbacdbfile );
-
-               $data = array();
-               for ( $i = 0; $i < 1000; $i++ ) {
-                       $key = $this->randomString();
-                       $value = $this->randomString();
-                       $w1->set( $key, $value );
-                       $w2->set( $key, $value );
-
-                       if ( !isset( $data[$key] ) ) {
-                               $data[$key] = $value;
-                       }
-               }
-
-               $w1->close();
-               $w2->close();
-
-               $this->assertEquals(
-                       md5_file( $phpcdbfile ),
-                       md5_file( $dbacdbfile ),
-                       'same hash'
-               );
-
-               $r1 = new CdbReaderPHP( $phpcdbfile );
-               $r2 = new CdbReaderDBA( $dbacdbfile );
-
-               foreach ( $data as $key => $value ) {
-                       if ( $key === '' ) {
-                               // Known bug
-                               continue;
-                       }
-                       $v1 = $r1->get( $key );
-                       $v2 = $r2->get( $key );
-
-                       $v1 = $v1 === false ? '(not found)' : $v1;
-                       $v2 = $v2 === false ? '(not found)' : $v2;
-
-                       # cdbAssert( 'Mismatch', $key, $v1, $v2 );
-                       $this->cdbAssert( "PHP error", $key, $v1, $value );
-                       $this->cdbAssert( "DBA error", $key, $v2, $value );
-               }
-       }
-
-       private function randomString() {
-               $len = mt_rand( 0, 10 );
-               $s = '';
-               for ( $j = 0; $j < $len; $j++ ) {
-                       $s .= chr( mt_rand( 0, 255 ) );
-               }
-
-               return $s;
-       }
-
-       private function cdbAssert( $msg, $key, $v1, $v2 ) {
-               $this->assertEquals(
-                       $v2,
-                       $v1,
-                       $msg . ', k=' . bin2hex( $key )
-               );
-       }
-}