* (bug 10739) Users can now enter comments when reverting files
[lhc/web/wiklou.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
15 /**
16 * Constructor
17 *
18 * @param File $file File we're reverting
19 */
20 public function __construct( $file ) {
21 $this->title = $file->getTitle();
22 $this->file = $file;
23 }
24
25 /**
26 * Fulfil the request; shows the form or reverts the file,
27 * pending authentication, confirmation, etc.
28 */
29 public function execute() {
30 global $wgOut, $wgRequest, $wgUser, $wgLang, $wgServer;
31 $this->setHeaders();
32
33 if( wfReadOnly() ) {
34 $wgOut->readOnlyPage();
35 return;
36 } elseif( !$wgUser->isLoggedIn() ) {
37 $wgOut->showErrorPage( 'uploadnologin', 'uploadnologintext' );
38 return;
39 } elseif( !$this->title->userCan( 'edit' ) ) {
40 // The standard read-only thing doesn't make a whole lot of sense
41 // here; surely it should show the image or something? -- RC
42 $article = new Article( $this->title );
43 $wgOut->readOnlyPage( $article->getContent(), true );
44 //$wgOut->readOnlyPage( new Article( $this->title )->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->timeAndDate( $this->getTimestamp() ),
73 $wgServer . $this->file->getArchiveUrl( $this->oldimage ) ) );
74 $wgOut->returnToMain( false, $this->title );
75 } else {
76 $wgOut->addWikiText( $status->getWikiText() );
77 }
78 return;
79 }
80
81 // Show the form
82 $this->showForm();
83 }
84
85 /**
86 * Show the confirmation form
87 */
88 private function showForm() {
89 global $wgOut, $wgUser, $wgRequest, $wgLang, $wgContLang, $wgServer;
90
91 /*
92 $cur = wfFindFile( $this->title );
93 $old = wfFindFile( $this->title, substr( $this->oldimage, 0, 14 ) );
94 */
95 $timestamp = $this->getTimestamp();
96
97 $form = Xml::openElement( 'form', array( 'method' => 'post', 'action' => $this->getAction() ) );
98 $form .= Xml::hidden( 'wpEditToken', $wgUser->editToken( $this->oldimage ) );
99 $form .= '<fieldset><legend>' . wfMsgHtml( 'filerevert-legend' ) . '</legend>';
100 $form .= wfMsgExt( 'filerevert-intro', 'parse', $this->title->getText(),
101 $wgLang->timeAndDate( $timestamp ), $wgServer . $this->file->getArchiveUrl( $this->oldimage ) );
102
103 /*
104 * I was going to do a little comparison (current vs. old) here,
105 * but realised it wasn't too straightforward to do a media transform
106 * with an *old* file version using the current mechanism. Leaving
107 * this here in case it becomes possible in the future. -- RC
108 *
109 $form .= '<table class="compare-files">';
110 $form .= '<tr>';
111 $form .= '<th>' . wfMsgHtml( 'filerevert-current' ) . '</th>';
112 $form .= '<th>' . wfMsgHtml( 'filerevert-old', $old->getTimestamp() ) . '</th>';
113 $form .= '</tr><tr>';
114 // FIXME: Hard-coding magic numbers makes baby Jesus cry...
115 $form .= '<td>' . $this->getThumbnail( $cur, 180 ) . '</td>';
116 $form .= '<td>' . $this->getThumbnail( $old, 180 ) . '</td>';
117 $form .= '</tr>';
118 $form .= '</table>';
119 */
120
121 $form .= '<p>' . Xml::inputLabel( wfMsg( 'filerevert-comment' ), 'wpComment', 'wpComment',
122 40, wfMsgForContent( 'filerevert-defaultcomment',
123 $wgContLang->timeAndDate( $timestamp, false, false ) ) ) . '</p>';
124 $form .= '<p>' . Xml::submitButton( wfMsg( 'filerevert-submit' ) ) . '</p>';
125 $form .= '</fieldset>';
126 $form .= '</form>';
127
128 $wgOut->addHtml( $form );
129 }
130
131 /**
132 * Set headers, titles and other bits
133 */
134 private function setHeaders() {
135 global $wgOut;
136 $wgOut->setPageTitle( wfMsg( 'filerevert', $this->title->getText() ) );
137 $wgOut->setRobotPolicy( 'noindex,nofollow' );
138 }
139
140 /**
141 * Is the provided `oldimage` value valid?
142 *
143 * @return bool
144 */
145 private function isValidOldSpec() {
146 return strlen( $this->oldimage ) >= 16
147 && strpos( $this->oldimage, '/' ) === false
148 && strpos( $this->oldimage, '\\' ) === false;
149 }
150
151 /**
152 * Does the provided `oldimage` value correspond
153 * to an existing, local, old version of this file?
154 *
155 * @return bool
156 */
157 private function haveOldVersion() {
158 $file = wfFindFile( $this->title, $this->oldimage );
159 return $file && $file->exists() && $file->isLocal();
160 }
161
162 /**
163 * Prepare the form action
164 *
165 * @return string
166 */
167 private function getAction() {
168 $q = array();
169 $q[] = 'action=revert';
170 $q[] = 'oldimage=' . urlencode( $this->oldimage );
171 return $this->title->getLocalUrl( implode( '&', $q ) );
172 }
173
174 /**
175 * Extract the timestamp of the old version
176 *
177 * @return string
178 */
179 private function getTimestamp() {
180 return substr( $this->oldimage, 0, 14 );
181 }
182
183 }