MediaWiki master
RevertAction.php
Go to the documentation of this file.
1<?php
13namespace MediaWiki\Actions;
14
31
39class RevertAction extends FormAction {
40
41 public function __construct(
42 Article $article,
44 private readonly Language $contentLanguage,
45 private readonly RepoGroup $repoGroup,
46 private readonly UrlUtils $urlUtils,
47 ) {
48 parent::__construct( $article, $context );
49 }
50
54 protected $oldFile;
55
57 public function getName() {
58 return 'revert';
59 }
60
62 public function getRestriction() {
63 // Required permissions of revert are complicated, will be checked below.
64 return 'upload';
65 }
66
68 protected function checkCanExecute( User $user ) {
69 if ( $this->getTitle()->getNamespace() !== NS_FILE ) {
70 throw new ErrorPageError( $this->msg( 'nosuchaction' ), $this->msg( 'nosuchactiontext' ) );
71 }
72
73 $rights = [ 'reupload' ];
74 if ( $user->equals( $this->getFile()->getUploader() ) ) {
75 // reupload-own is more basic, put it in the front for error messages.
76 array_unshift( $rights, 'reupload-own' );
77 }
78 if ( !$user->isAllowedAny( ...$rights ) ) {
79 throw new PermissionsError( $rights[0] );
80 }
81
82 parent::checkCanExecute( $user );
83
84 $oldimage = $this->getRequest()->getText( 'oldimage' );
85 if ( strlen( $oldimage ) < 16
86 || str_contains( $oldimage, '/' )
87 || str_contains( $oldimage, '\\' )
88 ) {
89 throw new ErrorPageError( 'internalerror', 'unexpected', [ 'oldimage', $oldimage ] );
90 }
91
92 $this->oldFile = $this->repoGroup->getLocalRepo()
93 ->newFromArchiveName( $this->getTitle(), $oldimage );
94
95 if ( !$this->oldFile->exists() ) {
96 throw new ErrorPageError( '', 'filerevert-badversion' );
97 }
98 }
99
101 protected function usesOOUI() {
102 return true;
103 }
104
105 protected function alterForm( HTMLForm $form ) {
106 $form->setWrapperLegendMsg( 'filerevert-legend' );
107 $form->setSubmitTextMsg( 'filerevert-submit' );
108 $form->addHiddenField( 'oldimage', $this->getRequest()->getText( 'oldimage' ) );
109 $form->setTokenSalt( [ 'revert', $this->getTitle()->getPrefixedDBkey() ] );
110 }
111
113 protected function getFormFields() {
114 $timestamp = $this->oldFile->getTimestamp();
115
116 $user = $this->getUser();
117 $lang = $this->getLanguage();
118 $userDate = $lang->userDate( $timestamp, $user );
119 $userTime = $lang->userTime( $timestamp, $user );
120 $siteTs = MWTimestamp::getLocalInstance( $timestamp );
121 $ts = $siteTs->format( 'YmdHis' );
122 $contLang = $this->contentLanguage;
123 $siteDate = $contLang->date( $ts, false, false );
124 $siteTime = $contLang->time( $ts, false, false );
125 $tzMsg = $siteTs->getTimezoneMessage()->inContentLanguage()->text();
126
127 return [
128 'intro' => [
129 'type' => 'info',
130 'raw' => true,
131 'default' => $this->msg( 'filerevert-intro',
132 $this->getTitle()->getText(), $userDate, $userTime,
133 (string)$this->urlUtils->expand(
134 $this->getFile()
135 ->getArchiveUrl(
136 $this->getRequest()->getText( 'oldimage' )
137 ),
139 ) )->parseAsBlock()
140 ],
141 'comment' => [
142 'type' => 'text',
143 'label-message' => 'filerevert-comment',
144 'default' => $this->msg( 'filerevert-defaultcomment', $siteDate, $siteTime,
145 $tzMsg )->inContentLanguage()->text()
146 ]
147 ];
148 }
149
151 public function onSubmit( $data ) {
153
154 $old = $this->getRequest()->getText( 'oldimage' );
156 $localFile = $this->getFile();
157 '@phan-var LocalFile $localFile';
158 $oldFile = OldLocalFile::newFromArchiveName( $this->getTitle(), $localFile->getRepo(), $old );
159
160 $source = $localFile->getArchiveVirtualUrl( $old );
161 $comment = $data['comment'];
162
163 if ( $localFile->getSha1() === $oldFile->getSha1() ) {
164 return Status::newFatal( 'filerevert-identical' );
165 }
166
167 // TODO: Preserve file properties from database instead of reloading from file
168 return $localFile->upload(
169 $source,
170 $comment,
171 $comment,
172 0,
173 false,
174 false,
175 $this->getAuthority(),
176 [],
177 true,
178 true
179 );
180 }
181
183 public function onSuccess() {
184 $timestamp = $this->oldFile->getTimestamp();
185 $user = $this->getUser();
186 $lang = $this->getLanguage();
187 $userDate = $lang->userDate( $timestamp, $user );
188 $userTime = $lang->userTime( $timestamp, $user );
189
190 $this->getOutput()->addWikiMsg( 'filerevert-success', $this->getTitle()->getText(),
191 $userDate, $userTime,
192 (string)$this->urlUtils->expand(
193 $this->getFile()
194 ->getArchiveUrl(
195 $this->getRequest()->getText( 'oldimage' )
196 ),
198 ) );
199 $this->getOutput()->returnToMain( false, $this->getTitle() );
200 }
201
203 protected function getPageTitle() {
204 return $this->msg( 'filerevert' )->plaintextParams( $this->getTitle()->getText() );
205 }
206
208 protected function getDescription() {
209 return OutputPage::buildBacklinkSubtitle( $this->getTitle() )->escaped();
210 }
211
213 public function doesWrites() {
214 return true;
215 }
216
221 private function getFile(): File {
223 $wikiPage = $this->getWikiPage();
224 // @phan-suppress-next-line PhanUndeclaredMethod
225 return $wikiPage->getFile();
226 }
227}
228
230class_alias( RevertAction::class, 'RevertAction' );
const NS_FILE
Definition Defines.php:57
const PROTO_CURRENT
Definition Defines.php:222
getWikiPage()
Get a WikiPage object.
Definition Action.php:192
IContextSource null $context
IContextSource if specified; otherwise we'll use the Context from the Page.
Definition Action.php:66
getUser()
Shortcut to get the User being used for this instance.
Definition Action.php:153
msg( $key,... $params)
Get a Message object with context set Parameters are the same as wfMessage()
Definition Action.php:227
getTitle()
Shortcut to get the Title object from the page.
Definition Action.php:213
getRequest()
Get the WebRequest being used for this instance.
Definition Action.php:133
useTransactionalTimeLimit()
Call wfTransactionalTimeLimit() if this request was POSTed.
Definition Action.php:475
getLanguage()
Shortcut to get the user Language being used for this instance.
Definition Action.php:182
getOutput()
Get the OutputPage being used for this instance.
Definition Action.php:143
getAuthority()
Shortcut to get the Authority executing this instance.
Definition Action.php:163
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...
__construct(Article $article, IContextSource $context, private readonly Language $contentLanguage, private readonly RepoGroup $repoGroup, private readonly UrlUtils $urlUtils,)
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...
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:79
Local file in the wiki's own database.
Definition LocalFile.php:81
Old file in the oldimage table.
Prioritized list of file repositories.
Definition RepoGroup.php:30
Object handling generic submission, CSRF protection, layout and other logic for UI forms in a reusabl...
Definition HTMLForm.php:195
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:69
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:64
Special handling for representing file pages.
Generic operation result class Has warning/error list, boolean status and arbitrary value.
Definition Status.php:44
User class for the MediaWiki software.
Definition User.php:130
isAllowedAny(... $permissions)
Checks whether this authority has any of the given permissions in general.Implementations must ensure...
Definition User.php:2141
equals(?UserIdentity $user)
Checks if two user objects point to the same user.
Definition User.php:3261
Library for creating and parsing MW-style timestamps.
A service to expand, parse, and otherwise manipulate URLs.
Definition UrlUtils.php:16
Interface for objects which can provide a MediaWiki context on request.
$source