From 062cfffeb2d132ead4d7d786c96dce5e7a0bc557 Mon Sep 17 00:00:00 2001 From: Max Semenik Date: Thu, 19 Jun 2014 11:36:56 -0700 Subject: [PATCH] Integrate Special:MyLanguage from the Translate extension In practice, this means the MediaWiki canonical way to uniquely and humanly name translation pages on a multilingual wiki becomes $source_page_title + '/' + $target_language_code, irrespective of the enabling of the navigational subtitle and of the relative titles (..) syntax for linking and transcluding, which are unrelated and keep being controlled by $wgNamespacesWithSubpages. This syntax has been prevalent on most wikis including mediawiki.org since at least 2009, also thanks to #titleparts in ParserFunctions. The part of the special page's functionality that made links to it red when destination page wasn't present will be integrated with a follow-up commit because they require more performance work. I'm also including some Title tests that were written for testing the redlinking functionality but are useful in general. Bug: 66762 Change-Id: I520077c931431b5919e0208f75c20b5b25f3159d --- RELEASE-NOTES-1.24 | 2 + includes/AutoLoader.php | 1 + includes/specialpage/SpecialPageFactory.php | 1 + includes/specials/SpecialMyLanguage.php | 94 +++++++++++++++++++ languages/messages/MessagesEn.php | 1 + tests/phpunit/includes/TitleTest.php | 37 ++++++++ .../specials/SpecialMyLanguageTest.php | 65 +++++++++++++ 7 files changed, 201 insertions(+) create mode 100644 includes/specials/SpecialMyLanguage.php create mode 100644 tests/phpunit/includes/specials/SpecialMyLanguageTest.php diff --git a/RELEASE-NOTES-1.24 b/RELEASE-NOTES-1.24 index 680a641429..6c85e4d121 100644 --- a/RELEASE-NOTES-1.24 +++ b/RELEASE-NOTES-1.24 @@ -129,6 +129,8 @@ production. * (bug 68085) Links of the form [[localInterwikiPrefix:languageCode:pageTitle]], where localInterwikiPrefix is a member of the $wgLocalInterwikis array, will no longer be displayed in the sidebar when $wgInterwikiMagic is true. +* New special page, MyLanguages, to redirect users to subpages with localised + versions of a page. (Integrated from Extension:Translate) === Bug fixes in 1.24 === * (bug 49116) Footer copyright notice is now always displayed in user language diff --git a/includes/AutoLoader.php b/includes/AutoLoader.php index 046a0df8bc..22a971cca7 100644 --- a/includes/AutoLoader.php +++ b/includes/AutoLoader.php @@ -1011,6 +1011,7 @@ $wgAutoloadLocalClasses = array( 'SpecialLog' => 'includes/specials/SpecialLog.php', 'SpecialMergeHistory' => 'includes/specials/SpecialMergeHistory.php', 'SpecialMycontributions' => 'includes/specials/SpecialMyRedirectPages.php', + 'SpecialMyLanguage' => 'includes/specials/SpecialMyLanguage.php', 'SpecialMypage' => 'includes/specials/SpecialMyRedirectPages.php', 'SpecialMytalk' => 'includes/specials/SpecialMyRedirectPages.php', 'SpecialMyuploads' => 'includes/specials/SpecialMyRedirectPages.php', diff --git a/includes/specialpage/SpecialPageFactory.php b/includes/specialpage/SpecialPageFactory.php index 9ff96ab941..07b6b4e0f2 100644 --- a/includes/specialpage/SpecialPageFactory.php +++ b/includes/specialpage/SpecialPageFactory.php @@ -160,6 +160,7 @@ class SpecialPageFactory { 'Emailuser' => 'SpecialEmailUser', 'Movepage' => 'MovePageForm', 'Mycontributions' => 'SpecialMycontributions', + 'MyLanguage' => 'SpecialMyLanguage', 'Mypage' => 'SpecialMypage', 'Mytalk' => 'SpecialMytalk', 'Myuploads' => 'SpecialMyuploads', diff --git a/includes/specials/SpecialMyLanguage.php b/includes/specials/SpecialMyLanguage.php new file mode 100644 index 0000000000..01bf0ecaa1 --- /dev/null +++ b/includes/specials/SpecialMyLanguage.php @@ -0,0 +1,94 @@ +findTitle( $par ); + // Go to the main page if given invalid title. + if ( !$title ) { + $title = Title::newMainPage(); + } + return $title; + } + + /** + * Assuming the user's interface language is fi. Given input Page, it + * returns Page/fi if it exists, otherwise Page. Given input Page/de, + * it returns Page/fi if it exists, otherwise Page/de if it exists, + * otherwise Page. + * + * @param $par + * @return Title|null + */ + public function findTitle( $par ) { + global $wgLanguageCode; + // base = title without language code suffix + // provided = the title as it was given + $base = $provided = Title::newFromText( $par ); + + if ( $base && strpos( $par, '/' ) !== false ) { + $pos = strrpos( $par, '/' ); + $basepage = substr( $par, 0, $pos ); + $code = substr( $par, $pos + 1 ); + if ( Language::isKnownLanguageTag( $code ) ) { + $base = Title::newFromText( $basepage ); + } + } + + if ( !$base ) { + return null; + } + + $uiCode = $this->getLanguage()->getCode(); + $proposed = $base->getSubpage( $uiCode ); + if ( $uiCode !== $wgLanguageCode && $proposed && $proposed->exists() ) { + return $proposed; + } elseif ( $provided && $provided->exists() ) { + return $provided; + } else { + return $base; + } + } +} diff --git a/languages/messages/MessagesEn.php b/languages/messages/MessagesEn.php index 0797bcf3fb..e2cd265f1b 100644 --- a/languages/messages/MessagesEn.php +++ b/languages/messages/MessagesEn.php @@ -437,6 +437,7 @@ $specialPageAliases = array( 'Mostrevisions' => array( 'MostRevisions' ), 'Movepage' => array( 'MovePage' ), 'Mycontributions' => array( 'MyContributions' ), + 'MyLanguage' => array( 'MyLanguage' ), 'Mypage' => array( 'MyPage' ), 'Mytalk' => array( 'MyTalk' ), 'Myuploads' => array( 'MyUploads', 'MyFiles' ), diff --git a/tests/phpunit/includes/TitleTest.php b/tests/phpunit/includes/TitleTest.php index 68715824af..12dda8982d 100644 --- a/tests/phpunit/includes/TitleTest.php +++ b/tests/phpunit/includes/TitleTest.php @@ -20,6 +20,19 @@ class TitleTest extends MediaWikiTestCase { ) ); } + public function addDBData() { + $this->db->replace( 'interwiki', 'iw_prefix', + array( + 'iw_prefix' => 'externalwiki', + 'iw_url' => '//example.com/$1', + 'iw_api' => '//example.com/api.php', + 'iw_wikiid' => '', + 'iw_local' => 0, + 'iw_trans' => 0, + ) + ); + } + /** * @covers Title::legalChars */ @@ -606,4 +619,28 @@ class TitleTest extends MediaWikiTestCase { $title = Title::newFromText( $full ); $this->assertEquals( $fragment, $title->getFragment() ); } + + /** + * @covers Title::isAlwaysKnown + * @dataProvider provideIsAlwaysKnown + * @param string $page + * @param bool $isKnown + */ + public function testIsAlwaysKnown( $page, $isKnown ) { + $title = Title::newFromText( $page ); + $this->assertEquals( $isKnown, $title->isAlwaysKnown() ); + } + + public function provideIsAlwaysKnown() { + return array( + array( 'Some nonexistent page', false ), + array( 'UTPage', false ), + array( '#test', true ), + array( 'Special:BlankPage', true ), + array( 'Special:SomeNonexistentSpecialPage', false ), + array( 'MediaWiki:Parentheses', true ), + array( 'MediaWiki:Some nonexistent message', false ), + array( 'externalwiki:Interwiki link', true ), + ); + } } diff --git a/tests/phpunit/includes/specials/SpecialMyLanguageTest.php b/tests/phpunit/includes/specials/SpecialMyLanguageTest.php new file mode 100644 index 0000000000..020d436216 --- /dev/null +++ b/tests/phpunit/includes/specials/SpecialMyLanguageTest.php @@ -0,0 +1,65 @@ +getId() == 0 ) { + $page->doEditContent( + new WikitextContent( 'UTContent' ), + 'UTPageSummary', + EDIT_NEW, + false, + User::newFromName( 'UTSysop' ) ); + } + } + } + + /** + * @covers SpecialMyLanguage::findTitle + * @dataProvider provideFindTitle + * @param $expected + * @param $subpage + * @param $langCode + * @param $userLang + */ + public function testFindTitle( $expected, $subpage, $langCode, $userLang ) { + $this->setMwGlobals( 'wgLanguageCode', $langCode ); + $special = new SpecialMyLanguage(); + $special->getContext()->setLanguage( $userLang ); + // Test with subpages both enabled and disabled + $this->mergeMwGlobalArrayValue( 'wgNamespacesWithSubpages', array( NS_MAIN => true ) ); + $this->assertTitle( $expected, $special->findTitle( $subpage ) ); + $this->mergeMwGlobalArrayValue( 'wgNamespacesWithSubpages', array( NS_MAIN => false ) ); + $this->assertTitle( $expected, $special->findTitle( $subpage ) ); + } + + /** + * @param string $expected + * @param Title|null $title + */ + private function assertTitle( $expected, $title ) { + if ( $title ) { + $title = $title->getPrefixedText(); + } + $this->assertEquals( $expected, $title ); + } + + public function provideFindTitle() { + return array( + array( null, '::Fail', 'en', 'en' ), + array( 'Page/Another', 'Page/Another/en', 'en', 'en' ), + array( 'Page/Another', 'Page/Another', 'en', 'en' ), + array( 'Page/Another/ru', 'Page/Another', 'en', 'ru' ), + array( 'Page/Another', 'Page/Another', 'en', 'es' ), + ); + } +} \ No newline at end of file -- 2.20.1