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 
45  public const CONSTRUCTOR_OPTIONS = [
46  'UseEnotif',
47  'ShowUpdatedMarker',
48  ];
49 
51  private $options;
52 
54  private $hookRunner;
55 
58 
60  private $readOnlyMode;
61 
63  private $revisionLookup;
64 
67 
70 
88 
98  public function __construct(
100  HookContainer $hookContainer,
106  ) {
107  $options->assertRequiredOptions( self::CONSTRUCTOR_OPTIONS );
108  $this->options = $options;
109  $this->hookRunner = new HookRunner( $hookContainer );
110  $this->permissionManager = $permissionManager;
111  $this->readOnlyMode = $readOnlyMode;
112  $this->revisionLookup = $revisionLookup;
113  $this->talkPageNotificationManager = $talkPageNotificationManager;
114  $this->watchedItemStore = $watchedItemStore;
115  }
116 
126  public function clearAllUserNotifications( UserIdentity $user ) {
127  if ( $this->readOnlyMode->isReadOnly() ) {
128  // Cannot change anything in read only
129  return;
130  }
131 
132  if ( !$this->permissionManager->userHasRight( $user, 'editmywatchlist' ) ) {
133  // User isn't allowed to edit the watchlist
134  return;
135  }
136 
137  if ( !$this->options->get( 'UseEnotif' ) &&
138  !$this->options->get( 'ShowUpdatedMarker' )
139  ) {
140  $this->talkPageNotificationManager->removeUserHasNewMessages( $user );
141  return;
142  }
143 
144  $userId = $user->getId();
145  if ( !$userId ) {
146  return;
147  }
148 
149  $this->watchedItemStore->resetAllNotificationTimestampsForUser( $user );
150 
151  // We also need to clear here the "you have new message" notification for the own
152  // user_talk page; it's cleared one page view later in WikiPage::doViewUpdates().
153  }
154 
167  UserIdentity $user,
169  int $oldid = 0
170  ) {
171  if ( $this->readOnlyMode->isReadOnly() ) {
172  // Cannot change anything in read only
173  return;
174  }
175 
176  if ( !$this->permissionManager->userHasRight( $user, 'editmywatchlist' ) ) {
177  // User isn't allowed to edit the watchlist
178  return;
179  }
180 
181  $userTalkPage = (
182  $title->getNamespace() === NS_USER_TALK &&
183  $title->getText() === $user->getName()
184  );
185 
186  if ( $userTalkPage ) {
187  // If we're working on user's talk page, we should update the talk page message indicator
188  if ( !$this->hookRunner->onUserClearNewTalkNotification( $user, $oldid ) ) {
189  return;
190  }
191 
192  // Try to update the DB post-send and only if needed...
195  DeferredUpdates::addCallableUpdate( function () use (
196  $user,
197  $oldid,
200  ) {
202  // no notifications to clear
203  return;
204  }
205  // Delete the last notifications (they stack up)
207 
208  // If there is a new, unseen, revision, use its timestamp
209  if ( !$oldid ) {
210  return;
211  }
212 
213  $oldRev = $revisionLookup->getRevisionById(
214  $oldid,
215  RevisionLookup::READ_LATEST
216  );
217  if ( !$oldRev ) {
218  return;
219  }
220 
221  $newRev = $revisionLookup->getNextRevision( $oldRev );
222  if ( $newRev ) {
224  $user,
225  $newRev
226  );
227  }
228  } );
229  }
230 
231  if ( !$this->options->get( 'UseEnotif' ) &&
232  !$this->options->get( 'ShowUpdatedMarker' )
233  ) {
234  return;
235  }
236 
237  if ( !$user->isRegistered() ) {
238  // Nothing else to do
239  return;
240  }
241 
242  // Only update the timestamp if the page is being watched.
243  // The query to find out if it is watched is cached both in memcached and per-invocation,
244  // and when it does have to be executed, it can be on a replica DB
245  // If this is the user's newtalk page, we always update the timestamp
246  $force = $userTalkPage ? 'force' : '';
247  $this->watchedItemStore->resetNotificationTimestamp( $user, $title, $force, $oldid );
248  }
249 
258  $userId = $user->getId();
259 
260  if ( !$userId ) {
261  return false;
262  }
263 
264  $cacheKey = 'u' . (string)$userId . '-' .
265  (string)$title->getNamespace() . ':' . $title->getDBkey();
266 
267  // avoid isset here, as it'll return false for null entries
268  if ( array_key_exists( $cacheKey, $this->notificationTimestampCache ) ) {
269  return $this->notificationTimestampCache[ $cacheKey ];
270  }
271 
272  $watchedItem = $this->watchedItemStore->getWatchedItem( $user, $title );
273  if ( $watchedItem ) {
274  $timestamp = $watchedItem->getNotificationTimestamp();
275  } else {
276  $timestamp = false;
277  }
278 
279  $this->notificationTimestampCache[ $cacheKey ] = $timestamp;
280  return $timestamp;
281  }
282 
283 }
MediaWiki\User\WatchlistNotificationManager\$revisionLookup
RevisionLookup $revisionLookup
Definition: WatchlistNotificationManager.php:63
MediaWiki\User\WatchlistNotificationManager\$permissionManager
PermissionManager $permissionManager
Definition: WatchlistNotificationManager.php:57
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:124
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:60
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:257
MediaWiki\User\TalkPageNotificationManager\setUserHasNewMessages
setUserHasNewMessages(UserIdentity $user, RevisionRecord $curRev=null)
Update the talk page messages status.
Definition: TalkPageNotificationManager.php:107
MediaWiki\Config\ServiceOptions
A class for passing options to services.
Definition: ServiceOptions.php:27
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:87
MediaWiki\User\WatchlistNotificationManager\__construct
__construct(ServiceOptions $options, HookContainer $hookContainer, PermissionManager $permissionManager, ReadOnlyMode $readOnlyMode, RevisionLookup $revisionLookup, TalkPageNotificationManager $talkPageNotificationManager, WatchedItemStoreInterface $watchedItemStore)
Definition: WatchlistNotificationManager.php:98
DeferredUpdates
Class for managing the deferral of updates within the scope of a PHP script invocation.
Definition: DeferredUpdates.php:82
MediaWiki\User\WatchlistNotificationManager\$talkPageNotificationManager
TalkPageNotificationManager $talkPageNotificationManager
Definition: WatchlistNotificationManager.php:66
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:45
MediaWiki\Permissions\PermissionManager
A service class for checking permissions To obtain an instance, use MediaWikiServices::getInstance()-...
Definition: PermissionManager.php:51
MediaWiki\User\WatchlistNotificationManager\$watchedItemStore
WatchedItemStoreInterface $watchedItemStore
Definition: WatchlistNotificationManager.php:69
MediaWiki\User\WatchlistNotificationManager\$options
ServiceOptions $options
Definition: WatchlistNotificationManager.php:51
MediaWiki\User
Definition: DefaultOptionsLookup.php:21
MediaWiki\User\TalkPageNotificationManager\userHasNewMessages
userHasNewMessages(UserIdentity $user)
Check if the user has new messages.
Definition: TalkPageNotificationManager.php:83
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:166
NS_USER_TALK
const NS_USER_TALK
Definition: Defines.php:66
MediaWiki\User\WatchlistNotificationManager\clearAllUserNotifications
clearAllUserNotifications(UserIdentity $user)
Resets all of the given user's page-change notification timestamps.
Definition: WatchlistNotificationManager.php:126
MediaWiki\HookContainer\HookContainer
HookContainer class.
Definition: HookContainer.php:45
MediaWiki\HookContainer\HookRunner
This class provides an implementation of the core hook interfaces, forwarding hook calls to HookConta...
Definition: HookRunner.php:571
MediaWiki\Linker\LinkTarget
Definition: LinkTarget.php:26
WatchedItemStoreInterface
Definition: WatchedItemStoreInterface.php:30
DeferredUpdates\addCallableUpdate
static addCallableUpdate( $callable, $stage=self::POSTSEND, $dbw=null)
Add an update to the pending update queue that invokes the specified callback when run.
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:66
MediaWiki\User\WatchlistNotificationManager\$hookRunner
HookRunner $hookRunner
Definition: WatchlistNotificationManager.php:54