MediaWiki  master
ApiEditPage.php
Go to the documentation of this file.
1 <?php
25 
35 class ApiEditPage extends ApiBase {
36  public function execute() {
38 
39  $user = $this->getUser();
40  $params = $this->extractRequestParams();
41 
42  $this->requireAtLeastOneParameter( $params, 'text', 'appendtext', 'prependtext', 'undo' );
43 
44  $pageObj = $this->getTitleOrPageId( $params );
45  $titleObj = $pageObj->getTitle();
46  $apiResult = $this->getResult();
47 
48  if ( $params['redirect'] ) {
49  if ( $params['prependtext'] === null && $params['appendtext'] === null
50  && $params['section'] !== 'new'
51  ) {
52  $this->dieWithError( 'apierror-redirect-appendonly' );
53  }
54  if ( $titleObj->isRedirect() ) {
55  $oldTitle = $titleObj;
56 
57  $titles = Revision::newFromTitle( $oldTitle, false, Revision::READ_LATEST )
58  ->getContent( RevisionRecord::FOR_THIS_USER, $user )
59  ->getRedirectChain();
60  // array_shift( $titles );
61  '@phan-var Title[] $titles';
62 
63  $redirValues = [];
64 
66  foreach ( $titles as $id => $newTitle ) {
67  $titles[$id - 1] = $titles[$id - 1] ?? $oldTitle;
68 
69  $redirValues[] = [
70  'from' => $titles[$id - 1]->getPrefixedText(),
71  'to' => $newTitle->getPrefixedText()
72  ];
73 
74  $titleObj = $newTitle;
75 
76  // T239428: Check whether the new title is valid
77  if ( $titleObj->isExternal() || !$titleObj->canExist() ) {
78  $redirValues[count( $redirValues ) - 1]['to'] = $titleObj->getFullText();
79  $this->dieWithError(
80  [
81  'apierror-edit-invalidredirect',
82  Message::plaintextParam( $oldTitle->getPrefixedText() ),
83  Message::plaintextParam( $titleObj->getFullText() ),
84  ],
85  'edit-invalidredirect',
86  [ 'redirects' => $redirValues ]
87  );
88  }
89  }
90 
91  ApiResult::setIndexedTagName( $redirValues, 'r' );
92  $apiResult->addValue( null, 'redirects', $redirValues );
93 
94  // Since the page changed, update $pageObj
95  $pageObj = WikiPage::factory( $titleObj );
96  }
97  }
98 
99  if ( !isset( $params['contentmodel'] ) || $params['contentmodel'] == '' ) {
100  $contentHandler = $pageObj->getContentHandler();
101  } else {
102  $contentHandler = ContentHandler::getForModelID( $params['contentmodel'] );
103  }
104  $contentModel = $contentHandler->getModelID();
105 
106  $name = $titleObj->getPrefixedDBkey();
107  $model = $contentHandler->getModelID();
108 
109  if ( $params['undo'] > 0 ) {
110  // allow undo via api
111  } elseif ( $contentHandler->supportsDirectApiEditing() === false ) {
112  $this->dieWithError( [ 'apierror-no-direct-editing', $model, $name ] );
113  }
114 
115  if ( !isset( $params['contentformat'] ) || $params['contentformat'] == '' ) {
116  $contentFormat = $contentHandler->getDefaultFormat();
117  } else {
118  $contentFormat = $params['contentformat'];
119  }
120 
121  if ( !$contentHandler->isSupportedFormat( $contentFormat ) ) {
122  $this->dieWithError( [ 'apierror-badformat', $contentFormat, $model, $name ] );
123  }
124 
125  if ( $params['createonly'] && $titleObj->exists() ) {
126  $this->dieWithError( 'apierror-articleexists' );
127  }
128  if ( $params['nocreate'] && !$titleObj->exists() ) {
129  $this->dieWithError( 'apierror-missingtitle' );
130  }
131 
132  // Now let's check whether we're even allowed to do this
134  $titleObj,
135  $titleObj->exists() ? 'edit' : [ 'edit', 'create' ],
136  [ 'autoblock' => true ]
137  );
138 
139  $toMD5 = $params['text'];
140  if ( !is_null( $params['appendtext'] ) || !is_null( $params['prependtext'] ) ) {
141  $content = $pageObj->getContent();
142 
143  if ( !$content ) {
144  if ( $titleObj->getNamespace() == NS_MEDIAWIKI ) {
145  # If this is a MediaWiki:x message, then load the messages
146  # and return the message value for x.
147  $text = $titleObj->getDefaultMessageText();
148  if ( $text === false ) {
149  $text = '';
150  }
151 
152  try {
153  $content = ContentHandler::makeContent( $text, $titleObj );
154  } catch ( MWContentSerializationException $ex ) {
155  $this->dieWithException( $ex, [
156  'wrap' => ApiMessage::create( 'apierror-contentserializationexception', 'parseerror' )
157  ] );
158  return;
159  }
160  } else {
161  # Otherwise, make a new empty content.
162  $content = $contentHandler->makeEmptyContent();
163  }
164  }
165 
166  // @todo Add support for appending/prepending to the Content interface
167 
168  if ( !( $content instanceof TextContent ) ) {
169  $modelName = $contentHandler->getModelID();
170  $this->dieWithError( [ 'apierror-appendnotsupported', $modelName ] );
171  }
172 
173  if ( !is_null( $params['section'] ) ) {
174  if ( !$contentHandler->supportsSections() ) {
175  $modelName = $contentHandler->getModelID();
176  $this->dieWithError( [ 'apierror-sectionsnotsupported', $modelName ] );
177  }
178 
179  if ( $params['section'] == 'new' ) {
180  // DWIM if they're trying to prepend/append to a new section.
181  $content = null;
182  } else {
183  // Process the content for section edits
184  $section = $params['section'];
185  $content = $content->getSection( $section );
186 
187  if ( !$content ) {
188  $this->dieWithError( [ 'apierror-nosuchsection', wfEscapeWikiText( $section ) ] );
189  }
190  }
191  }
192 
193  if ( !$content ) {
194  $text = '';
195  } else {
196  $text = $content->serialize( $contentFormat );
197  }
198 
199  $params['text'] = $params['prependtext'] . $text . $params['appendtext'];
200  $toMD5 = $params['prependtext'] . $params['appendtext'];
201  }
202 
203  if ( $params['undo'] > 0 ) {
204  if ( $params['undoafter'] > 0 ) {
205  if ( $params['undo'] < $params['undoafter'] ) {
206  list( $params['undo'], $params['undoafter'] ) =
207  [ $params['undoafter'], $params['undo'] ];
208  }
209  $undoafterRev = Revision::newFromId( $params['undoafter'] );
210  }
211  $undoRev = Revision::newFromId( $params['undo'] );
212  if ( is_null( $undoRev ) || $undoRev->isDeleted( RevisionRecord::DELETED_TEXT ) ) {
213  $this->dieWithError( [ 'apierror-nosuchrevid', $params['undo'] ] );
214  }
215 
216  if ( $params['undoafter'] == 0 ) {
217  $undoafterRev = $undoRev->getPrevious();
218  }
219  if ( is_null( $undoafterRev ) || $undoafterRev->isDeleted( RevisionRecord::DELETED_TEXT ) ) {
220  $this->dieWithError( [ 'apierror-nosuchrevid', $params['undoafter'] ] );
221  }
222 
223  if ( $undoRev->getPage() != $pageObj->getId() ) {
224  $this->dieWithError( [ 'apierror-revwrongpage', $undoRev->getId(),
225  $titleObj->getPrefixedText() ] );
226  }
227  if ( $undoafterRev->getPage() != $pageObj->getId() ) {
228  $this->dieWithError( [ 'apierror-revwrongpage', $undoafterRev->getId(),
229  $titleObj->getPrefixedText() ] );
230  }
231 
232  $newContent = $contentHandler->getUndoContent(
233  $pageObj->getRevision(),
234  $undoRev,
235  $undoafterRev
236  );
237 
238  if ( !$newContent ) {
239  $this->dieWithError( 'undo-failure', 'undofailure' );
240  }
241  if ( empty( $params['contentmodel'] )
242  && empty( $params['contentformat'] )
243  ) {
244  // If we are reverting content model, the new content model
245  // might not support the current serialization format, in
246  // which case go back to the old serialization format,
247  // but only if the user hasn't specified a format/model
248  // parameter.
249  if ( !$newContent->isSupportedFormat( $contentFormat ) ) {
250  $contentFormat = $undoafterRev->getContentFormat();
251  }
252  // Override content model with model of undid revision.
253  $contentModel = $newContent->getModel();
254  }
255  $params['text'] = $newContent->serialize( $contentFormat );
256  // If no summary was given and we only undid one rev,
257  // use an autosummary
258 
259  if ( is_null( $params['summary'] ) ) {
260  $nextRev = MediaWikiServices::getInstance()->getRevisionLookup()
261  ->getNextRevision( $undoafterRev->getRevisionRecord() );
262  if ( $nextRev && $nextRev->getId() == $params['undo'] ) {
263  $params['summary'] = wfMessage( 'undo-summary' )
264  ->params( $params['undo'], $undoRev->getUserText() )
265  ->inContentLanguage()->text();
266  }
267  }
268  }
269 
270  // See if the MD5 hash checks out
271  if ( !is_null( $params['md5'] ) && md5( $toMD5 ) !== $params['md5'] ) {
272  $this->dieWithError( 'apierror-badmd5' );
273  }
274 
275  // EditPage wants to parse its stuff from a WebRequest
276  // That interface kind of sucks, but it's workable
277  $requestArray = [
278  'wpTextbox1' => $params['text'],
279  'format' => $contentFormat,
280  'model' => $contentModel,
281  'wpEditToken' => $params['token'],
282  'wpIgnoreBlankSummary' => true,
283  'wpIgnoreBlankArticle' => true,
284  'wpIgnoreSelfRedirect' => true,
285  'bot' => $params['bot'],
286  'wpUnicodeCheck' => EditPage::UNICODE_CHECK,
287  ];
288 
289  if ( !is_null( $params['summary'] ) ) {
290  $requestArray['wpSummary'] = $params['summary'];
291  }
292 
293  if ( !is_null( $params['sectiontitle'] ) ) {
294  $requestArray['wpSectionTitle'] = $params['sectiontitle'];
295  }
296 
297  // TODO: Pass along information from 'undoafter' as well
298  if ( $params['undo'] > 0 ) {
299  $requestArray['wpUndidRevision'] = $params['undo'];
300  }
301 
302  // Watch out for basetimestamp == '' or '0'
303  // It gets treated as NOW, almost certainly causing an edit conflict
304  if ( $params['basetimestamp'] !== null && (bool)$this->getMain()->getVal( 'basetimestamp' ) ) {
305  $requestArray['wpEdittime'] = $params['basetimestamp'];
306  } else {
307  $requestArray['wpEdittime'] = $pageObj->getTimestamp();
308  }
309 
310  if ( $params['starttimestamp'] !== null ) {
311  $requestArray['wpStarttime'] = $params['starttimestamp'];
312  } else {
313  $requestArray['wpStarttime'] = wfTimestampNow(); // Fake wpStartime
314  }
315 
316  if ( $params['minor'] || ( !$params['notminor'] && $user->getOption( 'minordefault' ) ) ) {
317  $requestArray['wpMinoredit'] = '';
318  }
319 
320  if ( $params['recreate'] ) {
321  $requestArray['wpRecreate'] = '';
322  }
323 
324  if ( !is_null( $params['section'] ) ) {
325  $section = $params['section'];
326  if ( !preg_match( '/^((T-)?\d+|new)$/', $section ) ) {
327  $this->dieWithError( 'apierror-invalidsection' );
328  }
329  $content = $pageObj->getContent();
330  if ( $section !== '0' && $section != 'new'
331  && ( !$content || !$content->getSection( $section ) )
332  ) {
333  $this->dieWithError( [ 'apierror-nosuchsection', $section ] );
334  }
335  $requestArray['wpSection'] = $params['section'];
336  } else {
337  $requestArray['wpSection'] = '';
338  }
339 
340  $watch = $this->getWatchlistValue( $params['watchlist'], $titleObj );
341 
342  // Deprecated parameters
343  if ( $params['watch'] ) {
344  $watch = true;
345  } elseif ( $params['unwatch'] ) {
346  $watch = false;
347  }
348 
349  if ( $watch ) {
350  $requestArray['wpWatchthis'] = '';
351  }
352 
353  // Apply change tags
354  if ( $params['tags'] ) {
355  $tagStatus = ChangeTags::canAddTagsAccompanyingChange( $params['tags'], $user );
356  if ( $tagStatus->isOK() ) {
357  $requestArray['wpChangeTags'] = implode( ',', $params['tags'] );
358  } else {
359  $this->dieStatus( $tagStatus );
360  }
361  }
362 
363  // Pass through anything else we might have been given, to support extensions
364  // This is kind of a hack but it's the best we can do to make extensions work
365  $requestArray += $this->getRequest()->getValues();
366 
367  global $wgTitle, $wgRequest;
368 
369  $req = new DerivativeRequest( $this->getRequest(), $requestArray, true );
370 
371  // Some functions depend on $wgTitle == $ep->mTitle
372  // TODO: Make them not or check if they still do
373  $wgTitle = $titleObj;
374 
375  $articleContext = new RequestContext;
376  $articleContext->setRequest( $req );
377  $articleContext->setWikiPage( $pageObj );
378  $articleContext->setUser( $this->getUser() );
379 
381  $articleObject = Article::newFromWikiPage( $pageObj, $articleContext );
382 
383  $ep = new EditPage( $articleObject );
384 
385  $ep->setApiEditOverride( true );
386  $ep->setContextTitle( $titleObj );
387  $ep->importFormData( $req );
388  $content = $ep->textbox1;
389 
390  // Do the actual save
391  $oldRevId = $articleObject->getRevIdFetched();
392  $result = null;
393  // Fake $wgRequest for some hooks inside EditPage
394  // @todo FIXME: This interface SUCKS
395  $oldRequest = $wgRequest;
396  $wgRequest = $req;
397 
398  $status = $ep->attemptSave( $result );
399  $wgRequest = $oldRequest;
400 
401  $r = [];
402  switch ( $status->value ) {
405  if ( isset( $status->apiHookResult ) ) {
406  $r = $status->apiHookResult;
407  $r['result'] = 'Failure';
408  $apiResult->addValue( null, $this->getModuleName(), $r );
409  return;
410  }
411  if ( !$status->getErrors() ) {
412  // This appears to be unreachable right now, because all
413  // code paths will set an error. Could change, though.
414  $status->fatal( 'hookaborted' ); //@codeCoverageIgnore
415  }
416  $this->dieStatus( $status );
417 
418  // These two cases will normally have been caught earlier, and will
419  // only occur if something blocks the user between the earlier
420  // check and the check in EditPage (presumably a hook). It's not
421  // obvious that this is even possible.
422  // @codeCoverageIgnoreStart
424  $this->dieBlocked( $user->getBlock() );
425 
427  $this->dieReadOnly();
428  // @codeCoverageIgnoreEnd
429 
431  $r['new'] = true;
432  // fall-through
433 
435  $r['result'] = 'Success';
436  $r['pageid'] = (int)$titleObj->getArticleID();
437  $r['title'] = $titleObj->getPrefixedText();
438  $r['contentmodel'] = $articleObject->getContentModel();
439  $newRevId = $articleObject->getLatest();
440  if ( $newRevId == $oldRevId ) {
441  $r['nochange'] = true;
442  } else {
443  $r['oldrevid'] = (int)$oldRevId;
444  $r['newrevid'] = (int)$newRevId;
445  $r['newtimestamp'] = wfTimestamp( TS_ISO_8601,
446  $pageObj->getTimestamp() );
447  }
448  break;
449 
450  default:
451  if ( !$status->getErrors() ) {
452  // EditPage sometimes only sets the status code without setting
453  // any actual error messages. Supply defaults for those cases.
454  switch ( $status->value ) {
455  // Currently needed
457  $status->fatal( 'apierror-noimageredirect-anon' );
458  break;
460  $status->fatal( 'apierror-noimageredirect' );
461  break;
464  $status->fatal( 'apierror-contenttoobig', $this->getConfig()->get( 'MaxArticleSize' ) );
465  break;
467  $status->fatal( 'apierror-noedit-anon' );
468  break;
470  $status->fatal( 'apierror-cantchangecontentmodel' );
471  break;
473  $status->fatal( 'apierror-pagedeleted' );
474  break;
476  $status->fatal( 'editconflict' );
477  break;
478 
479  // Currently shouldn't be needed, but here in case
480  // hooks use them without setting appropriate
481  // errors on the status.
482  // @codeCoverageIgnoreStart
484  $status->fatal( 'apierror-spamdetected', $result['spam'] );
485  break;
487  $status->fatal( 'apierror-noedit' );
488  break;
490  $status->fatal( 'apierror-ratelimited' );
491  break;
493  $status->fatal( 'nocreate-loggedin' );
494  break;
496  $status->fatal( 'apierror-emptypage' );
497  break;
499  $status->fatal( 'apierror-emptynewsection' );
500  break;
502  $status->fatal( 'apierror-summaryrequired' );
503  break;
504  default:
505  wfWarn( __METHOD__ . ": Unknown EditPage code {$status->value} with no message" );
506  $status->fatal( 'apierror-unknownerror-editpage', $status->value );
507  break;
508  // @codeCoverageIgnoreEnd
509  }
510  }
511  $this->dieStatus( $status );
512  }
513  $apiResult->addValue( null, $this->getModuleName(), $r );
514  }
515 
516  public function mustBePosted() {
517  return true;
518  }
519 
520  public function isWriteMode() {
521  return true;
522  }
523 
524  public function getAllowedParams() {
525  return [
526  'title' => [
527  ApiBase::PARAM_TYPE => 'string',
528  ],
529  'pageid' => [
530  ApiBase::PARAM_TYPE => 'integer',
531  ],
532  'section' => null,
533  'sectiontitle' => [
534  ApiBase::PARAM_TYPE => 'string',
535  ],
536  'text' => [
537  ApiBase::PARAM_TYPE => 'text',
538  ],
539  'summary' => null,
540  'tags' => [
541  ApiBase::PARAM_TYPE => 'tags',
542  ApiBase::PARAM_ISMULTI => true,
543  ],
544  'minor' => false,
545  'notminor' => false,
546  'bot' => false,
547  'basetimestamp' => [
548  ApiBase::PARAM_TYPE => 'timestamp',
549  ],
550  'starttimestamp' => [
551  ApiBase::PARAM_TYPE => 'timestamp',
552  ],
553  'recreate' => false,
554  'createonly' => false,
555  'nocreate' => false,
556  'watch' => [
557  ApiBase::PARAM_DFLT => false,
559  ],
560  'unwatch' => [
561  ApiBase::PARAM_DFLT => false,
563  ],
564  'watchlist' => [
565  ApiBase::PARAM_DFLT => 'preferences',
567  'watch',
568  'unwatch',
569  'preferences',
570  'nochange'
571  ],
572  ],
573  'md5' => null,
574  'prependtext' => [
575  ApiBase::PARAM_TYPE => 'text',
576  ],
577  'appendtext' => [
578  ApiBase::PARAM_TYPE => 'text',
579  ],
580  'undo' => [
581  ApiBase::PARAM_TYPE => 'integer',
582  ApiBase::PARAM_MIN => 0,
584  ],
585  'undoafter' => [
586  ApiBase::PARAM_TYPE => 'integer',
587  ApiBase::PARAM_MIN => 0,
589  ],
590  'redirect' => [
591  ApiBase::PARAM_TYPE => 'boolean',
592  ApiBase::PARAM_DFLT => false,
593  ],
594  'contentformat' => [
596  ],
597  'contentmodel' => [
599  ],
600  'token' => [
601  // Standard definition automatically inserted
602  ApiBase::PARAM_HELP_MSG_APPEND => [ 'apihelp-edit-param-token' ],
603  ],
604  ];
605  }
606 
607  public function needsToken() {
608  return 'csrf';
609  }
610 
611  protected function getExamplesMessages() {
612  return [
613  'action=edit&title=Test&summary=test%20summary&' .
614  'text=article%20content&basetimestamp=2007-08-24T12:34:54Z&token=123ABC'
615  => 'apihelp-edit-example-edit',
616  'action=edit&title=Test&summary=NOTOC&minor=&' .
617  'prependtext=__NOTOC__%0A&basetimestamp=2007-08-24T12:34:54Z&token=123ABC'
618  => 'apihelp-edit-example-prepend',
619  'action=edit&title=Test&undo=13585&undoafter=13579&' .
620  'basetimestamp=2007-08-24T12:34:54Z&token=123ABC'
621  => 'apihelp-edit-example-undo',
622  ];
623  }
624 
625  public function getHelpUrls() {
626  return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Edit';
627  }
628 }
static factory(Title $title)
Create a WikiPage object of the appropriate class for the given title.
Definition: WikiPage.php:142
requireAtLeastOneParameter( $params,... $required)
Die if none of a certain set of parameters is set and not false.
Definition: ApiBase.php:953
const PARAM_TYPE
(string|string[]) Either an array of allowed value strings, or a string type as described below...
Definition: ApiBase.php:94
wfEscapeWikiText( $text)
Escapes the given text so that it may be output using addWikiText() without any linking, formatting, etc.
const AS_READ_ONLY_PAGE_ANON
Status: this anonymous user is not allowed to edit this page.
Definition: EditPage.php:86
wfWarn( $msg, $callerOffset=1, $level=E_USER_NOTICE)
Send a warning either to the debug log or in a PHP error depending on $wgDevelopmentWarnings.
getResult()
Get the result object.
Definition: ApiBase.php:640
static getAllContentFormats()
const AS_ARTICLE_WAS_DELETED
Status: article was deleted while editing and param wpRecreate == false or form was not posted...
Definition: EditPage.php:107
dieStatus(StatusValue $status)
Throw an ApiUsageException based on the Status object.
Definition: ApiBase.php:2078
const AS_HOOK_ERROR
Status: Article update aborted by a hook function.
Definition: EditPage.php:66
useTransactionalTimeLimit()
Call wfTransactionalTimeLimit() if this request was POSTed.
Definition: ApiBase.php:1863
const PARAM_DFLT
(null|boolean|integer|string) Default value of the parameter.
Definition: ApiBase.php:55
getMain()
Get the main module.
Definition: ApiBase.php:536
dieBlocked(AbstractBlock $block)
Throw an ApiUsageException, which will (if uncaught) call the main module&#39;s error handler and die wit...
Definition: ApiBase.php:2047
static getContentModels()
The edit page/HTML interface (split from Article) The actual database and text munging is still in Ar...
Definition: EditPage.php:47
Similar to FauxRequest, but only fakes URL parameters and method (POST or GET) and use the base reque...
const AS_SUMMARY_NEEDED
Status: no edit summary given and the user has forceeditsummary set and the user is not editing in hi...
Definition: EditPage.php:129
const AS_HOOK_ERROR_EXPECTED
Status: A hook function returned an error.
Definition: EditPage.php:71
const AS_BLOCKED_PAGE_FOR_USER
Status: User is blocked from editing this page.
Definition: EditPage.php:76
dieWithError( $msg, $code=null, $data=null, $httpCode=null)
Abort execution with an error.
Definition: ApiBase.php:2006
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user...
Definition: ApiBase.php:761
dieWithException( $exception, array $options=[])
Abort execution with an error derived from an exception.
Definition: ApiBase.php:2018
const AS_NO_CREATE_PERMISSION
Status: user tried to create this page, but is not allowed to do that ( Title->userCan(&#39;create&#39;) == f...
Definition: EditPage.php:113
static newFromTitle(LinkTarget $linkTarget, $id=0, $flags=0)
Load either the current, or a specified, revision that&#39;s attached to a given link target...
Definition: Revision.php:139
static setIndexedTagName(array &$arr, $tag)
Set the tag name for numeric-keyed values in XML format.
Definition: ApiResult.php:616
const AS_CONTENT_TOO_BIG
Status: Content too big (> $wgMaxArticleSize)
Definition: EditPage.php:81
const PARAM_HELP_MSG_APPEND
((string|array|Message)[]) Specify additional i18n messages to append to the normal message for this ...
Definition: ApiBase.php:138
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
getWatchlistValue( $watchlist, $titleObj, $userOption=null)
Return true if we&#39;re to watch the page, false if not, null if no change.
Definition: ApiBase.php:1090
static getForModelID( $modelId)
Returns the ContentHandler singleton for the given model ID.
const AS_SPAM_ERROR
Status: summary contained spam according to one of the regexes in $wgSummarySpamRegex.
Definition: EditPage.php:149
const PARAM_RANGE_ENFORCE
(boolean) For PARAM_TYPE &#39;integer&#39;, enforce PARAM_MIN and PARAM_MAX?
Definition: ApiBase.php:124
const AS_SUCCESS_UPDATE
Status: Article successfully updated.
Definition: EditPage.php:56
const AS_READ_ONLY_PAGE
Status: wiki is in readonly mode (wfReadOnly() == true)
Definition: EditPage.php:96
A module that allows for editing and creating pages.
Definition: ApiEditPage.php:35
wfTimestampNow()
Convenience function; returns MediaWiki timestamp for the present time.
const UNICODE_CHECK
Used for Unicode support checks.
Definition: EditPage.php:51
const AS_NO_CHANGE_CONTENT_MODEL
Status: user tried to modify the content model, but is not allowed to do that ( User::isAllowed(&#39;edit...
Definition: EditPage.php:165
getModuleName()
Get the name of the module being executed by this instance.
Definition: ApiBase.php:520
const AS_SUCCESS_NEW_ARTICLE
Status: Article successfully created.
Definition: EditPage.php:61
checkTitleUserPermissions(LinkTarget $linkTarget, $actions, $options=[])
Helper function for permission-denied errors.
Definition: ApiBase.php:2148
const AS_IMAGE_REDIRECT_LOGGED
Status: logged in user is not allowed to upload (User::isAllowed(&#39;upload&#39;) == false) ...
Definition: EditPage.php:159
const NS_MEDIAWIKI
Definition: Defines.php:68
getTitleOrPageId( $params, $load=false)
Get a WikiPage object from a title or pageid param, if possible.
Definition: ApiBase.php:1025
dieReadOnly()
Helper function for readonly errors.
Definition: ApiBase.php:2106
const AS_RATE_LIMITED
Status: rate limiter for action &#39;edit&#39; was tripped.
Definition: EditPage.php:101
const AS_MAX_ARTICLE_SIZE_EXCEEDED
Status: article is too big (> $wgMaxArticleSize), after merging in the new section.
Definition: EditPage.php:139
const AS_IMAGE_REDIRECT_ANON
Status: anonymous user is not allowed to upload (User::isAllowed(&#39;upload&#39;) == false) ...
Definition: EditPage.php:154
const AS_TEXTBOX_EMPTY
Status: user tried to create a new section without content.
Definition: EditPage.php:134
const PARAM_ISMULTI
(boolean) Accept multiple pipe-separated values for this parameter (e.g.
Definition: ApiBase.php:58
This abstract class implements many basic API functions, and is the base of all API classes...
Definition: ApiBase.php:42
const AS_BLANK_ARTICLE
Status: user tried to create a blank page and wpIgnoreBlankArticle == false.
Definition: EditPage.php:118
if(! $wgDBerrorLogTZ) $wgRequest
Definition: Setup.php:729
const PARAM_DEPRECATED
(boolean) Is the parameter deprecated (will show a warning)?
Definition: ApiBase.php:112
$content
Definition: router.php:78
static canAddTagsAccompanyingChange(array $tags, User $user=null)
Is it OK to allow the user to apply all the specified tags at the same time as they edit/make the cha...
Definition: ChangeTags.php:525
if(isset( $_SERVER['PATH_INFO']) && $_SERVER['PATH_INFO'] !='') $wgTitle
Definition: api.php:53
const AS_CONFLICT_DETECTED
Status: (non-resolvable) edit conflict.
Definition: EditPage.php:123
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
const PARAM_MIN
(integer) Lowest value allowed for the parameter, for PARAM_TYPE &#39;integer&#39; and &#39;limit&#39;.
Definition: ApiBase.php:106
static newFromWikiPage(WikiPage $page, IContextSource $context)
Create an Article object of the appropriate class for the given page.
Definition: Article.php:195
static newFromId( $id, $flags=0)
Load a page revision from a given revision ID number.
Definition: Revision.php:120
const AS_READ_ONLY_PAGE_LOGGED
Status: this logged in user is not allowed to edit this page.
Definition: EditPage.php:91
static makeContent( $text, Title $title=null, $modelId=null, $format=null)
Convenience function for creating a Content object from a given textual representation.
static plaintextParam( $plaintext)
Definition: Message.php:1108
return true
Definition: router.php:92
Exception representing a failure to serialize or unserialize a content object.
static create( $msg, $code=null, array $data=null)
Create an IApiMessage for the message.
Definition: ApiMessage.php:40