MediaWiki  master
ApiQueryRevisionsBase.php
Go to the documentation of this file.
1 <?php
34 
43 
44  // region Constants for internal use. Don't use externally.
47  // Bits to indicate the results of the revdel permission check on a revision,
48  // see self::checkRevDel()
49  private const IS_DELETED = 1; // Whether the field is revision-deleted
50  private const CANNOT_VIEW = 2; // Whether the user cannot view the field due to revdel
51 
52  // endregion
53 
57 
58  protected $fld_ids = false, $fld_flags = false, $fld_timestamp = false,
59  $fld_size = false, $fld_slotsize = false, $fld_sha1 = false, $fld_slotsha1 = false,
60  $fld_comment = false, $fld_parsedcomment = false, $fld_user = false, $fld_userid = false,
61  $fld_content = false, $fld_tags = false, $fld_contentmodel = false, $fld_roles = false,
62  $fld_parsetree = false;
63 
65  private $revisionStore;
66 
69 
71  private $parserFactory;
72 
75 
78 
91  public function __construct(
92  ApiQuery $queryModule,
93  $moduleName,
94  $paramPrefix = '',
100  ) {
101  parent::__construct( $queryModule, $moduleName, $paramPrefix );
102  // This class is part of the stable interface and
103  // therefor fallback to global state, if services are not provided
104  $services = MediaWikiServices::getInstance();
105  $this->revisionStore = $revisionStore ?? $services->getRevisionStore();
106  $this->contentHandlerFactory = $contentHandlerFactory ?? $services->getContentHandlerFactory();
107  $this->parserFactory = $parserFactory ?? $services->getParserFactory();
108  $this->slotRoleRegistry = $slotRoleRegistry ?? $services->getSlotRoleRegistry();
109  $this->contentTransformer = $contentTransformer ?? $services->getContentTransformer();
110  }
111 
112  public function execute() {
113  $this->run();
114  }
115 
116  public function executeGenerator( $resultPageSet ) {
117  $this->run( $resultPageSet );
118  }
119 
124  abstract protected function run( ApiPageSet $resultPageSet = null );
125 
131  protected function parseParameters( $params ) {
132  $prop = array_fill_keys( $params['prop'], true );
133 
134  $this->fld_ids = isset( $prop['ids'] );
135  $this->fld_flags = isset( $prop['flags'] );
136  $this->fld_timestamp = isset( $prop['timestamp'] );
137  $this->fld_comment = isset( $prop['comment'] );
138  $this->fld_parsedcomment = isset( $prop['parsedcomment'] );
139  $this->fld_size = isset( $prop['size'] );
140  $this->fld_slotsize = isset( $prop['slotsize'] );
141  $this->fld_sha1 = isset( $prop['sha1'] );
142  $this->fld_slotsha1 = isset( $prop['slotsha1'] );
143  $this->fld_content = isset( $prop['content'] );
144  $this->fld_contentmodel = isset( $prop['contentmodel'] );
145  $this->fld_userid = isset( $prop['userid'] );
146  $this->fld_user = isset( $prop['user'] );
147  $this->fld_tags = isset( $prop['tags'] );
148  $this->fld_roles = isset( $prop['roles'] );
149  $this->fld_parsetree = isset( $prop['parsetree'] );
150 
151  $this->slotRoles = $params['slots'];
152 
153  if ( $this->slotRoles !== null ) {
154  if ( $this->fld_parsetree ) {
155  $this->dieWithError( [
156  'apierror-invalidparammix-cannotusewith',
157  $this->encodeParamName( 'prop=parsetree' ),
158  $this->encodeParamName( 'slots' ),
159  ], 'invalidparammix' );
160  }
161  foreach ( [
162  'expandtemplates', 'generatexml', 'parse', 'diffto', 'difftotext', 'difftotextpst',
163  'contentformat'
164  ] as $p ) {
165  if ( $params[$p] !== null && $params[$p] !== false ) {
166  $this->dieWithError( [
167  'apierror-invalidparammix-cannotusewith',
168  $this->encodeParamName( $p ),
169  $this->encodeParamName( 'slots' ),
170  ], 'invalidparammix' );
171  }
172  }
173  }
174 
175  if ( !empty( $params['contentformat'] ) ) {
176  $this->contentFormat = $params['contentformat'];
177  }
178 
179  $this->limit = $params['limit'];
180 
181  if ( $params['difftotext'] !== null ) {
182  $this->difftotext = $params['difftotext'];
183  $this->difftotextpst = $params['difftotextpst'];
184  } elseif ( $params['diffto'] !== null ) {
185  if ( $params['diffto'] == 'cur' ) {
186  $params['diffto'] = 0;
187  }
188  if ( ( !ctype_digit( $params['diffto'] ) || $params['diffto'] < 0 )
189  && $params['diffto'] != 'prev' && $params['diffto'] != 'next'
190  ) {
191  $p = $this->getModulePrefix();
192  $this->dieWithError( [ 'apierror-baddiffto', $p ], 'diffto' );
193  }
194  // Check whether the revision exists and is readable,
195  // DifferenceEngine returns a rather ambiguous empty
196  // string if that's not the case
197  if ( $params['diffto'] != 0 ) {
198  $difftoRev = $this->revisionStore->getRevisionById( $params['diffto'] );
199  if ( !$difftoRev ) {
200  $this->dieWithError( [ 'apierror-nosuchrevid', $params['diffto'] ] );
201  }
202  $revDel = $this->checkRevDel( $difftoRev, RevisionRecord::DELETED_TEXT );
203  if ( $revDel & self::CANNOT_VIEW ) {
204  $this->addWarning( [ 'apiwarn-difftohidden', $difftoRev->getId() ] );
205  $params['diffto'] = null;
206  }
207  }
208  $this->diffto = $params['diffto'];
209  }
210 
211  $this->fetchContent = $this->fld_content || $this->diffto !== null
212  || $this->difftotext !== null || $this->fld_parsetree;
213 
214  $smallLimit = false;
215  if ( $this->fetchContent ) {
216  $smallLimit = true;
217  $this->expandTemplates = $params['expandtemplates'];
218  $this->generateXML = $params['generatexml'];
219  $this->parseContent = $params['parse'];
220  if ( $this->parseContent ) {
221  // Must manually initialize unset limit
222  if ( $this->limit === null ) {
223  $this->limit = 1;
224  }
225  }
226  $this->section = $params['section'] ?? false;
227  }
228 
229  $userMax = $this->parseContent ? 1 : ( $smallLimit ? ApiBase::LIMIT_SML1 : ApiBase::LIMIT_BIG1 );
230  $botMax = $this->parseContent ? 1 : ( $smallLimit ? ApiBase::LIMIT_SML2 : ApiBase::LIMIT_BIG2 );
231  if ( $this->limit == 'max' ) {
232  $this->limit = $this->getMain()->canApiHighLimits() ? $botMax : $userMax;
233  if ( $this->setParsedLimit ) {
234  $this->getResult()->addParsedLimit( $this->getModuleName(), $this->limit );
235  }
236  }
237 
238  $this->limit = $this->getMain()->getParamValidator()->validateValue(
239  $this, 'limit', $this->limit ?? 10, [
240  ParamValidator::PARAM_TYPE => 'limit',
241  IntegerDef::PARAM_MIN => 1,
242  IntegerDef::PARAM_MAX => $userMax,
243  IntegerDef::PARAM_MAX2 => $botMax,
244  IntegerDef::PARAM_IGNORE_RANGE => true,
245  ]
246  );
247 
248  $this->needSlots = $this->fetchContent || $this->fld_contentmodel ||
249  $this->fld_slotsize || $this->fld_slotsha1;
250  if ( $this->needSlots && $this->slotRoles === null ) {
251  $encParam = $this->encodeParamName( 'slots' );
252  $name = $this->getModuleName();
253  $parent = $this->getParent();
254  $parentParam = $parent->encodeParamName( $parent->getModuleManager()->getModuleGroup( $name ) );
255  $this->addDeprecation(
256  [ 'apiwarn-deprecation-missingparam', $encParam ],
257  "action=query&{$parentParam}={$name}&!{$encParam}"
258  );
259  }
260  }
261 
269  private function checkRevDel( RevisionRecord $revision, $field ) {
270  $ret = $revision->isDeleted( $field ) ? self::IS_DELETED : 0;
271  if ( $ret ) {
272  $canSee = $revision->userCan( $field, $this->getAuthority() );
273  $ret |= ( $canSee ? 0 : self::CANNOT_VIEW );
274  }
275  return $ret;
276  }
277 
286  protected function extractRevisionInfo( RevisionRecord $revision, $row ) {
287  $vals = [];
288  $anyHidden = false;
289 
290  if ( $this->fld_ids ) {
291  $vals['revid'] = (int)$revision->getId();
292  if ( $revision->getParentId() !== null ) {
293  $vals['parentid'] = (int)$revision->getParentId();
294  }
295  }
296 
297  if ( $this->fld_flags ) {
298  $vals['minor'] = $revision->isMinor();
299  }
300 
301  if ( $this->fld_user || $this->fld_userid ) {
302  $revDel = $this->checkRevDel( $revision, RevisionRecord::DELETED_USER );
303  if ( $revDel & self::IS_DELETED ) {
304  $vals['userhidden'] = true;
305  $anyHidden = true;
306  }
307  if ( !( $revDel & self::CANNOT_VIEW ) ) {
308  $u = $revision->getUser( RevisionRecord::RAW );
309  if ( $this->fld_user ) {
310  $vals['user'] = $u->getName();
311  }
312  $userid = $u->getId();
313  if ( !$userid ) {
314  $vals['anon'] = true;
315  }
316 
317  if ( $this->fld_userid ) {
318  $vals['userid'] = $userid;
319  }
320  }
321  }
322 
323  if ( $this->fld_timestamp ) {
324  $vals['timestamp'] = wfTimestamp( TS_ISO_8601, $revision->getTimestamp() );
325  }
326 
327  if ( $this->fld_size ) {
328  try {
329  $vals['size'] = (int)$revision->getSize();
330  } catch ( RevisionAccessException $e ) {
331  // Back compat: If there's no size, return 0.
332  // @todo: Gergő says to mention T198099 as a "todo" here.
333  $vals['size'] = 0;
334  }
335  }
336 
337  if ( $this->fld_sha1 ) {
338  $revDel = $this->checkRevDel( $revision, RevisionRecord::DELETED_TEXT );
339  if ( $revDel & self::IS_DELETED ) {
340  $vals['sha1hidden'] = true;
341  $anyHidden = true;
342  }
343  if ( !( $revDel & self::CANNOT_VIEW ) ) {
344  try {
345  $vals['sha1'] = Wikimedia\base_convert( $revision->getSha1(), 36, 16, 40 );
346  } catch ( RevisionAccessException $e ) {
347  // Back compat: If there's no sha1, return empty string.
348  // @todo: Gergő says to mention T198099 as a "todo" here.
349  $vals['sha1'] = '';
350  }
351  }
352  }
353 
354  try {
355  if ( $this->fld_roles ) {
356  $vals['roles'] = $revision->getSlotRoles();
357  }
358 
359  if ( $this->needSlots ) {
360  $revDel = $this->checkRevDel( $revision, RevisionRecord::DELETED_TEXT );
361  if ( ( $this->fld_slotsha1 || $this->fetchContent ) && ( $revDel & self::IS_DELETED ) ) {
362  $anyHidden = true;
363  }
364  $vals = array_merge( $vals, $this->extractAllSlotInfo( $revision, $revDel ) );
365  }
366  } catch ( RevisionAccessException $ex ) {
367  // This is here so T212428 doesn't spam the log.
368  // TODO: find out why T212428 happens in the first place!
369  $vals['slotsmissing'] = true;
370 
371  LoggerFactory::getInstance( 'api-warning' )->error(
372  'Failed to access revision slots',
373  [ 'revision' => $revision->getId(), 'exception' => $ex, ]
374  );
375  }
376 
377  if ( $this->fld_comment || $this->fld_parsedcomment ) {
378  $revDel = $this->checkRevDel( $revision, RevisionRecord::DELETED_COMMENT );
379  if ( $revDel & self::IS_DELETED ) {
380  $vals['commenthidden'] = true;
381  $anyHidden = true;
382  }
383  if ( !( $revDel & self::CANNOT_VIEW ) ) {
384  $comment = $revision->getComment( RevisionRecord::RAW );
385  $comment = $comment ? $comment->text : '';
386 
387  if ( $this->fld_comment ) {
388  $vals['comment'] = $comment;
389  }
390 
391  if ( $this->fld_parsedcomment ) {
392  $vals['parsedcomment'] = Linker::formatComment(
393  $comment, Title::newFromLinkTarget( $revision->getPageAsLinkTarget() )
394  );
395  }
396  }
397  }
398 
399  if ( $this->fld_tags ) {
400  if ( $row->ts_tags ) {
401  $tags = explode( ',', $row->ts_tags );
402  ApiResult::setIndexedTagName( $tags, 'tag' );
403  $vals['tags'] = $tags;
404  } else {
405  $vals['tags'] = [];
406  }
407  }
408 
409  if ( $anyHidden && $revision->isDeleted( RevisionRecord::DELETED_RESTRICTED ) ) {
410  $vals['suppressed'] = true;
411  }
412 
413  return $vals;
414  }
415 
425  private function extractAllSlotInfo( RevisionRecord $revision, $revDel ): array {
426  $vals = [];
427 
428  if ( $this->slotRoles === null ) {
429  try {
430  $slot = $revision->getSlot( SlotRecord::MAIN, RevisionRecord::RAW );
431  } catch ( RevisionAccessException $e ) {
432  // Back compat: If there's no slot, there's no content, so set 'textmissing'
433  // @todo: Gergő says to mention T198099 as a "todo" here.
434  $vals['textmissing'] = true;
435  $slot = null;
436  }
437 
438  if ( $slot ) {
439  $content = null;
440  $vals += $this->extractSlotInfo( $slot, $revDel, $content );
441  if ( !empty( $vals['nosuchsection'] ) ) {
442  $this->dieWithError(
443  [
444  'apierror-nosuchsection-what',
445  wfEscapeWikiText( $this->section ),
446  $this->msg( 'revid', $revision->getId() )
447  ],
448  'nosuchsection'
449  );
450  }
451  if ( $content ) {
452  $vals += $this->extractDeprecatedContent( $content, $revision );
453  }
454  }
455  } else {
456  $roles = array_intersect( $this->slotRoles, $revision->getSlotRoles() );
457  $vals['slots'] = [
459  ];
460  foreach ( $roles as $role ) {
461  try {
462  $slot = $revision->getSlot( $role, RevisionRecord::RAW );
463  } catch ( RevisionAccessException $e ) {
464  // Don't error out here so the client can still process other slots/revisions.
465  // @todo: Gergő says to mention T198099 as a "todo" here.
466  $vals['slots'][$role]['missing'] = true;
467  continue;
468  }
469  $content = null;
470  $vals['slots'][$role] = $this->extractSlotInfo( $slot, $revDel, $content );
471  // @todo Move this into extractSlotInfo() (and remove its $content parameter)
472  // when extractDeprecatedContent() is no more.
473  if ( $content ) {
475  $vals['slots'][$role]['contentmodel'] = $content->getModel();
476  $vals['slots'][$role]['contentformat'] = $content->getDefaultFormat();
478  $vals['slots'][$role],
479  'content',
480  $content->serialize()
481  );
482  }
483  }
484  ApiResult::setArrayType( $vals['slots'], 'kvp', 'role' );
485  ApiResult::setIndexedTagName( $vals['slots'], 'slot' );
486  }
487  return $vals;
488  }
489 
499  private function extractSlotInfo( SlotRecord $slot, $revDel, &$content = null ) {
500  $vals = [];
501  ApiResult::setArrayType( $vals, 'assoc' );
502 
503  if ( $this->fld_slotsize ) {
504  $vals['size'] = (int)$slot->getSize();
505  }
506 
507  if ( $this->fld_slotsha1 ) {
508  if ( $revDel & self::IS_DELETED ) {
509  $vals['sha1hidden'] = true;
510  }
511  if ( !( $revDel & self::CANNOT_VIEW ) ) {
512  if ( $slot->getSha1() != '' ) {
513  $vals['sha1'] = Wikimedia\base_convert( $slot->getSha1(), 36, 16, 40 );
514  } else {
515  $vals['sha1'] = '';
516  }
517  }
518  }
519 
520  if ( $this->fld_contentmodel ) {
521  $vals['contentmodel'] = $slot->getModel();
522  }
523 
524  $content = null;
525  if ( $this->fetchContent ) {
526  if ( $revDel & self::IS_DELETED ) {
527  $vals['texthidden'] = true;
528  }
529  if ( !( $revDel & self::CANNOT_VIEW ) ) {
530  try {
531  $content = $slot->getContent();
532  } catch ( RevisionAccessException $e ) {
533  // @todo: Gergő says to mention T198099 as a "todo" here.
534  $vals['textmissing'] = true;
535  }
536  // Expand templates after getting section content because
537  // template-added sections don't count and Parser::preprocess()
538  // will have less input
539  if ( $content && $this->section !== false ) {
540  $content = $content->getSection( $this->section );
541  if ( !$content ) {
542  $vals['nosuchsection'] = true;
543  }
544  }
545  }
546  }
547 
548  return $vals;
549  }
550 
557  private function extractDeprecatedContent( Content $content, RevisionRecord $revision ) {
558  $vals = [];
560 
561  if ( $this->fld_parsetree || ( $this->fld_content && $this->generateXML ) ) {
562  if ( $content->getModel() === CONTENT_MODEL_WIKITEXT ) {
564  '@phan-var WikitextContent $content';
565  $t = $content->getText(); # note: don't set $text
566 
567  $parser = $this->parserFactory->create();
568  $parser->startExternalParse(
569  $title,
570  ParserOptions::newFromContext( $this->getContext() ),
571  Parser::OT_PREPROCESS
572  );
573  $dom = $parser->preprocessToDom( $t );
574  if ( is_callable( [ $dom, 'saveXML' ] ) ) {
575  // @phan-suppress-next-line PhanUndeclaredMethod
576  $xml = $dom->saveXML();
577  } else {
578  // @phan-suppress-next-line PhanUndeclaredMethod
579  $xml = $dom->__toString();
580  }
581  $vals['parsetree'] = $xml;
582  } else {
583  $vals['badcontentformatforparsetree'] = true;
584  $this->addWarning(
585  [
586  'apierror-parsetree-notwikitext-title',
587  wfEscapeWikiText( $title->getPrefixedText() ),
588  $content->getModel()
589  ],
590  'parsetree-notwikitext'
591  );
592  }
593  }
594 
595  if ( $this->fld_content ) {
596  $text = null;
597 
598  if ( $this->expandTemplates && !$this->parseContent ) {
599  if ( $content->getModel() === CONTENT_MODEL_WIKITEXT ) {
601  '@phan-var WikitextContent $content';
602  $text = $content->getText();
603 
604  $text = $this->parserFactory->create()->preprocess(
605  $text,
606  $title,
607  ParserOptions::newFromContext( $this->getContext() )
608  );
609  } else {
610  $this->addWarning( [
611  'apierror-templateexpansion-notwikitext',
612  wfEscapeWikiText( $title->getPrefixedText() ),
613  $content->getModel()
614  ] );
615  $vals['badcontentformat'] = true;
616  $text = false;
617  }
618  }
619  if ( $this->parseContent ) {
620  $po = $content->getParserOutput(
621  $title,
622  $revision->getId(),
623  ParserOptions::newFromContext( $this->getContext() )
624  );
625  $text = $po->getText();
626  }
627 
628  if ( $text === null ) {
629  $format = $this->contentFormat ?: $content->getDefaultFormat();
630  $model = $content->getModel();
631 
632  if ( !$content->isSupportedFormat( $format ) ) {
633  $name = wfEscapeWikiText( $title->getPrefixedText() );
634  $this->addWarning( [ 'apierror-badformat', $this->contentFormat, $model, $name ] );
635  $vals['badcontentformat'] = true;
636  $text = false;
637  } else {
638  $text = $content->serialize( $format );
639  // always include format and model.
640  // Format is needed to deserialize, model is needed to interpret.
641  $vals['contentformat'] = $format;
642  $vals['contentmodel'] = $model;
643  }
644  }
645 
646  if ( $text !== false ) {
647  ApiResult::setContentValue( $vals, 'content', $text );
648  }
649  }
650 
651  if ( $content && ( $this->diffto !== null || $this->difftotext !== null ) ) {
652  static $n = 0; // Number of uncached diffs we've had
653 
654  if ( $n < $this->getConfig()->get( 'APIMaxUncachedDiffs' ) ) {
655  $vals['diff'] = [];
656  $context = new DerivativeContext( $this->getContext() );
657  $context->setTitle( $title );
658  $handler = $content->getContentHandler();
659 
660  if ( $this->difftotext !== null ) {
661  $model = $title->getContentModel();
662 
663  if ( $this->contentFormat
664  && !$this->contentHandlerFactory->getContentHandler( $model )
665  ->isSupportedFormat( $this->contentFormat )
666  ) {
667  $name = wfEscapeWikiText( $title->getPrefixedText() );
668  $this->addWarning( [ 'apierror-badformat', $this->contentFormat, $model, $name ] );
669  $vals['diff']['badcontentformat'] = true;
670  $engine = null;
671  } else {
672  $difftocontent = ContentHandler::makeContent(
673  $this->difftotext,
674  $title,
675  $model,
676  $this->contentFormat
677  );
678 
679  if ( $this->difftotextpst ) {
680  $popts = ParserOptions::newFromContext( $this->getContext() );
681  $difftocontent = $this->contentTransformer->preSaveTransform(
682  $difftocontent,
683  $title,
684  $this->getUser(),
685  $popts
686  );
687  }
688 
689  $engine = $handler->createDifferenceEngine( $context );
690  $engine->setContent( $content, $difftocontent );
691  }
692  } else {
693  $engine = $handler->createDifferenceEngine( $context, $revision->getId(), $this->diffto );
694  $vals['diff']['from'] = $engine->getOldid();
695  $vals['diff']['to'] = $engine->getNewid();
696  }
697  if ( $engine ) {
698  $difftext = $engine->getDiffBody();
699  ApiResult::setContentValue( $vals['diff'], 'body', $difftext );
700  if ( !$engine->wasCacheHit() ) {
701  $n++;
702  }
703  }
704  } else {
705  $vals['diff']['notcached'] = true;
706  }
707  }
708 
709  return $vals;
710  }
711 
718  public function getCacheMode( $params ) {
719  if ( $this->userCanSeeRevDel() ) {
720  return 'private';
721  }
722 
723  return 'public';
724  }
725 
731  public function getAllowedParams() {
732  $slotRoles = $this->slotRoleRegistry->getKnownRoles();
733  sort( $slotRoles, SORT_STRING );
734 
735  return [
736  'prop' => [
737  ApiBase::PARAM_ISMULTI => true,
738  ApiBase::PARAM_DFLT => 'ids|timestamp|flags|comment|user',
740  'ids',
741  'flags',
742  'timestamp',
743  'user',
744  'userid',
745  'size',
746  'slotsize',
747  'sha1',
748  'slotsha1',
749  'contentmodel',
750  'comment',
751  'parsedcomment',
752  'content',
753  'tags',
754  'roles',
755  'parsetree',
756  ],
757  ApiBase::PARAM_HELP_MSG => 'apihelp-query+revisions+base-param-prop',
759  'ids' => 'apihelp-query+revisions+base-paramvalue-prop-ids',
760  'flags' => 'apihelp-query+revisions+base-paramvalue-prop-flags',
761  'timestamp' => 'apihelp-query+revisions+base-paramvalue-prop-timestamp',
762  'user' => 'apihelp-query+revisions+base-paramvalue-prop-user',
763  'userid' => 'apihelp-query+revisions+base-paramvalue-prop-userid',
764  'size' => 'apihelp-query+revisions+base-paramvalue-prop-size',
765  'slotsize' => 'apihelp-query+revisions+base-paramvalue-prop-slotsize',
766  'sha1' => 'apihelp-query+revisions+base-paramvalue-prop-sha1',
767  'slotsha1' => 'apihelp-query+revisions+base-paramvalue-prop-slotsha1',
768  'contentmodel' => 'apihelp-query+revisions+base-paramvalue-prop-contentmodel',
769  'comment' => 'apihelp-query+revisions+base-paramvalue-prop-comment',
770  'parsedcomment' => 'apihelp-query+revisions+base-paramvalue-prop-parsedcomment',
771  'content' => 'apihelp-query+revisions+base-paramvalue-prop-content',
772  'tags' => 'apihelp-query+revisions+base-paramvalue-prop-tags',
773  'roles' => 'apihelp-query+revisions+base-paramvalue-prop-roles',
774  'parsetree' => [ 'apihelp-query+revisions+base-paramvalue-prop-parsetree',
776  ],
778  'parsetree' => true,
779  ],
780  ],
781  'slots' => [
783  ApiBase::PARAM_HELP_MSG => 'apihelp-query+revisions+base-param-slots',
784  ApiBase::PARAM_ISMULTI => true,
785  ApiBase::PARAM_ALL => true,
786  ],
787  'limit' => [
788  ApiBase::PARAM_TYPE => 'limit',
789  ApiBase::PARAM_MIN => 1,
792  ApiBase::PARAM_HELP_MSG => 'apihelp-query+revisions+base-param-limit',
793  ],
794  'expandtemplates' => [
795  ApiBase::PARAM_DFLT => false,
796  ApiBase::PARAM_HELP_MSG => 'apihelp-query+revisions+base-param-expandtemplates',
798  ],
799  'generatexml' => [
800  ApiBase::PARAM_DFLT => false,
802  ApiBase::PARAM_HELP_MSG => 'apihelp-query+revisions+base-param-generatexml',
803  ],
804  'parse' => [
805  ApiBase::PARAM_DFLT => false,
806  ApiBase::PARAM_HELP_MSG => 'apihelp-query+revisions+base-param-parse',
808  ],
809  'section' => [
810  ApiBase::PARAM_HELP_MSG => 'apihelp-query+revisions+base-param-section',
811  ],
812  'diffto' => [
813  ApiBase::PARAM_HELP_MSG => 'apihelp-query+revisions+base-param-diffto',
815  ],
816  'difftotext' => [
817  ApiBase::PARAM_HELP_MSG => 'apihelp-query+revisions+base-param-difftotext',
819  ],
820  'difftotextpst' => [
821  ApiBase::PARAM_DFLT => false,
822  ApiBase::PARAM_HELP_MSG => 'apihelp-query+revisions+base-param-difftotextpst',
824  ],
825  'contentformat' => [
826  ApiBase::PARAM_TYPE => $this->contentHandlerFactory->getAllContentFormats(),
827  ApiBase::PARAM_HELP_MSG => 'apihelp-query+revisions+base-param-contentformat',
829  ],
830  ];
831  }
832 }
ApiQueryRevisionsBase\parseParameters
parseParameters( $params)
Parse the parameters into the various instance fields.
Definition: ApiQueryRevisionsBase.php:131
ContextSource\$context
IContextSource $context
Definition: ContextSource.php:39
ContextSource\getConfig
getConfig()
Definition: ContextSource.php:72
MediaWiki\Revision\RevisionAccessException
Exception representing a failure to look up a revision.
Definition: RevisionAccessException.php:37
MediaWiki\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:389
ContextSource\getContext
getContext()
Get the base IContextSource object.
Definition: ContextSource.php:47
ApiQuery
This is the main query class.
Definition: ApiQuery.php:37
MediaWiki\Revision\RevisionRecord
Page revision base class.
Definition: RevisionRecord.php:47
ApiBase\addWarning
addWarning( $msg, $code=null, $data=null)
Add a warning for this module.
Definition: ApiBase.php:1297
ApiQueryRevisionsBase\$fld_slotsize
$fld_slotsize
Definition: ApiQueryRevisionsBase.php:59
ApiQueryGeneratorBase\encodeParamName
encodeParamName( $paramName)
Overrides ApiBase to prepend 'g' to every generator parameter.
Definition: ApiQueryGeneratorBase.php:70
ApiQueryRevisionsBase\$contentHandlerFactory
IContentHandlerFactory $contentHandlerFactory
Definition: ApiQueryRevisionsBase.php:68
ApiQueryRevisionsBase\$fld_comment
$fld_comment
Definition: ApiQueryRevisionsBase.php:60
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:193
MediaWiki\Revision\RevisionStore
Service for looking up page revisions.
Definition: RevisionStore.php:88
ApiQueryBase\getParent
getParent()
Get the parent of this module.Stability: stableto 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:1379
ApiBase\PARAM_HELP_MSG
const PARAM_HELP_MSG
(string|array|Message) Specify an alternative i18n documentation message for this parameter.
Definition: ApiBase.php:105
ApiBase\PARAM_ALL
const PARAM_ALL
Definition: ApiBase.php:81
ApiQueryRevisionsBase\$fld_roles
$fld_roles
Definition: ApiQueryRevisionsBase.php:61
ApiQueryRevisionsBase\$section
$section
Definition: ApiQueryRevisionsBase.php:55
wfTimestamp
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
Definition: GlobalFunctions.php:1668
ApiQueryRevisionsBase\CANNOT_VIEW
const CANNOT_VIEW
Definition: ApiQueryRevisionsBase.php:50
ApiQueryRevisionsBase\extractAllSlotInfo
extractAllSlotInfo(RevisionRecord $revision, $revDel)
Extracts information about all relevant slots.
Definition: ApiQueryRevisionsBase.php:425
ApiBase\PARAM_TYPE
const PARAM_TYPE
Definition: ApiBase.php:72
ApiBase\getResult
getResult()
Get the result object.
Definition: ApiBase.php:571
ApiQueryRevisionsBase\$fld_userid
$fld_userid
Definition: ApiQueryRevisionsBase.php:60
MediaWiki\Revision\RevisionRecord\isMinor
isMinor()
MCR migration note: this replaced Revision::isMinor.
Definition: RevisionRecord.php:426
ApiQueryRevisionsBase\$fld_sha1
$fld_sha1
Definition: ApiQueryRevisionsBase.php:59
MediaWiki\Revision\RevisionRecord\getSha1
getSha1()
Returns the base36 sha1 of this revision.
MediaWiki\Revision\SlotRecord\getSha1
getSha1()
Returns the content size.
Definition: SlotRecord.php:556
ApiQueryRevisionsBase\$fetchContent
$fetchContent
Definition: ApiQueryRevisionsBase.php:55
ApiQueryRevisionsBase\$setParsedLimit
$setParsedLimit
Definition: ApiQueryRevisionsBase.php:55
ApiQueryRevisionsBase\$slotRoles
$slotRoles
Definition: ApiQueryRevisionsBase.php:56
ContextSource\getUser
getUser()
Definition: ContextSource.php:136
ApiBase\PARAM_DEPRECATED_VALUES
const PARAM_DEPRECATED_VALUES
Definition: ApiBase.php:84
ApiQueryRevisionsBase\$difftotextpst
$difftotextpst
Definition: ApiQueryRevisionsBase.php:54
ApiPageSet
This class contains a list of pages that the client has requested.
Definition: ApiPageSet.php:45
ApiQueryRevisionsBase\$limit
$limit
Definition: ApiQueryRevisionsBase.php:54
ApiQueryRevisionsBase\$fld_content
$fld_content
Definition: ApiQueryRevisionsBase.php:61
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:466
ApiQueryRevisionsBase\$fld_contentmodel
$fld_contentmodel
Definition: ApiQueryRevisionsBase.php:61
ApiQueryRevisionsBase
A base class for functions common to producing a list of revisions.
Definition: ApiQueryRevisionsBase.php:42
ApiQueryRevisionsBase\$fld_slotsha1
$fld_slotsha1
Definition: ApiQueryRevisionsBase.php:59
ApiBase\PARAM_DEPRECATED
const PARAM_DEPRECATED
Definition: ApiBase.php:77
ApiBase\PARAM_MIN
const PARAM_MIN
Definition: ApiBase.php:75
DerivativeContext
An IContextSource implementation which will inherit context from another source but allow individual ...
Definition: DerivativeContext.php:32
ApiQueryRevisionsBase\$expandTemplates
$expandTemplates
Definition: ApiQueryRevisionsBase.php:54
ApiResult\setArrayType
static setArrayType(array &$arr, $type, $kvpKeyName=null)
Set the array data type.
Definition: ApiResult.php:715
ApiQueryRevisionsBase\$contentFormat
$contentFormat
Definition: ApiQueryRevisionsBase.php:55
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:163
ApiQueryRevisionsBase\getAllowedParams
getAllowedParams()
Definition: ApiQueryRevisionsBase.php:731
ApiBase\PARAM_MAX
const PARAM_MAX
Definition: ApiBase.php:73
MediaWiki\Content\Transform\ContentTransformer
A service to transform content.
Definition: ContentTransformer.php:15
$title
$title
Definition: testCompression.php:38
ApiQueryRevisionsBase\$diffto
$diffto
Definition: ApiQueryRevisionsBase.php:54
MediaWiki\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:413
WikitextContent
Content object for wiki text pages.
Definition: WikitextContent.php:36
ApiQueryRevisionsBase\$fld_parsetree
$fld_parsetree
Definition: ApiQueryRevisionsBase.php:62
ApiQueryRevisionsBase\execute
execute()
Definition: ApiQueryRevisionsBase.php:112
ApiQueryRevisionsBase\IS_DELETED
const IS_DELETED
Definition: ApiQueryRevisionsBase.php:49
ApiQueryRevisionsBase\$fld_tags
$fld_tags
Definition: ApiQueryRevisionsBase.php:61
ApiQueryRevisionsBase\$needSlots
$needSlots
Definition: ApiQueryRevisionsBase.php:56
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:146
ApiQueryRevisionsBase\checkRevDel
checkRevDel(RevisionRecord $revision, $field)
Test revision deletion status.
Definition: ApiQueryRevisionsBase.php:269
ApiBase\getModulePrefix
getModulePrefix()
Get parameter prefix (usually two letters or an empty string).
Definition: ApiBase.php:448
ContextSource\msg
msg( $key,... $params)
Get a Message object with context set Parameters are the same as wfMessage()
Definition: ContextSource.php:197
MediaWiki\Revision\RevisionRecord\getParentId
getParentId( $wikiId=self::LOCAL)
Get parent revision ID (the original previous page revision).
Definition: RevisionRecord.php:297
ApiResult\setIndexedTagName
static setIndexedTagName(array &$arr, $tag)
Set the tag name for numeric-keyed values in XML format.
Definition: ApiResult.php:603
ParserFactory
Definition: ParserFactory.php:37
$content
$content
Definition: router.php:76
ApiQueryRevisionsBase\$parseContent
$parseContent
Definition: ApiQueryRevisionsBase.php:55
ApiQueryRevisionsBase\$parserFactory
ParserFactory $parserFactory
Definition: ApiQueryRevisionsBase.php:71
ParserOptions\newFromContext
static newFromContext(IContextSource $context)
Get a ParserOptions object from a IContextSource object.
Definition: ParserOptions.php:1112
ApiBase\addDeprecation
addDeprecation( $msg, $feature, $data=[])
Add a deprecation warning for this module.
Definition: ApiBase.php:1311
MediaWiki\Content\IContentHandlerFactory
Definition: IContentHandlerFactory.php:10
ContextSource\getAuthority
getAuthority()
Definition: ContextSource.php:144
ApiBase\LIMIT_SML2
const LIMIT_SML2
Slow query, apihighlimits limit.
Definition: ApiBase.php:169
MediaWiki\Revision\RevisionRecord\getPageAsLinkTarget
getPageAsLinkTarget()
Returns the title of the page this revision is associated with as a LinkTarget object.
Definition: RevisionRecord.php:355
ApiQueryRevisionsBase\extractRevisionInfo
extractRevisionInfo(RevisionRecord $revision, $row)
Extract information from the RevisionRecord.
Definition: ApiQueryRevisionsBase.php:286
wfEscapeWikiText
wfEscapeWikiText( $text)
Escapes the given text so that it may be output using addWikiText() without any linking,...
Definition: GlobalFunctions.php:1459
ApiQueryRevisionsBase\$slotRoleRegistry
SlotRoleRegistry $slotRoleRegistry
Definition: ApiQueryRevisionsBase.php:74
CONTENT_MODEL_WIKITEXT
const CONTENT_MODEL_WIKITEXT
Definition: Defines.php:208
ApiQueryRevisionsBase\getCacheMode
getCacheMode( $params)
Definition: ApiQueryRevisionsBase.php:718
ApiQueryRevisionsBase\$fld_flags
$fld_flags
Definition: ApiQueryRevisionsBase.php:58
Title\newFromLinkTarget
static newFromLinkTarget(LinkTarget $linkTarget, $forceClone='')
Returns a Title given a LinkTarget.
Definition: Title.php:295
ApiQueryRevisionsBase\__construct
__construct(ApiQuery $queryModule, $moduleName, $paramPrefix='', RevisionStore $revisionStore=null, IContentHandlerFactory $contentHandlerFactory=null, ParserFactory $parserFactory=null, SlotRoleRegistry $slotRoleRegistry=null, ContentTransformer $contentTransformer=null)
Definition: ApiQueryRevisionsBase.php:91
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:1372
Content
Base interface for content objects.
Definition: Content.php:35
ApiQueryRevisionsBase\$difftotext
$difftotext
Definition: ApiQueryRevisionsBase.php:54
ApiQueryGeneratorBase
Definition: ApiQueryGeneratorBase.php:28
MediaWiki\Revision\RevisionRecord\getSlotRoles
getSlotRoles()
Returns the slot names (roles) of all slots present in this revision.
Definition: RevisionRecord.php:207
ApiQueryRevisionsBase\$fld_ids
$fld_ids
Definition: ApiQueryRevisionsBase.php:58
MediaWiki\Revision\SlotRecord\getSize
getSize()
Returns the content size.
Definition: SlotRecord.php:540
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:165
MediaWiki\Revision\RevisionRecord\getId
getId( $wikiId=self::LOCAL)
Get revision ID.
Definition: RevisionRecord.php:279
MediaWiki\Revision\RevisionRecord\isDeleted
isDeleted( $field)
MCR migration note: this replaced Revision::isDeleted.
Definition: RevisionRecord.php:437
ApiQueryRevisionsBase\$contentTransformer
ContentTransformer $contentTransformer
Definition: ApiQueryRevisionsBase.php:77
ApiBase\PARAM_DFLT
const PARAM_DFLT
Definition: ApiBase.php:70
MediaWiki\Revision\RevisionRecord\userCan
userCan( $field, Authority $performer)
Determine if the give authority is allowed to view a particular field of this revision,...
Definition: RevisionRecord.php:509
ApiBase\getModuleName
getModuleName()
Get the name of the module being executed by this instance.
Definition: ApiBase.php:440
ApiQueryRevisionsBase\$fld_user
$fld_user
Definition: ApiQueryRevisionsBase.php:60
ApiBase\PARAM_ISMULTI
const PARAM_ISMULTI
Definition: ApiBase.php:71
MediaWiki\Revision\RevisionRecord\getTimestamp
getTimestamp()
MCR migration note: this replaced Revision::getTimestamp.
Definition: RevisionRecord.php:459
ApiQueryRevisionsBase\$fld_timestamp
$fld_timestamp
Definition: ApiQueryRevisionsBase.php:58
ApiQueryRevisionsBase\$revisionStore
RevisionStore $revisionStore
Definition: ApiQueryRevisionsBase.php:65
ApiBase\PARAM_MAX2
const PARAM_MAX2
Definition: ApiBase.php:74
MediaWiki\Revision\RevisionRecord\getSize
getSize()
Returns the nominal size of this revision, in bogo-bytes.
MediaWiki\Revision\SlotRoleRegistry
A registry service for SlotRoleHandlers, used to define which slot roles are available on which page.
Definition: SlotRoleRegistry.php:48
ApiBase\getMain
getMain()
Get the main module.
Definition: ApiBase.php:456
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)
Definition: ApiQueryRevisionsBase.php:116
$t
$t
Definition: testCompression.php:74
ApiQueryRevisionsBase\$fld_parsedcomment
$fld_parsedcomment
Definition: ApiQueryRevisionsBase.php:60
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:138
ApiQueryBase\userCanSeeRevDel
userCanSeeRevDel()
Check whether the current user has permission to view revision-deleted fields.
Definition: ApiQueryBase.php:607
ApiQueryRevisionsBase\$fld_size
$fld_size
Definition: ApiQueryRevisionsBase.php:59
MediaWiki\Revision\SlotRecord\getContent
getContent()
Returns the Content of the given slot.
Definition: SlotRecord.php:317
MediaWiki\Revision\SlotRecord\getModel
getModel()
Returns the content model.
Definition: SlotRecord.php:584
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:557
ApiQueryRevisionsBase\extractSlotInfo
extractSlotInfo(SlotRecord $slot, $revDel, &$content=null)
Extract information from the SlotRecord.
Definition: ApiQueryRevisionsBase.php:499
MediaWiki\Revision\RevisionRecord\getSlot
getSlot( $role, $audience=self::FOR_PUBLIC, Authority $performer=null)
Returns meta-data for the given slot.
Definition: RevisionRecord.php:180
MediaWiki\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:167
ApiQueryRevisionsBase\$generateXML
$generateXML
Definition: ApiQueryRevisionsBase.php:54