Merge "API: Rewrite queries for list=allusers"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Mon, 29 Sep 2014 20:36:32 +0000 (20:36 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Mon, 29 Sep 2014 20:36:32 +0000 (20:36 +0000)
32 files changed:
RELEASE-NOTES-1.25
docs/hooks.txt
includes/ChangeTags.php
includes/MovePage.php
includes/OutputPage.php
includes/PrefixSearch.php
includes/api/ApiQueryAllUsers.php
includes/cache/bloom/BloomCache.php
includes/content/AbstractContent.php
includes/db/DatabaseMssql.php
includes/filerepo/file/File.php
includes/mail/MailAddress.php
includes/media/DjVuImage.php
includes/page/Article.php
includes/pager/IndexPager.php
includes/parser/Parser.php
includes/parser/ParserOutput.php
includes/resourceloader/ResourceLoaderWikiModule.php
includes/site/SiteSQLStore.php
includes/specials/SpecialActiveusers.php
includes/specials/SpecialCategories.php
includes/specials/SpecialChangeEmail.php
includes/specials/SpecialContributions.php
includes/specials/SpecialVersion.php
includes/specials/SpecialWantedfiles.php
includes/upload/UploadBase.php
resources/Resources.php
resources/src/mediawiki.special/mediawiki.special.css
tests/phpunit/includes/changes/EnhancedChangesListTest.php
tests/phpunit/includes/config/HashConfigTest.php
tests/phpunit/includes/mail/MailAddressTest.php
tests/phpunit/includes/specialpage/SpecialPageFactoryTest.php

index 22033cf..2a6d951 100644 (file)
@@ -13,6 +13,8 @@ production.
 === New features in 1.25 ===
 * (bug 58139) ResourceLoaderFileModule now supports language fallback
   for 'languageScripts'.
+* Added a new hook, "ContentAlterParserOutput", to allow extensions to modify the
+  parser output for a content object before links update.
 
 === Bug fixes in 1.25 ===
 
index 51da2d4..d862983 100644 (file)
@@ -912,6 +912,15 @@ generation of HTML may be skipped, but other information should still be present
 ParserOutput object.
 &$output: ParserOutput, to manipulate or replace
 
+'ContentAlterParserOutput': Modify parser output for a given content object.
+Called by Content::getParserOutput after parsing has finished. Can be used
+for changes that depend on the result of the parsing but have to be done
+before LinksUpdate is called (such as adding tracking categories based on
+the rendered HTML).
+$content: The Content to render
+$title: Title of the page, as context
+$parserOutput: ParserOutput to manipulate
+
 'ConvertContent': Called by AbstractContent::convert when a conversion to another
 content model is requested.
 $content: The Content object to be converted.
index 94b7b7a..a3c2360 100644 (file)
@@ -265,7 +265,7 @@ class ChangeTags {
                                'tagfilter',
                                20,
                                $selected,
-                               array( 'class' => 'mw-tagfilter-input', 'id' => 'tagfilter' )
+                               array( 'class' => 'mw-tagfilter-input mw-ui-input mw-ui-input-inline', 'id' => 'tagfilter' )
                        )
                );
 
index cea91d2..5c9490b 100644 (file)
@@ -423,5 +423,4 @@ class MovePage {
                $logid = $logEntry->insert();
                $logEntry->publish( $logid );
        }
-
-}
\ No newline at end of file
+}
index 3321747..e1b6e0e 100644 (file)
@@ -2769,7 +2769,6 @@ $templates
                                );
                                $context = new ResourceLoaderContext( $resourceLoader, new FauxRequest( $query ) );
 
-
                                // Extract modules that know they're empty and see if we have one or more
                                // raw modules
                                $isRaw = false;
index 718750f..1f684fb 100644 (file)
@@ -195,7 +195,7 @@ abstract class PrefixSearch {
                // Unlike SpecialPage itself, we want the canonical forms of both
                // canonical and alias title forms...
                $keys = array();
-               foreach ( SpecialPageFactory::getNames() as $page  ) {
+               foreach ( SpecialPageFactory::getNames() as $page ) {
                        $keys[$wgContLang->caseFold( $page )] = $page;
                }
 
index 776649f..e1cc75a 100644 (file)
@@ -50,7 +50,7 @@ class ApiQueryAllUsers extends ApiQueryBase {
 
                if ( $params['activeusers'] ) {
                        // Update active user cache
-                       SpecialActiveUsers::mergeActiveUsers( 600, $activeUserDays );
+                       SpecialActiveUsers::mergeActiveUsers( 300, $activeUserDays );
                }
 
                $db = $this->getDB();
index 236db95..a15b461 100644 (file)
@@ -318,6 +318,6 @@ class EmptyBloomCache extends BloomCache {
        }
 
        protected function doGetStatus( $virtualKey ) {
-               return array( 'lastID' => null, 'asOfTime' => null, 'epoch' => null ) ;
+               return array( 'lastID' => null, 'asOfTime' => null, 'epoch' => null );
        }
 }
index 9d257a6..cb39fac 100644 (file)
@@ -491,6 +491,8 @@ abstract class AbstractContent implements Content {
                        $options->setRedirectTarget( $oldRedir );
                }
 
+               wfRunHooks( 'ContentAlterParserOutput', array( $this, $title, $po ) );
+
                return $po;
        }
 
index af3cc72..ab8d366 100644 (file)
@@ -692,7 +692,7 @@ class DatabaseMssql extends DatabaseBase {
                        if ( !is_null( $identity ) ) {
                                // then we want to get the identity column value we were assigned and save it off
                                $row = $ret->fetchObject();
-                               if( is_object( $row ) ){
+                               if ( is_object( $row ) ) {
                                        $this->mInsertId = $row->$identity;
                                }
                        }
index b574c5e..7563d64 100644 (file)
@@ -1237,7 +1237,7 @@ abstract class File {
                        $that = $this;
                        $work = new PoolCounterWorkViaCallback( 'GetLocalFileCopy', sha1( $this->getName() ),
                                array(
-                                       'doWork' => function() use ( $that ) {
+                                       'doWork' => function () use ( $that ) {
                                                return $that->getLocalRefPath();
                                        }
                                )
index 6817908..7a228bd 100644 (file)
@@ -38,7 +38,7 @@ class MailAddress {
        function __construct( $address, $name = null, $realName = null ) {
                if ( is_object( $address ) && $address instanceof User ) {
                        // Old calling format, now deprecated
-                       wfDeprecated( __METHOD__ . ' with a User object' , '1.24' );
+                       wfDeprecated( __METHOD__ . ' with a User object', '1.24' );
                        $this->address = $address->getEmail();
                        $this->name = $address->getName();
                        $this->realName = $address->getRealName();
index 6ff19c9..596d3e8 100644 (file)
@@ -265,12 +265,16 @@ class DjVuImage {
 
        /**
         * Return an XML string describing the DjVu image
-        * @return string
+        * @return string|bool
         */
        function retrieveMetaData() {
                global $wgDjvuToXML, $wgDjvuDump, $wgDjvuTxt;
                wfProfileIn( __METHOD__ );
 
+               if ( !$this->isValid() ) {
+                       return false;
+               }
+
                if ( isset( $wgDjvuDump ) ) {
                        # djvudump is faster as of version 3.5
                        # http://sourceforge.net/tracker/index.php?func=detail&aid=1704049&group_id=32953&atid=406583
index f93f4f5..e562d43 100644 (file)
@@ -986,6 +986,10 @@ class Article implements Page {
                $query = $request->getValues();
                unset( $query['rdfrom'] );
                unset( $query['title'] );
+               if ( $this->getTitle()->isRedirect() ) {
+                       // Prevent double redirects
+                       $query['redirect'] = 'no';
+               }
                $redirectTargetUrl = $this->getTitle()->getLinkURL( $query );
 
                if ( isset( $this->mRedirectedFrom ) ) {
index ce6dc50..9398e30 100644 (file)
@@ -478,7 +478,6 @@ abstract class IndexPager extends ContextSource implements Pager {
                        $attrs['class'] = "mw-{$type}link";
                }
 
-
                return Linker::linkKnown(
                        $this->getTitle(),
                        $text,
index 2d72deb..ddd1f9a 100644 (file)
@@ -4359,40 +4359,12 @@ class Parser {
        }
 
        /**
-        * Add a tracking category, getting the title from a system message,
-        * or print a debug message if the title is invalid.
-        *
-        * Please add any message that you use with this function to
-        * $wgTrackingCategories. That way they will be listed on
-        * Special:TrackingCategories.
-        *
+        * @see ParserOutput::addTrackingCategory()
         * @param string $msg Message key
         * @return bool Whether the addition was successful
         */
        public function addTrackingCategory( $msg ) {
-               if ( $this->mTitle->getNamespace() === NS_SPECIAL ) {
-                       wfDebug( __METHOD__ . ": Not adding tracking category $msg to special page!\n" );
-                       return false;
-               }
-               // Important to parse with correct title (bug 31469)
-               $cat = wfMessage( $msg )
-                       ->title( $this->getTitle() )
-                       ->inContentLanguage()
-                       ->text();
-
-               # Allow tracking categories to be disabled by setting them to "-"
-               if ( $cat === '-' ) {
-                       return false;
-               }
-
-               $containerCategory = Title::makeTitleSafe( NS_CATEGORY, $cat );
-               if ( $containerCategory ) {
-                       $this->mOutput->addCategory( $containerCategory->getDBkey(), $this->getDefaultSort() );
-                       return true;
-               } else {
-                       wfDebug( __METHOD__ . ": [[MediaWiki:$msg]] is not a valid title!\n" );
-                       return false;
-               }
+               return $this->mOutput->addTrackingCategory( $msg, $this->mTitle );
        }
 
        /**
index 5037ce1..43e8d0b 100644 (file)
@@ -471,6 +471,46 @@ class ParserOutput extends CacheTime {
                $this->mPreventClickjacking = $this->mPreventClickjacking || $out->getPreventClickjacking();
        }
 
+       /**
+        * Add a tracking category, getting the title from a system message,
+        * or print a debug message if the title is invalid.
+        *
+        * Please add any message that you use with this function to
+        * $wgTrackingCategories. That way they will be listed on
+        * Special:TrackingCategories.
+        *
+        * @param string $msg Message key
+        * @param Title $title title of the page which is being tracked
+        * @return bool Whether the addition was successful
+        * @since 1.25
+        */
+       public function addTrackingCategory( $msg, $title ) {
+               if ( $title->getNamespace() === NS_SPECIAL ) {
+                       wfDebug( __METHOD__ . ": Not adding tracking category $msg to special page!\n" );
+                       return false;
+               }
+
+               // Important to parse with correct title (bug 31469)
+               $cat = wfMessage( $msg )
+                       ->title( $title )
+                       ->inContentLanguage()
+                       ->text();
+
+               # Allow tracking categories to be disabled by setting them to "-"
+               if ( $cat === '-' ) {
+                       return false;
+               }
+
+               $containerCategory = Title::makeTitleSafe( NS_CATEGORY, $cat );
+               if ( $containerCategory ) {
+                       $this->addCategory( $containerCategory->getDBkey(), $this->getProperty( 'defaultsort' ) ?: '' );
+                       return true;
+               } else {
+                       wfDebug( __METHOD__ . ": [[MediaWiki:$msg]] is not a valid title!\n" );
+                       return false;
+               }
+       }
+
        /**
         * Override the title to be used for display
         * -- this is assumed to have been validated
index 99a8739..2a1736d 100644 (file)
@@ -170,7 +170,7 @@ abstract class ResourceLoaderWikiModule extends ResourceLoaderModule {
                $modifiedTime = 1; // wfTimestamp() interprets 0 as "now"
                $titleInfo = $this->getTitleInfo( $context );
                if ( count( $titleInfo ) ) {
-                       $mtimes = array_map( function( $value ) {
+                       $mtimes = array_map( function ( $value ) {
                                return $value['timestamp'];
                        }, $titleInfo );
                        $modifiedTime = max( $modifiedTime, max( $mtimes ) );
index d133468..e5d05be 100644 (file)
@@ -395,7 +395,7 @@ class SiteSQLStore implements SiteStore {
                $dbw->startAtomic( __METHOD__ );
                $ok = $dbw->delete( 'sites', '*', __METHOD__ );
                $ok = $dbw->delete( 'site_identifiers', '*', __METHOD__ ) && $ok;
-               $dbw->endAtomic( __METHOD__);
+               $dbw->endAtomic( __METHOD__ );
 
                $this->reset();
 
index 10ab46a..6219fc4 100644 (file)
@@ -259,7 +259,7 @@ class SpecialActiveUsers extends SpecialPage {
                        array( 'activeusers-intro', $this->getLanguage()->formatNum( $days ) ) );
 
                // Occasionally merge in new updates
-               $seconds = min( self::mergeActiveUsers( 600, $days ), $days * 86400 );
+               $seconds = min( self::mergeActiveUsers( 300, $days ), $days * 86400 );
                // Mention the level of staleness
                $out->addWikiMsg( 'cachedspecial-viewing-cached-ttl',
                        $this->getLanguage()->formatDuration( $seconds ) );
index 371cd9f..bf6bb35 100644 (file)
@@ -192,7 +192,7 @@ class CategoryPager extends AlphabeticPager {
                                        $this->msg( 'categories' )->text(),
                                        Xml::inputLabel(
                                                $this->msg( 'categoriesfrom' )->text(),
-                                               'from', 'from', 20, $from, array( 'class' => 'mw-ui-input-inline') ) .
+                                               'from', 'from', 20, $from, array( 'class' => 'mw-ui-input-inline' ) ) .
                                                ' ' .
                                                Xml::submitButton(
                                                        $this->msg( 'allpagessubmit' )->text(),
index f5df54e..12bbd2a 100644 (file)
@@ -112,7 +112,7 @@ class SpecialChangeEmail extends FormSpecialPage {
                $form->setTableId( 'mw-changeemail-table' );
                $form->setWrapperLegend( false );
                $form->setSubmitTextMsg( 'changeemail-submit' );
-               $form->addHiddenField( 'returnto', $this->getRequest()->getVal( 'returnto' ) );
+               $form->addHiddenFields( $this->getRequest()->getValues( 'returnto', 'returntoquery' ) );
        }
 
        public function onSubmit( array $data ) {
@@ -125,18 +125,21 @@ class SpecialChangeEmail extends FormSpecialPage {
        }
 
        public function onSuccess() {
-               $titleObj = Title::newFromText( $this->getRequest()->getVal( 'returnto' ) );
+               $request = $this->getRequest();
+
+               $titleObj = Title::newFromText( $request->getVal( 'returnto' ) );
                if ( !$titleObj instanceof Title ) {
                        $titleObj = Title::newMainPage();
                }
+               $query = $request->getVal( 'returntoquery' );
 
                if ( $this->status->value === true ) {
-                       $this->getOutput()->redirect( $titleObj->getFullURL() );
+                       $this->getOutput()->redirect( $titleObj->getFullURL( $query ) );
                } elseif ( $this->status->value === 'eauth' ) {
                        # Notify user that a confirmation email has been sent...
                        $this->getOutput()->wrapWikiMsg( "<div class='error' style='clear: both;'>\n$1\n</div>",
                                'eauthentsent', $this->getUser()->getName() );
-                       $this->getOutput()->addReturnTo( $titleObj ); // just show the link to go back
+                       $this->getOutput()->addReturnTo( $titleObj, wfCgiToArray( $query ) ); // just show the link to go back
                }
        }
 
index 32a887c..4b4f545 100644 (file)
@@ -478,13 +478,8 @@ class SpecialContributions extends IncludableSpecialPage {
                if ( $tagFilter ) {
                        $filterSelection = Html::rawElement(
                                'td',
-                               array( 'class' => 'mw-label' ),
-                               array_shift( $tagFilter )
-                       );
-                       $filterSelection .= Html::rawElement(
-                               'td',
-                               array( 'class' => 'mw-input' ),
-                               implode( '&#160', $tagFilter )
+                               array(),
+                               array_shift( $tagFilter ) . implode( '&#160', $tagFilter )
                        );
                } else {
                        $filterSelection = Html::rawElement( 'td', array( 'colspan' => 2 ), '' );
@@ -510,7 +505,7 @@ class SpecialContributions extends IncludableSpecialPage {
                        'target',
                        $this->opts['target'],
                        'text',
-                       array( 'size' => '40', 'required' => '', 'class' => 'mw-input' ) +
+                       array( 'size' => '40', 'required' => '', 'class' => 'mw-input mw-ui-input-inline' ) +
                                ( $this->opts['target'] ? array() : array( 'autofocus' )
                                )
                );
@@ -522,16 +517,12 @@ class SpecialContributions extends IncludableSpecialPage {
 
                $namespaceSelection = Xml::tags(
                        'td',
-                       array( 'class' => 'mw-label' ),
+                       array(),
                        Xml::label(
                                $this->msg( 'namespace' )->text(),
                                'namespace',
                                ''
-                       )
-               );
-               $namespaceSelection .= Html::rawElement(
-                       'td',
-                       null,
+                       ) .
                        Html::namespaceSelector(
                                array( 'selected' => $this->opts['namespace'], 'all' => '' ),
                                array(
@@ -612,6 +603,11 @@ class SpecialContributions extends IncludableSpecialPage {
                        $deletedOnlyCheck . $checkLabelTopOnly . $checkLabelNewOnly
                );
 
+               $className = 'mw-submit';
+               if ( $this->getConfig( 'UseMediaWikiUIEverywhere') ) {
+                       $className .= ' mw-ui-button mw-ui-progressive';
+               }
+
                $dateSelectionAndSubmit = Xml::tags( 'td', array( 'colspan' => 2 ),
                        Xml::dateMenu(
                                $this->opts['year'] === '' ? MWTimestamp::getInstance()->format( 'Y' ) : $this->opts['year'],
@@ -619,7 +615,7 @@ class SpecialContributions extends IncludableSpecialPage {
                        ) . ' ' .
                                Xml::submitButton(
                                        $this->msg( 'sp-contributions-submit' )->text(),
-                                       array( 'class' => 'mw-submit' )
+                                       array( 'class' => $className )
                                )
                );
 
index 3508823..6b9173f 100644 (file)
@@ -525,8 +525,17 @@ class SpecialVersion extends SpecialPage {
                        );
 
                        array_walk( $tags, function ( &$value ) {
-                               $value = '&lt;' . htmlspecialchars( $value ) . '&gt;';
+                               // Bidirectional isolation improves readability in RTL wikis
+                               $value = Html::element(
+                                       'bdi',
+                                       // Prevent < and > from slipping to another line
+                                       array(
+                                               'style' => 'white-space: nowrap;',
+                                       ),
+                                       "<$value>"
+                               );
                        } );
+
                        $out .= $this->listToText( $tags );
                } else {
                        $out = '';
index 937a503..16127d9 100644 (file)
@@ -102,7 +102,7 @@ class WantedFilesPage extends WantedQueryPage {
         * @return boolean
         */
        protected function existenceCheck( Title $title ) {
-               return (bool) wfFindFile( $title );
+               return (bool)wfFindFile( $title );
        }
 
        function getQueryInfo() {
index 2419299..7741c35 100644 (file)
@@ -767,7 +767,7 @@ abstract class UploadBase {
                rsort( $sizes );
 
                foreach ( $sizes as $size ) {
-                       $jobs []= new ThumbnailRenderJob( $this->getLocalFile()->getTitle(), array(
+                       $jobs[] = new ThumbnailRenderJob( $this->getLocalFile()->getTitle(), array(
                                'transformParams' => array( 'width' => $size ),
                        ) );
                }
index c2c09df..2fa0c3a 100644 (file)
@@ -1333,9 +1333,13 @@ return array(
                        'size-megabytes',
                        'size-gigabytes',
                        'largefileserver',
+                       'editwarning-warning',
+                       // editwarning-warning uses {{int:prefs-editing}}
+                       'prefs-editing',
                ),
                'dependencies' => array(
                        'jquery.spinner',
+                       'mediawiki.jqueryMsg',
                        'mediawiki.api',
                        'mediawiki.libs.jpegmeta',
                        'mediawiki.Title',
index 0356fc7..d245726 100644 (file)
@@ -118,3 +118,8 @@ table.mw-userrights-groups * td,
 table.mw-userrights-groups * th {
        padding-right: 1.5em;
 }
+
+/* Special:Contributions */
+.mw-contributions-form select {
+       vertical-align: middle;
+}
index 40a11d2..7a82680 100644 (file)
@@ -31,7 +31,7 @@ class EnhancedChangesListTest extends MediaWikiLangTestCase {
                        'mediawiki.special.changeslist',
                        $styleModules,
                        'has mediawiki.special.changeslist'
-                );
+               );
 
                $this->assertContains(
                        'mediawiki.special.changeslist.enhanced',
@@ -75,10 +75,10 @@ class EnhancedChangesListTest extends MediaWikiLangTestCase {
                $this->assertEquals( '', $html );
        }
 
-         /**
-          * @todo more tests for actual formatting, this is more of a smoke test
-          */
-         public function testEndRecentChangesList() {
+       /**
+        * @todo more tests for actual formatting, this is more of a smoke test
+        */
+       public function testEndRecentChangesList() {
                $enhancedChangesList = $this->newEnhancedChangesList();
                $enhancedChangesList->beginRecentChangesList();
 
@@ -92,7 +92,7 @@ class EnhancedChangesListTest extends MediaWikiLangTestCase {
 
                preg_match_all( '/td class="mw-enhanced-rc-nested"/', $html, $matches );
                $this->assertCount( 2, $matches[0] );
-         }
+       }
 
        /**
         * @return EnhancedChangesList
index 3ad3bfb..06973b0 100644 (file)
@@ -60,4 +60,4 @@ class HashConfigTest extends MediaWikiTestCase {
                $conf->set( 'one', '3' );
                $this->assertEquals( '3', $conf->get( 'one' ) );
        }
-}
\ No newline at end of file
+}
index 76566eb..dd8ab3e 100644 (file)
@@ -60,5 +60,4 @@ class MailAddressTest extends MediaWikiTestCase {
                $ma = new MailAddress( 'some@email.com', 'UserName', 'A real name' );
                $this->assertEquals( $ma->toString(), (string)$ma );
        }
-
-}
\ No newline at end of file
+}
index 4619c2e..42602dc 100644 (file)
@@ -35,10 +35,10 @@ class SpecialPageFactoryTest extends MediaWikiTestCase {
        public function specialPageProvider() {
                return array(
                        'class name' => array( 'SpecialAllPages', false ),
-                       'closure' => array( function() {
+                       'closure' => array( function () {
                                return new SpecialAllPages();
                        }, false ),
-                       'function' => array( array( $this, 'newSpecialAllPages' ), false  ),
+                       'function' => array( array( $this, 'newSpecialAllPages' ), false ),
                );
        }