X-Git-Url: https://git.cyclocoop.org/%242?a=blobdiff_plain;f=includes%2Fwatcheditem%2FWatchedItemStore.php;h=35e824e036eab6bd96ea915204209874408cc488;hb=3c198b9dc85654bddf4bf7ad8875339151bc15c1;hp=c68d6d7fdff57235df010ecd78c0a4e6b00336c0;hpb=0caca7aefdf9ebb31c90adb25f1bc6758704c42c;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/watcheditem/WatchedItemStore.php b/includes/watcheditem/WatchedItemStore.php index c68d6d7fdf..35e824e036 100644 --- a/includes/watcheditem/WatchedItemStore.php +++ b/includes/watcheditem/WatchedItemStore.php @@ -13,10 +13,6 @@ use Wikimedia\Rdbms\LoadBalancer; * Database interaction & caching * TODO caching should be factored out into a CachingWatchedItemStore class * - * Uses database because this uses User::isAnon - * - * @group Database - * * @author Addshore * @since 1.27 */ @@ -55,6 +51,11 @@ class WatchedItemStore implements WatchedItemStoreInterface, StatsdAwareInterfac */ private $revisionGetTimestampFromIdCallback; + /** + * @var int + */ + private $updateRowsPerQuery; + /** * @var StatsdDataFactoryInterface */ @@ -64,18 +65,23 @@ class WatchedItemStore implements WatchedItemStoreInterface, StatsdAwareInterfac * @param LoadBalancer $loadBalancer * @param HashBagOStuff $cache * @param ReadOnlyMode $readOnlyMode + * @param int $updateRowsPerQuery */ public function __construct( LoadBalancer $loadBalancer, HashBagOStuff $cache, - ReadOnlyMode $readOnlyMode + ReadOnlyMode $readOnlyMode, + $updateRowsPerQuery ) { $this->loadBalancer = $loadBalancer; $this->cache = $cache; $this->readOnlyMode = $readOnlyMode; $this->stats = new NullStatsdDataFactory(); - $this->deferredUpdatesAddCallableUpdateCallback = [ 'DeferredUpdates', 'addCallableUpdate' ]; - $this->revisionGetTimestampFromIdCallback = [ 'Revision', 'getTimestampFromId' ]; + $this->deferredUpdatesAddCallableUpdateCallback = + [ DeferredUpdates::class, 'addCallableUpdate' ]; + $this->revisionGetTimestampFromIdCallback = + [ Revision::class, 'getTimestampFromId' ]; + $this->updateRowsPerQuery = $updateRowsPerQuery; } /** @@ -215,6 +221,56 @@ class WatchedItemStore implements WatchedItemStoreInterface, StatsdAwareInterfac return $this->loadBalancer->getConnectionRef( $dbIndex, [ 'watchlist' ] ); } + /** + * Deletes ALL watched items for the given user when under + * $updateRowsPerQuery entries exist. + * + * @since 1.30 + * + * @param User $user + * + * @return bool true on success, false when too many items are watched + */ + public function clearUserWatchedItems( User $user ) { + if ( $this->countWatchedItems( $user ) > $this->updateRowsPerQuery ) { + return false; + } + + $dbw = $this->loadBalancer->getConnectionRef( DB_MASTER ); + $dbw->delete( + 'watchlist', + [ 'wl_user' => $user->getId() ], + __METHOD__ + ); + $this->uncacheAllItemsForUser( $user ); + + return true; + } + + private function uncacheAllItemsForUser( User $user ) { + $userId = $user->getId(); + foreach ( $this->cacheIndex as $ns => $dbKeyIndex ) { + foreach ( $dbKeyIndex as $dbKey => $userIndex ) { + if ( array_key_exists( $userId, $userIndex ) ) { + $this->cache->delete( $userIndex[$userId] ); + unset( $this->cacheIndex[$ns][$dbKey][$userId] ); + } + } + } + + // Cleanup empty cache keys + foreach ( $this->cacheIndex as $ns => $dbKeyIndex ) { + foreach ( $dbKeyIndex as $dbKey => $userIndex ) { + if ( empty( $this->cacheIndex[$ns][$dbKey] ) ) { + unset( $this->cacheIndex[$ns][$dbKey] ); + } + } + if ( empty( $this->cacheIndex[$ns] ) ) { + unset( $this->cacheIndex[$ns] ); + } + } + } + /** * Queues a job that will clear the users watchlist using the Job Queue. *