Extract language/variants check to a service

The $hasLangauges and $hasVariants checks were used in couple places,
which lead to the same code used in many places.
Following the DRY rule, let's implement a Service that can do that
check, and use that service everywhere in code.

Bug: T224735
Change-Id: I46d58758356e870c408a74b2c087a42d6ad0ddea
This commit is contained in:
Piotr Miazga 2019-07-09 18:10:31 +02:00 committed by Jdlrobson
parent dee1c197b9
commit d7f60a26db
10 changed files with 207 additions and 73 deletions

View File

@ -0,0 +1,51 @@
<?php
/**
* 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
*/
namespace MediaWiki\Minerva;
use OutputPage;
use Title;
/**
* Helper class to encapsulate logic responsible for checking languages and variants for given title
* @package MediaWiki\Minerva
*/
class LanguagesHelper {
/**
* @var bool
*/
private $hasLanguages;
/**
* @param OutputPage $out Output page to fetch language links
*/
public function __construct( OutputPage $out ) {
$this->hasLanguages = !empty( $out->getLanguageLinks() );
}
/**
* Whether the Title is also available in other languages or variants
* @param Title $title
* @return bool
*/
public function doesTitleHasLanguagesOrVariants( Title $title ) {
return $this->hasLanguages || $title->getPageLanguage()->hasVariants();
}
}

View File

@ -20,6 +20,7 @@
*/
use MediaWiki\MediaWikiServices;
use MediaWiki\Minerva\LanguagesHelper;
use MediaWiki\Minerva\Menu\Definitions;
use MediaWiki\Minerva\Menu\Main as MainMenu;
use MediaWiki\Minerva\Menu\PageActions as PageActionsMenu;
@ -53,9 +54,9 @@ return [
$skinOptions = $services->getService( 'Minerva.SkinOptions' );
$context = RequestContext::getMain();
$title = $context->getTitle();
$output = $context->getOutput();
$user = $context->getUser();
$userPageHelper = $services->getService( 'Minerva.SkinUserPageHelper' );
$languagesHelper = $services->getService( 'Minerva.LanguagesHelper' );
$toolbarBuilder = new PageActionsMenu\ToolbarBuilder(
$title,
$user,
@ -63,18 +64,17 @@ return [
$services->getPermissionManager(),
$services->getService( 'Minerva.Permissions' ),
$skinOptions,
$services->get( 'Minerva.SkinUserPageHelper' )
$userPageHelper,
$languagesHelper
);
if ( $skinOptions->get( SkinOptions::OPTION_OVERFLOW_SUBMENU ) ) {
$hasVariants = $title->getPageLanguage()->hasVariants();
$hasLanguages = count( $output->getLanguageLinks() );
$overflowBuilder = $userPageHelper->isUserPage() ?
new PageActionsMenu\UserNamespaceOverflowBuilder(
$title,
$context,
$userPageHelper,
$services->getService( 'Minerva.Permissions' ),
$hasVariants || $hasLanguages
$languagesHelper
) :
new PageActionsMenu\DefaultOverflowBuilder(
$context
@ -92,6 +92,9 @@ return [
'Minerva.SkinUserPageHelper' => function (): SkinUserPageHelper {
return new SkinUserPageHelper( RequestContext::getMain()->getTitle() );
},
'Minerva.LanguagesHelper' => function (): LanguagesHelper {
return new LanguagesHelper( RequestContext::getMain()->getOutput() );
},
'Minerva.SkinOptions' => function (): SkinOptions {
return new SkinOptions();
},
@ -107,9 +110,9 @@ return [
$context->getTitle(),
$context->getConfig(),
$context->getUser(),
$context->getOutput(),
$services->getService( 'Minerva.SkinOptions' ),
$contentHandler
$contentHandler,
$services->getService( 'Minerva.LanguagesHelper' )
);
} else {
return new MinervaNoPagePermissions();

View File

@ -51,8 +51,11 @@ final class PageActionsDirector {
* @param IOverflowBuilder $overflowBuilder The overflow menu builder
* @param MessageLocalizer $messageLocalizer Message localizer used to translate texts
*/
public function __construct( ToolbarBuilder $toolbarBuilder, IOverflowBuilder $overflowBuilder,
MessageLocalizer $messageLocalizer ) {
public function __construct(
ToolbarBuilder $toolbarBuilder,
IOverflowBuilder $overflowBuilder,
MessageLocalizer $messageLocalizer
) {
$this->toolbarBuilder = $toolbarBuilder;
$this->overflowBuilder = $overflowBuilder;
$this->messageLocalizer = $messageLocalizer;
@ -61,12 +64,11 @@ final class PageActionsDirector {
/**
* Build the menu data array that can be passed to views/javascript
* @param array $toolbox An array of common toolbox items from the sidebar menu
* @param bool $doesHaveLangUrls Whether the page is also available in other languages or variants
* @return array
* @throws MWException
*/
public function buildMenu( array $toolbox, $doesHaveLangUrls ): array {
$toolbar = $this->toolbarBuilder->getGroup( $doesHaveLangUrls );
public function buildMenu( array $toolbox ): array {
$toolbar = $this->toolbarBuilder->getGroup();
$overflowMenu = $this->overflowBuilder->getGroup( $toolbox );
$menu = [

View File

@ -22,6 +22,7 @@ namespace MediaWiki\Minerva\Menu\PageActions;
use ExtensionRegistry;
use Hooks;
use MediaWiki\Minerva\LanguagesHelper;
use MediaWiki\Minerva\Menu\Entries\IMenuEntry;
use MediaWiki\Minerva\Menu\Entries\LanguageSelectorEntry;
use MediaWiki\Minerva\Menu\Group;
@ -71,6 +72,11 @@ class ToolbarBuilder {
* @var SkinUserPageHelper
*/
private $userPageHelper;
/**
* @var LanguagesHelper
*/
private $languagesHelper;
/**
* Build Group containing icons for toolbar
* @param Title $title Article title user is currently browsing
@ -80,6 +86,7 @@ class ToolbarBuilder {
* @param IMinervaPagePermissions $permissions Minerva permissions system
* @param SkinOptions $skinOptions Skin options
* @param SkinUserPageHelper $userPageHelper User Page helper
* @param LanguagesHelper $languagesHelper Helper to check title languages/variants
*/
public function __construct(
Title $title,
@ -88,7 +95,8 @@ class ToolbarBuilder {
PermissionManager $permissionManager,
IMinervaPagePermissions $permissions,
SkinOptions $skinOptions,
SkinUserPageHelper $userPageHelper
SkinUserPageHelper $userPageHelper,
LanguagesHelper $languagesHelper
) {
$this->title = $title;
$this->user = $user;
@ -97,15 +105,14 @@ class ToolbarBuilder {
$this->permissions = $permissions;
$this->skinOptions = $skinOptions;
$this->userPageHelper = $userPageHelper;
$this->languagesHelper = $languagesHelper;
}
/**
* @param bool $doesPageHaveLanguages Whether the page is also available in other languages
* or variants
* @return Group
* @throws MWException
*/
public function getGroup( $doesPageHaveLanguages ): Group {
public function getGroup(): Group {
$group = new Group();
$permissions = $this->permissions;
$userPageWithOveflowMode = $this->skinOptions->get( SkinOptions::OPTION_OVERFLOW_SUBMENU ) &&
@ -115,7 +122,7 @@ class ToolbarBuilder {
IMinervaPagePermissions::SWITCH_LANGUAGE ) ) {
$group->insertEntry( new LanguageSelectorEntry(
$this->title,
$doesPageHaveLanguages,
$this->languagesHelper->doesTitleHasLanguagesOrVariants( $this->title ),
$this->messageLocalizer,
MinervaUI::iconClass( 'language-switcher', 'element', '' ) )
);

View File

@ -21,6 +21,7 @@
namespace MediaWiki\Minerva\Menu\PageActions;
use Hooks;
use MediaWiki\Minerva\LanguagesHelper;
use MediaWiki\Minerva\Menu\Group;
use MediaWiki\Minerva\Menu\Entries\LanguageSelectorEntry;
use MediaWiki\Minerva\Permissions\IMinervaPagePermissions;
@ -55,9 +56,9 @@ class UserNamespaceOverflowBuilder implements IOverflowBuilder {
private $permissions;
/**
* @var bool
* @var LanguagesHelper
*/
private $doesPageHaveLanguages;
private $languagesHelper;
/**
* Initialize the overflow menu visible on the User namespace
@ -65,20 +66,20 @@ class UserNamespaceOverflowBuilder implements IOverflowBuilder {
* @param MessageLocalizer $msgLocalizer
* @param SkinUserPageHelper $userPageHelper
* @param IMinervaPagePermissions $permissions
* @param bool $doesPageHaveLanguages
* @param LanguagesHelper $languagesHelper
*/
public function __construct(
Title $title,
MessageLocalizer $msgLocalizer,
SkinUserPageHelper $userPageHelper,
IMinervaPagePermissions $permissions,
$doesPageHaveLanguages
LanguagesHelper $languagesHelper
) {
$this->title = $title;
$this->messageLocalizer = $msgLocalizer;
$this->pageUser = $userPageHelper->getPageUser();
$this->permissions = $permissions;
$this->doesPageHaveLanguages = $doesPageHaveLanguages;
$this->languagesHelper = $languagesHelper;
}
/**
@ -88,8 +89,10 @@ class UserNamespaceOverflowBuilder implements IOverflowBuilder {
public function getGroup( array $toolbox ): Group {
$group = new Group();
if ( $this->permissions->isAllowed( IMinervaPagePermissions::SWITCH_LANGUAGE ) ) {
$group->insertEntry( new LanguageSelectorEntry( $this->title,
$this->doesPageHaveLanguages, $this->messageLocalizer,
$group->insertEntry( new LanguageSelectorEntry(
$this->title,
$this->languagesHelper->doesTitleHasLanguagesOrVariants( $this->title ),
$this->messageLocalizer,
MinervaUI::iconClass( 'language-switcher-base20', 'before',
'minerva-page-actions-language-switcher toggle-list-item__anchor--menu' ),
'minerva-page-actions-language-switcher'

View File

@ -22,8 +22,8 @@ namespace MediaWiki\Minerva\Permissions;
use Config;
use ConfigException;
use ContentHandler;
use MediaWiki\Minerva\LanguagesHelper;
use MediaWiki\Minerva\SkinOptions;
use OutputPage;
use Title;
use User;
@ -51,39 +51,39 @@ final class MinervaPagePermissions implements IMinervaPagePermissions {
*/
private $contentHandler;
/**
* @var OutputPage just to retrieve list of language links
*/
private $output;
/**
* @var SkinOptions Minerva skin options
*/
private $skinOptions;
/**
* @var LanguagesHelper
*/
private $languagesHelper;
/**
* Initialize internal Minerva Permissions system
* @param Title $title Current page title
* @param Config $config Minerva config
* @param User $user Currently logged in user
* @param OutputPage $output Output page used to fetch languages
* @param SkinOptions $skinOptions Skin options`
* @param ContentHandler $contentHandler
* @param LanguagesHelper $languagesHelper
*/
public function __construct(
Title $title,
Config $config,
User $user,
OutputPage $output,
SkinOptions $skinOptions,
ContentHandler $contentHandler
ContentHandler $contentHandler,
LanguagesHelper $languagesHelper
) {
$this->title = $title;
$this->config = $config;
$this->user = $user;
$this->output = $output;
$this->skinOptions = $skinOptions;
$this->contentHandler = $contentHandler;
$this->languagesHelper = $languagesHelper;
}
/**
@ -148,11 +148,8 @@ final class MinervaPagePermissions implements IMinervaPagePermissions {
if ( $wgHideInterlanguageLinks ) {
return false;
}
$hasVariants = $this->title->getPageLanguage()->hasVariants();
$hasLanguages = count( $this->output->getLanguageLinks() );
return $hasVariants || $hasLanguages ||
$this->config->get( 'MinervaAlwaysShowLanguageButton' );
return $this->languagesHelper->doesTitleHasLanguagesOrVariants( $this->title ) ||
$this->config->get( 'MinervaAlwaysShowLanguageButton' );
}
return true;
}

View File

@ -39,9 +39,6 @@ class SkinMinerva extends SkinTemplate {
/** @var string $template Name of this used template */
public $template = 'MinervaTemplate';
/** @var bool Whether the page is also available in other languages or variants */
protected $doesPageHaveLanguages = false;
/** @var SkinOptions */
private $skinOptions;
@ -152,9 +149,6 @@ class SkinMinerva extends SkinTemplate {
// Generate skin template
$tpl = parent::prepareQuickTemplate();
$this->doesPageHaveLanguages = $tpl->data['content_navigation']['variants'] ||
$tpl->data['language_urls'];
// Set whether or not the page content should be wrapped in div.content (for
// example, on a special page)
$tpl->set( 'unstyledContent', $out->getProperty( 'unstyledContent' ) );
@ -713,8 +707,10 @@ class SkinMinerva extends SkinTemplate {
* @return array
*/
protected function getSecondaryActions( BaseTemplate $tpl ) {
/** @var \MediaWiki\Minerva\LanguagesHelper $languagesHelper */
$languagesHelper = MediaWikiServices::getInstance()
->getService( 'Minerva.LanguagesHelper' );
$buttons = [];
// always add a button to link to the talk page
// in beta it will be the entry point for the talk overlay feature,
// in stable it will link to the wikitext talk page
@ -742,7 +738,7 @@ class SkinMinerva extends SkinTemplate {
}
}
if ( $this->doesPageHaveLanguages && $title->isMainPage() ) {
if ( $languagesHelper->doesTitleHasLanguagesOrVariants( $title ) && $title->isMainPage() ) {
$buttons['language'] = $this->getLanguageButton();
}
@ -766,7 +762,7 @@ class SkinMinerva extends SkinTemplate {
/** @var \MediaWiki\Minerva\Menu\PageActions\PageActionsDirector $director */
$director = MediaWikiServices::getInstance()->getService( 'Minerva.Menu.PageActionsDirector' );
$tpl->set( 'page_actions',
$director->buildMenu( $tpl->getToolbox(), $this->doesPageHaveLanguages )
$director->buildMenu( $tpl->getToolbox() )
);
}

View File

@ -86,6 +86,7 @@
"MediaWiki\\Minerva\\MenuBuilder": "includes/menu/Group.php",
"MediaWiki\\Minerva\\ResourceLoaderLessVarFileModule": "includes/ResourceLoaderLessVarFileModule.php",
"MediaWiki\\Minerva\\SkinOptions": "includes/SkinOptions.php",
"MediaWiki\\Minerva\\LanguagesHelper": "includes/LanguagesHelper.php",
"MediaWiki\\Minerva\\SkinUserPageHelper": "includes/skins/SkinUserPageHelper.php"
},
"ConfigRegistry": {

View File

@ -3,13 +3,12 @@
namespace Tests\MediaWiki\Minerva;
use ContentHandler;
use MediaWiki\Minerva\LanguagesHelper;
use MediaWiki\Minerva\Permissions\IMinervaPagePermissions;
use MediaWiki\Minerva\Permissions\MinervaPagePermissions;
use MediaWiki\Minerva\SkinOptions;
use MediaWikiTestCase;
use OutputPage;
use Title;
use RequestContext;
use User;
/**
@ -24,10 +23,19 @@ class MinervaPagePermissionsTest extends MediaWikiTestCase {
array $options = [],
ContentHandler $contentHandler = null,
User $user = null,
OutputPage $outputPage = null,
$hasOtherLanguagesOrVariants = false,
$alwaysShowLanguageButton = true
) {
$outputPage = $outputPage ?? RequestContext::getMain()->getOutput();
$languageHelper = $this->getMock(
LanguagesHelper::class,
[ 'doesTitleHasLanguagesOrVariants' ],
[],
'',
false
);
$languageHelper->expects( $this->any() )
->method( 'doesTitleHasLanguagesOrVariants' )
->willReturn( $hasOtherLanguagesOrVariants );
$user = $user ?? $this->getTestUser()->getUser();
$actions = $actions ?? [
@ -36,7 +44,6 @@ class MinervaPagePermissionsTest extends MediaWikiTestCase {
IMinervaPagePermissions::TALK,
IMinervaPagePermissions::SWITCH_LANGUAGE,
];
$contentHandler = $contentHandler ??
$this->getMockForAbstractClass( ContentHandler::class, [], '', false );
$skinOptions = new SkinOptions();
@ -51,9 +58,9 @@ class MinervaPagePermissionsTest extends MediaWikiTestCase {
'MinervaAlwaysShowLanguageButton' => $alwaysShowLanguageButton
] ),
$user,
$outputPage,
$skinOptions,
$contentHandler
$contentHandler,
$languageHelper
);
}
@ -144,10 +151,9 @@ class MinervaPagePermissionsTest extends MediaWikiTestCase {
public static function switchLanguagePageActionProvider() {
return [
[ true, true, false, true ],
[ false, false, true, true ],
[ false, false, false, false ],
[ true, false, false, true ],
[ true, false, true ],
[ false, true, true ],
[ false, false, false ],
];
}
@ -182,25 +188,14 @@ class MinervaPagePermissionsTest extends MediaWikiTestCase {
* @covers ::isAllowed
*/
public function testSwitchLanguagePageAction(
$hasLanguages,
$hasVariants,
$hasLanguagesOrVariants,
$minervaAlwaysShowLanguageButton,
$expected
) {
$out = RequestContext::getMain()->getOutput();
$out->setLanguageLinks( $hasLanguages ? [ 'pl:StronaTestowa', 'en:TestPage' ] : [] );
$languageMock = $this->getMock( \Language::class, [ 'hasVariants' ], [], '', false );
$languageMock->expects( $this->once() )
->method( 'hasVariants' )
->willReturn( $hasVariants );
$title = $this->getMock( Title::class, [ 'isMainPage', 'getPageLanguage' ] );
$title = $this->getMock( Title::class, [ 'isMainPage' ] );
$title->expects( $this->once() )
->method( 'isMainPage' )
->willReturn( false );
$title->expects( $this->once() )
->method( 'getPageLanguage' )
->willReturn( $languageMock );
$permissions = $this->buildPermissionsObject(
$title,
@ -208,7 +203,7 @@ class MinervaPagePermissionsTest extends MediaWikiTestCase {
[],
null,
null,
$out,
$hasLanguagesOrVariants,
$minervaAlwaysShowLanguageButton
);

View File

@ -0,0 +1,79 @@
<?php
namespace Tests\MediaWiki\Minerva;
use MediaWiki\Minerva\LanguagesHelper;
use PHPUnit\Framework\MockObject\Invocation;
/**
* Class SkinMinervaTest
* @package Tests\MediaWiki\Minerva
* @group MinervaNeue
* @coversDefaultClass \MediaWiki\Minerva\LanguagesHelper
*/
class LanguagesHelperTest extends \MediaWikiUnitTestCase {
/**
* Build test Output object
* @param array $langLinks
* @return \OutputPage
*/
private function getOutput( array $langLinks ) {
$out = $this->getMock(
\OutputPage::class,
[ 'getLanguageLinks' ],
[],
'',
false
);
$out->expects( $this->once() )
->method( 'getLanguageLinks' )
->willReturn( $langLinks );
return $out;
}
/**
* Build test Title object
* @param $hasVariants
* @param Invocation|null $matcher
* @return \Title
*/
private function getTitle( $hasVariants, Invocation $matcher = null ) {
$languageMock = $this->getMock( \Language::class, [ 'hasVariants' ], [], '', false );
$languageMock->expects( $matcher ?? $this->any() )
->method( 'hasVariants' )
->willReturn( $hasVariants );
$title = $this->getMock( \Title::class, [ 'getPageLanguage' ] );
$title->expects( $matcher ?? $this->any() )
->method( 'getPageLanguage' )
->willReturn( $languageMock );
return $title;
}
/**
* @covers ::__construct
* @covers ::doesTitleHasLanguagesOrVariants
*/
public function testReturnsWhenOutputPageHasLangLinks() {
$helper = new LanguagesHelper( $this->getOutput( [ 'pl:StronaTestowa', 'en:TestPage' ] ) );
$this->assertTrue( $helper->doesTitleHasLanguagesOrVariants( $this->getTitle( false ) ) );
$this->assertTrue( $helper->doesTitleHasLanguagesOrVariants( $this->getTitle( true ) ) );
}
/**
* @covers ::__construct
* @covers ::doesTitleHasLanguagesOrVariants
*/
public function testReturnsWhenOutputDoesNotHaveLangLinks() {
$helper = new LanguagesHelper( $this->getOutput( [] ) );
$this->assertFalse( $helper->doesTitleHasLanguagesOrVariants(
$this->getTitle( false ), $this->once() ) );
$this->assertTrue( $helper->doesTitleHasLanguagesOrVariants(
$this->getTitle( true ), $this->once() ) );
}
}