MediaWiki
REL1_24
|
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 }