use Wikimedia\Assert\Assert;
use Wikimedia\ScopedCallback;
use Wikimedia\Rdbms\LoadBalancer;
-use Wikimedia\Rdbms\DBUnexpectedError;
/**
* Storage layer class for WatchedItems.
- * Database interaction.
+ * Database interaction & caching
+ * TODO caching should be factored out into a CachingWatchedItemStore class
*
* Uses database because this uses User::isAnon
*
* @author Addshore
* @since 1.27
*/
-class WatchedItemStore implements StatsdAwareInterface {
-
- const SORT_DESC = 'DESC';
- const SORT_ASC = 'ASC';
+class WatchedItemStore implements WatchedItemStoreInterface, StatsdAwareInterface {
/**
* @var LoadBalancer
$this->revisionGetTimestampFromIdCallback = [ 'Revision', 'getTimestampFromId' ];
}
+ /**
+ * @param StatsdDataFactoryInterface $stats
+ */
public function setStatsdDataFactory( StatsdDataFactoryInterface $stats ) {
$this->stats = $stats;
}
}
/**
- * Count the number of individual items that are watched by the user.
- * If a subject and corresponding talk page are watched this will return 2.
+ * Queues a job that will clear the users watchlist using the Job Queue.
*
- * @param User $user
+ * @since 1.31
*
+ * @param User $user
+ */
+ public function clearUserWatchedItemsUsingJobQueue( User $user ) {
+ $job = ClearUserWatchlistJob::newForUser( $user, $this->getMaxId() );
+ // TODO inject me.
+ JobQueueGroup::singleton()->push( $job );
+ }
+
+ /**
+ * @since 1.31
+ * @return int The maximum current wl_id
+ */
+ public function getMaxId() {
+ $dbr = $this->getConnectionRef( DB_REPLICA );
+ return (int)$dbr->selectField(
+ 'watchlist',
+ 'MAX(wl_id)',
+ '',
+ __METHOD__
+ );
+ }
+
+ /**
+ * @since 1.31
+ * @param User $user
* @return int
*/
public function countWatchedItems( User $user ) {
}
/**
+ * @since 1.27
* @param LinkTarget $target
- *
* @return int
*/
public function countWatchers( LinkTarget $target ) {
}
/**
- * Number of page watchers who also visited a "recent" edit
- *
+ * @since 1.27
* @param LinkTarget $target
- * @param mixed $threshold timestamp accepted by wfTimestamp
- *
+ * @param string|int $threshold
* @return int
- * @throws DBUnexpectedError
- * @throws MWException
*/
public function countVisitingWatchers( LinkTarget $target, $threshold ) {
$dbr = $this->getConnectionRef( DB_REPLICA );
}
/**
+ * @since 1.27
* @param LinkTarget[] $targets
- * @param array $options Allowed keys:
- * 'minimumWatchers' => int
- *
- * @return array multi dimensional like $return[$namespaceId][$titleString] = int $watchers
- * All targets will be present in the result. 0 either means no watchers or the number
- * of watchers was below the minimumWatchers option if passed.
+ * @param array $options
+ * @return array
*/
public function countWatchersMultiple( array $targets, array $options = [] ) {
$dbOptions = [ 'GROUP BY' => [ 'wl_namespace', 'wl_title' ] ];
}
/**
- * Number of watchers of each page who have visited recent edits to that page
- *
- * @param array $targetsWithVisitThresholds array of pairs (LinkTarget $target, mixed $threshold),
- * $threshold is:
- * - a timestamp of the recent edit if $target exists (format accepted by wfTimestamp)
- * - null if $target doesn't exist
+ * @since 1.27
+ * @param array $targetsWithVisitThresholds
* @param int|null $minimumWatchers
- * @return array multi-dimensional like $return[$namespaceId][$titleString] = $watchers,
- * where $watchers is an int:
- * - if the page exists, number of users watching who have visited the page recently
- * - if the page doesn't exist, number of users that have the page on their watchlist
- * - 0 means there are no visiting watchers or their number is below the minimumWatchers
- * option (if passed).
+ * @return array
*/
public function countVisitingWatchersMultiple(
array $targetsWithVisitThresholds,
}
/**
- * Get an item (may be cached)
- *
+ * @since 1.27
* @param User $user
* @param LinkTarget $target
- *
- * @return WatchedItem|false
+ * @return bool
*/
public function getWatchedItem( User $user, LinkTarget $target ) {
if ( $user->isAnon() ) {
}
/**
- * Loads an item from the db
- *
+ * @since 1.27
* @param User $user
* @param LinkTarget $target
- *
- * @return WatchedItem|false
+ * @return bool
*/
public function loadWatchedItem( User $user, LinkTarget $target ) {
// Only loggedin user can have a watchlist
}
/**
+ * @since 1.27
* @param User $user
- * @param array $options Allowed keys:
- * 'forWrite' => bool defaults to false
- * 'sort' => string optional sorting by namespace ID and title
- * one of the self::SORT_* constants
- *
+ * @param array $options
* @return WatchedItem[]
*/
public function getWatchedItemsForUser( User $user, array $options = [] ) {
}
/**
- * Must be called separately for Subject & Talk namespaces
- *
+ * @since 1.27
* @param User $user
* @param LinkTarget $target
- *
* @return bool
*/
public function isWatched( User $user, LinkTarget $target ) {
}
/**
+ * @since 1.27
* @param User $user
* @param LinkTarget[] $targets
- *
- * @return array multi-dimensional like $return[$namespaceId][$titleString] = $timestamp,
- * where $timestamp is:
- * - string|null value of wl_notificationtimestamp,
- * - false if $target is not watched by $user.
+ * @return array
*/
public function getNotificationTimestampsBatch( User $user, array $targets ) {
$timestamps = [];
}
/**
- * Must be called separately for Subject & Talk namespaces
- *
+ * @since 1.27
* @param User $user
* @param LinkTarget $target
*/
}
/**
+ * @since 1.27
* @param User $user
* @param LinkTarget[] $targets
- *
- * @return bool success
+ * @return bool
*/
public function addWatchBatchForUser( User $user, array $targets ) {
if ( $this->readOnlyMode->isReadOnly() ) {
}
/**
- * Removes the an entry for the User watching the LinkTarget
- * Must be called separately for Subject & Talk namespaces
- *
+ * @since 1.27
* @param User $user
* @param LinkTarget $target
- *
- * @return bool success
- * @throws DBUnexpectedError
- * @throws MWException
+ * @return bool
*/
public function removeWatch( User $user, LinkTarget $target ) {
// Only logged in user can have a watchlist
}
/**
- * @param User $user The user to set the timestamp for
- * @param string|null $timestamp Set the update timestamp to this value
- * @param LinkTarget[] $targets List of targets to update. Default to all targets
- *
- * @return bool success
+ * @since 1.27
+ * @param User $user
+ * @param string|int $timestamp
+ * @param LinkTarget[] $targets
+ * @return bool
*/
public function setNotificationTimestampsForUser( User $user, $timestamp, array $targets = [] ) {
// Only loggedin user can have a watchlist
}
/**
- * @param User $editor The editor that triggered the update. Their notification
- * timestamp will not be updated(they have already seen it)
- * @param LinkTarget $target The target to update timestamps for
- * @param string $timestamp Set the update timestamp to this value
- *
- * @return int[] Array of user IDs the timestamp has been updated for
+ * @since 1.27
+ * @param User $editor
+ * @param LinkTarget $target
+ * @param string|int $timestamp
+ * @return int
*/
public function updateNotificationTimestamp( User $editor, LinkTarget $target, $timestamp ) {
$dbw = $this->getConnectionRef( DB_MASTER );
}
/**
- * Reset the notification timestamp of this entry
- *
+ * @since 1.27
* @param User $user
* @param Title $title
- * @param string $force Whether to force the write query to be executed even if the
- * page is not watched or the notification timestamp is already NULL.
- * 'force' in order to force
- * @param int $oldid The revision id being viewed. If not given or 0, latest revision is assumed.
- *
- * @return bool success
+ * @param string $force
+ * @param int $oldid
+ * @return bool
*/
public function resetNotificationTimestamp( User $user, Title $title, $force = '', $oldid = 0 ) {
// Only loggedin user can have a watchlist
}
/**
+ * @since 1.27
* @param User $user
- * @param int $unreadLimit
- *
- * @return int|bool The number of unread notifications
- * true if greater than or equal to $unreadLimit
+ * @param int|null $unreadLimit
+ * @return int|bool
*/
public function countUnreadNotifications( User $user, $unreadLimit = null ) {
$queryOptions = [];
}
/**
- * Check if the given title already is watched by the user, and if so
- * add a watch for the new title.
- *
- * To be used for page renames and such.
- *
+ * @since 1.27
* @param LinkTarget $oldTarget
* @param LinkTarget $newTarget
*/
}
/**
- * Check if the given title already is watched by the user, and if so
- * add a watch for the new title.
- *
- * To be used for page renames and such.
- * This must be called separately for Subject and Talk pages
- *
+ * @since 1.27
* @param LinkTarget $oldTarget
* @param LinkTarget $newTarget
*/