]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blob - includes/FileRevertForm.php
MediaWiki 1.11.0-scripts
[autoinstallsdev/mediawiki.git] / includes / FileRevertForm.php
1 <?php
2
3 /**
4  * File reversion user interface
5  *
6  * @addtogroup Media
7  * @author Rob Church <robchur@gmail.com>
8  */
9 class FileRevertForm {
10
11         private $title = null;
12         private $file = null;
13         private $oldimage = '';
14         private $timestamp = false;
15         
16         /**
17          * Constructor
18          *
19          * @param File $file File we're reverting
20          */
21         public function __construct( $file ) {
22                 $this->title = $file->getTitle();
23                 $this->file = $file;
24         }
25         
26         /**
27          * Fulfil the request; shows the form or reverts the file,
28          * pending authentication, confirmation, etc.
29          */
30         public function execute() {
31                 global $wgOut, $wgRequest, $wgUser, $wgLang, $wgServer;
32                 $this->setHeaders();
33
34                 if( wfReadOnly() ) {
35                         $wgOut->readOnlyPage();
36                         return;
37                 } elseif( !$wgUser->isLoggedIn() ) {
38                         $wgOut->showErrorPage( 'uploadnologin', 'uploadnologintext' );
39                         return;
40                 } elseif( !$this->title->userCan( 'edit' ) ) {
41                         // The standard read-only thing doesn't make a whole lot of sense
42                         // here; surely it should show the image or something? -- RC
43                         $article = new Article( $this->title );
44                         $wgOut->readOnlyPage( $article->getContent(), true );
45                         return;
46                 } elseif( $wgUser->isBlocked() ) {
47                         $wgOut->blockedPage();
48                         return;
49                 }
50                 
51                 $this->oldimage = $wgRequest->getText( 'oldimage' );
52                 $token = $wgRequest->getText( 'wpEditToken' );
53                 if( !$this->isValidOldSpec() ) {
54                         $wgOut->showUnexpectedValueError( 'oldimage', htmlspecialchars( $this->oldimage ) );
55                         return;
56                 }
57                 
58                 if( !$this->haveOldVersion() ) {
59                         $wgOut->addHtml( wfMsgExt( 'filerevert-badversion', 'parse' ) );
60                         $wgOut->returnToMain( false, $this->title );
61                         return;
62                 }
63                 
64                 // Perform the reversion if appropriate
65                 if( $wgRequest->wasPosted() && $wgUser->matchEditToken( $token, $this->oldimage ) ) {
66                         $source = $this->file->getArchiveVirtualUrl( $this->oldimage );
67                         $comment = $wgRequest->getText( 'wpComment' );
68                         // TODO: Preserve file properties from database instead of reloading from file
69                         $status = $this->file->upload( $source, $comment, $comment );
70                         if( $status->isGood() ) {
71                                 $wgOut->addHtml( wfMsgExt( 'filerevert-success', 'parse', $this->title->getText(),
72                                         $wgLang->date( $this->getTimestamp(), true ),
73                                         $wgLang->time( $this->getTimestamp(), true ),
74                                         $wgServer . $this->file->getArchiveUrl( $this->oldimage ) ) );
75                                 $wgOut->returnToMain( false, $this->title );
76                         } else {
77                                 $wgOut->addWikiText( $status->getWikiText() );
78                         }
79                         return;
80                 }
81                 
82                 // Show the form
83                 $this->showForm();              
84         }
85         
86         /**
87          * Show the confirmation form
88          */
89         private function showForm() {
90                 global $wgOut, $wgUser, $wgRequest, $wgLang, $wgContLang, $wgServer;
91                 $timestamp = $this->getTimestamp();
92
93                 $form  = Xml::openElement( 'form', array( 'method' => 'post', 'action' => $this->getAction() ) );
94                 $form .= Xml::hidden( 'wpEditToken', $wgUser->editToken( $this->oldimage ) );
95                 $form .= '<fieldset><legend>' . wfMsgHtml( 'filerevert-legend' ) . '</legend>';
96                 $form .= wfMsgExt( 'filerevert-intro', 'parse', $this->title->getText(),
97                         $wgLang->date( $timestamp, true ), $wgLang->time( $timestamp, true ), $wgServer . $this->file->getArchiveUrl( $this->oldimage ) );
98                 $form .= '<p>' . Xml::inputLabel( wfMsg( 'filerevert-comment' ), 'wpComment', 'wpComment',
99                         60, wfMsgForContent( 'filerevert-defaultcomment',
100                         $wgContLang->date( $timestamp, false, false ), $wgContLang->time( $timestamp, false, false ) ) ) . '</p>';
101                 $form .= '<p>' . Xml::submitButton( wfMsg( 'filerevert-submit' ) ) . '</p>';
102                 $form .= '</fieldset>';
103                 $form .= '</form>';
104                 
105                 $wgOut->addHtml( $form );
106         }
107         
108         /**
109          * Set headers, titles and other bits
110          */
111         private function setHeaders() {
112                 global $wgOut, $wgUser;
113                 $wgOut->setPageTitle( wfMsg( 'filerevert', $this->title->getText() ) );
114                 $wgOut->setRobotPolicy( 'noindex,nofollow' );
115                 $wgOut->setSubtitle( wfMsg( 'filerevert-backlink', $wgUser->getSkin()->makeKnownLinkObj( $this->title ) ) );
116         }
117         
118         /**
119          * Is the provided `oldimage` value valid?
120          *
121          * @return bool
122          */
123         private function isValidOldSpec() {
124                 return strlen( $this->oldimage ) >= 16
125                         && strpos( $this->oldimage, '/' ) === false
126                         && strpos( $this->oldimage, '\\' ) === false;
127         }
128         
129         /**
130          * Does the provided `oldimage` value correspond
131          * to an existing, local, old version of this file?
132          *
133          * @return bool
134          */
135         private function haveOldVersion() {
136                 $file = wfFindFile( $this->title, $this->oldimage );
137                 return $file && $file->exists() && $file->isLocal();
138         }
139         
140         /**
141          * Prepare the form action
142          *
143          * @return string
144          */
145         private function getAction() {
146                 $q = array();
147                 $q[] = 'action=revert';
148                 $q[] = 'oldimage=' . urlencode( $this->oldimage );
149                 return $this->title->getLocalUrl( implode( '&', $q ) );
150         }
151         
152         /**
153          * Extract the timestamp of the old version
154          *
155          * @return string
156          */
157         private function getTimestamp() {
158                 if( $this->timestamp === false ) {
159                         $file = RepoGroup::singleton()->getLocalRepo()->newFromArchiveName( $this->title, $this->oldimage );
160                         $this->timestamp = $file->getTimestamp();
161                 }
162                 return $this->timestamp;
163         }
164         
165 }