Avoid multiple writes to changetags table in recentchanges_save hook
authorcenarium <cenarium.sysop@gmail.com>
Fri, 23 Sep 2016 14:36:48 +0000 (16:36 +0200)
committercenarium <cenarium.sysop@gmail.com>
Tue, 27 Sep 2016 14:08:31 +0000 (16:08 +0200)
Currently, extensions that add tags within the recentchanges_save
hook directly call ChangeTags::addTags. This often results in
consecutive writes to the changetags table.
This provides a addTags method to RecentChange so extensions
can simply use it when they want a tag added. And all the actual
tagging is done once at the end.

Change-Id: I8df2fd983c12632337e8d2922fa357808482338c

includes/changes/RecentChange.php
includes/logging/LogEntry.php

index 794865e..7ae1f29 100644 (file)
@@ -90,6 +90,11 @@ class RecentChange {
         */
        public $counter = -1;
 
+       /**
+        * @var array List of tags to apply
+        */
+       private $tags = [];
+
        /**
         * @var array Array of change types
         */
@@ -326,6 +331,11 @@ class RecentChange {
                # Notify extensions
                Hooks::run( 'RecentChange_save', [ &$this ] );
 
+               if ( count( $this->tags ) ) {
+                       ChangeTags::addTags( $this->tags, $this->mAttribs['rc_id'],
+                               $this->mAttribs['rc_this_oldid'], $this->mAttribs['rc_logid'], null );
+               }
+
                # Notify external application via UDP
                if ( !$noudp ) {
                        $this->notifyRCFeeds();
@@ -610,14 +620,11 @@ class RecentChange {
 
                DeferredUpdates::addCallableUpdate(
                        function () use ( $rc, $tags ) {
+                               $rc->addTags( $tags );
                                $rc->save();
                                if ( $rc->mAttribs['rc_patrolled'] ) {
                                        PatrolLog::record( $rc, true, $rc->getPerformer() );
                                }
-                               if ( count( $tags ) ) {
-                                       ChangeTags::addTags( $tags, $rc->mAttribs['rc_id'],
-                                               $rc->mAttribs['rc_this_oldid'], null, null );
-                               }
                        },
                        DeferredUpdates::POSTSEND,
                        wfGetDB( DB_MASTER )
@@ -686,14 +693,11 @@ class RecentChange {
 
                DeferredUpdates::addCallableUpdate(
                        function () use ( $rc, $tags ) {
+                               $rc->addTags( $tags );
                                $rc->save();
                                if ( $rc->mAttribs['rc_patrolled'] ) {
                                        PatrolLog::record( $rc, true, $rc->getPerformer() );
                                }
-                               if ( count( $tags ) ) {
-                                       ChangeTags::addTags( $tags, $rc->mAttribs['rc_id'],
-                                               $rc->mAttribs['rc_this_oldid'], null, null );
-                               }
                        },
                        DeferredUpdates::POSTSEND,
                        wfGetDB( DB_MASTER )
@@ -1026,4 +1030,16 @@ class RecentChange {
 
                return $unserializedParams;
        }
+
+       /**
+        * Tags to append to the recent change,
+        * and associated revision/log
+        *
+        * @since 1.28
+        *
+        * @param array $tags
+        */
+       public function addTags( $tags ) {
+               $this->tags = array_merge( $tags, $this->tags );
+       }
 }
index 7746d99..21864ee 100644 (file)
@@ -714,6 +714,12 @@ class ManualLogEntry extends LogEntryBase {
                                        $rc = $this->getRecentChange( $newId );
 
                                        if ( $to === 'rc' || $to === 'rcandudp' ) {
+                                               // save RC, passing tags so they are applied there
+                                               $tags = $this->getTags();
+                                               if ( is_null( $tags ) ) {
+                                                       $tags = [];
+                                               }
+                                               $rc->addTags( $tags );
                                                $rc->save( 'pleasedontudp' );
                                        }
 
@@ -727,14 +733,6 @@ class ManualLogEntry extends LogEntryBase {
                                        ) {
                                                PatrolLog::record( $rc, true, $this->getPerformer() );
                                        }
-
-                                       // Add change tags to the log entry and (if applicable) the associated revision
-                                       $tags = $this->getTags();
-                                       if ( !is_null( $tags ) ) {
-                                               $rcId = $rc->getAttribute( 'rc_id' );
-                                               $revId = $this->getAssociatedRevId(); // Use null if $revId is 0
-                                               ChangeTags::addTags( $tags, $rcId, $revId > 0 ? $revId : null, $newId );
-                                       }
                                }
                        },
                        DeferredUpdates::POSTSEND,