MediaWiki  master
AbstractContent.php
Go to the documentation of this file.
1 <?php
31 
39 abstract class AbstractContent implements Content {
48  protected $model_id;
49 
57  public function __construct( $modelId = null ) {
58  $this->model_id = $modelId;
59  }
60 
67  public function getModel() {
68  return $this->model_id;
69  }
70 
79  protected function checkModelID( $modelId ) {
80  if ( $modelId !== $this->model_id ) {
81  throw new MWException(
82  "Bad content model: " .
83  "expected {$this->model_id} " .
84  "but got $modelId."
85  );
86  }
87  }
88 
95  public function getContentHandler() {
96  return $this->getContentHandlerFactory()->getContentHandler( $this->getModel() );
97  }
98 
103  return MediaWikiServices::getInstance()->getContentHandlerFactory();
104  }
105 
112  public function getDefaultFormat() {
113  return $this->getContentHandler()->getDefaultFormat();
114  }
115 
122  public function getSupportedFormats() {
123  return $this->getContentHandler()->getSupportedFormats();
124  }
125 
135  public function isSupportedFormat( $format ) {
136  if ( !$format ) {
137  return true; // this means "use the default"
138  }
139 
140  return $this->getContentHandler()->isSupportedFormat( $format );
141  }
142 
150  protected function checkFormat( $format ) {
151  if ( !$this->isSupportedFormat( $format ) ) {
152  throw new MWException(
153  "Format $format is not supported for content model " .
154  $this->getModel()
155  );
156  }
157  }
158 
169  public function serialize( $format = null ) {
170  return $this->getContentHandler()->serializeContent( $this, $format );
171  }
172 
181  public function isEmpty() {
182  return $this->getSize() === 0;
183  }
184 
195  public function isValid() {
196  return true;
197  }
198 
220  public function equals( Content $that = null ) {
221  if ( $that === null ) {
222  return false;
223  }
224 
225  if ( $that === $this ) {
226  return true;
227  }
228 
229  if ( $that->getModel() !== $this->getModel() ) {
230  return false;
231  }
232 
233  // For type safety. Needed for odd cases like MessageContent using CONTENT_MODEL_WIKITEXT
234  if ( get_class( $that ) !== get_class( $this ) ) {
235  return false;
236  }
237 
238  return $this->equalsInternal( $that );
239  }
240 
261  protected function equalsInternal( Content $that ) {
262  return $this->serialize() === $that->serialize();
263  }
264 
289  public function getSecondaryDataUpdates( Title $title, Content $old = null,
290  $recursive = true, ParserOutput $parserOutput = null
291  ) {
292  if ( $parserOutput === null ) {
293  $parserOutput = $this->getParserOutput( $title, null, null, false );
294  }
295 
296  $updates = [
297  new LinksUpdate( $title, $parserOutput, $recursive )
298  ];
299 
300  Hooks::runner()->onSecondaryDataUpdates( $title, $old, $recursive, $parserOutput, $updates );
301 
302  return $updates;
303  }
304 
312  public function getRedirectChain() {
313  global $wgMaxRedirects;
314  $title = $this->getRedirectTarget();
315  if ( $title === null ) {
316  return null;
317  }
318  $wikiPageFactory = MediaWikiServices::getInstance()->getWikiPageFactory();
319  // recursive check to follow double redirects
320  $recurse = $wgMaxRedirects;
321  $titles = [ $title ];
322  while ( --$recurse > 0 ) {
323  if ( $title->isRedirect() ) {
324  $page = $wikiPageFactory->newFromTitle( $title );
325  $newtitle = $page->getRedirectTarget();
326  } else {
327  break;
328  }
329  // Redirects to some special pages are not permitted
330  if ( $newtitle instanceof Title && $newtitle->isValidRedirectTarget() ) {
331  // The new title passes the checks, so make that our current
332  // title so that further recursion can be checked
333  $title = $newtitle;
334  $titles[] = $newtitle;
335  } else {
336  break;
337  }
338  }
339 
340  return $titles;
341  }
342 
353  public function getRedirectTarget() {
354  return null;
355  }
356 
366  public function getUltimateRedirectTarget() {
367  $titles = $this->getRedirectChain();
368 
369  return $titles ? array_pop( $titles ) : null;
370  }
371 
379  public function isRedirect() {
380  return $this->getRedirectTarget() !== null;
381  }
382 
396  public function updateRedirect( Title $target ) {
397  return $this;
398  }
399 
409  public function getSection( $sectionId ) {
410  return null;
411  }
412 
424  public function replaceSection( $sectionId, Content $with, $sectionTitle = '' ) {
425  return null;
426  }
427 
439  public function preSaveTransform( Title $title, User $user, ParserOptions $popts ) {
440  return $this;
441  }
442 
452  public function addSectionHeader( $header ) {
453  return $this;
454  }
455 
467  public function preloadTransform( Title $title, ParserOptions $popts, $params = [] ) {
468  return $this;
469  }
470 
483  public function prepareSave( WikiPage $page, $flags, $parentRevId, User $user ) {
484  if ( $this->isValid() ) {
485  return Status::newGood();
486  } else {
487  return Status::newFatal( "invalid-content-data" );
488  }
489  }
490 
502  public function getDeletionUpdates( WikiPage $page, ParserOutput $parserOutput = null ) {
503  return [
504  new LinksDeletionUpdate( $page ),
505  ];
506  }
507 
521  public function matchMagicWord( MagicWord $word ) {
522  return false;
523  }
524 
538  public function convert( $toModel, $lossy = '' ) {
539  if ( $this->getModel() === $toModel ) {
540  // nothing to do, shorten out.
541  return $this;
542  }
543 
544  $lossy = ( $lossy === 'lossy' ); // string flag, convert to boolean for convenience
545  $result = false;
546 
547  Hooks::runner()->onConvertContent( $this, $toModel, $lossy, $result );
548 
549  return $result;
550  }
551 
574  public function getParserOutput( Title $title, $revId = null,
575  ParserOptions $options = null, $generateHtml = true
576  ) {
577  if ( $options === null ) {
578  $options = ParserOptions::newCanonical( 'canonical' );
579  }
580 
581  $po = new ParserOutput();
582  $options->registerWatcher( [ $po, 'recordOption' ] );
583 
584  if ( Hooks::runner()->onContentGetParserOutput(
585  $this, $title, $revId, $options, $generateHtml, $po )
586  ) {
587  // Save and restore the old value, just in case something is reusing
588  // the ParserOptions object in some weird way.
589  $oldRedir = $options->getRedirectTarget();
590  $options->setRedirectTarget( $this->getRedirectTarget() );
591  $this->fillParserOutput( $title, $revId, $options, $generateHtml, $po );
592  $options->setRedirectTarget( $oldRedir );
593  }
594 
595  Hooks::runner()->onContentAlterParserOutput( $this, $title, $po );
596  $options->registerWatcher( null );
597 
598  return $po;
599  }
600 
624  protected function fillParserOutput( Title $title, $revId,
625  ParserOptions $options, $generateHtml, ParserOutput &$output
626  ) {
627  // Don't make abstract, so subclasses that override getParserOutput() directly don't fail.
628  throw new MWException( 'Subclasses of AbstractContent must override fillParserOutput!' );
629  }
630 }
AbstractContent\getSecondaryDataUpdates
getSecondaryDataUpdates(Title $title, Content $old=null, $recursive=true, ParserOutput $parserOutput=null)
Returns a list of DataUpdate objects for recording information about this Content in some secondary d...
Definition: AbstractContent.php:289
ParserOptions
Set options of the Parser.
Definition: ParserOptions.php:44
AbstractContent\addSectionHeader
addSectionHeader( $header)
Stable to override.
Definition: AbstractContent.php:452
Content\serialize
serialize( $format=null)
Convenience method for serializing this Content object.
ParserOutput
Definition: ParserOutput.php:31
AbstractContent\isRedirect
isRedirect()
Definition: AbstractContent.php:379
StatusValue\newFatal
static newFatal( $message,... $parameters)
Factory function for fatal errors.
Definition: StatusValue.php:70
AbstractContent\fillParserOutput
fillParserOutput(Title $title, $revId, ParserOptions $options, $generateHtml, ParserOutput &$output)
Fills the provided ParserOutput with information derived from the content.
Definition: AbstractContent.php:624
AbstractContent\convert
convert( $toModel, $lossy='')
This base implementation calls the hook ConvertContent to enable custom conversions.
Definition: AbstractContent.php:538
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:166
AbstractContent\replaceSection
replaceSection( $sectionId, Content $with, $sectionTitle='')
Stable to override.
Definition: AbstractContent.php:424
AbstractContent\checkFormat
checkFormat( $format)
Definition: AbstractContent.php:150
AbstractContent\getParserOutput
getParserOutput(Title $title, $revId=null, ParserOptions $options=null, $generateHtml=true)
Returns a ParserOutput object containing information derived from this content.
Definition: AbstractContent.php:574
AbstractContent\getContentHandlerFactory
getContentHandlerFactory()
Definition: AbstractContent.php:102
AbstractContent\getRedirectTarget
getRedirectTarget()
Subclasses that implement redirects should override this.
Definition: AbstractContent.php:353
AbstractContent\updateRedirect
updateRedirect(Title $target)
This default implementation always returns $this.
Definition: AbstractContent.php:396
WikiPage
Class representing a MediaWiki article and history.
Definition: WikiPage.php:55
LinksUpdate
Class the manages updates of *_link tables as well as similar extension-managed tables.
Definition: LinksUpdate.php:37
AbstractContent\getRedirectChain
getRedirectChain()
Definition: AbstractContent.php:312
AbstractContent\equals
equals(Content $that=null)
Decides whether two Content objects are equal.
Definition: AbstractContent.php:220
AbstractContent\isEmpty
isEmpty()
Stable to override.
Definition: AbstractContent.php:181
AbstractContent\getUltimateRedirectTarget
getUltimateRedirectTarget()
Definition: AbstractContent.php:366
Content\getSize
getSize()
Returns the content's nominal size in "bogo-bytes".
AbstractContent\matchMagicWord
matchMagicWord(MagicWord $word)
This default implementation always returns false.
Definition: AbstractContent.php:521
AbstractContent\preSaveTransform
preSaveTransform(Title $title, User $user, ParserOptions $popts)
Stable to override.
Definition: AbstractContent.php:439
AbstractContent\getDefaultFormat
getDefaultFormat()
Definition: AbstractContent.php:112
MWException
MediaWiki exception.
Definition: MWException.php:29
AbstractContent\checkModelID
checkModelID( $modelId)
Definition: AbstractContent.php:79
AbstractContent\getContentHandler
getContentHandler()
Definition: AbstractContent.php:95
AbstractContent\isSupportedFormat
isSupportedFormat( $format)
Definition: AbstractContent.php:135
AbstractContent\serialize
serialize( $format=null)
Stable to override.
Definition: AbstractContent.php:169
Title\isValidRedirectTarget
isValidRedirectTarget()
Check if this Title is a valid redirect target.
Definition: Title.php:4291
AbstractContent\prepareSave
prepareSave(WikiPage $page, $flags, $parentRevId, User $user)
Stable to override.
Definition: AbstractContent.php:483
$title
$title
Definition: testCompression.php:38
AbstractContent\__construct
__construct( $modelId=null)
Stable to call.
Definition: AbstractContent.php:57
MagicWord
This class encapsulates "magic words" such as "#redirect", NOTOC, etc.
Definition: MagicWord.php:60
AbstractContent\preloadTransform
preloadTransform(Title $title, ParserOptions $popts, $params=[])
Stable to override.
Definition: AbstractContent.php:467
AbstractContent\equalsInternal
equalsInternal(Content $that)
Checks whether $that is logically equal to this Content object.
Definition: AbstractContent.php:261
MediaWiki\Content\IContentHandlerFactory
Definition: IContentHandlerFactory.php:10
$header
$header
Definition: updateCredits.php:37
StatusValue\newGood
static newGood( $value=null)
Factory function for good results.
Definition: StatusValue.php:82
AbstractContent
Base implementation for content objects.
Definition: AbstractContent.php:39
AbstractContent\getSection
getSection( $sectionId)
Stable to override.
Definition: AbstractContent.php:409
Hooks\runner
static runner()
Get a HookRunner instance for calling hooks using the new interfaces.
Definition: Hooks.php:172
ParserOptions\newCanonical
static newCanonical( $context=null, $userLang=null)
Creates a "canonical" ParserOptions object.
Definition: ParserOptions.php:1133
LinksDeletionUpdate
Update object handling the cleanup of links tables after a page was deleted.
Definition: LinksDeletionUpdate.php:28
AbstractContent\getDeletionUpdates
getDeletionUpdates(WikiPage $page, ParserOutput $parserOutput=null)
Stable to override.
Definition: AbstractContent.php:502
Content
Base interface for content objects.
Definition: Content.php:35
AbstractContent\getModel
getModel()
Definition: AbstractContent.php:67
AbstractContent\$model_id
string $model_id
Name of the content model this Content object represents.
Definition: AbstractContent.php:48
Title
Represents a title within MediaWiki.
Definition: Title.php:46
$wgMaxRedirects
$wgMaxRedirects
Max number of redirects to follow when resolving redirects.
Definition: DefaultSettings.php:4514
User
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition: User.php:56
AbstractContent\getSupportedFormats
getSupportedFormats()
Definition: AbstractContent.php:122
AbstractContent\isValid
isValid()
Subclasses may override this to implement (light weight) validation.
Definition: AbstractContent.php:195