Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 94 |
|
0.00% |
0 / 13 |
CRAP | |
0.00% |
0 / 1 |
RevertAction | |
0.00% |
0 / 94 |
|
0.00% |
0 / 13 |
380 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
getName | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getRestriction | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
checkCanExecute | |
0.00% |
0 / 12 |
|
0.00% |
0 / 1 |
42 | |||
usesOOUI | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
alterForm | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
getFormFields | |
0.00% |
0 / 32 |
|
0.00% |
0 / 1 |
2 | |||
onSubmit | |
0.00% |
0 / 20 |
|
0.00% |
0 / 1 |
6 | |||
onSuccess | |
0.00% |
0 / 15 |
|
0.00% |
0 / 1 |
2 | |||
getPageTitle | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getDescription | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
doesWrites | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getFile | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | /** |
3 | * File reversion user interface |
4 | * |
5 | * This program is free software; you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License as published by |
7 | * the Free Software Foundation; either version 2 of the License, or |
8 | * (at your option) any later version. |
9 | * |
10 | * This program is distributed in the hope that it will be useful, |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | * GNU General Public License for more details. |
14 | * |
15 | * You should have received a copy of the GNU General Public License |
16 | * along with this program; if not, write to the Free Software |
17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
18 | * |
19 | * @file |
20 | * @ingroup Actions |
21 | * @ingroup Media |
22 | * @author Alexandre Emsenhuber |
23 | * @author Rob Church <robchur@gmail.com> |
24 | */ |
25 | |
26 | use MediaWiki\Context\IContextSource; |
27 | use MediaWiki\HTMLForm\HTMLForm; |
28 | use MediaWiki\Language\Language; |
29 | use MediaWiki\MediaWikiServices; |
30 | use MediaWiki\Output\OutputPage; |
31 | use MediaWiki\Status\Status; |
32 | use MediaWiki\User\User; |
33 | use MediaWiki\Utils\MWTimestamp; |
34 | |
35 | /** |
36 | * File reversion user interface |
37 | * WikiPage must contain getFile method: \WikiFilePage |
38 | * Article::getFile is only for b/c: \ImagePage |
39 | * |
40 | * @ingroup Actions |
41 | */ |
42 | class RevertAction extends FormAction { |
43 | |
44 | private Language $contentLanguage; |
45 | private RepoGroup $repoGroup; |
46 | |
47 | /** |
48 | * @param Article $article |
49 | * @param IContextSource $context |
50 | * @param Language $contentLanguage |
51 | * @param RepoGroup $repoGroup |
52 | */ |
53 | public function __construct( |
54 | Article $article, |
55 | IContextSource $context, |
56 | Language $contentLanguage, |
57 | RepoGroup $repoGroup |
58 | ) { |
59 | parent::__construct( $article, $context ); |
60 | $this->contentLanguage = $contentLanguage; |
61 | $this->repoGroup = $repoGroup; |
62 | } |
63 | |
64 | /** |
65 | * @var OldLocalFile |
66 | */ |
67 | protected $oldFile; |
68 | |
69 | public function getName() { |
70 | return 'revert'; |
71 | } |
72 | |
73 | public function getRestriction() { |
74 | return 'upload'; |
75 | } |
76 | |
77 | protected function checkCanExecute( User $user ) { |
78 | if ( $this->getTitle()->getNamespace() !== NS_FILE ) { |
79 | throw new ErrorPageError( $this->msg( 'nosuchaction' ), $this->msg( 'nosuchactiontext' ) ); |
80 | } |
81 | parent::checkCanExecute( $user ); |
82 | |
83 | $oldimage = $this->getRequest()->getText( 'oldimage' ); |
84 | if ( strlen( $oldimage ) < 16 |
85 | || strpos( $oldimage, '/' ) !== false |
86 | || strpos( $oldimage, '\\' ) !== false |
87 | ) { |
88 | throw new ErrorPageError( 'internalerror', 'unexpected', [ 'oldimage', $oldimage ] ); |
89 | } |
90 | |
91 | $this->oldFile = $this->repoGroup->getLocalRepo() |
92 | ->newFromArchiveName( $this->getTitle(), $oldimage ); |
93 | |
94 | if ( !$this->oldFile->exists() ) { |
95 | throw new ErrorPageError( '', 'filerevert-badversion' ); |
96 | } |
97 | } |
98 | |
99 | protected function usesOOUI() { |
100 | return true; |
101 | } |
102 | |
103 | protected function alterForm( HTMLForm $form ) { |
104 | $form->setWrapperLegendMsg( 'filerevert-legend' ); |
105 | $form->setSubmitTextMsg( 'filerevert-submit' ); |
106 | $form->addHiddenField( 'oldimage', $this->getRequest()->getText( 'oldimage' ) ); |
107 | $form->setTokenSalt( [ 'revert', $this->getTitle()->getPrefixedDBkey() ] ); |
108 | } |
109 | |
110 | protected function getFormFields() { |
111 | $timestamp = $this->oldFile->getTimestamp(); |
112 | |
113 | $user = $this->getUser(); |
114 | $lang = $this->getLanguage(); |
115 | $userDate = $lang->userDate( $timestamp, $user ); |
116 | $userTime = $lang->userTime( $timestamp, $user ); |
117 | $siteTs = MWTimestamp::getLocalInstance( $timestamp ); |
118 | $ts = $siteTs->format( 'YmdHis' ); |
119 | $contLang = $this->contentLanguage; |
120 | $siteDate = $contLang->date( $ts, false, false ); |
121 | $siteTime = $contLang->time( $ts, false, false ); |
122 | $tzMsg = $siteTs->getTimezoneMessage()->inContentLanguage()->text(); |
123 | |
124 | return [ |
125 | 'intro' => [ |
126 | 'type' => 'info', |
127 | 'raw' => true, |
128 | 'default' => $this->msg( 'filerevert-intro', |
129 | $this->getTitle()->getText(), $userDate, $userTime, |
130 | (string)MediaWikiServices::getInstance()->getUrlUtils()->expand( |
131 | $this->getFile() |
132 | ->getArchiveUrl( |
133 | $this->getRequest()->getText( 'oldimage' ) |
134 | ), |
135 | PROTO_CURRENT |
136 | ) )->parseAsBlock() |
137 | ], |
138 | 'comment' => [ |
139 | 'type' => 'text', |
140 | 'label-message' => 'filerevert-comment', |
141 | 'default' => $this->msg( 'filerevert-defaultcomment', $siteDate, $siteTime, |
142 | $tzMsg )->inContentLanguage()->text() |
143 | ] |
144 | ]; |
145 | } |
146 | |
147 | public function onSubmit( $data ) { |
148 | $this->useTransactionalTimeLimit(); |
149 | |
150 | $old = $this->getRequest()->getText( 'oldimage' ); |
151 | /** @var LocalFile $localFile */ |
152 | $localFile = $this->getFile(); |
153 | '@phan-var LocalFile $localFile'; |
154 | $oldFile = OldLocalFile::newFromArchiveName( $this->getTitle(), $localFile->getRepo(), $old ); |
155 | |
156 | $source = $localFile->getArchiveVirtualUrl( $old ); |
157 | $comment = $data['comment']; |
158 | |
159 | if ( $localFile->getSha1() === $oldFile->getSha1() ) { |
160 | return Status::newFatal( 'filerevert-identical' ); |
161 | } |
162 | |
163 | // TODO: Preserve file properties from database instead of reloading from file |
164 | return $localFile->upload( |
165 | $source, |
166 | $comment, |
167 | $comment, |
168 | 0, |
169 | false, |
170 | false, |
171 | $this->getAuthority(), |
172 | [], |
173 | true, |
174 | true |
175 | ); |
176 | } |
177 | |
178 | public function onSuccess() { |
179 | $timestamp = $this->oldFile->getTimestamp(); |
180 | $user = $this->getUser(); |
181 | $lang = $this->getLanguage(); |
182 | $userDate = $lang->userDate( $timestamp, $user ); |
183 | $userTime = $lang->userTime( $timestamp, $user ); |
184 | |
185 | $this->getOutput()->addWikiMsg( 'filerevert-success', $this->getTitle()->getText(), |
186 | $userDate, $userTime, |
187 | (string)MediaWikiServices::getInstance()->getUrlUtils()->expand( |
188 | $this->getFile() |
189 | ->getArchiveUrl( |
190 | $this->getRequest()->getText( 'oldimage' ) |
191 | ), |
192 | PROTO_CURRENT |
193 | ) ); |
194 | $this->getOutput()->returnToMain( false, $this->getTitle() ); |
195 | } |
196 | |
197 | protected function getPageTitle() { |
198 | return $this->msg( 'filerevert' )->plaintextParams( $this->getTitle()->getText() ); |
199 | } |
200 | |
201 | protected function getDescription() { |
202 | return OutputPage::buildBacklinkSubtitle( $this->getTitle() )->escaped(); |
203 | } |
204 | |
205 | public function doesWrites() { |
206 | return true; |
207 | } |
208 | |
209 | /** |
210 | * @since 1.35 |
211 | * @return File |
212 | */ |
213 | private function getFile(): File { |
214 | /** @var \WikiFilePage $wikiPage */ |
215 | $wikiPage = $this->getWikiPage(); |
216 | // @phan-suppress-next-line PhanUndeclaredMethod |
217 | return $wikiPage->getFile(); |
218 | } |
219 | } |