MediaWiki  REL1_22
WikitextContent.php
Go to the documentation of this file.
00001 <?php
00033 class WikitextContent extends TextContent {
00034 
00035     public function __construct( $text ) {
00036         parent::__construct( $text, CONTENT_MODEL_WIKITEXT );
00037     }
00038 
00042     public function getSection( $section ) {
00043         global $wgParser;
00044 
00045         $text = $this->getNativeData();
00046         $sect = $wgParser->getSection( $text, $section, false );
00047 
00048         if ( $sect === false ) {
00049             return false;
00050         } else {
00051             return new WikitextContent( $sect );
00052         }
00053     }
00054 
00058     public function replaceSection( $section, Content $with, $sectionTitle = '' ) {
00059         wfProfileIn( __METHOD__ );
00060 
00061         $myModelId = $this->getModel();
00062         $sectionModelId = $with->getModel();
00063 
00064         if ( $sectionModelId != $myModelId ) {
00065             wfProfileOut( __METHOD__ );
00066             throw new MWException( "Incompatible content model for section: " .
00067                 "document uses $myModelId but " .
00068                 "section uses $sectionModelId." );
00069         }
00070 
00071         $oldtext = $this->getNativeData();
00072         $text = $with->getNativeData();
00073 
00074         if ( $section === '' ) {
00075             wfProfileOut( __METHOD__ );
00076             return $with; # XXX: copy first?
00077         } if ( $section == 'new' ) {
00078             # Inserting a new section
00079             $subject = $sectionTitle ? wfMessage( 'newsectionheaderdefaultlevel' )
00080                 ->rawParams( $sectionTitle )->inContentLanguage()->text() . "\n\n" : '';
00081             if ( wfRunHooks( 'PlaceNewSection', array( $this, $oldtext, $subject, &$text ) ) ) {
00082                 $text = strlen( trim( $oldtext ) ) > 0
00083                     ? "{$oldtext}\n\n{$subject}{$text}"
00084                     : "{$subject}{$text}";
00085             }
00086         } else {
00087             # Replacing an existing section; roll out the big guns
00088             global $wgParser;
00089 
00090             $text = $wgParser->replaceSection( $oldtext, $section, $text );
00091         }
00092 
00093         $newContent = new WikitextContent( $text );
00094 
00095         wfProfileOut( __METHOD__ );
00096         return $newContent;
00097     }
00098 
00106     public function addSectionHeader( $header ) {
00107         $text = wfMessage( 'newsectionheaderdefaultlevel' )
00108             ->rawParams( $header )->inContentLanguage()->text();
00109         $text .= "\n\n";
00110         $text .= $this->getNativeData();
00111 
00112         return new WikitextContent( $text );
00113     }
00114 
00124     public function preSaveTransform( Title $title, User $user, ParserOptions $popts ) {
00125         global $wgParser;
00126 
00127         $text = $this->getNativeData();
00128         $pst = $wgParser->preSaveTransform( $text, $title, $user, $popts );
00129         rtrim( $pst );
00130 
00131         return ( $text === $pst ) ? $this : new WikitextContent( $pst );
00132     }
00133 
00142     public function preloadTransform( Title $title, ParserOptions $popts ) {
00143         global $wgParser;
00144 
00145         $text = $this->getNativeData();
00146         $plt = $wgParser->getPreloadText( $text, $title, $popts );
00147 
00148         return new WikitextContent( $plt );
00149     }
00150 
00161     public function getRedirectTarget() {
00162         global $wgMaxRedirects;
00163         if ( $wgMaxRedirects < 1 ) {
00164             // redirects are disabled, so quit early
00165             return null;
00166         }
00167         $redir = MagicWord::get( 'redirect' );
00168         $text = trim( $this->getNativeData() );
00169         if ( $redir->matchStartAndRemove( $text ) ) {
00170             // Extract the first link and see if it's usable
00171             // Ensure that it really does come directly after #REDIRECT
00172             // Some older redirects included a colon, so don't freak about that!
00173             $m = array();
00174             if ( preg_match( '!^\s*:?\s*\[{2}(.*?)(?:\|.*?)?\]{2}!', $text, $m ) ) {
00175                 // Strip preceding colon used to "escape" categories, etc.
00176                 // and URL-decode links
00177                 if ( strpos( $m[1], '%' ) !== false ) {
00178                     // Match behavior of inline link parsing here;
00179                     $m[1] = rawurldecode( ltrim( $m[1], ':' ) );
00180                 }
00181                 $title = Title::newFromText( $m[1] );
00182                 // If the title is a redirect to bad special pages or is invalid, return null
00183                 if ( !$title instanceof Title || !$title->isValidRedirectTarget() ) {
00184                     return null;
00185                 }
00186                 return $title;
00187             }
00188         }
00189         return null;
00190     }
00191 
00204     public function updateRedirect( Title $target ) {
00205         if ( !$this->isRedirect() ) {
00206             return $this;
00207         }
00208 
00209         # Fix the text
00210         # Remember that redirect pages can have categories, templates, etc.,
00211         # so the regex has to be fairly general
00212         $newText = preg_replace( '/ \[ \[  [^\]]*  \] \] /x',
00213             '[[' . $target->getFullText() . ']]',
00214             $this->getNativeData(), 1 );
00215 
00216         return new WikitextContent( $newText );
00217     }
00218 
00232     public function isCountable( $hasLinks = null, Title $title = null ) {
00233         global $wgArticleCountMethod;
00234 
00235         if ( $this->isRedirect() ) {
00236             return false;
00237         }
00238 
00239         $text = $this->getNativeData();
00240 
00241         switch ( $wgArticleCountMethod ) {
00242             case 'any':
00243                 return true;
00244             case 'comma':
00245                 return strpos( $text, ',' ) !== false;
00246             case 'link':
00247                 if ( $hasLinks === null ) { # not known, find out
00248                     if ( !$title ) {
00249                         $context = RequestContext::getMain();
00250                         $title = $context->getTitle();
00251                     }
00252 
00253                     $po = $this->getParserOutput( $title, null, null, false );
00254                     $links = $po->getLinks();
00255                     $hasLinks = !empty( $links );
00256                 }
00257 
00258                 return $hasLinks;
00259         }
00260 
00261         return false;
00262     }
00263 
00264     public function getTextForSummary( $maxlength = 250 ) {
00265         $truncatedtext = parent::getTextForSummary( $maxlength );
00266 
00267         # clean up unfinished links
00268         # XXX: make this optional? wasn't there in autosummary, but required for
00269         # deletion summary.
00270         $truncatedtext = preg_replace( '/\[\[([^\]]*)\]?$/', '$1', $truncatedtext );
00271 
00272         return $truncatedtext;
00273     }
00274 
00289     public function getParserOutput( Title $title,
00290         $revId = null,
00291         ParserOptions $options = null, $generateHtml = true
00292     ) {
00293         global $wgParser;
00294 
00295         if ( !$options ) {
00296             //NOTE: use canonical options per default to produce cacheable output
00297             $options = $this->getContentHandler()->makeParserOptions( 'canonical' );
00298         }
00299 
00300         $po = $wgParser->parse( $this->getNativeData(), $title, $options, true, true, $revId );
00301         return $po;
00302     }
00303 
00304     protected function getHtml() {
00305         throw new MWException(
00306             "getHtml() not implemented for wikitext. "
00307                 . "Use getParserOutput()->getText()."
00308         );
00309     }
00310 
00320     public function matchMagicWord( MagicWord $word ) {
00321         return $word->match( $this->getNativeData() );
00322     }
00323 }