131 $this->hookRunner =
new HookRunner( $hookContainer );
151 if ( $this->readOnlyMode->isReadOnly() ) {
156 if ( !$performer instanceof
Authority ) {
157 $performer = $this->userFactory->newFromUserIdentity( $performer );
160 if ( !$performer->isAllowed(
'editmywatchlist' ) ) {
165 $user = $performer->getUser();
167 if ( !$this->options->get(
'UseEnotif' ) &&
168 !$this->options->get(
'ShowUpdatedMarker' )
170 $this->talkPageNotificationManager->removeUserHasNewMessages( $user );
174 $userId = $user->getId();
179 $this->watchedItemStore->resetAllNotificationTimestampsForUser( $user );
201 if ( $this->readOnlyMode->isReadOnly() ) {
206 if ( !$performer instanceof
Authority ) {
207 $performer = $this->userFactory->newFromUserIdentity( $performer );
210 if ( !$performer->isAllowed(
'editmywatchlist' ) ) {
215 $userIdentity = $performer->getUser();
218 $title->getDBkey() === strtr( $userIdentity->getName(),
' ',
'_' )
221 if ( $userTalkPage ) {
223 if ( !$this->hookRunner->onUserClearNewTalkNotification(
233 DeferredUpdates::addCallableUpdate(
static function () use (
253 RevisionLookup::READ_LATEST
269 if ( !$this->options->get(
'UseEnotif' ) &&
270 !$this->options->get(
'ShowUpdatedMarker' )
275 if ( !$userIdentity->isRegistered() ) {
284 $force = $userTalkPage ?
'force' :
'';
285 $this->watchedItemStore->resetNotificationTimestamp( $userIdentity,
$title, $force, $oldid );
296 $userId = $user->
getId();
302 $cacheKey =
'u' . (string)$userId .
'-' .
303 (
string)
$title->getNamespace() .
':' .
$title->getDBkey();
306 if ( array_key_exists( $cacheKey, $this->notificationTimestampCache ) ) {
307 return $this->notificationTimestampCache[ $cacheKey ];
310 $watchedItem = $this->watchedItemStore->getWatchedItem( $user,
$title );
311 if ( $watchedItem ) {
312 $timestamp = $watchedItem->getNotificationTimestamp();
317 $this->notificationTimestampCache[ $cacheKey ] = $timestamp;
327 if ( !$this->nsInfo->
isWatchable( $target->getNamespace() ) ) {
347 if ( $this->isWatchable( $target ) ) {
348 return $this->watchedItemStore->isWatched( $userIdentity, $target );
362 if ( $performer->isAllowed(
'viewmywatchlist' ) ) {
363 return $this->isWatchedIgnoringRights( $performer->
getUser(), $target );
376 if ( $this->isWatchable( $target ) ) {
377 return $this->watchedItemStore->isTempWatched( $userIdentity, $target );
391 if ( $performer->isAllowed(
'viewmywatchlist' ) ) {
392 return $this->isTempWatchedIgnoringRights( $performer->
getUser(), $target );
409 ?
string $expiry =
null
411 if ( !$this->isWatchable( $target ) ) {
412 return StatusValue::newFatal(
'watchlistnotwatchable' );
415 $wikiPage = $this->wikiPageFactory->newFromTitle( $target );
416 $title = $wikiPage->getTitle();
419 $status = Status::newFatal(
'hookaborted' );
420 $user = $this->userFactory->newFromUserIdentity( $userIdentity );
421 if ( $this->hookRunner->onWatchArticle( $user, $wikiPage, $status, $expiry ) ) {
422 $status = StatusValue::newGood();
423 $this->watchedItemStore->addWatch( $userIdentity, $this->nsInfo->getSubjectPage(
$title ), $expiry );
424 if ( $this->nsInfo->canHaveTalkPage(
$title ) ) {
425 $this->watchedItemStore->addWatch( $userIdentity, $this->nsInfo->getTalkPage(
$title ), $expiry );
427 $this->hookRunner->onWatchArticleComplete( $user, $wikiPage );
431 $user->invalidateCache();
449 ?
string $expiry =
null
451 if ( !$performer->isAllowed(
'editmywatchlist' ) ) {
456 return $this->addWatchIgnoringRights( $performer->getUser(), $target, $expiry );
470 if ( !$this->isWatchable( $target ) ) {
471 return StatusValue::newFatal(
'watchlistnotwatchable' );
474 $wikiPage = $this->wikiPageFactory->newFromTitle( $target );
475 $title = $wikiPage->getTitle();
478 $status = Status::newFatal(
'hookaborted' );
479 $user = $this->userFactory->newFromUserIdentity( $userIdentity );
480 if ( $this->hookRunner->onUnwatchArticle( $user, $wikiPage, $status ) ) {
481 $status = StatusValue::newGood();
482 $this->watchedItemStore->removeWatch( $userIdentity, $this->nsInfo->getSubjectPage(
$title ) );
483 if ( $this->nsInfo->canHaveTalkPage(
$title ) ) {
484 $this->watchedItemStore->removeWatch( $userIdentity, $this->nsInfo->getTalkPage(
$title ) );
486 $this->hookRunner->onUnwatchArticleComplete( $user, $wikiPage );
490 $user->invalidateCache();
507 if ( !$performer->isAllowed(
'editmywatchlist' ) ) {
512 return $this->removeWatchIgnoringRights( $performer->getUser(), $target );
532 string $expiry =
null
535 if ( !$performer->getUser()->isRegistered() ) {
536 return StatusValue::newGood();
540 $link = TitleValue::newFromPage( $target );
541 $oldWatchedItem = $this->watchedItemStore->getWatchedItem( $performer->getUser(), $link );
542 $changingWatchStatus = (bool)$oldWatchedItem !== $watch;
543 if ( $oldWatchedItem && $expiry !==
null ) {
545 $oldWatchPeriod = $oldWatchedItem->getExpiry() ??
'infinity';
546 $changingWatchStatus = $changingWatchStatus ||
547 $oldWatchPeriod !== ExpiryDef::normalizeExpiry( $expiry, TS_MW );
550 if ( $changingWatchStatus ) {
554 return $this->addWatchIgnoringRights( $performer->getUser(), $target, $expiry );
556 return $this->removeWatch( $performer, $target );
568class_alias( WatchlistManager::class,
'MediaWiki\User\WatchlistNotificationManager' );
if(ini_get('mbstring.func_overload')) if(!defined('MW_ENTRY_POINT'))
Pre-config setup: Before loading LocalSettings.php.
Class for managing the deferral of updates within the scope of a PHP script invocation.
Manages user talk page notifications.
setUserHasNewMessages(UserIdentity $user, RevisionRecord $curRev=null)
Update the talk page messages status.
userHasNewMessages(UserIdentity $user)
Check if the user has new messages.
removeUserHasNewMessages(UserIdentity $user)
Remove the new messages status.
This is a utility class for dealing with namespaces that encodes all the "magic" behaviors of them ba...
A service class for fetching the wiki's current read-only mode.
Generic operation result class Has warning/error list, boolean status and arbitrary value.
static newGood( $value=null)
Factory function for good results.
Generic operation result class Has warning/error list, boolean status and arbitrary value.
Represents a page (or page fragment) title within MediaWiki.
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...