MediaWiki REL1_34
RollbackAction.php
Go to the documentation of this file.
1<?php
24
31
32 public function getName() {
33 return 'rollback';
34 }
35
36 public function getRestriction() {
37 return 'rollback';
38 }
39
40 protected function usesOOUI() {
41 return true;
42 }
43
44 protected function getDescription() {
45 return '';
46 }
47
48 public function doesWrites() {
49 return true;
50 }
51
52 public function onSuccess() {
53 return false;
54 }
55
56 public function onSubmit( $data ) {
57 return false;
58 }
59
60 protected function alterForm( HTMLForm $form ) {
61 $form->setWrapperLegendMsg( 'confirm-rollback-top' );
62 $form->setSubmitTextMsg( 'confirm-rollback-button' );
63 $form->setTokenSalt( 'rollback' );
64
65 $from = $this->getRequest()->getVal( 'from' );
66 if ( $from === null ) {
67 throw new BadRequestError( 'rollbackfailed', 'rollback-missingparam' );
68 }
69 foreach ( [ 'from', 'bot', 'hidediff', 'summary', 'token' ] as $param ) {
70 $val = $this->getRequest()->getVal( $param );
71 if ( $val !== null ) {
72 $form->addHiddenField( $param, $val );
73 }
74 }
75 }
76
82 public function show() {
83 if ( $this->getUser()->getOption( 'showrollbackconfirmation' ) == false ||
84 $this->getRequest()->wasPosted() ) {
85 $this->handleRollbackRequest();
86 } else {
88 }
89 }
90
91 public function handleRollbackRequest() {
93
94 $request = $this->getRequest();
95 $user = $this->getUser();
96 $from = $request->getVal( 'from' );
97 $rev = $this->page->getRevision();
98 if ( $from === null ) {
99 throw new ErrorPageError( 'rollbackfailed', 'rollback-missingparam' );
100 }
101 if ( !$rev ) {
102 throw new ErrorPageError( 'rollbackfailed', 'rollback-missingrevision' );
103 }
104 if ( $from !== $rev->getUserText() ) {
105 throw new ErrorPageError( 'rollbackfailed', 'alreadyrolled', [
106 $this->getTitle()->getPrefixedText(),
107 $from,
108 $rev->getUserText()
109 ] );
110 }
111
112 $data = null;
113 $errors = $this->page->doRollback(
114 $from,
115 $request->getText( 'summary' ),
116 $request->getVal( 'token' ),
117 $request->getBool( 'bot' ),
118 $data,
119 $this->getUser()
120 );
121
122 if ( in_array( [ 'actionthrottledtext' ], $errors ) ) {
123 throw new ThrottledError;
124 }
125
126 if ( $this->hasRollbackRelatedErrors( $errors ) ) {
127 $this->getOutput()->setPageTitle( $this->msg( 'rollbackfailed' ) );
128 $errArray = $errors[0];
129 $errMsg = array_shift( $errArray );
130 $this->getOutput()->addWikiMsgArray( $errMsg, $errArray );
131
132 if ( isset( $data['current'] ) ) {
134 $current = $data['current'];
135
136 if ( $current->getComment() != '' ) {
137 $this->getOutput()->addWikiMsg(
138 'editcomment',
140 Linker::formatComment( $current->getComment() )
141 )
142 );
143 }
144 }
145
146 return;
147 }
148
149 # NOTE: Permission errors already handled by Action::checkExecute.
150 if ( $errors == [ [ 'readonlytext' ] ] ) {
151 throw new ReadOnlyError;
152 }
153
154 # XXX: Would be nice if ErrorPageError could take multiple errors, and/or a status object.
155 # Right now, we only show the first error
156 foreach ( $errors as $error ) {
157 throw new ErrorPageError( 'rollbackfailed', $error[0], array_slice( $error, 1 ) );
158 }
159
161 $current = $data['current'];
162 $target = $data['target'];
163 $newId = $data['newid'];
164 $this->getOutput()->setPageTitle( $this->msg( 'actioncomplete' ) );
165 $this->getOutput()->setRobotPolicy( 'noindex,nofollow' );
166
167 $old = Linker::revUserTools( $current );
168 $new = Linker::revUserTools( $target );
169 $this->getOutput()->addHTML(
170 $this->msg( 'rollback-success' )
171 ->rawParams( $old, $new )
172 ->params( $current->getUserText( RevisionRecord::FOR_THIS_USER, $user ) )
173 ->params( $target->getUserText( RevisionRecord::FOR_THIS_USER, $user ) )
174 ->parseAsBlock()
175 );
176
177 if ( $user->getBoolOption( 'watchrollback' ) ) {
178 $user->addWatch( $this->page->getTitle(), User::IGNORE_USER_RIGHTS );
179 }
180
181 $this->getOutput()->returnToMain( false, $this->getTitle() );
182
183 if ( !$request->getBool( 'hidediff', false ) &&
184 !$this->getUser()->getBoolOption( 'norollbackdiff' )
185 ) {
186 $contentHandler = $current->getContentHandler();
187 $de = $contentHandler->createDifferenceEngine(
188 $this->getContext(),
189 $current->getId(),
190 $newId,
191 false,
192 true
193 );
194 $de->showDiff( '', '' );
195 }
196 }
197
202 private function enableTransactionalTimelimit() {
203 // If Rollbacks are made POST-only, use $this->useTransactionalTimeLimit()
205 if ( !$this->getRequest()->wasPosted() ) {
210 $fname = __METHOD__;
211 $trxLimits = $this->context->getConfig()->get( 'TrxProfilerLimits' );
212 $trxProfiler = Profiler::instance()->getTransactionProfiler();
213 $trxProfiler->redefineExpectations( $trxLimits['POST'], $fname );
214 DeferredUpdates::addCallableUpdate( function () use ( $trxProfiler, $trxLimits, $fname
215 ) {
216 $trxProfiler->redefineExpectations( $trxLimits['PostSend-POST'], $fname );
217 } );
218 }
219 }
220
221 private function showRollbackConfirmationForm() {
222 $form = $this->getForm();
223 if ( $form->show() ) {
224 $this->onSuccess();
225 }
226 }
227
228 protected function getFormFields() {
229 return [
230 'intro' => [
231 'type' => 'info',
232 'vertical-label' => true,
233 'raw' => true,
234 'default' => $this->msg( 'confirm-rollback-bottom' )->parse()
235 ]
236 ];
237 }
238
239 private function hasRollbackRelatedErrors( array $errors ) {
240 return isset( $errors[0][0] ) &&
241 ( $errors[0][0] == 'alreadyrolled' ||
242 $errors[0][0] == 'cantrollback'
243 );
244 }
245}
wfTransactionalTimeLimit()
Set PHP's time limit to the larger of php.ini or $wgTransactionalTimeLimit.
getTitle()
Shortcut to get the Title object from the page.
Definition Action.php:247
getContext()
Get the IContextSource in use here.
Definition Action.php:179
getOutput()
Get the OutputPage being used for this instance.
Definition Action.php:208
getUser()
Shortcut to get the User being used for this instance.
Definition Action.php:218
msg( $key,... $params)
Get a Message object with context set Parameters are the same as wfMessage()
Definition Action.php:259
getRequest()
Get the WebRequest being used for this instance.
Definition Action.php:198
An error page that emits an HTTP 400 Bad Request status code.
An error page which can definitely be safely rendered using the OutputPage.
An action which shows a form and does something based on the input from the form.
getForm()
Get the HTMLForm to control behavior.
Object handling generic submission, CSRF protection, layout and other logic for UI forms in a reusabl...
Definition HTMLForm.php:131
setSubmitTextMsg( $msg)
Set the text for the submit button to a message.
setWrapperLegendMsg( $msg)
Prompt the whole form to be wrapped in a "<fieldset>", with this message as its "<legend>" element.
addHiddenField( $name, $value, array $attribs=[])
Add a hidden field to the output.
Definition HTMLForm.php:939
setTokenSalt( $salt)
Set the salt for the edit token.
static revUserTools( $rev, $isPublic=false, $useParentheses=true)
Generate a user tool link cluster if the current user is allowed to view it.
Definition Linker.php:1124
static formatComment( $comment, $title=null, $local=false, $wikiId=null)
This function is called by all recent changes variants, by the page history, and by the user contribu...
Definition Linker.php:1165
Page revision base class.
static rawParam( $raw)
Definition Message.php:1027
Show an error when the wiki is locked/read-only and the user tries to do something that requires writ...
User interface for the rollback action.
getFormFields()
Get an HTMLForm descriptor array.
getDescription()
Returns the description that goes below the <h1> tag.
enableTransactionalTimelimit()
Enables transactional time limit for POST and GET requests to RollbackAction.
usesOOUI()
Whether the form should use OOUI.
onSubmit( $data)
Process the form on POST submission.
alterForm(HTMLForm $form)
Play with the HTMLForm if you need to more substantially.
getRestriction()
Get the permission required to perform this action.
onSuccess()
Do something exciting on successful processing of the form.
hasRollbackRelatedErrors(array $errors)
doesWrites()
Indicates whether this action may perform database writes.
getName()
Return the name of the action this object responds to.
Show an error when the user hits a rate limit.
const IGNORE_USER_RIGHTS
Definition User.php:83