MediaWiki  master
ContentHandler.php
Go to the documentation of this file.
1 <?php
2 
33 use MediaWiki\HookContainer\ProtectedHookAccessorTrait;
40 
62 abstract class ContentHandler {
63  use ProtectedHookAccessorTrait;
64 
97  public static function getContentText( Content $content = null ) {
99 
100  if ( $content === null ) {
101  return '';
102  }
103 
104  if ( $content instanceof TextContent ) {
105  return $content->getText();
106  }
107 
108  wfDebugLog( 'ContentHandler', 'Accessing ' . $content->getModel() . ' content as text!' );
109 
110  if ( $wgContentHandlerTextFallback == 'fail' ) {
111  throw new MWException(
112  "Attempt to get text from Content with model " .
113  $content->getModel()
114  );
115  }
116 
117  if ( $wgContentHandlerTextFallback == 'serialize' ) {
118  return $content->serialize();
119  }
120 
121  return null;
122  }
123 
148  public static function makeContent( $text, Title $title = null,
149  $modelId = null, $format = null ) {
150  if ( $modelId === null ) {
151  if ( $title === null ) {
152  throw new MWException( "Must provide a Title object or a content model ID." );
153  }
154 
155  $modelId = $title->getContentModel();
156  }
157 
158  return MediaWikiServices::getInstance()
159  ->getContentHandlerFactory()
160  ->getContentHandler( $modelId )
161  ->unserializeContent( $text, $format );
162  }
163 
200  public static function getDefaultModelFor( Title $title ) {
201  $slotRoleregistry = MediaWikiServices::getInstance()->getSlotRoleRegistry();
202  $mainSlotHandler = $slotRoleregistry->getRoleHandler( 'main' );
203  return $mainSlotHandler->getDefaultModel( $title );
204  }
205 
220  public static function getForTitle( Title $title ) {
221  wfDeprecated( __METHOD__, '1.35' );
222  return MediaWikiServices::getInstance()
223  ->getContentHandlerFactory()
224  ->getContentHandler( $title->getContentModel() );
225  }
226 
242  public static function getForContent( Content $content ) {
243  return MediaWikiServices::getInstance()
244  ->getContentHandlerFactory()
245  ->getContentHandler( $content->getModel() );
246  }
247 
277  public static function getForModelID( $modelId ) {
278  return MediaWikiServices::getInstance()
279  ->getContentHandlerFactory()
280  ->getContentHandler( $modelId );
281  }
282 
290  public static function cleanupHandlersCache() {
291  wfDeprecated( __METHOD__, '1.35' );
292  // No-op: no longer needed, since the instance cache is in the
293  // ContentHandlerFactory service, and services get reset between tests
294  }
295 
309  public static function getLocalizedName( $name, Language $lang = null ) {
310  // Messages: content-model-wikitext, content-model-text,
311  // content-model-javascript, content-model-css
312  $key = "content-model-$name";
313 
314  $msg = wfMessage( $key );
315  if ( $lang ) {
316  $msg->inLanguage( $lang );
317  }
318 
319  return $msg->exists() ? $msg->plain() : $name;
320  }
321 
330  public static function getContentModels() {
331  return MediaWikiServices::getInstance()->getContentHandlerFactory()->getContentModels();
332  }
333 
342  public static function getAllContentFormats() {
343  return MediaWikiServices::getInstance()->getContentHandlerFactory()->getAllContentFormats();
344  }
345 
346  // ------------------------------------------------------------------------
347 
351  protected $mModelID;
352 
357 
369  public function __construct( $modelId, $formats ) {
370  $this->mModelID = $modelId;
371  $this->mSupportedFormats = $formats;
372  }
373 
386  abstract public function serializeContent( Content $content, $format = null );
387 
400  public function exportTransform( $blob, $format = null ) {
401  return $blob;
402  }
403 
416  abstract public function unserializeContent( $blob, $format = null );
417 
430  public function importTransform( $blob, $format = null ) {
431  return $blob;
432  }
433 
443  abstract public function makeEmptyContent();
444 
463  public function makeRedirectContent( Title $destination, $text = '' ) {
464  return null;
465  }
466 
475  public function getModelID() {
476  return $this->mModelID;
477  }
478 
487  protected function checkModelID( $model_id ) {
488  if ( $model_id !== $this->mModelID ) {
489  throw new MWException( "Bad content model: " .
490  "expected {$this->mModelID} " .
491  "but got $model_id." );
492  }
493  }
494 
505  public function getSupportedFormats() {
507  }
508 
521  public function getDefaultFormat() {
522  return $this->mSupportedFormats[0];
523  }
524 
539  public function isSupportedFormat( $format ) {
540  if ( !$format ) {
541  return true; // this means "use the default"
542  }
543 
544  return in_array( $format, $this->mSupportedFormats );
545  }
546 
554  protected function checkFormat( $format ) {
555  if ( !$this->isSupportedFormat( $format ) ) {
556  throw new MWException(
557  "Format $format is not supported for content model "
558  . $this->getModelID()
559  );
560  }
561  }
562 
579  public function getActionOverrides() {
580  return [];
581  }
582 
610  public function createDifferenceEngine( IContextSource $context, $old = 0, $new = 0,
611  $rcid = 0, // FIXME: Deprecated, no longer used
612  $refreshCache = false, $unhide = false
613  ) {
614  $diffEngineClass = $this->getDiffEngineClass();
615  $differenceEngine = new $diffEngineClass( $context, $old, $new, $rcid, $refreshCache, $unhide );
616  $this->getHookRunner()->onGetDifferenceEngine(
617  $context, $old, $new, $refreshCache, $unhide, $differenceEngine );
618  return $differenceEngine;
619  }
620 
631  final public function getSlotDiffRenderer( IContextSource $context, array $options = [] ) {
632  $slotDiffRenderer = $this->getSlotDiffRendererWithOptions( $context, $options );
633  if ( get_class( $slotDiffRenderer ) === TextSlotDiffRenderer::class ) {
634  // To keep B/C, when SlotDiffRenderer is not overridden for a given content type
635  // but DifferenceEngine is, use that instead.
636  $differenceEngine = $this->createDifferenceEngine( $context );
637  if ( get_class( $differenceEngine ) !== DifferenceEngine::class ) {
638  // TODO turn this into a deprecation warning in a later release
639  LoggerFactory::getInstance( 'diff' )->info(
640  'Falling back to DifferenceEngineSlotDiffRenderer', [
641  'modelID' => $this->getModelID(),
642  'DifferenceEngine' => get_class( $differenceEngine ),
643  ] );
644  $slotDiffRenderer = new DifferenceEngineSlotDiffRenderer( $differenceEngine );
645  }
646  }
647  $this->getHookRunner()->onGetSlotDiffRenderer( $this, $slotDiffRenderer, $context );
648  return $slotDiffRenderer;
649  }
650 
657  protected function getSlotDiffRendererInternal( IContextSource $context ) {
658  return null;
659  }
660 
670  protected function getSlotDiffRendererWithOptions( IContextSource $context, $options = [] ) {
671  $internalRenderer = $this->getSlotDiffRendererInternal( $context );
672  // `getSlotDiffRendererInternal` has been overriden by a class using the deprecated method.
673  // Options will not work so exit early!
674  if ( $internalRenderer !== null ) {
675  return $internalRenderer;
676  }
677 
678  $contentLanguage = MediaWikiServices::getInstance()->getContentLanguage();
679  $statsdDataFactory = MediaWikiServices::getInstance()->getStatsdDataFactory();
680  $slotDiffRenderer = new TextSlotDiffRenderer();
681  $slotDiffRenderer->setStatsdDataFactory( $statsdDataFactory );
682  // XXX using the page language would be better, but it's unclear how that should be injected
683  $slotDiffRenderer->setLanguage( $contentLanguage );
684 
685  $inline = ( $options['diff-type'] ?? '' ) === 'inline';
686  $engine = DifferenceEngine::getEngine();
687 
688  if ( $engine === 'php' ) {
689  $slotDiffRenderer->setEngine( TextSlotDiffRenderer::ENGINE_PHP );
690  } elseif ( $engine === 'wikidiff2' ) {
691  if ( $inline ) {
692  $slotDiffRenderer->setEngine( TextSlotDiffRenderer::ENGINE_WIKIDIFF2_INLINE );
693  } else {
694  $slotDiffRenderer->setEngine( TextSlotDiffRenderer::ENGINE_WIKIDIFF2 );
695  }
696  } else {
697  $slotDiffRenderer->setEngine( TextSlotDiffRenderer::ENGINE_EXTERNAL, $engine );
698  }
699 
700  return $slotDiffRenderer;
701  }
702 
723  public function getPageLanguage( Title $title, Content $content = null ) {
724  global $wgLang;
725  $services = MediaWikiServices::getInstance();
726  $pageLang = $services->getContentLanguage();
727 
728  if ( $title->inNamespace( NS_MEDIAWIKI ) ) {
729  // Parse mediawiki messages with correct target language
730  list( /* $unused */, $lang ) = $services->getMessageCache()->figureMessage( $title->getText() );
731  $pageLang = $services->getLanguageFactory()->getLanguage( $lang );
732  }
733 
734  // Simplify hook handlers by only passing objects of one type, in case nothing
735  // else has unstubbed the StubUserLang object by now.
737 
738  $this->getHookRunner()->onPageContentLanguage( $title, $pageLang, $wgLang );
739 
740  if ( !$pageLang instanceof Language ) {
741  wfDeprecated( 'the hook PageContentLanguage with other types than a Language object in $pageLang', '1.33' );
742  $pageLang = wfGetLangObj( $pageLang );
743  }
744 
745  return $pageLang;
746  }
747 
769  public function getPageViewLanguage( Title $title, Content $content = null ) {
770  $pageLang = $this->getPageLanguage( $title, $content );
771 
772  if ( $title->getNamespace() !== NS_MEDIAWIKI ) {
773  // If the user chooses a variant, the content is actually
774  // in a language whose code is the variant code.
775  $variant = $this->getLanguageConverter( $pageLang )->getPreferredVariant();
776  if ( $pageLang->getCode() !== $variant ) {
777  $pageLang = MediaWikiServices::getInstance()->getLanguageFactory()
778  ->getLanguage( $variant );
779  }
780  }
781 
782  return $pageLang;
783  }
784 
805  public function canBeUsedOn( Title $title ) {
806  $ok = true;
807 
808  $this->getHookRunner()->onContentModelCanBeUsedOn( $this->getModelID(), $title, $ok );
809 
810  return $ok;
811  }
812 
821  protected function getDiffEngineClass() {
822  return DifferenceEngine::class;
823  }
824 
840  public function merge3( Content $oldContent, Content $myContent, Content $yourContent ) {
841  return false;
842  }
843 
849  private function getLanguageConverter( $language ): ILanguageConverter {
850  return MediaWikiServices::getInstance()->getLanguageConverterFactory()
851  ->getLanguageConverter( $language );
852  }
853 
866  private function getChangeType(
867  Content $oldContent = null,
868  Content $newContent = null,
869  $flags = 0
870  ) {
871  $oldTarget = $oldContent !== null ? $oldContent->getRedirectTarget() : null;
872  $newTarget = $newContent !== null ? $newContent->getRedirectTarget() : null;
873 
874  // We check for the type of change in the given edit, and return string key accordingly
875 
876  // Blanking of a page
877  if ( $oldContent && $oldContent->getSize() > 0 &&
878  $newContent && $newContent->getSize() === 0
879  ) {
880  return 'blank';
881  }
882 
883  // Redirects
884  if ( $newTarget ) {
885  if ( !$oldTarget ) {
886  // New redirect page (by creating new page or by changing content page)
887  return 'new-redirect';
888  } elseif ( !$newTarget->equals( $oldTarget ) ||
889  $oldTarget->getFragment() !== $newTarget->getFragment()
890  ) {
891  // Redirect target changed
892  return 'changed-redirect-target';
893  }
894  } elseif ( $oldTarget ) {
895  // Changing an existing redirect into a non-redirect
896  return 'removed-redirect';
897  }
898 
899  // New page created
900  if ( $flags & EDIT_NEW && $newContent ) {
901  if ( $newContent->getSize() === 0 ) {
902  // New blank page
903  return 'newblank';
904  } else {
905  return 'newpage';
906  }
907  }
908 
909  // Removing more than 90% of the page
910  if ( $oldContent && $newContent && $oldContent->getSize() > 10 * $newContent->getSize() ) {
911  return 'replace';
912  }
913 
914  // Content model changed
915  if ( $oldContent && $newContent && $oldContent->getModel() !== $newContent->getModel() ) {
916  return 'contentmodelchange';
917  }
918 
919  return null;
920  }
921 
934  public function getAutosummary(
935  Content $oldContent = null,
936  Content $newContent = null,
937  $flags = 0
938  ) {
939  $changeType = $this->getChangeType( $oldContent, $newContent, $flags );
940 
941  // There's no applicable auto-summary for our case, so our auto-summary is empty.
942  if ( !$changeType ) {
943  return '';
944  }
945 
946  // Set the maximum auto-summary length to the general maximum summary length
947  // T221617
949 
950  // Decide what kind of auto-summary is needed.
951  switch ( $changeType ) {
952  case 'new-redirect':
953  $newTarget = $newContent->getRedirectTarget();
954  $truncatedtext = $newContent->getTextForSummary(
955  $summaryLimit
956  - strlen( wfMessage( 'autoredircomment' )->inContentLanguage()->text() )
957  - strlen( $newTarget->getFullText() )
958  );
959 
960  return wfMessage( 'autoredircomment', $newTarget->getFullText() )
961  ->plaintextParams( $truncatedtext )->inContentLanguage()->text();
962  case 'changed-redirect-target':
963  $oldTarget = $oldContent->getRedirectTarget();
964  $newTarget = $newContent->getRedirectTarget();
965 
966  $truncatedtext = $newContent->getTextForSummary(
967  $summaryLimit
968  - strlen( wfMessage( 'autosumm-changed-redirect-target' )
969  ->inContentLanguage()->text() )
970  - strlen( $oldTarget->getFullText() )
971  - strlen( $newTarget->getFullText() )
972  );
973 
974  return wfMessage( 'autosumm-changed-redirect-target',
975  $oldTarget->getFullText(),
976  $newTarget->getFullText() )
977  ->rawParams( $truncatedtext )->inContentLanguage()->text();
978  case 'removed-redirect':
979  $oldTarget = $oldContent->getRedirectTarget();
980  $truncatedtext = $newContent->getTextForSummary(
981  $summaryLimit
982  - strlen( wfMessage( 'autosumm-removed-redirect' )
983  ->inContentLanguage()->text() )
984  - strlen( $oldTarget->getFullText() ) );
985 
986  return wfMessage( 'autosumm-removed-redirect', $oldTarget->getFullText() )
987  ->rawParams( $truncatedtext )->inContentLanguage()->text();
988  case 'newpage':
989  // If they're making a new article, give its text, truncated, in the summary.
990  $truncatedtext = $newContent->getTextForSummary(
991  $summaryLimit - strlen( wfMessage( 'autosumm-new' )->inContentLanguage()->text() ) );
992 
993  return wfMessage( 'autosumm-new' )->rawParams( $truncatedtext )
994  ->inContentLanguage()->text();
995  case 'blank':
996  return wfMessage( 'autosumm-blank' )->inContentLanguage()->text();
997  case 'replace':
998  $truncatedtext = $newContent->getTextForSummary(
999  $summaryLimit - strlen( wfMessage( 'autosumm-replace' )->inContentLanguage()->text() ) );
1000 
1001  return wfMessage( 'autosumm-replace' )->rawParams( $truncatedtext )
1002  ->inContentLanguage()->text();
1003  case 'newblank':
1004  return wfMessage( 'autosumm-newblank' )->inContentLanguage()->text();
1005  default:
1006  return '';
1007  }
1008  }
1009 
1022  public function getChangeTag(
1023  Content $oldContent = null,
1024  Content $newContent = null,
1025  $flags = 0
1026  ) {
1027  $changeType = $this->getChangeType( $oldContent, $newContent, $flags );
1028 
1029  // There's no applicable tag for this change.
1030  if ( !$changeType ) {
1031  return null;
1032  }
1033 
1034  // Core tags use the same keys as ones returned from $this->getChangeType()
1035  // but prefixed with pseudo namespace 'mw-', so we add the prefix before checking
1036  // if this type of change should be tagged
1037  $tag = 'mw-' . $changeType;
1038 
1039  // Not all change types are tagged, so we check against the list of defined tags.
1040  if ( in_array( $tag, ChangeTags::getSoftwareTags() ) ) {
1041  return $tag;
1042  }
1043 
1044  return null;
1045  }
1046 
1059  public function getAutoDeleteReason( Title $title, &$hasHistory = false ) {
1060  if ( func_num_args() === 2 ) {
1061  wfDeprecated( __METHOD__ . ': $hasHistory parameter', '1.38' );
1062  }
1063  $dbr = wfGetDB( DB_REPLICA );
1064  $revStore = MediaWikiServices::getInstance()->getRevisionStore();
1065 
1066  // Get the last revision
1067  $revRecord = $revStore->getRevisionByTitle( $title );
1068 
1069  if ( $revRecord === null ) {
1070  return false;
1071  }
1072 
1073  // Get the article's contents
1074  $content = $revRecord->getContent( SlotRecord::MAIN );
1075  $blank = false;
1076 
1077  // If the page is blank, use the text from the previous revision,
1078  // which can only be blank if there's a move/import/protect dummy
1079  // revision involved
1080  if ( !$content || $content->isEmpty() ) {
1081  $prev = $revStore->getPreviousRevision( $revRecord );
1082 
1083  if ( $prev ) {
1084  $revRecord = $prev;
1085  $content = $prev->getContent( SlotRecord::MAIN );
1086  $blank = true;
1087  }
1088  }
1089 
1090  $this->checkModelID( $revRecord->getSlot( SlotRecord::MAIN )->getModel() );
1091 
1092  // Find out if there was only one contributor
1093  // Only scan the last 20 revisions
1094  $revQuery = $revStore->getQueryInfo();
1095  $res = $dbr->select(
1096  $revQuery['tables'],
1097  [ 'rev_user_text' => $revQuery['fields']['rev_user_text'] ],
1098  [
1099  'rev_page' => $title->getArticleID(),
1100  $dbr->bitAnd( 'rev_deleted', RevisionRecord::DELETED_USER ) . ' = 0'
1101  ],
1102  __METHOD__,
1103  [ 'LIMIT' => 20 ],
1104  $revQuery['joins']
1105  );
1106 
1107  if ( $res === false ) {
1108  // This page has no revisions, which is very weird
1109  return false;
1110  }
1111 
1112  $hasHistory = ( $res->numRows() > 1 );
1113  $row = $dbr->fetchObject( $res );
1114 
1115  if ( $row ) { // $row is false if the only contributor is hidden
1116  $onlyAuthor = $row->rev_user_text;
1117  // Try to find a second contributor
1118  foreach ( $res as $row ) {
1119  if ( $row->rev_user_text != $onlyAuthor ) { // T24999
1120  $onlyAuthor = false;
1121  break;
1122  }
1123  }
1124  } else {
1125  $onlyAuthor = false;
1126  }
1127 
1128  // Generate the summary with a '$1' placeholder
1129  if ( $blank ) {
1130  // The current revision is blank and the one before is also
1131  // blank. It's just not our lucky day
1132  $reason = wfMessage( 'exbeforeblank', '$1' )->inContentLanguage()->text();
1133  } else {
1134  if ( $onlyAuthor ) {
1135  $reason = wfMessage(
1136  'excontentauthor',
1137  '$1',
1138  $onlyAuthor
1139  )->inContentLanguage()->text();
1140  } else {
1141  $reason = wfMessage( 'excontent', '$1' )->inContentLanguage()->text();
1142  }
1143  }
1144 
1145  if ( $reason == '-' ) {
1146  // Allow these UI messages to be blanked out cleanly
1147  return '';
1148  }
1149 
1150  // Max content length = max comment length - length of the comment (excl. $1)
1151  $maxLength = CommentStore::COMMENT_CHARACTER_LIMIT - ( strlen( $reason ) - 2 );
1152  $text = $content ? $content->getTextForSummary( $maxLength ) : '';
1153 
1154  // Now replace the '$1' placeholder
1155  $reason = str_replace( '$1', $text, $reason );
1156 
1157  return $reason;
1158  }
1159 
1177  public function getUndoContent(
1178  Content $currentContent,
1179  Content $undoContent,
1180  Content $undoAfterContent,
1181  $undoIsLatest = false
1182  ) {
1183  try {
1184  $this->checkModelID( $currentContent->getModel() );
1185  $this->checkModelID( $undoContent->getModel() );
1186  if ( !$undoIsLatest ) {
1187  // If we are undoing the most recent revision,
1188  // its ok to revert content model changes. However
1189  // if we are undoing a revision in the middle, then
1190  // doing that will be confusing.
1191  $this->checkModelID( $undoAfterContent->getModel() );
1192  }
1193  } catch ( MWException $e ) {
1194  // If the revisions have different content models
1195  // just return false
1196  return false;
1197  }
1198 
1199  if ( $currentContent->equals( $undoContent ) ) {
1200  // No use doing a merge if it's just a straight revert.
1201  return $undoAfterContent;
1202  }
1203 
1204  $undone_content = $this->merge3( $undoContent, $undoAfterContent, $currentContent );
1205 
1206  return $undone_content;
1207  }
1208 
1218  public function isParserCacheSupported() {
1219  return false;
1220  }
1221 
1233  public function supportsSections() {
1234  return false;
1235  }
1236 
1245  public function supportsCategories() {
1246  return true;
1247  }
1248 
1260  public function supportsRedirects() {
1261  return false;
1262  }
1263 
1271  public function supportsDirectEditing() {
1272  return false;
1273  }
1274 
1283  public function generateHTMLOnEdit(): bool {
1284  return true;
1285  }
1286 
1294  public function supportsDirectApiEditing() {
1295  return $this->supportsDirectEditing();
1296  }
1297 
1310  public function getFieldsForSearchIndex( SearchEngine $engine ) {
1311  $fields = [];
1312  $fields['category'] = $engine->makeSearchFieldMapping(
1313  'category',
1315  );
1316  $fields['category']->setFlag( SearchIndexField::FLAG_CASEFOLD );
1317 
1318  $fields['external_link'] = $engine->makeSearchFieldMapping(
1319  'external_link',
1321  );
1322 
1323  $fields['outgoing_link'] = $engine->makeSearchFieldMapping(
1324  'outgoing_link',
1326  );
1327 
1328  $fields['template'] = $engine->makeSearchFieldMapping(
1329  'template',
1331  );
1332  $fields['template']->setFlag( SearchIndexField::FLAG_CASEFOLD );
1333 
1334  $fields['content_model'] = $engine->makeSearchFieldMapping(
1335  'content_model',
1337  );
1338 
1339  return $fields;
1340  }
1341 
1351  protected function addSearchField( &$fields, SearchEngine $engine, $name, $type ) {
1352  $fields[$name] = $engine->makeSearchFieldMapping( $name, $type );
1353  return $fields;
1354  }
1355 
1379  public function getDataForSearchIndex(
1380  WikiPage $page,
1381  ParserOutput $output,
1382  SearchEngine $engine
1383  ) {
1384  $fieldData = [];
1385  $content = $page->getContent();
1386 
1387  if ( $content ) {
1388  $searchDataExtractor = new ParserOutputSearchDataExtractor();
1389 
1390  $fieldData['category'] = $searchDataExtractor->getCategories( $output );
1391  $fieldData['external_link'] = $searchDataExtractor->getExternalLinks( $output );
1392  $fieldData['outgoing_link'] = $searchDataExtractor->getOutgoingLinks( $output );
1393  $fieldData['template'] = $searchDataExtractor->getTemplates( $output );
1394 
1395  $text = $content->getTextForSearchIndex();
1396 
1397  $fieldData['text'] = $text;
1398  $fieldData['source_text'] = $text;
1399  $fieldData['text_bytes'] = $content->getSize();
1400  $fieldData['content_model'] = $content->getModel();
1401  }
1402 
1403  $this->getHookRunner()->onSearchDataForIndex( $fieldData, $this, $page, $output, $engine );
1404  return $fieldData;
1405  }
1406 
1424  public function getParserOutputForIndexing( WikiPage $page, ParserCache $cache = null ) {
1425  // TODO: MCR: ContentHandler should be called per slot, not for the whole page.
1426  // See T190066.
1427  $parserOptions = $page->makeParserOptions( 'canonical' );
1428  if ( $cache ) {
1429  $parserOutput = $cache->get( $page, $parserOptions );
1430  }
1431 
1432  if ( empty( $parserOutput ) ) {
1433  $renderer = MediaWikiServices::getInstance()->getRevisionRenderer();
1434  $revisionRecord = $this->latestRevision( $page );
1435  $parserOutput =
1436  $renderer->getRenderedRevision(
1437  $revisionRecord,
1438  $parserOptions
1439  )->getRevisionParserOutput( [
1440  // subclasses may want to add the following here:
1441  // 'generate-html' => false,
1442  ] );
1443  if ( $cache ) {
1444  $cache->save( $parserOutput, $page, $parserOptions );
1445  }
1446  }
1447  return $parserOutput;
1448  }
1449 
1458  protected function latestRevision( WikiPage $page ): RevisionRecord {
1459  $revRecord = $page->getRevisionRecord();
1460  if ( $revRecord == null ) {
1461  // If the content represents a brand new page it's possible
1462  // we need to fetch it from the primary.
1463  $page->loadPageData( WikiPage::READ_LATEST );
1464  $revRecord = $page->getRevisionRecord();
1465  if ( $revRecord == null ) {
1466  $text = $page->getTitle()->getPrefixedText();
1467  throw new MWException(
1468  "No revision could be loaded for page: $text" );
1469  }
1470  }
1471 
1472  return $revRecord;
1473  }
1474 
1507  public function getSecondaryDataUpdates(
1508  Title $title,
1509  Content $content,
1510  $role,
1511  SlotRenderingProvider $slotOutput
1512  ) {
1513  return [];
1514  }
1515 
1546  public function getDeletionUpdates( Title $title, $role ) {
1547  return [];
1548  }
1549 
1564  public function preSaveTransform(
1565  Content $content,
1566  PreSaveTransformParams $pstParams
1567  ): Content {
1568  $shouldCallDeprecatedMethod = $this->shouldCallDeprecatedContentTransformMethod(
1569  $content,
1570  $pstParams
1571  );
1572 
1573  if ( !$shouldCallDeprecatedMethod ) {
1574  return $content;
1575  }
1576 
1577  return $this->callDeprecatedContentPST(
1578  $content,
1579  $pstParams
1580  );
1581  }
1582 
1597  public function preloadTransform(
1598  Content $content,
1599  PreloadTransformParams $pltParams
1600  ): Content {
1601  $shouldCallDeprecatedMethod = $this->shouldCallDeprecatedContentTransformMethod(
1602  $content,
1603  $pltParams
1604  );
1605 
1606  if ( !$shouldCallDeprecatedMethod ) {
1607  return $content;
1608  }
1609 
1610  return $this->callDeprecatedContentPLT(
1611  $content,
1612  $pltParams
1613  );
1614  }
1615 
1634  public function validateSave(
1635  Content $content,
1636  ValidationParams $validationParams
1637  ) {
1638  $detectPSDeprecatedOverride = MWDebug::detectDeprecatedOverride(
1639  $content,
1640  AbstractContent::class,
1641  'prepareSave',
1642  '1.38'
1643  );
1644 
1645  if ( $detectPSDeprecatedOverride ) {
1646  $services = MediaWikiServices::getInstance();
1647  $page = $validationParams->getPageIdentity();
1648  $user = RequestContext::getMain()->getUser();
1649 
1650  if ( !( $page instanceof WikiPage ) ) {
1651  $wikiPageFactory = $services->getWikiPageFactory();
1652  $page = $wikiPageFactory->newFromTitle( $page );
1653  }
1654 
1655  return $content->prepareSave(
1656  $page,
1657  $validationParams->getFlags(),
1658  $validationParams->getParentRevisionId(),
1659  $user
1660  );
1661  }
1662 
1663  if ( $content->isValid() ) {
1664  return StatusValue::newGood();
1665  } else {
1666  return StatusValue::newFatal( "invalid-content-data" );
1667  }
1668  }
1669 
1686  public function getParserOutput(
1687  Content $content,
1688  ContentParseParams $cpoParams
1689  ) {
1690  $detectGPODeprecatedOverride = MWDebug::detectDeprecatedOverride(
1691  $content,
1692  AbstractContent::class,
1693  'getParserOutput',
1694  '1.38'
1695  );
1696  $detectFPODeprecatedOverride = MWDebug::detectDeprecatedOverride(
1697  $content,
1698  AbstractContent::class,
1699  'fillParserOutput',
1700  '1.38'
1701  );
1702  if ( $detectGPODeprecatedOverride || $detectFPODeprecatedOverride ) {
1703  return $this->callDeprecatedContentGPO( $content, $cpoParams );
1704  }
1705 
1706  $services = MediaWikiServices::getInstance();
1707  $title = $services->getTitleFactory()->castFromPageReference( $cpoParams->getPage() );
1708  $parserOptions = $cpoParams->getParserOptions();
1709 
1710  $po = new ParserOutput();
1711  $parserOptions->registerWatcher( [ $po, 'recordOption' ] );
1712  if ( Hooks::runner()->onContentGetParserOutput(
1713  $content, $title, $cpoParams->getRevId(), $parserOptions, $cpoParams->getGenerateHtml(), $po )
1714  ) {
1715  // Save and restore the old value, just in case something is reusing
1716  // the ParserOptions object in some weird way.
1717  $oldRedir = $parserOptions->getRedirectTarget();
1718  $parserOptions->setRedirectTarget( $content->getRedirectTarget() );
1719  $this->fillParserOutput(
1720  $content,
1721  $cpoParams,
1722  $po
1723  );
1724  MediaWikiServices::getInstance()->get( '_ParserObserver' )->notifyParse(
1725  $title,
1726  $cpoParams->getRevId(),
1727  $parserOptions,
1728  $po
1729  );
1730  $parserOptions->setRedirectTarget( $oldRedir );
1731  }
1732 
1733  Hooks::runner()->onContentAlterParserOutput( $content, $title, $po );
1734  $parserOptions->registerWatcher( null );
1735 
1736  return $po;
1737  }
1738 
1748  public function fillParserOutputInternal(
1749  Content $content,
1750  ContentParseParams $cpoParams,
1751  ParserOutput &$output
1752  ) {
1753  $this->fillParserOutput( $content, $cpoParams, $output );
1754  }
1755 
1774  protected function fillParserOutput(
1775  Content $content,
1776  ContentParseParams $cpoParams,
1777  ParserOutput &$output
1778  ) {
1779  // Subclasses must override fillParserOutput() to directly don't fail.
1780  throw new MWException( 'Subclasses of ContentHandler must override fillParserOutput!' );
1781  }
1782 
1792  Content $content,
1793  $params
1794  ): bool {
1795  $method = $params instanceof PreSaveTransformParams
1796  ? "preSaveTransform"
1797  : "preloadTransform";
1799  $content,
1800  AbstractContent::class,
1801  $method,
1802  '1.37'
1803  );
1804  }
1805 
1814  protected function callDeprecatedContentPST(
1815  Content $content,
1816  PreSaveTransformParams $params
1817  ): Content {
1818  $services = MediaWikiServices::getInstance();
1819  $legacyUser = $services->getUserFactory()->newFromUserIdentity( $params->getUser() );
1820  $legacyTitle = $services->getTitleFactory()->castFromPageReference( $params->getPage() );
1821 
1822  return $content->preSaveTransform(
1823  $legacyTitle,
1824  $legacyUser,
1825  $params->getParserOptions()
1826  );
1827  }
1828 
1837  protected function callDeprecatedContentPLT(
1838  Content $content,
1839  PreloadTransformParams $params
1840  ): Content {
1841  $services = MediaWikiServices::getInstance();
1842  $legacyTitle = $services->getTitleFactory()->castFromPageReference( $params->getPage() );
1843  return $content->preloadTransform(
1844  $legacyTitle,
1845  $params->getParserOptions(),
1846  $params->getParams()
1847  );
1848  }
1849 
1858  protected function callDeprecatedContentGPO(
1859  Content $content,
1860  ContentParseParams $cpoParams
1861  ) {
1862  $services = MediaWikiServices::getInstance();
1863  $legacyTitle = $services->getTitleFactory()->castFromPageReference( $cpoParams->getPage() );
1864  return $content->getParserOutput(
1865  $legacyTitle,
1866  $cpoParams->getRevId(),
1867  $cpoParams->getParserOptions(),
1868  $cpoParams->getGenerateHtml()
1869  );
1870  }
1871 }
SearchIndexField\INDEX_TYPE_KEYWORD
const INDEX_TYPE_KEYWORD
KEYWORD fields are indexed without any processing, so are appropriate for e.g.
Definition: SearchIndexField.php:24
ContentHandler\getSecondaryDataUpdates
getSecondaryDataUpdates(Title $title, Content $content, $role, SlotRenderingProvider $slotOutput)
Returns a list of DeferrableUpdate objects for recording information about the given Content in some ...
Definition: ContentHandler.php:1507
ContentHandler
A content handler knows how do deal with a specific type of content on a wiki page.
Definition: ContentHandler.php:62
ContentHandler\getForModelID
static getForModelID( $modelId)
Returns the ContentHandler singleton for the given model ID.
Definition: ContentHandler.php:277
ContentHandler\callDeprecatedContentPLT
callDeprecatedContentPLT(Content $content, PreloadTransformParams $params)
If provided content overrides deprecated Content::preloadTransform, call it and return.
Definition: ContentHandler.php:1837
MediaWiki\Content\Renderer\ContentParseParams\getRevId
getRevId()
Definition: ContentParseParams.php:48
MediaWiki\Content\Renderer\ContentParseParams\getPage
getPage()
Definition: ContentParseParams.php:40
MediaWiki\Revision\RevisionRecord
Page revision base class.
Definition: RevisionRecord.php:47
ContentHandler\getAllContentFormats
static getAllContentFormats()
Definition: ContentHandler.php:342
WikiPage\loadPageData
loadPageData( $from='fromdb')
Load the object from a given source by title.
Definition: WikiPage.php:468
DifferenceEngine\getEngine
static getEngine()
Process DiffEngine config and get a sensible, usable engine.
Definition: DifferenceEngine.php:1438
WikiPage\getRevisionRecord
getRevisionRecord()
Get the latest revision.
Definition: WikiPage.php:818
ParserOutput
Definition: ParserOutput.php:35
StatusValue\newFatal
static newFatal( $message,... $parameters)
Factory function for fatal errors.
Definition: StatusValue.php:70
NS_MEDIAWIKI
const NS_MEDIAWIKI
Definition: Defines.php:72
MediaWiki\Content\Renderer\ContentParseParams\getGenerateHtml
getGenerateHtml()
Definition: ContentParseParams.php:64
ContentHandler\supportsDirectEditing
supportsDirectEditing()
Return true if this content model supports direct editing, such as via EditPage.
Definition: ContentHandler.php:1271
MediaWiki\Content\ValidationParams\getPageIdentity
getPageIdentity()
Definition: ValidationParams.php:30
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:202
$lang
if(!isset( $args[0])) $lang
Definition: testCompression.php:37
ContentHandler\getSlotDiffRendererInternal
getSlotDiffRendererInternal(IContextSource $context)
Return the SlotDiffRenderer appropriate for this content handler.
Definition: ContentHandler.php:657
ContentHandler\preloadTransform
preloadTransform(Content $content, PreloadTransformParams $pltParams)
Returns a $content object with preload transformations applied (or the same object if no transformati...
Definition: ContentHandler.php:1597
ContentHandler\getActionOverrides
getActionOverrides()
Returns overrides for action handlers.
Definition: ContentHandler.php:579
ContentHandler\checkModelID
checkModelID( $model_id)
Definition: ContentHandler.php:487
ContentHandler\unserializeContent
unserializeContent( $blob, $format=null)
Unserializes a Content object of the type supported by this ContentHandler.
ContentHandler\getPageViewLanguage
getPageViewLanguage(Title $title, Content $content=null)
Get the language in which the content of this page is written when viewed by user.
Definition: ContentHandler.php:769
WikiPage
Class representing a MediaWiki article and history.
Definition: WikiPage.php:62
ContentHandler\$mSupportedFormats
string[] $mSupportedFormats
Definition: ContentHandler.php:356
WikiPage\makeParserOptions
makeParserOptions( $context)
Get parser options suitable for rendering the primary article wikitext.
Definition: WikiPage.php:2001
wfMessage
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
Definition: GlobalFunctions.php:1183
ContentHandler\getAutosummary
getAutosummary(Content $oldContent=null, Content $newContent=null, $flags=0)
Return an applicable auto-summary if one exists for the given edit.
Definition: ContentHandler.php:934
TextSlotDiffRenderer\ENGINE_EXTERNAL
const ENGINE_EXTERNAL
Use an external executable.
Definition: TextSlotDiffRenderer.php:50
ContentHandler\getDeletionUpdates
getDeletionUpdates(Title $title, $role)
Returns a list of DeferrableUpdate objects for removing information about content in some secondary d...
Definition: ContentHandler.php:1546
ContentHandler\getForTitle
static getForTitle(Title $title)
Returns the appropriate ContentHandler singleton for the given title.
Definition: ContentHandler.php:220
MediaWiki\Content\Transform\PreloadTransformParams
Definition: PreloadTransformParams.php:11
MediaWiki\Content\ValidationParams
Definition: ValidationParams.php:10
TextSlotDiffRenderer\ENGINE_WIKIDIFF2
const ENGINE_WIKIDIFF2
Use the wikidiff2 PHP module.
Definition: TextSlotDiffRenderer.php:44
SearchIndexField\FLAG_CASEFOLD
const FLAG_CASEFOLD
Generic field flags.
Definition: SearchIndexField.php:45
ContentHandler\getChangeTag
getChangeTag(Content $oldContent=null, Content $newContent=null, $flags=0)
Return an applicable tag if one exists for the given edit or return null.
Definition: ContentHandler.php:1022
MediaWiki\Content\Transform\PreSaveTransformParams\getUser
getUser()
$res
$res
Definition: testCompression.php:57
ContentHandler\serializeContent
serializeContent(Content $content, $format=null)
Serializes a Content object of the type supported by this ContentHandler.
ContentHandler\getUndoContent
getUndoContent(Content $currentContent, Content $undoContent, Content $undoAfterContent, $undoIsLatest=false)
Get the Content object that needs to be saved in order to undo all changes between $undo and $undoaft...
Definition: ContentHandler.php:1177
$revQuery
$revQuery
Definition: testCompression.php:56
$wgLang
$wgLang
Definition: Setup.php:857
ContentHandler\shouldCallDeprecatedContentTransformMethod
shouldCallDeprecatedContentTransformMethod(Content $content, $params)
Check if we need to provide content overrides deprecated Content method.
Definition: ContentHandler.php:1791
wfDebugLog
wfDebugLog( $logGroup, $text, $dest='all', array $context=[])
Send a line to a supplementary debug log file, if configured, or main debug log if not.
Definition: GlobalFunctions.php:958
ContentHandler\supportsSections
supportsSections()
Returns true if this content model supports sections.
Definition: ContentHandler.php:1233
MediaWiki\Content\Renderer\ContentParseParams
Definition: ContentParseParams.php:11
MediaWiki\Revision\SlotRenderingProvider
A lazy provider of ParserOutput objects for a revision's individual slots.
Definition: SlotRenderingProvider.php:12
ContentHandler\isSupportedFormat
isSupportedFormat( $format)
Returns true if $format is a serialization format supported by this ContentHandler,...
Definition: ContentHandler.php:539
MediaWiki\Content\Transform\PreloadTransformParams\getPage
getPage()
$dbr
$dbr
Definition: testCompression.php:54
ContentHandler\createDifferenceEngine
createDifferenceEngine(IContextSource $context, $old=0, $new=0, $rcid=0, $refreshCache=false, $unhide=false)
Factory for creating an appropriate DifferenceEngine for this content model.
Definition: ContentHandler.php:610
ContentHandler\canBeUsedOn
canBeUsedOn(Title $title)
Determines whether the content type handled by this ContentHandler can be used for the main slot of t...
Definition: ContentHandler.php:805
MediaWiki\Search\ParserOutputSearchDataExtractor
Extracts data from ParserOutput for indexing in the search engine.
Definition: ParserOutputSearchDataExtractor.php:29
ContentHandler\importTransform
importTransform( $blob, $format=null)
Apply import transformation (per default, returns $blob unchanged).
Definition: ContentHandler.php:430
ContentHandler\supportsRedirects
supportsRedirects()
Returns true if this content model supports redirects.
Definition: ContentHandler.php:1260
MediaWiki\Content\Transform\PreSaveTransformParams
Definition: PreSaveTransformParams.php:12
$wgContentHandlerTextFallback
$wgContentHandlerTextFallback
How to react if a plain text version of a non-text Content object is requested using ContentHandler::...
Definition: DefaultSettings.php:2470
ContentHandler\getDefaultModelFor
static getDefaultModelFor(Title $title)
Returns the name of the default content model to be used for the page with the given title.
Definition: ContentHandler.php:200
ContentHandler\validateSave
validateSave(Content $content, ValidationParams $validationParams)
Validate content for saving it.
Definition: ContentHandler.php:1634
MWException
MediaWiki exception.
Definition: MWException.php:29
wfDeprecated
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Logs a warning that a deprecated feature was used.
Definition: GlobalFunctions.php:997
MediaWiki\Logger\LoggerFactory
PSR-3 logger instance factory.
Definition: LoggerFactory.php:45
ContentHandler\generateHTMLOnEdit
generateHTMLOnEdit()
Whether an edit on the content should trigger an HTML render and ParserCache entry.
Definition: ContentHandler.php:1283
ContentHandler\getLanguageConverter
getLanguageConverter( $language)
Shorthand for getting a Language Converter for specific language.
Definition: ContentHandler.php:849
ContentHandler\getContentModels
static getContentModels()
Definition: ContentHandler.php:330
$blob
$blob
Definition: testCompression.php:70
ContentHandler\supportsDirectApiEditing
supportsDirectApiEditing()
Whether or not this content model supports direct editing via ApiEditPage.
Definition: ContentHandler.php:1294
wfGetDB
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
Definition: GlobalFunctions.php:2200
MediaWiki\Content\Renderer\ContentParseParams\getParserOptions
getParserOptions()
Definition: ContentParseParams.php:56
MediaWiki\Content\ValidationParams\getFlags
getFlags()
Definition: ValidationParams.php:38
WikiPage\getTitle
getTitle()
Get the title object of the article.
Definition: WikiPage.php:313
ContentHandler\getSlotDiffRendererWithOptions
getSlotDiffRendererWithOptions(IContextSource $context, $options=[])
Return the SlotDiffRenderer appropriate for this content handler.
Definition: ContentHandler.php:670
EDIT_NEW
const EDIT_NEW
Definition: Defines.php:125
wfGetLangObj
wfGetLangObj( $langcode=false)
Return a Language object from $langcode.
Definition: GlobalFunctions.php:1133
TextSlotDiffRenderer\ENGINE_PHP
const ENGINE_PHP
Use the PHP diff implementation (DiffEngine).
Definition: TextSlotDiffRenderer.php:41
ContentHandler\merge3
merge3(Content $oldContent, Content $myContent, Content $yourContent)
Attempts to merge differences between three versions.
Definition: ContentHandler.php:840
ChangeTags\getSoftwareTags
static getSoftwareTags( $all=false)
Loads defined core tags, checks for invalid types (if not array), and filters for supported and enabl...
Definition: ChangeTags.php:158
ContentHandler\makeEmptyContent
makeEmptyContent()
Creates an empty Content object of the type supported by this ContentHandler.
$title
$title
Definition: testCompression.php:38
ContentHandler\getDataForSearchIndex
getDataForSearchIndex(WikiPage $page, ParserOutput $output, SearchEngine $engine)
Return fields to be indexed by search engine as representation of this document.
Definition: ContentHandler.php:1379
TextSlotDiffRenderer\ENGINE_WIKIDIFF2_INLINE
const ENGINE_WIKIDIFF2_INLINE
Use the wikidiff2 PHP module.
Definition: TextSlotDiffRenderer.php:47
DB_REPLICA
const DB_REPLICA
Definition: defines.php:25
$revStore
$revStore
Definition: testCompression.php:55
ContentHandler\getSlotDiffRenderer
getSlotDiffRenderer(IContextSource $context, array $options=[])
Get an appropriate SlotDiffRenderer for this content model.
Definition: ContentHandler.php:631
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:148
ContentHandler\getParserOutput
getParserOutput(Content $content, ContentParseParams $cpoParams)
Returns a ParserOutput object containing information derived from this content.
Definition: ContentHandler.php:1686
ContentHandler\getPageLanguage
getPageLanguage(Title $title, Content $content=null)
Get the language in which the content of the given page is written.
Definition: ContentHandler.php:723
ContentHandler\isParserCacheSupported
isParserCacheSupported()
Returns true for content models that support caching using the ParserCache mechanism.
Definition: ContentHandler.php:1218
Content\equals
equals(Content $that=null)
Returns true if this Content objects is conceptually equivalent to the given Content object.
$content
$content
Definition: router.php:76
ContentHandler\getDefaultFormat
getDefaultFormat()
The format used for serialization/deserialization by default by this ContentHandler.
Definition: ContentHandler.php:521
ILanguageConverter
The shared interface for all language converters.
Definition: ILanguageConverter.php:29
ContentHandler\getChangeType
getChangeType(Content $oldContent=null, Content $newContent=null, $flags=0)
Return type of change if one exists for the given edit.
Definition: ContentHandler.php:866
WikiPage\getContent
getContent( $audience=RevisionRecord::FOR_PUBLIC, Authority $performer=null)
Get the content of the current revision.
Definition: WikiPage.php:839
ContentHandler\fillParserOutput
fillParserOutput(Content $content, ContentParseParams $cpoParams, ParserOutput &$output)
Fills the provided ParserOutput with information derived from the content.
Definition: ContentHandler.php:1774
ContentHandler\cleanupHandlersCache
static cleanupHandlersCache()
Definition: ContentHandler.php:290
MediaWiki\Content\ValidationParams\getParentRevisionId
getParentRevisionId()
Definition: ValidationParams.php:48
ContentHandler\getLocalizedName
static getLocalizedName( $name, Language $lang=null)
Returns the localized name for a given content model.
Definition: ContentHandler.php:309
StatusValue\newGood
static newGood( $value=null)
Factory function for good results.
Definition: StatusValue.php:82
ContentHandler\latestRevision
latestRevision(WikiPage $page)
Get the latest revision of the given $page, fetching it from the primary if necessary.
Definition: ContentHandler.php:1458
ContentHandler\getDiffEngineClass
getDiffEngineClass()
Returns the name of the diff engine to use.
Definition: ContentHandler.php:821
Hooks\runner
static runner()
Get a HookRunner instance for calling hooks using the new interfaces.
Definition: Hooks.php:173
ContentHandler\supportsCategories
supportsCategories()
Returns true if this content model supports categories.
Definition: ContentHandler.php:1245
ContentHandler\$mModelID
string $mModelID
Definition: ContentHandler.php:351
ContentHandler\preSaveTransform
preSaveTransform(Content $content, PreSaveTransformParams $pstParams)
Returns a $content object with pre-save transformations applied (or the same object if no transformat...
Definition: ContentHandler.php:1564
RequestContext\getMain
static getMain()
Get the RequestContext object associated with the main request.
Definition: RequestContext.php:484
MediaWiki\Content\Transform\PreloadTransformParams\getParams
getParams()
TextContent
Content object implementation for representing flat text.
Definition: TextContent.php:39
SearchEngine
Contain a class for special pages.
Definition: SearchEngine.php:37
IContextSource
Interface for objects which can provide a MediaWiki context on request.
Definition: IContextSource.php:58
ContentHandler\exportTransform
exportTransform( $blob, $format=null)
Applies transformations on export (returns the blob unchanged per default).
Definition: ContentHandler.php:400
Content
Base interface for content objects.
Definition: Content.php:35
ContentHandler\getFieldsForSearchIndex
getFieldsForSearchIndex(SearchEngine $engine)
Get fields definition for search index.
Definition: ContentHandler.php:1310
CommentStore\COMMENT_CHARACTER_LIMIT
const COMMENT_CHARACTER_LIMIT
Maximum length of a comment in UTF-8 characters.
Definition: CommentStore.php:48
SearchEngine\makeSearchFieldMapping
makeSearchFieldMapping( $name, $type)
Create a search field definition.
Definition: SearchEngine.php:776
Title
Represents a title within MediaWiki.
Definition: Title.php:47
MWDebug\detectDeprecatedOverride
static detectDeprecatedOverride( $instance, $class, $method, $version=false, $component=false, $callerOffset=2)
Show a warning if $method declared in $class is overridden in $instance.
Definition: MWDebug.php:257
ContentHandler\makeRedirectContent
makeRedirectContent(Title $destination, $text='')
Creates a new Content object that acts as a redirect to the given page, or null if redirects are not ...
Definition: ContentHandler.php:463
ContentHandler\checkFormat
checkFormat( $format)
Convenient for checking whether a format provided as a parameter is actually supported.
Definition: ContentHandler.php:554
ContentHandler\getContentText
static getContentText(Content $content=null)
Convenience function for getting flat text from a Content object.
Definition: ContentHandler.php:97
$cache
$cache
Definition: mcc.php:33
MediaWiki\Content\Transform\PreloadTransformParams\getParserOptions
getParserOptions()
DifferenceEngineSlotDiffRenderer
B/C adapter for turning a DifferenceEngine into a SlotDiffRenderer.
Definition: DifferenceEngineSlotDiffRenderer.php:32
ParserCache
Cache for ParserOutput objects corresponding to the latest page revisions.
Definition: ParserCache.php:63
Content\getModel
getModel()
Returns the ID of the content model used by this Content object.
MediaWiki\Content\Transform\PreSaveTransformParams\getParserOptions
getParserOptions()
ContentHandler\getAutoDeleteReason
getAutoDeleteReason(Title $title, &$hasHistory=false)
Auto-generates a deletion reason.
Definition: ContentHandler.php:1059
ContentHandler\addSearchField
addSearchField(&$fields, SearchEngine $engine, $name, $type)
Add new field definition to array.
Definition: ContentHandler.php:1351
ContentHandler\callDeprecatedContentPST
callDeprecatedContentPST(Content $content, PreSaveTransformParams $params)
Provided content overrides deprecated Content::preSaveTransform, call it and return.
Definition: ContentHandler.php:1814
ContentHandler\__construct
__construct( $modelId, $formats)
Constructor, initializing the ContentHandler instance with its model ID and a list of supported forma...
Definition: ContentHandler.php:369
StubObject\unstub
static unstub(&$obj)
Unstubs an object, if it is a stub object.
Definition: StubObject.php:101
ContentHandler\fillParserOutputInternal
fillParserOutputInternal(Content $content, ContentParseParams $cpoParams, ParserOutput &$output)
A temporary layer to move AbstractContent::fillParserOutput to ContentHandler::fillParserOutput.
Definition: ContentHandler.php:1748
ContentHandler\callDeprecatedContentGPO
callDeprecatedContentGPO(Content $content, ContentParseParams $cpoParams)
If provided content overrides deprecated Content::getParserOutput, call it and return.
Definition: ContentHandler.php:1858
ContentHandler\getSupportedFormats
getSupportedFormats()
Returns a list of serialization formats supported by the serializeContent() and unserializeContent() ...
Definition: ContentHandler.php:505
Language
Internationalisation code See https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation for more...
Definition: Language.php:42
ContentHandler\getModelID
getModelID()
Returns the model id that identifies the content model this ContentHandler can handle.
Definition: ContentHandler.php:475
MediaWiki\Revision\SlotRecord
Value object representing a content slot associated with a page revision.
Definition: SlotRecord.php:40
ContentHandler\getForContent
static getForContent(Content $content)
Returns the appropriate ContentHandler singleton for the given Content object.
Definition: ContentHandler.php:242
ContentHandler\getParserOutputForIndexing
getParserOutputForIndexing(WikiPage $page, ParserCache $cache=null)
Produce page output suitable for indexing.
Definition: ContentHandler.php:1424
MediaWiki\Content\Transform\PreSaveTransformParams\getPage
getPage()
TextSlotDiffRenderer
Renders a slot diff by doing a text diff on the native representation.
Definition: TextSlotDiffRenderer.php:38
SearchIndexField\INDEX_TYPE_TEXT
const INDEX_TYPE_TEXT
TEXT fields are suitable for natural language and may be subject to analysis such as stemming.
Definition: SearchIndexField.php:19
$type
$type
Definition: testCompression.php:52