MediaWiki REL1_37
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,
63
66
69
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'] = [
458 ApiResult::META_KVP_MERGE => true,
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
558 $vals = [];
559 $title = Title::newFromLinkTarget( $revision->getPageAsLinkTarget() );
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' => [
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' => [
782 ApiBase::PARAM_TYPE => $slotRoles,
783 ApiBase::PARAM_HELP_MSG => 'apihelp-query+revisions+base-param-slots',
785 ApiBase::PARAM_ALL => true,
786 ],
787 'limit' => [
788 ApiBase::PARAM_TYPE => 'limit',
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}
getAuthority()
const CONTENT_MODEL_WIKITEXT
Definition Defines.php:208
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
wfEscapeWikiText( $text)
Escapes the given text so that it may be output using addWikiText() without any linking,...
getContext()
dieWithError( $msg, $code=null, $data=null, $httpCode=0)
Abort execution with an error.
Definition ApiBase.php:1436
getModulePrefix()
Get parameter prefix (usually two letters or an empty string).
Definition ApiBase.php:505
const PARAM_MAX2
Definition ApiBase.php:89
const PARAM_DEPRECATED
Definition ApiBase.php:101
const PARAM_MAX
Definition ApiBase.php:85
const PARAM_DEPRECATED_VALUES
Definition ApiBase.php:129
getMain()
Get the main module.
Definition ApiBase.php:513
const PARAM_TYPE
Definition ApiBase.php:81
const PARAM_DFLT
Definition ApiBase.php:73
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:195
addDeprecation( $msg, $feature, $data=[])
Add a deprecation warning for this module.
Definition ApiBase.php:1368
const PARAM_MIN
Definition ApiBase.php:93
const LIMIT_BIG1
Fast query, standard limit.
Definition ApiBase.php:220
const LIMIT_SML2
Slow query, apihighlimits limit.
Definition ApiBase.php:226
getResult()
Get the result object.
Definition ApiBase.php:628
const LIMIT_SML1
Slow query, standard limit.
Definition ApiBase.php:224
const PARAM_HELP_MSG
(string|array|Message) Specify an alternative i18n documentation message for this parameter.
Definition ApiBase.php:162
addWarning( $msg, $code=null, $data=null)
Add a warning for this module.
Definition ApiBase.php:1354
const PARAM_ALL
Definition ApiBase.php:117
const LIMIT_BIG2
Fast query, apihighlimits limit.
Definition ApiBase.php:222
getModuleName()
Get the name of the module being executed by this instance.
Definition ApiBase.php:497
const PARAM_ISMULTI
Definition ApiBase.php:77
This class contains a list of pages that the client has requested.
getParent()
Get the parent of this module.to override 1.25 ApiBase|null
encodeParamName( $paramName)
Overrides ApiBase to prepend 'g' to every generator parameter.
A base class for functions common to producing a list of revisions.
extractAllSlotInfo(RevisionRecord $revision, $revDel)
Extracts information about all relevant slots.
__construct(ApiQuery $queryModule, $moduleName, $paramPrefix='', RevisionStore $revisionStore=null, IContentHandlerFactory $contentHandlerFactory=null, ParserFactory $parserFactory=null, SlotRoleRegistry $slotRoleRegistry=null, ContentTransformer $contentTransformer=null)
parseParameters( $params)
Parse the parameters into the various instance fields.
IContentHandlerFactory $contentHandlerFactory
extractDeprecatedContent(Content $content, RevisionRecord $revision)
Format a Content using deprecated options.
ContentTransformer $contentTransformer
SlotRoleRegistry $slotRoleRegistry
extractSlotInfo(SlotRecord $slot, $revDel, &$content=null)
Extract information from the SlotRecord.
run(ApiPageSet $resultPageSet=null)
checkRevDel(RevisionRecord $revision, $field)
Test revision deletion status.
extractRevisionInfo(RevisionRecord $revision, $row)
Extract information from the RevisionRecord.
This is the main query class.
Definition ApiQuery.php:37
static setArrayType(array &$arr, $type, $kvpKeyName=null)
Set the array data type.
static setIndexedTagName(array &$arr, $tag)
Set the tag name for numeric-keyed values in XML format.
static setContentValue(array &$arr, $name, $value, $flags=0)
Add an output value to the array by name and mark as META_CONTENT.
msg( $key,... $params)
Get a Message object with context set Parameters are the same as wfMessage()
An IContextSource implementation which will inherit context from another source but allow individual ...
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
PSR-3 logger instance factory.
MediaWikiServices is the service locator for the application scope of MediaWiki.
Exception representing a failure to look up a revision.
Page revision base class.
getUser( $audience=self::FOR_PUBLIC, Authority $performer=null)
Fetch revision's author's user identity, if it's available to the specified audience.
getSize()
Returns the nominal size of this revision, in bogo-bytes.
getSlotRoles()
Returns the slot names (roles) of all slots present in this revision.
getParentId( $wikiId=self::LOCAL)
Get parent revision ID (the original previous page revision).
getTimestamp()
MCR migration note: this replaced Revision::getTimestamp.
getComment( $audience=self::FOR_PUBLIC, Authority $performer=null)
Fetch revision comment, if it's available to the specified audience.
getSlot( $role, $audience=self::FOR_PUBLIC, Authority $performer=null)
Returns meta-data for the given slot.
getSha1()
Returns the base36 sha1 of this revision.
isMinor()
MCR migration note: this replaced Revision::isMinor.
getPageAsLinkTarget()
Returns the title of the page this revision is associated with as a LinkTarget object.
userCan( $field, Authority $performer)
Determine if the give authority is allowed to view a particular field of this revision,...
isDeleted( $field)
MCR migration note: this replaced Revision::isDeleted.
getId( $wikiId=self::LOCAL)
Get revision ID.
Service for looking up page revisions.
Value object representing a content slot associated with a page revision.
getContent()
Returns the Content of the given slot.
getSha1()
Returns the content size.
getSize()
Returns the content size.
getModel()
Returns the content model.
A registry service for SlotRoleHandlers, used to define which slot roles are available on which page.
Service for formatting and validating API parameters.
Type definition for integer types.
Content object for wiki text pages.
Base interface for content objects.
Definition Content.php:35
getModel()
Returns the ID of the content model used by this Content object.
getDefaultFormat()
Convenience method that returns the default serialization format for the content model that this Cont...
$content
Definition router.php:76