MediaWiki  master
ParserOutput.php
Go to the documentation of this file.
1 <?php
2 
4 
27 class ParserOutput extends CacheTime {
35 
39  public const SUPPORTS_UNWRAP_TRANSFORM = 1;
40 
44  public $mText = null;
45 
51 
55  public $mCategories;
56 
60  public $mIndicators = [];
61 
65  public $mTitleText;
66 
72  public $mLinks = [];
73 
78  public $mLinksSpecial = [];
79 
84  public $mTemplates = [];
85 
90  public $mTemplateIds = [];
91 
95  public $mImages = [];
96 
100  public $mFileSearchOptions = [];
101 
105  public $mExternalLinks = [];
106 
111  public $mInterwikiLinks = [];
112 
116  public $mNewSection = false;
117 
121  public $mHideNewSection = false;
122 
126  public $mNoGallery = false;
127 
131  public $mHeadItems = [];
132 
136  public $mModules = [];
137 
141  public $mModuleStyles = [];
142 
146  public $mJsConfigVars = [];
147 
151  public $mOutputHooks = [];
152 
157  public $mWarnings = [];
158 
162  public $mSections = [];
163 
167  public $mProperties = [];
168 
172  public $mTOCHTML = '';
173 
177  public $mTimestamp;
178 
182  public $mEnableOOUI = false;
183 
187  private $mIndexPolicy = '';
188 
192  private $mAccessedOptions = [];
193 
197  private $mExtensionData = [];
198 
202  private $mLimitReportData = [];
203 
205  private $mLimitReportJSData = [];
206 
210  private $mParseStartTime = [];
211 
215  private $mPreventClickjacking = false;
216 
220  private $mExtraScriptSrcs = [];
221 
225  private $mExtraDefaultSrcs = [];
226 
230  private $mExtraStyleSrcs = [];
231 
235  private $mFlags = [];
236 
238  private const SPECULATIVE_FIELDS = [
239  'speculativePageIdUsed',
240  'mSpeculativeRevId',
241  'revisionTimestampUsed'
242  ];
243 
250 
253 
257  private $mWrapperDivClasses = [];
258 
260  private $mMaxAdaptiveExpiry = INF;
261 
262  private const EDITSECTION_REGEX =
263  '#<(?:mw:)?editsection page="(.*?)" section="(.*?)"(?:/>|>(.*?)(</(?:mw:)?editsection>))#s';
264 
265  // finalizeAdaptiveCacheExpiry() uses TTL = MAX( m * PARSE_TIME + b, MIN_AR_TTL)
266  // Current values imply that m=3933.333333 and b=-333.333333
267  // See https://www.nngroup.com/articles/website-response-times/
268  private const PARSE_FAST_SEC = 0.100; // perceived "fast" page parse
269  private const PARSE_SLOW_SEC = 1.0; // perceived "slow" page parse
270  private const FAST_AR_TTL = 60; // adaptive TTL for "fast" pages
271  private const SLOW_AR_TTL = 3600; // adaptive TTL for "slow" pages
272  private const MIN_AR_TTL = 15; // min adaptive TTL (for sanity, pool counter, and edit stashing)
273 
283  public function __construct( $text = '', $languageLinks = [], $categoryLinks = [],
284  $unused = false, $titletext = ''
285  ) {
286  $this->mText = $text;
287  $this->mLanguageLinks = $languageLinks;
288  $this->mCategories = $categoryLinks;
289  $this->mTitleText = $titletext;
290  }
291 
302  public function hasText() {
303  return ( $this->mText !== null );
304  }
305 
314  public function getRawText() {
315  if ( $this->mText === null ) {
316  throw new LogicException( 'This ParserOutput contains no text!' );
317  }
318 
319  return $this->mText;
320  }
321 
348  public function getText( $options = [] ) {
349  $options += [
350  'allowTOC' => true,
351  'enableSectionEditLinks' => true,
352  'skin' => null,
353  'unwrap' => false,
354  'deduplicateStyles' => true,
355  'wrapperDivClass' => $this->getWrapperDivClass(),
356  ];
357  $text = $this->getRawText();
358 
359  Hooks::runner()->onParserOutputPostCacheTransform( $this, $text, $options );
360 
361  if ( $options['wrapperDivClass'] !== '' && !$options['unwrap'] ) {
362  $text = Html::rawElement( 'div', [ 'class' => $options['wrapperDivClass'] ], $text );
363  }
364 
365  if ( $options['enableSectionEditLinks'] ) {
366  // TODO: Passing the skin should be required
367  $skin = $options['skin'] ?: RequestContext::getMain()->getSkin();
368 
369  $text = preg_replace_callback(
370  self::EDITSECTION_REGEX,
371  function ( $m ) use ( $skin ) {
372  $editsectionPage = Title::newFromText( htmlspecialchars_decode( $m[1] ) );
373  $editsectionSection = htmlspecialchars_decode( $m[2] );
374  $editsectionContent = isset( $m[4] ) ? Sanitizer::decodeCharReferences( $m[3] ) : null;
375 
376  if ( !is_object( $editsectionPage ) ) {
377  LoggerFactory::getInstance( 'Parser' )
378  ->error(
379  'ParserOutput::getText(): bad title in editsection placeholder',
380  [
381  'placeholder' => $m[0],
382  'editsectionPage' => $m[1],
383  'titletext' => $this->getTitleText(),
384  'phab' => 'T261347'
385  ]
386  );
387  return '';
388  }
389 
390  return $skin->doEditSectionLink(
391  $editsectionPage,
392  $editsectionSection,
393  $editsectionContent,
394  $skin->getLanguage()
395  );
396  },
397  $text
398  );
399  } else {
400  $text = preg_replace( self::EDITSECTION_REGEX, '', $text );
401  }
402 
403  if ( $options['allowTOC'] ) {
404  $text = str_replace( [ Parser::TOC_START, Parser::TOC_END ], '', $text );
405  } else {
406  $text = preg_replace(
407  '#' . preg_quote( Parser::TOC_START, '#' ) . '.*?' . preg_quote( Parser::TOC_END, '#' ) . '#s',
408  '',
409  $text
410  );
411  }
412 
413  if ( $options['deduplicateStyles'] ) {
414  $seen = [];
415  $text = preg_replace_callback(
416  '#<style\s+([^>]*data-mw-deduplicate\s*=[^>]*)>.*?</style>#s',
417  function ( $m ) use ( &$seen ) {
418  $attr = Sanitizer::decodeTagAttributes( $m[1] );
419  if ( !isset( $attr['data-mw-deduplicate'] ) ) {
420  return $m[0];
421  }
422 
423  $key = $attr['data-mw-deduplicate'];
424  if ( !isset( $seen[$key] ) ) {
425  $seen[$key] = true;
426  return $m[0];
427  }
428 
429  // We were going to use an empty <style> here, but there
430  // was concern that would be too much overhead for browsers.
431  // So let's hope a <link> with a non-standard rel and href isn't
432  // going to be misinterpreted or mangled by any subsequent processing.
433  return Html::element( 'link', [
434  'rel' => 'mw-deduplicated-inline-style',
435  'href' => "mw-data:" . wfUrlencode( $key ),
436  ] );
437  },
438  $text
439  );
440  }
441 
442  // Hydrate slot section header placeholders generated by RevisionRenderer.
443  $text = preg_replace_callback(
444  '#<mw:slotheader>(.*?)</mw:slotheader>#',
445  function ( $m ) {
446  $role = htmlspecialchars_decode( $m[1] );
447  // TODO: map to message, using the interface language. Set lang="xyz" accordingly.
448  $headerText = $role;
449  return $headerText;
450  },
451  $text
452  );
453  return $text;
454  }
455 
461  public function addCacheMessage( string $msg ) {
462  $this->mText .= "\n<!-- $msg\n -->\n";
463  }
464 
470  public function addWrapperDivClass( $class ) {
471  $this->mWrapperDivClasses[$class] = true;
472  }
473 
478  public function clearWrapperDivClass() {
479  $this->mWrapperDivClasses = [];
480  }
481 
489  public function getWrapperDivClass() {
490  return implode( ' ', array_keys( $this->mWrapperDivClasses ) );
491  }
492 
497  public function setSpeculativeRevIdUsed( $id ) {
498  $this->mSpeculativeRevId = $id;
499  }
500 
505  public function getSpeculativeRevIdUsed() {
507  }
508 
513  public function setSpeculativePageIdUsed( $id ) {
514  $this->speculativePageIdUsed = $id;
515  }
516 
521  public function getSpeculativePageIdUsed() {
523  }
524 
529  public function setRevisionTimestampUsed( $timestamp ) {
530  $this->revisionTimestampUsed = $timestamp;
531  }
532 
537  public function getRevisionTimestampUsed() {
539  }
540 
545  public function setRevisionUsedSha1Base36( $hash ) {
546  if ( $hash === null ) {
547  return; // e.g. RevisionRecord::getSha1() returned null
548  }
549 
550  if (
551  $this->revisionUsedSha1Base36 !== null &&
552  $this->revisionUsedSha1Base36 !== $hash
553  ) {
554  $this->revisionUsedSha1Base36 = ''; // mismatched
555  } else {
556  $this->revisionUsedSha1Base36 = $hash;
557  }
558  }
559 
564  public function getRevisionUsedSha1Base36() {
566  }
567 
568  public function &getLanguageLinks() {
569  return $this->mLanguageLinks;
570  }
571 
572  public function getInterwikiLinks() {
573  return $this->mInterwikiLinks;
574  }
575 
576  public function getCategoryLinks() {
577  return array_keys( $this->mCategories );
578  }
579 
580  public function &getCategories() {
581  return $this->mCategories;
582  }
583 
588  public function getIndicators() {
589  return $this->mIndicators;
590  }
591 
592  public function getTitleText() {
593  return $this->mTitleText;
594  }
595 
596  public function getSections() {
597  return $this->mSections;
598  }
599 
600  public function &getLinks() {
601  return $this->mLinks;
602  }
603 
608  public function &getLinksSpecial() {
609  return $this->mLinksSpecial;
610  }
611 
612  public function &getTemplates() {
613  return $this->mTemplates;
614  }
615 
616  public function &getTemplateIds() {
617  return $this->mTemplateIds;
618  }
619 
620  public function &getImages() {
621  return $this->mImages;
622  }
623 
624  public function &getFileSearchOptions() {
626  }
627 
628  public function &getExternalLinks() {
629  return $this->mExternalLinks;
630  }
631 
632  public function setNoGallery( $value ) {
633  $this->mNoGallery = (bool)$value;
634  }
635 
636  public function getNoGallery() {
637  return $this->mNoGallery;
638  }
639 
640  public function getHeadItems() {
641  return $this->mHeadItems;
642  }
643 
644  public function getModules() {
645  return $this->mModules;
646  }
647 
648  public function getModuleStyles() {
649  return $this->mModuleStyles;
650  }
651 
656  public function getJsConfigVars() {
657  return $this->mJsConfigVars;
658  }
659 
660  public function getOutputHooks() {
661  return (array)$this->mOutputHooks;
662  }
663 
664  public function getWarnings() {
665  return array_keys( $this->mWarnings );
666  }
667 
668  public function getIndexPolicy() {
669  return $this->mIndexPolicy;
670  }
671 
672  public function getTOCHTML() {
673  return $this->mTOCHTML;
674  }
675 
679  public function getTimestamp() {
680  return $this->mTimestamp;
681  }
682 
683  public function getLimitReportData() {
685  }
686 
687  public function getLimitReportJSData() {
689  }
690 
691  public function getEnableOOUI() {
692  return $this->mEnableOOUI;
693  }
694 
700  public function getExtraCSPDefaultSrcs() {
702  }
703 
709  public function getExtraCSPScriptSrcs() {
711  }
712 
718  public function getExtraCSPStyleSrcs() {
719  return $this->mExtraStyleSrcs;
720  }
721 
722  public function setText( $text ) {
723  return wfSetVar( $this->mText, $text );
724  }
725 
726  public function setLanguageLinks( $ll ) {
727  return wfSetVar( $this->mLanguageLinks, $ll );
728  }
729 
730  public function setCategoryLinks( $cl ) {
731  return wfSetVar( $this->mCategories, $cl );
732  }
733 
734  public function setTitleText( $t ) {
735  return wfSetVar( $this->mTitleText, $t );
736  }
737 
738  public function setSections( $toc ) {
739  return wfSetVar( $this->mSections, $toc );
740  }
741 
742  public function setIndexPolicy( $policy ) {
743  return wfSetVar( $this->mIndexPolicy, $policy );
744  }
745 
746  public function setTOCHTML( $tochtml ) {
747  return wfSetVar( $this->mTOCHTML, $tochtml );
748  }
749 
750  public function setTimestamp( $timestamp ) {
751  return wfSetVar( $this->mTimestamp, $timestamp );
752  }
753 
754  public function addCategory( $c, $sort ) {
755  $this->mCategories[$c] = $sort;
756  }
757 
763  public function setIndicator( $id, $content ) {
764  $this->mIndicators[$id] = $content;
765  }
766 
774  public function setEnableOOUI( $enable = false ) {
775  $this->mEnableOOUI = $enable;
776  }
777 
778  public function addLanguageLink( $t ) {
779  $this->mLanguageLinks[] = $t;
780  }
781 
782  public function addWarning( $s ) {
783  $this->mWarnings[$s] = 1;
784  }
785 
786  public function addOutputHook( $hook, $data = false ) {
787  $this->mOutputHooks[] = [ $hook, $data ];
788  }
789 
790  public function setNewSection( $value ) {
791  $this->mNewSection = (bool)$value;
792  }
793 
794  public function hideNewSection( $value ) {
795  $this->mHideNewSection = (bool)$value;
796  }
797 
798  public function getHideNewSection() {
799  return (bool)$this->mHideNewSection;
800  }
801 
802  public function getNewSection() {
803  return (bool)$this->mNewSection;
804  }
805 
813  public static function isLinkInternal( $internal, $url ) {
814  return (bool)preg_match( '/^' .
815  # If server is proto relative, check also for http/https links
816  ( substr( $internal, 0, 2 ) === '//' ? '(?:https?:)?' : '' ) .
817  preg_quote( $internal, '/' ) .
818  # check for query/path/anchor or end of link in each case
819  '(?:[\?\/\#]|$)/i',
820  $url
821  );
822  }
823 
824  public function addExternalLink( $url ) {
825  # We don't register links pointing to our own server, unless... :-)
827 
828  # Replace unnecessary URL escape codes with the referenced character
829  # This prevents spammers from hiding links from the filters
830  $url = Parser::normalizeLinkUrl( $url );
831 
832  $registerExternalLink = true;
834  $registerExternalLink = !self::isLinkInternal( $wgServer, $url );
835  }
836  if ( $registerExternalLink ) {
837  $this->mExternalLinks[$url] = 1;
838  }
839  }
840 
847  public function addLink( Title $title, $id = null ) {
848  if ( $title->isExternal() ) {
849  // Don't record interwikis in pagelinks
850  $this->addInterwikiLink( $title );
851  return;
852  }
853  $ns = $title->getNamespace();
854  $dbk = $title->getDBkey();
855  if ( $ns === NS_MEDIA ) {
856  // Normalize this pseudo-alias if it makes it down here...
857  $ns = NS_FILE;
858  } elseif ( $ns === NS_SPECIAL ) {
859  // We don't want to record Special: links in the database, so put them in a separate place.
860  // It might actually be wise to, but we'd need to do some normalization.
861  $this->mLinksSpecial[$dbk] = 1;
862  return;
863  } elseif ( $dbk === '' ) {
864  // Don't record self links - [[#Foo]]
865  return;
866  }
867  if ( !isset( $this->mLinks[$ns] ) ) {
868  $this->mLinks[$ns] = [];
869  }
870  if ( $id === null ) {
871  $id = $title->getArticleID();
872  }
873  $this->mLinks[$ns][$dbk] = $id;
874  }
875 
882  public function addImage( $name, $timestamp = null, $sha1 = null ) {
883  $this->mImages[$name] = 1;
884  if ( $timestamp !== null && $sha1 !== null ) {
885  $this->mFileSearchOptions[$name] = [ 'time' => $timestamp, 'sha1' => $sha1 ];
886  }
887  }
888 
895  public function addTemplate( $title, $page_id, $rev_id ) {
896  $ns = $title->getNamespace();
897  $dbk = $title->getDBkey();
898  if ( !isset( $this->mTemplates[$ns] ) ) {
899  $this->mTemplates[$ns] = [];
900  }
901  $this->mTemplates[$ns][$dbk] = $page_id;
902  if ( !isset( $this->mTemplateIds[$ns] ) ) {
903  $this->mTemplateIds[$ns] = [];
904  }
905  $this->mTemplateIds[$ns][$dbk] = $rev_id; // For versioning
906  }
907 
912  public function addInterwikiLink( $title ) {
913  if ( !$title->isExternal() ) {
914  throw new MWException( 'Non-interwiki link passed, internal parser error.' );
915  }
916  $prefix = $title->getInterwiki();
917  if ( !isset( $this->mInterwikiLinks[$prefix] ) ) {
918  $this->mInterwikiLinks[$prefix] = [];
919  }
920  $this->mInterwikiLinks[$prefix][$title->getDBkey()] = 1;
921  }
922 
930  public function addHeadItem( $section, $tag = false ) {
931  if ( $tag !== false ) {
932  $this->mHeadItems[$tag] = $section;
933  } else {
934  $this->mHeadItems[] = $section;
935  }
936  }
937 
942  public function addModules( $modules ) {
943  $this->mModules = array_merge( $this->mModules, (array)$modules );
944  }
945 
950  public function addModuleStyles( $modules ) {
951  $this->mModuleStyles = array_merge( $this->mModuleStyles, (array)$modules );
952  }
953 
961  public function addJsConfigVars( $keys, $value = null ) {
962  if ( is_array( $keys ) ) {
963  foreach ( $keys as $key => $value ) {
964  $this->mJsConfigVars[$key] = $value;
965  }
966  return;
967  }
968 
969  $this->mJsConfigVars[$keys] = $value;
970  }
971 
977  public function addOutputPageMetadata( OutputPage $out ) {
978  $this->addModules( $out->getModules() );
979  $this->addModuleStyles( $out->getModuleStyles() );
980  $this->addJsConfigVars( $out->getJsConfigVars() );
981 
982  $this->mHeadItems = array_merge( $this->mHeadItems, $out->getHeadItemsArray() );
983  $this->mPreventClickjacking = $this->mPreventClickjacking || $out->getPreventClickjacking();
984  }
985 
1002  public function addTrackingCategory( $msg, $title ) {
1003  if ( $title->isSpecialPage() ) {
1004  wfDebug( __METHOD__ . ": Not adding tracking category $msg to special page!" );
1005  return false;
1006  }
1007 
1008  // Important to parse with correct title (T33469)
1009  $cat = wfMessage( $msg )
1010  ->title( $title )
1011  ->inContentLanguage()
1012  ->text();
1013 
1014  # Allow tracking categories to be disabled by setting them to "-"
1015  if ( $cat === '-' ) {
1016  return false;
1017  }
1018 
1019  $containerCategory = Title::makeTitleSafe( NS_CATEGORY, $cat );
1020  if ( $containerCategory ) {
1021  $this->addCategory( $containerCategory->getDBkey(), $this->getProperty( 'defaultsort' ) ?: '' );
1022  return true;
1023  } else {
1024  wfDebug( __METHOD__ . ": [[MediaWiki:$msg]] is not a valid title!" );
1025  return false;
1026  }
1027  }
1028 
1040  public function setDisplayTitle( $text ) {
1041  $this->setTitleText( $text );
1042  $this->setProperty( 'displaytitle', $text );
1043  }
1044 
1053  public function getDisplayTitle() {
1054  $t = $this->getTitleText();
1055  if ( $t === '' ) {
1056  return false;
1057  }
1058  return $t;
1059  }
1060 
1066  public function setFlag( $flag ) {
1067  $this->mFlags[$flag] = true;
1068  }
1069 
1074  public function getFlag( $flag ) {
1075  return isset( $this->mFlags[$flag] );
1076  }
1077 
1082  public function getAllFlags() {
1083  return array_keys( $this->mFlags );
1084  }
1085 
1151  public function setProperty( $name, $value ) {
1152  $this->mProperties[$name] = $value;
1153  }
1154 
1163  public function getProperty( $name ) {
1164  return $this->mProperties[$name] ?? false;
1165  }
1166 
1167  public function unsetProperty( $name ) {
1168  unset( $this->mProperties[$name] );
1169  }
1170 
1171  public function getProperties() {
1172  if ( !isset( $this->mProperties ) ) {
1173  $this->mProperties = [];
1174  }
1175  return $this->mProperties;
1176  }
1177 
1183  public function getUsedOptions() : array {
1184  // TODO: Merge mAccessedOptions with CacheTime::mUsedOptions
1185  if ( !isset( $this->mAccessedOptions ) ) {
1186  return [];
1187  }
1188  return array_keys( $this->mAccessedOptions );
1189  }
1190 
1203  public function recordOption( $option ) {
1204  $this->mAccessedOptions[$option] = true;
1205  }
1206 
1251  public function setExtensionData( $key, $value ) {
1252  if ( $value === null ) {
1253  unset( $this->mExtensionData[$key] );
1254  } else {
1255  $this->mExtensionData[$key] = $value;
1256  }
1257  }
1258 
1270  public function getExtensionData( $key ) {
1271  return $this->mExtensionData[$key] ?? null;
1272  }
1273 
1274  private static function getTimes( $clock = null ) {
1275  $ret = [];
1276  if ( !$clock || $clock === 'wall' ) {
1277  $ret['wall'] = microtime( true );
1278  }
1279  if ( !$clock || $clock === 'cpu' ) {
1280  $ru = getrusage( 0 /* RUSAGE_SELF */ );
1281  $ret['cpu'] = $ru['ru_utime.tv_sec'] + $ru['ru_utime.tv_usec'] / 1e6;
1282  $ret['cpu'] += $ru['ru_stime.tv_sec'] + $ru['ru_stime.tv_usec'] / 1e6;
1283  }
1284  return $ret;
1285  }
1286 
1291  public function resetParseStartTime() {
1292  $this->mParseStartTime = self::getTimes();
1293  }
1294 
1306  public function getTimeSinceStart( $clock ) {
1307  if ( !isset( $this->mParseStartTime[$clock] ) ) {
1308  return null;
1309  }
1310 
1311  $end = self::getTimes( $clock );
1312  return $end[$clock] - $this->mParseStartTime[$clock];
1313  }
1314 
1334  public function setLimitReportData( $key, $value ) {
1335  $this->mLimitReportData[$key] = $value;
1336 
1337  if ( is_array( $value ) ) {
1338  if ( array_keys( $value ) === [ 0, 1 ]
1339  && is_numeric( $value[0] )
1340  && is_numeric( $value[1] )
1341  ) {
1342  $data = [ 'value' => $value[0], 'limit' => $value[1] ];
1343  } else {
1344  $data = $value;
1345  }
1346  } else {
1347  $data = $value;
1348  }
1349 
1350  if ( strpos( $key, '-' ) ) {
1351  list( $ns, $name ) = explode( '-', $key, 2 );
1352  $this->mLimitReportJSData[$ns][$name] = $data;
1353  } else {
1354  $this->mLimitReportJSData[$key] = $data;
1355  }
1356  }
1357 
1368  public function hasDynamicContent() {
1369  global $wgParserCacheExpireTime;
1370 
1371  return $this->getCacheExpiry() < $wgParserCacheExpireTime;
1372  }
1373 
1381  public function preventClickjacking( $flag = null ) {
1382  return wfSetVar( $this->mPreventClickjacking, $flag );
1383  }
1384 
1391  public function updateRuntimeAdaptiveExpiry( $ttl ) {
1392  $this->mMaxAdaptiveExpiry = min( $ttl, $this->mMaxAdaptiveExpiry );
1393  $this->updateCacheExpiry( $ttl );
1394  }
1395 
1405  public function addExtraCSPDefaultSrc( $src ) {
1406  $this->mExtraDefaultSrcs[] = $src;
1407  }
1408 
1415  public function addExtraCSPStyleSrc( $src ) {
1416  $this->mExtraStyleSrcs[] = $src;
1417  }
1418 
1427  public function addExtraCSPScriptSrc( $src ) {
1428  $this->mExtraScriptSrcs[] = $src;
1429  }
1430 
1436  public function finalizeAdaptiveCacheExpiry() {
1437  if ( is_infinite( $this->mMaxAdaptiveExpiry ) ) {
1438  return; // not set
1439  }
1440 
1441  $runtime = $this->getTimeSinceStart( 'wall' );
1442  if ( is_float( $runtime ) ) {
1443  $slope = ( self::SLOW_AR_TTL - self::FAST_AR_TTL )
1444  / ( self::PARSE_SLOW_SEC - self::PARSE_FAST_SEC );
1445  // SLOW_AR_TTL = PARSE_SLOW_SEC * $slope + $point
1446  $point = self::SLOW_AR_TTL - self::PARSE_SLOW_SEC * $slope;
1447 
1448  $adaptiveTTL = min(
1449  max( $slope * $runtime + $point, self::MIN_AR_TTL ),
1450  $this->mMaxAdaptiveExpiry
1451  );
1452  $this->updateCacheExpiry( $adaptiveTTL );
1453  }
1454  }
1455 
1456  public function __sleep() {
1457  return array_filter( array_keys( get_object_vars( $this ) ),
1458  function ( $field ) {
1459  if ( $field === 'mParseStartTime' ) {
1460  return false;
1461  } elseif ( strpos( $field, "\0" ) !== false ) {
1462  // Unserializing unknown private fields in HHVM causes
1463  // member variables with nulls in their names (T229366)
1464  return false;
1465  } else {
1466  return true;
1467  }
1468  }
1469  );
1470  }
1471 
1480  $this->mOutputHooks = self::mergeList( $this->mOutputHooks, $source->getOutputHooks() );
1481  $this->mWarnings = self::mergeMap( $this->mWarnings, $source->mWarnings ); // don't use getter
1482  $this->mTimestamp = $this->useMaxValue( $this->mTimestamp, $source->getTimestamp() );
1483 
1484  foreach ( self::SPECULATIVE_FIELDS as $field ) {
1485  if ( $this->$field && $source->$field && $this->$field !== $source->$field ) {
1486  wfLogWarning( __METHOD__ . ": inconsistent '$field' properties!" );
1487  }
1488  $this->$field = $this->useMaxValue( $this->$field, $source->$field );
1489  }
1490 
1491  $this->mParseStartTime = $this->useEachMinValue(
1492  $this->mParseStartTime,
1493  $source->mParseStartTime
1494  );
1495 
1496  $this->mFlags = self::mergeMap( $this->mFlags, $source->mFlags );
1497  $this->mAccessedOptions = self::mergeMap( $this->mAccessedOptions, $source->mAccessedOptions );
1498 
1499  // TODO: maintain per-slot limit reports!
1500  if ( empty( $this->mLimitReportData ) ) {
1501  $this->mLimitReportData = $source->mLimitReportData;
1502  }
1503  if ( empty( $this->mLimitReportJSData ) ) {
1504  $this->mLimitReportJSData = $source->mLimitReportJSData;
1505  }
1506  }
1507 
1516  // HTML and HTTP
1517  $this->mHeadItems = self::mergeMixedList( $this->mHeadItems, $source->getHeadItems() );
1518  $this->mModules = self::mergeList( $this->mModules, $source->getModules() );
1519  $this->mModuleStyles = self::mergeList( $this->mModuleStyles, $source->getModuleStyles() );
1520  $this->mJsConfigVars = self::mergeMap( $this->mJsConfigVars, $source->getJsConfigVars() );
1521  $this->mMaxAdaptiveExpiry = min( $this->mMaxAdaptiveExpiry, $source->mMaxAdaptiveExpiry );
1522  $this->mExtraStyleSrcs = self::mergeList(
1523  $this->mExtraStyleSrcs,
1524  $source->getExtraCSPStyleSrcs()
1525  );
1526  $this->mExtraScriptSrcs = self::mergeList(
1527  $this->mExtraScriptSrcs,
1528  $source->getExtraCSPScriptSrcs()
1529  );
1530  $this->mExtraDefaultSrcs = self::mergeList(
1531  $this->mExtraDefaultSrcs,
1532  $source->getExtraCSPDefaultSrcs()
1533  );
1534 
1535  // "noindex" always wins!
1536  if ( $this->mIndexPolicy === 'noindex' || $source->mIndexPolicy === 'noindex' ) {
1537  $this->mIndexPolicy = 'noindex';
1538  } elseif ( $this->mIndexPolicy !== 'index' ) {
1539  $this->mIndexPolicy = $source->mIndexPolicy;
1540  }
1541 
1542  // Skin control
1543  $this->mNewSection = $this->mNewSection || $source->getNewSection();
1544  $this->mHideNewSection = $this->mHideNewSection || $source->getHideNewSection();
1545  $this->mNoGallery = $this->mNoGallery || $source->getNoGallery();
1546  $this->mEnableOOUI = $this->mEnableOOUI || $source->getEnableOOUI();
1547  $this->mPreventClickjacking = $this->mPreventClickjacking || $source->preventClickjacking();
1548 
1549  // TODO: we'll have to be smarter about this!
1550  $this->mSections = array_merge( $this->mSections, $source->getSections() );
1551  $this->mTOCHTML .= $source->mTOCHTML;
1552 
1553  // XXX: we don't want to concatenate title text, so first write wins.
1554  // We should use the first *modified* title text, but we don't have the original to check.
1555  if ( $this->mTitleText === null || $this->mTitleText === '' ) {
1556  $this->mTitleText = $source->mTitleText;
1557  }
1558 
1559  // class names are stored in array keys
1560  $this->mWrapperDivClasses = self::mergeMap(
1561  $this->mWrapperDivClasses,
1562  $source->mWrapperDivClasses
1563  );
1564 
1565  // NOTE: last write wins, same as within one ParserOutput
1566  $this->mIndicators = self::mergeMap( $this->mIndicators, $source->getIndicators() );
1567 
1568  // NOTE: include extension data in "tracking meta data" as well as "html meta data"!
1569  // TODO: add a $mergeStrategy parameter to setExtensionData to allow different
1570  // kinds of extension data to be merged in different ways.
1571  $this->mExtensionData = self::mergeMap(
1572  $this->mExtensionData,
1573  $source->mExtensionData
1574  );
1575  }
1576 
1585  $this->mLanguageLinks = self::mergeList( $this->mLanguageLinks, $source->getLanguageLinks() );
1586  $this->mCategories = self::mergeMap( $this->mCategories, $source->getCategories() );
1587  $this->mLinks = self::merge2D( $this->mLinks, $source->getLinks() );
1588  $this->mTemplates = self::merge2D( $this->mTemplates, $source->getTemplates() );
1589  $this->mTemplateIds = self::merge2D( $this->mTemplateIds, $source->getTemplateIds() );
1590  $this->mImages = self::mergeMap( $this->mImages, $source->getImages() );
1591  $this->mFileSearchOptions = self::mergeMap(
1592  $this->mFileSearchOptions,
1593  $source->getFileSearchOptions()
1594  );
1595  $this->mExternalLinks = self::mergeMap( $this->mExternalLinks, $source->getExternalLinks() );
1596  $this->mInterwikiLinks = self::merge2D(
1597  $this->mInterwikiLinks,
1598  $source->getInterwikiLinks()
1599  );
1600 
1601  // TODO: add a $mergeStrategy parameter to setProperty to allow different
1602  // kinds of properties to be merged in different ways.
1603  $this->mProperties = self::mergeMap( $this->mProperties, $source->getProperties() );
1604 
1605  // NOTE: include extension data in "tracking meta data" as well as "html meta data"!
1606  // TODO: add a $mergeStrategy parameter to setExtensionData to allow different
1607  // kinds of extension data to be merged in different ways.
1608  $this->mExtensionData = self::mergeMap(
1609  $this->mExtensionData,
1610  $source->mExtensionData
1611  );
1612  }
1613 
1614  private static function mergeMixedList( array $a, array $b ) {
1615  return array_unique( array_merge( $a, $b ), SORT_REGULAR );
1616  }
1617 
1618  private static function mergeList( array $a, array $b ) {
1619  return array_values( array_unique( array_merge( $a, $b ), SORT_REGULAR ) );
1620  }
1621 
1622  private static function mergeMap( array $a, array $b ) {
1623  return array_replace( $a, $b );
1624  }
1625 
1626  private static function merge2D( array $a, array $b ) {
1627  $values = [];
1628  $keys = array_merge( array_keys( $a ), array_keys( $b ) );
1629 
1630  foreach ( $keys as $k ) {
1631  if ( empty( $a[$k] ) ) {
1632  $values[$k] = $b[$k];
1633  } elseif ( empty( $b[$k] ) ) {
1634  $values[$k] = $a[$k];
1635  } elseif ( is_array( $a[$k] ) && is_array( $b[$k] ) ) {
1636  $values[$k] = array_replace( $a[$k], $b[$k] );
1637  } else {
1638  $values[$k] = $b[$k];
1639  }
1640  }
1641 
1642  return $values;
1643  }
1644 
1645  private static function useEachMinValue( array $a, array $b ) {
1646  $values = [];
1647  $keys = array_merge( array_keys( $a ), array_keys( $b ) );
1648 
1649  foreach ( $keys as $k ) {
1650  if ( is_array( $a[$k] ?? null ) && is_array( $b[$k] ?? null ) ) {
1651  $values[$k] = self::useEachMinValue( $a[$k], $b[$k] );
1652  } else {
1653  $values[$k] = self::useMinValue( $a[$k] ?? null, $b[$k] ?? null );
1654  }
1655  }
1656 
1657  return $values;
1658  }
1659 
1660  private static function useMinValue( $a, $b ) {
1661  if ( $a === null ) {
1662  return $b;
1663  }
1664 
1665  if ( $b === null ) {
1666  return $a;
1667  }
1668 
1669  return min( $a, $b );
1670  }
1671 
1672  private static function useMaxValue( $a, $b ) {
1673  if ( $a === null ) {
1674  return $b;
1675  }
1676 
1677  if ( $b === null ) {
1678  return $a;
1679  }
1680 
1681  return max( $a, $b );
1682  }
1683 
1691  public function jsonSerialize() {
1692  $data = [
1693  '_type_' => 'ParserOutput',
1694 
1695  'Text' => $this->mText,
1696  'LanguageLinks' => $this->mLanguageLinks,
1697  'Categories' => $this->mCategories,
1698  'Indicators' => $this->mIndicators,
1699  'TitleText' => $this->mTitleText,
1700  'Links' => $this->mLinks,
1701  'LinksSpecial' => $this->mLinksSpecial,
1702  'Templates' => $this->mTemplates,
1703  'TemplateIds' => $this->mTemplateIds,
1704  'Images' => $this->mImages,
1705  'FileSearchOptions' => $this->mFileSearchOptions,
1706  'ExternalLinks' => $this->mExternalLinks,
1707  'InterwikiLinks' => $this->mInterwikiLinks,
1708  'NewSection' => $this->mNewSection,
1709  'HideNewSection' => $this->mHideNewSection,
1710  'NoGallery' => $this->mNoGallery,
1711  'HeadItems' => $this->mHeadItems,
1712  'Modules' => $this->mModules,
1713  'ModuleStyles' => $this->mModuleStyles,
1714  'JsConfigVars' => $this->mJsConfigVars,
1715  'OutputHooks' => $this->mOutputHooks,
1716  'Warnings' => $this->mWarnings,
1717  'Sections' => $this->mSections,
1718  'Properties' => $this->mProperties, // may contain arbitrary structures!
1719  'TOCHTML' => $this->mTOCHTML,
1720  'Timestamp' => $this->mTimestamp,
1721  'EnableOOUI' => $this->mEnableOOUI,
1722  'IndexPolicy' => $this->mIndexPolicy,
1723  'AccessedOptions' => $this->mAccessedOptions,
1724  'ExtensionData' => $this->mExtensionData, // may contain arbitrary structures!
1725  'LimitReportData' => $this->mLimitReportData,
1726  'LimitReportJSData' => $this->mLimitReportJSData,
1727  'ParseStartTime' => $this->mParseStartTime,
1728  'PreventClickjacking' => $this->mPreventClickjacking,
1729  'ExtraScriptSrcs' => $this->mExtraScriptSrcs,
1730  'ExtraDefaultSrcs' => $this->mExtraDefaultSrcs,
1731  'ExtraStyleSrcs' => $this->mExtraStyleSrcs,
1732  'Flags' => $this->mFlags,
1733  'SpeculativeRevId' => $this->mSpeculativeRevId,
1734  'SpeculativePageIdUsed' => $this->speculativePageIdUsed,
1735  'RevisionTimestampUsed' => $this->revisionTimestampUsed,
1736  'RevisionUsedSha1Base36' => $this->revisionUsedSha1Base36,
1737  'WrapperDivClasses' => $this->mWrapperDivClasses,
1738  ];
1739 
1740  // Fill in missing fields from parents. Array addition does not override existing fields.
1741  $data += parent::jsonSerialize();
1742 
1743  // TODO: make more fields optional!
1744 
1745  if ( $this->mMaxAdaptiveExpiry !== INF ) {
1746  // NOTE: JSON can't encode infinity!
1747  $data['MaxAdaptiveExpiry'] = $this->mMaxAdaptiveExpiry;
1748  }
1749 
1750  return $data;
1751  }
1752 
1763  public static function newFromJson( $jsonData ) {
1764  if ( is_string( $jsonData ) ) {
1765  $jsonData = FormatJson::decode( $jsonData, true );
1766  if ( !$jsonData ) {
1767  // TODO: in PHP 7.3, we can use JsonException
1768  throw new InvalidArgumentException( 'Bad JSON' );
1769  }
1770  }
1771 
1772  if ( is_object( $jsonData ) ) {
1773  $jsonData = (array)$jsonData;
1774  }
1775 
1776  $output = new ParserOutput();
1777  $output->initFromJson( $jsonData );
1778 
1779  return $output;
1780  }
1781 
1786  protected function initFromJson( array $jsonData ) {
1787  parent::initFromJson( $jsonData );
1788 
1789  $this->mText = $jsonData['Text'];
1790  $this->mLanguageLinks = $jsonData['LanguageLinks'];
1791  $this->mCategories = $jsonData['Categories'];
1792  $this->mIndicators = $jsonData['Indicators'];
1793  $this->mTitleText = $jsonData['TitleText'];
1794  $this->mLinks = $jsonData['Links'];
1795  $this->mLinksSpecial = $jsonData['LinksSpecial'];
1796  $this->mTemplates = $jsonData['Templates'];
1797  $this->mTemplateIds = $jsonData['TemplateIds'];
1798  $this->mImages = $jsonData['Images'];
1799  $this->mFileSearchOptions = $jsonData['FileSearchOptions'];
1800  $this->mExternalLinks = $jsonData['ExternalLinks'];
1801  $this->mInterwikiLinks = $jsonData['InterwikiLinks'];
1802  $this->mNewSection = $jsonData['NewSection'];
1803  $this->mHideNewSection = $jsonData['HideNewSection'];
1804  $this->mNoGallery = $jsonData['NoGallery'];
1805  $this->mHeadItems = $jsonData['HeadItems'];
1806  $this->mModules = $jsonData['Modules'];
1807  $this->mModuleStyles = $jsonData['ModuleStyles'];
1808  $this->mJsConfigVars = $jsonData['JsConfigVars'];
1809  $this->mOutputHooks = $jsonData['OutputHooks'];
1810  $this->mWarnings = $jsonData['Warnings'];
1811  $this->mSections = $jsonData['Sections'];
1812  $this->mProperties = $jsonData['Properties'];
1813  $this->mTOCHTML = $jsonData['TOCHTML'];
1814  $this->mTimestamp = $jsonData['Timestamp'];
1815  $this->mEnableOOUI = $jsonData['EnableOOUI'];
1816  $this->mIndexPolicy = $jsonData['IndexPolicy'];
1817  $this->mAccessedOptions = $jsonData['AccessedOptions'];
1818  $this->mExtensionData = $jsonData['ExtensionData'];
1819  $this->mLimitReportData = $jsonData['LimitReportData'];
1820  $this->mLimitReportJSData = $jsonData['LimitReportJSData'];
1821  $this->mParseStartTime = $jsonData['ParseStartTime'];
1822  $this->mPreventClickjacking = $jsonData['PreventClickjacking'];
1823  $this->mExtraScriptSrcs = $jsonData['ExtraScriptSrcs'];
1824  $this->mExtraDefaultSrcs = $jsonData['ExtraDefaultSrcs'];
1825  $this->mExtraStyleSrcs = $jsonData['ExtraStyleSrcs'];
1826  $this->mFlags = $jsonData['Flags'];
1827  $this->mSpeculativeRevId = $jsonData['SpeculativeRevId'];
1828  $this->speculativePageIdUsed = $jsonData['SpeculativePageIdUsed'];
1829  $this->revisionTimestampUsed = $jsonData['RevisionTimestampUsed'];
1830  $this->revisionUsedSha1Base36 = $jsonData['RevisionUsedSha1Base36'];
1831  $this->mWrapperDivClasses = $jsonData['WrapperDivClasses'];
1832  $this->mMaxAdaptiveExpiry = $jsonData['MaxAdaptiveExpiry'] ?? INF;
1833  }
1834 }
ParserOutput\$mImages
array $mImages
DB keys of the images used, in the array key only.
Definition: ParserOutput.php:95
ParserOutput\$mWrapperDivClasses
$mWrapperDivClasses
string CSS classes to use for the wrapping div, stored in the array keys.
Definition: ParserOutput.php:257
ParserOutput\addCacheMessage
addCacheMessage(string $msg)
Adds a comment notice about cache state to the text of the page.
Definition: ParserOutput.php:461
ParserOutput\addOutputPageMetadata
addOutputPageMetadata(OutputPage $out)
Copy items from the OutputPage object into this one.
Definition: ParserOutput.php:977
ParserOutput\getEnableOOUI
getEnableOOUI()
Definition: ParserOutput.php:691
ParserOutput\mergeMap
static mergeMap(array $a, array $b)
Definition: ParserOutput.php:1622
ParserOutput\$mEnableOOUI
bool $mEnableOOUI
Whether OOUI should be enabled.
Definition: ParserOutput.php:182
ParserOutput\$mWarnings
array $mWarnings
Warning text to be returned to the user.
Definition: ParserOutput.php:157
ParserOutput\$mJsConfigVars
array $mJsConfigVars
JavaScript config variable for mw.config combined with this page.
Definition: ParserOutput.php:146
CacheTime\getCacheExpiry
getCacheExpiry()
Returns the number of seconds after which this object should expire.
Definition: CacheTime.php:136
ParserOutput\$mFileSearchOptions
array $mFileSearchOptions
DB keys of the images used mapped to sha1 and MW timestamp.
Definition: ParserOutput.php:100
Title\newFromText
static newFromText( $text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Definition: Title.php:328
ParserOutput\setTitleText
setTitleText( $t)
Definition: ParserOutput.php:734
ParserOutput
Definition: ParserOutput.php:27
ParserOutput\setSpeculativeRevIdUsed
setSpeculativeRevIdUsed( $id)
Definition: ParserOutput.php:497
ParserOutput\SUPPORTS_UNWRAP_TRANSFORM
const SUPPORTS_UNWRAP_TRANSFORM
Definition: ParserOutput.php:39
CacheTime
Parser cache specific expiry check.
Definition: CacheTime.php:31
ParserOutput\resetParseStartTime
resetParseStartTime()
Resets the parse start timestamps for future calls to getTimeSinceStart()
Definition: ParserOutput.php:1291
ParserOutput\setDisplayTitle
setDisplayTitle( $text)
Override the title to be used for display.
Definition: ParserOutput.php:1040
ParserOutput\$mLanguageLinks
array $mLanguageLinks
List of the full text of language links, in the order they appear.
Definition: ParserOutput.php:50
ParserOutput\setTimestamp
setTimestamp( $timestamp)
Definition: ParserOutput.php:750
ParserOutput\getUsedOptions
getUsedOptions()
Returns the options from its ParserOptions which have been taken into account to produce this output.
Definition: ParserOutput.php:1183
ParserOutput\mergeMixedList
static mergeMixedList(array $a, array $b)
Definition: ParserOutput.php:1614
ParserOutput\addExtraCSPScriptSrc
addExtraCSPScriptSrc( $src)
Add an extra value to Content-Security-Policy script-src directive.
Definition: ParserOutput.php:1427
ParserOutput\setLimitReportData
setLimitReportData( $key, $value)
Sets parser limit report data for a key.
Definition: ParserOutput.php:1334
wfSetVar
wfSetVar(&$dest, $source, $force=false)
Sets dest to source and returns the original value of dest If source is NULL, it just returns the val...
Definition: GlobalFunctions.php:1550
ParserOutput\merge2D
static merge2D(array $a, array $b)
Definition: ParserOutput.php:1626
ParserOutput\addWrapperDivClass
addWrapperDivClass( $class)
Add a CSS class to use for the wrapping div.
Definition: ParserOutput.php:470
ParserOutput\$mLimitReportJSData
array $mLimitReportJSData
Parser limit report data for JSON.
Definition: ParserOutput.php:205
ParserOutput\$mModules
array $mModules
Modules to be loaded by ResourceLoader.
Definition: ParserOutput.php:136
ParserOutput\__sleep
__sleep()
Definition: ParserOutput.php:1456
ParserOutput\setNewSection
setNewSection( $value)
Definition: ParserOutput.php:790
ParserOutput\getModules
getModules()
Definition: ParserOutput.php:644
ParserOutput\$mAccessedOptions
true[] $mAccessedOptions
List of ParserOptions (stored in the keys).
Definition: ParserOutput.php:192
ParserOutput\getImages
& getImages()
Definition: ParserOutput.php:620
ParserOutput\addModules
addModules( $modules)
Definition: ParserOutput.php:942
ParserOutput\MIN_AR_TTL
const MIN_AR_TTL
Definition: ParserOutput.php:272
ParserOutput\$mLinksSpecial
array $mLinksSpecial
Keys are DBKs for the links to special pages in the document.
Definition: ParserOutput.php:78
ParserOutput\$mOutputHooks
array $mOutputHooks
Hook tags as per $wgParserOutputHooks.
Definition: ParserOutput.php:151
ParserOutput\setIndicator
setIndicator( $id, $content)
Definition: ParserOutput.php:763
ParserOutput\addTemplate
addTemplate( $title, $page_id, $rev_id)
Register a template dependency for this output.
Definition: ParserOutput.php:895
ParserOutput\getJsConfigVars
getJsConfigVars()
Definition: ParserOutput.php:656
wfUrlencode
wfUrlencode( $s)
We want some things to be included as literal characters in our title URLs for prettiness,...
Definition: GlobalFunctions.php:308
ParserOutput\jsonSerialize
jsonSerialize()
Returns a JSON serializable structure representing this ParserOutput instance.
Definition: ParserOutput.php:1691
ParserOutput\mergeTrackingMetaDataFrom
mergeTrackingMetaDataFrom(ParserOutput $source)
Merges dependency tracking metadata such as backlinks, images used, and extension data from $source i...
Definition: ParserOutput.php:1584
ParserOutput\addExtraCSPStyleSrc
addExtraCSPStyleSrc( $src)
Add an extra value to Content-Security-Policy style-src directive.
Definition: ParserOutput.php:1415
OutputPage\getModuleStyles
getModuleStyles( $filter=false, $position=null)
Get the list of style-only modules to load on this page.
Definition: OutputPage.php:570
NS_FILE
const NS_FILE
Definition: Defines.php:75
ParserOutput\unsetProperty
unsetProperty( $name)
Definition: ParserOutput.php:1167
ParserOutput\setFlag
setFlag( $flag)
Attach a flag to the output so that it can be checked later to handle special cases.
Definition: ParserOutput.php:1066
ParserOutput\hideNewSection
hideNewSection( $value)
Definition: ParserOutput.php:794
ParserOutput\addLink
addLink(Title $title, $id=null)
Record a local or interwiki inline link for saving in future link tables.
Definition: ParserOutput.php:847
wfMessage
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
Definition: GlobalFunctions.php:1220
ParserOutput\$mMaxAdaptiveExpiry
int $mMaxAdaptiveExpiry
Upper bound of expiry based on parse duration.
Definition: ParserOutput.php:260
$s
$s
Definition: mergeMessageFileList.php:184
ParserOutput\__construct
__construct( $text='', $languageLinks=[], $categoryLinks=[], $unused=false, $titletext='')
Definition: ParserOutput.php:283
wfLogWarning
wfLogWarning( $msg, $callerOffset=1, $level=E_USER_WARNING)
Send a warning as a PHP error and the debug log.
Definition: GlobalFunctions.php:1087
ParserOutput\EDITSECTION_REGEX
const EDITSECTION_REGEX
Definition: ParserOutput.php:262
ParserOutput\PARSE_SLOW_SEC
const PARSE_SLOW_SEC
Definition: ParserOutput.php:269
ParserOutput\getHeadItems
getHeadItems()
Definition: ParserOutput.php:640
ParserOutput\PARSE_FAST_SEC
const PARSE_FAST_SEC
Definition: ParserOutput.php:268
ParserOutput\setSpeculativePageIdUsed
setSpeculativePageIdUsed( $id)
Definition: ParserOutput.php:513
ParserOutput\getProperties
getProperties()
Definition: ParserOutput.php:1171
ParserOutput\mergeList
static mergeList(array $a, array $b)
Definition: ParserOutput.php:1618
ParserOutput\$mProperties
array $mProperties
Name/value pairs to be cached in the DB.
Definition: ParserOutput.php:167
ParserOutput\getModuleStyles
getModuleStyles()
Definition: ParserOutput.php:648
ParserOutput\$mHeadItems
array $mHeadItems
Items to put in the <head> section.
Definition: ParserOutput.php:131
ParserOutput\$mTimestamp
string $mTimestamp
Timestamp of the revision.
Definition: ParserOutput.php:177
NS_SPECIAL
const NS_SPECIAL
Definition: Defines.php:58
ParserOutput\getExtraCSPDefaultSrcs
getExtraCSPDefaultSrcs()
Get extra Content-Security-Policy 'default-src' directives.
Definition: ParserOutput.php:700
FormatJson\decode
static decode( $value, $assoc=false)
Decodes a JSON string.
Definition: FormatJson.php:174
ParserOutput\addExtraCSPDefaultSrc
addExtraCSPDefaultSrc( $src)
Add an extra value to Content-Security-Policy default-src directive.
Definition: ParserOutput.php:1405
ParserOutput\getLimitReportJSData
getLimitReportJSData()
Definition: ParserOutput.php:687
MWException
MediaWiki exception.
Definition: MWException.php:29
Parser\TOC_START
const TOC_START
Definition: Parser.php:148
OutputPage\getModules
getModules( $filter=false, $position=null, $param='mModules', $type=ResourceLoaderModule::TYPE_COMBINED)
Get the list of modules to include on this page.
Definition: OutputPage.php:545
ParserOutput\getCategoryLinks
getCategoryLinks()
Definition: ParserOutput.php:576
MediaWiki\Logger\LoggerFactory
PSR-3 logger instance factory.
Definition: LoggerFactory.php:45
ParserOutput\setRevisionUsedSha1Base36
setRevisionUsedSha1Base36( $hash)
Definition: ParserOutput.php:545
ParserOutput\$mLinks
int[][] $mLinks
2-D map of NS/DBK to ID for the links in the document.
Definition: ParserOutput.php:72
ParserOutput\getFlag
getFlag( $flag)
Definition: ParserOutput.php:1074
ParserOutput\getTimestamp
getTimestamp()
Definition: ParserOutput.php:679
ParserOutput\isLinkInternal
static isLinkInternal( $internal, $url)
Checks, if a url is pointing to the own server.
Definition: ParserOutput.php:813
ParserOutput\addExternalLink
addExternalLink( $url)
Definition: ParserOutput.php:824
ParserOutput\$mExtraDefaultSrcs
array $mExtraDefaultSrcs
Extra default-src for CSP [Everything but script and style].
Definition: ParserOutput.php:225
ParserOutput\getInterwikiLinks
getInterwikiLinks()
Definition: ParserOutput.php:572
ParserOutput\$mLimitReportData
array $mLimitReportData
Parser limit report data.
Definition: ParserOutput.php:202
ParserOutput\mergeHtmlMetaDataFrom
mergeHtmlMetaDataFrom(ParserOutput $source)
Merges HTML metadata such as head items, JS config vars, and HTTP cache control info from $source int...
Definition: ParserOutput.php:1515
ParserOutput\updateRuntimeAdaptiveExpiry
updateRuntimeAdaptiveExpiry( $ttl)
Lower the runtime adaptive TTL to at most this value.
Definition: ParserOutput.php:1391
ParserOutput\getTimeSinceStart
getTimeSinceStart( $clock)
Returns the time since resetParseStartTime() was last called.
Definition: ParserOutput.php:1306
$modules
$modules
Definition: HTMLFormElement.php:15
ParserOutput\addImage
addImage( $name, $timestamp=null, $sha1=null)
Register a file dependency for this output.
Definition: ParserOutput.php:882
ParserOutput\$mHideNewSection
bool $mHideNewSection
Hide the new section link?
Definition: ParserOutput.php:121
ParserOutput\$mTemplates
array $mTemplates
2-D map of NS/DBK to ID for the template references.
Definition: ParserOutput.php:84
ParserOutput\$mNewSection
bool $mNewSection
Show a new section link?
Definition: ParserOutput.php:116
$wgParserCacheExpireTime
$wgParserCacheExpireTime
The expiry time for the parser cache, in seconds.
Definition: DefaultSettings.php:2646
ParserOutput\getTimes
static getTimes( $clock=null)
Definition: ParserOutput.php:1274
ParserOutput\addCategory
addCategory( $c, $sort)
Definition: ParserOutput.php:754
ParserOutput\useMaxValue
static useMaxValue( $a, $b)
Definition: ParserOutput.php:1672
Parser\TOC_END
const TOC_END
Definition: Parser.php:149
$title
$title
Definition: testCompression.php:38
ParserOutput\SUPPORTS_STATELESS_TRANSFORMS
const SUPPORTS_STATELESS_TRANSFORMS
Feature flags to indicate to extensions that MediaWiki core supports and uses getText() stateless tra...
Definition: ParserOutput.php:34
ParserOutput\addModuleStyles
addModuleStyles( $modules)
Definition: ParserOutput.php:950
ParserOutput\mergeInternalMetaDataFrom
mergeInternalMetaDataFrom(ParserOutput $source)
Merges internal metadata such as flags, accessed options, and profiling info from $source into this P...
Definition: ParserOutput.php:1479
ParserOutput\setText
setText( $text)
Definition: ParserOutput.php:722
NS_CATEGORY
const NS_CATEGORY
Definition: Defines.php:83
ParserOutput\$mModuleStyles
array $mModuleStyles
Modules of which only the CSSS will be loaded by ResourceLoader.
Definition: ParserOutput.php:141
ParserOutput\getDisplayTitle
getDisplayTitle()
Get the title to be used for display.
Definition: ParserOutput.php:1053
ParserOutput\$mFlags
array $mFlags
Generic flags.
Definition: ParserOutput.php:235
ParserOutput\getIndicators
getIndicators()
Definition: ParserOutput.php:588
ParserOutput\setLanguageLinks
setLanguageLinks( $ll)
Definition: ParserOutput.php:726
ParserOutput\getSpeculativePageIdUsed
getSpeculativePageIdUsed()
Definition: ParserOutput.php:521
wfDebug
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
Definition: GlobalFunctions.php:910
OutputPage
This is one of the Core classes and should be read at least once by any new developers.
Definition: OutputPage.php:47
ParserOutput\getLanguageLinks
& getLanguageLinks()
Definition: ParserOutput.php:568
ParserOutput\$mPreventClickjacking
bool $mPreventClickjacking
Whether to emit X-Frame-Options: DENY.
Definition: ParserOutput.php:215
ParserOutput\getLinksSpecial
& getLinksSpecial()
Definition: ParserOutput.php:608
ParserOutput\getExternalLinks
& getExternalLinks()
Definition: ParserOutput.php:628
ParserOutput\getTemplateIds
& getTemplateIds()
Definition: ParserOutput.php:616
OutputPage\getPreventClickjacking
getPreventClickjacking()
Get the prevent-clickjacking flag.
Definition: OutputPage.php:2364
ParserOutput\getTOCHTML
getTOCHTML()
Definition: ParserOutput.php:672
ParserOutput\recordOption
recordOption( $option)
Tags a parser option for use in the cache key for this parser output.
Definition: ParserOutput.php:1203
ParserOutput\addOutputHook
addOutputHook( $hook, $data=false)
Definition: ParserOutput.php:786
ParserOutput\getExtraCSPScriptSrcs
getExtraCSPScriptSrcs()
Get extra Content-Security-Policy 'script-src' directives.
Definition: ParserOutput.php:709
ParserOutput\SLOW_AR_TTL
const SLOW_AR_TTL
Definition: ParserOutput.php:271
ParserOutput\getTitleText
getTitleText()
Definition: ParserOutput.php:592
ParserOutput\clearWrapperDivClass
clearWrapperDivClass()
Clears the CSS class to use for the wrapping div, effectively disabling the wrapper div until addWrap...
Definition: ParserOutput.php:478
Title\makeTitleSafe
static makeTitleSafe( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:617
ParserOutput\setProperty
setProperty( $name, $value)
Set a property to be stored in the page_props database table.
Definition: ParserOutput.php:1151
ParserOutput\getNewSection
getNewSection()
Definition: ParserOutput.php:802
$content
$content
Definition: router.php:76
ParserOutput\setExtensionData
setExtensionData( $key, $value)
Attaches arbitrary data to this ParserObject.
Definition: ParserOutput.php:1251
ParserOutput\$mExtensionData
array $mExtensionData
extra data used by extensions.
Definition: ParserOutput.php:197
OutputPage\getHeadItemsArray
getHeadItemsArray()
Get an array of head items.
Definition: OutputPage.php:652
NS_MEDIA
const NS_MEDIA
Definition: Defines.php:57
ParserOutput\getOutputHooks
getOutputHooks()
Definition: ParserOutput.php:660
ParserOutput\$speculativePageIdUsed
int null $speculativePageIdUsed
Assumed page ID for {{PAGEID}} if no revision is set.
Definition: ParserOutput.php:247
ParserOutput\getHideNewSection
getHideNewSection()
Definition: ParserOutput.php:798
$wgServer
$wgServer
URL of the server.
Definition: DefaultSettings.php:111
Hooks\runner
static runner()
Get a HookRunner instance for calling hooks using the new interfaces.
Definition: Hooks.php:172
ParserOutput\$revisionUsedSha1Base36
string null $revisionUsedSha1Base36
SHA-1 base 36 hash of any self-transclusion.
Definition: ParserOutput.php:252
ParserOutput\$mExtraStyleSrcs
array $mExtraStyleSrcs
Extra style-src for CSP.
Definition: ParserOutput.php:230
ParserOutput\getRevisionUsedSha1Base36
getRevisionUsedSha1Base36()
Definition: ParserOutput.php:564
ParserOutput\$mExtraScriptSrcs
array $mExtraScriptSrcs
Extra script-src for CSP.
Definition: ParserOutput.php:220
ParserOutput\getNoGallery
getNoGallery()
Definition: ParserOutput.php:636
ParserOutput\addWarning
addWarning( $s)
Definition: ParserOutput.php:782
RequestContext\getMain
static getMain()
Get the RequestContext object associated with the main request.
Definition: RequestContext.php:454
ParserOutput\$mTemplateIds
array $mTemplateIds
2-D map of NS/DBK to rev ID for the template references.
Definition: ParserOutput.php:90
ParserOutput\getTemplates
& getTemplates()
Definition: ParserOutput.php:612
ParserOutput\setSections
setSections( $toc)
Definition: ParserOutput.php:738
ParserOutput\setCategoryLinks
setCategoryLinks( $cl)
Definition: ParserOutput.php:730
ParserOutput\$mParseStartTime
array $mParseStartTime
Timestamps for getTimeSinceStart().
Definition: ParserOutput.php:210
ParserOutput\getRevisionTimestampUsed
getRevisionTimestampUsed()
Definition: ParserOutput.php:537
ParserOutput\getFileSearchOptions
& getFileSearchOptions()
Definition: ParserOutput.php:624
Title
Represents a title within MediaWiki.
Definition: Title.php:41
ParserOutput\$mTOCHTML
string $mTOCHTML
HTML of the TOC.
Definition: ParserOutput.php:172
ParserOutput\getProperty
getProperty( $name)
Definition: ParserOutput.php:1163
Parser\normalizeLinkUrl
static normalizeLinkUrl( $url)
Replace unusual escape codes in a URL with their equivalent characters.
Definition: Parser.php:2229
ParserOutput\$mExternalLinks
array $mExternalLinks
External link URLs, in the key only.
Definition: ParserOutput.php:105
ParserOutput\$mIndicators
array $mIndicators
Page status indicators, usually displayed in top-right corner.
Definition: ParserOutput.php:60
ParserOutput\FAST_AR_TTL
const FAST_AR_TTL
Definition: ParserOutput.php:270
ParserOutput\addJsConfigVars
addJsConfigVars( $keys, $value=null)
Add one or more variables to be set in mw.config in JavaScript.
Definition: ParserOutput.php:961
ParserOutput\getCategories
& getCategories()
Definition: ParserOutput.php:580
ParserOutput\hasText
hasText()
Returns true if text was passed to the constructor, or set using setText().
Definition: ParserOutput.php:302
ParserOutput\$mNoGallery
bool $mNoGallery
No gallery on category page? (NOGALLERY).
Definition: ParserOutput.php:126
ParserOutput\getRawText
getRawText()
Get the cacheable text with <mw:editsection> markers still in it.
Definition: ParserOutput.php:314
Html\rawElement
static rawElement( $element, $attribs=[], $contents='')
Returns an HTML element in a string.
Definition: Html.php:209
ParserOutput\useMinValue
static useMinValue( $a, $b)
Definition: ParserOutput.php:1660
ParserOutput\$mIndexPolicy
string $mIndexPolicy
'index' or 'noindex'? Any other value will result in no change.
Definition: ParserOutput.php:187
$keys
$keys
Definition: testCompression.php:72
ParserOutput\newFromJson
static newFromJson( $jsonData)
Construct a ParserOutput instance from a structure returned by jsonSerialize()
Definition: ParserOutput.php:1763
ParserOutput\getLimitReportData
getLimitReportData()
Definition: ParserOutput.php:683
CacheTime\updateCacheExpiry
updateCacheExpiry( $seconds)
Sets the number of seconds after which this object should expire.
Definition: CacheTime.php:119
ParserOutput\addTrackingCategory
addTrackingCategory( $msg, $title)
Add a tracking category, getting the title from a system message, or print a debug message if the tit...
Definition: ParserOutput.php:1002
$source
$source
Definition: mwdoc-filter.php:34
ParserOutput\useEachMinValue
static useEachMinValue(array $a, array $b)
Definition: ParserOutput.php:1645
ParserOutput\getExtensionData
getExtensionData( $key)
Gets extensions data previously attached to this ParserOutput using setExtensionData().
Definition: ParserOutput.php:1270
ParserOutput\addLanguageLink
addLanguageLink( $t)
Definition: ParserOutput.php:778
ParserOutput\$mInterwikiLinks
array $mInterwikiLinks
2-D map of prefix/DBK (in keys only) for the inline interwiki links in the document.
Definition: ParserOutput.php:111
Sanitizer\decodeTagAttributes
static decodeTagAttributes( $text)
Return an associative array of attribute names and values from a partial tag string.
Definition: Sanitizer.php:1008
ParserOutput\getText
getText( $options=[])
Get the output HTML.
Definition: ParserOutput.php:348
ParserOutput\setRevisionTimestampUsed
setRevisionTimestampUsed( $timestamp)
Definition: ParserOutput.php:529
$t
$t
Definition: testCompression.php:74
Sanitizer\decodeCharReferences
static decodeCharReferences( $text)
Decode any character references, numeric or named entities, in the text and return a UTF-8 string.
Definition: Sanitizer.php:1232
Html\element
static element( $element, $attribs=[], $contents='')
Identical to rawElement(), but HTML-escapes $contents (like Xml::element()).
Definition: Html.php:231
ParserOutput\$revisionTimestampUsed
int null $revisionTimestampUsed
Assumed rev timestamp for {{REVISIONTIMESTAMP}} if no revision is set.
Definition: ParserOutput.php:249
ParserOutput\$mSections
array $mSections
Table of contents.
Definition: ParserOutput.php:162
ParserOutput\$mText
string null $mText
The output text.
Definition: ParserOutput.php:44
ParserOutput\addInterwikiLink
addInterwikiLink( $title)
Definition: ParserOutput.php:912
ParserOutput\setTOCHTML
setTOCHTML( $tochtml)
Definition: ParserOutput.php:746
ParserOutput\$mTitleText
string $mTitleText
Title text of the chosen language variant, as HTML.
Definition: ParserOutput.php:65
OutputPage\getJsConfigVars
getJsConfigVars()
Get the javascript config vars to include on this page.
Definition: OutputPage.php:3219
$wgRegisterInternalExternals
$wgRegisterInternalExternals
By default MediaWiki does not register links pointing to same server in externallinks dataset,...
Definition: DefaultSettings.php:9025
ParserOutput\getSections
getSections()
Definition: ParserOutput.php:596
ParserOutput\$mSpeculativeRevId
int null $mSpeculativeRevId
Assumed rev ID for {{REVISIONID}} if no revision is set.
Definition: ParserOutput.php:237
ParserOutput\hasDynamicContent
hasDynamicContent()
Check whether the cache TTL was lowered due to dynamic content.
Definition: ParserOutput.php:1368
ParserOutput\addHeadItem
addHeadItem( $section, $tag=false)
Add some text to the "<head>".
Definition: ParserOutput.php:930
ParserOutput\setEnableOOUI
setEnableOOUI( $enable=false)
Enables OOUI, if true, in any OutputPage instance this ParserOutput object is added to.
Definition: ParserOutput.php:774
ParserOutput\$mCategories
array $mCategories
Map of category names to sort keys.
Definition: ParserOutput.php:55
ParserOutput\finalizeAdaptiveCacheExpiry
finalizeAdaptiveCacheExpiry()
Call this when parsing is done to lower the TTL based on low parse times.
Definition: ParserOutput.php:1436
ParserOutput\getSpeculativeRevIdUsed
getSpeculativeRevIdUsed()
Definition: ParserOutput.php:505
ParserOutput\getLinks
& getLinks()
Definition: ParserOutput.php:600
ParserOutput\setIndexPolicy
setIndexPolicy( $policy)
Definition: ParserOutput.php:742
ParserOutput\setNoGallery
setNoGallery( $value)
Definition: ParserOutput.php:632
ParserOutput\getAllFlags
getAllFlags()
Definition: ParserOutput.php:1082
ParserOutput\getIndexPolicy
getIndexPolicy()
Definition: ParserOutput.php:668
ParserOutput\getExtraCSPStyleSrcs
getExtraCSPStyleSrcs()
Get extra Content-Security-Policy 'style-src' directives.
Definition: ParserOutput.php:718
ParserOutput\getWrapperDivClass
getWrapperDivClass()
Returns the class (or classes) to be used with the wrapper div for this otuput.
Definition: ParserOutput.php:489
ParserOutput\preventClickjacking
preventClickjacking( $flag=null)
Get or set the prevent-clickjacking flag.
Definition: ParserOutput.php:1381
ParserOutput\getWarnings
getWarnings()
Definition: ParserOutput.php:664
ParserOutput\initFromJson
initFromJson(array $jsonData)
Initialize member fields from an array returned by jsonSerialize().
Definition: ParserOutput.php:1786