MediaWiki REL1_39
ApiProtect.php
Go to the documentation of this file.
1<?php
28
32class ApiProtect extends ApiBase {
33
35
37 private $restrictionStore;
38
46 public function __construct(
47 ApiMain $mainModule,
48 $moduleName,
49 WatchlistManager $watchlistManager,
50 UserOptionsLookup $userOptionsLookup,
51 RestrictionStore $restrictionStore
52 ) {
53 parent::__construct( $mainModule, $moduleName );
54 $this->restrictionStore = $restrictionStore;
55
56 // Variables needed in ApiWatchlistTrait trait
57 $this->watchlistExpiryEnabled = $this->getConfig()->get( MainConfigNames::WatchlistExpiry );
58 $this->watchlistMaxDuration =
59 $this->getConfig()->get( MainConfigNames::WatchlistExpiryMaxDuration );
60 $this->watchlistManager = $watchlistManager;
61 $this->userOptionsLookup = $userOptionsLookup;
62 }
63
64 public function execute() {
65 $params = $this->extractRequestParams();
66
67 $pageObj = $this->getTitleOrPageId( $params, 'fromdbmaster' );
68 $titleObj = $pageObj->getTitle();
69 $this->getErrorFormatter()->setContextTitle( $titleObj );
70
71 $this->checkTitleUserPermissions( $titleObj, 'protect' );
72
73 $user = $this->getUser();
74 $tags = $params['tags'];
75
76 // Check if user can add tags
77 if ( $tags !== null ) {
78 $ableToTag = ChangeTags::canAddTagsAccompanyingChange( $tags, $this->getAuthority() );
79 if ( !$ableToTag->isOK() ) {
80 $this->dieStatus( $ableToTag );
81 }
82 }
83
84 $expiry = (array)$params['expiry'];
85 if ( count( $expiry ) != count( $params['protections'] ) ) {
86 if ( count( $expiry ) == 1 ) {
87 $expiry = array_fill( 0, count( $params['protections'] ), $expiry[0] );
88 } else {
89 $this->dieWithError( [
90 'apierror-toofewexpiries',
91 count( $expiry ),
92 count( $params['protections'] )
93 ] );
94 }
95 }
96
97 $restrictionTypes = $this->restrictionStore->listApplicableRestrictionTypes( $titleObj );
98 $levels = $this->getPermissionManager()->getNamespaceRestrictionLevels(
99 $titleObj->getNamespace(),
100 $user
101 );
102
103 $protections = [];
104 $expiryarray = [];
105 $resultProtections = [];
106 foreach ( $params['protections'] as $i => $prot ) {
107 $p = explode( '=', $prot );
108 $protections[$p[0]] = ( $p[1] == 'all' ? '' : $p[1] );
109
110 if ( $titleObj->exists() && $p[0] == 'create' ) {
111 $this->dieWithError( 'apierror-create-titleexists' );
112 }
113 if ( !$titleObj->exists() && $p[0] != 'create' ) {
114 $this->dieWithError( 'apierror-missingtitle-createonly' );
115 }
116
117 if ( !in_array( $p[0], $restrictionTypes ) && $p[0] != 'create' ) {
118 $this->dieWithError( [ 'apierror-protect-invalidaction', wfEscapeWikiText( $p[0] ) ] );
119 }
120 if ( !in_array( $p[1], $levels ) && $p[1] != 'all' ) {
121 $this->dieWithError( [ 'apierror-protect-invalidlevel', wfEscapeWikiText( $p[1] ) ] );
122 }
123
124 if ( wfIsInfinity( $expiry[$i] ) ) {
125 $expiryarray[$p[0]] = 'infinity';
126 } else {
127 $exp = strtotime( $expiry[$i] );
128 if ( $exp < 0 || !$exp ) {
129 $this->dieWithError( [ 'apierror-invalidexpiry', wfEscapeWikiText( $expiry[$i] ) ] );
130 }
131
132 $exp = wfTimestamp( TS_MW, $exp );
133 if ( $exp < wfTimestampNow() ) {
134 $this->dieWithError( [ 'apierror-pastexpiry', wfEscapeWikiText( $expiry[$i] ) ] );
135 }
136 $expiryarray[$p[0]] = $exp;
137 }
138 $resultProtections[] = [
139 $p[0] => $protections[$p[0]],
140 'expiry' => ApiResult::formatExpiry( $expiryarray[$p[0]], 'infinite' ),
141 ];
142 }
143
144 $cascade = $params['cascade'];
145
146 $watch = $params['watch'] ? 'watch' : $params['watchlist'];
147 $watchlistExpiry = $this->getExpiryFromParams( $params );
148 $this->setWatch( $watch, $titleObj, $user, 'watchdefault', $watchlistExpiry );
149
150 $status = $pageObj->doUpdateRestrictions(
151 $protections,
152 $expiryarray,
153 $cascade,
154 $params['reason'],
155 $user,
156 $tags ?? []
157 );
158
159 if ( !$status->isOK() ) {
160 $this->dieStatus( $status );
161 }
162 $res = [
163 'title' => $titleObj->getPrefixedText(),
164 'reason' => $params['reason']
165 ];
166 if ( $cascade ) {
167 $res['cascade'] = true;
168 }
169 $res['protections'] = $resultProtections;
170 $result = $this->getResult();
171 ApiResult::setIndexedTagName( $res['protections'], 'protection' );
172 $result->addValue( null, $this->getModuleName(), $res );
173 }
174
175 public function mustBePosted() {
176 return true;
177 }
178
179 public function isWriteMode() {
180 return true;
181 }
182
183 public function getAllowedParams() {
184 return [
185 'title' => [
186 ParamValidator::PARAM_TYPE => 'string',
187 ],
188 'pageid' => [
189 ParamValidator::PARAM_TYPE => 'integer',
190 ],
191 'protections' => [
192 ParamValidator::PARAM_ISMULTI => true,
193 ParamValidator::PARAM_REQUIRED => true,
194 ],
195 'expiry' => [
196 ParamValidator::PARAM_ISMULTI => true,
197 ParamValidator::PARAM_ALLOW_DUPLICATES => true,
198 ParamValidator::PARAM_DEFAULT => 'infinite',
199 ],
200 'reason' => '',
201 'tags' => [
202 ParamValidator::PARAM_TYPE => 'tags',
203 ParamValidator::PARAM_ISMULTI => true,
204 ],
205 'cascade' => false,
206 'watch' => [
207 ParamValidator::PARAM_DEFAULT => false,
208 ParamValidator::PARAM_DEPRECATED => true,
209 ],
210 ] + $this->getWatchlistParams();
211 }
212
213 public function needsToken() {
214 return 'csrf';
215 }
216
217 protected function getExamplesMessages() {
218 $title = Title::newMainPage()->getPrefixedText();
219 $mp = rawurlencode( $title );
220
221 return [
222 "action=protect&title={$mp}&token=123ABC&" .
223 'protections=edit=sysop|move=sysop&cascade=&expiry=20070901163000|never'
224 => 'apihelp-protect-example-protect',
225 "action=protect&title={$mp}&token=123ABC&" .
226 'protections=edit=all|move=all&reason=Lifting%20restrictions'
227 => 'apihelp-protect-example-unprotect',
228 "action=protect&title={$mp}&token=123ABC&" .
229 'protections=&reason=Lifting%20restrictions'
230 => 'apihelp-protect-example-unprotect2',
231 ];
232 }
233
234 public function getHelpUrls() {
235 return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Protect';
236 }
237}
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.
wfTimestampNow()
Convenience function; returns MediaWiki timestamp for the present time.
wfIsInfinity( $str)
Determine input string is represents as infinity.
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
wfEscapeWikiText( $text)
Escapes the given text so that it may be output using addWikiText() without any linking,...
This abstract class implements many basic API functions, and is the base of all API classes.
Definition ApiBase.php:56
dieWithError( $msg, $code=null, $data=null, $httpCode=0)
Abort execution with an error.
Definition ApiBase.php:1454
getErrorFormatter()
Definition ApiBase.php:640
getPermissionManager()
Obtain a PermissionManager instance that subclasses may use in their authorization checks.
Definition ApiBase.php:686
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
checkTitleUserPermissions( $pageIdentity, $actions, array $options=[])
Helper function for permission-denied errors.
Definition ApiBase.php:1586
getModuleName()
Get the name of the module being executed by this instance.
Definition ApiBase.php:498
getTitleOrPageId( $params, $load=false)
Get a WikiPage object from a title or pageid param, if possible.
Definition ApiBase.php:1036
dieStatus(StatusValue $status)
Throw an ApiUsageException based on the Status object.
Definition ApiBase.php:1515
This is the main API class, used for both external and internal processing.
Definition ApiMain.php:52
isWriteMode()
Indicates whether this module requires write mode.
getExamplesMessages()
Returns usage examples for this module.
needsToken()
Returns the token type this module requires in order to execute.
__construct(ApiMain $mainModule, $moduleName, WatchlistManager $watchlistManager, UserOptionsLookup $userOptionsLookup, RestrictionStore $restrictionStore)
mustBePosted()
Indicates whether this module must be called with a POST request.
getAllowedParams()
Returns an array of allowed parameters (parameter name) => (default value) or (parameter name) => (ar...
execute()
Evaluates the parameters, performs the requested query, and sets up the result.
getHelpUrls()
Return links to more detailed help pages about the module.
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.
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...