58 private $isEnotifEnabled;
64 private $readOnlyMode;
67 private $revisionLookup;
70 private $talkPageNotificationManager;
73 private $watchedItemStore;
82 private $wikiPageFactory;
100 private $notificationTimestampCache = [];
125 $this->hookRunner =
new HookRunner( $hookContainer );
126 $this->readOnlyMode = $readOnlyMode;
127 $this->revisionLookup = $revisionLookup;
128 $this->talkPageNotificationManager = $talkPageNotificationManager;
129 $this->watchedItemStore = $watchedItemStore;
130 $this->userFactory = $userFactory;
131 $this->nsInfo = $nsInfo;
132 $this->wikiPageFactory = $wikiPageFactory;
145 if ( $this->readOnlyMode->isReadOnly() ) {
150 if ( !$performer instanceof
Authority ) {
151 $performer = $this->userFactory->newFromUserIdentity( $performer );
154 if ( !$performer->isAllowed(
'editmywatchlist' ) ) {
159 $user = $performer->getUser();
161 if ( !$this->isEnotifEnabled ) {
162 $this->talkPageNotificationManager->removeUserHasNewMessages( $user );
166 if ( !$user->isRegistered() ) {
170 $this->watchedItemStore->resetAllNotificationTimestampsForUser( $user );
195 if ( $this->readOnlyMode->isReadOnly() ) {
200 if ( !$performer instanceof
Authority ) {
201 $performer = $this->userFactory->newFromUserIdentity( $performer );
204 if ( !$performer->isAllowed(
'editmywatchlist' ) ) {
209 $userIdentity = $performer->getUser();
212 $title->getDBkey() === strtr( $userIdentity->getName(),
' ',
'_' )
215 if ( $userTalkPage ) {
218 } elseif ( !$oldRev ) {
219 $oldRev = $this->revisionLookup->getRevisionById( $oldid );
221 $this->talkPageNotificationManager->clearForPageView( $userIdentity, $oldRev );
224 if ( !$this->isEnotifEnabled ) {
228 if ( !$userIdentity->isRegistered() ) {
237 $force = $userTalkPage ?
'force' :
'';
238 $this->watchedItemStore->resetNotificationTimestamp( $userIdentity,
$title, $force, $oldid );
253 $cacheKey =
'u' . $user->
getId() .
'-' .
257 if ( array_key_exists( $cacheKey, $this->notificationTimestampCache ) ) {
258 return $this->notificationTimestampCache[ $cacheKey ];
261 $watchedItem = $this->watchedItemStore->getWatchedItem( $user,
$title );
262 if ( $watchedItem ) {
263 $timestamp = $watchedItem->getNotificationTimestamp();
268 $this->notificationTimestampCache[ $cacheKey ] = $timestamp;
278 if ( !$this->nsInfo->
isWatchable( $target->getNamespace() ) ) {
298 if ( $this->isWatchable( $target ) ) {
299 return $this->watchedItemStore->isWatched( $userIdentity, $target );
313 if ( $performer->isAllowed(
'viewmywatchlist' ) ) {
314 return $this->isWatchedIgnoringRights( $performer->
getUser(), $target );
327 if ( $this->isWatchable( $target ) ) {
328 return $this->watchedItemStore->isTempWatched( $userIdentity, $target );
342 if ( $performer->isAllowed(
'viewmywatchlist' ) ) {
343 return $this->isTempWatchedIgnoringRights( $performer->
getUser(), $target );
360 ?
string $expiry =
null
362 if ( !$this->isWatchable( $target ) ) {
366 $wikiPage = $this->wikiPageFactory->newFromTitle( $target );
367 $title = $wikiPage->getTitle();
371 $user = $this->userFactory->newFromUserIdentity( $userIdentity );
372 if ( $this->hookRunner->onWatchArticle( $user, $wikiPage, $status, $expiry ) ) {
374 $this->watchedItemStore->addWatch( $userIdentity, $this->nsInfo->getSubjectPage(
$title ), $expiry );
375 if ( $this->nsInfo->canHaveTalkPage(
$title ) ) {
376 $this->watchedItemStore->addWatch( $userIdentity, $this->nsInfo->getTalkPage(
$title ), $expiry );
378 $this->hookRunner->onWatchArticleComplete( $user, $wikiPage );
382 $user->invalidateCache();
400 ?
string $expiry =
null
402 if ( !$performer->isAllowed(
'editmywatchlist' ) ) {
407 return $this->addWatchIgnoringRights( $performer->getUser(), $target, $expiry );
421 if ( !$this->isWatchable( $target ) ) {
425 $wikiPage = $this->wikiPageFactory->newFromTitle( $target );
426 $title = $wikiPage->getTitle();
430 $user = $this->userFactory->newFromUserIdentity( $userIdentity );
431 if ( $this->hookRunner->onUnwatchArticle( $user, $wikiPage, $status ) ) {
433 $this->watchedItemStore->removeWatch( $userIdentity, $this->nsInfo->getSubjectPage(
$title ) );
434 if ( $this->nsInfo->canHaveTalkPage(
$title ) ) {
435 $this->watchedItemStore->removeWatch( $userIdentity, $this->nsInfo->getTalkPage(
$title ) );
437 $this->hookRunner->onUnwatchArticleComplete( $user, $wikiPage );
441 $user->invalidateCache();
458 if ( !$performer->isAllowed(
'editmywatchlist' ) ) {
463 return $this->removeWatchIgnoringRights( $performer->getUser(), $target );
483 string $expiry =
null
486 if ( !$performer->
getUser()->isRegistered() ) {
491 $oldWatchedItem = $this->watchedItemStore->getWatchedItem( $performer->getUser(), $target );
492 $changingWatchStatus = (bool)$oldWatchedItem !== $watch;
493 if ( $oldWatchedItem && $expiry !==
null ) {
495 $oldWatchPeriod = $oldWatchedItem->getExpiry() ??
'infinity';
496 $changingWatchStatus = $changingWatchStatus ||
497 $oldWatchPeriod !== ExpiryDef::normalizeExpiry( $expiry, TS_MW );
500 if ( $changingWatchStatus ) {
504 return $this->addWatchIgnoringRights( $performer->getUser(), $target, $expiry );
506 return $this->removeWatch( $performer, $target );
if(!defined('MW_SETUP_CALLBACK'))
Service for creating WikiPage objects.
Manages user talk page notifications.
This is a utility class for dealing with namespaces that encodes all the "magic" behaviors of them ba...
Generic operation result class Has warning/error list, boolean status and arbitrary value.
static newFatal( $message,... $parameters)
Factory function for fatal errors.
static newGood( $value=null)
Factory function for good results.
Generic operation result class Has warning/error list, boolean status and arbitrary value.
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
static newFatalPermissionDeniedStatus( $permission)
Factory function for fatal permission-denied errors.
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...