MediaWiki  master
AbstractContent.php
Go to the documentation of this file.
1 <?php
31 
37 abstract class AbstractContent implements Content {
46  protected $model_id;
47 
53  public function __construct( $modelId = null ) {
54  $this->model_id = $modelId;
55  }
56 
63  public function getModel() {
64  return $this->model_id;
65  }
66 
75  protected function checkModelID( $modelId ) {
76  if ( $modelId !== $this->model_id ) {
77  throw new MWException(
78  "Bad content model: " .
79  "expected {$this->model_id} " .
80  "but got $modelId."
81  );
82  }
83  }
84 
91  public function getContentHandler() {
92  return $this->getContentHandlerFactory()->getContentHandler( $this->getModel() );
93  }
94 
99  return MediaWikiServices::getInstance()->getContentHandlerFactory();
100  }
101 
108  public function getDefaultFormat() {
109  return $this->getContentHandler()->getDefaultFormat();
110  }
111 
118  public function getSupportedFormats() {
119  return $this->getContentHandler()->getSupportedFormats();
120  }
121 
131  public function isSupportedFormat( $format ) {
132  if ( !$format ) {
133  return true; // this means "use the default"
134  }
135 
136  return $this->getContentHandler()->isSupportedFormat( $format );
137  }
138 
146  protected function checkFormat( $format ) {
147  if ( !$this->isSupportedFormat( $format ) ) {
148  throw new MWException(
149  "Format $format is not supported for content model " .
150  $this->getModel()
151  );
152  }
153  }
154 
164  public function serialize( $format = null ) {
165  return $this->getContentHandler()->serializeContent( $this, $format );
166  }
167 
175  public function isEmpty() {
176  return $this->getSize() === 0;
177  }
178 
188  public function isValid() {
189  return true;
190  }
191 
212  public function equals( Content $that = null ) {
213  if ( $that === null ) {
214  return false;
215  }
216 
217  if ( $that === $this ) {
218  return true;
219  }
220 
221  if ( $that->getModel() !== $this->getModel() ) {
222  return false;
223  }
224 
225  // For type safety. Needed for odd cases like MessageContent using CONTENT_MODEL_WIKITEXT
226  if ( get_class( $that ) !== get_class( $this ) ) {
227  return false;
228  }
229 
230  return $this->equalsInternal( $that );
231  }
232 
251  protected function equalsInternal( Content $that ) {
252  return $this->serialize() === $that->serialize();
253  }
254 
278  public function getSecondaryDataUpdates( Title $title, Content $old = null,
279  $recursive = true, ParserOutput $parserOutput = null
280  ) {
281  if ( $parserOutput === null ) {
282  $parserOutput = $this->getParserOutput( $title, null, null, false );
283  }
284 
285  $updates = [
286  new LinksUpdate( $title, $parserOutput, $recursive )
287  ];
288 
289  Hooks::run( 'SecondaryDataUpdates', [ $title, $old, $recursive, $parserOutput, &$updates ] );
290 
291  return $updates;
292  }
293 
301  public function getRedirectChain() {
302  global $wgMaxRedirects;
303  $title = $this->getRedirectTarget();
304  if ( $title === null ) {
305  return null;
306  }
307  // recursive check to follow double redirects
308  $recurse = $wgMaxRedirects;
309  $titles = [ $title ];
310  while ( --$recurse > 0 ) {
311  if ( $title->isRedirect() ) {
312  $page = WikiPage::factory( $title );
313  $newtitle = $page->getRedirectTarget();
314  } else {
315  break;
316  }
317  // Redirects to some special pages are not permitted
318  if ( $newtitle instanceof Title && $newtitle->isValidRedirectTarget() ) {
319  // The new title passes the checks, so make that our current
320  // title so that further recursion can be checked
321  $title = $newtitle;
322  $titles[] = $newtitle;
323  } else {
324  break;
325  }
326  }
327 
328  return $titles;
329  }
330 
340  public function getRedirectTarget() {
341  return null;
342  }
343 
353  public function getUltimateRedirectTarget() {
354  $titles = $this->getRedirectChain();
355 
356  return $titles ? array_pop( $titles ) : null;
357  }
358 
366  public function isRedirect() {
367  return $this->getRedirectTarget() !== null;
368  }
369 
382  public function updateRedirect( Title $target ) {
383  return $this;
384  }
385 
394  public function getSection( $sectionId ) {
395  return null;
396  }
397 
408  public function replaceSection( $sectionId, Content $with, $sectionTitle = '' ) {
409  return null;
410  }
411 
422  public function preSaveTransform( Title $title, User $user, ParserOptions $popts ) {
423  return $this;
424  }
425 
434  public function addSectionHeader( $header ) {
435  return $this;
436  }
437 
448  public function preloadTransform( Title $title, ParserOptions $popts, $params = [] ) {
449  return $this;
450  }
451 
463  public function prepareSave( WikiPage $page, $flags, $parentRevId, User $user ) {
464  if ( $this->isValid() ) {
465  return Status::newGood();
466  } else {
467  return Status::newFatal( "invalid-content-data" );
468  }
469  }
470 
481  public function getDeletionUpdates( WikiPage $page, ParserOutput $parserOutput = null ) {
482  return [
483  new LinksDeletionUpdate( $page ),
484  ];
485  }
486 
499  public function matchMagicWord( MagicWord $word ) {
500  return false;
501  }
502 
514  public function convert( $toModel, $lossy = '' ) {
515  if ( $this->getModel() === $toModel ) {
516  // nothing to do, shorten out.
517  return $this;
518  }
519 
520  $lossy = ( $lossy === 'lossy' ); // string flag, convert to boolean for convenience
521  $result = false;
522 
523  Hooks::run( 'ConvertContent', [ $this, $toModel, $lossy, &$result ] );
524 
525  return $result;
526  }
527 
548  public function getParserOutput( Title $title, $revId = null,
549  ParserOptions $options = null, $generateHtml = true
550  ) {
551  if ( $options === null ) {
552  $options = ParserOptions::newCanonical( 'canonical' );
553  }
554 
555  $po = new ParserOutput();
556  $options->registerWatcher( [ $po, 'recordOption' ] );
557 
558  if ( Hooks::run( 'ContentGetParserOutput',
559  [ $this, $title, $revId, $options, $generateHtml, &$po ] )
560  ) {
561  // Save and restore the old value, just in case something is reusing
562  // the ParserOptions object in some weird way.
563  $oldRedir = $options->getRedirectTarget();
564  $options->setRedirectTarget( $this->getRedirectTarget() );
565  $this->fillParserOutput( $title, $revId, $options, $generateHtml, $po );
566  $options->setRedirectTarget( $oldRedir );
567  }
568 
569  Hooks::run( 'ContentAlterParserOutput', [ $this, $title, $po ] );
570  $options->registerWatcher( null );
571 
572  return $po;
573  }
574 
596  protected function fillParserOutput( Title $title, $revId,
597  ParserOptions $options, $generateHtml, ParserOutput &$output
598  ) {
599  // Don't make abstract, so subclasses that override getParserOutput() directly don't fail.
600  throw new MWException( 'Subclasses of AbstractContent must override fillParserOutput!' );
601  }
602 }
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:278
ParserOptions
Set options of the Parser.
Definition: ParserOptions.php:42
AbstractContent\addSectionHeader
addSectionHeader( $header)
Definition: AbstractContent.php:434
Content\serialize
serialize( $format=null)
Convenience method for serializing this Content object.
ParserOutput
Definition: ParserOutput.php:25
AbstractContent\isRedirect
isRedirect()
Definition: AbstractContent.php:366
StatusValue\newFatal
static newFatal( $message,... $parameters)
Factory function for fatal errors.
Definition: StatusValue.php:69
AbstractContent\fillParserOutput
fillParserOutput(Title $title, $revId, ParserOptions $options, $generateHtml, ParserOutput &$output)
Fills the provided ParserOutput with information derived from the content.
Definition: AbstractContent.php:596
AbstractContent\convert
convert( $toModel, $lossy='')
This base implementation calls the hook ConvertContent to enable custom conversions.
Definition: AbstractContent.php:514
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:144
AbstractContent\replaceSection
replaceSection( $sectionId, Content $with, $sectionTitle='')
Definition: AbstractContent.php:408
AbstractContent\checkFormat
checkFormat( $format)
Definition: AbstractContent.php:146
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:548
AbstractContent\getContentHandlerFactory
getContentHandlerFactory()
Definition: AbstractContent.php:98
AbstractContent\getRedirectTarget
getRedirectTarget()
Subclasses that implement redirects should override this.
Definition: AbstractContent.php:340
AbstractContent\updateRedirect
updateRedirect(Title $target)
This default implementation always returns $this.
Definition: AbstractContent.php:382
WikiPage
Class representing a MediaWiki article and history.
Definition: WikiPage.php:48
LinksUpdate
Class the manages updates of *_link tables as well as similar extension-managed tables.
Definition: LinksUpdate.php:36
AbstractContent\getRedirectChain
getRedirectChain()
Definition: AbstractContent.php:301
AbstractContent\equals
equals(Content $that=null)
Decides whether two Content objects are equal.
Definition: AbstractContent.php:212
AbstractContent\isEmpty
isEmpty()
Definition: AbstractContent.php:175
AbstractContent\getUltimateRedirectTarget
getUltimateRedirectTarget()
Definition: AbstractContent.php:353
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:499
AbstractContent\preSaveTransform
preSaveTransform(Title $title, User $user, ParserOptions $popts)
Definition: AbstractContent.php:422
AbstractContent\getDefaultFormat
getDefaultFormat()
Definition: AbstractContent.php:108
MWException
MediaWiki exception.
Definition: MWException.php:26
AbstractContent\checkModelID
checkModelID( $modelId)
Definition: AbstractContent.php:75
AbstractContent\getContentHandler
getContentHandler()
Definition: AbstractContent.php:91
WikiPage\factory
static factory(Title $title)
Create a WikiPage object of the appropriate class for the given title.
Definition: WikiPage.php:143
AbstractContent\isSupportedFormat
isSupportedFormat( $format)
Definition: AbstractContent.php:131
AbstractContent\serialize
serialize( $format=null)
Definition: AbstractContent.php:164
Title\isValidRedirectTarget
isValidRedirectTarget()
Check if this Title is a valid redirect target.
Definition: Title.php:4304
AbstractContent\prepareSave
prepareSave(WikiPage $page, $flags, $parentRevId, User $user)
Definition: AbstractContent.php:463
$title
$title
Definition: testCompression.php:38
AbstractContent\__construct
__construct( $modelId=null)
Definition: AbstractContent.php:53
MagicWord
This class encapsulates "magic words" such as "#redirect", NOTOC, etc.
Definition: MagicWord.php:57
AbstractContent\preloadTransform
preloadTransform(Title $title, ParserOptions $popts, $params=[])
Definition: AbstractContent.php:448
AbstractContent\equalsInternal
equalsInternal(Content $that)
Checks whether $that is logically equal to this Content object.
Definition: AbstractContent.php:251
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:81
AbstractContent
Base implementation for content objects.
Definition: AbstractContent.php:37
AbstractContent\getSection
getSection( $sectionId)
Definition: AbstractContent.php:394
ParserOptions\newCanonical
static newCanonical( $context=null, $userLang=null)
Creates a "canonical" ParserOptions object.
Definition: ParserOptions.php:1123
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)
Definition: AbstractContent.php:481
Content
Base interface for content objects.
Definition: Content.php:34
AbstractContent\getModel
getModel()
Definition: AbstractContent.php:63
AbstractContent\$model_id
string $model_id
Name of the content model this Content object represents.
Definition: AbstractContent.php:46
Title
Represents a title within MediaWiki.
Definition: Title.php:42
$wgMaxRedirects
$wgMaxRedirects
Max number of redirects to follow when resolving redirects.
Definition: DefaultSettings.php:4468
User
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition: User.php:54
Hooks\run
static run( $event, array $args=[], $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
Definition: Hooks.php:133
AbstractContent\getSupportedFormats
getSupportedFormats()
Definition: AbstractContent.php:118
AbstractContent\isValid
isValid()
Subclasses may override this to implement (light weight) validation.
Definition: AbstractContent.php:188