(bug 41990) Fix regression in API edit of redirect
authorBrad Jorsch <bjorsch@wikimedia.org>
Mon, 12 Nov 2012 05:42:26 +0000 (21:42 -0800)
committerReedy <reedy@wikimedia.org>
Mon, 12 Nov 2012 15:03:27 +0000 (15:03 +0000)
Before ContentHandler, an API edit passing a redirect for title and
redirect=true and omitting basetimestamp would use the last revision
timestamp of the target page. When ContentHandler was merged, this was
accidentally changed to use the last revision timestamp of the redirect
page, which was likely much earlier than the target page's last revision
and so causes an edit conflict in almost all cases.

Some scripts took advantage of this along with appendtext to add notices
to users' talk pages, so restore that old behavior. We'll also adjust
the contentmodel/contentformat detection added by ContentHandler to use
the model and format of the target page rather than the redirect in this
case, as that seems more likely to be less wrong.

Change-Id: If0c674e26a4deb54ec14f0bf45418d666a397347

RELEASE-NOTES-1.21
includes/api/ApiEditPage.php

index 923df75..16d842b 100644 (file)
@@ -63,6 +63,8 @@ production.
 * (bug 41899) A PHP notice no longer occurs when using the "rvcontinue" API parameter.
 * (bug 42036) Account creation emails now contain canonical (not
   protocol-relative) URLs.
+* (bug 41990) Fix regression: API edit with redirect=true and lacking
+  starttimestamp and basetimestamp should not cause an edit conflict.
 
 === API changes in 1.21 ===
 * prop=revisions can now report the contentmodel and contentformat, see docs/contenthandler.txt
index 4cb91bc..81b3ef2 100644 (file)
@@ -54,28 +54,6 @@ class ApiEditPage extends ApiBase {
                        $this->dieUsageMsg( array( 'invalidtitle', $params['title'] ) );
                }
 
-               if ( !isset( $params['contentmodel'] ) || $params['contentmodel'] == '' ) {
-                       $contentHandler = $pageObj->getContentHandler();
-               } else {
-                       $contentHandler = ContentHandler::getForModelID( $params['contentmodel'] );
-               }
-
-               // @todo ask handler whether direct editing is supported at all! make allowFlatEdit() method or some such
-
-               if ( !isset( $params['contentformat'] ) || $params['contentformat'] == '' ) {
-                       $params['contentformat'] = $contentHandler->getDefaultFormat();
-               }
-
-               $contentFormat = $params['contentformat'];
-
-               if ( !$contentHandler->isSupportedFormat( $contentFormat ) ) {
-                       $name = $titleObj->getPrefixedDBkey();
-                       $model = $contentHandler->getModelID();
-
-                       $this->dieUsage( "The requested format $contentFormat is not supported for content model ".
-                                                       " $model used by $name", 'badformat' );
-               }
-
                $apiResult = $this->getResult();
 
                if ( $params['redirect'] ) {
@@ -104,9 +82,34 @@ class ApiEditPage extends ApiBase {
 
                                $apiResult->setIndexedTagName( $redirValues, 'r' );
                                $apiResult->addValue( null, 'redirects', $redirValues );
+
+                               // Since the page changed, update $pageObj
+                               $pageObj = WikiPage::factory( $titleObj );
                        }
                }
 
+               if ( !isset( $params['contentmodel'] ) || $params['contentmodel'] == '' ) {
+                       $contentHandler = $pageObj->getContentHandler();
+               } else {
+                       $contentHandler = ContentHandler::getForModelID( $params['contentmodel'] );
+               }
+
+               // @todo ask handler whether direct editing is supported at all! make allowFlatEdit() method or some such
+
+               if ( !isset( $params['contentformat'] ) || $params['contentformat'] == '' ) {
+                       $params['contentformat'] = $contentHandler->getDefaultFormat();
+               }
+
+               $contentFormat = $params['contentformat'];
+
+               if ( !$contentHandler->isSupportedFormat( $contentFormat ) ) {
+                       $name = $titleObj->getPrefixedDBkey();
+                       $model = $contentHandler->getModelID();
+
+                       $this->dieUsage( "The requested format $contentFormat is not supported for content model ".
+                                                       " $model used by $name", 'badformat' );
+               }
+
                if ( $params['createonly'] && $titleObj->exists() ) {
                        $this->dieUsageMsg( 'createonly-exists' );
                }