MediaWiki REL1_31
ContentHandler.php
Go to the documentation of this file.
1<?php
2
4
49abstract class ContentHandler {
79 public static function getContentText( Content $content = null ) {
81
82 if ( is_null( $content ) ) {
83 return '';
84 }
85
86 if ( $content instanceof TextContent ) {
87 return $content->getNativeData();
88 }
89
90 wfDebugLog( 'ContentHandler', 'Accessing ' . $content->getModel() . ' content as text!' );
91
92 if ( $wgContentHandlerTextFallback == 'fail' ) {
93 throw new MWException(
94 "Attempt to get text from Content with model " .
95 $content->getModel()
96 );
97 }
98
99 if ( $wgContentHandlerTextFallback == 'serialize' ) {
100 return $content->serialize();
101 }
102
103 return null;
104 }
105
129 public static function makeContent( $text, Title $title = null,
130 $modelId = null, $format = null ) {
131 if ( is_null( $modelId ) ) {
132 if ( is_null( $title ) ) {
133 throw new MWException( "Must provide a Title object or a content model ID." );
134 }
135
136 $modelId = $title->getContentModel();
137 }
138
139 $handler = self::getForModelID( $modelId );
140
141 return $handler->unserializeContent( $text, $format );
142 }
143
178 public static function getDefaultModelFor( Title $title ) {
179 // NOTE: this method must not rely on $title->getContentModel() directly or indirectly,
180 // because it is used to initialize the mContentModel member.
181
182 $ns = $title->getNamespace();
183
184 $ext = false;
185 $m = null;
186 $model = MWNamespace::getNamespaceContentModel( $ns );
187
188 // Hook can determine default model
189 if ( !Hooks::run( 'ContentHandlerDefaultModelFor', [ $title, &$model ] ) ) {
190 if ( !is_null( $model ) ) {
191 return $model;
192 }
193 }
194
195 // Could this page contain code based on the title?
196 $isCodePage = NS_MEDIAWIKI == $ns && preg_match( '!\.(css|js|json)$!u', $title->getText(), $m );
197 if ( $isCodePage ) {
198 $ext = $m[1];
199 }
200
201 // Is this a user subpage containing code?
202 $isCodeSubpage = NS_USER == $ns
203 && !$isCodePage
204 && preg_match( "/\\/.*\\.(js|css|json)$/", $title->getText(), $m );
205 if ( $isCodeSubpage ) {
206 $ext = $m[1];
207 }
208
209 // Is this wikitext, according to $wgNamespaceContentModels or the DefaultModelFor hook?
210 $isWikitext = is_null( $model ) || $model == CONTENT_MODEL_WIKITEXT;
211 $isWikitext = $isWikitext && !$isCodePage && !$isCodeSubpage;
212
213 if ( !$isWikitext ) {
214 switch ( $ext ) {
215 case 'js':
217 case 'css':
218 return CONTENT_MODEL_CSS;
219 case 'json':
220 return CONTENT_MODEL_JSON;
221 default:
222 return is_null( $model ) ? CONTENT_MODEL_TEXT : $model;
223 }
224 }
225
226 // We established that it must be wikitext
227
229 }
230
240 public static function getForTitle( Title $title ) {
241 $modelId = $title->getContentModel();
242
243 return self::getForModelID( $modelId );
244 }
245
256 public static function getForContent( Content $content ) {
257 $modelId = $content->getModel();
258
259 return self::getForModelID( $modelId );
260 }
261
265 protected static $handlers;
266
293 public static function getForModelID( $modelId ) {
294 global $wgContentHandlers;
295
296 if ( isset( self::$handlers[$modelId] ) ) {
297 return self::$handlers[$modelId];
298 }
299
300 if ( empty( $wgContentHandlers[$modelId] ) ) {
301 $handler = null;
302
303 Hooks::run( 'ContentHandlerForModelID', [ $modelId, &$handler ] );
304
305 if ( $handler === null ) {
306 throw new MWUnknownContentModelException( $modelId );
307 }
308
309 if ( !( $handler instanceof ContentHandler ) ) {
310 throw new MWException( "ContentHandlerForModelID must supply a ContentHandler instance" );
311 }
312 } else {
313 $classOrCallback = $wgContentHandlers[$modelId];
314
315 if ( is_callable( $classOrCallback ) ) {
316 $handler = call_user_func( $classOrCallback, $modelId );
317 } else {
318 $handler = new $classOrCallback( $modelId );
319 }
320
321 if ( !( $handler instanceof ContentHandler ) ) {
322 throw new MWException( "$classOrCallback from \$wgContentHandlers is not " .
323 "compatible with ContentHandler" );
324 }
325 }
326
327 wfDebugLog( 'ContentHandler', 'Created handler for ' . $modelId
328 . ': ' . get_class( $handler ) );
329
330 self::$handlers[$modelId] = $handler;
331
332 return self::$handlers[$modelId];
333 }
334
338 public static function cleanupHandlersCache() {
339 self::$handlers = [];
340 }
341
355 public static function getLocalizedName( $name, Language $lang = null ) {
356 // Messages: content-model-wikitext, content-model-text,
357 // content-model-javascript, content-model-css
358 $key = "content-model-$name";
359
360 $msg = wfMessage( $key );
361 if ( $lang ) {
362 $msg->inLanguage( $lang );
363 }
364
365 return $msg->exists() ? $msg->plain() : $name;
366 }
367
368 public static function getContentModels() {
369 global $wgContentHandlers;
370
371 $models = array_keys( $wgContentHandlers );
372 Hooks::run( 'GetContentModels', [ &$models ] );
373 return $models;
374 }
375
376 public static function getAllContentFormats() {
377 global $wgContentHandlers;
378
379 $formats = [];
380
381 foreach ( $wgContentHandlers as $model => $class ) {
382 $handler = self::getForModelID( $model );
383 $formats = array_merge( $formats, $handler->getSupportedFormats() );
384 }
385
386 $formats = array_unique( $formats );
387
388 return $formats;
389 }
390
391 // ------------------------------------------------------------------------
392
396 protected $mModelID;
397
402
412 public function __construct( $modelId, $formats ) {
413 $this->mModelID = $modelId;
414 $this->mSupportedFormats = $formats;
415 }
416
427 abstract public function serializeContent( Content $content, $format = null );
428
439 public function exportTransform( $blob, $format = null ) {
440 return $blob;
441 }
442
453 abstract public function unserializeContent( $blob, $format = null );
454
466 public function importTransform( $blob, $format = null ) {
467 return $blob;
468 }
469
478 abstract public function makeEmptyContent();
479
497 public function makeRedirectContent( Title $destination, $text = '' ) {
498 return null;
499 }
500
509 public function getModelID() {
510 return $this->mModelID;
511 }
512
521 protected function checkModelID( $model_id ) {
522 if ( $model_id !== $this->mModelID ) {
523 throw new MWException( "Bad content model: " .
524 "expected {$this->mModelID} " .
525 "but got $model_id." );
526 }
527 }
528
538 public function getSupportedFormats() {
539 return $this->mSupportedFormats;
540 }
541
553 public function getDefaultFormat() {
554 return $this->mSupportedFormats[0];
555 }
556
570 public function isSupportedFormat( $format ) {
571 if ( !$format ) {
572 return true; // this means "use the default"
573 }
574
575 return in_array( $format, $this->mSupportedFormats );
576 }
577
585 protected function checkFormat( $format ) {
586 if ( !$this->isSupportedFormat( $format ) ) {
587 throw new MWException(
588 "Format $format is not supported for content model "
589 . $this->getModelID()
590 );
591 }
592 }
593
609 public function getActionOverrides() {
610 return [];
611 }
612
627 public function createDifferenceEngine( IContextSource $context, $old = 0, $new = 0,
628 $rcid = 0, // FIXME: Deprecated, no longer used
629 $refreshCache = false, $unhide = false
630 ) {
631 // hook: get difference engine
632 $differenceEngine = null;
633 if ( !Hooks::run( 'GetDifferenceEngine',
635 ) ) {
636 return $differenceEngine;
637 }
638 $diffEngineClass = $this->getDiffEngineClass();
639 return new $diffEngineClass( $context, $old, $new, $rcid, $refreshCache, $unhide );
640 }
641
661 public function getPageLanguage( Title $title, Content $content = null ) {
662 global $wgContLang, $wgLang;
663 $pageLang = $wgContLang;
664
665 if ( $title->getNamespace() == NS_MEDIAWIKI ) {
666 // Parse mediawiki messages with correct target language
667 list( /* $unused */, $lang ) = MessageCache::singleton()->figureMessage( $title->getText() );
668 $pageLang = Language::factory( $lang );
669 }
670
671 Hooks::run( 'PageContentLanguage', [ $title, &$pageLang, $wgLang ] );
672
673 return wfGetLangObj( $pageLang );
674 }
675
696 public function getPageViewLanguage( Title $title, Content $content = null ) {
697 $pageLang = $this->getPageLanguage( $title, $content );
698
699 if ( $title->getNamespace() !== NS_MEDIAWIKI ) {
700 // If the user chooses a variant, the content is actually
701 // in a language whose code is the variant code.
702 $variant = $pageLang->getPreferredVariant();
703 if ( $pageLang->getCode() !== $variant ) {
704 $pageLang = Language::factory( $variant );
705 }
706 }
707
708 return $pageLang;
709 }
710
727 public function canBeUsedOn( Title $title ) {
728 $ok = true;
729
730 Hooks::run( 'ContentModelCanBeUsedOn', [ $this->getModelID(), $title, &$ok ] );
731
732 return $ok;
733 }
734
742 protected function getDiffEngineClass() {
743 return DifferenceEngine::class;
744 }
745
760 public function merge3( Content $oldContent, Content $myContent, Content $yourContent ) {
761 return false;
762 }
763
775 private function getChangeType(
776 Content $oldContent = null,
777 Content $newContent = null,
778 $flags = 0
779 ) {
780 $oldTarget = $oldContent !== null ? $oldContent->getRedirectTarget() : null;
781 $newTarget = $newContent !== null ? $newContent->getRedirectTarget() : null;
782
783 // We check for the type of change in the given edit, and return string key accordingly
784
785 // Blanking of a page
786 if ( $oldContent && $oldContent->getSize() > 0 &&
787 $newContent && $newContent->getSize() === 0
788 ) {
789 return 'blank';
790 }
791
792 // Redirects
793 if ( $newTarget ) {
794 if ( !$oldTarget ) {
795 // New redirect page (by creating new page or by changing content page)
796 return 'new-redirect';
797 } elseif ( !$newTarget->equals( $oldTarget ) ||
798 $oldTarget->getFragment() !== $newTarget->getFragment()
799 ) {
800 // Redirect target changed
801 return 'changed-redirect-target';
802 }
803 } elseif ( $oldTarget ) {
804 // Changing an existing redirect into a non-redirect
805 return 'removed-redirect';
806 }
807
808 // New page created
809 if ( $flags & EDIT_NEW && $newContent ) {
810 if ( $newContent->getSize() === 0 ) {
811 // New blank page
812 return 'newblank';
813 } else {
814 return 'newpage';
815 }
816 }
817
818 // Removing more than 90% of the page
819 if ( $oldContent && $newContent && $oldContent->getSize() > 10 * $newContent->getSize() ) {
820 return 'replace';
821 }
822
823 // Content model changed
824 if ( $oldContent && $newContent && $oldContent->getModel() !== $newContent->getModel() ) {
825 return 'contentmodelchange';
826 }
827
828 return null;
829 }
830
842 public function getAutosummary(
843 Content $oldContent = null,
844 Content $newContent = null,
845 $flags = 0
846 ) {
847 $changeType = $this->getChangeType( $oldContent, $newContent, $flags );
848
849 // There's no applicable auto-summary for our case, so our auto-summary is empty.
850 if ( !$changeType ) {
851 return '';
852 }
853
854 // Decide what kind of auto-summary is needed.
855 switch ( $changeType ) {
856 case 'new-redirect':
857 $newTarget = $newContent->getRedirectTarget();
858 $truncatedtext = $newContent->getTextForSummary(
859 250
860 - strlen( wfMessage( 'autoredircomment' )->inContentLanguage()->text() )
861 - strlen( $newTarget->getFullText() )
862 );
863
864 return wfMessage( 'autoredircomment', $newTarget->getFullText() )
865 ->plaintextParams( $truncatedtext )->inContentLanguage()->text();
866 case 'changed-redirect-target':
867 $oldTarget = $oldContent->getRedirectTarget();
868 $newTarget = $newContent->getRedirectTarget();
869
870 $truncatedtext = $newContent->getTextForSummary(
871 250
872 - strlen( wfMessage( 'autosumm-changed-redirect-target' )
873 ->inContentLanguage()->text() )
874 - strlen( $oldTarget->getFullText() )
875 - strlen( $newTarget->getFullText() )
876 );
877
878 return wfMessage( 'autosumm-changed-redirect-target',
879 $oldTarget->getFullText(),
880 $newTarget->getFullText() )
881 ->rawParams( $truncatedtext )->inContentLanguage()->text();
882 case 'removed-redirect':
883 $oldTarget = $oldContent->getRedirectTarget();
884 $truncatedtext = $newContent->getTextForSummary(
885 250
886 - strlen( wfMessage( 'autosumm-removed-redirect' )
887 ->inContentLanguage()->text() )
888 - strlen( $oldTarget->getFullText() ) );
889
890 return wfMessage( 'autosumm-removed-redirect', $oldTarget->getFullText() )
891 ->rawParams( $truncatedtext )->inContentLanguage()->text();
892 case 'newpage':
893 // If they're making a new article, give its text, truncated, in the summary.
894 $truncatedtext = $newContent->getTextForSummary(
895 200 - strlen( wfMessage( 'autosumm-new' )->inContentLanguage()->text() ) );
896
897 return wfMessage( 'autosumm-new' )->rawParams( $truncatedtext )
898 ->inContentLanguage()->text();
899 case 'blank':
900 return wfMessage( 'autosumm-blank' )->inContentLanguage()->text();
901 case 'replace':
902 $truncatedtext = $newContent->getTextForSummary(
903 200 - strlen( wfMessage( 'autosumm-replace' )->inContentLanguage()->text() ) );
904
905 return wfMessage( 'autosumm-replace' )->rawParams( $truncatedtext )
906 ->inContentLanguage()->text();
907 case 'newblank':
908 return wfMessage( 'autosumm-newblank' )->inContentLanguage()->text();
909 default:
910 return '';
911 }
912 }
913
925 public function getChangeTag(
926 Content $oldContent = null,
927 Content $newContent = null,
928 $flags = 0
929 ) {
930 $changeType = $this->getChangeType( $oldContent, $newContent, $flags );
931
932 // There's no applicable tag for this change.
933 if ( !$changeType ) {
934 return null;
935 }
936
937 // Core tags use the same keys as ones returned from $this->getChangeType()
938 // but prefixed with pseudo namespace 'mw-', so we add the prefix before checking
939 // if this type of change should be tagged
940 $tag = 'mw-' . $changeType;
941
942 // Not all change types are tagged, so we check against the list of defined tags.
943 if ( in_array( $tag, ChangeTags::getSoftwareTags() ) ) {
944 return $tag;
945 }
946
947 return null;
948 }
949
965 public function getAutoDeleteReason( Title $title, &$hasHistory ) {
967
968 // Get the last revision
969 $rev = Revision::newFromTitle( $title );
970
971 if ( is_null( $rev ) ) {
972 return false;
973 }
974
975 // Get the article's contents
976 $content = $rev->getContent();
977 $blank = false;
978
979 // If the page is blank, use the text from the previous revision,
980 // which can only be blank if there's a move/import/protect dummy
981 // revision involved
982 if ( !$content || $content->isEmpty() ) {
983 $prev = $rev->getPrevious();
984
985 if ( $prev ) {
986 $rev = $prev;
987 $content = $rev->getContent();
988 $blank = true;
989 }
990 }
991
992 $this->checkModelID( $rev->getContentModel() );
993
994 // Find out if there was only one contributor
995 // Only scan the last 20 revisions
996 $revQuery = Revision::getQueryInfo();
997 $res = $dbr->select(
998 $revQuery['tables'],
999 [ 'rev_user_text' => $revQuery['fields']['rev_user_text'] ],
1000 [
1001 'rev_page' => $title->getArticleID(),
1002 $dbr->bitAnd( 'rev_deleted', Revision::DELETED_USER ) . ' = 0'
1003 ],
1004 __METHOD__,
1005 [ 'LIMIT' => 20 ],
1006 $revQuery['joins']
1007 );
1008
1009 if ( $res === false ) {
1010 // This page has no revisions, which is very weird
1011 return false;
1012 }
1013
1014 $hasHistory = ( $res->numRows() > 1 );
1015 $row = $dbr->fetchObject( $res );
1016
1017 if ( $row ) { // $row is false if the only contributor is hidden
1018 $onlyAuthor = $row->rev_user_text;
1019 // Try to find a second contributor
1020 foreach ( $res as $row ) {
1021 if ( $row->rev_user_text != $onlyAuthor ) { // T24999
1022 $onlyAuthor = false;
1023 break;
1024 }
1025 }
1026 } else {
1027 $onlyAuthor = false;
1028 }
1029
1030 // Generate the summary with a '$1' placeholder
1031 if ( $blank ) {
1032 // The current revision is blank and the one before is also
1033 // blank. It's just not our lucky day
1034 $reason = wfMessage( 'exbeforeblank', '$1' )->inContentLanguage()->text();
1035 } else {
1036 if ( $onlyAuthor ) {
1037 $reason = wfMessage(
1038 'excontentauthor',
1039 '$1',
1040 $onlyAuthor
1041 )->inContentLanguage()->text();
1042 } else {
1043 $reason = wfMessage( 'excontent', '$1' )->inContentLanguage()->text();
1044 }
1045 }
1046
1047 if ( $reason == '-' ) {
1048 // Allow these UI messages to be blanked out cleanly
1049 return '';
1050 }
1051
1052 // Max content length = max comment length - length of the comment (excl. $1)
1053 $text = $content ? $content->getTextForSummary( 255 - ( strlen( $reason ) - 2 ) ) : '';
1054
1055 // Now replace the '$1' placeholder
1056 $reason = str_replace( '$1', $text, $reason );
1057
1058 return $reason;
1059 }
1060
1074 public function getUndoContent( Revision $current, Revision $undo, Revision $undoafter ) {
1075 $cur_content = $current->getContent();
1076
1077 if ( empty( $cur_content ) ) {
1078 return false; // no page
1079 }
1080
1081 $undo_content = $undo->getContent();
1082 $undoafter_content = $undoafter->getContent();
1083
1084 if ( !$undo_content || !$undoafter_content ) {
1085 return false; // no content to undo
1086 }
1087
1088 try {
1089 $this->checkModelID( $cur_content->getModel() );
1090 $this->checkModelID( $undo_content->getModel() );
1091 if ( $current->getId() !== $undo->getId() ) {
1092 // If we are undoing the most recent revision,
1093 // its ok to revert content model changes. However
1094 // if we are undoing a revision in the middle, then
1095 // doing that will be confusing.
1096 $this->checkModelID( $undoafter_content->getModel() );
1097 }
1098 } catch ( MWException $e ) {
1099 // If the revisions have different content models
1100 // just return false
1101 return false;
1102 }
1103
1104 if ( $cur_content->equals( $undo_content ) ) {
1105 // No use doing a merge if it's just a straight revert.
1106 return $undoafter_content;
1107 }
1108
1109 $undone_content = $this->merge3( $undo_content, $undoafter_content, $cur_content );
1110
1111 return $undone_content;
1112 }
1113
1128 public function makeParserOptions( $context ) {
1129 global $wgContLang;
1130
1131 if ( $context instanceof IContextSource ) {
1132 $user = $context->getUser();
1133 $lang = $context->getLanguage();
1134 } elseif ( $context instanceof User ) { // settings per user (even anons)
1135 $user = $context;
1136 $lang = null;
1137 } elseif ( $context === 'canonical' ) { // canonical settings
1138 $user = new User;
1140 } else {
1141 throw new MWException( "Bad context for parser options: $context" );
1142 }
1143
1144 return ParserOptions::newCanonical( $user, $lang );
1145 }
1146
1155 public function isParserCacheSupported() {
1156 return false;
1157 }
1158
1168 public function supportsSections() {
1169 return false;
1170 }
1171
1178 public function supportsCategories() {
1179 return true;
1180 }
1181
1191 public function supportsRedirects() {
1192 return false;
1193 }
1194
1200 public function supportsDirectEditing() {
1201 return false;
1202 }
1203
1209 public function supportsDirectApiEditing() {
1210 return $this->supportsDirectEditing();
1211 }
1212
1224 $fields['category'] = $engine->makeSearchFieldMapping(
1225 'category',
1227 );
1228 $fields['category']->setFlag( SearchIndexField::FLAG_CASEFOLD );
1229
1230 $fields['external_link'] = $engine->makeSearchFieldMapping(
1231 'external_link',
1233 );
1234
1235 $fields['outgoing_link'] = $engine->makeSearchFieldMapping(
1236 'outgoing_link',
1238 );
1239
1240 $fields['template'] = $engine->makeSearchFieldMapping(
1241 'template',
1243 );
1244 $fields['template']->setFlag( SearchIndexField::FLAG_CASEFOLD );
1245
1246 $fields['content_model'] = $engine->makeSearchFieldMapping(
1247 'content_model',
1249 );
1250
1251 return $fields;
1252 }
1253
1263 protected function addSearchField( &$fields, SearchEngine $engine, $name, $type ) {
1264 $fields[$name] = $engine->makeSearchFieldMapping( $name, $type );
1265 return $fields;
1266 }
1267
1279 public function getDataForSearchIndex(
1280 WikiPage $page,
1283 ) {
1284 $fieldData = [];
1285 $content = $page->getContent();
1286
1287 if ( $content ) {
1288 $searchDataExtractor = new ParserOutputSearchDataExtractor();
1289
1290 $fieldData['category'] = $searchDataExtractor->getCategories( $output );
1291 $fieldData['external_link'] = $searchDataExtractor->getExternalLinks( $output );
1292 $fieldData['outgoing_link'] = $searchDataExtractor->getOutgoingLinks( $output );
1293 $fieldData['template'] = $searchDataExtractor->getTemplates( $output );
1294
1295 $text = $content->getTextForSearchIndex();
1296
1297 $fieldData['text'] = $text;
1298 $fieldData['source_text'] = $text;
1299 $fieldData['text_bytes'] = $content->getSize();
1300 $fieldData['content_model'] = $content->getModel();
1301 }
1302
1303 Hooks::run( 'SearchDataForIndex', [ &$fieldData, $this, $page, $output, $engine ] );
1304 return $fieldData;
1305 }
1306
1316 public function getParserOutputForIndexing( WikiPage $page, ParserCache $cache = null ) {
1317 $parserOptions = $page->makeParserOptions( 'canonical' );
1318 $revId = $page->getRevision()->getId();
1319 if ( $cache ) {
1320 $parserOutput = $cache->get( $page, $parserOptions );
1321 }
1322 if ( empty( $parserOutput ) ) {
1323 $parserOutput =
1324 $page->getContent()->getParserOutput( $page->getTitle(), $revId, $parserOptions );
1325 if ( $cache ) {
1326 $cache->save( $parserOutput, $page, $parserOptions );
1327 }
1328 }
1329 return $parserOutput;
1330 }
1331
1332}
$wgContentHandlerTextFallback
How to react if a plain text version of a non-text Content object is requested using ContentHandler::...
$wgContentHandlers
Plugins for page content model handling.
wfGetLangObj( $langcode=false)
Return a Language object from $langcode.
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
wfDebugLog( $logGroup, $text, $dest='all', array $context=[])
Send a line to a supplementary debug log file, if configured, or main debug log if not.
static getSoftwareTags( $all=false)
Loads defined core tags, checks for invalid types (if not array), and filters for supported and enabl...
A content handler knows how do deal with a specific type of content on a wiki page.
getParserOutputForIndexing(WikiPage $page, ParserCache $cache=null)
Produce page output suitable for indexing.
getModelID()
Returns the model id that identifies the content model this ContentHandler can handle.
makeRedirectContent(Title $destination, $text='')
Creates a new Content object that acts as a redirect to the given page, or null if redirects are not ...
__construct( $modelId, $formats)
Constructor, initializing the ContentHandler instance with its model ID and a list of supported forma...
static getAllContentFormats()
string[] $mSupportedFormats
getChangeType(Content $oldContent=null, Content $newContent=null, $flags=0)
Return type of change if one exists for the given edit.
checkModelID( $model_id)
static makeContent( $text, Title $title=null, $modelId=null, $format=null)
Convenience function for creating a Content object from a given textual representation.
importTransform( $blob, $format=null)
Apply import transformation (per default, returns $blob unchanged).
isParserCacheSupported()
Returns true for content models that support caching using the ParserCache mechanism.
static getForModelID( $modelId)
Returns the ContentHandler singleton for the given model ID.
supportsDirectApiEditing()
Whether or not this content model supports direct editing via ApiEditPage.
getAutoDeleteReason(Title $title, &$hasHistory)
Auto-generates a deletion reason.
getChangeTag(Content $oldContent=null, Content $newContent=null, $flags=0)
Return an applicable tag if one exists for the given edit or return null.
getDiffEngineClass()
Returns the name of the diff engine to use.
static getForTitle(Title $title)
Returns the appropriate ContentHandler singleton for the given title.
exportTransform( $blob, $format=null)
Applies transformations on export (returns the blob unchanged per default).
merge3(Content $oldContent, Content $myContent, Content $yourContent)
Attempts to merge differences between three versions.
getAutosummary(Content $oldContent=null, Content $newContent=null, $flags=0)
Return an applicable auto-summary if one exists for the given edit.
checkFormat( $format)
Convenient for checking whether a format provided as a parameter is actually supported.
addSearchField(&$fields, SearchEngine $engine, $name, $type)
Add new field definition to array.
getActionOverrides()
Returns overrides for action handlers.
createDifferenceEngine(IContextSource $context, $old=0, $new=0, $rcid=0, $refreshCache=false, $unhide=false)
Factory for creating an appropriate DifferenceEngine for this content model.
getUndoContent(Revision $current, Revision $undo, Revision $undoafter)
Get the Content object that needs to be saved in order to undo all revisions between $undo and $undoa...
static getContentModels()
getPageLanguage(Title $title, Content $content=null)
Get the language in which the content of the given page is written.
getDefaultFormat()
The format used for serialization/deserialization by default by this ContentHandler.
static getDefaultModelFor(Title $title)
Returns the name of the default content model to be used for the page with the given title.
unserializeContent( $blob, $format=null)
Unserializes a Content object of the type supported by this ContentHandler.
static getLocalizedName( $name, Language $lang=null)
Returns the localized name for a given content model.
supportsDirectEditing()
Return true if this content model supports direct editing, such as via EditPage.
isSupportedFormat( $format)
Returns true if $format is a serialization format supported by this ContentHandler,...
getSupportedFormats()
Returns a list of serialization formats supported by the serializeContent() and unserializeContent() ...
supportsSections()
Returns true if this content model supports sections.
static cleanupHandlersCache()
Clean up handlers cache.
static getContentText(Content $content=null)
Convenience function for getting flat text from a Content object.
getDataForSearchIndex(WikiPage $page, ParserOutput $output, SearchEngine $engine)
Return fields to be indexed by search engine as representation of this document.
supportsCategories()
Returns true if this content model supports categories.
static getForContent(Content $content)
Returns the appropriate ContentHandler singleton for the given Content object.
supportsRedirects()
Returns true if this content model supports redirects.
canBeUsedOn(Title $title)
Determines whether the content type handled by this ContentHandler can be used on the given page.
serializeContent(Content $content, $format=null)
Serializes a Content object of the type supported by this ContentHandler.
makeEmptyContent()
Creates an empty Content object of the type supported by this ContentHandler.
static array $handlers
A Cache of ContentHandler instances by model id.
makeParserOptions( $context)
Get parser options suitable for rendering and caching the article.
getFieldsForSearchIndex(SearchEngine $engine)
Get fields definition for search index.
getPageViewLanguage(Title $title, Content $content=null)
Get the language in which the content of this page is written when viewed by user.
Internationalisation code.
Definition Language.php:35
MediaWiki exception.
Exception thrown when an unregistered content model is requested.
Extracts data from ParserOutput for indexing in the search engine.
static singleton()
Get the signleton instance of this class.
getId()
Get revision ID.
Definition Revision.php:617
getContent( $audience=self::FOR_PUBLIC, User $user=null)
Fetch revision content if it's available to the specified audience.
Definition Revision.php:929
Contain a class for special pages.
Content object implementation for representing flat text.
Represents a title within MediaWiki.
Definition Title.php:39
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition User.php:53
Class representing a MediaWiki article and history.
Definition WikiPage.php:37
getRevision()
Get the latest revision.
Definition WikiPage.php:697
makeParserOptions( $context)
Get parser options suitable for rendering the primary article wikitext.
getContent( $audience=Revision::FOR_PUBLIC, User $user=null)
Get the content of the current revision.
Definition WikiPage.php:718
getTitle()
Get the title object of the article.
Definition WikiPage.php:236
$res
Definition database.txt:21
deferred txt A few of the database updates required by various functions here can be deferred until after the result page is displayed to the user For updating the view updating the linked to tables after a etc PHP does not yet have any way to tell the server to actually return and disconnect while still running these but it might have such a feature in the future We handle these by creating a deferred update object and putting those objects on a global list
Definition deferred.txt:11
this class mediates it Skin Encapsulates a look and feel for the wiki All of the functions that render HTML and make choices about how to render it are here and are called from various other places when and is meant to be subclassed with other skins that may override some of its functions The User object contains a reference to a and so rather than having a global skin object we just rely on the global User and get the skin with $wgUser and also has some character encoding functions and other locale stuff The current user interface language is instantiated as and the local content language as $wgContLang
Definition design.txt:57
design txt This is a brief overview of the new design More thorough and up to date information is available on the documentation wiki at etc Handles the details of getting and saving to the user table of the and dealing with sessions and cookies OutputPage Encapsulates the entire HTML page that will be sent in response to any server request It is used by calling its functions to add text
Definition design.txt:18
this class mediates it Skin Encapsulates a look and feel for the wiki All of the functions that render HTML and make choices about how to render it are here and are called from various other places when and is meant to be subclassed with other skins that may override some of its functions The User object contains a reference to a and so rather than having a global skin object we just rely on the global User and get the skin with $wgUser and also has some character encoding functions and other locale stuff The current user interface language is instantiated as $wgLang
Definition design.txt:56
null for the local wiki Added should default to null in handler for backwards compatibility add a value to it if you want to add a cookie that have to vary cache options can modify as strings Extensions should add to this list prev or next $refreshCache
Definition hooks.txt:1632
null for the local wiki Added should default to null in handler for backwards compatibility add a value to it if you want to add a cookie that have to vary cache options can modify as strings Extensions should add to this list prev or next refreshes the diff cache $unhide
Definition hooks.txt:1633
static configuration should be added through ResourceLoaderGetConfigVars instead can be used to get the real title after the basic globals have been set but before ordinary actions take place $output
Definition hooks.txt:2255
do that in ParserLimitReportFormat instead use this to modify the parameters of the image all existing parser cache entries will be invalid To avoid you ll need to handle that somehow(e.g. with the RejectParserCacheValue hook) because MediaWiki won 't do it for you. & $defaults also a ContextSource after deleting those rows but within the same transaction you ll probably need to make sure the header is varied on and they can depend only on the ResourceLoaderContext $context
Definition hooks.txt:2811
either a unescaped string or a HtmlArmor object after in associative array form externallinks including delete and has completed for all link tables whether this was an auto creation default is conds Array Extra conditions for the No matching items in log is displayed if loglist is empty msgKey Array If you want a nice box with a set this to the key of the message First element is the message additional optional elements are parameters for the key that are processed with wfMessage() -> params() ->parseAsBlock() - offset Set to overwrite offset parameter in $wgRequest set to '' to unset offset - wrap String Wrap the message in html(usually something like "&lt;div ...>$1&lt;/div>"). - flags Integer display flags(NO_ACTION_LINK, NO_EXTRA_USER_LINKS) 'LogException':Called before an exception(or PHP error) is logged. This is meant for integration with external error aggregation services
null for the local wiki Added should default to null in handler for backwards compatibility add a value to it if you want to add a cookie that have to vary cache options can modify as strings Extensions should add to this list prev or next refreshes the diff cache allow viewing deleted revs & $differenceEngine
Definition hooks.txt:1634
Allows to change the fields on the form that will be generated $name
Definition hooks.txt:302
the value to return A Title object or null for latest all implement SearchIndexField $engine
Definition hooks.txt:2881
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that probably a stub it is not rendered in wiki pages or galleries in category pages allow injecting custom HTML after the section Any uses of the hook need to handle escaping see BaseTemplate::getToolbox and BaseTemplate::makeListItem for details on the format of individual items inside of this array or by returning and letting standard HTTP rendering take place modifiable or by returning false and taking over the output modifiable modifiable after all normalizations have been except for the $wgMaxImageArea check set to true or false to override the $wgMaxImageArea check result gives extension the possibility to transform it themselves $handler
Definition hooks.txt:903
presenting them properly to the user as errors is done by the caller return true use this to change the list i e etc $rev
Definition hooks.txt:1777
returning false will NOT prevent logging $e
Definition hooks.txt:2176
const CONTENT_MODEL_CSS
Definition Defines.php:247
const CONTENT_MODEL_WIKITEXT
Definition Defines.php:245
const CONTENT_MODEL_JSON
Definition Defines.php:249
const CONTENT_MODEL_TEXT
Definition Defines.php:248
const CONTENT_MODEL_JAVASCRIPT
Definition Defines.php:246
const EDIT_NEW
Definition Defines.php:162
Base interface for content objects.
Definition Content.php:34
getModel()
Returns the ID of the content model used by this Content object.
Interface for objects which can provide a MediaWiki context on request.
const INDEX_TYPE_TEXT
Field types.
const FLAG_CASEFOLD
Generic field flags.
$cache
Definition mcc.php:33
const DB_REPLICA
Definition defines.php:25
if(!is_readable( $file)) $ext
Definition router.php:55
if(!isset( $args[0])) $lang