MediaWiki  master
ContentHandler.php
Go to the documentation of this file.
1 <?php
34 }
35 
46  private $modelId;
47 
49  function __construct( $modelId ) {
50  parent::__construct( "The content model '$modelId' is not registered on this wiki.\n" .
51  'See https://www.mediawiki.org/wiki/Content_handlers to find out which extensions ' .
52  'handle this content model.' );
53  $this->modelId = $modelId;
54  }
55 
57  public function getModelId() {
58  return $this->modelId;
59  }
60 }
61 
81 abstract class ContentHandler {
89  protected static $enableDeprecationWarnings = false;
90 
120  public static function getContentText( Content $content = null ) {
122 
123  if ( is_null( $content ) ) {
124  return '';
125  }
126 
127  if ( $content instanceof TextContent ) {
128  return $content->getNativeData();
129  }
130 
131  wfDebugLog( 'ContentHandler', 'Accessing ' . $content->getModel() . ' content as text!' );
132 
133  if ( $wgContentHandlerTextFallback == 'fail' ) {
134  throw new MWException(
135  "Attempt to get text from Content with model " .
136  $content->getModel()
137  );
138  }
139 
140  if ( $wgContentHandlerTextFallback == 'serialize' ) {
141  return $content->serialize();
142  }
143 
144  return null;
145  }
146 
170  public static function makeContent( $text, Title $title = null,
171  $modelId = null, $format = null ) {
172  if ( is_null( $modelId ) ) {
173  if ( is_null( $title ) ) {
174  throw new MWException( "Must provide a Title object or a content model ID." );
175  }
176 
177  $modelId = $title->getContentModel();
178  }
179 
180  $handler = ContentHandler::getForModelID( $modelId );
181 
182  return $handler->unserializeContent( $text, $format );
183  }
184 
219  public static function getDefaultModelFor( Title $title ) {
220  // NOTE: this method must not rely on $title->getContentModel() directly or indirectly,
221  // because it is used to initialize the mContentModel member.
222 
223  $ns = $title->getNamespace();
224 
225  $ext = false;
226  $m = null;
228 
229  // Hook can determine default model
230  if ( !Hooks::run( 'ContentHandlerDefaultModelFor', [ $title, &$model ] ) ) {
231  if ( !is_null( $model ) ) {
232  return $model;
233  }
234  }
235 
236  // Could this page contain code based on the title?
237  $isCodePage = NS_MEDIAWIKI == $ns && preg_match( '!\.(css|js|json)$!u', $title->getText(), $m );
238  if ( $isCodePage ) {
239  $ext = $m[1];
240  }
241 
242  // Hook can force JS/CSS
243  Hooks::run( 'TitleIsCssOrJsPage', [ $title, &$isCodePage ], '1.25' );
244 
245  // Is this a user subpage containing code?
246  $isCodeSubpage = NS_USER == $ns
247  && !$isCodePage
248  && preg_match( "/\\/.*\\.(js|css|json)$/", $title->getText(), $m );
249  if ( $isCodeSubpage ) {
250  $ext = $m[1];
251  }
252 
253  // Is this wikitext, according to $wgNamespaceContentModels or the DefaultModelFor hook?
254  $isWikitext = is_null( $model ) || $model == CONTENT_MODEL_WIKITEXT;
255  $isWikitext = $isWikitext && !$isCodePage && !$isCodeSubpage;
256 
257  // Hook can override $isWikitext
258  Hooks::run( 'TitleIsWikitextPage', [ $title, &$isWikitext ], '1.25' );
259 
260  if ( !$isWikitext ) {
261  switch ( $ext ) {
262  case 'js':
264  case 'css':
265  return CONTENT_MODEL_CSS;
266  case 'json':
267  return CONTENT_MODEL_JSON;
268  default:
269  return is_null( $model ) ? CONTENT_MODEL_TEXT : $model;
270  }
271  }
272 
273  // We established that it must be wikitext
274 
275  return CONTENT_MODEL_WIKITEXT;
276  }
277 
287  public static function getForTitle( Title $title ) {
288  $modelId = $title->getContentModel();
289 
290  return ContentHandler::getForModelID( $modelId );
291  }
292 
303  public static function getForContent( Content $content ) {
304  $modelId = $content->getModel();
305 
306  return ContentHandler::getForModelID( $modelId );
307  }
308 
312  protected static $handlers;
313 
340  public static function getForModelID( $modelId ) {
342 
343  if ( isset( ContentHandler::$handlers[$modelId] ) ) {
344  return ContentHandler::$handlers[$modelId];
345  }
346 
347  if ( empty( $wgContentHandlers[$modelId] ) ) {
348  $handler = null;
349 
350  Hooks::run( 'ContentHandlerForModelID', [ $modelId, &$handler ] );
351 
352  if ( $handler === null ) {
353  throw new MWUnknownContentModelException( $modelId );
354  }
355 
356  if ( !( $handler instanceof ContentHandler ) ) {
357  throw new MWException( "ContentHandlerForModelID must supply a ContentHandler instance" );
358  }
359  } else {
360  $classOrCallback = $wgContentHandlers[$modelId];
361 
362  if ( is_callable( $classOrCallback ) ) {
363  $handler = call_user_func( $classOrCallback, $modelId );
364  } else {
365  $handler = new $classOrCallback( $modelId );
366  }
367 
368  if ( !( $handler instanceof ContentHandler ) ) {
369  throw new MWException( "$classOrCallback from \$wgContentHandlers is not " .
370  "compatible with ContentHandler" );
371  }
372  }
373 
374  wfDebugLog( 'ContentHandler', 'Created handler for ' . $modelId
375  . ': ' . get_class( $handler ) );
376 
377  ContentHandler::$handlers[$modelId] = $handler;
378 
379  return ContentHandler::$handlers[$modelId];
380  }
381 
395  public static function getLocalizedName( $name, Language $lang = null ) {
396  // Messages: content-model-wikitext, content-model-text,
397  // content-model-javascript, content-model-css
398  $key = "content-model-$name";
399 
400  $msg = wfMessage( $key );
401  if ( $lang ) {
402  $msg->inLanguage( $lang );
403  }
404 
405  return $msg->exists() ? $msg->plain() : $name;
406  }
407 
408  public static function getContentModels() {
410 
411  return array_keys( $wgContentHandlers );
412  }
413 
414  public static function getAllContentFormats() {
416 
417  $formats = [];
418 
419  foreach ( $wgContentHandlers as $model => $class ) {
420  $handler = ContentHandler::getForModelID( $model );
421  $formats = array_merge( $formats, $handler->getSupportedFormats() );
422  }
423 
424  $formats = array_unique( $formats );
425 
426  return $formats;
427  }
428 
429  // ------------------------------------------------------------------------
430 
434  protected $mModelID;
435 
439  protected $mSupportedFormats;
440 
450  public function __construct( $modelId, $formats ) {
451  $this->mModelID = $modelId;
452  $this->mSupportedFormats = $formats;
453 
454  $this->mModelName = preg_replace( '/(Content)?Handler$/', '', get_class( $this ) );
455  $this->mModelName = preg_replace( '/[_\\\\]/', '', $this->mModelName );
456  $this->mModelName = strtolower( $this->mModelName );
457  }
458 
469  abstract public function serializeContent( Content $content, $format = null );
470 
481  public function exportTransform( $blob, $format = null ) {
482  return $blob;
483  }
484 
495  abstract public function unserializeContent( $blob, $format = null );
496 
508  public function importTransform( $blob, $format = null ) {
509  return $blob;
510  }
511 
520  abstract public function makeEmptyContent();
521 
539  public function makeRedirectContent( Title $destination, $text = '' ) {
540  return null;
541  }
542 
551  public function getModelID() {
552  return $this->mModelID;
553  }
554 
563  protected function checkModelID( $model_id ) {
564  if ( $model_id !== $this->mModelID ) {
565  throw new MWException( "Bad content model: " .
566  "expected {$this->mModelID} " .
567  "but got $model_id." );
568  }
569  }
570 
580  public function getSupportedFormats() {
581  return $this->mSupportedFormats;
582  }
583 
595  public function getDefaultFormat() {
596  return $this->mSupportedFormats[0];
597  }
598 
612  public function isSupportedFormat( $format ) {
613  if ( !$format ) {
614  return true; // this means "use the default"
615  }
616 
617  return in_array( $format, $this->mSupportedFormats );
618  }
619 
627  protected function checkFormat( $format ) {
628  if ( !$this->isSupportedFormat( $format ) ) {
629  throw new MWException(
630  "Format $format is not supported for content model "
631  . $this->getModelID()
632  );
633  }
634  }
635 
651  public function getActionOverrides() {
652  return [];
653  }
654 
669  public function createDifferenceEngine( IContextSource $context, $old = 0, $new = 0,
670  $rcid = 0, // FIXME: Deprecated, no longer used
671  $refreshCache = false, $unhide = false ) {
672 
673  // hook: get difference engine
674  $differenceEngine = null;
675  if ( !Hooks::run( 'GetDifferenceEngine',
676  [ $context, $old, $new, $refreshCache, $unhide, &$differenceEngine ]
677  ) ) {
678  return $differenceEngine;
679  }
680  $diffEngineClass = $this->getDiffEngineClass();
681  return new $diffEngineClass( $context, $old, $new, $rcid, $refreshCache, $unhide );
682  }
683 
703  public function getPageLanguage( Title $title, Content $content = null ) {
705  $pageLang = $wgContLang;
706 
707  if ( $title->getNamespace() == NS_MEDIAWIKI ) {
708  // Parse mediawiki messages with correct target language
709  list( /* $unused */, $lang ) = MessageCache::singleton()->figureMessage( $title->getText() );
710  $pageLang = wfGetLangObj( $lang );
711  }
712 
713  Hooks::run( 'PageContentLanguage', [ $title, &$pageLang, $wgLang ] );
714 
715  return wfGetLangObj( $pageLang );
716  }
717 
738  public function getPageViewLanguage( Title $title, Content $content = null ) {
739  $pageLang = $this->getPageLanguage( $title, $content );
740 
741  if ( $title->getNamespace() !== NS_MEDIAWIKI ) {
742  // If the user chooses a variant, the content is actually
743  // in a language whose code is the variant code.
744  $variant = $pageLang->getPreferredVariant();
745  if ( $pageLang->getCode() !== $variant ) {
746  $pageLang = Language::factory( $variant );
747  }
748  }
749 
750  return $pageLang;
751  }
752 
769  public function canBeUsedOn( Title $title ) {
770  $ok = true;
771 
772  Hooks::run( 'ContentModelCanBeUsedOn', [ $this->getModelID(), $title, &$ok ] );
773 
774  return $ok;
775  }
776 
784  protected function getDiffEngineClass() {
786  }
787 
802  public function merge3( Content $oldContent, Content $myContent, Content $yourContent ) {
803  return false;
804  }
805 
817  public function getAutosummary( Content $oldContent = null, Content $newContent = null,
818  $flags ) {
819  // Decide what kind of auto-summary is needed.
820 
821  // Redirect auto-summaries
822 
828  $ot = !is_null( $oldContent ) ? $oldContent->getRedirectTarget() : null;
829  $rt = !is_null( $newContent ) ? $newContent->getRedirectTarget() : null;
830 
831  if ( is_object( $rt ) ) {
832  if ( !is_object( $ot )
833  || !$rt->equals( $ot )
834  || $ot->getFragment() != $rt->getFragment()
835  ) {
836  $truncatedtext = $newContent->getTextForSummary(
837  250
838  - strlen( wfMessage( 'autoredircomment' )->inContentLanguage()->text() )
839  - strlen( $rt->getFullText() ) );
840 
841  return wfMessage( 'autoredircomment', $rt->getFullText() )
842  ->rawParams( $truncatedtext )->inContentLanguage()->text();
843  }
844  }
845 
846  // New page auto-summaries
847  if ( $flags & EDIT_NEW && $newContent->getSize() > 0 ) {
848  // If they're making a new article, give its text, truncated, in
849  // the summary.
850 
851  $truncatedtext = $newContent->getTextForSummary(
852  200 - strlen( wfMessage( 'autosumm-new' )->inContentLanguage()->text() ) );
853 
854  return wfMessage( 'autosumm-new' )->rawParams( $truncatedtext )
855  ->inContentLanguage()->text();
856  }
857 
858  // Blanking auto-summaries
859  if ( !empty( $oldContent ) && $oldContent->getSize() > 0 && $newContent->getSize() == 0 ) {
860  return wfMessage( 'autosumm-blank' )->inContentLanguage()->text();
861  } elseif ( !empty( $oldContent )
862  && $oldContent->getSize() > 10 * $newContent->getSize()
863  && $newContent->getSize() < 500
864  ) {
865  // Removing more than 90% of the article
866 
867  $truncatedtext = $newContent->getTextForSummary(
868  200 - strlen( wfMessage( 'autosumm-replace' )->inContentLanguage()->text() ) );
869 
870  return wfMessage( 'autosumm-replace' )->rawParams( $truncatedtext )
871  ->inContentLanguage()->text();
872  }
873 
874  // New blank article auto-summary
875  if ( $flags & EDIT_NEW && $newContent->isEmpty() ) {
876  return wfMessage( 'autosumm-newblank' )->inContentLanguage()->text();
877  }
878 
879  // If we reach this point, there's no applicable auto-summary for our
880  // case, so our auto-summary is empty.
881  return '';
882  }
883 
899  public function getAutoDeleteReason( Title $title, &$hasHistory ) {
900  $dbr = wfGetDB( DB_SLAVE );
901 
902  // Get the last revision
903  $rev = Revision::newFromTitle( $title );
904 
905  if ( is_null( $rev ) ) {
906  return false;
907  }
908 
909  // Get the article's contents
910  $content = $rev->getContent();
911  $blank = false;
912 
913  // If the page is blank, use the text from the previous revision,
914  // which can only be blank if there's a move/import/protect dummy
915  // revision involved
916  if ( !$content || $content->isEmpty() ) {
917  $prev = $rev->getPrevious();
918 
919  if ( $prev ) {
920  $rev = $prev;
921  $content = $rev->getContent();
922  $blank = true;
923  }
924  }
925 
926  $this->checkModelID( $rev->getContentModel() );
927 
928  // Find out if there was only one contributor
929  // Only scan the last 20 revisions
930  $res = $dbr->select( 'revision', 'rev_user_text',
931  [
932  'rev_page' => $title->getArticleID(),
933  $dbr->bitAnd( 'rev_deleted', Revision::DELETED_USER ) . ' = 0'
934  ],
935  __METHOD__,
936  [ 'LIMIT' => 20 ]
937  );
938 
939  if ( $res === false ) {
940  // This page has no revisions, which is very weird
941  return false;
942  }
943 
944  $hasHistory = ( $res->numRows() > 1 );
945  $row = $dbr->fetchObject( $res );
946 
947  if ( $row ) { // $row is false if the only contributor is hidden
948  $onlyAuthor = $row->rev_user_text;
949  // Try to find a second contributor
950  foreach ( $res as $row ) {
951  if ( $row->rev_user_text != $onlyAuthor ) { // Bug 22999
952  $onlyAuthor = false;
953  break;
954  }
955  }
956  } else {
957  $onlyAuthor = false;
958  }
959 
960  // Generate the summary with a '$1' placeholder
961  if ( $blank ) {
962  // The current revision is blank and the one before is also
963  // blank. It's just not our lucky day
964  $reason = wfMessage( 'exbeforeblank', '$1' )->inContentLanguage()->text();
965  } else {
966  if ( $onlyAuthor ) {
967  $reason = wfMessage(
968  'excontentauthor',
969  '$1',
970  $onlyAuthor
971  )->inContentLanguage()->text();
972  } else {
973  $reason = wfMessage( 'excontent', '$1' )->inContentLanguage()->text();
974  }
975  }
976 
977  if ( $reason == '-' ) {
978  // Allow these UI messages to be blanked out cleanly
979  return '';
980  }
981 
982  // Max content length = max comment length - length of the comment (excl. $1)
983  $text = $content ? $content->getTextForSummary( 255 - ( strlen( $reason ) - 2 ) ) : '';
984 
985  // Now replace the '$1' placeholder
986  $reason = str_replace( '$1', $text, $reason );
987 
988  return $reason;
989  }
990 
1004  public function getUndoContent( Revision $current, Revision $undo, Revision $undoafter ) {
1005  $cur_content = $current->getContent();
1006 
1007  if ( empty( $cur_content ) ) {
1008  return false; // no page
1009  }
1010 
1011  $undo_content = $undo->getContent();
1012  $undoafter_content = $undoafter->getContent();
1013 
1014  if ( !$undo_content || !$undoafter_content ) {
1015  return false; // no content to undo
1016  }
1017 
1018  $this->checkModelID( $cur_content->getModel() );
1019  $this->checkModelID( $undo_content->getModel() );
1020  $this->checkModelID( $undoafter_content->getModel() );
1021 
1022  if ( $cur_content->equals( $undo_content ) ) {
1023  // No use doing a merge if it's just a straight revert.
1024  return $undoafter_content;
1025  }
1026 
1027  $undone_content = $this->merge3( $undo_content, $undoafter_content, $cur_content );
1028 
1029  return $undone_content;
1030  }
1031 
1046  public function makeParserOptions( $context ) {
1048 
1049  if ( $context instanceof IContextSource ) {
1051  } elseif ( $context instanceof User ) { // settings per user (even anons)
1052  $options = ParserOptions::newFromUser( $context );
1053  } elseif ( $context === 'canonical' ) { // canonical settings
1054  $options = ParserOptions::newFromUserAndLang( new User, $wgContLang );
1055  } else {
1056  throw new MWException( "Bad context for parser options: $context" );
1057  }
1058 
1059  $options->enableLimitReport( $wgEnableParserLimitReporting ); // show inclusion/loop reports
1060  $options->setTidy( true ); // fix bad HTML
1061 
1062  return $options;
1063  }
1064 
1073  public function isParserCacheSupported() {
1074  return false;
1075  }
1076 
1086  public function supportsSections() {
1087  return false;
1088  }
1089 
1096  public function supportsCategories() {
1097  return true;
1098  }
1099 
1109  public function supportsRedirects() {
1110  return false;
1111  }
1112 
1118  public function supportsDirectEditing() {
1119  return false;
1120  }
1121 
1127  public function supportsDirectApiEditing() {
1128  return $this->supportsDirectEditing();
1129  }
1130 
1144  public static function deprecated( $func, $version, $component = false ) {
1145  if ( self::$enableDeprecationWarnings ) {
1146  wfDeprecated( $func, $version, $component, 3 );
1147  }
1148  }
1149 
1167  public static function runLegacyHooks( $event, $args = [],
1168  $warn = null
1169  ) {
1170 
1171  if ( $warn === null ) {
1172  $warn = self::$enableDeprecationWarnings;
1173  }
1174 
1175  if ( !Hooks::isRegistered( $event ) ) {
1176  return true; // nothing to do here
1177  }
1178 
1179  if ( $warn ) {
1180  // Log information about which handlers are registered for the legacy hook,
1181  // so we can find and fix them.
1182 
1183  $handlers = Hooks::getHandlers( $event );
1184  $handlerInfo = [];
1185 
1186  MediaWiki\suppressWarnings();
1187 
1188  foreach ( $handlers as $handler ) {
1189  if ( is_array( $handler ) ) {
1190  if ( is_object( $handler[0] ) ) {
1191  $info = get_class( $handler[0] );
1192  } else {
1193  $info = $handler[0];
1194  }
1195 
1196  if ( isset( $handler[1] ) ) {
1197  $info .= '::' . $handler[1];
1198  }
1199  } elseif ( is_object( $handler ) ) {
1200  $info = get_class( $handler[0] );
1201  $info .= '::on' . $event;
1202  } else {
1203  $info = $handler;
1204  }
1205 
1206  $handlerInfo[] = $info;
1207  }
1208 
1209  MediaWiki\restoreWarnings();
1210 
1211  wfWarn( "Using obsolete hook $event via ContentHandler::runLegacyHooks()! Handlers: " .
1212  implode( ', ', $handlerInfo ), 2 );
1213  }
1214 
1215  // convert Content objects to text
1216  $contentObjects = [];
1217  $contentTexts = [];
1218 
1219  foreach ( $args as $k => $v ) {
1220  if ( $v instanceof Content ) {
1221  /* @var Content $v */
1222 
1223  $contentObjects[$k] = $v;
1224 
1225  $v = $v->serialize();
1226  $contentTexts[$k] = $v;
1227  $args[$k] = $v;
1228  }
1229  }
1230 
1231  // call the hook functions
1232  $ok = Hooks::run( $event, $args );
1233 
1234  // see if the hook changed the text
1235  foreach ( $contentTexts as $k => $orig ) {
1236  /* @var Content $content */
1237 
1238  $modified = $args[$k];
1239  $content = $contentObjects[$k];
1240 
1241  if ( $modified !== $orig ) {
1242  // text was changed, create updated Content object
1243  $content = $content->getContentHandler()->unserializeContent( $modified );
1244  }
1245 
1246  $args[$k] = $content;
1247  }
1248 
1249  return $ok;
1250  }
1251 
1258  public function getFieldsForSearchIndex( SearchEngine $engine ) {
1259  /* Default fields:
1260  /*
1261  * namespace
1262  * namespace_text
1263  * redirect
1264  * source_text
1265  * suggest
1266  * timestamp
1267  * title
1268  * text
1269  * text_bytes
1270  */
1271  return [];
1272  }
1273 }
static newFromContext(IContextSource $context)
Get a ParserOptions object from a IContextSource object.
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
wfGetDB($db, $groups=[], $wiki=false)
Get a Database object.
const CONTENT_MODEL_WIKITEXT
Definition: Defines.php:278
getContentHandler()
Convenience method that returns the ContentHandler singleton for handling the content model that this...
serialize($format=null)
Convenience method for serializing this Content object.
getArticleID($flags=0)
Get the article ID for this Title from the link cache, adding it if necessary.
Definition: Title.php:3141
getText()
Get the text form (spaces not underscores) of the main part.
Definition: Title.php:872
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 prev or next refreshes the diff cache $unhide
Definition: hooks.txt:1435
if(!isset($args[0])) $lang
static isRegistered($name)
Returns true if a hook has a function registered to it.
Definition: Hooks.php:83
static newFromUserAndLang(User $user, Language $lang)
Get a ParserOptions object from a given user and language.
$wgEnableParserLimitReporting
Whether to include the NewPP limit report as a HTML comment.
it s the revision text itself In either if gzip is the revision text is gzipped $flags
Definition: hooks.txt:2588
static getHandlers($name)
Returns an array of all the event functions attached to a hook This combines functions registered via...
Definition: Hooks.php:97
const CONTENT_MODEL_TEXT
Definition: Defines.php:281
getTextForSummary($maxLength=250)
Returns a textual representation of the content suitable for use in edit summaries and log messages...
Represents a title within MediaWiki.
Definition: Title.php:36
when a variable name is used in a it is silently declared as a new local masking the global
Definition: design.txt:93
static newFromUser($user)
Get a ParserOptions object from a given user.
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:117
const CONTENT_MODEL_JSON
Definition: Defines.php:282
$wgContentHandlerTextFallback
How to react if a plain text version of a non-text Content object is requested using ContentHandler::...
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
static getNamespaceContentModel($index)
Get the default content model for a namespace This does not mean that all pages in that namespace hav...
if($line===false) $args
Definition: cdb.php:64
The User object encapsulates all of the user-specific settings (user_id, name, rights, email address, options, last login time).
Definition: User.php:47
getContentModel($flags=0)
Get the page's content model id, see the CONTENT_MODEL_XXX constants.
Definition: Title.php:923
wfDebugLog($logGroup, $text, $dest= 'all', array $context=[])
Send a line to a supplementary debug log file, if configured, or main debug log if not...
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 prev or next $refreshCache
Definition: hooks.txt:1435
wfWarn($msg, $callerOffset=1, $level=E_USER_NOTICE)
Send a warning either to the debug log or in a PHP error depending on $wgDevelopmentWarnings.
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist e g Watchlist 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:1020
string $modelId
The name of the unknown content model.
MediaWiki exception.
Definition: MWException.php:26
isEmpty()
Returns true if this Content object represents empty content.
Internationalisation code.
Definition: Language.php:39
wfDeprecated($function, $version=false, $component=false, $callerOffset=2)
Throws a warning that $function is deprecated.
const DB_SLAVE
Definition: Defines.php:46
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped just before the function returns a value If you return an< a > element with HTML attributes $attribs and contents $html will be returned If you return $ret will be returned after processing 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 unsetoffset-wrap String Wrap the message in html(usually something like"&lt
static run($event, array $args=[], $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
Definition: Hooks.php:131
getNamespace()
Get the namespace index, i.e.
Definition: Title.php:913
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
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:1601
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
const NS_MEDIAWIKI
Definition: Defines.php:77
CONTENT_MODEL_JAVASCRIPT
Uploads have to be specially set up to be secure.
getNativeData()
Returns native representation of the data.
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
Exception thrown when an unregistered content model is requested.
const DELETED_USER
Definition: Revision.php:78
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
const EDIT_NEW
Definition: Defines.php:179
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist e g Watchlist 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:1020
$wgContentHandlers
Plugins for page content model handling.
Contain a class for special pages.
getContent($audience=self::FOR_PUBLIC, User $user=null)
Fetch revision content if it's available to the specified audience.
Definition: Revision.php:1046
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:56
const CONTENT_MODEL_CSS
Definition: Defines.php:280
$version
Definition: parserTests.php:94
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:776
getModel()
Returns the ID of the content model used by this Content object.
static factory($code)
Get a cached or new language object for a given language code.
Definition: Language.php:179
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 prev or next refreshes the diff cache allow viewing deleted revs & $differenceEngine
Definition: hooks.txt:1435
static singleton()
Get the signleton instance of this class.
Exception representing a failure to serialize or unserialize a content object.
wfGetLangObj($langcode=false)
Return a Language object from $langcode.
Allows to change the fields on the form that will be generated $name
Definition: hooks.txt:310