MediaWiki
master
|
00001 <?php 00002 00024 class ParserOutput extends CacheTime { 00025 var $mText, # The output text 00026 $mLanguageLinks, # List of the full text of language links, in the order they appear 00027 $mCategories, # Map of category names to sort keys 00028 $mTitleText, # title text of the chosen language variant 00029 $mLinks = array(), # 2-D map of NS/DBK to ID for the links in the document. ID=zero for broken. 00030 $mTemplates = array(), # 2-D map of NS/DBK to ID for the template references. ID=zero for broken. 00031 $mTemplateIds = array(), # 2-D map of NS/DBK to rev ID for the template references. ID=zero for broken. 00032 $mImages = array(), # DB keys of the images used, in the array key only 00033 $mFileSearchOptions = array(), # DB keys of the images used mapped to sha1 and MW timestamp 00034 $mExternalLinks = array(), # External link URLs, in the key only 00035 $mInterwikiLinks = array(), # 2-D map of prefix/DBK (in keys only) for the inline interwiki links in the document. 00036 $mNewSection = false, # Show a new section link? 00037 $mHideNewSection = false, # Hide the new section link? 00038 $mNoGallery = false, # No gallery on category page? (__NOGALLERY__) 00039 $mHeadItems = array(), # Items to put in the <head> section 00040 $mModules = array(), # Modules to be loaded by the resource loader 00041 $mModuleScripts = array(), # Modules of which only the JS will be loaded by the resource loader 00042 $mModuleStyles = array(), # Modules of which only the CSSS will be loaded by the resource loader 00043 $mModuleMessages = array(), # Modules of which only the messages will be loaded by the resource loader 00044 $mOutputHooks = array(), # Hook tags as per $wgParserOutputHooks 00045 $mWarnings = array(), # Warning text to be returned to the user. Wikitext formatted, in the key only 00046 $mSections = array(), # Table of contents 00047 $mEditSectionTokens = false, # prefix/suffix markers if edit sections were output as tokens 00048 $mProperties = array(), # Name/value pairs to be cached in the DB 00049 $mTOCHTML = '', # HTML of the TOC 00050 $mTimestamp; # Timestamp of the revision 00051 private $mIndexPolicy = ''; # 'index' or 'noindex'? Any other value will result in no change. 00052 private $mAccessedOptions = array(); # List of ParserOptions (stored in the keys) 00053 private $mSecondaryDataUpdates = array(); # List of DataUpdate, used to save info from the page somewhere else. 00054 00055 const EDITSECTION_REGEX = '#<(?:mw:)?editsection page="(.*?)" section="(.*?)"(?:/>|>(.*?)(</(?:mw:)?editsection>))#'; 00056 00057 function __construct( $text = '', $languageLinks = array(), $categoryLinks = array(), 00058 $containsOldMagic = false, $titletext = '' ) 00059 { 00060 $this->mText = $text; 00061 $this->mLanguageLinks = $languageLinks; 00062 $this->mCategories = $categoryLinks; 00063 $this->mContainsOldMagic = $containsOldMagic; 00064 $this->mTitleText = $titletext; 00065 } 00066 00067 function getText() { 00068 if ( $this->mEditSectionTokens ) { 00069 return preg_replace_callback( ParserOutput::EDITSECTION_REGEX, 00070 array( &$this, 'replaceEditSectionLinksCallback' ), $this->mText ); 00071 } 00072 return preg_replace( ParserOutput::EDITSECTION_REGEX, '', $this->mText ); 00073 } 00074 00082 function replaceEditSectionLinksCallback( $m ) { 00083 global $wgOut, $wgLang; 00084 $args = array( 00085 htmlspecialchars_decode($m[1]), 00086 htmlspecialchars_decode($m[2]), 00087 isset($m[4]) ? $m[3] : null, 00088 ); 00089 $args[0] = Title::newFromText( $args[0] ); 00090 if ( !is_object($args[0]) ) { 00091 throw new MWException("Bad parser output text."); 00092 } 00093 $args[] = $wgLang->getCode(); 00094 $skin = $wgOut->getSkin(); 00095 return call_user_func_array( array( $skin, 'doEditSectionLink' ), $args ); 00096 } 00097 00098 function &getLanguageLinks() { return $this->mLanguageLinks; } 00099 function getInterwikiLinks() { return $this->mInterwikiLinks; } 00100 function getCategoryLinks() { return array_keys( $this->mCategories ); } 00101 function &getCategories() { return $this->mCategories; } 00102 function getTitleText() { return $this->mTitleText; } 00103 function getSections() { return $this->mSections; } 00104 function getEditSectionTokens() { return $this->mEditSectionTokens; } 00105 function &getLinks() { return $this->mLinks; } 00106 function &getTemplates() { return $this->mTemplates; } 00107 function &getTemplateIds() { return $this->mTemplateIds; } 00108 function &getImages() { return $this->mImages; } 00109 function &getFileSearchOptions() { return $this->mFileSearchOptions; } 00110 function &getExternalLinks() { return $this->mExternalLinks; } 00111 function getNoGallery() { return $this->mNoGallery; } 00112 function getHeadItems() { return $this->mHeadItems; } 00113 function getModules() { return $this->mModules; } 00114 function getModuleScripts() { return $this->mModuleScripts; } 00115 function getModuleStyles() { return $this->mModuleStyles; } 00116 function getModuleMessages() { return $this->mModuleMessages; } 00117 function getOutputHooks() { return (array)$this->mOutputHooks; } 00118 function getWarnings() { return array_keys( $this->mWarnings ); } 00119 function getIndexPolicy() { return $this->mIndexPolicy; } 00120 function getTOCHTML() { return $this->mTOCHTML; } 00121 function getTimestamp() { return $this->mTimestamp; } 00122 00123 function setText( $text ) { return wfSetVar( $this->mText, $text ); } 00124 function setLanguageLinks( $ll ) { return wfSetVar( $this->mLanguageLinks, $ll ); } 00125 function setCategoryLinks( $cl ) { return wfSetVar( $this->mCategories, $cl ); } 00126 00127 function setTitleText( $t ) { return wfSetVar( $this->mTitleText, $t ); } 00128 function setSections( $toc ) { return wfSetVar( $this->mSections, $toc ); } 00129 function setEditSectionTokens( $t ) { return wfSetVar( $this->mEditSectionTokens, $t ); } 00130 function setIndexPolicy( $policy ) { return wfSetVar( $this->mIndexPolicy, $policy ); } 00131 function setTOCHTML( $tochtml ) { return wfSetVar( $this->mTOCHTML, $tochtml ); } 00132 function setTimestamp( $timestamp ) { return wfSetVar( $this->mTimestamp, $timestamp ); } 00133 00134 function addCategory( $c, $sort ) { $this->mCategories[$c] = $sort; } 00135 function addLanguageLink( $t ) { $this->mLanguageLinks[] = $t; } 00136 function addWarning( $s ) { $this->mWarnings[$s] = 1; } 00137 00138 function addOutputHook( $hook, $data = false ) { 00139 $this->mOutputHooks[] = array( $hook, $data ); 00140 } 00141 00142 function setNewSection( $value ) { 00143 $this->mNewSection = (bool)$value; 00144 } 00145 function hideNewSection ( $value ) { 00146 $this->mHideNewSection = (bool)$value; 00147 } 00148 function getHideNewSection () { 00149 return (bool)$this->mHideNewSection; 00150 } 00151 function getNewSection() { 00152 return (bool)$this->mNewSection; 00153 } 00154 00162 static function isLinkInternal( $internal, $url ) { 00163 return (bool)preg_match( '/^' . 00164 # If server is proto relative, check also for http/https links 00165 ( substr( $internal, 0, 2 ) === '//' ? '(?:https?:)?' : '' ) . 00166 preg_quote( $internal, '/' ) . 00167 # check for query/path/anchor or end of link in each case 00168 '(?:[\?\/\#]|$)/i', 00169 $url 00170 ); 00171 } 00172 00173 function addExternalLink( $url ) { 00174 # We don't register links pointing to our own server, unless... :-) 00175 global $wgServer, $wgRegisterInternalExternals; 00176 00177 $registerExternalLink = true; 00178 if( !$wgRegisterInternalExternals ) { 00179 $registerExternalLink = !self::isLinkInternal( $wgServer, $url ); 00180 } 00181 if( $registerExternalLink ) { 00182 $this->mExternalLinks[$url] = 1; 00183 } 00184 } 00185 00192 function addLink( $title, $id = null ) { 00193 if ( $title->isExternal() ) { 00194 // Don't record interwikis in pagelinks 00195 $this->addInterwikiLink( $title ); 00196 return; 00197 } 00198 $ns = $title->getNamespace(); 00199 $dbk = $title->getDBkey(); 00200 if ( $ns == NS_MEDIA ) { 00201 // Normalize this pseudo-alias if it makes it down here... 00202 $ns = NS_FILE; 00203 } elseif( $ns == NS_SPECIAL ) { 00204 // We don't record Special: links currently 00205 // It might actually be wise to, but we'd need to do some normalization. 00206 return; 00207 } elseif( $dbk === '' ) { 00208 // Don't record self links - [[#Foo]] 00209 return; 00210 } 00211 if ( !isset( $this->mLinks[$ns] ) ) { 00212 $this->mLinks[$ns] = array(); 00213 } 00214 if ( is_null( $id ) ) { 00215 $id = $title->getArticleID(); 00216 } 00217 $this->mLinks[$ns][$dbk] = $id; 00218 } 00219 00227 function addImage( $name, $timestamp = null, $sha1 = null ) { 00228 $this->mImages[$name] = 1; 00229 if ( $timestamp !== null && $sha1 !== null ) { 00230 $this->mFileSearchOptions[$name] = array( 'time' => $timestamp, 'sha1' => $sha1 ); 00231 } 00232 } 00233 00241 function addTemplate( $title, $page_id, $rev_id ) { 00242 $ns = $title->getNamespace(); 00243 $dbk = $title->getDBkey(); 00244 if ( !isset( $this->mTemplates[$ns] ) ) { 00245 $this->mTemplates[$ns] = array(); 00246 } 00247 $this->mTemplates[$ns][$dbk] = $page_id; 00248 if ( !isset( $this->mTemplateIds[$ns] ) ) { 00249 $this->mTemplateIds[$ns] = array(); 00250 } 00251 $this->mTemplateIds[$ns][$dbk] = $rev_id; // For versioning 00252 } 00253 00258 function addInterwikiLink( $title ) { 00259 $prefix = $title->getInterwiki(); 00260 if( $prefix == '' ) { 00261 throw new MWException( 'Non-interwiki link passed, internal parser error.' ); 00262 } 00263 if (!isset($this->mInterwikiLinks[$prefix])) { 00264 $this->mInterwikiLinks[$prefix] = array(); 00265 } 00266 $this->mInterwikiLinks[$prefix][$title->getDBkey()] = 1; 00267 } 00268 00274 function addHeadItem( $section, $tag = false ) { 00275 if ( $tag !== false ) { 00276 $this->mHeadItems[$tag] = $section; 00277 } else { 00278 $this->mHeadItems[] = $section; 00279 } 00280 } 00281 00282 public function addModules( $modules ) { 00283 $this->mModules = array_merge( $this->mModules, (array) $modules ); 00284 } 00285 00286 public function addModuleScripts( $modules ) { 00287 $this->mModuleScripts = array_merge( $this->mModuleScripts, (array)$modules ); 00288 } 00289 00290 public function addModuleStyles( $modules ) { 00291 $this->mModuleStyles = array_merge( $this->mModuleStyles, (array)$modules ); 00292 } 00293 00294 public function addModuleMessages( $modules ) { 00295 $this->mModuleMessages = array_merge( $this->mModuleMessages, (array)$modules ); 00296 } 00297 00303 public function addOutputPageMetadata( OutputPage $out ) { 00304 $this->addModules( $out->getModules() ); 00305 $this->addModuleScripts( $out->getModuleScripts() ); 00306 $this->addModuleStyles( $out->getModuleStyles() ); 00307 $this->addModuleMessages( $out->getModuleMessages() ); 00308 00309 $this->mHeadItems = array_merge( $this->mHeadItems, $out->getHeadItemsArray() ); 00310 } 00311 00319 public function setDisplayTitle( $text ) { 00320 $this->setTitleText( $text ); 00321 $this->setProperty( 'displaytitle', $text ); 00322 } 00323 00329 public function getDisplayTitle() { 00330 $t = $this->getTitleText(); 00331 if( $t === '' ) { 00332 return false; 00333 } 00334 return $t; 00335 } 00336 00340 public function setFlag( $flag ) { 00341 $this->mFlags[$flag] = true; 00342 } 00343 00344 public function getFlag( $flag ) { 00345 return isset( $this->mFlags[$flag] ); 00346 } 00347 00389 public function setProperty( $name, $value ) { 00390 $this->mProperties[$name] = $value; 00391 } 00392 00393 public function getProperty( $name ){ 00394 return isset( $this->mProperties[$name] ) ? $this->mProperties[$name] : false; 00395 } 00396 00397 public function getProperties() { 00398 if ( !isset( $this->mProperties ) ) { 00399 $this->mProperties = array(); 00400 } 00401 return $this->mProperties; 00402 } 00403 00404 00410 public function getUsedOptions() { 00411 if ( !isset( $this->mAccessedOptions ) ) { 00412 return array(); 00413 } 00414 return array_keys( $this->mAccessedOptions ); 00415 } 00416 00421 function recordOption( $option ) { 00422 $this->mAccessedOptions[$option] = true; 00423 } 00424 00433 public function addSecondaryDataUpdate( DataUpdate $update ) { 00434 $this->mSecondaryDataUpdates[] = $update; 00435 } 00436 00453 public function getSecondaryDataUpdates( Title $title = null, $recursive = true ) { 00454 if ( is_null( $title ) ) { 00455 $title = Title::newFromText( $this->getTitleText() ); 00456 } 00457 00458 $linksUpdate = new LinksUpdate( $title, $this, $recursive ); 00459 00460 if ( $this->mSecondaryDataUpdates === array() ) { 00461 return array( $linksUpdate ); 00462 } else { 00463 $updates = array_merge( $this->mSecondaryDataUpdates, array( $linksUpdate ) ); 00464 } 00465 00466 return $updates; 00467 } 00468 00469 }