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  // recursive check to follow double redirects
319  $recurse = $wgMaxRedirects;
320  $titles = [ $title ];
321  while ( --$recurse > 0 ) {
322  if ( $title->isRedirect() ) {
323  $page = WikiPage::factory( $title );
324  $newtitle = $page->getRedirectTarget();
325  } else {
326  break;
327  }
328  // Redirects to some special pages are not permitted
329  if ( $newtitle instanceof Title && $newtitle->isValidRedirectTarget() ) {
330  // The new title passes the checks, so make that our current
331  // title so that further recursion can be checked
332  $title = $newtitle;
333  $titles[] = $newtitle;
334  } else {
335  break;
336  }
337  }
338 
339  return $titles;
340  }
341 
352  public function getRedirectTarget() {
353  return null;
354  }
355 
365  public function getUltimateRedirectTarget() {
366  $titles = $this->getRedirectChain();
367 
368  return $titles ? array_pop( $titles ) : null;
369  }
370 
378  public function isRedirect() {
379  return $this->getRedirectTarget() !== null;
380  }
381 
395  public function updateRedirect( Title $target ) {
396  return $this;
397  }
398 
408  public function getSection( $sectionId ) {
409  return null;
410  }
411 
423  public function replaceSection( $sectionId, Content $with, $sectionTitle = '' ) {
424  return null;
425  }
426 
438  public function preSaveTransform( Title $title, User $user, ParserOptions $popts ) {
439  return $this;
440  }
441 
451  public function addSectionHeader( $header ) {
452  return $this;
453  }
454 
466  public function preloadTransform( Title $title, ParserOptions $popts, $params = [] ) {
467  return $this;
468  }
469 
482  public function prepareSave( WikiPage $page, $flags, $parentRevId, User $user ) {
483  if ( $this->isValid() ) {
484  return Status::newGood();
485  } else {
486  return Status::newFatal( "invalid-content-data" );
487  }
488  }
489 
501  public function getDeletionUpdates( WikiPage $page, ParserOutput $parserOutput = null ) {
502  return [
503  new LinksDeletionUpdate( $page ),
504  ];
505  }
506 
520  public function matchMagicWord( MagicWord $word ) {
521  return false;
522  }
523 
537  public function convert( $toModel, $lossy = '' ) {
538  if ( $this->getModel() === $toModel ) {
539  // nothing to do, shorten out.
540  return $this;
541  }
542 
543  $lossy = ( $lossy === 'lossy' ); // string flag, convert to boolean for convenience
544  $result = false;
545 
546  Hooks::runner()->onConvertContent( $this, $toModel, $lossy, $result );
547 
548  return $result;
549  }
550 
573  public function getParserOutput( Title $title, $revId = null,
574  ParserOptions $options = null, $generateHtml = true
575  ) {
576  if ( $options === null ) {
577  $options = ParserOptions::newCanonical( 'canonical' );
578  }
579 
580  $po = new ParserOutput();
581  $options->registerWatcher( [ $po, 'recordOption' ] );
582 
583  if ( Hooks::runner()->onContentGetParserOutput(
584  $this, $title, $revId, $options, $generateHtml, $po )
585  ) {
586  // Save and restore the old value, just in case something is reusing
587  // the ParserOptions object in some weird way.
588  $oldRedir = $options->getRedirectTarget();
589  $options->setRedirectTarget( $this->getRedirectTarget() );
590  $this->fillParserOutput( $title, $revId, $options, $generateHtml, $po );
591  $options->setRedirectTarget( $oldRedir );
592  }
593 
594  Hooks::runner()->onContentAlterParserOutput( $this, $title, $po );
595  $options->registerWatcher( null );
596 
597  return $po;
598  }
599 
623  protected function fillParserOutput( Title $title, $revId,
624  ParserOptions $options, $generateHtml, ParserOutput &$output
625  ) {
626  // Don't make abstract, so subclasses that override getParserOutput() directly don't fail.
627  throw new MWException( 'Subclasses of AbstractContent must override fillParserOutput!' );
628  }
629 }
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:451
Content\serialize
serialize( $format=null)
Convenience method for serializing this Content object.
ParserOutput
Definition: ParserOutput.php:25
AbstractContent\isRedirect
isRedirect()
Definition: AbstractContent.php:378
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:623
AbstractContent\convert
convert( $toModel, $lossy='')
This base implementation calls the hook ConvertContent to enable custom conversions.
Definition: AbstractContent.php:537
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:154
AbstractContent\replaceSection
replaceSection( $sectionId, Content $with, $sectionTitle='')
Stable to override.
Definition: AbstractContent.php:423
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:573
AbstractContent\getContentHandlerFactory
getContentHandlerFactory()
Definition: AbstractContent.php:102
AbstractContent\getRedirectTarget
getRedirectTarget()
Subclasses that implement redirects should override this.
Definition: AbstractContent.php:352
AbstractContent\updateRedirect
updateRedirect(Title $target)
This default implementation always returns $this.
Definition: AbstractContent.php:395
WikiPage
Class representing a MediaWiki article and history.
Definition: WikiPage.php:52
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:365
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:520
AbstractContent\preSaveTransform
preSaveTransform(Title $title, User $user, ParserOptions $popts)
Stable to override.
Definition: AbstractContent.php:438
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
WikiPage\factory
static factory(Title $title)
Create a WikiPage object of the appropriate class for the given title.
Definition: WikiPage.php:156
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:4334
AbstractContent\prepareSave
prepareSave(WikiPage $page, $flags, $parentRevId, User $user)
Stable to override.
Definition: AbstractContent.php:482
$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:466
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:41
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:408
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:1135
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:501
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:42
$wgMaxRedirects
$wgMaxRedirects
Max number of redirects to follow when resolving redirects.
Definition: DefaultSettings.php:4506
User
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition: User.php:55
AbstractContent\getSupportedFormats
getSupportedFormats()
Definition: AbstractContent.php:122
AbstractContent\isValid
isValid()
Subclasses may override this to implement (light weight) validation.
Definition: AbstractContent.php:195