MediaWiki  master
AbstractContent.php
Go to the documentation of this file.
1 <?php
35 
43 abstract class AbstractContent implements Content {
52  protected $model_id;
53 
61  public function __construct( $modelId = null ) {
62  $this->model_id = $modelId;
63  }
64 
71  public function getModel() {
72  return $this->model_id;
73  }
74 
83  protected function checkModelID( $modelId ) {
84  if ( $modelId !== $this->model_id ) {
85  throw new MWException(
86  "Bad content model: " .
87  "expected {$this->model_id} " .
88  "but got $modelId."
89  );
90  }
91  }
92 
99  public function getContentHandler() {
100  return $this->getContentHandlerFactory()->getContentHandler( $this->getModel() );
101  }
102 
107  return MediaWikiServices::getInstance()->getContentHandlerFactory();
108  }
109 
116  public function getDefaultFormat() {
117  return $this->getContentHandler()->getDefaultFormat();
118  }
119 
126  public function getSupportedFormats() {
127  return $this->getContentHandler()->getSupportedFormats();
128  }
129 
139  public function isSupportedFormat( $format ) {
140  if ( !$format ) {
141  return true; // this means "use the default"
142  }
143 
144  return $this->getContentHandler()->isSupportedFormat( $format );
145  }
146 
154  protected function checkFormat( $format ) {
155  if ( !$this->isSupportedFormat( $format ) ) {
156  throw new MWException(
157  "Format $format is not supported for content model " .
158  $this->getModel()
159  );
160  }
161  }
162 
173  public function serialize( $format = null ) {
174  return $this->getContentHandler()->serializeContent( $this, $format );
175  }
176 
185  public function isEmpty() {
186  return $this->getSize() === 0;
187  }
188 
199  public function isValid() {
200  return true;
201  }
202 
224  public function equals( Content $that = null ) {
225  if ( $that === null ) {
226  return false;
227  }
228 
229  if ( $that === $this ) {
230  return true;
231  }
232 
233  if ( $that->getModel() !== $this->getModel() ) {
234  return false;
235  }
236 
237  // For type safety. Needed for odd cases like MessageContent using CONTENT_MODEL_WIKITEXT
238  if ( get_class( $that ) !== get_class( $this ) ) {
239  return false;
240  }
241 
242  return $this->equalsInternal( $that );
243  }
244 
265  protected function equalsInternal( Content $that ) {
266  return $this->serialize() === $that->serialize();
267  }
268 
278  public function getRedirectChain() {
279  $maxRedirects = MediaWikiServices::getInstance()->getMainConfig()->get( 'MaxRedirects' );
280  $title = $this->getRedirectTarget();
281  if ( $title === null ) {
282  return null;
283  }
284  $wikiPageFactory = MediaWikiServices::getInstance()->getWikiPageFactory();
285  // recursive check to follow double redirects
286  $recurse = $maxRedirects;
287  $titles = [ $title ];
288  while ( --$recurse > 0 ) {
289  if ( $title->isRedirect() ) {
290  $page = $wikiPageFactory->newFromTitle( $title );
291  $newtitle = $page->getRedirectTarget();
292  } else {
293  break;
294  }
295  // Redirects to some special pages are not permitted
296  if ( $newtitle instanceof Title && $newtitle->isValidRedirectTarget() ) {
297  // The new title passes the checks, so make that our current
298  // title so that further recursion can be checked
299  $title = $newtitle;
300  $titles[] = $newtitle;
301  } else {
302  break;
303  }
304  }
305 
306  return $titles;
307  }
308 
319  public function getRedirectTarget() {
320  return null;
321  }
322 
334  public function getUltimateRedirectTarget() {
335  $titles = $this->getRedirectChain();
336 
337  return $titles ? array_pop( $titles ) : null;
338  }
339 
347  public function isRedirect() {
348  return $this->getRedirectTarget() !== null;
349  }
350 
364  public function updateRedirect( Title $target ) {
365  return $this;
366  }
367 
377  public function getSection( $sectionId ) {
378  return null;
379  }
380 
392  public function replaceSection( $sectionId, Content $with, $sectionTitle = '' ) {
393  return null;
394  }
395 
409  public function preSaveTransform( Title $title, User $user, ParserOptions $popts ) {
410  wfDeprecated( __METHOD__, '1.37' );
411  $pstParams = new PreSaveTransformParamsValue( $title, $user, $popts );
412  return $this->getContentHandler()->preSaveTransform(
413  $this,
414  $pstParams
415  );
416  }
417 
427  public function addSectionHeader( $header ) {
428  return $this;
429  }
430 
442  public function preloadTransform( Title $title, ParserOptions $popts, $params = [] ) {
443  wfDeprecated( __METHOD__, '1.37' );
444  $pltParams = new PreloadTransformParamsValue( $title, $popts, $params );
445  return $this->getContentHandler()->preloadTransform(
446  $this,
447  $pltParams
448  );
449  }
450 
464  public function prepareSave( WikiPage $page, $flags, $parentRevId, User $user ) {
465  wfDeprecated( __METHOD__, '1.38' );
466  $detectPSDeprecatedOverride = MWDebug::detectDeprecatedOverride(
467  $this,
468  self::class,
469  'prepareSave',
470  '1.38'
471  );
472 
473  if ( $detectPSDeprecatedOverride ) {
474  if ( $this->isValid() ) {
475  return Status::newGood();
476  } else {
477  return Status::newFatal( "invalid-content-data" );
478  }
479  }
480 
481  $validationParams = new ValidationParams( $page, $flags, $parentRevId );
482  $statusValue = $this->getContentHandler()->validateSave(
483  $this,
484  $validationParams
485  );
486 
487  return Status::wrap( $statusValue );
488  }
489 
503  public function matchMagicWord( MagicWord $word ) {
504  return false;
505  }
506 
520  public function convert( $toModel, $lossy = '' ) {
521  if ( $this->getModel() === $toModel ) {
522  // nothing to do, shorten out.
523  return $this;
524  }
525 
526  $lossy = ( $lossy === 'lossy' ); // string flag, convert to boolean for convenience
527  $result = false;
528 
529  Hooks::runner()->onConvertContent( $this, $toModel, $lossy, $result );
530 
531  return $result;
532  }
533 
555  public function getParserOutput( Title $title, $revId = null,
556  ParserOptions $options = null, $generateHtml = true
557  ) {
558  wfDeprecated( __METHOD__, '1.38' );
559  $detectGPODeprecatedOverride = MWDebug::detectDeprecatedOverride(
560  $this,
561  self::class,
562  'getParserOutput',
563  '1.38'
564  );
565  $detectFPODeprecatedOverride = MWDebug::detectDeprecatedOverride(
566  $this,
567  self::class,
568  'fillParserOutput',
569  '1.38'
570  );
571 
572  if ( $detectGPODeprecatedOverride || $detectFPODeprecatedOverride ) {
573  if ( $options === null ) {
574  $options = ParserOptions::newCanonical( 'canonical' );
575  }
576 
577  $po = new ParserOutput();
578  $options->registerWatcher( [ $po, 'recordOption' ] );
579 
580  if ( Hooks::runner()->onContentGetParserOutput(
581  $this, $title, $revId, $options, $generateHtml, $po )
582  ) {
583  // Save and restore the old value, just in case something is reusing
584  // the ParserOptions object in some weird way.
585  $oldRedir = $options->getRedirectTarget();
586  $options->setRedirectTarget( $this->getRedirectTarget() );
587  $this->fillParserOutput( $title, $revId, $options, $generateHtml, $po );
588  $options->setRedirectTarget( $oldRedir );
589  }
590 
591  Hooks::runner()->onContentAlterParserOutput( $this, $title, $po );
592  $options->registerWatcher( null );
593 
594  return $po;
595  }
596 
597  $cpoParams = new ContentParseParams( $title, $revId, $options, $generateHtml );
598  return $this->getContentHandler()->getParserOutput(
599  $this,
600  $cpoParams
601  );
602  }
603 
625  protected function fillParserOutput( Title $title, $revId,
626  ParserOptions $options, $generateHtml, ParserOutput &$output
627  ) {
628  wfDeprecated( __METHOD__, '1.38' );
629  $cpoParams = new ContentParseParams( $title, $revId, $options, $generateHtml );
630  return $this->getContentHandler()->fillParserOutputInternal( $this, $cpoParams, $output );
631  }
632 }
ParserOptions
Set options of the Parser.
Definition: ParserOptions.php:45
AbstractContent\addSectionHeader
addSectionHeader( $header)
Definition: AbstractContent.php:427
Content\serialize
serialize( $format=null)
Convenience method for serializing this Content object.
ParserOutput
Definition: ParserOutput.php:35
AbstractContent\isRedirect
isRedirect()
Definition: AbstractContent.php:347
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:625
AbstractContent\convert
convert( $toModel, $lossy='')
This base implementation calls the hook ConvertContent to enable custom conversions.
Definition: AbstractContent.php:520
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:203
AbstractContent\replaceSection
replaceSection( $sectionId, Content $with, $sectionTitle='')
Definition: AbstractContent.php:392
AbstractContent\checkFormat
checkFormat( $format)
Definition: AbstractContent.php:154
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:555
AbstractContent\getContentHandlerFactory
getContentHandlerFactory()
Definition: AbstractContent.php:106
AbstractContent\getRedirectTarget
getRedirectTarget()
Subclasses that implement redirects should override this.
Definition: AbstractContent.php:319
AbstractContent\updateRedirect
updateRedirect(Title $target)
This default implementation always returns $this.
Definition: AbstractContent.php:364
MediaWiki\Content\Transform\PreSaveTransformParamsValue
Definition: PreSaveTransformParamsValue.php:12
WikiPage
Class representing a MediaWiki article and history.
Definition: WikiPage.php:63
AbstractContent\getRedirectChain
getRedirectChain()
Definition: AbstractContent.php:278
MediaWiki\Content\ValidationParams
Definition: ValidationParams.php:10
AbstractContent\equals
equals(Content $that=null)
Decides whether two Content objects are equal.
Definition: AbstractContent.php:224
AbstractContent\isEmpty
isEmpty()
Definition: AbstractContent.php:185
AbstractContent\getUltimateRedirectTarget
getUltimateRedirectTarget()
Definition: AbstractContent.php:334
Content\getSize
getSize()
Returns the content's nominal size in "bogo-bytes".
MediaWiki\Content\Renderer\ContentParseParams
Definition: ContentParseParams.php:11
AbstractContent\matchMagicWord
matchMagicWord(MagicWord $word)
This default implementation always returns false.
Definition: AbstractContent.php:503
AbstractContent\preSaveTransform
preSaveTransform(Title $title, User $user, ParserOptions $popts)
Definition: AbstractContent.php:409
MediaWiki\Content\Transform\PreloadTransformParamsValue
Definition: PreloadTransformParamsValue.php:11
AbstractContent\getDefaultFormat
getDefaultFormat()
Definition: AbstractContent.php:116
MWException
MediaWiki exception.
Definition: MWException.php:29
AbstractContent\checkModelID
checkModelID( $modelId)
Definition: AbstractContent.php:83
AbstractContent\getContentHandler
getContentHandler()
Definition: AbstractContent.php:99
wfDeprecated
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Logs a warning that a deprecated feature was used.
Definition: GlobalFunctions.php:997
AbstractContent\isSupportedFormat
isSupportedFormat( $format)
Definition: AbstractContent.php:139
Status\wrap
static wrap( $sv)
Succinct helper method to wrap a StatusValue.
Definition: Status.php:62
AbstractContent\serialize
serialize( $format=null)
Definition: AbstractContent.php:173
Title\isValidRedirectTarget
isValidRedirectTarget()
Check if this Title is a valid redirect target.
Definition: Title.php:3829
AbstractContent\prepareSave
prepareSave(WikiPage $page, $flags, $parentRevId, User $user)
Definition: AbstractContent.php:464
ParserOptions\newCanonical
static newCanonical( $context, $userLang=null)
Creates a "canonical" ParserOptions object.
Definition: ParserOptions.php:1089
$title
$title
Definition: testCompression.php:38
AbstractContent\__construct
__construct( $modelId=null)
Definition: AbstractContent.php:61
MagicWord
This class encapsulates "magic words" such as "#redirect", NOTOC, etc.
Definition: MagicWord.php:60
AbstractContent\preloadTransform
preloadTransform(Title $title, ParserOptions $popts, $params=[])
Definition: AbstractContent.php:442
AbstractContent\equalsInternal
equalsInternal(Content $that)
Checks whether $that is logically equal to this Content object.
Definition: AbstractContent.php:265
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:43
AbstractContent\getSection
getSection( $sectionId)
Definition: AbstractContent.php:377
Hooks\runner
static runner()
Get a HookRunner instance for calling hooks using the new interfaces.
Definition: Hooks.php:173
Content
Base interface for content objects.
Definition: Content.php:35
AbstractContent\getModel
getModel()
Definition: AbstractContent.php:71
AbstractContent\$model_id
string $model_id
Name of the content model this Content object represents.
Definition: AbstractContent.php:52
Title
Represents a title within MediaWiki.
Definition: Title.php:47
MWDebug\detectDeprecatedOverride
static detectDeprecatedOverride( $instance, $class, $method, $version=false, $component=false, $callerOffset=2)
Show a warning if $method declared in $class is overridden in $instance.
Definition: MWDebug.php:257
User
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition: User.php:67
AbstractContent\getSupportedFormats
getSupportedFormats()
Definition: AbstractContent.php:126
AbstractContent\isValid
isValid()
Subclasses may override this to implement (light weight) validation.
Definition: AbstractContent.php:199