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