MediaWiki  1.34.0
AbstractContent.php
Go to the documentation of this file.
1 <?php
34 abstract class AbstractContent implements Content {
43  protected $model_id;
44 
50  public function __construct( $modelId = null ) {
51  $this->model_id = $modelId;
52  }
53 
60  public function getModel() {
61  return $this->model_id;
62  }
63 
72  protected function checkModelID( $modelId ) {
73  if ( $modelId !== $this->model_id ) {
74  throw new MWException(
75  "Bad content model: " .
76  "expected {$this->model_id} " .
77  "but got $modelId."
78  );
79  }
80  }
81 
88  public function getContentHandler() {
89  return ContentHandler::getForContent( $this );
90  }
91 
98  public function getDefaultFormat() {
99  return $this->getContentHandler()->getDefaultFormat();
100  }
101 
108  public function getSupportedFormats() {
109  return $this->getContentHandler()->getSupportedFormats();
110  }
111 
121  public function isSupportedFormat( $format ) {
122  if ( !$format ) {
123  return true; // this means "use the default"
124  }
125 
126  return $this->getContentHandler()->isSupportedFormat( $format );
127  }
128 
136  protected function checkFormat( $format ) {
137  if ( !$this->isSupportedFormat( $format ) ) {
138  throw new MWException(
139  "Format $format is not supported for content model " .
140  $this->getModel()
141  );
142  }
143  }
144 
154  public function serialize( $format = null ) {
155  return $this->getContentHandler()->serializeContent( $this, $format );
156  }
157 
165  public function isEmpty() {
166  return $this->getSize() === 0;
167  }
168 
178  public function isValid() {
179  return true;
180  }
181 
202  public function equals( Content $that = null ) {
203  if ( is_null( $that ) ) {
204  return false;
205  }
206 
207  if ( $that === $this ) {
208  return true;
209  }
210 
211  if ( $that->getModel() !== $this->getModel() ) {
212  return false;
213  }
214 
215  // For type safety. Needed for odd cases like MessageContent using CONTENT_MODEL_WIKITEXT
216  if ( get_class( $that ) !== get_class( $this ) ) {
217  return false;
218  }
219 
220  return $this->equalsInternal( $that );
221  }
222 
241  protected function equalsInternal( Content $that ) {
242  return $this->serialize() === $that->serialize();
243  }
244 
268  public function getSecondaryDataUpdates( Title $title, Content $old = null,
269  $recursive = true, ParserOutput $parserOutput = null
270  ) {
271  if ( $parserOutput === null ) {
272  $parserOutput = $this->getParserOutput( $title, null, null, false );
273  }
274 
275  $updates = [
276  new LinksUpdate( $title, $parserOutput, $recursive )
277  ];
278 
279  Hooks::run( 'SecondaryDataUpdates', [ $title, $old, $recursive, $parserOutput, &$updates ] );
280 
281  return $updates;
282  }
283 
291  public function getRedirectChain() {
292  global $wgMaxRedirects;
293  $title = $this->getRedirectTarget();
294  if ( is_null( $title ) ) {
295  return null;
296  }
297  // recursive check to follow double redirects
298  $recurse = $wgMaxRedirects;
299  $titles = [ $title ];
300  while ( --$recurse > 0 ) {
301  if ( $title->isRedirect() ) {
302  $page = WikiPage::factory( $title );
303  $newtitle = $page->getRedirectTarget();
304  } else {
305  break;
306  }
307  // Redirects to some special pages are not permitted
308  if ( $newtitle instanceof Title && $newtitle->isValidRedirectTarget() ) {
309  // The new title passes the checks, so make that our current
310  // title so that further recursion can be checked
311  $title = $newtitle;
312  $titles[] = $newtitle;
313  } else {
314  break;
315  }
316  }
317 
318  return $titles;
319  }
320 
330  public function getRedirectTarget() {
331  return null;
332  }
333 
343  public function getUltimateRedirectTarget() {
344  $titles = $this->getRedirectChain();
345 
346  return $titles ? array_pop( $titles ) : null;
347  }
348 
356  public function isRedirect() {
357  return $this->getRedirectTarget() !== null;
358  }
359 
372  public function updateRedirect( Title $target ) {
373  return $this;
374  }
375 
384  public function getSection( $sectionId ) {
385  return null;
386  }
387 
398  public function replaceSection( $sectionId, Content $with, $sectionTitle = '' ) {
399  return null;
400  }
401 
412  public function preSaveTransform( Title $title, User $user, ParserOptions $popts ) {
413  return $this;
414  }
415 
424  public function addSectionHeader( $header ) {
425  return $this;
426  }
427 
438  public function preloadTransform( Title $title, ParserOptions $popts, $params = [] ) {
439  return $this;
440  }
441 
453  public function prepareSave( WikiPage $page, $flags, $parentRevId, User $user ) {
454  if ( $this->isValid() ) {
455  return Status::newGood();
456  } else {
457  return Status::newFatal( "invalid-content-data" );
458  }
459  }
460 
471  public function getDeletionUpdates( WikiPage $page, ParserOutput $parserOutput = null ) {
472  return [
473  new LinksDeletionUpdate( $page ),
474  ];
475  }
476 
489  public function matchMagicWord( MagicWord $word ) {
490  return false;
491  }
492 
504  public function convert( $toModel, $lossy = '' ) {
505  if ( $this->getModel() === $toModel ) {
506  // nothing to do, shorten out.
507  return $this;
508  }
509 
510  $lossy = ( $lossy === 'lossy' ); // string flag, convert to boolean for convenience
511  $result = false;
512 
513  Hooks::run( 'ConvertContent', [ $this, $toModel, $lossy, &$result ] );
514 
515  return $result;
516  }
517 
538  public function getParserOutput( Title $title, $revId = null,
539  ParserOptions $options = null, $generateHtml = true
540  ) {
541  if ( $options === null ) {
542  $options = ParserOptions::newCanonical( 'canonical' );
543  }
544 
545  $po = new ParserOutput();
546  $options->registerWatcher( [ $po, 'recordOption' ] );
547 
548  if ( Hooks::run( 'ContentGetParserOutput',
549  [ $this, $title, $revId, $options, $generateHtml, &$po ] )
550  ) {
551  // Save and restore the old value, just in case something is reusing
552  // the ParserOptions object in some weird way.
553  $oldRedir = $options->getRedirectTarget();
554  $options->setRedirectTarget( $this->getRedirectTarget() );
555  $this->fillParserOutput( $title, $revId, $options, $generateHtml, $po );
556  $options->setRedirectTarget( $oldRedir );
557  }
558 
559  Hooks::run( 'ContentAlterParserOutput', [ $this, $title, $po ] );
560  $options->registerWatcher( null );
561 
562  return $po;
563  }
564 
586  protected function fillParserOutput( Title $title, $revId,
587  ParserOptions $options, $generateHtml, ParserOutput &$output
588  ) {
589  // Don't make abstract, so subclasses that override getParserOutput() directly don't fail.
590  throw new MWException( 'Subclasses of AbstractContent must override fillParserOutput!' );
591  }
592 }
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:268
ParserOptions
Set options of the Parser.
Definition: ParserOptions.php:42
AbstractContent\addSectionHeader
addSectionHeader( $header)
Definition: AbstractContent.php:424
Content\serialize
serialize( $format=null)
Convenience method for serializing this Content object.
ParserOutput
Definition: ParserOutput.php:25
AbstractContent\isRedirect
isRedirect()
Definition: AbstractContent.php:356
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:586
AbstractContent\convert
convert( $toModel, $lossy='')
This base implementation calls the hook ConvertContent to enable custom conversions.
Definition: AbstractContent.php:504
AbstractContent\replaceSection
replaceSection( $sectionId, Content $with, $sectionTitle='')
Definition: AbstractContent.php:398
AbstractContent\checkFormat
checkFormat( $format)
Definition: AbstractContent.php:136
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:538
AbstractContent\getRedirectTarget
getRedirectTarget()
Subclasses that implement redirects should override this.
Definition: AbstractContent.php:330
AbstractContent\updateRedirect
updateRedirect(Title $target)
This default implementation always returns $this.
Definition: AbstractContent.php:372
WikiPage
Class representing a MediaWiki article and history.
Definition: WikiPage.php:47
LinksUpdate
Class the manages updates of *_link tables as well as similar extension-managed tables.
Definition: LinksUpdate.php:35
AbstractContent\getRedirectChain
getRedirectChain()
Definition: AbstractContent.php:291
AbstractContent\equals
equals(Content $that=null)
Decides whether two Content objects are equal.
Definition: AbstractContent.php:202
AbstractContent\isEmpty
isEmpty()
Definition: AbstractContent.php:165
AbstractContent\getUltimateRedirectTarget
getUltimateRedirectTarget()
Definition: AbstractContent.php:343
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:489
AbstractContent\preSaveTransform
preSaveTransform(Title $title, User $user, ParserOptions $popts)
Definition: AbstractContent.php:412
AbstractContent\getDefaultFormat
getDefaultFormat()
Definition: AbstractContent.php:98
MWException
MediaWiki exception.
Definition: MWException.php:26
AbstractContent\checkModelID
checkModelID( $modelId)
Definition: AbstractContent.php:72
AbstractContent\getContentHandler
getContentHandler()
Definition: AbstractContent.php:88
WikiPage\factory
static factory(Title $title)
Create a WikiPage object of the appropriate class for the given title.
Definition: WikiPage.php:142
AbstractContent\isSupportedFormat
isSupportedFormat( $format)
Definition: AbstractContent.php:121
AbstractContent\serialize
serialize( $format=null)
Definition: AbstractContent.php:154
Title\isValidRedirectTarget
isValidRedirectTarget()
Check if this Title is a valid redirect target.
Definition: Title.php:4492
AbstractContent\prepareSave
prepareSave(WikiPage $page, $flags, $parentRevId, User $user)
Definition: AbstractContent.php:453
$title
$title
Definition: testCompression.php:34
AbstractContent\__construct
__construct( $modelId=null)
Definition: AbstractContent.php:50
$output
$output
Definition: SyntaxHighlight.php:335
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:438
AbstractContent\equalsInternal
equalsInternal(Content $that)
Checks whether $that is logically equal to this Content object.
Definition: AbstractContent.php:241
$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:34
AbstractContent\getSection
getSection( $sectionId)
Definition: AbstractContent.php:384
ParserOptions\newCanonical
static newCanonical( $context=null, $userLang=null)
Creates a "canonical" ParserOptions object.
Definition: ParserOptions.php:1073
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:471
Content
Base interface for content objects.
Definition: Content.php:34
AbstractContent\getModel
getModel()
Definition: AbstractContent.php:60
AbstractContent\$model_id
$model_id
Name of the content model this Content object represents.
Definition: AbstractContent.php:43
Title
Represents a title within MediaWiki.
Definition: Title.php:42
$wgMaxRedirects
$wgMaxRedirects
Max number of redirects to follow when resolving redirects.
Definition: DefaultSettings.php:4090
User
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition: User.php:51
Hooks\run
static run( $event, array $args=[], $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
Definition: Hooks.php:200
ContentHandler\getForContent
static getForContent(Content $content)
Returns the appropriate ContentHandler singleton for the given Content object.
Definition: ContentHandler.php:217
AbstractContent\getSupportedFormats
getSupportedFormats()
Definition: AbstractContent.php:108
AbstractContent\isValid
isValid()
Subclasses may override this to implement (light weight) validation.
Definition: AbstractContent.php:178