2019-05-23 22:34:10 +00:00
|
|
|
<?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\Menu\PageActions;
|
|
|
|
|
|
|
|
use ExtensionRegistry;
|
|
|
|
use Hooks;
|
2019-07-09 16:10:31 +00:00
|
|
|
use MediaWiki\Minerva\LanguagesHelper;
|
2019-07-01 18:06:01 +00:00
|
|
|
use MediaWiki\Minerva\Menu\Entries\IMenuEntry;
|
|
|
|
use MediaWiki\Minerva\Menu\Entries\LanguageSelectorEntry;
|
2019-05-23 22:34:10 +00:00
|
|
|
use MediaWiki\Minerva\Menu\Group;
|
2019-05-24 00:07:27 +00:00
|
|
|
use MediaWiki\Minerva\Permissions\IMinervaPagePermissions;
|
2019-06-24 16:15:06 +00:00
|
|
|
use MediaWiki\Minerva\SkinOptions;
|
|
|
|
use MediaWiki\Minerva\SkinUserPageHelper;
|
2019-05-23 23:14:06 +00:00
|
|
|
use MediaWiki\Permissions\PermissionManager;
|
2019-05-23 22:34:10 +00:00
|
|
|
use MessageLocalizer;
|
|
|
|
use MinervaUI;
|
|
|
|
use MWException;
|
|
|
|
use SkinMinerva;
|
|
|
|
use SpecialMobileHistory;
|
|
|
|
use SpecialPage;
|
|
|
|
use Title;
|
|
|
|
use User;
|
|
|
|
|
|
|
|
class ToolbarBuilder {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var User Currently logged in user
|
|
|
|
*/
|
|
|
|
private $user;
|
|
|
|
/**
|
|
|
|
* @var Title Article title user is currently browsing
|
|
|
|
*/
|
|
|
|
private $title;
|
|
|
|
/**
|
|
|
|
* @var MessageLocalizer Message localizer to generate localized texts
|
|
|
|
*/
|
|
|
|
private $messageLocalizer;
|
2019-05-24 00:07:27 +00:00
|
|
|
/**
|
|
|
|
* @var IMinervaPagePermissions
|
|
|
|
*/
|
|
|
|
private $permissions;
|
2019-05-23 22:34:10 +00:00
|
|
|
|
2019-05-23 23:14:06 +00:00
|
|
|
/**
|
|
|
|
* @var PermissionManager
|
|
|
|
*/
|
|
|
|
private $permissionsManager;
|
2019-06-24 16:15:06 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @var SkinOptions
|
|
|
|
*/
|
|
|
|
private $skinOptions;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var SkinUserPageHelper
|
|
|
|
*/
|
|
|
|
private $userPageHelper;
|
2019-07-09 16:10:31 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @var LanguagesHelper
|
|
|
|
*/
|
|
|
|
private $languagesHelper;
|
2019-05-23 22:34:10 +00:00
|
|
|
/**
|
|
|
|
* Build Group containing icons for toolbar
|
|
|
|
* @param Title $title Article title user is currently browsing
|
|
|
|
* @param User $user Currently logged in user
|
|
|
|
* @param MessageLocalizer $msgLocalizer Message localizer to generate localized texts
|
2019-05-23 23:14:06 +00:00
|
|
|
* @param PermissionManager $permissionManager Mediawiki Permissions Manager
|
2019-05-24 00:07:27 +00:00
|
|
|
* @param IMinervaPagePermissions $permissions Minerva permissions system
|
2019-06-24 16:15:06 +00:00
|
|
|
* @param SkinOptions $skinOptions Skin options
|
|
|
|
* @param SkinUserPageHelper $userPageHelper User Page helper
|
2019-07-09 16:10:31 +00:00
|
|
|
* @param LanguagesHelper $languagesHelper Helper to check title languages/variants
|
2019-05-23 22:34:10 +00:00
|
|
|
*/
|
2019-05-24 00:07:27 +00:00
|
|
|
public function __construct(
|
|
|
|
Title $title,
|
|
|
|
User $user,
|
|
|
|
MessageLocalizer $msgLocalizer,
|
|
|
|
PermissionManager $permissionManager,
|
2019-06-24 16:15:06 +00:00
|
|
|
IMinervaPagePermissions $permissions,
|
|
|
|
SkinOptions $skinOptions,
|
2019-07-09 16:10:31 +00:00
|
|
|
SkinUserPageHelper $userPageHelper,
|
|
|
|
LanguagesHelper $languagesHelper
|
2019-06-24 16:15:06 +00:00
|
|
|
) {
|
2019-05-23 22:34:10 +00:00
|
|
|
$this->title = $title;
|
|
|
|
$this->user = $user;
|
|
|
|
$this->messageLocalizer = $msgLocalizer;
|
2019-05-23 23:14:06 +00:00
|
|
|
$this->permissionsManager = $permissionManager;
|
2019-05-24 00:07:27 +00:00
|
|
|
$this->permissions = $permissions;
|
2019-06-24 16:15:06 +00:00
|
|
|
$this->skinOptions = $skinOptions;
|
|
|
|
$this->userPageHelper = $userPageHelper;
|
2019-07-09 16:10:31 +00:00
|
|
|
$this->languagesHelper = $languagesHelper;
|
2019-05-23 22:34:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return Group
|
|
|
|
* @throws MWException
|
|
|
|
*/
|
2019-07-09 16:10:31 +00:00
|
|
|
public function getGroup(): Group {
|
2019-05-23 22:34:10 +00:00
|
|
|
$group = new Group();
|
2019-05-24 00:07:27 +00:00
|
|
|
$permissions = $this->permissions;
|
2019-06-24 17:59:11 +00:00
|
|
|
$userPageWithOveflowMode = $this->skinOptions->get( SkinOptions::OPTION_OVERFLOW_SUBMENU ) &&
|
|
|
|
$this->userPageHelper->isUserPage();
|
2019-05-23 22:34:10 +00:00
|
|
|
|
2019-06-24 17:59:11 +00:00
|
|
|
if ( !$userPageWithOveflowMode && $permissions->isAllowed(
|
|
|
|
IMinervaPagePermissions::SWITCH_LANGUAGE ) ) {
|
|
|
|
$group->insertEntry( new LanguageSelectorEntry(
|
|
|
|
$this->title,
|
2019-07-09 16:10:31 +00:00
|
|
|
$this->languagesHelper->doesTitleHasLanguagesOrVariants( $this->title ),
|
2019-06-24 17:59:11 +00:00
|
|
|
$this->messageLocalizer,
|
|
|
|
MinervaUI::iconClass( 'language-switcher', 'element', '' ) )
|
|
|
|
);
|
2019-05-23 22:34:10 +00:00
|
|
|
}
|
|
|
|
|
2019-05-24 00:07:27 +00:00
|
|
|
if ( $permissions->isAllowed( IMinervaPagePermissions::WATCH ) ) {
|
2019-05-23 22:34:10 +00:00
|
|
|
$group->insertEntry( $this->createWatchPageAction() );
|
|
|
|
}
|
|
|
|
|
2019-05-24 00:07:27 +00:00
|
|
|
if ( $permissions->isAllowed( IMinervaPagePermissions::HISTORY ) ) {
|
2019-05-23 22:34:10 +00:00
|
|
|
$group->insertEntry( $this->getHistoryPageAction() );
|
|
|
|
}
|
|
|
|
|
2019-06-24 17:59:11 +00:00
|
|
|
if ( $userPageWithOveflowMode ) {
|
2019-06-24 16:15:06 +00:00
|
|
|
// User links are hidden when Overflow menu is visible. We want to show Contributions
|
|
|
|
// link on toolbar only when overflow is visible
|
|
|
|
$group->insertEntry( $this->createContributionsPageAction() );
|
|
|
|
}
|
|
|
|
|
2019-05-23 22:34:10 +00:00
|
|
|
Hooks::run( 'MobileMenu', [ 'pageactions.toolbar', &$group ] );
|
|
|
|
|
|
|
|
// We want the edit icon/action always to be the last element on the toolbar list
|
2019-05-24 00:07:27 +00:00
|
|
|
if ( $permissions->isAllowed( IMinervaPagePermissions::EDIT ) ) {
|
2019-05-23 22:34:10 +00:00
|
|
|
$group->insertEntry( $this->createEditPageAction() );
|
|
|
|
}
|
|
|
|
return $group;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2019-06-24 16:15:06 +00:00
|
|
|
* Create Contributions page action visible on user pages
|
|
|
|
*
|
|
|
|
* @return IMenuEntry
|
|
|
|
*/
|
|
|
|
protected function createContributionsPageAction(): IMenuEntry {
|
|
|
|
$pageUser = $this->userPageHelper->getPageUser();
|
|
|
|
$label = $this->messageLocalizer->msg( 'mobile-frontend-user-page-contributions' );
|
|
|
|
|
|
|
|
return PageActionMenuEntry::create(
|
|
|
|
'page-actions-contributions',
|
|
|
|
SpecialPage::getTitleFor( 'Contributions', $pageUser )->getLocalURL(),
|
|
|
|
MinervaUI::iconClass( 'contributions' ),
|
|
|
|
$label
|
|
|
|
)->setTitle( $label );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2019-05-23 22:34:10 +00:00
|
|
|
* Creates the "edit" page action: the well-known pencil icon that, when tapped, will open an
|
|
|
|
* editor with the lead section loaded.
|
|
|
|
*
|
|
|
|
* @return PageActionMenuEntry An edit page actions menu entry
|
|
|
|
* @throws MWException
|
2019-05-23 23:14:06 +00:00
|
|
|
* @throws \Exception
|
2019-05-23 22:34:10 +00:00
|
|
|
*/
|
2019-06-21 16:52:22 +00:00
|
|
|
protected function createEditPageAction(): IMenuEntry {
|
2019-05-23 22:34:10 +00:00
|
|
|
$title = $this->title;
|
|
|
|
$user = $this->user;
|
2019-05-23 23:14:06 +00:00
|
|
|
$pm = $this->permissionsManager;
|
2019-05-23 22:34:10 +00:00
|
|
|
|
|
|
|
$editArgs = [ 'action' => 'edit' ];
|
|
|
|
if ( $title->isWikitextPage() ) {
|
|
|
|
// If the content model is wikitext we'll default to editing the lead section.
|
|
|
|
// Full wikitext editing is hard on mobile devices.
|
|
|
|
$editArgs['section'] = SkinMinerva::LEAD_SECTION_NUMBER;
|
|
|
|
}
|
2019-05-23 23:14:06 +00:00
|
|
|
|
|
|
|
$userQuickEditCheck =
|
|
|
|
$pm->userCan( 'edit', $user, $title, PermissionManager::RIGOR_QUICK ) &&
|
|
|
|
(
|
|
|
|
$title->exists() ||
|
|
|
|
$pm->userCan( 'create', $user, $title, PermissionManager::RIGOR_QUICK )
|
|
|
|
);
|
|
|
|
|
|
|
|
$userBlockInfo = $user->isAnon() ? false : $pm->isBlockedFrom( $user, $title, true );
|
2019-05-23 22:34:10 +00:00
|
|
|
$userCanEdit = $userQuickEditCheck && !$userBlockInfo;
|
|
|
|
|
|
|
|
$entry = new PageActionMenuEntry(
|
|
|
|
'page-actions-edit',
|
|
|
|
$title->getLocalURL( $editArgs ),
|
|
|
|
'edit-page '
|
|
|
|
. MinervaUI::iconClass( $userCanEdit ? 'edit-enabled' : 'edit', 'element' ),
|
|
|
|
$this->messageLocalizer->msg( 'mobile-frontend-editor-edit' )
|
|
|
|
);
|
|
|
|
return $entry
|
|
|
|
->setTitle( $this->messageLocalizer->msg( 'mobile-frontend-pageaction-edit-tooltip' ) )
|
|
|
|
->setNodeID( 'ca-edit' );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates the "watch" or "unwatch" action: the well-known star icon that, when tapped, will
|
|
|
|
* add the page to or remove the page from the user's watchlist; or, if the user is logged out,
|
|
|
|
* will direct the user's UA to Special:Login.
|
|
|
|
*
|
|
|
|
* @return PageActionMenuEntry An watch/unwatch page actions menu entry
|
|
|
|
* @throws MWException
|
|
|
|
*/
|
2019-06-21 16:52:22 +00:00
|
|
|
protected function createWatchPageAction(): IMenuEntry {
|
2019-05-23 22:34:10 +00:00
|
|
|
$title = $this->title;
|
|
|
|
$user = $this->user;
|
|
|
|
$isWatched = $title && $user->isLoggedIn() && $user->isWatched( $title );
|
2019-07-30 20:10:34 +00:00
|
|
|
$newModeToSet = $isWatched ? 'unwatch' : 'watch';
|
2019-05-23 22:34:10 +00:00
|
|
|
$href = $user->isAnon()
|
|
|
|
? $this->getLoginUrl( [ 'returnto' => $title ] )
|
2019-07-30 20:10:34 +00:00
|
|
|
: $title->getLocalURL( [ 'action' => $newModeToSet ] );
|
2019-05-23 22:34:10 +00:00
|
|
|
|
|
|
|
if ( $isWatched ) {
|
|
|
|
$msg = $this->messageLocalizer->msg( 'unwatchthispage' );
|
|
|
|
$icon = 'watched';
|
|
|
|
} else {
|
|
|
|
$msg = $this->messageLocalizer->msg( 'watchthispage' );
|
|
|
|
$icon = 'watch';
|
|
|
|
}
|
|
|
|
$iconClass = MinervaUI::iconClass( $icon, 'element', 'watch-this-article' ) . ' jsonly';
|
|
|
|
if ( $isWatched ) {
|
|
|
|
$iconClass .= ' watched';
|
|
|
|
}
|
|
|
|
|
|
|
|
$entry = new PageActionMenuEntry(
|
|
|
|
'page-actions-watch',
|
|
|
|
$href,
|
|
|
|
$iconClass,
|
|
|
|
$msg
|
|
|
|
);
|
|
|
|
return $entry
|
|
|
|
->setTitle( $msg )
|
|
|
|
->setNodeID( 'ca-watch' );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates a history action: An icon that links to the mobile history page.
|
|
|
|
*
|
|
|
|
* @return PageActionMenuEntry A menu entry object that represents a map of HTML attributes
|
|
|
|
* and a 'text' property to be used with the pageActionMenu.mustache template.
|
|
|
|
* @throws MWException
|
|
|
|
*/
|
2019-06-21 16:52:22 +00:00
|
|
|
protected function getHistoryPageAction(): IMenuEntry {
|
2019-05-23 22:34:10 +00:00
|
|
|
return new PageActionMenuEntry(
|
|
|
|
'page-actions-history',
|
|
|
|
$this->getHistoryUrl( $this->title ),
|
|
|
|
MinervaUI::iconClass( 'clock' ),
|
|
|
|
$this->messageLocalizer->msg( 'mobile-frontend-history' )
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the URL for the history page for the given title using Special:History
|
|
|
|
* when available.
|
|
|
|
* FIXME: temporary duplicated code, same as SkinMinerva::getHistoryUrl()
|
|
|
|
* @param Title $title The Title object of the page being viewed
|
|
|
|
* @return string
|
|
|
|
* @throws MWException
|
|
|
|
*/
|
|
|
|
protected function getHistoryUrl( Title $title ) {
|
|
|
|
return ExtensionRegistry::getInstance()->isLoaded( 'MobileFrontend' ) &&
|
|
|
|
SpecialMobileHistory::shouldUseSpecialHistory( $title, $this->user ) ?
|
|
|
|
SpecialPage::getTitleFor( 'History', $title )->getLocalURL() :
|
|
|
|
$title->getLocalURL( [ 'action' => 'history' ] );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Prepares a url to the Special:UserLogin with query parameters
|
|
|
|
* @param array $query
|
|
|
|
* @return string
|
|
|
|
* @throws MWException
|
|
|
|
*/
|
|
|
|
private function getLoginUrl( $query ) {
|
|
|
|
return SpecialPage::getTitleFor( 'Userlogin' )->getLocalURL( $query );
|
|
|
|
}
|
|
|
|
}
|