MediaWiki REL1_39
ApiRollback.php
Go to the documentation of this file.
1<?php
30
34class ApiRollback extends ApiBase {
35
37
39 private $rollbackPageFactory;
40
41 public function __construct(
42 ApiMain $mainModule,
43 $moduleName,
44 RollbackPageFactory $rollbackPageFactory,
45 WatchlistManager $watchlistManager,
46 UserOptionsLookup $userOptionsLookup
47 ) {
48 parent::__construct( $mainModule, $moduleName );
49 $this->rollbackPageFactory = $rollbackPageFactory;
50
51 // Variables needed in ApiWatchlistTrait trait
52 $this->watchlistExpiryEnabled = $this->getConfig()->get( MainConfigNames::WatchlistExpiry );
53 $this->watchlistMaxDuration =
54 $this->getConfig()->get( MainConfigNames::WatchlistExpiryMaxDuration );
55 $this->watchlistManager = $watchlistManager;
56 $this->userOptionsLookup = $userOptionsLookup;
57 }
58
62 private $mTitleObj = null;
63
67 private $mUser = null;
68
69 public function execute() {
71
72 $user = $this->getUser();
73 $params = $this->extractRequestParams();
74
75 $titleObj = $this->getRbTitle( $params );
76
77 // If change tagging was requested, check that the user is allowed to tag,
78 // and the tags are valid. TODO: move inside rollback command?
79 if ( $params['tags'] ) {
80 $tagStatus = ChangeTags::canAddTagsAccompanyingChange( $params['tags'], $this->getAuthority() );
81 if ( !$tagStatus->isOK() ) {
82 $this->dieStatus( $tagStatus );
83 }
84 }
85
86 // @TODO: remove this hack once rollback uses POST (T88044)
87 $fname = __METHOD__;
88 $trxLimits = $this->getConfig()->get( MainConfigNames::TrxProfilerLimits );
89 $trxProfiler = Profiler::instance()->getTransactionProfiler();
90 $trxProfiler->redefineExpectations( $trxLimits['POST'], $fname );
91 DeferredUpdates::addCallableUpdate( static function () use ( $trxProfiler, $trxLimits, $fname ) {
92 $trxProfiler->redefineExpectations( $trxLimits['PostSend-POST'], $fname );
93 } );
94
95 $rollbackResult = $this->rollbackPageFactory
96 ->newRollbackPage( $titleObj, $this->getAuthority(), $this->getRbUser( $params ) )
97 ->setSummary( $params['summary'] )
98 ->markAsBot( $params['markbot'] )
99 ->setChangeTags( $params['tags'] )
100 ->rollbackIfAllowed();
101
102 if ( !$rollbackResult->isGood() ) {
103 $this->dieStatus( $rollbackResult );
104 }
105
106 $watch = $params['watchlist'] ?? 'preferences';
107 $watchlistExpiry = $this->getExpiryFromParams( $params );
108
109 // Watch pages
110 $this->setWatch( $watch, $titleObj, $user, 'watchrollback', $watchlistExpiry );
111
112 $details = $rollbackResult->getValue();
113 $currentRevisionRecord = $details['current-revision-record'];
114 $targetRevisionRecord = $details['target-revision-record'];
115
116 $info = [
117 'title' => $titleObj->getPrefixedText(),
118 'pageid' => $currentRevisionRecord->getPageId(),
119 'summary' => $details['summary'],
120 'revid' => (int)$details['newid'],
121 // The revision being reverted (previously the current revision of the page)
122 'old_revid' => $currentRevisionRecord->getID(),
123 // The revision being restored (the last revision before revision(s) by the reverted user)
124 'last_revid' => $targetRevisionRecord->getID()
125 ];
126
127 $this->getResult()->addValue( null, $this->getModuleName(), $info );
128 }
129
130 public function mustBePosted() {
131 return true;
132 }
133
134 public function isWriteMode() {
135 return true;
136 }
137
138 public function getAllowedParams() {
139 $params = [
140 'title' => null,
141 'pageid' => [
142 ParamValidator::PARAM_TYPE => 'integer'
143 ],
144 'tags' => [
145 ParamValidator::PARAM_TYPE => 'tags',
146 ParamValidator::PARAM_ISMULTI => true,
147 ],
148 'user' => [
149 ParamValidator::PARAM_TYPE => 'user',
150 UserDef::PARAM_ALLOWED_USER_TYPES => [ 'name', 'ip', 'id', 'interwiki' ],
151 UserDef::PARAM_RETURN_OBJECT => true,
152 ParamValidator::PARAM_REQUIRED => true
153 ],
154 'summary' => '',
155 'markbot' => false,
156 ];
157
158 // Params appear in the docs in the order they are defined,
159 // which is why this is here (we want it above the token param).
160 $params += $this->getWatchlistParams();
161
162 return $params + [
163 'token' => [
164 // Standard definition automatically inserted
165 ApiBase::PARAM_HELP_MSG_APPEND => [ 'api-help-param-token-webui' ],
166 ],
167 ];
168 }
169
170 public function needsToken() {
171 return 'rollback';
172 }
173
179 private function getRbUser( array $params ): UserIdentity {
180 if ( $this->mUser !== null ) {
181 return $this->mUser;
182 }
183
184 $this->mUser = $params['user'];
185
186 return $this->mUser;
187 }
188
194 private function getRbTitle( array $params ) {
195 if ( $this->mTitleObj !== null ) {
196 return $this->mTitleObj;
197 }
198
199 $this->requireOnlyOneParameter( $params, 'title', 'pageid' );
200
201 if ( isset( $params['title'] ) ) {
202 $this->mTitleObj = Title::newFromText( $params['title'] );
203 if ( !$this->mTitleObj || $this->mTitleObj->isExternal() ) {
204 $this->dieWithError( [ 'apierror-invalidtitle', wfEscapeWikiText( $params['title'] ) ] );
205 }
206 } elseif ( isset( $params['pageid'] ) ) {
207 $this->mTitleObj = Title::newFromID( $params['pageid'] );
208 if ( !$this->mTitleObj ) {
209 $this->dieWithError( [ 'apierror-nosuchpageid', $params['pageid'] ] );
210 }
211 }
212
213 if ( !$this->mTitleObj->exists() ) {
214 $this->dieWithError( 'apierror-missingtitle' );
215 }
216
217 return $this->mTitleObj;
218 }
219
220 protected function getExamplesMessages() {
221 $title = Title::newMainPage()->getPrefixedText();
222 $mp = rawurlencode( $title );
223
224 return [
225 "action=rollback&title={$mp}&user=Example&token=123ABC" =>
226 'apihelp-rollback-example-simple',
227 "action=rollback&title={$mp}&user=192.0.2.5&" .
228 'token=123ABC&summary=Reverting%20vandalism&markbot=1' =>
229 'apihelp-rollback-example-summary',
230 ];
231 }
232
233 public function getHelpUrls() {
234 return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Rollback';
235 }
236}
getExpiryFromParams(array $params)
Get formatted expiry from the given parameters, or null if no expiry was provided.
setWatch(string $watch, Title $title, User $user, ?string $userOption=null, ?string $expiry=null)
Set a watch (or unwatch) based the based on a watchlist parameter.
getWatchlistParams(array $watchOptions=[])
Get additional allow params specific to watchlisting.
wfEscapeWikiText( $text)
Escapes the given text so that it may be output using addWikiText() without any linking,...
if(!defined('MW_SETUP_CALLBACK'))
The persistent session ID (if any) loaded at startup.
Definition WebStart.php:82
This abstract class implements many basic API functions, and is the base of all API classes.
Definition ApiBase.php:56
const PARAM_HELP_MSG_APPEND
((string|array|Message)[]) Specify additional i18n messages to append to the normal message for this ...
Definition ApiBase.php:170
getResult()
Get the result object.
Definition ApiBase.php:629
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
Definition ApiBase.php:765
getModuleName()
Get the name of the module being executed by this instance.
Definition ApiBase.php:498
dieStatus(StatusValue $status)
Throw an ApiUsageException based on the Status object.
Definition ApiBase.php:1515
useTransactionalTimeLimit()
Call wfTransactionalTimeLimit() if this request was POSTed.
Definition ApiBase.php:1299
This is the main API class, used for both external and internal processing.
Definition ApiMain.php:52
getAllowedParams()
Returns an array of allowed parameters (parameter name) => (default value) or (parameter name) => (ar...
getHelpUrls()
Return links to more detailed help pages about the module.
isWriteMode()
Indicates whether this module requires write mode.
getExamplesMessages()
Returns usage examples for this module.
__construct(ApiMain $mainModule, $moduleName, RollbackPageFactory $rollbackPageFactory, WatchlistManager $watchlistManager, UserOptionsLookup $userOptionsLookup)
execute()
Evaluates the parameters, performs the requested query, and sets up the result.
mustBePosted()
Indicates whether this module must be called with a POST request.
needsToken()
Returns the token type this module requires in order to execute.
static canAddTagsAccompanyingChange(array $tags, Authority $performer=null, $checkBlock=true)
Is it OK to allow the user to apply all the specified tags at the same time as they edit/make the cha...
A class containing constants representing the names of configuration variables.
Type definition for user types.
Definition UserDef.php:27
Provides access to user options.
Represents a title within MediaWiki.
Definition Title.php:49
static newFromID( $id, $flags=0)
Create a new Title from an article ID.
Definition Title.php:518
static newFromText( $text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Definition Title.php:370
Service for formatting and validating API parameters.
trait ApiWatchlistTrait
An ApiWatchlistTrait adds class properties and convenience methods for APIs that allow you to watch a...
Service for page rollback actions.
Interface for objects representing user identity.
return true
Definition router.php:92