57 private $isEnotifEnabled;
63 private $readOnlyMode;
66 private $revisionLookup;
69 private $talkPageNotificationManager;
72 private $watchedItemStore;
81 private $wikiPageFactory;
99 private $notificationTimestampCache = [];
124 $this->hookRunner =
new HookRunner( $hookContainer );
125 $this->readOnlyMode = $readOnlyMode;
126 $this->revisionLookup = $revisionLookup;
127 $this->talkPageNotificationManager = $talkPageNotificationManager;
128 $this->watchedItemStore = $watchedItemStore;
129 $this->userFactory = $userFactory;
130 $this->nsInfo = $nsInfo;
131 $this->wikiPageFactory = $wikiPageFactory;
144 if ( $this->readOnlyMode->isReadOnly() ) {
149 if ( !$performer instanceof
Authority ) {
150 $performer = $this->userFactory->newFromUserIdentity( $performer );
153 $user = $performer->getUser();
157 if ( !$this->isEnotifEnabled ) {
158 $this->talkPageNotificationManager->removeUserHasNewMessages( $user );
162 if ( !$performer->isAllowed(
'editmywatchlist' ) ) {
167 if ( !$user->isRegistered() ) {
171 $this->watchedItemStore->resetAllNotificationTimestampsForUser( $user );
196 if ( $this->readOnlyMode->isReadOnly() ) {
201 if ( !$performer instanceof
Authority ) {
202 $performer = $this->userFactory->newFromUserIdentity( $performer );
205 $userIdentity = $performer->getUser();
208 $title->getDBkey() === strtr( $userIdentity->getName(),
' ',
'_' )
211 if ( $userTalkPage ) {
214 } elseif ( !$oldRev ) {
215 $oldRev = $this->revisionLookup->getRevisionById( $oldid );
220 $this->talkPageNotificationManager->clearForPageView( $userIdentity, $oldRev );
223 if ( !$this->isEnotifEnabled ) {
227 if ( !$userIdentity->isRegistered() ) {
235 if ( !$performer->isAllowed(
'editmywatchlist' ) ) {
244 $force = $userTalkPage ?
'force' :
'';
245 $this->watchedItemStore->resetNotificationTimestamp( $userIdentity, $title, $force, $oldid );
260 $cacheKey =
'u' . $user->
getId() .
'-' .
261 $title->getNamespace() .
':' . $title->getDBkey();
264 if ( array_key_exists( $cacheKey, $this->notificationTimestampCache ) ) {
265 return $this->notificationTimestampCache[ $cacheKey ];
268 $watchedItem = $this->watchedItemStore->getWatchedItem( $user, $title );
269 if ( $watchedItem ) {
270 $timestamp = $watchedItem->getNotificationTimestamp();
275 $this->notificationTimestampCache[ $cacheKey ] = $timestamp;
285 if ( !$this->nsInfo->
isWatchable( $target->getNamespace() ) ) {
305 if ( $this->isWatchable( $target ) ) {
306 return $this->watchedItemStore->isWatched( $userIdentity, $target );
320 if ( $performer->isAllowed(
'viewmywatchlist' ) ) {
321 return $this->isWatchedIgnoringRights( $performer->
getUser(), $target );
334 if ( $this->isWatchable( $target ) ) {
335 return $this->watchedItemStore->isTempWatched( $userIdentity, $target );
349 if ( $performer->isAllowed(
'viewmywatchlist' ) ) {
350 return $this->isTempWatchedIgnoringRights( $performer->
getUser(), $target );
367 ?
string $expiry =
null
369 if ( !$this->isWatchable( $target ) ) {
370 return StatusValue::newFatal(
'watchlistnotwatchable' );
373 $wikiPage = $this->wikiPageFactory->newFromTitle( $target );
374 $title = $wikiPage->getTitle();
377 $status = Status::newFatal(
'hookaborted' );
378 $user = $this->userFactory->newFromUserIdentity( $userIdentity );
379 if ( $this->hookRunner->onWatchArticle( $user, $wikiPage, $status, $expiry ) ) {
380 $status = StatusValue::newGood();
381 $this->watchedItemStore->addWatch( $userIdentity, $this->nsInfo->getSubjectPage( $title ), $expiry );
382 if ( $this->nsInfo->canHaveTalkPage( $title ) ) {
383 $this->watchedItemStore->addWatch( $userIdentity, $this->nsInfo->getTalkPage( $title ), $expiry );
385 $this->hookRunner->onWatchArticleComplete( $user, $wikiPage );
389 $user->invalidateCache();
407 ?
string $expiry =
null
409 if ( !$performer->isAllowed(
'editmywatchlist' ) ) {
411 return User::newFatalPermissionDeniedStatus(
'editmywatchlist' );
414 return $this->addWatchIgnoringRights( $performer->getUser(), $target, $expiry );
428 if ( !$this->isWatchable( $target ) ) {
429 return StatusValue::newFatal(
'watchlistnotwatchable' );
432 $wikiPage = $this->wikiPageFactory->newFromTitle( $target );
433 $title = $wikiPage->getTitle();
436 $status = Status::newFatal(
'hookaborted' );
437 $user = $this->userFactory->newFromUserIdentity( $userIdentity );
438 if ( $this->hookRunner->onUnwatchArticle( $user, $wikiPage, $status ) ) {
439 $status = StatusValue::newGood();
440 $this->watchedItemStore->removeWatch( $userIdentity, $this->nsInfo->getSubjectPage( $title ) );
441 if ( $this->nsInfo->canHaveTalkPage( $title ) ) {
442 $this->watchedItemStore->removeWatch( $userIdentity, $this->nsInfo->getTalkPage( $title ) );
444 $this->hookRunner->onUnwatchArticleComplete( $user, $wikiPage );
448 $user->invalidateCache();
465 if ( !$performer->isAllowed(
'editmywatchlist' ) ) {
467 return User::newFatalPermissionDeniedStatus(
'editmywatchlist' );
470 return $this->removeWatchIgnoringRights( $performer->getUser(), $target );
490 ?
string $expiry =
null
493 if ( !$performer->getUser()->isRegistered() || $performer->isTemp() ) {
494 return StatusValue::newGood();
500 $oldWatchedItem = $this->watchedItemStore->getWatchedItem( $performer->getUser(), $target );
501 $changingWatchStatus = (bool)$oldWatchedItem !== $watch;
502 if ( $oldWatchedItem && $expiry !==
null ) {
504 $oldWatchPeriod = $oldWatchedItem->getExpiry() ??
'infinity';
505 $changingWatchStatus = $changingWatchStatus ||
506 $oldWatchPeriod !== ExpiryDef::normalizeExpiry( $expiry, TS_MW );
509 if ( $changingWatchStatus ) {
513 return $this->addWatchIgnoringRights( $performer->getUser(), $target, $expiry );
515 return $this->removeWatch( $performer, $target );
if(!defined('MW_SETUP_CALLBACK'))
Service for creating WikiPage objects.
Manages user talk page notifications.
Generic operation result class Has warning/error list, boolean status and arbitrary value.
static newGood( $value=null)
Factory function for good results.
Interface for objects (potentially) representing an editable wiki page.
canExist()
Checks whether this PageIdentity represents a "proper" page, meaning that it could exist as an editab...