Avoid system styling issue of <textarea>s in Firefox+Linux
[lhc/web/wiklou.git] / includes / WatchedItemStore.php
index eb652ce..6486955 100644 (file)
@@ -145,16 +145,28 @@ class WatchedItemStore implements StatsdAwareInterface {
        }
 
        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
@@ -667,6 +679,41 @@ class WatchedItemStore implements StatsdAwareInterface {
                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)
@@ -697,15 +744,24 @@ class WatchedItemStore implements StatsdAwareInterface {
                        $fname = __METHOD__;
                        $dbw->onTransactionIdle(
                                function () use ( $dbw, $timestamp, $watchers, $target, $fname ) {
-                                       $dbw->update( 'watchlist',
-                                               [ /* SET */
-                                                       'wl_notificationtimestamp' => $dbw->timestamp( $timestamp )
-                                               ], [ /* WHERE */
-                                                       'wl_user' => $watchers,
-                                                       'wl_namespace' => $target->getNamespace(),
-                                                       'wl_title' => $target->getDBkey(),
-                                               ], $fname
-                                       );
+                                       global $wgUpdateRowsPerQuery;
+
+                                       $watchersChunks = array_chunk( $watchers, $wgUpdateRowsPerQuery );
+                                       foreach ( $watchersChunks as $watchersChunk ) {
+                                               $dbw->update( 'watchlist',
+                                                       [ /* SET */
+                                                               'wl_notificationtimestamp' => $dbw->timestamp( $timestamp )
+                                                       ], [ /* WHERE - TODO Use wl_id T130067 */
+                                                               'wl_user' => $watchersChunk,
+                                                               'wl_namespace' => $target->getNamespace(),
+                                                               'wl_title' => $target->getDBkey(),
+                                                       ], $fname
+                                               );
+                                               if ( count( $watchersChunks ) > 1 ) {
+                                                       $dbw->commit( __METHOD__, 'flush' );
+                                                       wfGetLBFactory()->waitForReplication( [ 'wiki' => $dbw->getWikiID() ] );
+                                               }
+                                       }
                                        $this->uncacheLinkTarget( $target );
                                }
                        );