MediaWiki master
ApiRollback.php
Go to the documentation of this file.
1<?php
9namespace MediaWiki\Api;
10
23
27class ApiRollback extends ApiBase {
28
30
31 public function __construct(
32 ApiMain $mainModule,
33 string $moduleName,
34 private readonly RollbackPageFactory $rollbackPageFactory,
35 WatchlistManager $watchlistManager,
36 WatchedItemStoreInterface $watchedItemStore,
37 UserOptionsLookup $userOptionsLookup,
38 ) {
39 parent::__construct( $mainModule, $moduleName );
40 // Variables needed in ApiWatchlistTrait trait
41 $this->watchlistExpiryEnabled = $this->getConfig()->get( MainConfigNames::WatchlistExpiry );
42 $this->watchlistMaxDuration =
44 $this->watchlistManager = $watchlistManager;
45 $this->watchedItemStore = $watchedItemStore;
46 $this->userOptionsLookup = $userOptionsLookup;
47 }
48
52 private $mTitleObj = null;
53
57 private $mUser = null;
58
59 public function execute() {
61
62 $user = $this->getUser();
63 $params = $this->extractRequestParams();
64
65 $titleObj = $this->getRbTitle( $params );
66
67 // If change tagging was requested, check that the user is allowed to tag,
68 // and the tags are valid. TODO: move inside rollback command?
69 if ( $params['tags'] ) {
70 $tagStatus = ChangeTags::canAddTagsAccompanyingChange( $params['tags'], $this->getAuthority() );
71 if ( !$tagStatus->isOK() ) {
72 $this->dieStatus( $tagStatus );
73 }
74 }
75
76 // @TODO: remove this hack once rollback uses POST (T88044)
77 $fname = __METHOD__;
78 $trxLimits = $this->getConfig()->get( MainConfigNames::TrxProfilerLimits );
79 $trxProfiler = Profiler::instance()->getTransactionProfiler();
80 $trxProfiler->redefineExpectations( $trxLimits['POST'], $fname );
81 DeferredUpdates::addCallableUpdate( static function () use ( $trxProfiler, $trxLimits, $fname ) {
82 $trxProfiler->redefineExpectations( $trxLimits['PostSend-POST'], $fname );
83 } );
84
85 $rollbackResult = $this->rollbackPageFactory
86 ->newRollbackPage( $titleObj, $this->getAuthority(), $this->getRbUser( $params ) )
87 ->setSummary( $params['summary'] )
88 ->markAsBot( $params['markbot'] )
89 ->setChangeTags( $params['tags'] )
90 ->rollbackIfAllowed();
91
92 if ( !$rollbackResult->isGood() ) {
93 $this->dieStatus( $rollbackResult );
94 }
95
96 $watch = $params['watchlist'] ?? 'preferences';
97 $watchlistExpiry = $this->getExpiryFromParams( $params, $titleObj, $user, 'watchrollback-expiry' );
98
99 // Watch pages
100 $this->setWatch( $watch, $titleObj, $user, 'watchrollback', $watchlistExpiry );
101
102 $details = $rollbackResult->getValue();
103 $currentRevisionRecord = $details['current-revision-record'];
104 $targetRevisionRecord = $details['target-revision-record'];
105
106 $info = [
107 'title' => $titleObj->getPrefixedText(),
108 'pageid' => $currentRevisionRecord->getPageId(),
109 'summary' => $details['summary'],
110 'revid' => (int)$details['newid'],
111 // The revision being reverted (previously the latest revision of the page)
112 'old_revid' => $currentRevisionRecord->getID(),
113 // The revision being restored (the last revision before revision(s) by the reverted user)
114 'last_revid' => $targetRevisionRecord->getID()
115 ];
116
117 $this->getResult()->addValue( null, $this->getModuleName(), $info );
118 }
119
121 public function mustBePosted() {
122 return true;
123 }
124
126 public function isWriteMode() {
127 return true;
128 }
129
131 public function getAllowedParams() {
132 $params = [
133 'title' => null,
134 'pageid' => [
135 ParamValidator::PARAM_TYPE => 'integer'
136 ],
137 'tags' => [
138 ParamValidator::PARAM_TYPE => 'tags',
139 ParamValidator::PARAM_ISMULTI => true,
140 ],
141 'user' => [
142 ParamValidator::PARAM_TYPE => 'user',
143 UserDef::PARAM_ALLOWED_USER_TYPES => [ 'name', 'ip', 'temp', 'id', 'interwiki' ],
144 UserDef::PARAM_RETURN_OBJECT => true,
145 ParamValidator::PARAM_REQUIRED => true
146 ],
147 'summary' => '',
148 'markbot' => false,
149 ];
150
151 // Params appear in the docs in the order they are defined,
152 // which is why this is here (we want it above the token param).
153 $params += $this->getWatchlistParams();
154
155 return $params + [
156 'token' => [
157 // Standard definition automatically inserted
158 ApiBase::PARAM_HELP_MSG_APPEND => [ 'api-help-param-token-webui' ],
159 ],
160 ];
161 }
162
164 public function needsToken() {
165 return 'rollback';
166 }
167
168 private function getRbUser( array $params ): UserIdentity {
169 if ( $this->mUser !== null ) {
170 return $this->mUser;
171 }
172
173 $this->mUser = $params['user'];
174
175 return $this->mUser;
176 }
177
183 private function getRbTitle( array $params ) {
184 if ( $this->mTitleObj !== null ) {
185 return $this->mTitleObj;
186 }
187
188 $this->requireOnlyOneParameter( $params, 'title', 'pageid' );
189
190 if ( isset( $params['title'] ) ) {
191 $this->mTitleObj = Title::newFromText( $params['title'] );
192 if ( !$this->mTitleObj || $this->mTitleObj->isExternal() ) {
193 $this->dieWithError( [ 'apierror-invalidtitle', wfEscapeWikiText( $params['title'] ) ] );
194 }
195 } elseif ( isset( $params['pageid'] ) ) {
196 $this->mTitleObj = Title::newFromID( $params['pageid'] );
197 if ( !$this->mTitleObj ) {
198 $this->dieWithError( [ 'apierror-nosuchpageid', $params['pageid'] ] );
199 }
200 }
201
202 if ( !$this->mTitleObj->exists() ) {
203 $this->dieWithError( 'apierror-missingtitle' );
204 }
205
206 return $this->mTitleObj;
207 }
208
210 protected function getExamplesMessages() {
211 $title = Title::newMainPage()->getPrefixedText();
212 $mp = rawurlencode( $title );
213
214 return [
215 "action=rollback&title={$mp}&user=Example&token=123ABC" =>
216 'apihelp-rollback-example-simple',
217 "action=rollback&title={$mp}&user=192.0.2.5&" .
218 'token=123ABC&summary=Reverting%20vandalism&markbot=1' =>
219 'apihelp-rollback-example-summary',
220 ];
221 }
222
224 public function getHelpUrls() {
225 return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Rollback';
226 }
227}
228
230class_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:71
This abstract class implements many basic API functions, and is the base of all API classes.
Definition ApiBase.php:60
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:1369
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:174
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:66
execute()
Evaluates the parameters, performs the requested query, and sets up the result.
getHelpUrls()
Return links to more detailed help pages about the module.1.25, returning boolean false is deprecated...
__construct(ApiMain $mainModule, string $moduleName, private readonly RollbackPageFactory $rollbackPageFactory, WatchlistManager $watchlistManager, WatchedItemStoreInterface $watchedItemStore, UserOptionsLookup $userOptionsLookup,)
isWriteMode()
Indicates whether this module requires write access to the wiki.API modules must override this method...
mustBePosted()
Indicates whether this module must be called with a POST request.Implementations of this method must ...
getExamplesMessages()
Returns usage examples for this module.Return value has query strings as keys, with values being eith...
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.Modules are strongly encouraged to us...
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
Profiler base class that defines the interface and some shared functionality.
Definition Profiler.php:26
Represents a title within MediaWiki.
Definition Title.php:69
Provides access to user options.
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.
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.
getExpiryFromParams(array $params, ?PageIdentity $page=null, ?UserIdentity $user=null, string $userOption='watchdefault-expiry')
Get formatted expiry from the given parameters.