MediaWiki  master
WikitextContent.php
Go to the documentation of this file.
00001 <?php
00025 class WikitextContent extends TextContent {
00026 
00027         public function __construct( $text ) {
00028                 parent::__construct( $text, CONTENT_MODEL_WIKITEXT );
00029         }
00030 
00034         public function getSection( $section ) {
00035                 global $wgParser;
00036 
00037                 $text = $this->getNativeData();
00038                 $sect = $wgParser->getSection( $text, $section, false );
00039 
00040                 if ( $sect === false ) {
00041                         return false;
00042                 } else {
00043                         return new WikitextContent( $sect );
00044                 }
00045         }
00046 
00050         public function replaceSection( $section, Content $with, $sectionTitle = '' ) {
00051                 wfProfileIn( __METHOD__ );
00052 
00053                 $myModelId = $this->getModel();
00054                 $sectionModelId = $with->getModel();
00055 
00056                 if ( $sectionModelId != $myModelId  ) {
00057                         throw new MWException( "Incompatible content model for section: " .
00058                                 "document uses $myModelId but " .
00059                                 "section uses $sectionModelId." );
00060                 }
00061 
00062                 $oldtext = $this->getNativeData();
00063                 $text = $with->getNativeData();
00064 
00065                 if ( $section === '' ) {
00066                         return $with; # XXX: copy first?
00067                 } if ( $section == 'new' ) {
00068                         # Inserting a new section
00069                         $subject = $sectionTitle ? wfMessage( 'newsectionheaderdefaultlevel' )
00070                                 ->rawParams( $sectionTitle )->inContentLanguage()->text() . "\n\n" : '';
00071                         if ( wfRunHooks( 'PlaceNewSection', array( $this, $oldtext, $subject, &$text ) ) ) {
00072                                 $text = strlen( trim( $oldtext ) ) > 0
00073                                         ? "{$oldtext}\n\n{$subject}{$text}"
00074                                         : "{$subject}{$text}";
00075                         }
00076                 } else {
00077                         # Replacing an existing section; roll out the big guns
00078                         global $wgParser;
00079 
00080                         $text = $wgParser->replaceSection( $oldtext, $section, $text );
00081                 }
00082 
00083                 $newContent = new WikitextContent( $text );
00084 
00085                 wfProfileOut( __METHOD__ );
00086                 return $newContent;
00087         }
00088 
00096         public function addSectionHeader( $header ) {
00097                 $text = wfMessage( 'newsectionheaderdefaultlevel' )
00098                         ->rawParams( $header )->inContentLanguage()->text();
00099                 $text .= "\n\n";
00100                 $text .= $this->getNativeData();
00101 
00102                 return new WikitextContent( $text );
00103         }
00104 
00114         public function preSaveTransform( Title $title, User $user, ParserOptions $popts ) {
00115                 global $wgParser;
00116 
00117                 $text = $this->getNativeData();
00118                 $pst = $wgParser->preSaveTransform( $text, $title, $user, $popts );
00119                 rtrim( $pst );
00120 
00121                 return ( $text === $pst ) ? $this : new WikitextContent( $pst );
00122         }
00123 
00132         public function preloadTransform( Title $title, ParserOptions $popts ) {
00133                 global $wgParser;
00134 
00135                 $text = $this->getNativeData();
00136                 $plt = $wgParser->getPreloadText( $text, $title, $popts );
00137 
00138                 return new WikitextContent( $plt );
00139         }
00140 
00151         public function getRedirectTarget() {
00152                 global $wgMaxRedirects;
00153                 if ( $wgMaxRedirects < 1 ) {
00154                         // redirects are disabled, so quit early
00155                         return null;
00156                 }
00157                 $redir = MagicWord::get( 'redirect' );
00158                 $text = trim( $this->getNativeData() );
00159                 if ( $redir->matchStartAndRemove( $text ) ) {
00160                         // Extract the first link and see if it's usable
00161                         // Ensure that it really does come directly after #REDIRECT
00162                         // Some older redirects included a colon, so don't freak about that!
00163                         $m = array();
00164                         if ( preg_match( '!^\s*:?\s*\[{2}(.*?)(?:\|.*?)?\]{2}!', $text, $m ) ) {
00165                                 // Strip preceding colon used to "escape" categories, etc.
00166                                 // and URL-decode links
00167                                 if ( strpos( $m[1], '%' ) !== false ) {
00168                                         // Match behavior of inline link parsing here;
00169                                         $m[1] = rawurldecode( ltrim( $m[1], ':' ) );
00170                                 }
00171                                 $title = Title::newFromText( $m[1] );
00172                                 // If the title is a redirect to bad special pages or is invalid, return null
00173                                 if ( !$title instanceof Title || !$title->isValidRedirectTarget() ) {
00174                                         return null;
00175                                 }
00176                                 return $title;
00177                         }
00178                 }
00179                 return null;
00180         }
00181 
00194         public function updateRedirect( Title $target ) {
00195                 if ( !$this->isRedirect() ) {
00196                         return $this;
00197                 }
00198 
00199                 # Fix the text
00200                 # Remember that redirect pages can have categories, templates, etc.,
00201                 # so the regex has to be fairly general
00202                 $newText = preg_replace( '/ \[ \[  [^\]]*  \] \] /x',
00203                         '[[' . $target->getFullText() . ']]',
00204                         $this->getNativeData(), 1 );
00205 
00206                 return new WikitextContent( $newText );
00207         }
00208 
00222         public function isCountable( $hasLinks = null, Title $title = null ) {
00223                 global $wgArticleCountMethod;
00224 
00225                 if ( $this->isRedirect( ) ) {
00226                         return false;
00227                 }
00228 
00229                 $text = $this->getNativeData();
00230 
00231                 switch ( $wgArticleCountMethod ) {
00232                         case 'any':
00233                                 return true;
00234                         case 'comma':
00235                                 return strpos( $text,  ',' ) !== false;
00236                         case 'link':
00237                                 if ( $hasLinks === null ) { # not known, find out
00238                                         if ( !$title ) {
00239                                                 $context = RequestContext::getMain();
00240                                                 $title = $context->getTitle();
00241                                         }
00242 
00243                                         $po = $this->getParserOutput( $title, null, null, false );
00244                                         $links = $po->getLinks();
00245                                         $hasLinks = !empty( $links );
00246                                 }
00247 
00248                                 return $hasLinks;
00249                 }
00250 
00251                 return false;
00252         }
00253 
00254         public function getTextForSummary( $maxlength = 250 ) {
00255                 $truncatedtext = parent::getTextForSummary( $maxlength );
00256 
00257                 # clean up unfinished links
00258                 # XXX: make this optional? wasn't there in autosummary, but required for
00259                 # deletion summary.
00260                 $truncatedtext = preg_replace( '/\[\[([^\]]*)\]?$/', '$1', $truncatedtext );
00261 
00262                 return $truncatedtext;
00263         }
00264 
00279         public function getParserOutput( Title $title,
00280                 $revId = null,
00281                 ParserOptions $options = null, $generateHtml = true
00282         ) {
00283                 global $wgParser;
00284 
00285                 if ( !$options ) {
00286                         //NOTE: use canonical options per default to produce cacheable output
00287                         $options = $this->getContentHandler()->makeParserOptions( 'canonical' );
00288                 }
00289 
00290                 $po = $wgParser->parse( $this->getNativeData(), $title, $options, true, true, $revId );
00291                 return $po;
00292         }
00293 
00294         protected function getHtml() {
00295                 throw new MWException(
00296                         "getHtml() not implemented for wikitext. "
00297                                 . "Use getParserOutput()->getText()."
00298                 );
00299         }
00300 
00310         public function matchMagicWord( MagicWord $word ) {
00311                 return $word->match( $this->getNativeData() );
00312         }
00313 }