[ Index ] |
PHP Cross Reference of MediaWiki-1.24.0 |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Content object for wiki text pages. 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 * http://www.gnu.org/copyleft/gpl.html 19 * 20 * @since 1.21 21 * 22 * @file 23 * @ingroup Content 24 * 25 * @author Daniel Kinzler 26 */ 27 28 /** 29 * Content object for wiki text pages. 30 * 31 * @ingroup Content 32 */ 33 class WikitextContent extends TextContent { 34 private $redirectTargetAndText = null; 35 36 public function __construct( $text ) { 37 parent::__construct( $text, CONTENT_MODEL_WIKITEXT ); 38 } 39 40 /** 41 * @param string|number $sectionId 42 * 43 * @return Content|bool|null 44 * 45 * @see Content::getSection() 46 */ 47 public function getSection( $sectionId ) { 48 global $wgParser; 49 50 $text = $this->getNativeData(); 51 $sect = $wgParser->getSection( $text, $sectionId, false ); 52 53 if ( $sect === false ) { 54 return false; 55 } else { 56 return new static( $sect ); 57 } 58 } 59 60 /** 61 * @param string|number|null|bool $sectionId 62 * @param Content $with 63 * @param string $sectionTitle 64 * 65 * @throws MWException 66 * @return Content 67 * 68 * @see Content::replaceSection() 69 */ 70 public function replaceSection( $sectionId, Content $with, $sectionTitle = '' ) { 71 wfProfileIn( __METHOD__ ); 72 73 $myModelId = $this->getModel(); 74 $sectionModelId = $with->getModel(); 75 76 if ( $sectionModelId != $myModelId ) { 77 wfProfileOut( __METHOD__ ); 78 throw new MWException( "Incompatible content model for section: " . 79 "document uses $myModelId but " . 80 "section uses $sectionModelId." ); 81 } 82 83 $oldtext = $this->getNativeData(); 84 $text = $with->getNativeData(); 85 86 if ( strval( $sectionId ) === '' ) { 87 wfProfileOut( __METHOD__ ); 88 89 return $with; # XXX: copy first? 90 } 91 92 if ( $sectionId === 'new' ) { 93 # Inserting a new section 94 $subject = $sectionTitle ? wfMessage( 'newsectionheaderdefaultlevel' ) 95 ->rawParams( $sectionTitle )->inContentLanguage()->text() . "\n\n" : ''; 96 if ( wfRunHooks( 'PlaceNewSection', array( $this, $oldtext, $subject, &$text ) ) ) { 97 $text = strlen( trim( $oldtext ) ) > 0 98 ? "{$oldtext}\n\n{$subject}{$text}" 99 : "{$subject}{$text}"; 100 } 101 } else { 102 # Replacing an existing section; roll out the big guns 103 global $wgParser; 104 105 $text = $wgParser->replaceSection( $oldtext, $sectionId, $text ); 106 } 107 108 $newContent = new static( $text ); 109 110 wfProfileOut( __METHOD__ ); 111 112 return $newContent; 113 } 114 115 /** 116 * Returns a new WikitextContent object with the given section heading 117 * prepended. 118 * 119 * @param string $header 120 * 121 * @return Content 122 */ 123 public function addSectionHeader( $header ) { 124 $text = wfMessage( 'newsectionheaderdefaultlevel' ) 125 ->rawParams( $header )->inContentLanguage()->text(); 126 $text .= "\n\n"; 127 $text .= $this->getNativeData(); 128 129 return new static( $text ); 130 } 131 132 /** 133 * Returns a Content object with pre-save transformations applied using 134 * Parser::preSaveTransform(). 135 * 136 * @param Title $title 137 * @param User $user 138 * @param ParserOptions $popts 139 * 140 * @return Content 141 */ 142 public function preSaveTransform( Title $title, User $user, ParserOptions $popts ) { 143 global $wgParser; 144 145 $text = $this->getNativeData(); 146 $pst = $wgParser->preSaveTransform( $text, $title, $user, $popts ); 147 rtrim( $pst ); 148 149 return ( $text === $pst ) ? $this : new static( $pst ); 150 } 151 152 /** 153 * Returns a Content object with preload transformations applied (or this 154 * object if no transformations apply). 155 * 156 * @param Title $title 157 * @param ParserOptions $popts 158 * @param array $params 159 * 160 * @return Content 161 */ 162 public function preloadTransform( Title $title, ParserOptions $popts, $params = array() ) { 163 global $wgParser; 164 165 $text = $this->getNativeData(); 166 $plt = $wgParser->getPreloadText( $text, $title, $popts, $params ); 167 168 return new static( $plt ); 169 } 170 171 /** 172 * Extract the redirect target and the remaining text on the page. 173 * 174 * @note migrated here from Title::newFromRedirectInternal() 175 * 176 * @since 1.23 177 * 178 * @return array List of two elements: Title|null and string. 179 */ 180 protected function getRedirectTargetAndText() { 181 global $wgMaxRedirects; 182 183 if ( $this->redirectTargetAndText !== null ) { 184 return $this->redirectTargetAndText; 185 } 186 187 if ( $wgMaxRedirects < 1 ) { 188 // redirects are disabled, so quit early 189 $this->redirectTargetAndText = array( null, $this->getNativeData() ); 190 return $this->redirectTargetAndText; 191 } 192 193 $redir = MagicWord::get( 'redirect' ); 194 $text = ltrim( $this->getNativeData() ); 195 if ( $redir->matchStartAndRemove( $text ) ) { 196 // Extract the first link and see if it's usable 197 // Ensure that it really does come directly after #REDIRECT 198 // Some older redirects included a colon, so don't freak about that! 199 $m = array(); 200 if ( preg_match( '!^\s*:?\s*\[{2}(.*?)(?:\|.*?)?\]{2}\s*!', $text, $m ) ) { 201 // Strip preceding colon used to "escape" categories, etc. 202 // and URL-decode links 203 if ( strpos( $m[1], '%' ) !== false ) { 204 // Match behavior of inline link parsing here; 205 $m[1] = rawurldecode( ltrim( $m[1], ':' ) ); 206 } 207 $title = Title::newFromText( $m[1] ); 208 // If the title is a redirect to bad special pages or is invalid, return null 209 if ( !$title instanceof Title || !$title->isValidRedirectTarget() ) { 210 $this->redirectTargetAndText = array( null, $this->getNativeData() ); 211 return $this->redirectTargetAndText; 212 } 213 214 $this->redirectTargetAndText = array( $title, substr( $text, strlen( $m[0] ) ) ); 215 return $this->redirectTargetAndText; 216 } 217 } 218 219 $this->redirectTargetAndText = array( null, $this->getNativeData() ); 220 return $this->redirectTargetAndText; 221 } 222 223 /** 224 * Implement redirect extraction for wikitext. 225 * 226 * @return Title|null 227 * 228 * @see Content::getRedirectTarget 229 */ 230 public function getRedirectTarget() { 231 list( $title, ) = $this->getRedirectTargetAndText(); 232 233 return $title; 234 } 235 236 /** 237 * This implementation replaces the first link on the page with the given new target 238 * if this Content object is a redirect. Otherwise, this method returns $this. 239 * 240 * @since 1.21 241 * 242 * @param Title $target 243 * 244 * @return Content 245 * 246 * @see Content::updateRedirect() 247 */ 248 public function updateRedirect( Title $target ) { 249 if ( !$this->isRedirect() ) { 250 return $this; 251 } 252 253 # Fix the text 254 # Remember that redirect pages can have categories, templates, etc., 255 # so the regex has to be fairly general 256 $newText = preg_replace( '/ \[ \[ [^\]]* \] \] /x', 257 '[[' . $target->getFullText() . ']]', 258 $this->getNativeData(), 1 ); 259 260 return new static( $newText ); 261 } 262 263 /** 264 * Returns true if this content is not a redirect, and this content's text 265 * is countable according to the criteria defined by $wgArticleCountMethod. 266 * 267 * @param bool $hasLinks If it is known whether this content contains 268 * links, provide this information here, to avoid redundant parsing to 269 * find out (default: null). 270 * @param Title $title Optional title, defaults to the title from the current main request. 271 * 272 * @return bool 273 */ 274 public function isCountable( $hasLinks = null, Title $title = null ) { 275 global $wgArticleCountMethod; 276 277 if ( $this->isRedirect() ) { 278 return false; 279 } 280 281 $text = $this->getNativeData(); 282 283 switch ( $wgArticleCountMethod ) { 284 case 'any': 285 return true; 286 case 'comma': 287 return strpos( $text, ',' ) !== false; 288 case 'link': 289 if ( $hasLinks === null ) { # not known, find out 290 if ( !$title ) { 291 $context = RequestContext::getMain(); 292 $title = $context->getTitle(); 293 } 294 295 $po = $this->getParserOutput( $title, null, null, false ); 296 $links = $po->getLinks(); 297 $hasLinks = !empty( $links ); 298 } 299 300 return $hasLinks; 301 } 302 303 return false; 304 } 305 306 /** 307 * @param int $maxlength 308 * @return string 309 */ 310 public function getTextForSummary( $maxlength = 250 ) { 311 $truncatedtext = parent::getTextForSummary( $maxlength ); 312 313 # clean up unfinished links 314 # XXX: make this optional? wasn't there in autosummary, but required for 315 # deletion summary. 316 $truncatedtext = preg_replace( '/\[\[([^\]]*)\]?$/', '$1', $truncatedtext ); 317 318 return $truncatedtext; 319 } 320 321 /** 322 * Returns a ParserOutput object resulting from parsing the content's text 323 * using $wgParser. 324 * 325 * @param Title $title 326 * @param int $revId Revision to pass to the parser (default: null) 327 * @param ParserOptions $options (default: null) 328 * @param bool $generateHtml (default: true) 329 * @param ParserOutput &$output ParserOutput representing the HTML form of the text, 330 * may be manipulated or replaced. 331 */ 332 protected function fillParserOutput( Title $title, $revId, 333 ParserOptions $options, $generateHtml, ParserOutput &$output 334 ) { 335 global $wgParser; 336 337 list( $redir, $text ) = $this->getRedirectTargetAndText(); 338 $output = $wgParser->parse( $text, $title, $options, true, true, $revId ); 339 340 // Add redirect indicator at the top 341 if ( $redir ) { 342 // Make sure to include the redirect link in pagelinks 343 $output->addLink( $redir ); 344 if ( $generateHtml ) { 345 $chain = $this->getRedirectChain(); 346 $output->setText( 347 Article::getRedirectHeaderHtml( $title->getPageLanguage(), $chain, false ) . 348 $output->getText() 349 ); 350 $output->addModuleStyles( 'mediawiki.action.view.redirectPage' ); 351 } 352 } 353 } 354 355 /** 356 * @throws MWException 357 */ 358 protected function getHtml() { 359 throw new MWException( 360 "getHtml() not implemented for wikitext. " 361 . "Use getParserOutput()->getText()." 362 ); 363 } 364 365 /** 366 * This implementation calls $word->match() on the this TextContent object's text. 367 * 368 * @param MagicWord $word 369 * 370 * @return bool 371 * 372 * @see Content::matchMagicWord() 373 */ 374 public function matchMagicWord( MagicWord $word ) { 375 return $word->match( $this->getNativeData() ); 376 } 377 378 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 14:03:12 2014 | Cross-referenced by PHPXref 0.7.1 |