Merge "resourceloader: Remove $wgUser optimization that uses session "
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Tue, 23 Feb 2016 19:54:05 +0000 (19:54 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Tue, 23 Feb 2016 19:54:05 +0000 (19:54 +0000)
25 files changed:
RELEASE-NOTES-1.27
autoload.php
includes/GlobalFunctions.php
includes/ListToggle.php [new file with mode: 0644]
includes/actions/HistoryAction.php
includes/content/JsonContent.php
includes/libs/objectcache/CachedBagOStuff.php
includes/libs/objectcache/HashBagOStuff.php
includes/specials/SpecialContributions.php
includes/specials/SpecialLog.php
tests/parser/parserTest.inc
tests/parser/parserTests.txt
tests/phpunit/includes/debug/logger/LegacyLoggerTest.php
tests/phpunit/includes/debug/logger/MonologSpiTest.php
tests/phpunit/includes/debug/logger/monolog/LineFormatterTest.php
tests/phpunit/includes/filebackend/SwiftFileBackendTest.php
tests/phpunit/includes/libs/ProcessCacheLRUTest.php
tests/phpunit/includes/libs/objectcache/CachedBagOStuffTest.php
tests/phpunit/includes/media/ExifBitmapTest.php
tests/phpunit/includes/media/XMPTest.php
tests/phpunit/includes/page/ArticleTest.php
tests/phpunit/includes/parser/NewParserTest.php
tests/phpunit/includes/password/BcryptPasswordTest.php
tests/phpunit/includes/registration/ExtensionProcessorTest.php
tests/phpunit/includes/utils/FileContentsHasherTest.php

index 3a83b36..50b5006 100644 (file)
@@ -317,6 +317,7 @@ changes to languages because of Phabricator reports.
   rather than consume everything until the end of the page.
 * New maintenance script resetUserEmail.php allows sysadmins to reset user emails in case
   a user forgot password/account was stolen.
+* wfCheckEntropy() was removed (deprecated in 1.27).
 
 == Compatibility ==
 
index 341cb90..23beaee 100644 (file)
@@ -703,6 +703,7 @@ $wgAutoloadLocalClasses = [
        'LinksDeletionUpdate' => __DIR__ . '/includes/deferred/LinksDeletionUpdate.php',
        'LinksUpdate' => __DIR__ . '/includes/deferred/LinksUpdate.php',
        'ListDuplicatedFilesPage' => __DIR__ . '/includes/specials/SpecialListDuplicatedFiles.php',
+       'ListToggle' => __DIR__ . '/includes/ListToggle.php',
        'ListVariants' => __DIR__ . '/maintenance/language/listVariants.php',
        'ListredirectsPage' => __DIR__ . '/includes/specials/SpecialListredirects.php',
        'LoadBalancer' => __DIR__ . '/includes/db/loadbalancer/LoadBalancer.php',
index 7a41f11..eb174f2 100644 (file)
@@ -2988,22 +2988,6 @@ function wfBaseConvert( $input, $sourceBase, $destBase, $pad = 1,
        return Wikimedia\base_convert( $input, $sourceBase, $destBase, $pad, $lowercase, $engine );
 }
 
-/**
- * Check if there is sufficient entropy in php's built-in session generation
- *
- * @deprecated since 1.27, PHP's session generation isn't used with
- *  MediaWiki\\Session\\SessionManager
- * @return bool True = there is sufficient entropy
- */
-function wfCheckEntropy() {
-       wfDeprecated( __FUNCTION__, '1.27' );
-       return (
-                       ( wfIsWindows() && version_compare( PHP_VERSION, '5.3.3', '>=' ) )
-                       || ini_get( 'session.entropy_file' )
-               )
-               && intval( ini_get( 'session.entropy_length' ) ) >= 32;
-}
-
 /**
  * @deprecated since 1.27, PHP's session generation isn't used with
  *  MediaWiki\\Session\\SessionManager
diff --git a/includes/ListToggle.php b/includes/ListToggle.php
new file mode 100644 (file)
index 0000000..dfa1763
--- /dev/null
@@ -0,0 +1,67 @@
+<?php
+/**
+ * Class for generating clickable toggle links for a list of checkboxes.
+ *
+ * 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 for generating clickable toggle links for a list of checkboxes.
+ *
+ * This is only supported on clients that have JavaScript enabled; it is hidden
+ * for clients that have it disabled.
+ *
+ * @since 1.27
+ */
+class ListToggle {
+       /** @var OutputPage */
+       private $output;
+
+       public function __construct( OutputPage $output ) {
+               $this->output = $output;
+
+               $output->addModules( 'mediawiki.checkboxtoggle' );
+               $output->addModuleStyles( 'mediawiki.checkboxtoggle.styles' );
+       }
+
+       private function checkboxLink( $checkboxType ) {
+               return Html::element(
+                       'a', [ 'href' => '#', 'class' => 'mw-checkbox-' . $checkboxType ],
+                       $this->output->msg( 'checkbox-' . $checkboxType )->text()
+               );
+       }
+
+       /**
+        * @return string
+        */
+       public function getHTML() {
+               // Select: All, None, Invert
+               $links = [];
+               $links[] = $this->checkboxLink( 'all' );
+               $links[] = $this->checkboxLink( 'none' );
+               $links[] = $this->checkboxLink( 'invert' );
+
+               return Html::rawElement( 'div',
+                       [
+                               'class' => 'mw-checkbox-toggle-controls'
+                       ],
+                       $this->output->msg( 'checkbox-select' )
+                               ->rawParams( $this->output->getLanguage()->commaList( $links ) )->escaped()
+               );
+       }
+}
index 073b3ca..6f1f3e8 100644 (file)
@@ -517,6 +517,11 @@ class HistoryPager extends ReverseChronologicalPager {
                        $this->buttons .= Xml::tags( 'div', [ 'class' =>
                                'mw-history-revisionactions' ], $actionButtons );
                }
+
+               if ( $user->isAllowed( 'deleterevision' ) || $this->showTagEditUI ) {
+                       $this->buttons .= ( new ListToggle( $this->getOutput() ) )->getHTML();
+               }
+
                $this->buttons .= '</div>';
 
                $s .= $this->buttons;
index 8fe88fe..b9215fc 100644 (file)
@@ -121,19 +121,19 @@ class JsonContent extends TextContent {
         */
        protected function rootValueTable( $val ) {
                if ( is_object( $val ) ) {
-                       return self::objectTable( $val );
+                       return $this->objectTable( $val );
                }
 
                if ( is_array( $val ) ) {
                        // Wrap arrays in another array so that they're visually boxed in a container.
                        // Otherwise they are visually indistinguishable from a single value.
-                       return self::arrayTable( [ $val ] );
+                       return $this->arrayTable( [ $val ] );
                }
 
                return Html::rawElement( 'table', [ 'class' => 'mw-json mw-json-single-value' ],
                        Html::rawElement( 'tbody', [],
                                Html::rawElement( 'tr', [],
-                                       Html::element( 'td', [], self::primitiveValue( $val ) )
+                                       Html::element( 'td', [], $this->primitiveValue( $val ) )
                                )
                        )
                );
@@ -174,7 +174,7 @@ class JsonContent extends TextContent {
         */
        protected function objectRow( $key, $val ) {
                $th = Html::element( 'th', [], $key );
-               $td = self::valueCell( $val );
+               $td = $this->valueCell( $val );
                return Html::rawElement( 'tr', [], $th . $td );
        }
 
@@ -211,7 +211,7 @@ class JsonContent extends TextContent {
         * @return string HTML.
         */
        protected function arrayRow( $val ) {
-               $td = self::valueCell( $val );
+               $td = $this->valueCell( $val );
                return Html::rawElement( 'tr', [], $td );
        }
 
@@ -223,14 +223,14 @@ class JsonContent extends TextContent {
         */
        protected function valueCell( $val ) {
                if ( is_object( $val ) ) {
-                       return Html::rawElement( 'td', [], self::objectTable( $val ) );
+                       return Html::rawElement( 'td', [], $this->objectTable( $val ) );
                }
 
                if ( is_array( $val ) ) {
-                       return Html::rawElement( 'td', [], self::arrayTable( $val ) );
+                       return Html::rawElement( 'td', [], $this->arrayTable( $val ) );
                }
 
-               return Html::element( 'td', [ 'class' => 'value' ], self::primitiveValue( $val ) );
+               return Html::element( 'td', [ 'class' => 'value' ], $this->primitiveValue( $val ) );
        }
 
        /**
index 798357d..3d5d383 100644 (file)
@@ -50,11 +50,9 @@ class CachedBagOStuff extends HashBagOStuff {
 
        protected function doGet( $key, $flags = 0 ) {
                $ret = parent::doGet( $key, $flags );
-               if ( $ret === false ) {
+               if ( $ret === false && !$this->hasKey( $key ) ) {
                        $ret = $this->backend->doGet( $key, $flags );
-                       if ( $ret !== false ) {
-                               $this->set( $key, $ret, 0, self::WRITE_CACHE_ONLY );
-                       }
+                       $this->set( $key, $ret, 0, self::WRITE_CACHE_ONLY );
                }
                return $ret;
        }
index 6e7fb0c..e03cec6 100644 (file)
@@ -60,8 +60,19 @@ class HashBagOStuff extends BagOStuff {
                return true;
        }
 
+       /**
+        * Does this bag have a non-null value for the given key?
+        *
+        * @param string $key
+        * @return bool
+        * @since 1.27
+        */
+       protected function hasKey( $key ) {
+               return isset( $this->bag[$key] );
+       }
+
        protected function doGet( $key, $flags = 0 ) {
-               if ( !isset( $this->bag[$key] ) ) {
+               if ( !$this->hasKey( $key ) ) {
                        return false;
                }
 
index 254d9e2..5a351a7 100644 (file)
@@ -934,14 +934,16 @@ class ContribsPager extends ReverseChronologicalPager {
        function doBatchLookups() {
                # Do a link batch query
                $this->mResult->seek( 0 );
-               $revIds = [];
+               $parentRevIds = [];
+               $this->mParentLens = [];
                $batch = new LinkBatch();
                # Give some pointers to make (last) links
                foreach ( $this->mResult as $row ) {
                        if ( isset( $row->rev_parent_id ) && $row->rev_parent_id ) {
-                               $revIds[] = $row->rev_parent_id;
+                               $parentRevIds[] = $row->rev_parent_id;
                        }
                        if ( isset( $row->rev_id ) ) {
+                               $this->mParentLens[$row->rev_id] = $row->rev_len;
                                if ( $this->contribs === 'newbie' ) { // multiple users
                                        $batch->add( NS_USER, $row->user_name );
                                        $batch->add( NS_USER_TALK, $row->user_name );
@@ -949,7 +951,11 @@ class ContribsPager extends ReverseChronologicalPager {
                                $batch->add( $row->page_namespace, $row->page_title );
                        }
                }
-               $this->mParentLens = Revision::getParentLengths( $this->mDbSecondary, $revIds );
+               # Fetch rev_len for revisions not already scanned above
+               $this->mParentLens += Revision::getParentLengths(
+                       $this->mDbSecondary,
+                       array_diff( $parentRevIds, array_keys( $this->mParentLens ) )
+               );
                $batch->execute();
                $this->mResult->seek( 0 );
        }
index bec871b..d4c7c6a 100644 (file)
@@ -259,31 +259,7 @@ class SpecialLog extends SpecialPage {
                        ) . "\n";
                }
 
-               // Select: All, None, Invert
-               $links = [];
-               $links[] = Html::element(
-                       'a', [ 'href' => '#', 'class' => 'mw-checkbox-all' ],
-                       $this->msg( 'checkbox-all' )->text()
-               );
-               $links[] = Html::element(
-                       'a', [ 'href' => '#', 'class' => 'mw-checkbox-none' ],
-                       $this->msg( 'checkbox-none' )->text()
-               );
-               $links[] = Html::element(
-                       'a', [ 'href' => '#', 'class' => 'mw-checkbox-invert' ],
-                       $this->msg( 'checkbox-invert' )->text()
-               );
-
-               $buttons .= Html::rawElement( 'p',
-                       [
-                               'class' => "mw-checkbox-toggle-controls"
-                       ],
-                       $this->msg( 'checkbox-select' )
-                               ->rawParams( $this->getLanguage()->commaList( $links ) )->escaped()
-               );
-
-               $this->getOutput()->addModules( 'mediawiki.checkboxtoggle' );
-               $this->getOutput()->addModuleStyles( 'mediawiki.checkboxtoggle.styles' );
+               $buttons .= ( new ListToggle( $this->getOutput() ) )->getHTML();
 
                $s .= $buttons . $formcontents . $buttons;
                $s .= Html::closeElement( 'form' );
index fa774c7..549a51f 100644 (file)
@@ -168,15 +168,16 @@ class ParserTest {
                        $wgUser, $wgLang, $wgOut, $wgRequest, $wgStyleDirectory,
                        $wgExtraNamespaces, $wgNamespaceAliases, $wgNamespaceProtection, $wgLocalFileRepo,
                        $wgExtraInterlanguageLinkPrefixes, $wgLocalInterwikis,
-                       $parserMemc, $wgThumbnailScriptPath, $wgScriptPath,
+                       $parserMemc, $wgThumbnailScriptPath, $wgScriptPath, $wgResourceBasePath,
                        $wgArticlePath, $wgScript, $wgStylePath, $wgExtensionAssetsPath,
                        $wgMainCacheType, $wgMessageCacheType, $wgParserCacheType, $wgLockManagers;
 
+               $wgScriptPath = '';
                $wgScript = '/index.php';
-               $wgScriptPath = '/';
-               $wgArticlePath = '/wiki/$1';
                $wgStylePath = '/skins';
+               $wgResourceBasePath = '';
                $wgExtensionAssetsPath = '/extensions';
+               $wgArticlePath = '/wiki/$1';
                $wgThumbnailScriptPath = false;
                $wgLockManagers = [ [
                        'name' => 'fsLockManager',
index 9ad7bd5..3bbc00d 100644 (file)
@@ -9804,8 +9804,7 @@ Magic Word: {{SCRIPTPATH}}
 !! wikitext
 {{SCRIPTPATH}}
 !! html
-<p>/
-</p>
+
 !! end
 
 !! test
index faad97b..37a28c3 100644 (file)
@@ -26,7 +26,7 @@ use Psr\Log\LogLevel;
 class LegacyLoggerTest extends MediaWikiTestCase {
 
        /**
-        * @covers LegacyLogger::interpolate
+        * @covers MediaWiki\Logger\LegacyLogger::interpolate
         * @dataProvider provideInterpolate
         */
        public function testInterpolate( $message, $context, $expect ) {
@@ -125,7 +125,7 @@ class LegacyLoggerTest extends MediaWikiTestCase {
        }
 
        /**
-        * @covers LegacyLogger::shouldEmit
+        * @covers MediaWiki\Logger\LegacyLogger::shouldEmit
         * @dataProvider provideShouldEmit
         */
        public function testShouldEmit( $level, $config, $expected ) {
index 206362f..0ee7d26 100644 (file)
@@ -26,7 +26,7 @@ use TestingAccessWrapper;
 class MonologSpiTest extends MediaWikiTestCase {
 
        /**
-        * @covers MonologSpi::mergeConfig
+        * @covers MediaWiki\Logger\MonologSpi::mergeConfig
         */
        public function testMergeConfig() {
                $base = [
index be23c4a..f33cf7e 100644 (file)
@@ -36,7 +36,7 @@ class LineFormatterTest extends MediaWikiTestCase {
        }
 
        /**
-        * @covers LineFormatter::normalizeException
+        * @covers MediaWiki\Logger\Monolog\LineFormatter::normalizeException
         */
        public function testNormalizeExceptionNoTrace() {
                $fixture = new LineFormatter();
@@ -55,7 +55,7 @@ class LineFormatterTest extends MediaWikiTestCase {
        }
 
        /**
-        * @covers LineFormatter::normalizeException
+        * @covers MediaWiki\Logger\Monolog\LineFormatter::normalizeException
         */
        public function testNormalizeExceptionTrace() {
                $fixture = new LineFormatter();
index 4f47f32..95ffb70 100644 (file)
@@ -27,17 +27,17 @@ class SwiftFileBackendTest extends MediaWikiTestCase {
        }
 
        /**
-        * @dataProvider provider_testSanitzeHdrs
-        * @covers SwiftFileBackend::sanitzeHdrs
+        * @dataProvider provider_testSanitizeHdrs
+        * @covers SwiftFileBackend::sanitizeHdrs
         * @covers SwiftFileBackend::getCustomHeaders
         */
-       public function testSanitzeHdrs( $raw, $sanitized ) {
+       public function testSanitizeHdrs( $raw, $sanitized ) {
                $hdrs = $this->backend->sanitizeHdrs( [ 'headers' => $raw ] );
 
                $this->assertEquals( $hdrs, $sanitized, 'sanitizeHdrs() has expected result' );
        }
 
-       public static function provider_testSanitzeHdrs() {
+       public static function provider_testSanitizeHdrs() {
                return [
                        [
                                [
index a579f3a..9c189d1 100644 (file)
@@ -94,7 +94,7 @@ class ProcessCacheLRUTest extends PHPUnit_Framework_TestCase {
        /**
         * @covers ProcessCacheLRU::get
         * @covers ProcessCacheLRU::set
-        * @covers ProcessCacheLRU::het
+        * @covers ProcessCacheLRU::has
         */
        public function testAddAndGetAKey() {
                $oneCache = new ProcessCacheLRUTestable( 1 );
@@ -184,7 +184,7 @@ class ProcessCacheLRUTest extends PHPUnit_Framework_TestCase {
        /**
         * @covers ProcessCacheLRU::get
         * @covers ProcessCacheLRU::set
-        * @covers ProcessCacheLRU::het
+        * @covers ProcessCacheLRU::has
         */
        public function testRecentlyAccessedKeyStickIn() {
                $cache = new ProcessCacheLRUTestable( 2 );
index 3b19c9a..7fe8055 100644 (file)
@@ -49,4 +49,22 @@ class CachedBagOStuffTest extends PHPUnit_Framework_TestCase {
                $cache->delete( 'foo', CachedBagOStuff::WRITE_CACHE_ONLY );
                $this->assertEquals( 'old', $cache->get( 'foo' ) ); // Reloaded from backend
        }
+
+       public function testCacheBackendMisses() {
+               $backend = new HashBagOStuff;
+               $cache = new CachedBagOStuff( $backend );
+
+               // First hit primes the cache with miss from the backend
+               $this->assertEquals( false, $cache->get( 'foo' ) );
+
+               // Change the value in the backend
+               $backend->set( 'foo', true );
+
+               // Second hit returns the cached miss
+               $this->assertEquals( false, $cache->get( 'foo' ) );
+
+               // But a fresh value is read from the backend
+               $backend->set( 'bar', true );
+               $this->assertEquals( true, $cache->get( 'bar' ) );
+       }
 }
index b777ed0..f70b42d 100644 (file)
@@ -146,7 +146,7 @@ class ExifBitmapTest extends MediaWikiMediaTestCase {
 
        /**
         * @dataProvider provideSwappingICCProfile
-        * @covers BitmapHandler::swapICCProfile
+        * @covers ExifBitmapHandler::swapICCProfile
         */
        public function testSwappingICCProfile(
                $sourceFilename, $controlFilename, $newProfileFilename, $oldProfileName
index dacef8d..bffe415 100644 (file)
@@ -175,7 +175,7 @@ class XMPTest extends MediaWikiTestCase {
 
        /**
         * Test for multi-section, hostile XML
-        * @covers checkParseSafety
+        * @covers XMPReader::checkParseSafety
         */
        public function testCheckParseSafety() {
 
index ae069ea..a96a296 100644 (file)
@@ -41,16 +41,6 @@ class ArticleTest extends MediaWikiTestCase {
                $this->assertEquals( 2, $this->article->mLatest, "Article __set magic" );
        }
 
-       /**
-        * @depends testImplementsSetMagic
-        * @covers Article::__call
-        */
-       public function testImplementsCallMagic() {
-               $this->article->mLatest = 33;
-               $this->article->mDataLoaded = true;
-               $this->assertEquals( 33, $this->article->getLatest(), "Article __call magic" );
-       }
-
        /**
         * @covers Article::__get
         * @covers Article::__set
index fa86eed..04d6067 100644 (file)
@@ -71,13 +71,14 @@ class NewParserTest extends MediaWikiTestCase {
                $tmpGlobals['wgSitename'] = 'MediaWiki';
                $tmpGlobals['wgServer'] = 'http://example.org';
                $tmpGlobals['wgServerName'] = 'example.org';
+               $tmpGlobals['wgScriptPath'] = '';
                $tmpGlobals['wgScript'] = '/index.php';
-               $tmpGlobals['wgScriptPath'] = '/';
+               $tmpGlobals['wgResourceBasePath'] = '';
+               $tmpGlobals['wgStylePath'] = '/skins';
+               $tmpGlobals['wgExtensionAssetsPath'] = '/extensions';
                $tmpGlobals['wgArticlePath'] = '/wiki/$1';
                $tmpGlobals['wgActionPaths'] = [];
                $tmpGlobals['wgVariantArticlePath'] = false;
-               $tmpGlobals['wgExtensionAssetsPath'] = '/extensions';
-               $tmpGlobals['wgStylePath'] = '/skins';
                $tmpGlobals['wgEnableUploads'] = true;
                $tmpGlobals['wgUploadNavigationUrl'] = false;
                $tmpGlobals['wgThumbnailScriptPath'] = false;
index 46ba46c..d6940b5 100644 (file)
@@ -3,7 +3,7 @@
 /**
  * @group large
  */
-class BcryptPasswordTestCase extends PasswordTestCase {
+class BcryptPasswordTest extends PasswordTestCase {
        protected function getTypeConfigs() {
                return [ 'bcrypt' => [
                        'class' => 'BcryptPassword',
index 35aca48..27c0c60 100644 (file)
@@ -130,7 +130,7 @@ class ExtensionProcessorTest extends MediaWikiTestCase {
                $this->assertEquals( 'somevalue', $extracted['globals']['egBar'] );
        }
 
-       public static function provideExtracttExtensionMessagesFiles() {
+       public static function provideExtractExtensionMessagesFiles() {
                $dir = __DIR__ . '/FooBar/';
                return [
                        [
@@ -155,10 +155,10 @@ class ExtensionProcessorTest extends MediaWikiTestCase {
        }
 
        /**
-        * @covers ExtensionProcessor::extracttExtensionMessagesFiles
-        * @dataProvider provideExtracttExtensionMessagesFiles
+        * @covers ExtensionProcessor::extractExtensionMessagesFiles
+        * @dataProvider provideExtractExtensionMessagesFiles
         */
-       public function testExtracttExtensionMessagesFiles( $input, $expected ) {
+       public function testExtractExtensionMessagesFiles( $input, $expected ) {
                $processor = new ExtensionProcessor();
                $processor->extractInfo( $this->dir, $input + self::$default, 1 );
                $out = $processor->getExtractedInfo();
index db18b72..2de4bff 100644 (file)
@@ -18,7 +18,7 @@ class FileContentsHasherTest extends MediaWikiTestCase {
        }
 
        /**
-        * @covers FileContentsHasher::getFileContentHash
+        * @covers FileContentsHasher::getFileContentsHash
         * @covers FileContentsHasher::getFileContentsHashInternal
         * @dataProvider provideSingleFile
         */
@@ -33,7 +33,7 @@ class FileContentsHasherTest extends MediaWikiTestCase {
        }
 
        /**
-        * @covers FileContentsHasher::getFileContentHash
+        * @covers FileContentsHasher::getFileContentsHash
         * @covers FileContentsHasher::getFileContentsHashInternal
         * @dataProvider provideMultipleFiles
         */