MediaWiki master
ApiRollback.php
Go to the documentation of this file.
1<?php
23namespace MediaWiki\Api;
24
34use Profiler;
36
40class ApiRollback extends ApiBase {
41
43
44 private RollbackPageFactory $rollbackPageFactory;
45
46 public function __construct(
47 ApiMain $mainModule,
48 string $moduleName,
49 RollbackPageFactory $rollbackPageFactory,
50 WatchlistManager $watchlistManager,
51 UserOptionsLookup $userOptionsLookup
52 ) {
53 parent::__construct( $mainModule, $moduleName );
54 $this->rollbackPageFactory = $rollbackPageFactory;
55
56 // Variables needed in ApiWatchlistTrait trait
57 $this->watchlistExpiryEnabled = $this->getConfig()->get( MainConfigNames::WatchlistExpiry );
58 $this->watchlistMaxDuration =
60 $this->watchlistManager = $watchlistManager;
61 $this->userOptionsLookup = $userOptionsLookup;
62 }
63
67 private $mTitleObj = null;
68
72 private $mUser = null;
73
74 public function execute() {
76
77 $user = $this->getUser();
78 $params = $this->extractRequestParams();
79
80 $titleObj = $this->getRbTitle( $params );
81
82 // If change tagging was requested, check that the user is allowed to tag,
83 // and the tags are valid. TODO: move inside rollback command?
84 if ( $params['tags'] ) {
85 $tagStatus = ChangeTags::canAddTagsAccompanyingChange( $params['tags'], $this->getAuthority() );
86 if ( !$tagStatus->isOK() ) {
87 $this->dieStatus( $tagStatus );
88 }
89 }
90
91 // @TODO: remove this hack once rollback uses POST (T88044)
92 $fname = __METHOD__;
93 $trxLimits = $this->getConfig()->get( MainConfigNames::TrxProfilerLimits );
94 $trxProfiler = Profiler::instance()->getTransactionProfiler();
95 $trxProfiler->redefineExpectations( $trxLimits['POST'], $fname );
96 DeferredUpdates::addCallableUpdate( static function () use ( $trxProfiler, $trxLimits, $fname ) {
97 $trxProfiler->redefineExpectations( $trxLimits['PostSend-POST'], $fname );
98 } );
99
100 $rollbackResult = $this->rollbackPageFactory
101 ->newRollbackPage( $titleObj, $this->getAuthority(), $this->getRbUser( $params ) )
102 ->setSummary( $params['summary'] )
103 ->markAsBot( $params['markbot'] )
104 ->setChangeTags( $params['tags'] )
105 ->rollbackIfAllowed();
106
107 if ( !$rollbackResult->isGood() ) {
108 $this->dieStatus( $rollbackResult );
109 }
110
111 $watch = $params['watchlist'] ?? 'preferences';
112 $watchlistExpiry = $this->getExpiryFromParams( $params );
113
114 // Watch pages
115 $this->setWatch( $watch, $titleObj, $user, 'watchrollback', $watchlistExpiry );
116
117 $details = $rollbackResult->getValue();
118 $currentRevisionRecord = $details['current-revision-record'];
119 $targetRevisionRecord = $details['target-revision-record'];
120
121 $info = [
122 'title' => $titleObj->getPrefixedText(),
123 'pageid' => $currentRevisionRecord->getPageId(),
124 'summary' => $details['summary'],
125 'revid' => (int)$details['newid'],
126 // The revision being reverted (previously the current revision of the page)
127 'old_revid' => $currentRevisionRecord->getID(),
128 // The revision being restored (the last revision before revision(s) by the reverted user)
129 'last_revid' => $targetRevisionRecord->getID()
130 ];
131
132 $this->getResult()->addValue( null, $this->getModuleName(), $info );
133 }
134
135 public function mustBePosted() {
136 return true;
137 }
138
139 public function isWriteMode() {
140 return true;
141 }
142
143 public function getAllowedParams() {
144 $params = [
145 'title' => null,
146 'pageid' => [
147 ParamValidator::PARAM_TYPE => 'integer'
148 ],
149 'tags' => [
150 ParamValidator::PARAM_TYPE => 'tags',
151 ParamValidator::PARAM_ISMULTI => true,
152 ],
153 'user' => [
154 ParamValidator::PARAM_TYPE => 'user',
155 UserDef::PARAM_ALLOWED_USER_TYPES => [ 'name', 'ip', 'temp', 'id', 'interwiki' ],
156 UserDef::PARAM_RETURN_OBJECT => true,
157 ParamValidator::PARAM_REQUIRED => true
158 ],
159 'summary' => '',
160 'markbot' => false,
161 ];
162
163 // Params appear in the docs in the order they are defined,
164 // which is why this is here (we want it above the token param).
165 $params += $this->getWatchlistParams();
166
167 return $params + [
168 'token' => [
169 // Standard definition automatically inserted
170 ApiBase::PARAM_HELP_MSG_APPEND => [ 'api-help-param-token-webui' ],
171 ],
172 ];
173 }
174
175 public function needsToken() {
176 return 'rollback';
177 }
178
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}
237
239class_alias( ApiRollback::class, 'ApiRollback' );
wfEscapeWikiText( $input)
Escapes the given text so that it may be output using addWikiText() without any linking,...
if(!defined('MW_SETUP_CALLBACK'))
Definition WebStart.php:81
This abstract class implements many basic API functions, and is the base of all API classes.
Definition ApiBase.php:75
getModuleName()
Get the name of the module being executed by this instance.
Definition ApiBase.php:557
useTransactionalTimeLimit()
Call wfTransactionalTimeLimit() if this request was POSTed.
Definition ApiBase.php:1370
getResult()
Get the result object.
Definition ApiBase.php:696
const PARAM_HELP_MSG_APPEND
((string|array|Message)[]) Specify additional i18n messages to append to the normal message for this ...
Definition ApiBase.php:189
dieStatus(StatusValue $status)
Throw an ApiUsageException based on the Status object.
Definition ApiBase.php:1573
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
Definition ApiBase.php:837
This is the main API class, used for both external and internal processing.
Definition ApiMain.php:78
execute()
Evaluates the parameters, performs the requested query, and sets up the result.
getHelpUrls()
Return links to more detailed help pages about the module.
isWriteMode()
Indicates whether this module requires write access to the wiki.
mustBePosted()
Indicates whether this module must be called with a POST request.
__construct(ApiMain $mainModule, string $moduleName, RollbackPageFactory $rollbackPageFactory, WatchlistManager $watchlistManager, UserOptionsLookup $userOptionsLookup)
getExamplesMessages()
Returns usage examples for this module.
getAllowedParams()
Returns an array of allowed parameters (parameter name) => (default value) or (parameter name) => (ar...
needsToken()
Returns the token type this module requires in order to execute.
Recent changes tagging.
Defer callable updates to run later in the PHP process.
A class containing constants representing the names of configuration variables.
const TrxProfilerLimits
Name constant for the TrxProfilerLimits setting, for use with Config::get()
const WatchlistExpiry
Name constant for the WatchlistExpiry setting, for use with Config::get()
const WatchlistExpiryMaxDuration
Name constant for the WatchlistExpiryMaxDuration setting, for use with Config::get()
Type definition for user types.
Definition UserDef.php:27
Represents a title within MediaWiki.
Definition Title.php:78
Provides access to user options.
Profiler base class that defines the interface and some shared functionality.
Definition Profiler.php:37
static instance()
Definition Profiler.php:105
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.
getExpiryFromParams(array $params)
Get formatted expiry from the given parameters, or null if no expiry was provided.
setWatch(string $watch, PageIdentity $page, 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.