Fixing E_NOTICE
[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 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;
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 wfExpandUrl( $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;
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 ),
98 wfExpandUrl( $this->file->getArchiveUrl( $this->oldimage ) ) );
99 $form .= '<p>' . Xml::inputLabel( wfMsg( 'filerevert-comment' ), 'wpComment', 'wpComment',
100 60, wfMsgForContent( 'filerevert-defaultcomment',
101 $wgContLang->date( $timestamp, false, false ), $wgContLang->time( $timestamp, false, false ) ) ) . '</p>';
102 $form .= '<p>' . Xml::submitButton( wfMsg( 'filerevert-submit' ) ) . '</p>';
103 $form .= '</fieldset>';
104 $form .= '</form>';
105
106 $wgOut->addHtml( $form );
107 }
108
109 /**
110 * Set headers, titles and other bits
111 */
112 private function setHeaders() {
113 global $wgOut, $wgUser;
114 $wgOut->setPageTitle( wfMsg( 'filerevert', $this->title->getText() ) );
115 $wgOut->setRobotPolicy( 'noindex,nofollow' );
116 $wgOut->setSubtitle( wfMsg( 'filerevert-backlink', $wgUser->getSkin()->makeKnownLinkObj( $this->title ) ) );
117 }
118
119 /**
120 * Is the provided `oldimage` value valid?
121 *
122 * @return bool
123 */
124 private function isValidOldSpec() {
125 return strlen( $this->oldimage ) >= 16
126 && strpos( $this->oldimage, '/' ) === false
127 && strpos( $this->oldimage, '\\' ) === false;
128 }
129
130 /**
131 * Does the provided `oldimage` value correspond
132 * to an existing, local, old version of this file?
133 *
134 * @return bool
135 */
136 private function haveOldVersion() {
137 $file = wfFindFile( $this->title, $this->oldimage );
138 return $file && $file->exists() && $file->isLocal();
139 }
140
141 /**
142 * Prepare the form action
143 *
144 * @return string
145 */
146 private function getAction() {
147 $q = array();
148 $q[] = 'action=revert';
149 $q[] = 'oldimage=' . urlencode( $this->oldimage );
150 return $this->title->getLocalUrl( implode( '&', $q ) );
151 }
152
153 /**
154 * Extract the timestamp of the old version
155 *
156 * @return string
157 */
158 private function getTimestamp() {
159 if( $this->timestamp === false ) {
160 $file = RepoGroup::singleton()->getLocalRepo()->newFromArchiveName( $this->title, $this->oldimage );
161 $this->timestamp = $file->getTimestamp();
162 }
163 return $this->timestamp;
164 }
165
166 }