Improvements to {{REVISIONUSER}} handling
authorAaron Schulz <aschulz@wikimedia.org>
Fri, 10 Jun 2016 06:22:45 +0000 (23:22 -0700)
committerOri.livneh <ori@wikimedia.org>
Tue, 14 Jun 2016 19:28:09 +0000 (19:28 +0000)
* Do not change the result to a null editing user anymore.
* Use a new vary-user flag instead of vary-revision. This
  will only cause a reparse on null edits. Normal edits
  can still use the prepared output now.
* Edit stashing now applies for pages with this magic word.
* Fixed bug where the second prepareContentForEdit() call
  (due to vary-X flags) would still check the edit stash.

Bug: T135261
Bug: T136678
Change-Id: Id1733443ac3bf053ca61e5ae25db3fbf4499e9f9

includes/Revision.php
includes/page/WikiPage.php
includes/parser/Parser.php

index 0e45b25..eda8989 100644 (file)
@@ -720,11 +720,28 @@ class Revision implements IDBAccessObject {
        /**
         * Set the revision ID
         *
+        * This should only be used for proposed revisions that turn out to be null edits
+        *
         * @since 1.19
         * @param int $id
         */
        public function setId( $id ) {
-               $this->mId = $id;
+               $this->mId = (int)$id;
+       }
+
+       /**
+        * Set the user ID/name
+        *
+        * This should only be used for proposed revisions that turn out to be null edits
+        *
+        * @since 1.28
+        * @param integer $id User ID
+        * @param string $name User name
+        */
+       public function setUserIdAndName( $id, $name ) {
+               $this->mUser = (int)$id;
+               $this->mUserText = $name;
+               $this->mOrigUserText = $name;
        }
 
        /**
index a3c3ece..8d9d5a8 100644 (file)
@@ -1794,8 +1794,12 @@ class WikiPage implements Page, IDBAccessObject {
                        $this->mTimestamp = $now;
                } else {
                        // Bug 32948: revision ID must be set to page {{REVISIONID}} and
-                       // related variables correctly
+                       // related variables correctly. Likewise for {{REVISIONUSER}} (T135261).
                        $revision->setId( $this->getLatest() );
+                       $revision->setUserIdAndName(
+                               $this->getUser( Revision::RAW ),
+                               $this->getUserText( Revision::RAW )
+                       );
                }
 
                if ( $changed ) {
@@ -2071,7 +2075,7 @@ class WikiPage implements Page, IDBAccessObject {
                } else {
                        $edit->timestamp = wfTimestampNow();
                }
-               // @note: $cachedEdit is not used if the rev ID was referenced in the text
+               // @note: $cachedEdit is safely not used if the rev ID was referenced in the text
                $edit->revid = $revid;
 
                if ( $cachedEdit ) {
@@ -2164,17 +2168,26 @@ class WikiPage implements Page, IDBAccessObject {
                ];
                $content = $revision->getContent();
 
-               // Parse the text
-               // Be careful not to do pre-save transform twice: $text is usually
-               // already pre-save transformed once.
-               if ( !$this->mPreparedEdit || $this->mPreparedEdit->output->getFlag( 'vary-revision' ) ) {
-                       wfDebug( __METHOD__ . ": No prepared edit or vary-revision is set...\n" );
-                       $editInfo = $this->prepareContentForEdit( $content, $revision, $user );
+               // See if the parser output before $revision was inserted is still valid
+               $editInfo = false;
+               if ( !$this->mPreparedEdit ) {
+                       wfDebug( __METHOD__ . ": No prepared edit...\n" );
+               } elseif ( $this->mPreparedEdit->output->getFlag( 'vary-revision' ) ) {
+                       wfDebug( __METHOD__ . ": Prepared edit has vary-revision...\n" );
+               } elseif ( $this->mPreparedEdit->output->getFlag( 'vary-user' ) && !$options['changed'] ) {
+                       wfDebug( __METHOD__ . ": Prepared edit has vary-user and is null...\n" );
                } else {
-                       wfDebug( __METHOD__ . ": No vary-revision, using prepared edit...\n" );
+                       wfDebug( __METHOD__ . ": Using prepared edit...\n" );
                        $editInfo = $this->mPreparedEdit;
                }
 
+               if ( !$editInfo ) {
+                       // Parse the text again if needed. Be careful not to do pre-save transform twice:
+                       // $text is usually already pre-save transformed once. Avoid using the edit stash
+                       // as any prepared content from there or in doEditContent() was already rejected.
+                       $editInfo = $this->prepareContentForEdit( $content, $revision, $user, null, false );
+               }
+
                // Save it to the parser cache.
                // Make sure the cache time matches page_touched to avoid double parsing.
                ParserCache::singleton()->save(
index cbdfec3..63a297b 100644 (file)
@@ -2648,9 +2648,9 @@ class Parser {
                                break;
                        case 'revisionuser':
                                # Let the edit saving system know we should parse the page
-                               # *after* a revision ID has been assigned. This is for null edits.
-                               $this->mOutput->setFlag( 'vary-revision' );
-                               wfDebug( __METHOD__ . ": {{REVISIONUSER}} used, setting vary-revision...\n" );
+                               # *after* a revision ID has been assigned for null edits.
+                               $this->mOutput->setFlag( 'vary-user' );
+                               wfDebug( __METHOD__ . ": {{REVISIONUSER}} used, setting vary-user...\n" );
                                $value = $this->getRevisionUser();
                                break;
                        case 'revisionsize':