MediaWiki  master
ApiQueryRevisionsBase.php
Go to the documentation of this file.
1 <?php
31 
40 
41  // region Constants for internal use. Don't use externally.
44  // Bits to indicate the results of the revdel permission check on a revision,
45  // see self::checkRevDel()
46  private const IS_DELETED = 1; // Whether the field is revision-deleted
47  private const CANNOT_VIEW = 2; // Whether the user cannot view the field due to revdel
48 
49  // endregion
50 
54 
55  protected $fld_ids = false, $fld_flags = false, $fld_timestamp = false,
56  $fld_size = false, $fld_slotsize = false, $fld_sha1 = false, $fld_slotsha1 = false,
57  $fld_comment = false, $fld_parsedcomment = false, $fld_user = false, $fld_userid = false,
58  $fld_content = false, $fld_tags = false, $fld_contentmodel = false, $fld_roles = false,
59  $fld_parsetree = false;
60 
61  public function execute() {
62  $this->run();
63  }
64 
65  public function executeGenerator( $resultPageSet ) {
66  $this->run( $resultPageSet );
67  }
68 
73  abstract protected function run( ApiPageSet $resultPageSet = null );
74 
80  protected function parseParameters( $params ) {
81  $prop = array_flip( $params['prop'] );
82 
83  $this->fld_ids = isset( $prop['ids'] );
84  $this->fld_flags = isset( $prop['flags'] );
85  $this->fld_timestamp = isset( $prop['timestamp'] );
86  $this->fld_comment = isset( $prop['comment'] );
87  $this->fld_parsedcomment = isset( $prop['parsedcomment'] );
88  $this->fld_size = isset( $prop['size'] );
89  $this->fld_slotsize = isset( $prop['slotsize'] );
90  $this->fld_sha1 = isset( $prop['sha1'] );
91  $this->fld_slotsha1 = isset( $prop['slotsha1'] );
92  $this->fld_content = isset( $prop['content'] );
93  $this->fld_contentmodel = isset( $prop['contentmodel'] );
94  $this->fld_userid = isset( $prop['userid'] );
95  $this->fld_user = isset( $prop['user'] );
96  $this->fld_tags = isset( $prop['tags'] );
97  $this->fld_roles = isset( $prop['roles'] );
98  $this->fld_parsetree = isset( $prop['parsetree'] );
99 
100  $this->slotRoles = $params['slots'];
101 
102  if ( $this->slotRoles !== null ) {
103  if ( $this->fld_parsetree ) {
104  $this->dieWithError( [
105  'apierror-invalidparammix-cannotusewith',
106  $this->encodeParamName( 'prop=parsetree' ),
107  $this->encodeParamName( 'slots' ),
108  ], 'invalidparammix' );
109  }
110  foreach ( [
111  'expandtemplates', 'generatexml', 'parse', 'diffto', 'difftotext', 'difftotextpst',
112  'contentformat'
113  ] as $p ) {
114  if ( $params[$p] !== null && $params[$p] !== false ) {
115  $this->dieWithError( [
116  'apierror-invalidparammix-cannotusewith',
117  $this->encodeParamName( $p ),
118  $this->encodeParamName( 'slots' ),
119  ], 'invalidparammix' );
120  }
121  }
122  }
123 
124  if ( !empty( $params['contentformat'] ) ) {
125  $this->contentFormat = $params['contentformat'];
126  }
127 
128  $this->limit = $params['limit'];
129 
130  if ( $params['difftotext'] !== null ) {
131  $this->difftotext = $params['difftotext'];
132  $this->difftotextpst = $params['difftotextpst'];
133  } elseif ( $params['diffto'] !== null ) {
134  if ( $params['diffto'] == 'cur' ) {
135  $params['diffto'] = 0;
136  }
137  if ( ( !ctype_digit( $params['diffto'] ) || $params['diffto'] < 0 )
138  && $params['diffto'] != 'prev' && $params['diffto'] != 'next'
139  ) {
140  $p = $this->getModulePrefix();
141  $this->dieWithError( [ 'apierror-baddiffto', $p ], 'diffto' );
142  }
143  // Check whether the revision exists and is readable,
144  // DifferenceEngine returns a rather ambiguous empty
145  // string if that's not the case
146  if ( $params['diffto'] != 0 ) {
147  $difftoRev = MediaWikiServices::getInstance()->getRevisionStore()
148  ->getRevisionById( $params['diffto'] );
149  if ( !$difftoRev ) {
150  $this->dieWithError( [ 'apierror-nosuchrevid', $params['diffto'] ] );
151  }
152  $revDel = $this->checkRevDel( $difftoRev, RevisionRecord::DELETED_TEXT );
153  if ( $revDel & self::CANNOT_VIEW ) {
154  $this->addWarning( [ 'apiwarn-difftohidden', $difftoRev->getId() ] );
155  $params['diffto'] = null;
156  }
157  }
158  $this->diffto = $params['diffto'];
159  }
160 
161  $this->fetchContent = $this->fld_content || $this->diffto !== null
162  || $this->difftotext !== null || $this->fld_parsetree;
163 
164  $smallLimit = false;
165  if ( $this->fetchContent ) {
166  $smallLimit = true;
167  $this->expandTemplates = $params['expandtemplates'];
168  $this->generateXML = $params['generatexml'];
169  $this->parseContent = $params['parse'];
170  if ( $this->parseContent ) {
171  // Must manually initialize unset limit
172  if ( $this->limit === null ) {
173  $this->limit = 1;
174  }
175  }
176  $this->section = $params['section'] ?? false;
177  }
178 
179  $userMax = $this->parseContent ? 1 : ( $smallLimit ? ApiBase::LIMIT_SML1 : ApiBase::LIMIT_BIG1 );
180  $botMax = $this->parseContent ? 1 : ( $smallLimit ? ApiBase::LIMIT_SML2 : ApiBase::LIMIT_BIG2 );
181  if ( $this->limit == 'max' ) {
182  $this->limit = $this->getMain()->canApiHighLimits() ? $botMax : $userMax;
183  if ( $this->setParsedLimit ) {
184  $this->getResult()->addParsedLimit( $this->getModuleName(), $this->limit );
185  }
186  }
187 
188  $this->limit = $this->getMain()->getParamValidator()->validateValue(
189  $this, 'limit', $this->limit ?? 10, [
190  ParamValidator::PARAM_TYPE => 'limit',
191  IntegerDef::PARAM_MIN => 1,
192  IntegerDef::PARAM_MAX => $userMax,
193  IntegerDef::PARAM_MAX2 => $botMax,
194  IntegerDef::PARAM_IGNORE_RANGE => true,
195  ]
196  );
197 
198  $this->needSlots = $this->fetchContent || $this->fld_contentmodel ||
199  $this->fld_slotsize || $this->fld_slotsha1;
200  if ( $this->needSlots && $this->slotRoles === null ) {
201  $encParam = $this->encodeParamName( 'slots' );
202  $name = $this->getModuleName();
203  $parent = $this->getParent();
204  $parentParam = $parent->encodeParamName( $parent->getModuleManager()->getModuleGroup( $name ) );
205  $this->addDeprecation(
206  [ 'apiwarn-deprecation-missingparam', $encParam ],
207  "action=query&{$parentParam}={$name}&!{$encParam}"
208  );
209  }
210  }
211 
219  private function checkRevDel( RevisionRecord $revision, $field ) {
220  $ret = $revision->isDeleted( $field ) ? self::IS_DELETED : 0;
221  if ( $ret ) {
222  $canSee = $revision->audienceCan( $field, RevisionRecord::FOR_THIS_USER, $this->getUser() );
223  $ret |= ( $canSee ? 0 : self::CANNOT_VIEW );
224  }
225  return $ret;
226  }
227 
236  protected function extractRevisionInfo( RevisionRecord $revision, $row ) {
237  $vals = [];
238  $anyHidden = false;
239 
240  if ( $this->fld_ids ) {
241  $vals['revid'] = (int)$revision->getId();
242  if ( $revision->getParentId() !== null ) {
243  $vals['parentid'] = (int)$revision->getParentId();
244  }
245  }
246 
247  if ( $this->fld_flags ) {
248  $vals['minor'] = $revision->isMinor();
249  }
250 
251  if ( $this->fld_user || $this->fld_userid ) {
252  $revDel = $this->checkRevDel( $revision, RevisionRecord::DELETED_USER );
253  if ( ( $revDel & self::IS_DELETED ) ) {
254  $vals['userhidden'] = true;
255  $anyHidden = true;
256  }
257  if ( !( $revDel & self::CANNOT_VIEW ) ) {
258  $u = $revision->getUser( RevisionRecord::RAW );
259  if ( $this->fld_user ) {
260  $vals['user'] = $u->getName();
261  }
262  $userid = $u->getId();
263  if ( !$userid ) {
264  $vals['anon'] = true;
265  }
266 
267  if ( $this->fld_userid ) {
268  $vals['userid'] = $userid;
269  }
270  }
271  }
272 
273  if ( $this->fld_timestamp ) {
274  $vals['timestamp'] = wfTimestamp( TS_ISO_8601, $revision->getTimestamp() );
275  }
276 
277  if ( $this->fld_size ) {
278  try {
279  $vals['size'] = (int)$revision->getSize();
280  } catch ( RevisionAccessException $e ) {
281  // Back compat: If there's no size, return 0.
282  // @todo: Gergő says to mention T198099 as a "todo" here.
283  $vals['size'] = 0;
284  }
285  }
286 
287  if ( $this->fld_sha1 ) {
288  $revDel = $this->checkRevDel( $revision, RevisionRecord::DELETED_TEXT );
289  if ( ( $revDel & self::IS_DELETED ) ) {
290  $vals['sha1hidden'] = true;
291  $anyHidden = true;
292  }
293  if ( !( $revDel & self::CANNOT_VIEW ) ) {
294  try {
295  $vals['sha1'] = Wikimedia\base_convert( $revision->getSha1(), 36, 16, 40 );
296  } catch ( RevisionAccessException $e ) {
297  // Back compat: If there's no sha1, return empty string.
298  // @todo: Gergő says to mention T198099 as a "todo" here.
299  $vals['sha1'] = '';
300  }
301  }
302  }
303 
304  try {
305  if ( $this->fld_roles ) {
306  $vals['roles'] = $revision->getSlotRoles();
307  }
308 
309  if ( $this->needSlots ) {
310  $revDel = $this->checkRevDel( $revision, RevisionRecord::DELETED_TEXT );
311  if ( ( $this->fld_slotsha1 || $this->fetchContent ) && ( $revDel & self::IS_DELETED ) ) {
312  $anyHidden = true;
313  }
314  $vals = array_merge( $vals, $this->extractAllSlotInfo( $revision, $revDel ) );
315  }
316  } catch ( RevisionAccessException $ex ) {
317  // This is here so T212428 doesn't spam the log.
318  // TODO: find out why T212428 happens in the first place!
319  $vals['slotsmissing'] = true;
320 
321  LoggerFactory::getInstance( 'api-warning' )->error(
322  'Failed to access revision slots',
323  [ 'revision' => $revision->getId(), 'exception' => $ex, ]
324  );
325  }
326 
327  if ( $this->fld_comment || $this->fld_parsedcomment ) {
328  $revDel = $this->checkRevDel( $revision, RevisionRecord::DELETED_COMMENT );
329  if ( ( $revDel & self::IS_DELETED ) ) {
330  $vals['commenthidden'] = true;
331  $anyHidden = true;
332  }
333  if ( !( $revDel & self::CANNOT_VIEW ) ) {
334  $comment = $revision->getComment( RevisionRecord::RAW );
335  $comment = $comment ? $comment->text : '';
336 
337  if ( $this->fld_comment ) {
338  $vals['comment'] = $comment;
339  }
340 
341  if ( $this->fld_parsedcomment ) {
342  $vals['parsedcomment'] = Linker::formatComment(
343  $comment, Title::newFromLinkTarget( $revision->getPageAsLinkTarget() )
344  );
345  }
346  }
347  }
348 
349  if ( $this->fld_tags ) {
350  if ( $row->ts_tags ) {
351  $tags = explode( ',', $row->ts_tags );
352  ApiResult::setIndexedTagName( $tags, 'tag' );
353  $vals['tags'] = $tags;
354  } else {
355  $vals['tags'] = [];
356  }
357  }
358 
359  if ( $anyHidden && $revision->isDeleted( RevisionRecord::DELETED_RESTRICTED ) ) {
360  $vals['suppressed'] = true;
361  }
362 
363  return $vals;
364  }
365 
375  private function extractAllSlotInfo( RevisionRecord $revision, $revDel ): array {
376  $vals = [];
377 
378  if ( $this->slotRoles === null ) {
379  try {
380  $slot = $revision->getSlot( SlotRecord::MAIN, RevisionRecord::RAW );
381  } catch ( RevisionAccessException $e ) {
382  // Back compat: If there's no slot, there's no content, so set 'textmissing'
383  // @todo: Gergő says to mention T198099 as a "todo" here.
384  $vals['textmissing'] = true;
385  $slot = null;
386  }
387 
388  if ( $slot ) {
389  $content = null;
390  $vals += $this->extractSlotInfo( $slot, $revDel, $content );
391  if ( !empty( $vals['nosuchsection'] ) ) {
392  $this->dieWithError(
393  [
394  'apierror-nosuchsection-what',
395  wfEscapeWikiText( $this->section ),
396  $this->msg( 'revid', $revision->getId() )
397  ],
398  'nosuchsection'
399  );
400  }
401  if ( $content ) {
402  $vals += $this->extractDeprecatedContent( $content, $revision );
403  }
404  }
405  } else {
406  $roles = array_intersect( $this->slotRoles, $revision->getSlotRoles() );
407  $vals['slots'] = [
409  ];
410  foreach ( $roles as $role ) {
411  try {
412  $slot = $revision->getSlot( $role, RevisionRecord::RAW );
413  } catch ( RevisionAccessException $e ) {
414  // Don't error out here so the client can still process other slots/revisions.
415  // @todo: Gergő says to mention T198099 as a "todo" here.
416  $vals['slots'][$role]['missing'] = true;
417  continue;
418  }
419  $content = null;
420  $vals['slots'][$role] = $this->extractSlotInfo( $slot, $revDel, $content );
421  // @todo Move this into extractSlotInfo() (and remove its $content parameter)
422  // when extractDeprecatedContent() is no more.
423  if ( $content ) {
425  $vals['slots'][$role]['contentmodel'] = $content->getModel();
426  $vals['slots'][$role]['contentformat'] = $content->getDefaultFormat();
428  $vals['slots'][$role],
429  'content',
430  $content->serialize()
431  );
432  }
433  }
434  ApiResult::setArrayType( $vals['slots'], 'kvp', 'role' );
435  ApiResult::setIndexedTagName( $vals['slots'], 'slot' );
436  }
437  return $vals;
438  }
439 
449  private function extractSlotInfo( SlotRecord $slot, $revDel, &$content = null ) {
450  $vals = [];
451  ApiResult::setArrayType( $vals, 'assoc' );
452 
453  if ( $this->fld_slotsize ) {
454  $vals['size'] = (int)$slot->getSize();
455  }
456 
457  if ( $this->fld_slotsha1 ) {
458  if ( ( $revDel & self::IS_DELETED ) ) {
459  $vals['sha1hidden'] = true;
460  }
461  if ( !( $revDel & self::CANNOT_VIEW ) ) {
462  if ( $slot->getSha1() != '' ) {
463  $vals['sha1'] = Wikimedia\base_convert( $slot->getSha1(), 36, 16, 40 );
464  } else {
465  $vals['sha1'] = '';
466  }
467  }
468  }
469 
470  if ( $this->fld_contentmodel ) {
471  $vals['contentmodel'] = $slot->getModel();
472  }
473 
474  $content = null;
475  if ( $this->fetchContent ) {
476  if ( ( $revDel & self::IS_DELETED ) ) {
477  $vals['texthidden'] = true;
478  }
479  if ( !( $revDel & self::CANNOT_VIEW ) ) {
480  try {
481  $content = $slot->getContent();
482  } catch ( RevisionAccessException $e ) {
483  // @todo: Gergő says to mention T198099 as a "todo" here.
484  $vals['textmissing'] = true;
485  }
486  // Expand templates after getting section content because
487  // template-added sections don't count and Parser::preprocess()
488  // will have less input
489  if ( $content && $this->section !== false ) {
490  $content = $content->getSection( $this->section );
491  if ( !$content ) {
492  $vals['nosuchsection'] = true;
493  }
494  }
495  }
496  }
497 
498  return $vals;
499  }
500 
507  private function extractDeprecatedContent( Content $content, RevisionRecord $revision ) {
508  $vals = [];
510 
511  if ( $this->fld_parsetree || ( $this->fld_content && $this->generateXML ) ) {
512  if ( $content->getModel() === CONTENT_MODEL_WIKITEXT ) {
514  '@phan-var WikitextContent $content';
515  $t = $content->getText(); # note: don't set $text
516 
517  $parser = MediaWikiServices::getInstance()->getParser();
518  $parser->startExternalParse(
519  $title,
520  ParserOptions::newFromContext( $this->getContext() ),
521  Parser::OT_PREPROCESS
522  );
523  $dom = $parser->preprocessToDom( $t );
524  if ( is_callable( [ $dom, 'saveXML' ] ) ) {
525  // @phan-suppress-next-line PhanUndeclaredMethod
526  $xml = $dom->saveXML();
527  } else {
528  // @phan-suppress-next-line PhanUndeclaredMethod
529  $xml = $dom->__toString();
530  }
531  $vals['parsetree'] = $xml;
532  } else {
533  $vals['badcontentformatforparsetree'] = true;
534  $this->addWarning(
535  [
536  'apierror-parsetree-notwikitext-title',
537  wfEscapeWikiText( $title->getPrefixedText() ),
538  $content->getModel()
539  ],
540  'parsetree-notwikitext'
541  );
542  }
543  }
544 
545  if ( $this->fld_content ) {
546  $text = null;
547 
548  if ( $this->expandTemplates && !$this->parseContent ) {
549  if ( $content->getModel() === CONTENT_MODEL_WIKITEXT ) {
551  '@phan-var WikitextContent $content';
552  $text = $content->getText();
553 
554  $text = MediaWikiServices::getInstance()->getParser()->preprocess(
555  $text,
556  $title,
557  ParserOptions::newFromContext( $this->getContext() )
558  );
559  } else {
560  $this->addWarning( [
561  'apierror-templateexpansion-notwikitext',
562  wfEscapeWikiText( $title->getPrefixedText() ),
563  $content->getModel()
564  ] );
565  $vals['badcontentformat'] = true;
566  $text = false;
567  }
568  }
569  if ( $this->parseContent ) {
570  $po = $content->getParserOutput(
571  $title,
572  $revision->getId(),
573  ParserOptions::newFromContext( $this->getContext() )
574  );
575  $text = $po->getText();
576  }
577 
578  if ( $text === null ) {
579  $format = $this->contentFormat ?: $content->getDefaultFormat();
580  $model = $content->getModel();
581 
582  if ( !$content->isSupportedFormat( $format ) ) {
583  $name = wfEscapeWikiText( $title->getPrefixedText() );
584  $this->addWarning( [ 'apierror-badformat', $this->contentFormat, $model, $name ] );
585  $vals['badcontentformat'] = true;
586  $text = false;
587  } else {
588  $text = $content->serialize( $format );
589  // always include format and model.
590  // Format is needed to deserialize, model is needed to interpret.
591  $vals['contentformat'] = $format;
592  $vals['contentmodel'] = $model;
593  }
594  }
595 
596  if ( $text !== false ) {
597  ApiResult::setContentValue( $vals, 'content', $text );
598  }
599  }
600 
601  if ( $content && ( $this->diffto !== null || $this->difftotext !== null ) ) {
602  static $n = 0; // Number of uncached diffs we've had
603 
604  if ( $n < $this->getConfig()->get( 'APIMaxUncachedDiffs' ) ) {
605  $vals['diff'] = [];
606  $context = new DerivativeContext( $this->getContext() );
607  $context->setTitle( $title );
608  $handler = $content->getContentHandler();
609 
610  if ( $this->difftotext !== null ) {
611  $model = $title->getContentModel();
612 
613  if ( $this->contentFormat
614  && !$this->getContentHandlerFactory()
615  ->getContentHandler( $model )
616  ->isSupportedFormat( $this->contentFormat )
617  ) {
618  $name = wfEscapeWikiText( $title->getPrefixedText() );
619  $this->addWarning( [ 'apierror-badformat', $this->contentFormat, $model, $name ] );
620  $vals['diff']['badcontentformat'] = true;
621  $engine = null;
622  } else {
623  $difftocontent = ContentHandler::makeContent(
624  $this->difftotext,
625  $title,
626  $model,
627  $this->contentFormat
628  );
629 
630  if ( $this->difftotextpst ) {
631  $popts = ParserOptions::newFromContext( $this->getContext() );
632  $difftocontent = $difftocontent->preSaveTransform( $title, $this->getUser(), $popts );
633  }
634 
635  $engine = $handler->createDifferenceEngine( $context );
636  $engine->setContent( $content, $difftocontent );
637  }
638  } else {
639  $engine = $handler->createDifferenceEngine( $context, $revision->getId(), $this->diffto );
640  $vals['diff']['from'] = $engine->getOldid();
641  $vals['diff']['to'] = $engine->getNewid();
642  }
643  if ( $engine ) {
644  $difftext = $engine->getDiffBody();
645  ApiResult::setContentValue( $vals['diff'], 'body', $difftext );
646  if ( !$engine->wasCacheHit() ) {
647  $n++;
648  }
649  }
650  } else {
651  $vals['diff']['notcached'] = true;
652  }
653  }
654 
655  return $vals;
656  }
657 
664  public function getCacheMode( $params ) {
665  if ( $this->userCanSeeRevDel() ) {
666  return 'private';
667  }
668 
669  return 'public';
670  }
671 
677  public function getAllowedParams() {
678  $slotRoles = MediaWikiServices::getInstance()->getSlotRoleRegistry()->getKnownRoles();
679  sort( $slotRoles, SORT_STRING );
680 
681  return [
682  'prop' => [
683  ApiBase::PARAM_ISMULTI => true,
684  ApiBase::PARAM_DFLT => 'ids|timestamp|flags|comment|user',
686  'ids',
687  'flags',
688  'timestamp',
689  'user',
690  'userid',
691  'size',
692  'slotsize',
693  'sha1',
694  'slotsha1',
695  'contentmodel',
696  'comment',
697  'parsedcomment',
698  'content',
699  'tags',
700  'roles',
701  'parsetree',
702  ],
703  ApiBase::PARAM_HELP_MSG => 'apihelp-query+revisions+base-param-prop',
705  'ids' => 'apihelp-query+revisions+base-paramvalue-prop-ids',
706  'flags' => 'apihelp-query+revisions+base-paramvalue-prop-flags',
707  'timestamp' => 'apihelp-query+revisions+base-paramvalue-prop-timestamp',
708  'user' => 'apihelp-query+revisions+base-paramvalue-prop-user',
709  'userid' => 'apihelp-query+revisions+base-paramvalue-prop-userid',
710  'size' => 'apihelp-query+revisions+base-paramvalue-prop-size',
711  'slotsize' => 'apihelp-query+revisions+base-paramvalue-prop-slotsize',
712  'sha1' => 'apihelp-query+revisions+base-paramvalue-prop-sha1',
713  'slotsha1' => 'apihelp-query+revisions+base-paramvalue-prop-slotsha1',
714  'contentmodel' => 'apihelp-query+revisions+base-paramvalue-prop-contentmodel',
715  'comment' => 'apihelp-query+revisions+base-paramvalue-prop-comment',
716  'parsedcomment' => 'apihelp-query+revisions+base-paramvalue-prop-parsedcomment',
717  'content' => 'apihelp-query+revisions+base-paramvalue-prop-content',
718  'tags' => 'apihelp-query+revisions+base-paramvalue-prop-tags',
719  'roles' => 'apihelp-query+revisions+base-paramvalue-prop-roles',
720  'parsetree' => [ 'apihelp-query+revisions+base-paramvalue-prop-parsetree',
722  ],
724  'parsetree' => true,
725  ],
726  ],
727  'slots' => [
729  ApiBase::PARAM_HELP_MSG => 'apihelp-query+revisions+base-param-slots',
730  ApiBase::PARAM_ISMULTI => true,
731  ApiBase::PARAM_ALL => true,
732  ],
733  'limit' => [
734  ApiBase::PARAM_TYPE => 'limit',
735  ApiBase::PARAM_MIN => 1,
738  ApiBase::PARAM_HELP_MSG => 'apihelp-query+revisions+base-param-limit',
739  ],
740  'expandtemplates' => [
741  ApiBase::PARAM_DFLT => false,
742  ApiBase::PARAM_HELP_MSG => 'apihelp-query+revisions+base-param-expandtemplates',
744  ],
745  'generatexml' => [
746  ApiBase::PARAM_DFLT => false,
748  ApiBase::PARAM_HELP_MSG => 'apihelp-query+revisions+base-param-generatexml',
749  ],
750  'parse' => [
751  ApiBase::PARAM_DFLT => false,
752  ApiBase::PARAM_HELP_MSG => 'apihelp-query+revisions+base-param-parse',
754  ],
755  'section' => [
756  ApiBase::PARAM_HELP_MSG => 'apihelp-query+revisions+base-param-section',
757  ],
758  'diffto' => [
759  ApiBase::PARAM_HELP_MSG => 'apihelp-query+revisions+base-param-diffto',
761  ],
762  'difftotext' => [
763  ApiBase::PARAM_HELP_MSG => 'apihelp-query+revisions+base-param-difftotext',
765  ],
766  'difftotextpst' => [
767  ApiBase::PARAM_DFLT => false,
768  ApiBase::PARAM_HELP_MSG => 'apihelp-query+revisions+base-param-difftotextpst',
770  ],
771  'contentformat' => [
772  ApiBase::PARAM_TYPE => $this->getContentHandlerFactory()->getAllContentFormats(),
773  ApiBase::PARAM_HELP_MSG => 'apihelp-query+revisions+base-param-contentformat',
775  ],
776  ];
777  }
778 
780  return MediaWikiServices::getInstance()->getContentHandlerFactory();
781  }
782 }
ApiQueryRevisionsBase\parseParameters
parseParameters( $params)
Parse the parameters into the various instance fields.
Definition: ApiQueryRevisionsBase.php:80
ContextSource\$context
IContextSource $context
Definition: ContextSource.php:38
ContextSource\getConfig
getConfig()
Definition: ContextSource.php:71
Revision\RevisionAccessException
Exception representing a failure to look up a revision.
Definition: RevisionAccessException.php:34
ContextSource\getContext
getContext()
Get the base IContextSource object.
Definition: ContextSource.php:46
Revision\RevisionRecord
Page revision base class.
Definition: RevisionRecord.php:45
ApiBase\addWarning
addWarning( $msg, $code=null, $data=null)
Add a warning for this module.
Definition: ApiBase.php:1289
ApiQueryRevisionsBase\$fld_slotsize
$fld_slotsize
Stable to override.
Definition: ApiQueryRevisionsBase.php:56
Revision\SlotRecord\getContent
getContent()
Returns the Content of the given slot.
Definition: SlotRecord.php:295
ApiQueryGeneratorBase\encodeParamName
encodeParamName( $paramName)
Overrides ApiBase to prepend 'g' to every generator parameter.
Definition: ApiQueryGeneratorBase.php:70
ApiQueryRevisionsBase\$fld_comment
$fld_comment
Stable to override.
Definition: ApiQueryRevisionsBase.php:57
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:166
Revision\RevisionRecord\isDeleted
isDeleted( $field)
MCR migration note: this replaces Revision::isDeleted.
Definition: RevisionRecord.php:417
ApiQueryBase\getParent
getParent()
Get the parent of this module Stable to override.1.25 ApiBase|null
Definition: ApiQueryBase.php:108
ApiBase\dieWithError
dieWithError( $msg, $code=null, $data=null, $httpCode=null)
Abort execution with an error.
Definition: ApiBase.php:1370
ApiBase\PARAM_HELP_MSG
const PARAM_HELP_MSG
(string|array|Message) Specify an alternative i18n documentation message for this parameter.
Definition: ApiBase.php:102
ApiBase\PARAM_ALL
const PARAM_ALL
Definition: ApiBase.php:78
ApiQueryRevisionsBase\$fld_roles
$fld_roles
Stable to override.
Definition: ApiQueryRevisionsBase.php:58
ApiQueryRevisionsBase\$section
$section
Stable to override.
Definition: ApiQueryRevisionsBase.php:52
wfTimestamp
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
Definition: GlobalFunctions.php:1831
ApiQueryRevisionsBase\CANNOT_VIEW
const CANNOT_VIEW
Stable to override.
Definition: ApiQueryRevisionsBase.php:47
ApiQueryRevisionsBase\extractAllSlotInfo
extractAllSlotInfo(RevisionRecord $revision, $revDel)
Extracts information about all relevant slots.
Definition: ApiQueryRevisionsBase.php:375
ApiBase\PARAM_TYPE
const PARAM_TYPE
Definition: ApiBase.php:69
Revision\RevisionRecord\audienceCan
audienceCan( $field, $audience, Authority $performer=null)
Check that the given audience has access to the given field.
Definition: RevisionRecord.php:459
ApiBase\getResult
getResult()
Get the result object.
Definition: ApiBase.php:558
ApiQueryRevisionsBase\$fld_userid
$fld_userid
Stable to override.
Definition: ApiQueryRevisionsBase.php:57
Revision\RevisionRecord\getTimestamp
getTimestamp()
MCR migration note: this replaces Revision::getTimestamp.
Definition: RevisionRecord.php:439
ApiQueryRevisionsBase\$fld_sha1
$fld_sha1
Stable to override.
Definition: ApiQueryRevisionsBase.php:56
ApiQueryRevisionsBase\$fetchContent
$fetchContent
Stable to override.
Definition: ApiQueryRevisionsBase.php:52
ApiQueryRevisionsBase\$setParsedLimit
$setParsedLimit
Stable to override.
Definition: ApiQueryRevisionsBase.php:52
ApiQueryRevisionsBase\$slotRoles
$slotRoles
Stable to override.
Definition: ApiQueryRevisionsBase.php:53
ContextSource\getUser
getUser()
Stable to override.
Definition: ContextSource.php:135
ApiBase\PARAM_DEPRECATED_VALUES
const PARAM_DEPRECATED_VALUES
Definition: ApiBase.php:81
ApiQueryRevisionsBase\$difftotextpst
$difftotextpst
Stable to override.
Definition: ApiQueryRevisionsBase.php:51
ApiPageSet
This class contains a list of pages that the client has requested.
Definition: ApiPageSet.php:42
ApiQueryRevisionsBase\$limit
$limit
Stable to override.
Definition: ApiQueryRevisionsBase.php:51
ApiQueryRevisionsBase\$fld_content
$fld_content
Stable to override.
Definition: ApiQueryRevisionsBase.php:58
Revision\RevisionRecord\getUser
getUser( $audience=self::FOR_PUBLIC, Authority $performer=null)
Fetch revision's author's user identity, if it's available to the specified audience.
Definition: RevisionRecord.php:369
ApiResult\setContentValue
static setContentValue(array &$arr, $name, $value, $flags=0)
Add an output value to the array by name and mark as META_CONTENT.
Definition: ApiResult.php:464
ApiQueryRevisionsBase\$fld_contentmodel
$fld_contentmodel
Stable to override.
Definition: ApiQueryRevisionsBase.php:58
ApiQueryRevisionsBase
A base class for functions common to producing a list of revisions.
Definition: ApiQueryRevisionsBase.php:39
ApiQueryRevisionsBase\$fld_slotsha1
$fld_slotsha1
Stable to override.
Definition: ApiQueryRevisionsBase.php:56
ApiBase\PARAM_DEPRECATED
const PARAM_DEPRECATED
Definition: ApiBase.php:74
ApiBase\PARAM_MIN
const PARAM_MIN
Definition: ApiBase.php:72
DerivativeContext
An IContextSource implementation which will inherit context from another source but allow individual ...
Definition: DerivativeContext.php:32
ApiQueryRevisionsBase\$expandTemplates
$expandTemplates
Stable to override.
Definition: ApiQueryRevisionsBase.php:51
ApiQueryRevisionsBase\getContentHandlerFactory
getContentHandlerFactory()
Stable to override.
Definition: ApiQueryRevisionsBase.php:779
ApiResult\setArrayType
static setArrayType(array &$arr, $type, $kvpKeyName=null)
Set the array data type.
Definition: ApiResult.php:713
Revision\RevisionRecord\getSize
getSize()
Returns the nominal size of this revision, in bogo-bytes.
ApiQueryRevisionsBase\$contentFormat
$contentFormat
Stable to override.
Definition: ApiQueryRevisionsBase.php:52
Revision\RevisionRecord\getSha1
getSha1()
Returns the base36 sha1 of this revision.
MediaWiki\Logger\LoggerFactory
PSR-3 logger instance factory.
Definition: LoggerFactory.php:45
ApiBase\LIMIT_BIG1
const LIMIT_BIG1
Fast query, standard limit.
Definition: ApiBase.php:160
ApiQueryRevisionsBase\getAllowedParams
getAllowedParams()
Stable to override.
Definition: ApiQueryRevisionsBase.php:677
Revision\RevisionRecord\isMinor
isMinor()
MCR migration note: this replaces Revision::isMinor.
Definition: RevisionRecord.php:406
ApiBase\PARAM_MAX
const PARAM_MAX
Definition: ApiBase.php:70
Revision\SlotRecord\getModel
getModel()
Returns the content model.
Definition: SlotRecord.php:559
$title
$title
Definition: testCompression.php:38
ApiQueryRevisionsBase\$diffto
$diffto
Stable to override.
Definition: ApiQueryRevisionsBase.php:51
Revision\RevisionRecord\getSlotRoles
getSlotRoles()
Returns the slot names (roles) of all slots present in this revision.
Definition: RevisionRecord.php:203
WikitextContent
Content object for wiki text pages.
Definition: WikitextContent.php:37
ApiQueryRevisionsBase\$fld_parsetree
$fld_parsetree
Stable to override.
Definition: ApiQueryRevisionsBase.php:59
ApiQueryRevisionsBase\execute
execute()
Stable to override.
Definition: ApiQueryRevisionsBase.php:61
ApiQueryRevisionsBase\IS_DELETED
const IS_DELETED
Stable to override.
Definition: ApiQueryRevisionsBase.php:46
ApiQueryRevisionsBase\$fld_tags
$fld_tags
Stable to override.
Definition: ApiQueryRevisionsBase.php:58
ApiQueryRevisionsBase\$needSlots
$needSlots
Stable to override.
Definition: ApiQueryRevisionsBase.php:53
ContentHandler\makeContent
static makeContent( $text, Title $title=null, $modelId=null, $format=null)
Convenience function for creating a Content object from a given textual representation.
Definition: ContentHandler.php:142
Revision\SlotRecord\getSha1
getSha1()
Returns the content size.
Definition: SlotRecord.php:531
ApiQueryRevisionsBase\checkRevDel
checkRevDel(RevisionRecord $revision, $field)
Test revision deletion status.
Definition: ApiQueryRevisionsBase.php:219
ApiBase\getModulePrefix
getModulePrefix()
Get parameter prefix (usually two letters or an empty string).
Definition: ApiBase.php:445
Revision\RevisionRecord\getId
getId()
Get revision ID.
Definition: RevisionRecord.php:264
ContextSource\msg
msg( $key,... $params)
Get a Message object with context set Parameters are the same as wfMessage()
Definition: ContextSource.php:195
Revision\RevisionRecord\getParentId
getParentId()
Get parent revision ID (the original previous page revision).
Definition: RevisionRecord.php:280
ApiResult\setIndexedTagName
static setIndexedTagName(array &$arr, $tag)
Set the tag name for numeric-keyed values in XML format.
Definition: ApiResult.php:601
$content
$content
Definition: router.php:76
Revision\SlotRecord\getSize
getSize()
Returns the content size.
Definition: SlotRecord.php:515
ApiQueryRevisionsBase\$parseContent
$parseContent
Stable to override.
Definition: ApiQueryRevisionsBase.php:52
ParserOptions\newFromContext
static newFromContext(IContextSource $context)
Get a ParserOptions object from a IContextSource object.
Definition: ParserOptions.php:1111
ApiBase\addDeprecation
addDeprecation( $msg, $feature, $data=[])
Add a deprecation warning for this module.
Definition: ApiBase.php:1303
MediaWiki\Content\IContentHandlerFactory
Definition: IContentHandlerFactory.php:10
ApiBase\LIMIT_SML2
const LIMIT_SML2
Slow query, apihighlimits limit.
Definition: ApiBase.php:166
ApiQueryRevisionsBase\extractRevisionInfo
extractRevisionInfo(RevisionRecord $revision, $row)
Extract information from the RevisionRecord.
Definition: ApiQueryRevisionsBase.php:236
wfEscapeWikiText
wfEscapeWikiText( $text)
Escapes the given text so that it may be output using addWikiText() without any linking,...
Definition: GlobalFunctions.php:1504
CONTENT_MODEL_WIKITEXT
const CONTENT_MODEL_WIKITEXT
Definition: Defines.php:218
ApiQueryRevisionsBase\getCacheMode
getCacheMode( $params)
Stable to override.
Definition: ApiQueryRevisionsBase.php:664
ApiQueryRevisionsBase\$fld_flags
$fld_flags
Stable to override.
Definition: ApiQueryRevisionsBase.php:55
Title\newFromLinkTarget
static newFromLinkTarget(LinkTarget $linkTarget, $forceClone='')
Returns a Title given a LinkTarget.
Definition: Title.php:289
Linker\formatComment
static formatComment( $comment, $title=null, $local=false, $wikiId=null)
This function is called by all recent changes variants, by the page history, and by the user contribu...
Definition: Linker.php:1198
Content
Base interface for content objects.
Definition: Content.php:35
ApiQueryRevisionsBase\$difftotext
$difftotext
Stable to override.
Definition: ApiQueryRevisionsBase.php:51
ApiQueryGeneratorBase
Stable to extend.
Definition: ApiQueryGeneratorBase.php:28
ApiQueryRevisionsBase\$fld_ids
$fld_ids
Stable to override.
Definition: ApiQueryRevisionsBase.php:55
Revision\RevisionRecord\getPageAsLinkTarget
getPageAsLinkTarget()
Returns the title of the page this revision is associated with as a LinkTarget object.
Definition: RevisionRecord.php:335
Wikimedia\ParamValidator\TypeDef\IntegerDef
Type definition for integer types.
Definition: IntegerDef.php:23
ApiBase\LIMIT_BIG2
const LIMIT_BIG2
Fast query, apihighlimits limit.
Definition: ApiBase.php:162
ApiBase\PARAM_DFLT
const PARAM_DFLT
Definition: ApiBase.php:67
ApiBase\getModuleName
getModuleName()
Get the name of the module being executed by this instance.
Definition: ApiBase.php:437
ApiQueryRevisionsBase\$fld_user
$fld_user
Stable to override.
Definition: ApiQueryRevisionsBase.php:57
ApiBase\PARAM_ISMULTI
const PARAM_ISMULTI
Definition: ApiBase.php:68
Revision\RevisionRecord\getComment
getComment( $audience=self::FOR_PUBLIC, Authority $performer=null)
Fetch revision comment, if it's available to the specified audience.
Definition: RevisionRecord.php:393
ApiQueryRevisionsBase\$fld_timestamp
$fld_timestamp
Stable to override.
Definition: ApiQueryRevisionsBase.php:55
ApiBase\PARAM_MAX2
const PARAM_MAX2
Definition: ApiBase.php:71
ApiBase\getMain
getMain()
Get the main module.
Definition: ApiBase.php:453
ApiResult\META_KVP_MERGE
const META_KVP_MERGE
Key for the metadata item that indicates that the KVP key should be added into an assoc value,...
Definition: ApiResult.php:129
ApiQueryRevisionsBase\executeGenerator
executeGenerator( $resultPageSet)
Stable to override.
Definition: ApiQueryRevisionsBase.php:65
$t
$t
Definition: testCompression.php:74
ApiQueryRevisionsBase\$fld_parsedcomment
$fld_parsedcomment
Stable to override.
Definition: ApiQueryRevisionsBase.php:57
ApiQueryRevisionsBase\run
run(ApiPageSet $resultPageSet=null)
ApiBase\PARAM_HELP_MSG_PER_VALUE
const PARAM_HELP_MSG_PER_VALUE
((string|array|Message)[]) When PARAM_TYPE is an array, this is an array mapping those values to $msg...
Definition: ApiBase.php:135
ApiQueryBase\userCanSeeRevDel
userCanSeeRevDel()
Check whether the current user has permission to view revision-deleted fields.
Definition: ApiQueryBase.php:607
ApiQueryRevisionsBase\$fld_size
$fld_size
Stable to override.
Definition: ApiQueryRevisionsBase.php:56
Wikimedia\ParamValidator\ParamValidator
Service for formatting and validating API parameters.
Definition: ParamValidator.php:42
ApiQueryRevisionsBase\extractDeprecatedContent
extractDeprecatedContent(Content $content, RevisionRecord $revision)
Format a Content using deprecated options.
Definition: ApiQueryRevisionsBase.php:507
ApiQueryRevisionsBase\extractSlotInfo
extractSlotInfo(SlotRecord $slot, $revDel, &$content=null)
Extract information from the SlotRecord.
Definition: ApiQueryRevisionsBase.php:449
Revision\SlotRecord
Value object representing a content slot associated with a page revision.
Definition: SlotRecord.php:40
ApiBase\LIMIT_SML1
const LIMIT_SML1
Slow query, standard limit.
Definition: ApiBase.php:164
ApiQueryRevisionsBase\$generateXML
$generateXML
Stable to override.
Definition: ApiQueryRevisionsBase.php:51
Revision\RevisionRecord\getSlot
getSlot( $role, $audience=self::FOR_PUBLIC, Authority $performer=null)
Returns meta-data for the given slot.
Definition: RevisionRecord.php:176