From: jenkins-bot Date: Wed, 11 Jan 2017 18:57:20 +0000 (+0000) Subject: Merge "SpecialPageLanguage: Redirect to redirect by adding redirect=no" X-Git-Tag: 1.31.0-rc.0~4348 X-Git-Url: http://git.cyclocoop.org/%7B%24www_url%7Dadmin/membres/fiche.php?a=commitdiff_plain;h=215d466ca94bfff667bd926b676d0b15e0215a68;hp=be215a6cb4bfe766cf02c6a3858c25a2b14b48fd;p=lhc%2Fweb%2Fwiklou.git Merge "SpecialPageLanguage: Redirect to redirect by adding redirect=no" --- diff --git a/includes/ProtectionForm.php b/includes/ProtectionForm.php index 58a04a1dcb..bcf4dda98a 100644 --- a/includes/ProtectionForm.php +++ b/includes/ProtectionForm.php @@ -184,9 +184,12 @@ class ProtectionForm { $out = $this->mContext->getOutput(); if ( !wfMessage( 'protect-dropdown' )->inContentLanguage()->isDisabled() ) { + $reasonsList = Xml::getArrayFromWikiTextList( + wfMessage( 'protect-dropdown' )->inContentLanguage()->text() + ); $out->addModules( 'mediawiki.reasonSuggest' ); $out->addJsConfigVars( [ - 'reasons' => 'protect-dropdown' + 'reasons' => $reasonsList ] ); } diff --git a/includes/Xml.php b/includes/Xml.php index e124c38b75..8f18046f5f 100644 --- a/includes/Xml.php +++ b/includes/Xml.php @@ -563,6 +563,36 @@ class Xml { . Xml::closeElement( 'select' ); } + /** + * Converts textual drop-down list to array + * + * @param string $list Correctly formatted text (newline delimited) to be + * used to generate the options. + * @return array + */ + public static function getArrayFromWikiTextList( $list = '' ) { + $options = []; + + foreach ( explode( "\n", $list ) as $option ) { + $value = trim( $option ); + if ( $value == '' ) { + continue; + } elseif ( substr( $value, 0, 1 ) == '*' && substr( $value, 1, 1 ) != '*' ) { + // A new group is starting ... + $value = trim( substr( $value, 1 ) ); + $options[] = $value; + } elseif ( substr( $value, 0, 2 ) == '**' ) { + // groupmember + $value = trim( substr( $value, 2 ) ); + $options[] = $value; + } else { + // groupless reason list + $options[] = $value; + } + } + return $options; + } + /** * Shortcut for creating fieldsets. * diff --git a/includes/page/Article.php b/includes/page/Article.php index d268e61de1..a4938547f3 100644 --- a/includes/page/Article.php +++ b/includes/page/Article.php @@ -1674,9 +1674,12 @@ class Article implements Page { $ctx = $this->getContext(); $outputPage = $ctx->getOutput(); if ( !wfMessage( 'deletereason-dropdown' )->inContentLanguage()->isDisabled() ) { + $reasonsList = Xml::getArrayFromWikiTextList( + wfMessage( 'deletereason-dropdown' )->inContentLanguage()->text() + ); $outputPage->addModules( 'mediawiki.reasonSuggest' ); $outputPage->addJsConfigVars( [ - 'reasons' => 'deletereason-dropdown' + 'reasons' => $reasonsList ] ); } $useMediaWikiUIEverywhere = $ctx->getConfig()->get( 'UseMediaWikiUIEverywhere' ); @@ -1693,7 +1696,6 @@ class Article implements Page { Hooks::run( 'ArticleConfirmDelete', [ $this, $outputPage, &$reason ] ); $user = $this->getContext()->getUser(); - if ( $user->isAllowed( 'suppressrevision' ) ) { $suppress = Html::openElement( 'div', [ 'id' => 'wpDeleteSuppressRow' ] ) . Xml::checkLabel( wfMessage( 'revdelete-suppress' )->text(), @@ -1703,7 +1705,6 @@ class Article implements Page { $suppress = ''; } $checkWatch = $user->getBoolOption( 'watchdeletion' ) || $user->isWatched( $title ); - $form = Html::openElement( 'form', [ 'method' => 'post', 'action' => $title->getLocalURL( 'action=delete' ), 'id' => 'deleteconfirm' ] ) . Html::openElement( 'fieldset', [ 'id' => 'mw-delete-table' ] ) . diff --git a/includes/site/HashSiteStore.php b/includes/site/HashSiteStore.php index 198d331d95..2c7965c902 100644 --- a/includes/site/HashSiteStore.php +++ b/includes/site/HashSiteStore.php @@ -37,7 +37,7 @@ class HashSiteStore implements SiteStore { private $sites = []; /** - * @param array $sites + * @param Site[] $sites */ public function __construct( $sites = [] ) { $this->saveSites( $sites ); diff --git a/includes/specials/SpecialBlock.php b/includes/specials/SpecialBlock.php index 730d94103d..7e02974003 100644 --- a/includes/specials/SpecialBlock.php +++ b/includes/specials/SpecialBlock.php @@ -128,9 +128,12 @@ class SpecialBlock extends FormSpecialPage { protected function getFormFields() { global $wgBlockAllowsUTEdit; if ( !wfMessage( 'ipbreason-dropdown' )->inContentLanguage()->isDisabled() ) { + $reasonsList = Xml::getArrayFromWikiTextList( + wfMessage( 'ipbreason-dropdown' )->inContentLanguage()->text() + ); $this->getOutput()->addModules( 'mediawiki.reasonSuggest' ); $this->getOutput()->addJsConfigVars( [ - 'reasons' => 'ipbreason-dropdown' + 'reasons' => $reasonsList ] ); } $user = $this->getUser(); diff --git a/includes/specials/SpecialUncategorizedcategories.php b/includes/specials/SpecialUncategorizedcategories.php index 86d8f89c52..7c3265d625 100644 --- a/includes/specials/SpecialUncategorizedcategories.php +++ b/includes/specials/SpecialUncategorizedcategories.php @@ -27,11 +27,54 @@ * @ingroup SpecialPage */ class UncategorizedCategoriesPage extends UncategorizedPagesPage { + /** + * Holds a list of categories, which shouldn't be listed on this special page, + * even if it is uncategorized. + * @var array + */ + private $exceptionList = null; + function __construct( $name = 'Uncategorizedcategories' ) { parent::__construct( $name ); $this->requestedNamespace = NS_CATEGORY; } + /** + * Returns an array of categorie titles (usually without the namespace), which + * shouldn't be listed on this page, even if they're uncategorized. + * + * @return array + */ + private function getExceptionList() { + if ( $this->exceptionList === null ) { + $exList = $this->msg( 'uncategorized-categories-exceptionlist' ) + ->inContentLanguage()->plain(); + $proposedTitles = explode( "\n", $exList ); + foreach ( $proposedTitles as $count => $title ) { + if ( strpos( $title, '*' ) !== 0 ) { + continue; + } + $title = preg_replace( "/^\\*\\s*/", '', $title ); + $title = Title::newFromText( $title, NS_CATEGORY ); + if ( $title ) { + $this->exceptionList[] = $title->getDBKey(); + } + } + } + return $this->exceptionList; + } + + public function getQueryInfo() { + $dbr = wfGetDB( DB_SLAVE ); + $query = parent::getQueryInfo(); + $exceptionList = $this->getExceptionList(); + if ( $exceptionList ) { + $query['conds'][] = 'page_title not in ( ' . $dbr->makeList( $exceptionList ) . ' )'; + } + + return $query; + } + /** * Formats the result * @param Skin $skin The current skin diff --git a/languages/i18n/en.json b/languages/i18n/en.json index a621f1c5b2..a53b2cce2d 100644 --- a/languages/i18n/en.json +++ b/languages/i18n/en.json @@ -1815,6 +1815,7 @@ "uncategorizedimages-summary": "", "uncategorizedtemplates": "Uncategorized templates", "uncategorizedtemplates-summary": "", + "uncategorized-categories-exceptionlist": " # Contains a list of catgeories, which shouldn't be mentioned on Special:UncategorizedCategories. One per line, starting with \"*\". Lines starting with another character (including whitespaces) are ignored. Use \"#\" for comments.", "unusedcategories": "Unused categories", "unusedcategories-summary": "", "unusedimages": "Unused files", diff --git a/languages/i18n/qqq.json b/languages/i18n/qqq.json index da43aef239..eee9b4e1d5 100644 --- a/languages/i18n/qqq.json +++ b/languages/i18n/qqq.json @@ -2000,6 +2000,7 @@ "uncategorizedimages-summary": "{{notranslate}}\nused in [[Special:Uncategorizedimages]]. [[mw:Manual:Interface/Special pages summary|mw manual]].", "uncategorizedtemplates": "{{doc-special|UncategorizedTemplates}}", "uncategorizedtemplates-summary": "{{doc-specialpagesummary|uncategorizedtemplates}}", + "uncategorized-categories-exceptionlist": "System message used as a list of exceptions for Special:UncategorizedCategories. {{notranslate}}", "unusedcategories": "{{doc-special|UnusedCategories}}", "unusedcategories-summary": "{{doc-specialpagesummary|unusedcategories}}", "unusedimages": "{{doc-special|UnusedImages}}", diff --git a/resources/src/mediawiki.messagePoster/mediawiki.messagePoster.factory.js b/resources/src/mediawiki.messagePoster/mediawiki.messagePoster.factory.js index b069d4ab4d..e20b422f14 100644 --- a/resources/src/mediawiki.messagePoster/mediawiki.messagePoster.factory.js +++ b/resources/src/mediawiki.messagePoster/mediawiki.messagePoster.factory.js @@ -63,18 +63,15 @@ api = apiUrl ? new mw.ForeignApi( apiUrl ) : new mw.Api(); return api.get( { + formatversion: 2, action: 'query', prop: 'info', - indexpageids: true, titles: title.getPrefixedDb() } ).then( function ( data ) { - var pageId, page, contentModel, moduleName; - if ( !data.query.pageids[ 0 ] ) { + var contentModel, moduleName, page = data.query.pages[ 0 ]; + if ( !page ) { return $.Deferred().reject( 'unexpected-response', 'Unexpected API response' ); } - pageId = data.query.pageids[ 0 ]; - page = data.query.pages[ pageId ]; - contentModel = page.contentmodel; moduleName = 'mediawiki.messagePoster.' + contentModel; return mw.loader.using( moduleName ).then( function () { diff --git a/resources/src/mediawiki/mediawiki.reasonSuggest.js b/resources/src/mediawiki/mediawiki.reasonSuggest.js index 9042278d07..71efdb07f7 100644 --- a/resources/src/mediawiki/mediawiki.reasonSuggest.js +++ b/resources/src/mediawiki/mediawiki.reasonSuggest.js @@ -3,14 +3,7 @@ */ ( function ( mw, $ ) { $( function () { - var api = new mw.Api(), reasons = []; - // These messages can be really big, so its loaded on-the-go - api.loadMessagesIfMissing( [ mw.config.get( 'reasons' ) ] ) - .done( function () { - // Convert from string to array, first index is unneeded - reasons = mw.msg( mw.config.get( 'reasons' ) ).split( '\n** ' ); - reasons.splice( 0, 1 ); - } ); + var reasons = mw.config.get( 'reasons' ); // Add relevant suggestion $( '#mwProtect-reason, #wpReason, #mw-input-wpReason-other' ).suggestions( { diff --git a/tests/common/TestSetup.php b/tests/common/TestSetup.php index 53e724bbed..38f56d20a1 100644 --- a/tests/common/TestSetup.php +++ b/tests/common/TestSetup.php @@ -1,7 +1,5 @@ replaceSearchEngineConfig(); diff --git a/tests/phpunit/includes/changes/TestRecentChangesHelper.php b/tests/phpunit/includes/changes/TestRecentChangesHelper.php index ae51a6c717..2f908feb63 100644 --- a/tests/phpunit/includes/changes/TestRecentChangesHelper.php +++ b/tests/phpunit/includes/changes/TestRecentChangesHelper.php @@ -1,5 +1,5 @@ assertEquals( 0, $sites->count() ); } + /** + * @param Site[] $sites + * + * @return SiteStore + */ private function getHashSiteStore( array $sites ) { $siteStore = new HashSiteStore(); $siteStore->saveSites( $sites ); diff --git a/tests/phpunit/includes/specials/SpecialUncategorizedcategoriesTest.php b/tests/phpunit/includes/specials/SpecialUncategorizedcategoriesTest.php new file mode 100644 index 0000000000..64e78f2828 --- /dev/null +++ b/tests/phpunit/includes/specials/SpecialUncategorizedcategoriesTest.php @@ -0,0 +1,62 @@ +getMockBuilder( 'RequestContext' )->getMock(); + $mockContext->method( 'msg' )->willReturn( $msg ); + $special = new UncategorizedCategoriesPage(); + $special->setContext( $mockContext ); + $this->assertEquals( [ + 'tables' => [ + 0 => 'page', + 1 => 'categorylinks', + ], + 'fields' => [ + 'namespace' => 'page_namespace', + 'title' => 'page_title', + 'value' => 'page_title', + ], + 'conds' => [ + 0 => 'cl_from IS NULL', + 'page_namespace' => 14, + 'page_is_redirect' => 0, + ] + $expected, + 'join_conds' => [ + 'categorylinks' => [ + 0 => 'LEFT JOIN', + 1 => 'cl_from = page_id', + ], + ], + ], $special->getQueryInfo() ); + } + + public function provideTestGetQueryInfoData() { + return [ + [ + "* Stubs\n* Test\n* *\n* * test123", + [ 1 => "page_title not in ( 'Stubs','Test','*','*_test123' )" ] + ], + [ + "Stubs\n* Test\n* *\n* * test123", + [ 1 => "page_title not in ( 'Test','*','*_test123' )" ] + ], + [ + "* StubsTest\n* *\n* * test123", + [ 1 => "page_title not in ( 'StubsTest','*','*_test123' )" ] + ], + [ "", [] ], + [ "\n\n\n", [] ], + [ "\n", [] ], + [ "Test\n*Test2", [ 1 => "page_title not in ( 'Test2' )" ] ], + [ "Test", [] ], + [ "*Test\nTest2", [ 1 => "page_title not in ( 'Test' )" ] ], + [ "Test\nTest2", [] ], + ]; + } +} diff --git a/tests/phpunit/structure/ExtensionJsonValidationTest.php b/tests/phpunit/structure/ExtensionJsonValidationTest.php index 8ba2aeb241..b19376d388 100644 --- a/tests/phpunit/structure/ExtensionJsonValidationTest.php +++ b/tests/phpunit/structure/ExtensionJsonValidationTest.php @@ -16,9 +16,6 @@ * http://www.gnu.org/copyleft/gpl.html */ -use Composer\Spdx\SpdxLicenses; -use JsonSchema\Validator; - /** * Validates all loaded extensions and skins using the ExtensionRegistry * against the extension.json schema in the docs/ folder.