Merge "Inject services into SpecialWatchlist/SpecialEditWatchlist"
This commit is contained in:
commit
a27e2f17c2
5 changed files with 122 additions and 55 deletions
|
|
@ -463,7 +463,12 @@ class SpecialPageFactory {
|
|||
'EditWatchlist' => [
|
||||
'class' => \SpecialEditWatchlist::class,
|
||||
'services' => [
|
||||
'WatchedItemStore'
|
||||
'WatchedItemStore',
|
||||
'TitleParser',
|
||||
'GenderCache',
|
||||
'LinkBatchFactory',
|
||||
'NamespaceInfo',
|
||||
'WikiPageFactory',
|
||||
]
|
||||
],
|
||||
'PasswordPolicies' => [
|
||||
|
|
@ -493,7 +498,16 @@ class SpecialPageFactory {
|
|||
'ActorMigration',
|
||||
]
|
||||
],
|
||||
'Watchlist' => \SpecialWatchlist::class,
|
||||
'Watchlist' => [
|
||||
'class' => \SpecialWatchlist::class,
|
||||
'services' => [
|
||||
'WatchedItemStore',
|
||||
'WatchlistNotificationManager',
|
||||
'PermissionManager',
|
||||
'DBLoadBalancer',
|
||||
'UserOptionsLookup',
|
||||
]
|
||||
],
|
||||
'Newpages' => [
|
||||
'class' => \SpecialNewpages::class,
|
||||
'services' => [
|
||||
|
|
|
|||
|
|
@ -26,9 +26,11 @@
|
|||
* @ingroup Watchlist
|
||||
*/
|
||||
|
||||
use MediaWiki\Cache\LinkBatchFactory;
|
||||
use MediaWiki\Linker\LinkRenderer;
|
||||
use MediaWiki\Linker\LinkTarget;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use MediaWiki\Page\WikiPageFactory;
|
||||
|
||||
/**
|
||||
* Provides the UI through which users can perform editing
|
||||
|
|
@ -53,33 +55,53 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
|
|||
|
||||
private $badItems = [];
|
||||
|
||||
/**
|
||||
* @var TitleParser
|
||||
*/
|
||||
/** @var TitleParser */
|
||||
private $titleParser;
|
||||
|
||||
/**
|
||||
* @var WatchedItemStoreInterface
|
||||
*/
|
||||
/** @var WatchedItemStoreInterface */
|
||||
private $watchedItemStore;
|
||||
|
||||
/** @var GenderCache */
|
||||
private $genderCache;
|
||||
|
||||
/** @var LinkBatchFactory */
|
||||
private $linkBatchFactory;
|
||||
|
||||
/** @var NamespaceInfo */
|
||||
private $nsInfo;
|
||||
|
||||
/** @var WikiPageFactory */
|
||||
private $wikiPageFactory;
|
||||
|
||||
/** @var bool Watchlist Expiry flag */
|
||||
private $isWatchlistExpiryEnabled;
|
||||
|
||||
public function __construct( WatchedItemStoreInterface $watchedItemStore ) {
|
||||
parent::__construct( 'EditWatchlist', 'editmywatchlist' );
|
||||
$this->watchedItemStore = $watchedItemStore;
|
||||
$this->isWatchlistExpiryEnabled = $this->getConfig()->get( 'WatchlistExpiry' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize any services we'll need (unless it has already been provided via a setter).
|
||||
* This allows for dependency injection even though we don't control object creation.
|
||||
* @param WatchedItemStoreInterface|null $watchedItemStore
|
||||
* @param TitleParser|null $titleParser
|
||||
* @param GenderCache|null $genderCache
|
||||
* @param LinkBatchFactory|null $linkBatchFactory
|
||||
* @param NamespaceInfo|null $nsInfo
|
||||
* @param WikiPageFactory|null $wikiPageFactory
|
||||
*/
|
||||
private function initServices() {
|
||||
if ( !$this->titleParser ) {
|
||||
$this->titleParser = MediaWikiServices::getInstance()->getTitleParser();
|
||||
}
|
||||
public function __construct(
|
||||
WatchedItemStoreInterface $watchedItemStore = null,
|
||||
TitleParser $titleParser = null,
|
||||
GenderCache $genderCache = null,
|
||||
LinkBatchFactory $linkBatchFactory = null,
|
||||
NamespaceInfo $nsInfo = null,
|
||||
WikiPageFactory $wikiPageFactory = null
|
||||
) {
|
||||
parent::__construct( 'EditWatchlist', 'editmywatchlist' );
|
||||
// This class is extended and therefor fallback to global state - T266065
|
||||
$services = MediaWikiServices::getInstance();
|
||||
$this->watchedItemStore = $watchedItemStore ?? $services->getWatchedItemStore();
|
||||
$this->titleParser = $titleParser ?? $services->getTitleParser();
|
||||
$this->genderCache = $genderCache ?? $services->getGenderCache();
|
||||
$this->linkBatchFactory = $linkBatchFactory ?? $services->getLinkBatchFactory();
|
||||
$this->nsInfo = $nsInfo ?? $services->getNamespaceInfo();
|
||||
$this->wikiPageFactory = $wikiPageFactory ?? $services->getWikiPageFactory();
|
||||
$this->isWatchlistExpiryEnabled = $this->getConfig()->get( 'WatchlistExpiry' );
|
||||
}
|
||||
|
||||
public function doesWrites() {
|
||||
|
|
@ -92,7 +114,6 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
|
|||
* @param int $mode
|
||||
*/
|
||||
public function execute( $mode ) {
|
||||
$this->initServices();
|
||||
$this->setHeaders();
|
||||
|
||||
# Anons don't get a watchlist
|
||||
|
|
@ -212,7 +233,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
|
|||
}
|
||||
}
|
||||
|
||||
MediaWikiServices::getInstance()->getGenderCache()->doTitlesArray( $titles );
|
||||
$this->genderCache->doTitlesArray( $titles );
|
||||
|
||||
$list = [];
|
||||
/** @var Title $title */
|
||||
|
|
@ -328,8 +349,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
|
|||
private function showTitles( $titles, &$output ) {
|
||||
$talk = $this->msg( 'talkpagelinktext' )->text();
|
||||
// Do a batch existence check
|
||||
$linkBatchFactory = MediaWikiServices::getInstance()->getLinkBatchFactory();
|
||||
$batch = $linkBatchFactory->newLinkBatch();
|
||||
$batch = $this->linkBatchFactory->newLinkBatch();
|
||||
if ( count( $titles ) >= 100 ) {
|
||||
$output = $this->msg( 'watchlistedit-too-many' )->parse();
|
||||
return;
|
||||
|
|
@ -398,7 +418,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
|
|||
}
|
||||
}
|
||||
|
||||
MediaWikiServices::getInstance()->getGenderCache()->doTitlesArray( $titles );
|
||||
$this->genderCache->doTitlesArray( $titles );
|
||||
|
||||
foreach ( $titles as $title ) {
|
||||
$list[] = $title->getPrefixedText();
|
||||
|
|
@ -418,7 +438,6 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
|
|||
*/
|
||||
protected function getWatchlistInfo() {
|
||||
$titles = [];
|
||||
$services = MediaWikiServices::getInstance();
|
||||
$options = [ 'sort' => WatchedItemStore::SORT_ASC ];
|
||||
|
||||
if ( $this->isWatchlistExpiryEnabled ) {
|
||||
|
|
@ -429,15 +448,14 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
|
|||
$this->getUser(), $options
|
||||
);
|
||||
|
||||
$linkBatchFactory = $services->getLinkBatchFactory();
|
||||
$lb = $linkBatchFactory->newLinkBatch();
|
||||
$lb = $this->linkBatchFactory->newLinkBatch();
|
||||
$context = $this->getContext();
|
||||
|
||||
foreach ( $watchedItems as $watchedItem ) {
|
||||
$namespace = $watchedItem->getLinkTarget()->getNamespace();
|
||||
$dbKey = $watchedItem->getLinkTarget()->getDBkey();
|
||||
$lb->add( $namespace, $dbKey );
|
||||
if ( !$services->getNamespaceInfo()->isTalk( $namespace ) ) {
|
||||
if ( !$this->nsInfo->isTalk( $namespace ) ) {
|
||||
$titles[$namespace][$dbKey] = $watchedItem->getExpiryInDaysText( $context );
|
||||
}
|
||||
}
|
||||
|
|
@ -547,7 +565,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
|
|||
$title = $target instanceof LinkTarget ?
|
||||
Title::newFromLinkTarget( $target ) :
|
||||
Title::newFromText( $target );
|
||||
$page = WikiPage::factory( $title );
|
||||
$page = $this->wikiPageFactory->newFromTitle( $title );
|
||||
$user = $this->getUser();
|
||||
if ( $action === 'Watch' ) {
|
||||
$this->getHookRunner()->onWatchArticleComplete( $user, $page );
|
||||
|
|
@ -564,7 +582,6 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
|
|||
*/
|
||||
private function getExpandedTargets( array $targets ) {
|
||||
$expandedTargets = [];
|
||||
$services = MediaWikiServices::getInstance();
|
||||
foreach ( $targets as $target ) {
|
||||
if ( !$target instanceof LinkTarget ) {
|
||||
try {
|
||||
|
|
@ -578,9 +595,9 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
|
|||
$ns = $target->getNamespace();
|
||||
$dbKey = $target->getDBkey();
|
||||
$expandedTargets[] =
|
||||
new TitleValue( $services->getNamespaceInfo()->getSubject( $ns ), $dbKey );
|
||||
new TitleValue( $this->nsInfo->getSubject( $ns ), $dbKey );
|
||||
$expandedTargets[] =
|
||||
new TitleValue( $services->getNamespaceInfo()->getTalk( $ns ), $dbKey );
|
||||
new TitleValue( $this->nsInfo->getTalk( $ns ), $dbKey );
|
||||
}
|
||||
return $expandedTargets;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,9 +21,11 @@
|
|||
* @ingroup SpecialPage
|
||||
*/
|
||||
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use MediaWiki\Permissions\PermissionManager;
|
||||
use MediaWiki\User\UserOptionsLookup;
|
||||
use MediaWiki\User\WatchlistNotificationManager;
|
||||
use Wikimedia\Rdbms\IDatabase;
|
||||
use Wikimedia\Rdbms\ILoadBalancer;
|
||||
use Wikimedia\Rdbms\IResultWrapper;
|
||||
|
||||
/**
|
||||
|
|
@ -41,8 +43,17 @@ class SpecialWatchlist extends ChangesListSpecialPage {
|
|||
/** @var float|int */
|
||||
private $maxDays;
|
||||
|
||||
/** @var WatchedItemStore */
|
||||
private $watchStore;
|
||||
/** @var WatchedItemStoreInterface */
|
||||
private $watchedItemStore;
|
||||
|
||||
/** @var WatchlistNotificationManager */
|
||||
private $watchlistNotificationManager;
|
||||
|
||||
/** @var PermissionManager */
|
||||
private $permissionManager;
|
||||
|
||||
/** @var ILoadBalancer */
|
||||
private $loadBalancer;
|
||||
|
||||
/** @var UserOptionsLookup */
|
||||
private $userOptionsLookup;
|
||||
|
|
@ -50,14 +61,28 @@ class SpecialWatchlist extends ChangesListSpecialPage {
|
|||
/** @var bool Watchlist Expiry flag */
|
||||
private $isWatchlistExpiryEnabled;
|
||||
|
||||
public function __construct( $page = 'Watchlist', $restriction = 'viewmywatchlist' ) {
|
||||
parent::__construct( $page, $restriction );
|
||||
/**
|
||||
* @param WatchedItemStoreInterface $watchedItemStore
|
||||
* @param WatchlistNotificationManager $watchlistNotificationManager
|
||||
* @param PermissionManager $permissionManager
|
||||
* @param ILoadBalancer $loadBalancer
|
||||
* @param UserOptionsLookup $userOptionsLookup
|
||||
*/
|
||||
public function __construct(
|
||||
WatchedItemStoreInterface $watchedItemStore,
|
||||
WatchlistNotificationManager $watchlistNotificationManager,
|
||||
PermissionManager $permissionManager,
|
||||
ILoadBalancer $loadBalancer,
|
||||
UserOptionsLookup $userOptionsLookup
|
||||
) {
|
||||
parent::__construct( 'Watchlist', 'viewmywatchlist' );
|
||||
|
||||
$this->watchedItemStore = $watchedItemStore;
|
||||
$this->watchlistNotificationManager = $watchlistNotificationManager;
|
||||
$this->permissionManager = $permissionManager;
|
||||
$this->loadBalancer = $loadBalancer;
|
||||
$this->userOptionsLookup = $userOptionsLookup;
|
||||
$this->maxDays = $this->getConfig()->get( 'RCMaxAge' ) / ( 3600 * 24 );
|
||||
// TODO Inject services
|
||||
$services = MediaWikiServices::getInstance();
|
||||
$this->watchStore = $services->getWatchedItemStore();
|
||||
$this->userOptionsLookup = $services->getUserOptionsLookup();
|
||||
$this->isWatchlistExpiryEnabled = $this->getConfig()->get( 'WatchlistExpiry' );
|
||||
}
|
||||
|
||||
|
|
@ -109,9 +134,7 @@ class SpecialWatchlist extends ChangesListSpecialPage {
|
|||
&& $request->wasPosted()
|
||||
&& $user->matchEditToken( $request->getVal( 'token' ) )
|
||||
) {
|
||||
MediaWikiServices::getInstance()
|
||||
->getWatchlistNotificationManager()
|
||||
->clearAllUserNotifications( $user );
|
||||
$this->watchlistNotificationManager->clearAllUserNotifications( $user );
|
||||
$output->redirect( $this->getPageTitle()->getFullURL( $opts->getChangedValues() ) );
|
||||
|
||||
return;
|
||||
|
|
@ -405,10 +428,9 @@ class SpecialWatchlist extends ChangesListSpecialPage {
|
|||
|
||||
// Log entries with DELETED_ACTION must not show up unless the user has
|
||||
// the necessary rights.
|
||||
$permissionManager = MediaWikiServices::getInstance()->getPermissionManager();
|
||||
if ( !$permissionManager->userHasRight( $user, 'deletedhistory' ) ) {
|
||||
if ( !$this->permissionManager->userHasRight( $user, 'deletedhistory' ) ) {
|
||||
$bitmask = LogPage::DELETED_ACTION;
|
||||
} elseif ( !$permissionManager->userHasAnyRight( $user, 'suppressrevision', 'viewsuppressed' ) ) {
|
||||
} elseif ( !$this->permissionManager->userHasAnyRight( $user, 'suppressrevision', 'viewsuppressed' ) ) {
|
||||
$bitmask = LogPage::DELETED_ACTION | LogPage::DELETED_RESTRICTED;
|
||||
} else {
|
||||
$bitmask = 0;
|
||||
|
|
@ -469,7 +491,7 @@ class SpecialWatchlist extends ChangesListSpecialPage {
|
|||
* @return IDatabase
|
||||
*/
|
||||
protected function getDB() {
|
||||
return wfGetDB( DB_REPLICA, 'watchlist' );
|
||||
return $this->loadBalancer->getConnectionRef( ILoadBalancer::DB_REPLICA, 'watchlist' );
|
||||
}
|
||||
|
||||
public function outputFeedLinks() {
|
||||
|
|
@ -529,7 +551,7 @@ class SpecialWatchlist extends ChangesListSpecialPage {
|
|||
$diffInDays = null;
|
||||
// Check if the watchlist expiry flag is enabled to show new tooltip message
|
||||
if ( $this->isWatchlistExpiryEnabled ) {
|
||||
$watchedItem = $this->watchStore->getWatchedItem( $this->getUser(), $rc->getTitle() );
|
||||
$watchedItem = $this->watchedItemStore->getWatchedItem( $this->getUser(), $rc->getTitle() );
|
||||
if ( $watchedItem instanceof WatchedItem && $watchedItem->getExpiry() !== null ) {
|
||||
$diffInDays = $watchedItem->getExpiryInDays();
|
||||
|
||||
|
|
@ -585,7 +607,7 @@ class SpecialWatchlist extends ChangesListSpecialPage {
|
|||
&& $this->userOptionsLookup->getBoolOption( $user, 'shownumberswatching' )
|
||||
) {
|
||||
$rcTitleValue = new TitleValue( (int)$obj->rc_namespace, $obj->rc_title );
|
||||
$rc->numberofWatchingusers = $this->watchStore->countWatchers( $rcTitleValue );
|
||||
$rc->numberofWatchingusers = $this->watchedItemStore->countWatchers( $rcTitleValue );
|
||||
} else {
|
||||
$rc->numberofWatchingusers = 0;
|
||||
}
|
||||
|
|
@ -894,7 +916,7 @@ class SpecialWatchlist extends ChangesListSpecialPage {
|
|||
* @return int
|
||||
*/
|
||||
protected function countItems() {
|
||||
$count = $this->watchStore->countWatchedItems( $this->getUser() );
|
||||
$count = $this->watchedItemStore->countWatchedItems( $this->getUser() );
|
||||
return floor( $count / 2 );
|
||||
}
|
||||
|
||||
|
|
@ -913,7 +935,7 @@ class SpecialWatchlist extends ChangesListSpecialPage {
|
|||
* @return string|null TS_MW timestamp of first unseen revision or null if there isn't one
|
||||
*/
|
||||
private function getLatestNotificationTimestamp( RecentChange $rc ) {
|
||||
return $this->watchStore->getLatestNotificationTimestamp(
|
||||
return $this->watchedItemStore->getLatestNotificationTimestamp(
|
||||
$rc->getAttribute( 'wl_notificationtimestamp' ),
|
||||
$this->getUser(),
|
||||
$rc->getTitle()
|
||||
|
|
|
|||
|
|
@ -17,8 +17,14 @@ class SpecialEditWatchlistTest extends SpecialPageTestBase {
|
|||
* @return SpecialPage
|
||||
*/
|
||||
protected function newSpecialPage() {
|
||||
$services = MediaWikiServices::getInstance();
|
||||
return new SpecialEditWatchlist(
|
||||
MediaWikiServices::getInstance()->getWatchedItemStore()
|
||||
$services->getWatchedItemStore(),
|
||||
$services->getTitleParser(),
|
||||
$services->getGenderCache(),
|
||||
$services->getLinkBatchFactory(),
|
||||
$services->getNamespaceInfo(),
|
||||
$services->getWikiPageFactory()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
<?php
|
||||
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use Wikimedia\TestingAccessWrapper;
|
||||
|
||||
/**
|
||||
|
|
@ -43,7 +44,14 @@ class SpecialWatchlistTest extends SpecialPageTestBase {
|
|||
* @return SpecialPage
|
||||
*/
|
||||
protected function newSpecialPage() {
|
||||
return new SpecialWatchlist();
|
||||
$services = MediaWikiServices::getInstance();
|
||||
return new SpecialWatchlist(
|
||||
$services->getWatchedItemStore(),
|
||||
$services->getWatchlistNotificationManager(),
|
||||
$services->getPermissionManager(),
|
||||
$services->getDBLoadBalancer(),
|
||||
$services->getUserOptionsLookup()
|
||||
);
|
||||
}
|
||||
|
||||
public function testNotLoggedIn_throwsException() {
|
||||
|
|
|
|||
Loading…
Reference in a new issue