MediaWiki  REL1_24
WikitextContent.php
Go to the documentation of this file.
00001 <?php
00033 class WikitextContent extends TextContent {
00034     private $redirectTargetAndText = null;
00035 
00036     public function __construct( $text ) {
00037         parent::__construct( $text, CONTENT_MODEL_WIKITEXT );
00038     }
00039 
00047     public function getSection( $sectionId ) {
00048         global $wgParser;
00049 
00050         $text = $this->getNativeData();
00051         $sect = $wgParser->getSection( $text, $sectionId, false );
00052 
00053         if ( $sect === false ) {
00054             return false;
00055         } else {
00056             return new static( $sect );
00057         }
00058     }
00059 
00070     public function replaceSection( $sectionId, Content $with, $sectionTitle = '' ) {
00071         wfProfileIn( __METHOD__ );
00072 
00073         $myModelId = $this->getModel();
00074         $sectionModelId = $with->getModel();
00075 
00076         if ( $sectionModelId != $myModelId ) {
00077             wfProfileOut( __METHOD__ );
00078             throw new MWException( "Incompatible content model for section: " .
00079                 "document uses $myModelId but " .
00080                 "section uses $sectionModelId." );
00081         }
00082 
00083         $oldtext = $this->getNativeData();
00084         $text = $with->getNativeData();
00085 
00086         if ( strval( $sectionId ) === '' ) {
00087             wfProfileOut( __METHOD__ );
00088 
00089             return $with; # XXX: copy first?
00090         }
00091 
00092         if ( $sectionId === 'new' ) {
00093             # Inserting a new section
00094             $subject = $sectionTitle ? wfMessage( 'newsectionheaderdefaultlevel' )
00095                     ->rawParams( $sectionTitle )->inContentLanguage()->text() . "\n\n" : '';
00096             if ( wfRunHooks( 'PlaceNewSection', array( $this, $oldtext, $subject, &$text ) ) ) {
00097                 $text = strlen( trim( $oldtext ) ) > 0
00098                     ? "{$oldtext}\n\n{$subject}{$text}"
00099                     : "{$subject}{$text}";
00100             }
00101         } else {
00102             # Replacing an existing section; roll out the big guns
00103             global $wgParser;
00104 
00105             $text = $wgParser->replaceSection( $oldtext, $sectionId, $text );
00106         }
00107 
00108         $newContent = new static( $text );
00109 
00110         wfProfileOut( __METHOD__ );
00111 
00112         return $newContent;
00113     }
00114 
00123     public function addSectionHeader( $header ) {
00124         $text = wfMessage( 'newsectionheaderdefaultlevel' )
00125             ->rawParams( $header )->inContentLanguage()->text();
00126         $text .= "\n\n";
00127         $text .= $this->getNativeData();
00128 
00129         return new static( $text );
00130     }
00131 
00142     public function preSaveTransform( Title $title, User $user, ParserOptions $popts ) {
00143         global $wgParser;
00144 
00145         $text = $this->getNativeData();
00146         $pst = $wgParser->preSaveTransform( $text, $title, $user, $popts );
00147         rtrim( $pst );
00148 
00149         return ( $text === $pst ) ? $this : new static( $pst );
00150     }
00151 
00162     public function preloadTransform( Title $title, ParserOptions $popts, $params = array() ) {
00163         global $wgParser;
00164 
00165         $text = $this->getNativeData();
00166         $plt = $wgParser->getPreloadText( $text, $title, $popts, $params );
00167 
00168         return new static( $plt );
00169     }
00170 
00180     protected function getRedirectTargetAndText() {
00181         global $wgMaxRedirects;
00182 
00183         if ( $this->redirectTargetAndText !== null ) {
00184             return $this->redirectTargetAndText;
00185         }
00186 
00187         if ( $wgMaxRedirects < 1 ) {
00188             // redirects are disabled, so quit early
00189             $this->redirectTargetAndText = array( null, $this->getNativeData() );
00190             return $this->redirectTargetAndText;
00191         }
00192 
00193         $redir = MagicWord::get( 'redirect' );
00194         $text = ltrim( $this->getNativeData() );
00195         if ( $redir->matchStartAndRemove( $text ) ) {
00196             // Extract the first link and see if it's usable
00197             // Ensure that it really does come directly after #REDIRECT
00198             // Some older redirects included a colon, so don't freak about that!
00199             $m = array();
00200             if ( preg_match( '!^\s*:?\s*\[{2}(.*?)(?:\|.*?)?\]{2}\s*!', $text, $m ) ) {
00201                 // Strip preceding colon used to "escape" categories, etc.
00202                 // and URL-decode links
00203                 if ( strpos( $m[1], '%' ) !== false ) {
00204                     // Match behavior of inline link parsing here;
00205                     $m[1] = rawurldecode( ltrim( $m[1], ':' ) );
00206                 }
00207                 $title = Title::newFromText( $m[1] );
00208                 // If the title is a redirect to bad special pages or is invalid, return null
00209                 if ( !$title instanceof Title || !$title->isValidRedirectTarget() ) {
00210                     $this->redirectTargetAndText = array( null, $this->getNativeData() );
00211                     return $this->redirectTargetAndText;
00212                 }
00213 
00214                 $this->redirectTargetAndText = array( $title, substr( $text, strlen( $m[0] ) ) );
00215                 return $this->redirectTargetAndText;
00216             }
00217         }
00218 
00219         $this->redirectTargetAndText = array( null, $this->getNativeData() );
00220         return $this->redirectTargetAndText;
00221     }
00222 
00230     public function getRedirectTarget() {
00231         list( $title, ) = $this->getRedirectTargetAndText();
00232 
00233         return $title;
00234     }
00235 
00248     public function updateRedirect( Title $target ) {
00249         if ( !$this->isRedirect() ) {
00250             return $this;
00251         }
00252 
00253         # Fix the text
00254         # Remember that redirect pages can have categories, templates, etc.,
00255         # so the regex has to be fairly general
00256         $newText = preg_replace( '/ \[ \[  [^\]]*  \] \] /x',
00257             '[[' . $target->getFullText() . ']]',
00258             $this->getNativeData(), 1 );
00259 
00260         return new static( $newText );
00261     }
00262 
00274     public function isCountable( $hasLinks = null, Title $title = null ) {
00275         global $wgArticleCountMethod;
00276 
00277         if ( $this->isRedirect() ) {
00278             return false;
00279         }
00280 
00281         $text = $this->getNativeData();
00282 
00283         switch ( $wgArticleCountMethod ) {
00284             case 'any':
00285                 return true;
00286             case 'comma':
00287                 return strpos( $text, ',' ) !== false;
00288             case 'link':
00289                 if ( $hasLinks === null ) { # not known, find out
00290                     if ( !$title ) {
00291                         $context = RequestContext::getMain();
00292                         $title = $context->getTitle();
00293                     }
00294 
00295                     $po = $this->getParserOutput( $title, null, null, false );
00296                     $links = $po->getLinks();
00297                     $hasLinks = !empty( $links );
00298                 }
00299 
00300                 return $hasLinks;
00301         }
00302 
00303         return false;
00304     }
00305 
00310     public function getTextForSummary( $maxlength = 250 ) {
00311         $truncatedtext = parent::getTextForSummary( $maxlength );
00312 
00313         # clean up unfinished links
00314         # XXX: make this optional? wasn't there in autosummary, but required for
00315         # deletion summary.
00316         $truncatedtext = preg_replace( '/\[\[([^\]]*)\]?$/', '$1', $truncatedtext );
00317 
00318         return $truncatedtext;
00319     }
00320 
00332     protected function fillParserOutput( Title $title, $revId,
00333             ParserOptions $options, $generateHtml, ParserOutput &$output
00334     ) {
00335         global $wgParser;
00336 
00337         list( $redir, $text ) = $this->getRedirectTargetAndText();
00338         $output = $wgParser->parse( $text, $title, $options, true, true, $revId );
00339 
00340         // Add redirect indicator at the top
00341         if ( $redir ) {
00342             // Make sure to include the redirect link in pagelinks
00343             $output->addLink( $redir );
00344             if ( $generateHtml ) {
00345                 $chain = $this->getRedirectChain();
00346                 $output->setText(
00347                     Article::getRedirectHeaderHtml( $title->getPageLanguage(), $chain, false ) .
00348                     $output->getText()
00349                 );
00350                 $output->addModuleStyles( 'mediawiki.action.view.redirectPage' );
00351             }
00352         }
00353     }
00354 
00358     protected function getHtml() {
00359         throw new MWException(
00360             "getHtml() not implemented for wikitext. "
00361                 . "Use getParserOutput()->getText()."
00362         );
00363     }
00364 
00374     public function matchMagicWord( MagicWord $word ) {
00375         return $word->match( $this->getNativeData() );
00376     }
00377 
00378 }