MediaWiki master
RevertAction.php
Go to the documentation of this file.
1<?php
26namespace MediaWiki\Actions;
27
44
52class RevertAction extends FormAction {
53
54 private Language $contentLanguage;
55 private RepoGroup $repoGroup;
56
63 public function __construct(
64 Article $article,
66 Language $contentLanguage,
67 RepoGroup $repoGroup
68 ) {
69 parent::__construct( $article, $context );
70 $this->contentLanguage = $contentLanguage;
71 $this->repoGroup = $repoGroup;
72 }
73
77 protected $oldFile;
78
80 public function getName() {
81 return 'revert';
82 }
83
85 public function getRestriction() {
86 // Required permissions of revert are complicated, will be checked below.
87 return 'upload';
88 }
89
91 protected function checkCanExecute( User $user ) {
92 if ( $this->getTitle()->getNamespace() !== NS_FILE ) {
93 throw new ErrorPageError( $this->msg( 'nosuchaction' ), $this->msg( 'nosuchactiontext' ) );
94 }
95
96 $rights = [ 'reupload' ];
97 if ( $user->equals( $this->getFile()->getUploader() ) ) {
98 // reupload-own is more basic, put it in the front for error messages.
99 array_unshift( $rights, 'reupload-own' );
100 }
101 if ( !$user->isAllowedAny( ...$rights ) ) {
102 throw new PermissionsError( $rights[0] );
103 }
104
105 parent::checkCanExecute( $user );
106
107 $oldimage = $this->getRequest()->getText( 'oldimage' );
108 if ( strlen( $oldimage ) < 16
109 || strpos( $oldimage, '/' ) !== false
110 || strpos( $oldimage, '\\' ) !== false
111 ) {
112 throw new ErrorPageError( 'internalerror', 'unexpected', [ 'oldimage', $oldimage ] );
113 }
114
115 $this->oldFile = $this->repoGroup->getLocalRepo()
116 ->newFromArchiveName( $this->getTitle(), $oldimage );
117
118 if ( !$this->oldFile->exists() ) {
119 throw new ErrorPageError( '', 'filerevert-badversion' );
120 }
121 }
122
124 protected function usesOOUI() {
125 return true;
126 }
127
128 protected function alterForm( HTMLForm $form ) {
129 $form->setWrapperLegendMsg( 'filerevert-legend' );
130 $form->setSubmitTextMsg( 'filerevert-submit' );
131 $form->addHiddenField( 'oldimage', $this->getRequest()->getText( 'oldimage' ) );
132 $form->setTokenSalt( [ 'revert', $this->getTitle()->getPrefixedDBkey() ] );
133 }
134
136 protected function getFormFields() {
137 $timestamp = $this->oldFile->getTimestamp();
138
139 $user = $this->getUser();
140 $lang = $this->getLanguage();
141 $userDate = $lang->userDate( $timestamp, $user );
142 $userTime = $lang->userTime( $timestamp, $user );
143 $siteTs = MWTimestamp::getLocalInstance( $timestamp );
144 $ts = $siteTs->format( 'YmdHis' );
145 $contLang = $this->contentLanguage;
146 $siteDate = $contLang->date( $ts, false, false );
147 $siteTime = $contLang->time( $ts, false, false );
148 $tzMsg = $siteTs->getTimezoneMessage()->inContentLanguage()->text();
149
150 return [
151 'intro' => [
152 'type' => 'info',
153 'raw' => true,
154 'default' => $this->msg( 'filerevert-intro',
155 $this->getTitle()->getText(), $userDate, $userTime,
156 (string)MediaWikiServices::getInstance()->getUrlUtils()->expand(
157 $this->getFile()
158 ->getArchiveUrl(
159 $this->getRequest()->getText( 'oldimage' )
160 ),
162 ) )->parseAsBlock()
163 ],
164 'comment' => [
165 'type' => 'text',
166 'label-message' => 'filerevert-comment',
167 'default' => $this->msg( 'filerevert-defaultcomment', $siteDate, $siteTime,
168 $tzMsg )->inContentLanguage()->text()
169 ]
170 ];
171 }
172
174 public function onSubmit( $data ) {
176
177 $old = $this->getRequest()->getText( 'oldimage' );
179 $localFile = $this->getFile();
180 '@phan-var LocalFile $localFile';
181 $oldFile = OldLocalFile::newFromArchiveName( $this->getTitle(), $localFile->getRepo(), $old );
182
183 $source = $localFile->getArchiveVirtualUrl( $old );
184 $comment = $data['comment'];
185
186 if ( $localFile->getSha1() === $oldFile->getSha1() ) {
187 return Status::newFatal( 'filerevert-identical' );
188 }
189
190 // TODO: Preserve file properties from database instead of reloading from file
191 return $localFile->upload(
192 $source,
193 $comment,
194 $comment,
195 0,
196 false,
197 false,
198 $this->getAuthority(),
199 [],
200 true,
201 true
202 );
203 }
204
206 public function onSuccess() {
207 $timestamp = $this->oldFile->getTimestamp();
208 $user = $this->getUser();
209 $lang = $this->getLanguage();
210 $userDate = $lang->userDate( $timestamp, $user );
211 $userTime = $lang->userTime( $timestamp, $user );
212
213 $this->getOutput()->addWikiMsg( 'filerevert-success', $this->getTitle()->getText(),
214 $userDate, $userTime,
215 (string)MediaWikiServices::getInstance()->getUrlUtils()->expand(
216 $this->getFile()
217 ->getArchiveUrl(
218 $this->getRequest()->getText( 'oldimage' )
219 ),
221 ) );
222 $this->getOutput()->returnToMain( false, $this->getTitle() );
223 }
224
226 protected function getPageTitle() {
227 return $this->msg( 'filerevert' )->plaintextParams( $this->getTitle()->getText() );
228 }
229
231 protected function getDescription() {
232 return OutputPage::buildBacklinkSubtitle( $this->getTitle() )->escaped();
233 }
234
236 public function doesWrites() {
237 return true;
238 }
239
244 private function getFile(): File {
246 $wikiPage = $this->getWikiPage();
247 // @phan-suppress-next-line PhanUndeclaredMethod
248 return $wikiPage->getFile();
249 }
250}
251
253class_alias( RevertAction::class, 'RevertAction' );
const NS_FILE
Definition Defines.php:71
const PROTO_CURRENT
Definition Defines.php:236
getWikiPage()
Get a WikiPage object.
Definition Action.php:205
IContextSource null $context
IContextSource if specified; otherwise we'll use the Context from the Page.
Definition Action.php:79
getUser()
Shortcut to get the User being used for this instance.
Definition Action.php:166
msg( $key,... $params)
Get a Message object with context set Parameters are the same as wfMessage()
Definition Action.php:240
getTitle()
Shortcut to get the Title object from the page.
Definition Action.php:226
getRequest()
Get the WebRequest being used for this instance.
Definition Action.php:146
useTransactionalTimeLimit()
Call wfTransactionalTimeLimit() if this request was POSTed.
Definition Action.php:488
getLanguage()
Shortcut to get the user Language being used for this instance.
Definition Action.php:195
getOutput()
Get the OutputPage being used for this instance.
Definition Action.php:156
getAuthority()
Shortcut to get the Authority executing this instance.
Definition Action.php:176
An action which shows a form and does something based on the input from the form.
File reversion user interface WikiPage must contain getFile method: \WikiFilePage Article::getFile is...
onSuccess()
Do something exciting on successful processing of the form.This might be to show a confirmation messa...
getFormFields()
Get an HTMLForm descriptor array.to override array
checkCanExecute(User $user)
Checks if the given user (identified by an object) can perform this action.Can be overridden by sub-c...
__construct(Article $article, IContextSource $context, Language $contentLanguage, RepoGroup $repoGroup)
getPageTitle()
Returns the name that goes in the <h1> page title.Since 1.45, returning a string from this method is ...
getRestriction()
Get the permission required to perform this action.Often, but not always, the same as the action name...
usesOOUI()
Whether the form should use OOUI.to override bool
onSubmit( $data)
Process the form on POST submission.If you don't want to do anything with the form,...
getDescription()
Returns the description that goes below the <h1> element.1.17 to override string HTML
alterForm(HTMLForm $form)
Play with the HTMLForm if you need to more substantially.
getName()
Return the name of the action this object responds to.1.17string Lowercase name
An error page which can definitely be safely rendered using the OutputPage.
Show an error when a user tries to do something they do not have the necessary permissions for.
Implements some public methods and some protected utility functions which are required by multiple ch...
Definition File.php:93
Local file in the wiki's own database.
Definition LocalFile.php:93
Old file in the oldimage table.
Prioritized list of file repositories.
Definition RepoGroup.php:38
Object handling generic submission, CSRF protection, layout and other logic for UI forms in a reusabl...
Definition HTMLForm.php:209
setWrapperLegendMsg( $msg)
Prompt the whole form to be wrapped in a "<fieldset>", with this message as its "<legend>" element.
setTokenSalt( $salt)
Set the salt for the edit token.
addHiddenField( $name, $value, array $attribs=[])
Add a hidden field to the output Array values are discarded for security reasons (per WebRequest::get...
setSubmitTextMsg( $msg)
Set the text for the submit button to a message.
Base class for language-specific code.
Definition Language.php:81
Service locator for MediaWiki core services.
static getInstance()
Returns the global default instance of the top level service locator.
This is one of the Core classes and should be read at least once by any new developers.
Legacy class representing an editable page and handling UI for some page actions.
Definition Article.php:76
Special handling for representing file pages.
Generic operation result class Has warning/error list, boolean status and arbitrary value.
Definition Status.php:54
User class for the MediaWiki software.
Definition User.php:123
isAllowedAny(... $permissions)
Checks whether this authority has any of the given permissions in general.
Definition User.php:2182
equals(?UserIdentity $user)
Checks if two user objects point to the same user.
Definition User.php:3296
Library for creating and parsing MW-style timestamps.
Interface for objects which can provide a MediaWiki context on request.
$source