Longer comment box
[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 return;
45 } elseif( $wgUser->isBlocked() ) {
46 $wgOut->blockedPage();
47 return;
48 }
49
50 $this->oldimage = $wgRequest->getText( 'oldimage' );
51 $token = $wgRequest->getText( 'wpEditToken' );
52 if( !$this->isValidOldSpec() ) {
53 $wgOut->showUnexpectedValueError( 'oldimage', htmlspecialchars( $this->oldimage ) );
54 return;
55 }
56
57 if( !$this->haveOldVersion() ) {
58 $wgOut->addHtml( wfMsgExt( 'filerevert-badversion', 'parse' ) );
59 $wgOut->returnToMain( false, $this->title );
60 return;
61 }
62
63 // Perform the reversion if appropriate
64 if( $wgRequest->wasPosted() && $wgUser->matchEditToken( $token, $this->oldimage ) ) {
65 $source = $this->file->getArchiveVirtualUrl( $this->oldimage );
66 $comment = $wgRequest->getText( 'wpComment' );
67 // TODO: Preserve file properties from database instead of reloading from file
68 $status = $this->file->upload( $source, $comment, $comment );
69 if( $status->isGood() ) {
70 $wgOut->addHtml( wfMsgExt( 'filerevert-success', 'parse', $this->title->getText(),
71 $wgLang->timeAndDate( $this->getTimestamp() ),
72 $wgServer . $this->file->getArchiveUrl( $this->oldimage ) ) );
73 $wgOut->returnToMain( false, $this->title );
74 } else {
75 $wgOut->addWikiText( $status->getWikiText() );
76 }
77 return;
78 }
79
80 // Show the form
81 $this->showForm();
82 }
83
84 /**
85 * Show the confirmation form
86 */
87 private function showForm() {
88 global $wgOut, $wgUser, $wgRequest, $wgLang, $wgContLang, $wgServer;
89
90 /*
91 $cur = wfFindFile( $this->title );
92 $old = wfFindFile( $this->title, substr( $this->oldimage, 0, 14 ) );
93 */
94 $timestamp = $this->getTimestamp();
95
96 $form = Xml::openElement( 'form', array( 'method' => 'post', 'action' => $this->getAction() ) );
97 $form .= Xml::hidden( 'wpEditToken', $wgUser->editToken( $this->oldimage ) );
98 $form .= '<fieldset><legend>' . wfMsgHtml( 'filerevert-legend' ) . '</legend>';
99 $form .= wfMsgExt( 'filerevert-intro', 'parse', $this->title->getText(),
100 $wgLang->timeAndDate( $timestamp ), $wgServer . $this->file->getArchiveUrl( $this->oldimage ) );
101
102 /*
103 * I was going to do a little comparison (current vs. old) here,
104 * but realised it wasn't too straightforward to do a media transform
105 * with an *old* file version using the current mechanism. Leaving
106 * this here in case it becomes possible in the future. -- RC
107 *
108 $form .= '<table class="compare-files">';
109 $form .= '<tr>';
110 $form .= '<th>' . wfMsgHtml( 'filerevert-current' ) . '</th>';
111 $form .= '<th>' . wfMsgHtml( 'filerevert-old', $old->getTimestamp() ) . '</th>';
112 $form .= '</tr><tr>';
113 // FIXME: Hard-coding magic numbers makes baby Jesus cry...
114 $form .= '<td>' . $this->getThumbnail( $cur, 180 ) . '</td>';
115 $form .= '<td>' . $this->getThumbnail( $old, 180 ) . '</td>';
116 $form .= '</tr>';
117 $form .= '</table>';
118 */
119
120 $form .= '<p>' . Xml::inputLabel( wfMsg( 'filerevert-comment' ), 'wpComment', 'wpComment',
121 60, wfMsgForContent( 'filerevert-defaultcomment',
122 $wgContLang->timeAndDate( $timestamp, false, false ) ) ) . '</p>';
123 $form .= '<p>' . Xml::submitButton( wfMsg( 'filerevert-submit' ) ) . '</p>';
124 $form .= '</fieldset>';
125 $form .= '</form>';
126
127 $wgOut->addHtml( $form );
128 }
129
130 /**
131 * Set headers, titles and other bits
132 */
133 private function setHeaders() {
134 global $wgOut;
135 $wgOut->setPageTitle( wfMsg( 'filerevert', $this->title->getText() ) );
136 $wgOut->setRobotPolicy( 'noindex,nofollow' );
137 }
138
139 /**
140 * Is the provided `oldimage` value valid?
141 *
142 * @return bool
143 */
144 private function isValidOldSpec() {
145 return strlen( $this->oldimage ) >= 16
146 && strpos( $this->oldimage, '/' ) === false
147 && strpos( $this->oldimage, '\\' ) === false;
148 }
149
150 /**
151 * Does the provided `oldimage` value correspond
152 * to an existing, local, old version of this file?
153 *
154 * @return bool
155 */
156 private function haveOldVersion() {
157 $file = wfFindFile( $this->title, $this->oldimage );
158 return $file && $file->exists() && $file->isLocal();
159 }
160
161 /**
162 * Prepare the form action
163 *
164 * @return string
165 */
166 private function getAction() {
167 $q = array();
168 $q[] = 'action=revert';
169 $q[] = 'oldimage=' . urlencode( $this->oldimage );
170 return $this->title->getLocalUrl( implode( '&', $q ) );
171 }
172
173 /**
174 * Extract the timestamp of the old version
175 *
176 * @return string
177 */
178 private function getTimestamp() {
179 return substr( $this->oldimage, 0, 14 );
180 }
181
182 }