From: Bryan Davis Date: Wed, 27 Jan 2016 17:26:42 +0000 (-0700) Subject: Support language fallbacks for Special:MyLanguage X-Git-Tag: 1.31.0-rc.0~1652 X-Git-Url: http://git.cyclocoop.org/%7D%7Cconcat%7B?a=commitdiff_plain;h=b8332e99160f8a3ef5351a618c0cb29464fbe3dd;p=lhc%2Fweb%2Fwiklou.git Support language fallbacks for Special:MyLanguage Add fallback lookup based on the interface language to Special:MyLanguage. Lookup order: -> -> -> Example when the user's lang is arz: arz -> -> ar -> en -> Bug: T50292 Change-Id: I245cab71fdd4b4585f86dde808493cd69841b09a --- diff --git a/includes/specials/SpecialMyLanguage.php b/includes/specials/SpecialMyLanguage.php index 9cb6d4b529..37d96f47cc 100644 --- a/includes/specials/SpecialMyLanguage.php +++ b/includes/specials/SpecialMyLanguage.php @@ -81,6 +81,7 @@ class SpecialMyLanguage extends RedirectSpecialArticle { } if ( !$base ) { + // No subpage provided or base page does not exist return null; } @@ -90,14 +91,38 @@ class SpecialMyLanguage extends RedirectSpecialArticle { } $uiCode = $this->getLanguage()->getCode(); + $wikiLangCode = $this->getConfig()->get( 'LanguageCode' ); + + if ( $uiCode === $wikiLangCode ) { + // Short circuit when the current UI language is the + // wiki's default language to avoid unnecessary page lookups. + return $base; + } + + // Check for a subpage in current UI language $proposed = $base->getSubpage( $uiCode ); - if ( $proposed && $proposed->exists() && $uiCode !== $base->getPageLanguage()->getCode() ) { + if ( $proposed && $proposed->exists() ) { return $proposed; - } elseif ( $provided && $provided->exists() ) { + } + + if ( $provided !== $base && $provided->exists() ) { + // Explicit language code given and the page exists return $provided; - } else { - return $base; } + + // Check for fallback languages specified by the UI language + $possibilities = Language::getFallbacksFor( $uiCode ); + foreach ( $possibilities as $lang ) { + if ( $lang !== $wikiLangCode ) { + $proposed = $base->getSubpage( $lang ); + if ( $proposed && $proposed->exists() ) { + return $proposed; + } + } + } + + // When all else has failed, return the base page + return $base; } /** diff --git a/tests/phpunit/includes/specials/SpecialMyLanguageTest.php b/tests/phpunit/includes/specials/SpecialMyLanguageTest.php index 89fd1b0696..84fa71a2c6 100644 --- a/tests/phpunit/includes/specials/SpecialMyLanguageTest.php +++ b/tests/phpunit/includes/specials/SpecialMyLanguageTest.php @@ -8,7 +8,10 @@ class SpecialMyLanguageTest extends MediaWikiTestCase { public function addDBDataOnce() { $titles = [ 'Page/Another', + 'Page/Another/ar', + 'Page/Another/en', 'Page/Another/ru', + 'Page/Another/zh-hans', ]; foreach ( $titles as $title ) { $page = WikiPage::factory( Title::newFromText( $title ) ); @@ -54,12 +57,22 @@ class SpecialMyLanguageTest extends MediaWikiTestCase { } public static function provideFindTitle() { + // See addDBDataOnce() for page declarations return [ + // [ $expected, $subpage, $langCode, $userLang ] [ null, '::Fail', 'en', 'en' ], [ 'Page/Another', 'Page/Another/en', 'en', 'en' ], [ 'Page/Another', 'Page/Another', 'en', 'en' ], [ 'Page/Another/ru', 'Page/Another', 'en', 'ru' ], [ 'Page/Another', 'Page/Another', 'en', 'es' ], + [ 'Page/Another/zh-hans', 'Page/Another', 'en', 'zh-hans' ], + [ 'Page/Another/zh-hans', 'Page/Another', 'en', 'zh-mo' ], + [ 'Page/Another/en', 'Page/Another', 'de', 'es' ], + [ 'Page/Another/ar', 'Page/Another', 'en', 'ar' ], + [ 'Page/Another/ar', 'Page/Another', 'en', 'arz' ], + [ 'Page/Another/ar', 'Page/Another/de', 'en', 'arz' ], + [ 'Page/Another/ru', 'Page/Another/ru', 'en', 'arz' ], + [ 'Page/Another/ar', 'Page/Another/ru', 'en', 'ar' ], ]; } }