Revision: 46260
Author:   catrope
Date:     2009-01-26 13:51:03 +0000 (Mon, 26 Jan 2009)

Log Message:
-----------
* API: (bug 15949) Add undo functionality to action=edit
* Move undo text generation from EditPage::getContent() to 
Article::getUndoText()
* Add some more examples for action=edit
* ApiEditPage.php: don't mix !is_null() and isset(), be consistent

Modified Paths:
--------------
    trunk/phase3/RELEASE-NOTES
    trunk/phase3/includes/Article.php
    trunk/phase3/includes/EditPage.php
    trunk/phase3/includes/api/ApiBase.php
    trunk/phase3/includes/api/ApiEditPage.php

Modified: trunk/phase3/RELEASE-NOTES
===================================================================
--- trunk/phase3/RELEASE-NOTES  2009-01-26 13:31:05 UTC (rev 46259)
+++ trunk/phase3/RELEASE-NOTES  2009-01-26 13:51:03 UTC (rev 46260)
@@ -97,6 +97,7 @@
 * (bug 17069) Added ucshow=patrolled|!patrolled to list=usercontribs
 * action=delete respects $wgDeleteRevisionsLimit and the bigdelete user right
 * (bug 17024) Added legaltitlechars field to meta=siteinfo&siprop=general 
output
+* (bug 15949) Add undo functionality to action=edit
 
 === Languages updated in 1.15 ===
 

Modified: trunk/phase3/includes/Article.php
===================================================================
--- trunk/phase3/includes/Article.php   2009-01-26 13:31:05 UTC (rev 46259)
+++ trunk/phase3/includes/Article.php   2009-01-26 13:51:03 UTC (rev 46260)
@@ -261,6 +261,28 @@
                global $wgParser;
                return $wgParser->getSection( $text, $section );
        }
+       
+       /**
+        * Get the text that needs to be saved in order to undo all revisions
+        * between $undo and $undoafter. Revisions must belong to the same page,
+        * must exist and must not be deleted
+        * @param $undo Revision 
+        * @param $undoafter Revision Must be an earlier revision than $undo
+        * @return mixed string on success, false on failure
+        */
+       public function getUndoText( Revision $undo, Revision $undoafter = null 
) {
+               $undo_text = $undo->getText();
+               $undoafter_text = $undoafter->getText();
+               $cur_text = $this->getContent();
+               if ( $cur_text == $undo_text ) {
+                       # No use doing a merge if it's just a straight revert.
+                       return $undoafter_text;
+               }
+               $undone_text = '';
+               if ( !wfMerge( $undo_text, $undoafter_text, $cur_text, 
$undone_text ) )
+                       return false;
+               return $undone_text;
+       }
 
        /**
         * @return int The oldid of the article that is to be shown, 0 for the

Modified: trunk/phase3/includes/EditPage.php
===================================================================
--- trunk/phase3/includes/EditPage.php  2009-01-26 13:31:05 UTC (rev 46259)
+++ trunk/phase3/includes/EditPage.php  2009-01-26 13:51:03 UTC (rev 46260)
@@ -165,18 +165,13 @@
                                        $undorev->getPage() == 
$this->mArticle->getID() &&
                                        !$undorev->isDeleted( 
Revision::DELETED_TEXT ) &&
                                        !$oldrev->isDeleted( 
Revision::DELETED_TEXT ) ) {
-                                       $undorev_text = $undorev->getText();
-                                       $oldrev_text = $oldrev->getText();
-                                       $currev_text = $text;
-
-                                       if ( $currev_text != $undorev_text ) {
-                                               $result = wfMerge( 
$undorev_text, $oldrev_text, $currev_text, $text );
+                                       
+                                       $undotext = 
$this->mArticle->getUndoText( $undorev, $oldrev );
+                                       if ( $undotext === false ) {
+                                               # Warn the user that something 
went wrong
+                                               $this->editFormPageTop .= 
$wgOut->parse( '<div class="error mw-undo-failure">' . wfMsgNoTrans( 
'undo-failure' ) . '</div>' );
                                        } else {
-                                               # No use doing a merge if it's 
just a straight revert.
-                                               $text = $oldrev_text;
-                                               $result = true;
-                                       }
-                                       if ( $result ) {
+                                               $text = $undotext;
                                                # Inform the user of our 
success and set an automatic edit summary
                                                $this->editFormPageTop .= 
$wgOut->parse( '<div class="mw-undo-success">' . wfMsgNoTrans( 'undo-success' ) 
. '</div>' );
                                                $firstrev = $oldrev->getNext();
@@ -186,9 +181,6 @@
                                                        $this->undidRev = $undo;
                                                }
                                                $this->formtype = 'diff';
-                                       } else {
-                                               # Warn the user that something 
went wrong
-                                               $this->editFormPageTop .= 
$wgOut->parse( '<div class="error mw-undo-failure">' . wfMsgNoTrans( 
'undo-failure' ) . '</div>' );
                                        }
                                } else {
                                        // Failed basic sanity checks.

Modified: trunk/phase3/includes/api/ApiBase.php
===================================================================
--- trunk/phase3/includes/api/ApiBase.php       2009-01-26 13:31:05 UTC (rev 
46259)
+++ trunk/phase3/includes/api/ApiBase.php       2009-01-26 13:51:03 UTC (rev 
46260)
@@ -705,6 +705,7 @@
                'missingparam' => array('code' => 'no$1', 'info' => "The \$1 
parameter must be set"),
                'invalidtitle' => array('code' => 'invalidtitle', 'info' => 
"Bad title ``\$1''"),
                'nosuchpageid' => array('code' => 'nosuchpageid', 'info' => 
"There is no page with ID \$1"),
+               'nosuchrevid' => array('code' => 'nosuchrevid', 'info' => 
"There is no revision with ID \$1"),
                'invaliduser' => array('code' => 'invaliduser', 'info' => 
"Invalid username ``\$1''"),
                'invalidexpiry' => array('code' => 'invalidexpiry', 'info' => 
"Invalid expiry time ``\$1''"),
                'pastexpiry' => array('code' => 'pastexpiry', 'info' => "Expiry 
time ``\$1'' is in the past"),
@@ -739,8 +740,10 @@
                'blankpage' => array('code' => 'emptypage', 'info' => "Creating 
new, empty pages is not allowed"),
                'editconflict' => array('code' => 'editconflict', 'info' => 
"Edit conflict detected"),
                'hashcheckfailed' => array('code' => 'badmd5', 'info' => "The 
supplied MD5 hash was incorrect"),
-               'missingtext' => array('code' => 'notext', 'info' => "One of 
the text, appendtext and prependtext parameters must be set"),
+               'missingtext' => array('code' => 'notext', 'info' => "One of 
the text, appendtext, prependtext and undo parameters must be set"),
                'emptynewsection' => array('code' => 'emptynewsection', 'info' 
=> 'Creating empty new sections is not possible.'),
+               'revwrongpage' => array('code' => 'revwrongpage', 'info' => 
"r\$1 is not a revision of ``\$2''"),
+               'undo-failure' => array('code' => 'undofailure', 'info' => 
'Undo failed due to conflicting intermediate edits'),
        );
 
        /**

Modified: trunk/phase3/includes/api/ApiEditPage.php
===================================================================
--- trunk/phase3/includes/api/ApiEditPage.php   2009-01-26 13:31:05 UTC (rev 
46259)
+++ trunk/phase3/includes/api/ApiEditPage.php   2009-01-26 13:51:03 UTC (rev 
46260)
@@ -48,7 +48,9 @@
                $params = $this->extractRequestParams();
                if(is_null($params['title']))
                        $this->dieUsageMsg(array('missingparam', 'title'));
-               if(is_null($params['text']) && is_null($params['appendtext']) 
&& is_null($params['prependtext']))
+               if(is_null($params['text']) && is_null($params['appendtext']) &&
+                               is_null($params['prependtext']) &&
+                               $params['undo'] == 0)
                        $this->dieUsageMsg(array('missingtext'));
                if(is_null($params['token']))
                        $this->dieUsageMsg(array('missingparam', 'token'));
@@ -79,9 +81,39 @@
                        $params['text'] = $params['prependtext'] . $content . 
$params['appendtext'];
                        $toMD5 = $params['prependtext'] . $params['appendtext'];
                }
+               
+               if($params['undo'] > 0)
+               {
+                       if($params['undoafter'] > 0)
+                       {
+                               if($params['undo'] < $params['undoafter'])
+                                       list($params['undo'], 
$params['undoafter']) =
+                                       array($params['undoafter'], 
$params['undo']);
+                               $undoafterRev = 
Revision::newFromID($params['undoafter']);
+                       }
+                       $undoRev = Revision::newFromID($params['undo']);
+                       if(is_null($undoRev) || 
$undoRev->isDeleted(Revision::DELETED_TEXT))
+                               $this->dieUsageMsg(array('nosuchrevid', 
$params['undo']));
+                       if($params['undoafter'] == 0)
+                               $undoafterRev = $undoRev->getPrevious();
+                       if(is_null($undoafterRev) || 
$undoafterRev->isDeleted(Revision::DELETED_TEXT))
+                               $this->dieUsageMsg(array('nosuchrevid', 
$params['undoafter']));
+                       if($undoRev->getPage() != $articleObj->getID())
+                               $this->dieUsageMsg(array('revwrongpage', 
$undoRev->getID(), $titleObj->getPrefixedText()));
+                       if($undoafterRev->getPage() != $articleObj->getID())
+                               $this->dieUsageMsg(array('revwrongpage', 
$undoafterRev->getID(), $titleObj->getPrefixedText()));
+                       $newtext = $articleObj->getUndoText($undoRev, 
$undoafterRev);
+                       if($newtext === false)
+                               $this->dieUsageMsg(array('undo-failure'));
+                       $params['text'] = $newtext;
+                       // If no summary was given and we only undid one rev,
+                       // use an autosummary
+                       if(is_null($params['summary']) && 
$titleObj->getNextRevisionID($undoafterRev->getID()) == $params['undo'])
+                               $params['summary'] = 
wfMsgForContent('undo-summary', $params['undo'], $undoRev->getUserText());
+               }
 
                # See if the MD5 hash checks out
-               if(isset($params['md5']))
+               if(!is_null($params['md5']))
                        if(md5($toMD5) !== $params['md5'])
                                $this->dieUsageMsg(array('hashcheckfailed'));
                
@@ -140,9 +172,9 @@
                # Run hooks
                # Handle CAPTCHA parameters
                global $wgRequest;
-               if(isset($params['captchaid']))
+               if(!is_null($params['captchaid']))
                        $wgRequest->setVal( 'wpCaptchaId', $params['captchaid'] 
);
-               if(isset($params['captchaword']))
+               if(!is_null($params['captchaword']))
                        $wgRequest->setVal( 'wpCaptchaWord', 
$params['captchaword'] );
                $r = array();
                if(!wfRunHooks('APIEditBeforeSave', array(&$ep, $ep->textbox1, 
&$r)))
@@ -269,6 +301,12 @@
                        'md5' => null,
                        'prependtext' => null,
                        'appendtext' => null,
+                       'undo' => array(
+                               ApiBase :: PARAM_TYPE => 'integer'
+                       ),
+                       'undoafter' => array(
+                               ApiBase :: PARAM_TYPE => 'integer'
+                       ),
                );
        }
 
@@ -300,13 +338,19 @@
                        'prependtext' => array( 'Add this text to the beginning 
of the page. Overrides text.',
                                                'Don\'t use together with 
section: that won\'t do what you expect.'),
                        'appendtext' => 'Add this text to the end of the page. 
Overrides text',
+                       'undo' => 'Undo this revision. Overrides text, 
prependtext and appendtext',
+                       'undoafter' => 'Undo all revisions from undo to this 
one. If not set, just undo one revision',
                );
        }
 
        protected function getExamples() {
                return array (
                        "Edit a page (anonymous user):",
-                       "    
api.php?action=edit&title=Test&summary=test%20summary&text=article%20content&basetimestamp=20070824123454&token=%2B\\"
+                       "    
api.php?action=edit&title=Test&summary=test%20summary&text=article%20content&basetimestamp=20070824123454&token=%2B\\",
+                       "Prepend __NOTOC__ to a page (anonymous user):",
+                       "    
api.php?action=edit&title=Test&summary=NOTOC&minor&prependtext=__NOTOC__%0A&basetimestamp=20070824123454&token=%2B\\",
+                       "Undo r13579 through r13585 with autosummary(anonymous 
user):",
+                       "    
api.php?action=edit&title=Test&undo=13585&undoafter=13579&basetimestamp=20070824123454&token=%2B\\",
                );
        }
 



_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs

Reply via email to