MediaWiki  1.29.1
ContentHandler.php
Go to the documentation of this file.
1 <?php
2 
4 
49 abstract class ContentHandler {
79  public static function getContentText( Content $content = null ) {
80  global $wgContentHandlerTextFallback;
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 
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;
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 
228  return CONTENT_MODEL_WIKITEXT;
229  }
230 
240  public static function getForTitle( Title $title ) {
241  $modelId = $title->getContentModel();
242 
243  return ContentHandler::getForModelID( $modelId );
244  }
245 
256  public static function getForContent( Content $content ) {
257  $modelId = $content->getModel();
258 
259  return ContentHandler::getForModelID( $modelId );
260  }
261 
265  protected static $handlers;
266 
293  public static function getForModelID( $modelId ) {
295 
296  if ( isset( ContentHandler::$handlers[$modelId] ) ) {
297  return ContentHandler::$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 
331 
332  return ContentHandler::$handlers[$modelId];
333  }
334 
348  public static function getLocalizedName( $name, Language $lang = null ) {
349  // Messages: content-model-wikitext, content-model-text,
350  // content-model-javascript, content-model-css
351  $key = "content-model-$name";
352 
353  $msg = wfMessage( $key );
354  if ( $lang ) {
355  $msg->inLanguage( $lang );
356  }
357 
358  return $msg->exists() ? $msg->plain() : $name;
359  }
360 
361  public static function getContentModels() {
363 
364  $models = array_keys( $wgContentHandlers );
365  Hooks::run( 'GetContentModels', [ &$models ] );
366  return $models;
367  }
368 
369  public static function getAllContentFormats() {
371 
372  $formats = [];
373 
374  foreach ( $wgContentHandlers as $model => $class ) {
376  $formats = array_merge( $formats, $handler->getSupportedFormats() );
377  }
378 
379  $formats = array_unique( $formats );
380 
381  return $formats;
382  }
383 
384  // ------------------------------------------------------------------------
385 
389  protected $mModelID;
390 
395 
405  public function __construct( $modelId, $formats ) {
406  $this->mModelID = $modelId;
407  $this->mSupportedFormats = $formats;
408  }
409 
420  abstract public function serializeContent( Content $content, $format = null );
421 
432  public function exportTransform( $blob, $format = null ) {
433  return $blob;
434  }
435 
446  abstract public function unserializeContent( $blob, $format = null );
447 
459  public function importTransform( $blob, $format = null ) {
460  return $blob;
461  }
462 
471  abstract public function makeEmptyContent();
472 
490  public function makeRedirectContent( Title $destination, $text = '' ) {
491  return null;
492  }
493 
502  public function getModelID() {
503  return $this->mModelID;
504  }
505 
514  protected function checkModelID( $model_id ) {
515  if ( $model_id !== $this->mModelID ) {
516  throw new MWException( "Bad content model: " .
517  "expected {$this->mModelID} " .
518  "but got $model_id." );
519  }
520  }
521 
531  public function getSupportedFormats() {
533  }
534 
546  public function getDefaultFormat() {
547  return $this->mSupportedFormats[0];
548  }
549 
563  public function isSupportedFormat( $format ) {
564  if ( !$format ) {
565  return true; // this means "use the default"
566  }
567 
568  return in_array( $format, $this->mSupportedFormats );
569  }
570 
578  protected function checkFormat( $format ) {
579  if ( !$this->isSupportedFormat( $format ) ) {
580  throw new MWException(
581  "Format $format is not supported for content model "
582  . $this->getModelID()
583  );
584  }
585  }
586 
602  public function getActionOverrides() {
603  return [];
604  }
605 
620  public function createDifferenceEngine( IContextSource $context, $old = 0, $new = 0,
621  $rcid = 0, // FIXME: Deprecated, no longer used
622  $refreshCache = false, $unhide = false ) {
623 
624  // hook: get difference engine
625  $differenceEngine = null;
626  if ( !Hooks::run( 'GetDifferenceEngine',
627  [ $context, $old, $new, $refreshCache, $unhide, &$differenceEngine ]
628  ) ) {
629  return $differenceEngine;
630  }
631  $diffEngineClass = $this->getDiffEngineClass();
632  return new $diffEngineClass( $context, $old, $new, $rcid, $refreshCache, $unhide );
633  }
634 
654  public function getPageLanguage( Title $title, Content $content = null ) {
656  $pageLang = $wgContLang;
657 
658  if ( $title->getNamespace() == NS_MEDIAWIKI ) {
659  // Parse mediawiki messages with correct target language
660  list( /* $unused */, $lang ) = MessageCache::singleton()->figureMessage( $title->getText() );
661  $pageLang = Language::factory( $lang );
662  }
663 
664  Hooks::run( 'PageContentLanguage', [ $title, &$pageLang, $wgLang ] );
665 
666  return wfGetLangObj( $pageLang );
667  }
668 
689  public function getPageViewLanguage( Title $title, Content $content = null ) {
690  $pageLang = $this->getPageLanguage( $title, $content );
691 
692  if ( $title->getNamespace() !== NS_MEDIAWIKI ) {
693  // If the user chooses a variant, the content is actually
694  // in a language whose code is the variant code.
695  $variant = $pageLang->getPreferredVariant();
696  if ( $pageLang->getCode() !== $variant ) {
697  $pageLang = Language::factory( $variant );
698  }
699  }
700 
701  return $pageLang;
702  }
703 
720  public function canBeUsedOn( Title $title ) {
721  $ok = true;
722 
723  Hooks::run( 'ContentModelCanBeUsedOn', [ $this->getModelID(), $title, &$ok ] );
724 
725  return $ok;
726  }
727 
735  protected function getDiffEngineClass() {
737  }
738 
753  public function merge3( Content $oldContent, Content $myContent, Content $yourContent ) {
754  return false;
755  }
756 
768  public function getAutosummary( Content $oldContent = null, Content $newContent = null,
769  $flags ) {
770  // Decide what kind of auto-summary is needed.
771 
772  // Redirect auto-summaries
773 
779  $ot = !is_null( $oldContent ) ? $oldContent->getRedirectTarget() : null;
780  $rt = !is_null( $newContent ) ? $newContent->getRedirectTarget() : null;
781 
782  if ( is_object( $rt ) ) {
783  if ( !is_object( $ot )
784  || !$rt->equals( $ot )
785  || $ot->getFragment() != $rt->getFragment()
786  ) {
787  $truncatedtext = $newContent->getTextForSummary(
788  250
789  - strlen( wfMessage( 'autoredircomment' )->inContentLanguage()->text() )
790  - strlen( $rt->getFullText() ) );
791 
792  return wfMessage( 'autoredircomment', $rt->getFullText() )
793  ->rawParams( $truncatedtext )->inContentLanguage()->text();
794  }
795  }
796 
797  // New page auto-summaries
798  if ( $flags & EDIT_NEW && $newContent->getSize() > 0 ) {
799  // If they're making a new article, give its text, truncated, in
800  // the summary.
801 
802  $truncatedtext = $newContent->getTextForSummary(
803  200 - strlen( wfMessage( 'autosumm-new' )->inContentLanguage()->text() ) );
804 
805  return wfMessage( 'autosumm-new' )->rawParams( $truncatedtext )
806  ->inContentLanguage()->text();
807  }
808 
809  // Blanking auto-summaries
810  if ( !empty( $oldContent ) && $oldContent->getSize() > 0 && $newContent->getSize() == 0 ) {
811  return wfMessage( 'autosumm-blank' )->inContentLanguage()->text();
812  } elseif ( !empty( $oldContent )
813  && $oldContent->getSize() > 10 * $newContent->getSize()
814  && $newContent->getSize() < 500
815  ) {
816  // Removing more than 90% of the article
817 
818  $truncatedtext = $newContent->getTextForSummary(
819  200 - strlen( wfMessage( 'autosumm-replace' )->inContentLanguage()->text() ) );
820 
821  return wfMessage( 'autosumm-replace' )->rawParams( $truncatedtext )
822  ->inContentLanguage()->text();
823  }
824 
825  // New blank article auto-summary
826  if ( $flags & EDIT_NEW && $newContent->isEmpty() ) {
827  return wfMessage( 'autosumm-newblank' )->inContentLanguage()->text();
828  }
829 
830  // If we reach this point, there's no applicable auto-summary for our
831  // case, so our auto-summary is empty.
832  return '';
833  }
834 
850  public function getAutoDeleteReason( Title $title, &$hasHistory ) {
851  $dbr = wfGetDB( DB_REPLICA );
852 
853  // Get the last revision
855 
856  if ( is_null( $rev ) ) {
857  return false;
858  }
859 
860  // Get the article's contents
861  $content = $rev->getContent();
862  $blank = false;
863 
864  // If the page is blank, use the text from the previous revision,
865  // which can only be blank if there's a move/import/protect dummy
866  // revision involved
867  if ( !$content || $content->isEmpty() ) {
868  $prev = $rev->getPrevious();
869 
870  if ( $prev ) {
871  $rev = $prev;
872  $content = $rev->getContent();
873  $blank = true;
874  }
875  }
876 
877  $this->checkModelID( $rev->getContentModel() );
878 
879  // Find out if there was only one contributor
880  // Only scan the last 20 revisions
881  $res = $dbr->select( 'revision', 'rev_user_text',
882  [
883  'rev_page' => $title->getArticleID(),
884  $dbr->bitAnd( 'rev_deleted', Revision::DELETED_USER ) . ' = 0'
885  ],
886  __METHOD__,
887  [ 'LIMIT' => 20 ]
888  );
889 
890  if ( $res === false ) {
891  // This page has no revisions, which is very weird
892  return false;
893  }
894 
895  $hasHistory = ( $res->numRows() > 1 );
896  $row = $dbr->fetchObject( $res );
897 
898  if ( $row ) { // $row is false if the only contributor is hidden
899  $onlyAuthor = $row->rev_user_text;
900  // Try to find a second contributor
901  foreach ( $res as $row ) {
902  if ( $row->rev_user_text != $onlyAuthor ) { // T24999
903  $onlyAuthor = false;
904  break;
905  }
906  }
907  } else {
908  $onlyAuthor = false;
909  }
910 
911  // Generate the summary with a '$1' placeholder
912  if ( $blank ) {
913  // The current revision is blank and the one before is also
914  // blank. It's just not our lucky day
915  $reason = wfMessage( 'exbeforeblank', '$1' )->inContentLanguage()->text();
916  } else {
917  if ( $onlyAuthor ) {
918  $reason = wfMessage(
919  'excontentauthor',
920  '$1',
921  $onlyAuthor
922  )->inContentLanguage()->text();
923  } else {
924  $reason = wfMessage( 'excontent', '$1' )->inContentLanguage()->text();
925  }
926  }
927 
928  if ( $reason == '-' ) {
929  // Allow these UI messages to be blanked out cleanly
930  return '';
931  }
932 
933  // Max content length = max comment length - length of the comment (excl. $1)
934  $text = $content ? $content->getTextForSummary( 255 - ( strlen( $reason ) - 2 ) ) : '';
935 
936  // Now replace the '$1' placeholder
937  $reason = str_replace( '$1', $text, $reason );
938 
939  return $reason;
940  }
941 
955  public function getUndoContent( Revision $current, Revision $undo, Revision $undoafter ) {
956  $cur_content = $current->getContent();
957 
958  if ( empty( $cur_content ) ) {
959  return false; // no page
960  }
961 
962  $undo_content = $undo->getContent();
963  $undoafter_content = $undoafter->getContent();
964 
965  if ( !$undo_content || !$undoafter_content ) {
966  return false; // no content to undo
967  }
968 
969  try {
970  $this->checkModelID( $cur_content->getModel() );
971  $this->checkModelID( $undo_content->getModel() );
972  if ( $current->getId() !== $undo->getId() ) {
973  // If we are undoing the most recent revision,
974  // its ok to revert content model changes. However
975  // if we are undoing a revision in the middle, then
976  // doing that will be confusing.
977  $this->checkModelID( $undoafter_content->getModel() );
978  }
979  } catch ( MWException $e ) {
980  // If the revisions have different content models
981  // just return false
982  return false;
983  }
984 
985  if ( $cur_content->equals( $undo_content ) ) {
986  // No use doing a merge if it's just a straight revert.
987  return $undoafter_content;
988  }
989 
990  $undone_content = $this->merge3( $undo_content, $undoafter_content, $cur_content );
991 
992  return $undone_content;
993  }
994 
1009  public function makeParserOptions( $context ) {
1010  global $wgContLang, $wgEnableParserLimitReporting;
1011 
1012  if ( $context instanceof IContextSource ) {
1014  } elseif ( $context instanceof User ) { // settings per user (even anons)
1016  } elseif ( $context === 'canonical' ) { // canonical settings
1018  } else {
1019  throw new MWException( "Bad context for parser options: $context" );
1020  }
1021 
1022  $options->enableLimitReport( $wgEnableParserLimitReporting ); // show inclusion/loop reports
1023  $options->setTidy( true ); // fix bad HTML
1024 
1025  return $options;
1026  }
1027 
1036  public function isParserCacheSupported() {
1037  return false;
1038  }
1039 
1049  public function supportsSections() {
1050  return false;
1051  }
1052 
1059  public function supportsCategories() {
1060  return true;
1061  }
1062 
1072  public function supportsRedirects() {
1073  return false;
1074  }
1075 
1081  public function supportsDirectEditing() {
1082  return false;
1083  }
1084 
1090  public function supportsDirectApiEditing() {
1091  return $this->supportsDirectEditing();
1092  }
1093 
1105  $fields['category'] = $engine->makeSearchFieldMapping(
1106  'category',
1108  );
1109  $fields['category']->setFlag( SearchIndexField::FLAG_CASEFOLD );
1110 
1111  $fields['external_link'] = $engine->makeSearchFieldMapping(
1112  'external_link',
1114  );
1115 
1116  $fields['outgoing_link'] = $engine->makeSearchFieldMapping(
1117  'outgoing_link',
1119  );
1120 
1121  $fields['template'] = $engine->makeSearchFieldMapping(
1122  'template',
1124  );
1125  $fields['template']->setFlag( SearchIndexField::FLAG_CASEFOLD );
1126 
1127  $fields['content_model'] = $engine->makeSearchFieldMapping(
1128  'content_model',
1130  );
1131 
1132  return $fields;
1133  }
1134 
1144  protected function addSearchField( &$fields, SearchEngine $engine, $name, $type ) {
1145  $fields[$name] = $engine->makeSearchFieldMapping( $name, $type );
1146  return $fields;
1147  }
1148 
1160  public function getDataForSearchIndex(
1161  WikiPage $page,
1164  ) {
1165  $fieldData = [];
1166  $content = $page->getContent();
1167 
1168  if ( $content ) {
1169  $searchDataExtractor = new ParserOutputSearchDataExtractor();
1170 
1171  $fieldData['category'] = $searchDataExtractor->getCategories( $output );
1172  $fieldData['external_link'] = $searchDataExtractor->getExternalLinks( $output );
1173  $fieldData['outgoing_link'] = $searchDataExtractor->getOutgoingLinks( $output );
1174  $fieldData['template'] = $searchDataExtractor->getTemplates( $output );
1175 
1176  $text = $content->getTextForSearchIndex();
1177 
1178  $fieldData['text'] = $text;
1179  $fieldData['source_text'] = $text;
1180  $fieldData['text_bytes'] = $content->getSize();
1181  $fieldData['content_model'] = $content->getModel();
1182  }
1183 
1184  Hooks::run( 'SearchDataForIndex', [ &$fieldData, $this, $page, $output, $engine ] );
1185  return $fieldData;
1186  }
1187 
1198  $parserOptions = $page->makeParserOptions( 'canonical' );
1199  $revId = $page->getRevision()->getId();
1200  if ( $cache ) {
1201  $parserOutput = $cache->get( $page, $parserOptions );
1202  }
1203  if ( empty( $parserOutput ) ) {
1204  $parserOutput =
1205  $page->getContent()->getParserOutput( $page->getTitle(), $revId, $parserOptions );
1206  if ( $cache ) {
1207  $cache->save( $parserOutput, $page, $parserOptions );
1208  }
1209  }
1210  return $parserOutput;
1211  }
1212 
1213 }
SearchIndexField\INDEX_TYPE_KEYWORD
const INDEX_TYPE_KEYWORD
Definition: SearchIndexField.php:11
Revision\DELETED_USER
const DELETED_USER
Definition: Revision.php:92
CONTENT_MODEL_JSON
const CONTENT_MODEL_JSON
Definition: Defines.php:237
ContentHandler
A content handler knows how do deal with a specific type of content on a wiki page.
Definition: ContentHandler.php:49
ContentHandler\getForModelID
static getForModelID( $modelId)
Returns the ContentHandler singleton for the given model ID.
Definition: ContentHandler.php:293
$context
error also a ContextSource you ll probably need to make sure the header is varied on and they can depend only on the ResourceLoaderContext $context
Definition: hooks.txt:2612
ContentHandler\getAutosummary
getAutosummary(Content $oldContent=null, Content $newContent=null, $flags)
Return an applicable auto-summary if one exists for the given edit.
Definition: ContentHandler.php:768
ContentHandler\getAllContentFormats
static getAllContentFormats()
Definition: ContentHandler.php:369
ParserOutput
Definition: ParserOutput.php:24
ContentHandler\supportsDirectEditing
supportsDirectEditing()
Return true if this content model supports direct editing, such as via EditPage.
Definition: ContentHandler.php:1081
$lang
if(!isset( $args[0])) $lang
Definition: testCompression.php:33
ContentHandler\makeParserOptions
makeParserOptions( $context)
Get parser options suitable for rendering and caching the article.
Definition: ContentHandler.php:1009
text
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:12
Revision\getContent
getContent( $audience=self::FOR_PUBLIC, User $user=null)
Fetch revision content if it's available to the specified audience.
Definition: Revision.php:1057
CONTENT_MODEL_CSS
const CONTENT_MODEL_CSS
Definition: Defines.php:235
ContentHandler\getActionOverrides
getActionOverrides()
Returns overrides for action handlers.
Definition: ContentHandler.php:602
ContentHandler\checkModelID
checkModelID( $model_id)
Definition: ContentHandler.php:514
MWNamespace\getNamespaceContentModel
static getNamespaceContentModel( $index)
Get the default content model for a namespace This does not mean that all pages in that namespace hav...
Definition: MWNamespace.php:435
ContentHandler\getAutoDeleteReason
getAutoDeleteReason(Title $title, &$hasHistory)
Auto-generates a deletion reason.
Definition: ContentHandler.php:850
ContentHandler\unserializeContent
unserializeContent( $blob, $format=null)
Unserializes a Content object of the type supported by this ContentHandler.
use
as see the revision history and available at free of to any person obtaining a copy of this software and associated documentation to deal in the Software without including without limitation the rights to use
Definition: MIT-LICENSE.txt:10
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:689
WikiPage
Class representing a MediaWiki article and history.
Definition: WikiPage.php:36
Title\getArticleID
getArticleID( $flags=0)
Get the article ID for this Title from the link cache, adding it if necessary.
Definition: Title.php:3220
ContentHandler\$mSupportedFormats
string[] $mSupportedFormats
Definition: ContentHandler.php:394
ContentHandler\getForTitle
static getForTitle(Title $title)
Returns the appropriate ContentHandler singleton for the given title.
Definition: ContentHandler.php:240
$res
$res
Definition: database.txt:21
$name
Allows to change the fields on the form that will be generated $name
Definition: hooks.txt:304
SearchIndexField\FLAG_CASEFOLD
const FLAG_CASEFOLD
Generic field flags.
Definition: SearchIndexField.php:32
CONTENT_MODEL_WIKITEXT
const CONTENT_MODEL_WIKITEXT
Definition: Defines.php:233
$type
do that in ParserLimitReportFormat instead use this to modify the parameters of the image and a DIV can begin in one section and end in another Make sure your code can handle that case gracefully See the EditSectionClearerLink extension for an example zero but section is usually empty its values are the globals values before the output is cached my talk my contributions etc etc otherwise the built in rate limiting checks are if enabled allows for interception of redirect as a string mapping parameter names to values & $type
Definition: hooks.txt:2536
Revision\getId
getId()
Get revision ID.
Definition: Revision.php:735
ContentHandler\serializeContent
serializeContent(Content $content, $format=null)
Serializes a Content object of the type supported by this ContentHandler.
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:1092
ContentHandler\supportsSections
supportsSections()
Returns true if this content model supports sections.
Definition: ContentHandler.php:1049
php
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
Definition: injection.txt:35
ContentHandler\isSupportedFormat
isSupportedFormat( $format)
Returns true if $format is a serialization format supported by this ContentHandler,...
Definition: ContentHandler.php:563
$differenceEngine
null for the 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:1572
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:620
ContentHandler\canBeUsedOn
canBeUsedOn(Title $title)
Determines whether the content type handled by this ContentHandler can be used on the given page.
Definition: ContentHandler.php:720
Revision
Definition: Revision.php:33
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:459
ContentHandler\supportsRedirects
supportsRedirects()
Returns true if this content model supports redirects.
Definition: ContentHandler.php:1072
Revision\newFromTitle
static newFromTitle(LinkTarget $linkTarget, $id=0, $flags=0)
Load either the current, or a specified, revision that's attached to a given link target.
Definition: Revision.php:134
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:178
MWException
MediaWiki exception.
Definition: MWException.php:26
$title
namespace and then decline to actually register it file or subcat img or subcat $title
Definition: hooks.txt:934
$wgContentHandlers
$wgContentHandlers
Plugins for page content model handling.
Definition: DefaultSettings.php:969
ContentHandler\getContentModels
static getContentModels()
Definition: ContentHandler.php:361
ParserOptions\newFromUserAndLang
static newFromUserAndLang(User $user, Language $lang)
Get a ParserOptions object from a given user and language.
Definition: ParserOptions.php:716
$blob
$blob
Definition: testCompression.php:63
ContentHandler\supportsDirectApiEditing
supportsDirectApiEditing()
Whether or not this content model supports direct editing via ApiEditPage.
Definition: ContentHandler.php:1090
$content
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist Do not use this to implement individual filters if they are compatible with the ChangesListFilter and ChangesListFilterGroup structure use sub classes of those in conjunction with the ChangesListSpecialPageStructuredFilters hook This hook can be used to implement filters that do not implement that or custom behavior that is not an individual filter e g Watchlist and Watchlist you will want to construct new ChangesListBooleanFilter or ChangesListStringOptionsFilter objects When constructing you specify which group they belong to You can reuse existing or create your you must register them with $special registerFilterGroup removed from all revisions and log entries to which it was applied This gives extensions a chance to take it off their books as the deletion has already been partly carried out by this point or something similar the user will be unable to create the tag set and then return false from the hook function Ensure you consume the ChangeTagAfterDelete hook to carry out custom deletion actions as context called by AbstractContent::getParserOutput May be used to override the normal model specific rendering of page content $content
Definition: hooks.txt:1049
wfGetDB
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
Definition: GlobalFunctions.php:3060
$page
do that in ParserLimitReportFormat instead use this to modify the parameters of the image and a DIV can begin in one section and end in another Make sure your code can handle that case gracefully See the EditSectionClearerLink extension for an example zero but section is usually empty its values are the globals values before the output is cached $page
Definition: hooks.txt:2536
wfGetLangObj
wfGetLangObj( $langcode=false)
Return a Language object from $langcode.
Definition: GlobalFunctions.php:1321
ContentHandler\merge3
merge3(Content $oldContent, Content $myContent, Content $yourContent)
Attempts to merge differences between three versions.
Definition: ContentHandler.php:753
ContentHandler\makeEmptyContent
makeEmptyContent()
Creates an empty Content object of the type supported by this ContentHandler.
$wgLang
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
$output
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist Do not use this to implement individual filters if they are compatible with the ChangesListFilter and ChangesListFilterGroup structure use sub classes of those in conjunction with the ChangesListSpecialPageStructuredFilters hook This hook can be used to implement filters that do not implement that or custom behavior that is not an individual filter e g Watchlist and Watchlist you will want to construct new ChangesListBooleanFilter or ChangesListStringOptionsFilter objects When constructing you specify which group they belong to You can reuse existing or create your you must register them with $special registerFilterGroup removed from all revisions and log entries to which it was applied This gives extensions a chance to take it off their books as the deletion has already been partly carried out by this point or something similar the user will be unable to create the tag set and then return false from the hook function Ensure you consume the ChangeTagAfterDelete hook to carry out custom deletion actions as context called by AbstractContent::getParserOutput May be used to override the normal model specific rendering of page content as context as context the output can only depend on parameters provided to this hook not on global state indicating whether full HTML should be generated If generation of HTML may be but other information should still be present in the ParserOutput object & $output
Definition: hooks.txt:1049
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:1160
$engine
the value to return A Title object or null for latest all implement SearchIndexField $engine
Definition: hooks.txt:2782
global
when a variable name is used in a it is silently declared as a new masking the global
Definition: design.txt:93
DB_REPLICA
const DB_REPLICA
Definition: defines.php:25
list
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
MessageCache\singleton
static singleton()
Get the signleton instance of this class.
Definition: MessageCache.php:113
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:129
ContentHandler\getPageLanguage
getPageLanguage(Title $title, Content $content=null)
Get the language in which the content of the given page is written.
Definition: ContentHandler.php:654
ContentHandler\isParserCacheSupported
isParserCacheSupported()
Returns true for content models that support caching using the ParserCache mechanism.
Definition: ContentHandler.php:1036
$e
div flags Integer display flags(NO_ACTION_LINK, NO_EXTRA_USER_LINKS) 'LogException' returning false will NOT prevent logging $e
Definition: hooks.txt:2122
ContentHandler\getDefaultFormat
getDefaultFormat()
The format used for serialization/deserialization by default by this ContentHandler.
Definition: ContentHandler.php:546
ContentHandler\getLocalizedName
static getLocalizedName( $name, Language $lang=null)
Returns the localized name for a given content model.
Definition: ContentHandler.php:348
ParserOptions\newFromContext
static newFromContext(IContextSource $context)
Get a ParserOptions object from a IContextSource object.
Definition: ParserOptions.php:726
ContentHandler\getDiffEngineClass
getDiffEngineClass()
Returns the name of the diff engine to use.
Definition: ContentHandler.php:735
$refreshCache
null for the 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:1572
ContentHandler\supportsCategories
supportsCategories()
Returns true if this content model supports categories.
Definition: ContentHandler.php:1059
ContentHandler\$mModelID
string $mModelID
Definition: ContentHandler.php:389
$handler
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:783
TextContent
Content object implementation for representing flat text.
Definition: TextContent.php:35
SearchEngine
Contain a class for special pages.
Definition: SearchEngine.php:34
IContextSource
Interface for objects which can provide a MediaWiki context on request.
Definition: IContextSource.php:55
ContentHandler\exportTransform
exportTransform( $blob, $format=null)
Applies transformations on export (returns the blob unchanged per default).
Definition: ContentHandler.php:432
Content
Base interface for content objects.
Definition: Content.php:34
ContentHandler\getFieldsForSearchIndex
getFieldsForSearchIndex(SearchEngine $engine)
Get fields definition for search index.
Definition: ContentHandler.php:1104
EDIT_NEW
const EDIT_NEW
Definition: Defines.php:150
$unhide
null for the 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:1572
Title
Represents a title within MediaWiki.
Definition: Title.php:39
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:490
ContentHandler\checkFormat
checkFormat( $format)
Convenient for checking whether a format provided as a parameter is actually supported.
Definition: ContentHandler.php:578
ContentHandler\getContentText
static getContentText(Content $content=null)
Convenience function for getting flat text from a Content object.
Definition: ContentHandler.php:79
$dbr
if(! $regexes) $dbr
Definition: cleanup.php:94
$cache
$cache
Definition: mcc.php:33
$ext
$ext
Definition: NoLocalSettings.php:25
$rev
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:1741
as
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
Definition: distributors.txt:9
ContentHandler\$handlers
static array $handlers
A Cache of ContentHandler instances by model id.
Definition: ContentHandler.php:265
ParserCache
Definition: ParserCache.php:28
NS_USER
const NS_USER
Definition: Defines.php:64
$revId
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist Do not use this to implement individual filters if they are compatible with the ChangesListFilter and ChangesListFilterGroup structure use sub classes of those in conjunction with the ChangesListSpecialPageStructuredFilters hook This hook can be used to implement filters that do not implement that or custom behavior that is not an individual filter e g Watchlist and Watchlist you will want to construct new ChangesListBooleanFilter or ChangesListStringOptionsFilter objects When constructing you specify which group they belong to You can reuse existing or create your you must register them with $special registerFilterGroup removed from all revisions and log entries to which it was applied This gives extensions a chance to take it off their books as the deletion has already been partly carried out by this point or something similar the user will be unable to create the tag set and then return false from the hook function Ensure you consume the ChangeTagAfterDelete hook to carry out custom deletion actions as context called by AbstractContent::getParserOutput May be used to override the normal model specific rendering of page content as context $revId
Definition: hooks.txt:1049
MWUnknownContentModelException
Exception thrown when an unregistered content model is requested.
Definition: MWUnknownContentModelException.php:10
ContentHandler\addSearchField
addSearchField(&$fields, SearchEngine $engine, $name, $type)
Add new field definition to array.
Definition: ContentHandler.php:1144
Language\factory
static factory( $code)
Get a cached or new language object for a given language code.
Definition: Language.php:183
wfMessage
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
NS_MEDIAWIKI
const NS_MEDIAWIKI
Definition: Defines.php:70
class
you have access to all of the normal MediaWiki so you can get a DB use the etc For full docs on the Maintenance class
Definition: maintenance.txt:52
CONTENT_MODEL_JAVASCRIPT
const CONTENT_MODEL_JAVASCRIPT
Definition: Defines.php:234
ContentHandler\__construct
__construct( $modelId, $formats)
Constructor, initializing the ContentHandler instance with its model ID and a list of supported forma...
Definition: ContentHandler.php:405
CONTENT_MODEL_TEXT
const CONTENT_MODEL_TEXT
Definition: Defines.php:236
User
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition: User.php:50
Hooks\run
static run( $event, array $args=[], $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
Definition: Hooks.php:131
ContentHandler\getUndoContent
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...
Definition: ContentHandler.php:955
ContentHandler\getSupportedFormats
getSupportedFormats()
Returns a list of serialization formats supported by the serializeContent() and unserializeContent() ...
Definition: ContentHandler.php:531
$options
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist Do not use this to implement individual filters if they are compatible with the ChangesListFilter and ChangesListFilterGroup structure use sub classes of those in conjunction with the ChangesListSpecialPageStructuredFilters hook This hook can be used to implement filters that do not implement that or custom behavior that is not an individual filter e g Watchlist and Watchlist you will want to construct new ChangesListBooleanFilter or ChangesListStringOptionsFilter objects When constructing you specify which group they belong to You can reuse existing or create your you must register them with $special registerFilterGroup removed from all revisions and log entries to which it was applied This gives extensions a chance to take it off their books as the deletion has already been partly carried out by this point or something similar the user will be unable to create the tag set and then return false from the hook function Ensure you consume the ChangeTagAfterDelete hook to carry out custom deletion actions as context called by AbstractContent::getParserOutput May be used to override the normal model specific rendering of page content as context as context $options
Definition: hooks.txt:1049
Language
Internationalisation code.
Definition: Language.php:35
$flags
it s the revision text itself In either if gzip is the revision text is gzipped $flags
Definition: hooks.txt:2749
ContentHandler\getModelID
getModelID()
Returns the model id that identifies the content model this ContentHandler can handle.
Definition: ContentHandler.php:502
$parserOutput
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist Do not use this to implement individual filters if they are compatible with the ChangesListFilter and ChangesListFilterGroup structure use sub classes of those in conjunction with the ChangesListSpecialPageStructuredFilters hook This hook can be used to implement filters that do not implement that or custom behavior that is not an individual filter e g Watchlist and Watchlist you will want to construct new ChangesListBooleanFilter or ChangesListStringOptionsFilter objects When constructing you specify which group they belong to You can reuse existing or create your you must register them with $special registerFilterGroup removed from all revisions and log entries to which it was applied This gives extensions a chance to take it off their books as the deletion has already been partly carried out by this point or something similar the user will be unable to create the tag set and then return false from the hook function Ensure you consume the ChangeTagAfterDelete hook to carry out custom deletion actions as context $parserOutput
Definition: hooks.txt:1049
ContentHandler\getForContent
static getForContent(Content $content)
Returns the appropriate ContentHandler singleton for the given Content object.
Definition: ContentHandler.php:256
ContentHandler\getParserOutputForIndexing
getParserOutputForIndexing(WikiPage $page, ParserCache $cache=null)
Produce page output suitable for indexing.
Definition: ContentHandler.php:1197
array
the array() calling protocol came about after MediaWiki 1.4rc1.
ParserOptions\newFromUser
static newFromUser( $user)
Get a ParserOptions object from a given user.
Definition: ParserOptions.php:705
$wgContLang
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 content language as $wgContLang
Definition: design.txt:56
SearchIndexField\INDEX_TYPE_TEXT
const INDEX_TYPE_TEXT
Field types.
Definition: SearchIndexField.php:10