MediaWiki  master
WatchlistNotificationManager.php
Go to the documentation of this file.
1 <?php
2 
23 namespace MediaWiki\User;
24 
25 use DeferredUpdates;
32 use ReadOnlyMode;
34 
41 
42  public const CONSTRUCTOR_OPTIONS = [
43  'UseEnotif',
44  'ShowUpdatedMarker',
45  ];
46 
48  private $options;
49 
51  private $hookRunner;
52 
55 
57  private $readOnlyMode;
58 
60  private $revisionLookup;
61 
64 
67 
85 
95  public function __construct(
97  HookContainer $hookContainer,
103  ) {
104  $options->assertRequiredOptions( self::CONSTRUCTOR_OPTIONS );
105  $this->options = $options;
106  $this->hookRunner = new HookRunner( $hookContainer );
107  $this->permissionManager = $permissionManager;
108  $this->readOnlyMode = $readOnlyMode;
109  $this->revisionLookup = $revisionLookup;
110  $this->talkPageNotificationManager = $talkPageNotificationManager;
111  $this->watchedItemStore = $watchedItemStore;
112  }
113 
123  public function clearAllUserNotifications( UserIdentity $user ) {
124  if ( $this->readOnlyMode->isReadOnly() ) {
125  // Cannot change anything in read only
126  return;
127  }
128 
129  if ( !$this->permissionManager->userHasRight( $user, 'editmywatchlist' ) ) {
130  // User isn't allowed to edit the watchlist
131  return;
132  }
133 
134  if ( !$this->options->get( 'UseEnotif' ) &&
135  !$this->options->get( 'ShowUpdatedMarker' )
136  ) {
137  $this->talkPageNotificationManager->removeUserHasNewMessages( $user );
138  return;
139  }
140 
141  $userId = $user->getId();
142  if ( !$userId ) {
143  return;
144  }
145 
146  $this->watchedItemStore->resetAllNotificationTimestampsForUser( $user );
147 
148  // We also need to clear here the "you have new message" notification for the own
149  // user_talk page; it's cleared one page view later in WikiPage::doViewUpdates().
150  }
151 
164  UserIdentity $user,
166  int $oldid = 0
167  ) {
168  if ( $this->readOnlyMode->isReadOnly() ) {
169  // Cannot change anything in read only
170  return;
171  }
172 
173  if ( !$this->permissionManager->userHasRight( $user, 'editmywatchlist' ) ) {
174  // User isn't allowed to edit the watchlist
175  return;
176  }
177 
178  $userTalkPage = (
179  $title->getNamespace() === NS_USER_TALK &&
180  $title->getText() === $user->getName()
181  );
182 
183  if ( $userTalkPage ) {
184  // If we're working on user's talk page, we should update the talk page message indicator
185  if ( !$this->hookRunner->onUserClearNewTalkNotification( $user, $oldid ) ) {
186  return;
187  }
188 
189  // Try to update the DB post-send and only if needed...
192  DeferredUpdates::addCallableUpdate( function () use (
193  $user,
194  $oldid,
197  ) {
199  // no notifications to clear
200  return;
201  }
202  // Delete the last notifications (they stack up)
204 
205  // If there is a new, unseen, revision, use its timestamp
206  if ( !$oldid ) {
207  return;
208  }
209 
210  $oldRev = $revisionLookup->getRevisionById(
211  $oldid,
212  RevisionLookup::READ_LATEST
213  );
214  if ( !$oldRev ) {
215  return;
216  }
217 
218  $newRev = $revisionLookup->getNextRevision( $oldRev );
219  if ( $newRev ) {
221  $user,
222  $newRev
223  );
224  }
225  } );
226  }
227 
228  if ( !$this->options->get( 'UseEnotif' ) &&
229  !$this->options->get( 'ShowUpdatedMarker' )
230  ) {
231  return;
232  }
233 
234  if ( !$user->isRegistered() ) {
235  // Nothing else to do
236  return;
237  }
238 
239  // Only update the timestamp if the page is being watched.
240  // The query to find out if it is watched is cached both in memcached and per-invocation,
241  // and when it does have to be executed, it can be on a replica DB
242  // If this is the user's newtalk page, we always update the timestamp
243  $force = $userTalkPage ? 'force' : '';
244  $this->watchedItemStore->resetNotificationTimestamp( $user, $title, $force, $oldid );
245  }
246 
255  $userId = $user->getId();
256 
257  if ( !$userId ) {
258  return false;
259  }
260 
261  $cacheKey = 'u' . (string)$userId . '-' .
262  (string)$title->getNamespace() . ':' . $title->getDBkey();
263 
264  // avoid isset here, as it'll return false for null entries
265  if ( array_key_exists( $cacheKey, $this->notificationTimestampCache ) ) {
266  return $this->notificationTimestampCache[ $cacheKey ];
267  }
268 
269  $watchedItem = $this->watchedItemStore->getWatchedItem( $user, $title );
270  if ( $watchedItem ) {
271  $timestamp = $watchedItem->getNotificationTimestamp();
272  } else {
273  $timestamp = false;
274  }
275 
276  $this->notificationTimestampCache[ $cacheKey ] = $timestamp;
277  return $timestamp;
278  }
279 
280 }
MediaWiki\User\WatchlistNotificationManager\$revisionLookup
RevisionLookup $revisionLookup
Definition: WatchlistNotificationManager.php:60
MediaWiki\User\WatchlistNotificationManager\$permissionManager
PermissionManager $permissionManager
Definition: WatchlistNotificationManager.php:54
if
if(ini_get( 'mbstring.func_overload')) if(!defined('MW_ENTRY_POINT'))
Pre-config setup: Before loading LocalSettings.php.
Definition: Setup.php:85
Revision\RevisionLookup\getNextRevision
getNextRevision(RevisionRecord $rev, $flags=0)
Get next revision for this title.
ReadOnlyMode
A service class for fetching the wiki's current read-only mode.
Definition: ReadOnlyMode.php:11
MediaWiki\User\TalkPageNotificationManager\removeUserHasNewMessages
removeUserHasNewMessages(UserIdentity $user)
Remove the new messages status.
Definition: TalkPageNotificationManager.php:121
MediaWiki\User\UserIdentity
Interface for objects representing user identity.
Definition: UserIdentity.php:32
Revision\RevisionLookup
Service for looking up page revisions.
Definition: RevisionLookup.php:38
MediaWiki\User\TalkPageNotificationManager
Manages user talk page notifications.
Definition: TalkPageNotificationManager.php:35
MediaWiki\User\WatchlistNotificationManager\$readOnlyMode
ReadOnlyMode $readOnlyMode
Definition: WatchlistNotificationManager.php:57
MediaWiki\User\WatchlistNotificationManager\getTitleNotificationTimestamp
getTitleNotificationTimestamp(UserIdentity $user, LinkTarget $title)
Get the timestamp when this page was updated since the user last saw it.
Definition: WatchlistNotificationManager.php:254
MediaWiki\User\TalkPageNotificationManager\setUserHasNewMessages
setUserHasNewMessages(UserIdentity $user, RevisionRecord $curRev=null)
Update the talk page messages status.
Definition: TalkPageNotificationManager.php:104
MediaWiki\Config\ServiceOptions
A class for passing options to services.
Definition: ServiceOptions.php:25
MediaWiki\User\UserIdentity\isRegistered
isRegistered()
MediaWiki\User\WatchlistNotificationManager
WatchlistNotificationManager service.
Definition: WatchlistNotificationManager.php:40
MediaWiki\User\WatchlistNotificationManager\$notificationTimestampCache
array $notificationTimestampCache
Cache for getTitleNotificationTimestamp.
Definition: WatchlistNotificationManager.php:84
MediaWiki\User\WatchlistNotificationManager\__construct
__construct(ServiceOptions $options, HookContainer $hookContainer, PermissionManager $permissionManager, ReadOnlyMode $readOnlyMode, RevisionLookup $revisionLookup, TalkPageNotificationManager $talkPageNotificationManager, WatchedItemStoreInterface $watchedItemStore)
Definition: WatchlistNotificationManager.php:95
DeferredUpdates
Class for managing the deferred updates.
Definition: DeferredUpdates.php:62
MediaWiki\User\WatchlistNotificationManager\$talkPageNotificationManager
TalkPageNotificationManager $talkPageNotificationManager
Definition: WatchlistNotificationManager.php:63
Revision\RevisionLookup\getRevisionById
getRevisionById( $id, $flags=0)
Load a page revision from a given revision ID number.
MediaWiki\User\UserIdentity\getName
getName()
$title
$title
Definition: testCompression.php:38
MediaWiki\User\WatchlistNotificationManager\CONSTRUCTOR_OPTIONS
const CONSTRUCTOR_OPTIONS
Definition: WatchlistNotificationManager.php:42
MediaWiki\Permissions\PermissionManager
A service class for checking permissions To obtain an instance, use MediaWikiServices::getInstance()-...
Definition: PermissionManager.php:49
NS_USER_TALK
const NS_USER_TALK
Definition: Defines.php:72
MediaWiki\User\WatchlistNotificationManager\$watchedItemStore
WatchedItemStoreInterface $watchedItemStore
Definition: WatchlistNotificationManager.php:66
MediaWiki\User\WatchlistNotificationManager\$options
ServiceOptions $options
Definition: WatchlistNotificationManager.php:48
MediaWiki\User
Definition: DefaultOptionsLookup.php:21
MediaWiki\User\TalkPageNotificationManager\userHasNewMessages
userHasNewMessages(UserIdentity $user)
Check if the user has new messages.
Definition: TalkPageNotificationManager.php:80
MediaWiki\User\UserIdentity\getId
getId()
MediaWiki\User\WatchlistNotificationManager\clearTitleUserNotifications
clearTitleUserNotifications(UserIdentity $user, LinkTarget $title, int $oldid=0)
Clear the user's notification timestamp for the given title.
Definition: WatchlistNotificationManager.php:163
MediaWiki\User\WatchlistNotificationManager\clearAllUserNotifications
clearAllUserNotifications(UserIdentity $user)
Resets all of the given user's page-change notification timestamps.
Definition: WatchlistNotificationManager.php:123
MediaWiki\HookContainer\HookContainer
HookContainer class.
Definition: HookContainer.php:44
MediaWiki\HookContainer\HookRunner
This class provides an implementation of the core hook interfaces, forwarding hook calls to HookConta...
Definition: HookRunner.php:570
MediaWiki\Linker\LinkTarget
Definition: LinkTarget.php:26
WatchedItemStoreInterface
Definition: WatchedItemStoreInterface.php:30
DeferredUpdates\addCallableUpdate
static addCallableUpdate( $callable, $stage=self::POSTSEND, $dbw=null)
Add a callable update.
Definition: DeferredUpdates.php:145
MediaWiki\Config\ServiceOptions\assertRequiredOptions
assertRequiredOptions(array $expectedKeys)
Assert that the list of options provided in this instance exactly match $expectedKeys,...
Definition: ServiceOptions.php:62
MediaWiki\User\WatchlistNotificationManager\$hookRunner
HookRunner $hookRunner
Definition: WatchlistNotificationManager.php:51