resourceloader: Use upsert() instead of replace() for module_deps write
[lhc/web/wiklou.git] / includes / WatchedItemStore.php
index 6c47cae..858d87b 100644 (file)
@@ -2,6 +2,7 @@
 
 use Liuggio\StatsdClient\Factory\StatsdDataFactoryInterface;
 use MediaWiki\Linker\LinkTarget;
+use MediaWiki\MediaWikiServices;
 use Wikimedia\Assert\Assert;
 use Wikimedia\ScopedCallback;
 
@@ -167,7 +168,7 @@ class WatchedItemStore implements StatsdAwareInterface {
         * @param User $user
         * @param LinkTarget $target
         *
-        * @return WatchedItem|null
+        * @return WatchedItem|false
         */
        private function getCached( User $user, LinkTarget $target ) {
                return $this->cache->get( $this->getCacheKey( $user, $target ) );
@@ -495,7 +496,7 @@ class WatchedItemStore implements StatsdAwareInterface {
 
                $watchedItems = [];
                foreach ( $res as $row ) {
-                       // todo these could all be cached at some point?
+                       // @todo: Should we add these to the process cache?
                        $watchedItems[] = new WatchedItem(
                                $user,
                                new TitleValue( (int)$row->wl_namespace, $row->wl_title ),
@@ -602,6 +603,7 @@ class WatchedItemStore implements StatsdAwareInterface {
                }
 
                $rows = [];
+               $items = [];
                foreach ( $targets as $target ) {
                        $rows[] = [
                                'wl_user' => $user->getId(),
@@ -609,6 +611,11 @@ class WatchedItemStore implements StatsdAwareInterface {
                                'wl_title' => $target->getDBkey(),
                                'wl_notificationtimestamp' => null,
                        ];
+                       $items[] = new WatchedItem(
+                               $user,
+                               $target,
+                               null
+                       );
                        $this->uncache( $user, $target );
                }
 
@@ -618,6 +625,12 @@ class WatchedItemStore implements StatsdAwareInterface {
                        // if there's already an entry for this page
                        $dbw->insert( 'watchlist', $toInsert, __METHOD__, 'IGNORE' );
                }
+               // Update process cache to ensure skin doesn't claim that the current
+               // page is unwatched in the response of action=watch itself (T28292).
+               // This would otherwise be re-queried from a slave by isWatched().
+               foreach ( $items as $item ) {
+                       $this->cache( $item );
+               }
 
                return true;
        }
@@ -656,7 +669,7 @@ class WatchedItemStore implements StatsdAwareInterface {
 
        /**
         * @param User $user The user to set the timestamp for
-        * @param string $timestamp Set the update timestamp to this value
+        * @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
@@ -675,9 +688,13 @@ class WatchedItemStore implements StatsdAwareInterface {
                        $conds[] = $batch->constructSet( 'wl', $dbw );
                }
 
+               if ( $timestamp !== null ) {
+                       $timestamp = $dbw->timestamp( $timestamp );
+               }
+
                $success = $dbw->update(
                        'watchlist',
-                       [ 'wl_notificationtimestamp' => $dbw->timestamp( $timestamp ) ],
+                       [ 'wl_notificationtimestamp' => $timestamp ],
                        $conds,
                        __METHOD__
                );
@@ -718,7 +735,7 @@ class WatchedItemStore implements StatsdAwareInterface {
                                        global $wgUpdateRowsPerQuery;
 
                                        $dbw = $this->getConnectionRef( DB_MASTER );
-                                       $factory = wfGetLBFactory();
+                                       $factory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
                                        $ticket = $factory->getEmptyTransactionTicket( __METHOD__ );
 
                                        $watchersChunks = array_chunk( $watchers, $wgUpdateRowsPerQuery );