* (bug 10739) Users can now enter comments when reverting files
authorRob Church <robchurch@users.mediawiki.org>
Sun, 29 Jul 2007 22:00:46 +0000 (22:00 +0000)
committerRob Church <robchurch@users.mediawiki.org>
Sun, 29 Jul 2007 22:00:46 +0000 (22:00 +0000)
* You'll see some commented-out bits left in indicating I had bigger plans for the interface - some notes there, in case it's possible in the future

RELEASE-NOTES
includes/AutoLoader.php
includes/FileRevertForm.php [new file with mode: 0644]
includes/ImagePage.php
languages/messages/MessagesEn.php
maintenance/language/messages.inc

index 6f66fb7..8e0f4cd 100644 (file)
@@ -160,6 +160,7 @@ it from source control: http://www.mediawiki.org/wiki/Download_from_SVN
   a difference page, to allow refreshing the cache in case of errors
 * (bug 10701) Link to Special:Listusers in default Special:Statistics messages
 * Improved file history presentation
+* (bug 10739) Users can now enter comments when reverting files
 
 == Bugfixes since 1.10 ==
 
index 222222b..0f7f11e 100644 (file)
@@ -101,6 +101,7 @@ function __autoload($className) {
                'ImagePage' => 'includes/ImagePage.php',
                'ImageHistoryList' => 'includes/ImagePage.php',
                'ImageRemote' => 'includes/ImageRemote.php',
+               'FileRevertForm' => 'includes/FileRevertForm.php',
                'Job' => 'includes/JobQueue.php',
                'EmaillingJob' => 'includes/EmaillingJob.php',
                'EnotifNotifyJob' => 'includes/EnotifNotifyJob.php',
diff --git a/includes/FileRevertForm.php b/includes/FileRevertForm.php
new file mode 100644 (file)
index 0000000..68b3b67
--- /dev/null
@@ -0,0 +1,183 @@
+<?php
+
+/**
+ * File reversion user interface
+ *
+ * @addtogroup Media
+ * @author Rob Church <robchur@gmail.com>
+ */
+class FileRevertForm {
+
+       private $title = null;
+       private $file = null;
+       private $oldimage = '';
+       
+       /**
+        * Constructor
+        *
+        * @param File $file File we're reverting
+        */
+       public function __construct( $file ) {
+               $this->title = $file->getTitle();
+               $this->file = $file;
+       }
+       
+       /**
+        * Fulfil the request; shows the form or reverts the file,
+        * pending authentication, confirmation, etc.
+        */
+       public function execute() {
+               global $wgOut, $wgRequest, $wgUser, $wgLang, $wgServer;
+               $this->setHeaders();
+
+               if( wfReadOnly() ) {
+                       $wgOut->readOnlyPage();
+                       return;
+               } elseif( !$wgUser->isLoggedIn() ) {
+                       $wgOut->showErrorPage( 'uploadnologin', 'uploadnologintext' );
+                       return;
+               } elseif( !$this->title->userCan( 'edit' ) ) {
+                       // The standard read-only thing doesn't make a whole lot of sense
+                       // here; surely it should show the image or something? -- RC
+                       $article = new Article( $this->title );
+                       $wgOut->readOnlyPage( $article->getContent(), true );
+                       //$wgOut->readOnlyPage( new Article( $this->title )->getContent(), true );
+                       return;
+               } elseif( $wgUser->isBlocked() ) {
+                       $wgOut->blockedPage();
+                       return;
+               }
+               
+               $this->oldimage = $wgRequest->getText( 'oldimage' );
+               $token = $wgRequest->getText( 'wpEditToken' );
+               if( !$this->isValidOldSpec() ) {
+                       $wgOut->showUnexpectedValueError( 'oldimage', htmlspecialchars( $this->oldimage ) );
+                       return;
+               }
+               
+               if( !$this->haveOldVersion() ) {
+                       $wgOut->addHtml( wfMsgExt( 'filerevert-badversion', 'parse' ) );
+                       $wgOut->returnToMain( false, $this->title );
+                       return;
+               }
+               
+               // Perform the reversion if appropriate
+               if( $wgRequest->wasPosted() && $wgUser->matchEditToken( $token, $this->oldimage ) ) {
+                       $source = $this->file->getArchiveVirtualUrl( $this->oldimage );
+                       $comment = $wgRequest->getText( 'wpComment' );
+                       // TODO: Preserve file properties from database instead of reloading from file
+                       $status = $this->file->upload( $source, $comment, $comment );
+                       if( $status->isGood() ) {
+                               $wgOut->addHtml( wfMsgExt( 'filerevert-success', 'parse', $this->title->getText(),
+                                       $wgLang->timeAndDate( $this->getTimestamp() ),
+                                       $wgServer . $this->file->getArchiveUrl( $this->oldimage ) ) );
+                               $wgOut->returnToMain( false, $this->title );
+                       } else {
+                               $wgOut->addWikiText( $status->getWikiText() );
+                       }
+                       return;
+               }
+               
+               // Show the form
+               $this->showForm();              
+       }
+       
+       /**
+        * Show the confirmation form
+        */
+       private function showForm() {
+               global $wgOut, $wgUser, $wgRequest, $wgLang, $wgContLang, $wgServer;
+               
+               /*
+               $cur = wfFindFile( $this->title );
+               $old = wfFindFile( $this->title, substr( $this->oldimage, 0, 14 ) );
+                */
+               $timestamp = $this->getTimestamp();
+
+               $form  = Xml::openElement( 'form', array( 'method' => 'post', 'action' => $this->getAction() ) );
+               $form .= Xml::hidden( 'wpEditToken', $wgUser->editToken( $this->oldimage ) );
+               $form .= '<fieldset><legend>' . wfMsgHtml( 'filerevert-legend' ) . '</legend>';
+               $form .= wfMsgExt( 'filerevert-intro', 'parse', $this->title->getText(),
+                       $wgLang->timeAndDate( $timestamp ), $wgServer . $this->file->getArchiveUrl( $this->oldimage ) );
+               
+               /*
+                * I was going to do a little comparison (current vs. old) here,
+                * but realised it wasn't too straightforward to do a media transform
+                * with an *old* file version using the current mechanism. Leaving
+                * this here in case it becomes possible in the future. -- RC
+                *
+               $form .= '<table class="compare-files">';
+               $form .= '<tr>';
+               $form .= '<th>' . wfMsgHtml( 'filerevert-current' ) . '</th>';
+               $form .= '<th>' . wfMsgHtml( 'filerevert-old', $old->getTimestamp() ) . '</th>';
+               $form .= '</tr><tr>';
+               // FIXME: Hard-coding magic numbers makes baby Jesus cry...
+               $form .= '<td>' . $this->getThumbnail( $cur, 180 ) . '</td>';
+               $form .= '<td>' . $this->getThumbnail( $old, 180 ) . '</td>';
+               $form .= '</tr>';               
+               $form .= '</table>';
+                */
+               
+               $form .= '<p>' . Xml::inputLabel( wfMsg( 'filerevert-comment' ), 'wpComment', 'wpComment',
+                       40, wfMsgForContent( 'filerevert-defaultcomment',
+                       $wgContLang->timeAndDate( $timestamp, false, false ) ) ) . '</p>';
+               $form .= '<p>' . Xml::submitButton( wfMsg( 'filerevert-submit' ) ) . '</p>';
+               $form .= '</fieldset>';
+               $form .= '</form>';
+               
+               $wgOut->addHtml( $form );
+       }
+       
+       /**
+        * Set headers, titles and other bits
+        */
+       private function setHeaders() {
+               global $wgOut;
+               $wgOut->setPageTitle( wfMsg( 'filerevert', $this->title->getText() ) );
+               $wgOut->setRobotPolicy( 'noindex,nofollow' );
+       }
+       
+       /**
+        * Is the provided `oldimage` value valid?
+        *
+        * @return bool
+        */
+       private function isValidOldSpec() {
+               return strlen( $this->oldimage ) >= 16
+                       && strpos( $this->oldimage, '/' ) === false
+                       && strpos( $this->oldimage, '\\' ) === false;
+       }
+       
+       /**
+        * Does the provided `oldimage` value correspond
+        * to an existing, local, old version of this file?
+        *
+        * @return bool
+        */
+       private function haveOldVersion() {
+               $file = wfFindFile( $this->title, $this->oldimage );
+               return $file && $file->exists() && $file->isLocal();
+       }
+       
+       /**
+        * Prepare the form action
+        *
+        * @return string
+        */
+       private function getAction() {
+               $q = array();
+               $q[] = 'action=revert';
+               $q[] = 'oldimage=' . urlencode( $this->oldimage );
+               return $this->title->getLocalUrl( implode( '&', $q ) );
+       }
+       
+       /**
+        * Extract the timestamp of the old version
+        *
+        * @return string
+        */
+       private function getTimestamp() {
+               return substr( $this->oldimage, 0, 14 );
+       }
+       
+}
\ No newline at end of file
index 0f829b4..c4bd441 100644 (file)
@@ -610,56 +610,12 @@ EOT
                return $status;
        }
 
+       /**
+        * Revert the file to an earlier version
+        */
        function revert() {
-               global $wgOut, $wgRequest, $wgUser;
-
-               $oldimage = $wgRequest->getText( 'oldimage' );
-               if ( strlen( $oldimage ) < 16 ) {
-                       $wgOut->showUnexpectedValueError( 'oldimage', htmlspecialchars($oldimage) );
-                       return;
-               }
-               if ( strstr( $oldimage, "/" ) || strstr( $oldimage, "\\" ) ) {
-                       $wgOut->showUnexpectedValueError( 'oldimage', htmlspecialchars($oldimage) );
-                       return;
-               }
-
-               if ( wfReadOnly() ) {
-                       $wgOut->readOnlyPage();
-                       return;
-               }
-               if( $wgUser->isAnon() ) {
-                       $wgOut->showErrorPage( 'uploadnologin', 'uploadnologintext' );
-                       return;
-               }
-               if ( ! $this->mTitle->userCan( 'edit' ) ) {
-                       $wgOut->readOnlyPage( $this->getContent(), true );
-                       return;
-               }
-               if ( $wgUser->isBlocked() ) {
-                       $wgOut->blockedPage();
-                       return;
-               }
-               if( !$wgUser->matchEditToken( $wgRequest->getVal( 'wpEditToken' ), $oldimage ) ) {
-                       $wgOut->showErrorPage( 'internalerror', 'sessionfailure' );
-                       return;
-               }
-
-               $sourcePath = $this->img->getArchiveVirtualUrl( $oldimage );
-               $comment = wfMsg( "reverted" );
-               // TODO: preserve file properties from DB instead of reloading from file
-               $status = $this->img->upload( $sourcePath, $comment, $comment );
-
-               if ( !$status->isGood() ) {
-                       $this->showError( $status->getWikiText() );
-                       return;
-               }
-
-               $wgOut->setPagetitle( wfMsg( 'actioncomplete' ) );
-               $wgOut->setRobotpolicy( 'noindex,nofollow' );
-               $wgOut->addHTML( wfMsg( 'imagereverted' ) );
-
-               $descTitle = $this->img->getTitle();
-               $wgOut->returnToMain( false, $descTitle->getPrefixedText() );
+               $reverter = new FileRevertForm( $this->img );
+               $reverter->execute();
        }
        
        /**
index b6bf8b4..940168d 100644 (file)
@@ -1467,6 +1467,16 @@ If you have this image in full resolution upload this one, otherwise change the
 'imagelist_description'     => 'Description',
 'imagelist_search_for'      => 'Search for image name:',
 
+# File reversion
+'filerevert' => 'Revert $1',
+'filerevert-legend' => 'Revert file',
+'filerevert-intro' => "<span class=\"plainlinks\">You are reverting '''[[Media:$1|$1]]''' to the [$3 version as of $2].</span>",
+'filerevert-comment' => 'Comment:',
+'filerevert-defaultcomment' => 'Reverted to version as of $1',
+'filerevert-submit' => 'Revert',
+'filerevert-success' => "<span class=\"plainlinks\">'''[[Media:$1|$1]]''' has been reverted to the [$3 version as of $2].</span>",
+'filerevert-badversion' => 'There is no previous local version of this file with the provided timestamp.',
+
 # MIME search
 'mimesearch'         => 'MIME search',
 'mimesearch-summary' => 'This page enables the filtering of files for its MIME-type. Input: contenttype/subtype, e.g. <tt>image/jpeg</tt>.',
@@ -1793,7 +1803,6 @@ See $2 for a record of recent deletions.',
 'deletionlog'                 => 'deletion log',
 'reverted'                    => 'Reverted to earlier revision',
 'deletecomment'               => 'Reason for deletion',
-'imagereverted'               => 'Revert to earlier version was successful.',
 'rollback'                    => 'Roll back edits',
 'rollback_short'              => 'Rollback',
 'rollbacklink'                => 'rollback',
index 4700bd3..f30850c 100644 (file)
@@ -877,6 +877,16 @@ $wgMessageStructure = array(
                'imagelist_description',
                'imagelist_search_for',
        ),
+       'filerevert' => array(
+               'filerevert',
+               'filerevert-legend',
+               'filerevert-intro',
+               'filerevert-comment',
+               'filerevert-defaultcomment',
+               'filerevert-submit',
+               'filerevert-success',
+               'filerevert-badversion',
+       ),
        'mimesearch' => array(
                'mimesearch',
                'mimesearch-summary',
@@ -1155,7 +1165,6 @@ $wgMessageStructure = array(
                'deletionlog',
                'reverted',
                'deletecomment',
-               'imagereverted',
                'rollback',
                'rollback_short',
                'rollbacklink',