<?php
use Liuggio\StatsdClient\Factory\StatsdDataFactoryInterface;
+use MediaWiki\MediaWikiServices;
use MediaWiki\Linker\LinkTarget;
use Wikimedia\Assert\Assert;
*/
private $stats;
- /**
- * @var self|null
- */
- private static $instance;
-
/**
* @param LoadBalancer $loadBalancer
* @param HashBagOStuff $cache
} );
}
- /**
- * Overrides the default instance of this class
- * This is intended for use while testing and will fail if MW_PHPUNIT_TEST is not defined.
- *
- * If this method is used it MUST also be called with null after a test to ensure a new
- * default instance is created next time getDefaultInstance is called.
- *
- * @param WatchedItemStore|null $store
- *
- * @return ScopedCallback to reset the overridden value
- * @throws MWException
- */
- public static function overrideDefaultInstance( WatchedItemStore $store = null ) {
- if ( !defined( 'MW_PHPUNIT_TEST' ) ) {
- throw new MWException(
- 'Cannot override ' . __CLASS__ . 'default instance in operation.'
- );
- }
-
- $previousValue = self::$instance;
- self::$instance = $store;
- return new ScopedCallback( function() use ( $previousValue ) {
- self::$instance = $previousValue;
- } );
- }
-
- /**
- * @return self
- */
- public static function getDefaultInstance() {
- if ( !self::$instance ) {
- self::$instance = new self(
- wfGetLB(),
- new HashBagOStuff( [ 'maxKeys' => 100 ] )
- );
- self::$instance->setStatsdDataFactory( RequestContext::getMain()->getStats() );
- }
- return self::$instance;
- }
-
private function getCacheKey( User $user, LinkTarget $target ) {
return $this->cache->makeKey(
(string)$target->getNamespace(),
}
private function uncacheLinkTarget( LinkTarget $target ) {
+ $this->stats->increment( 'WatchedItemStore.uncacheLinkTarget' );
if ( !isset( $this->cacheIndex[$target->getNamespace()][$target->getDBkey()] ) ) {
return;
}
- $this->stats->increment( 'WatchedItemStore.uncacheLinkTarget' );
foreach ( $this->cacheIndex[$target->getNamespace()][$target->getDBkey()] as $key ) {
$this->stats->increment( 'WatchedItemStore.uncacheLinkTarget.items' );
$this->cache->delete( $key );
}
}
+ private function uncacheUser( User $user ) {
+ $this->stats->increment( 'WatchedItemStore.uncacheUser' );
+ foreach ( $this->cacheIndex as $ns => $dbKeyArray ) {
+ foreach ( $dbKeyArray as $dbKey => $userArray ) {
+ if ( isset( $userArray[$user->getId()] ) ) {
+ $this->stats->increment( 'WatchedItemStore.uncacheUser.items' );
+ $this->cache->delete( $userArray[$user->getId()] );
+ }
+ }
+ }
+ }
+
/**
* @param User $user
* @param LinkTarget $target
$this->reuseConnection( $dbr );
foreach ( $res as $row ) {
- $timestamps[(int)$row->wl_namespace][$row->wl_title] = $row->wl_notificationtimestamp;
+ $timestamps[$row->wl_namespace][$row->wl_title] = $row->wl_notificationtimestamp;
}
return $timestamps;
return $success;
}
+ /**
+ * @param User $user The user to set the timestamp for
+ * @param string $timestamp Set the update timestamp to this value
+ * @param LinkTarget[] $targets List of targets to update. Default to all targets
+ *
+ * @return bool success
+ */
+ public function setNotificationTimestampsForUser( User $user, $timestamp, array $targets = [] ) {
+ // Only loggedin user can have a watchlist
+ if ( $user->isAnon() ) {
+ return false;
+ }
+
+ $dbw = $this->getConnection( DB_MASTER );
+
+ $conds = [ 'wl_user' => $user->getId() ];
+ if ( $targets ) {
+ $batch = new LinkBatch( $targets );
+ $conds[] = $batch->constructSet( 'wl', $dbw );
+ }
+
+ $success = $dbw->update(
+ 'watchlist',
+ [ 'wl_notificationtimestamp' => $dbw->timestamp( $timestamp ) ],
+ $conds,
+ __METHOD__
+ );
+
+ $this->reuseConnection( $dbw );
+
+ $this->uncacheUser( $user );
+
+ return $success;
+ }
+
/**
* @param User $editor The editor that triggered the update. Their notification
* timestamp will not be updated(they have already seen it)