MediaWiki  REL1_24
AbstractContent.php
Go to the documentation of this file.
00001 <?php
00034 abstract class AbstractContent implements Content {
00043     protected $model_id;
00044 
00050     public function __construct( $modelId = null ) {
00051         $this->model_id = $modelId;
00052     }
00053 
00059     public function getModel() {
00060         return $this->model_id;
00061     }
00062 
00071     protected function checkModelID( $modelId ) {
00072         if ( $modelId !== $this->model_id ) {
00073             throw new MWException(
00074                 "Bad content model: " .
00075                 "expected {$this->model_id} " .
00076                 "but got $modelId."
00077             );
00078         }
00079     }
00080 
00086     public function getContentHandler() {
00087         return ContentHandler::getForContent( $this );
00088     }
00089 
00095     public function getDefaultFormat() {
00096         return $this->getContentHandler()->getDefaultFormat();
00097     }
00098 
00104     public function getSupportedFormats() {
00105         return $this->getContentHandler()->getSupportedFormats();
00106     }
00107 
00117     public function isSupportedFormat( $format ) {
00118         if ( !$format ) {
00119             return true; // this means "use the default"
00120         }
00121 
00122         return $this->getContentHandler()->isSupportedFormat( $format );
00123     }
00124 
00132     protected function checkFormat( $format ) {
00133         if ( !$this->isSupportedFormat( $format ) ) {
00134             throw new MWException(
00135                 "Format $format is not supported for content model " .
00136                 $this->getModel()
00137             );
00138         }
00139     }
00140 
00150     public function serialize( $format = null ) {
00151         return $this->getContentHandler()->serializeContent( $this, $format );
00152     }
00153 
00161     public function isEmpty() {
00162         return $this->getSize() === 0;
00163     }
00164 
00174     public function isValid() {
00175         return true;
00176     }
00177 
00187     public function equals( Content $that = null ) {
00188         if ( is_null( $that ) ) {
00189             return false;
00190         }
00191 
00192         if ( $that === $this ) {
00193             return true;
00194         }
00195 
00196         if ( $that->getModel() !== $this->getModel() ) {
00197             return false;
00198         }
00199 
00200         return $this->getNativeData() === $that->getNativeData();
00201     }
00202 
00226     public function getSecondaryDataUpdates( Title $title, Content $old = null,
00227         $recursive = true, ParserOutput $parserOutput = null ) {
00228         if ( $parserOutput === null ) {
00229             $parserOutput = $this->getParserOutput( $title, null, null, false );
00230         }
00231 
00232         return $parserOutput->getSecondaryDataUpdates( $title, $recursive );
00233     }
00234 
00242     public function getRedirectChain() {
00243         global $wgMaxRedirects;
00244         $title = $this->getRedirectTarget();
00245         if ( is_null( $title ) ) {
00246             return null;
00247         }
00248         // recursive check to follow double redirects
00249         $recurse = $wgMaxRedirects;
00250         $titles = array( $title );
00251         while ( --$recurse > 0 ) {
00252             if ( $title->isRedirect() ) {
00253                 $page = WikiPage::factory( $title );
00254                 $newtitle = $page->getRedirectTarget();
00255             } else {
00256                 break;
00257             }
00258             // Redirects to some special pages are not permitted
00259             if ( $newtitle instanceof Title && $newtitle->isValidRedirectTarget() ) {
00260                 // The new title passes the checks, so make that our current
00261                 // title so that further recursion can be checked
00262                 $title = $newtitle;
00263                 $titles[] = $newtitle;
00264             } else {
00265                 break;
00266             }
00267         }
00268 
00269         return $titles;
00270     }
00271 
00281     public function getRedirectTarget() {
00282         return null;
00283     }
00284 
00294     public function getUltimateRedirectTarget() {
00295         $titles = $this->getRedirectChain();
00296 
00297         return $titles ? array_pop( $titles ) : null;
00298     }
00299 
00307     public function isRedirect() {
00308         return $this->getRedirectTarget() !== null;
00309     }
00310 
00323     public function updateRedirect( Title $target ) {
00324         return $this;
00325     }
00326 
00334     public function getSection( $sectionId ) {
00335         return null;
00336     }
00337 
00345     public function replaceSection( $sectionId, Content $with, $sectionTitle = '' ) {
00346         return null;
00347     }
00348 
00356     public function preSaveTransform( Title $title, User $user, ParserOptions $popts ) {
00357         return $this;
00358     }
00359 
00367     public function addSectionHeader( $header ) {
00368         return $this;
00369     }
00370 
00378     public function preloadTransform( Title $title, ParserOptions $popts, $params = array() ) {
00379         return $this;
00380     }
00381 
00389     public function prepareSave( WikiPage $page, $flags, $baseRevId, User $user ) {
00390         if ( $this->isValid() ) {
00391             return Status::newGood();
00392         } else {
00393             return Status::newFatal( "invalid-content-data" );
00394         }
00395     }
00396 
00407     public function getDeletionUpdates( WikiPage $page, ParserOutput $parserOutput = null ) {
00408         return array(
00409             new LinksDeletionUpdate( $page ),
00410         );
00411     }
00412 
00425     public function matchMagicWord( MagicWord $word ) {
00426         return false;
00427     }
00428 
00440     public function convert( $toModel, $lossy = '' ) {
00441         if ( $this->getModel() === $toModel ) {
00442             //nothing to do, shorten out.
00443             return $this;
00444         }
00445 
00446         $lossy = ( $lossy === 'lossy' ); // string flag, convert to boolean for convenience
00447         $result = false;
00448 
00449         wfRunHooks( 'ConvertContent', array( $this, $toModel, $lossy, &$result ) );
00450 
00451         return $result;
00452     }
00453 
00474     public function getParserOutput( Title $title, $revId = null,
00475         ParserOptions $options = null, $generateHtml = true
00476     ) {
00477         if ( $options === null ) {
00478             $options = $this->getContentHandler()->makeParserOptions( 'canonical' );
00479         }
00480 
00481         $po = new ParserOutput();
00482 
00483         if ( wfRunHooks( 'ContentGetParserOutput',
00484             array( $this, $title, $revId, $options, $generateHtml, &$po ) ) ) {
00485 
00486             // Save and restore the old value, just in case something is reusing
00487             // the ParserOptions object in some weird way.
00488             $oldRedir = $options->getRedirectTarget();
00489             $options->setRedirectTarget( $this->getRedirectTarget() );
00490             $this->fillParserOutput( $title, $revId, $options, $generateHtml, $po );
00491             $options->setRedirectTarget( $oldRedir );
00492         }
00493 
00494         return $po;
00495     }
00496 
00517     protected function fillParserOutput( Title $title, $revId,
00518         ParserOptions $options, $generateHtml, ParserOutput &$output
00519     ) {
00520         // Don't make abstract, so subclasses that override getParserOutput() directly don't fail.
00521         throw new MWException( 'Subclasses of AbstractContent must override fillParserOutput!' );
00522     }
00523 }