MediaWiki  master
ParserOptions.php
Go to the documentation of this file.
1 <?php
28 use Wikimedia\ScopedCallback;
29 
46 
52  private static $defaults = null;
53 
58  private static $lazyOptions = null;
59 
64  private static $initialLazyOptions = [
65  'dateformat' => [ __CLASS__, 'initDateFormat' ],
66  'speculativeRevId' => [ __CLASS__, 'initSpeculativeRevId' ],
67  'speculativePageId' => [ __CLASS__, 'initSpeculativePageId' ],
68  ];
69 
74  private static $cacheVaryingOptionsHash = null;
75 
81  'dateformat' => true,
82  'numberheadings' => true,
83  'thumbsize' => true,
84  'printable' => true,
85  'userlang' => true,
86  ];
87 
93  private static $callbacks = [
94  'currentRevisionRecordCallback' => true,
95  'templateCallback' => true,
96  'speculativeRevIdCallback' => true,
97  'speculativePageIdCallback' => true,
98  ];
99 
104  private $options;
105 
111  private $mTimestamp;
112 
118  private $mUser;
119 
125  private $onAccessCallback = null;
126 
133  private $redirectTarget = null;
134 
138  private $mExtraKey = '';
139 
146  public function getOption( $name ) {
147  if ( !array_key_exists( $name, $this->options ) ) {
148  throw new InvalidArgumentException( "Unknown parser option $name" );
149  }
150 
151  $this->lazyLoadOption( $name );
152  $this->optionUsed( $name );
153  return $this->options[$name];
154  }
155 
159  private function lazyLoadOption( $name ) {
161  if ( isset( $lazyOptions[$name] ) && $this->options[$name] === null ) {
162  $this->options[$name] = call_user_func( $lazyOptions[$name], $this, $name );
163  }
164  }
165 
177  public static function getLazyOptions(): array {
178  return self::$lazyOptions;
179  }
180 
189  private static function getCacheVaryingOptionsHash(): array {
190  // Trigger a call to the 'ParserOptionsRegister' hook if it hasn't
191  // already been called.
192  if ( self::$cacheVaryingOptionsHash === null ) {
194  }
196  }
197 
206  public function setOption( $name, $value ) {
207  if ( !array_key_exists( $name, $this->options ) ) {
208  throw new InvalidArgumentException( "Unknown parser option $name" );
209  }
210  $old = $this->options[$name];
211  $this->options[$name] = $value;
212  return $old;
213  }
214 
223  protected function setOptionLegacy( $name, $value ) {
224  if ( !array_key_exists( $name, $this->options ) ) {
225  throw new InvalidArgumentException( "Unknown parser option $name" );
226  }
227  return wfSetVar( $this->options[$name], $value );
228  }
229 
238  public function getInterwikiMagic() {
239  return $this->getOption( 'interwikiMagic' );
240  }
241 
247  public function setInterwikiMagic( $x ) {
248  return $this->setOptionLegacy( 'interwikiMagic', $x );
249  }
250 
255  public function getAllowExternalImages() {
256  return $this->getOption( 'allowExternalImages' );
257  }
258 
266  public function setAllowExternalImages( $x ) {
267  wfDeprecated( __METHOD__, '1.35' );
268  return $this->setOptionLegacy( 'allowExternalImages', $x );
269  }
270 
278  public function getAllowExternalImagesFrom() {
279  return $this->getOption( 'allowExternalImagesFrom' );
280  }
281 
292  public function setAllowExternalImagesFrom( $x ) {
293  wfDeprecated( __METHOD__, '1.35' );
294  return $this->setOptionLegacy( 'allowExternalImagesFrom', $x );
295  }
296 
301  public function getEnableImageWhitelist() {
302  return $this->getOption( 'enableImageWhitelist' );
303  }
304 
312  public function setEnableImageWhitelist( $x ) {
313  wfDeprecated( __METHOD__, '1.35' );
314  return $this->setOptionLegacy( 'enableImageWhitelist', $x );
315  }
316 
321  public function getNumberHeadings() {
322  return $this->getOption( 'numberheadings' );
323  }
324 
330  public function setNumberHeadings( $x ) {
331  return $this->setOptionLegacy( 'numberheadings', $x );
332  }
333 
338  public function getAllowSpecialInclusion() {
339  return $this->getOption( 'allowSpecialInclusion' );
340  }
341 
347  public function setAllowSpecialInclusion( $x ) {
348  return $this->setOptionLegacy( 'allowSpecialInclusion', $x );
349  }
350 
357  public function setTidy( $x ) {
358  wfDeprecated( __METHOD__, '1.35' );
359  // This has no effect.
360  return null;
361  }
362 
367  public function getInterfaceMessage() {
368  return $this->getOption( 'interfaceMessage' );
369  }
370 
376  public function setInterfaceMessage( $x ) {
377  return $this->setOptionLegacy( 'interfaceMessage', $x );
378  }
379 
384  public function getTargetLanguage() {
385  return $this->getOption( 'targetLanguage' );
386  }
387 
393  public function setTargetLanguage( $x ) {
394  return $this->setOption( 'targetLanguage', $x );
395  }
396 
401  public function getMaxIncludeSize() {
402  return $this->getOption( 'maxIncludeSize' );
403  }
404 
410  public function setMaxIncludeSize( $x ) {
411  return $this->setOptionLegacy( 'maxIncludeSize', $x );
412  }
413 
418  public function getMaxPPNodeCount() {
419  return $this->getOption( 'maxPPNodeCount' );
420  }
421 
427  public function setMaxPPNodeCount( $x ) {
428  return $this->setOptionLegacy( 'maxPPNodeCount', $x );
429  }
430 
435  public function getMaxPPExpandDepth() {
436  return $this->getOption( 'maxPPExpandDepth' );
437  }
438 
443  public function getMaxTemplateDepth() {
444  return $this->getOption( 'maxTemplateDepth' );
445  }
446 
452  public function setMaxTemplateDepth( $x ) {
453  return $this->setOptionLegacy( 'maxTemplateDepth', $x );
454  }
455 
462  return $this->getOption( 'expensiveParserFunctionLimit' );
463  }
464 
471  public function setExpensiveParserFunctionLimit( $x ) {
472  return $this->setOptionLegacy( 'expensiveParserFunctionLimit', $x );
473  }
474 
480  public function getRemoveComments() {
481  return $this->getOption( 'removeComments' );
482  }
483 
490  public function setRemoveComments( $x ) {
491  return $this->setOptionLegacy( 'removeComments', $x );
492  }
493 
498  public function getEnableLimitReport() {
499  return $this->getOption( 'enableLimitReport' );
500  }
501 
507  public function enableLimitReport( $x = true ) {
508  return $this->setOptionLegacy( 'enableLimitReport', $x );
509  }
510 
516  public function getCleanSignatures() {
517  return $this->getOption( 'cleanSignatures' );
518  }
519 
526  public function setCleanSignatures( $x ) {
527  return $this->setOptionLegacy( 'cleanSignatures', $x );
528  }
529 
534  public function getExternalLinkTarget() {
535  return $this->getOption( 'externalLinkTarget' );
536  }
537 
543  public function setExternalLinkTarget( $x ) {
544  return $this->setOptionLegacy( 'externalLinkTarget', $x );
545  }
546 
551  public function getDisableContentConversion() {
552  return $this->getOption( 'disableContentConversion' );
553  }
554 
560  public function disableContentConversion( $x = true ) {
561  return $this->setOptionLegacy( 'disableContentConversion', $x );
562  }
563 
568  public function getDisableTitleConversion() {
569  return $this->getOption( 'disableTitleConversion' );
570  }
571 
577  public function disableTitleConversion( $x = true ) {
578  return $this->setOptionLegacy( 'disableTitleConversion', $x );
579  }
580 
585  public function getThumbSize() {
586  return $this->getOption( 'thumbsize' );
587  }
588 
594  public function setThumbSize( $x ) {
595  return $this->setOptionLegacy( 'thumbsize', $x );
596  }
597 
602  public function getStubThreshold() {
603  return $this->getOption( 'stubthreshold' );
604  }
605 
611  public function setStubThreshold( $x ) {
612  return $this->setOptionLegacy( 'stubthreshold', $x );
613  }
614 
619  public function getIsPreview() {
620  return $this->getOption( 'isPreview' );
621  }
622 
628  public function setIsPreview( $x ) {
629  return $this->setOptionLegacy( 'isPreview', $x );
630  }
631 
636  public function getIsSectionPreview() {
637  return $this->getOption( 'isSectionPreview' );
638  }
639 
645  public function setIsSectionPreview( $x ) {
646  return $this->setOptionLegacy( 'isSectionPreview', $x );
647  }
648 
653  public function getIsPrintable() {
654  return $this->getOption( 'printable' );
655  }
656 
662  public function setIsPrintable( $x ) {
663  return $this->setOptionLegacy( 'printable', $x );
664  }
665 
670  public function getPreSaveTransform() {
671  return $this->getOption( 'preSaveTransform' );
672  }
673 
679  public function setPreSaveTransform( $x ) {
680  return $this->setOptionLegacy( 'preSaveTransform', $x );
681  }
682 
687  public function getDateFormat() {
688  return $this->getOption( 'dateformat' );
689  }
690 
696  private static function initDateFormat( ParserOptions $popt ) {
697  return $popt->getUser()->getDatePreference();
698  }
699 
705  public function setDateFormat( $x ) {
706  return $this->setOptionLegacy( 'dateformat', $x );
707  }
708 
726  public function getUserLangObj() {
727  return $this->getOption( 'userlang' );
728  }
729 
742  public function getUserLang() {
743  return $this->getUserLangObj()->getCode();
744  }
745 
751  public function setUserLang( $x ) {
752  if ( is_string( $x ) ) {
753  $x = MediaWikiServices::getInstance()->getLanguageFactory()->getLanguage( $x );
754  }
755 
756  return $this->setOptionLegacy( 'userlang', $x );
757  }
758 
764  public function getMagicISBNLinks() {
765  return $this->getOption( 'magicISBNLinks' );
766  }
767 
773  public function getMagicPMIDLinks() {
774  return $this->getOption( 'magicPMIDLinks' );
775  }
776 
782  public function getMagicRFCLinks() {
783  return $this->getOption( 'magicRFCLinks' );
784  }
785 
800  public function getAllowUnsafeRawHtml() {
801  return $this->getOption( 'allowUnsafeRawHtml' );
802  }
803 
812  public function setAllowUnsafeRawHtml( $x ) {
813  return $this->setOptionLegacy( 'allowUnsafeRawHtml', $x );
814  }
815 
821  public function getWrapOutputClass() {
822  return $this->getOption( 'wrapclass' );
823  }
824 
832  public function setWrapOutputClass( $className ) {
833  if ( $className === true ) { // DWIM, they probably want the default class name
834  $className = 'mw-parser-output';
835  }
836  if ( $className === false ) {
837  wfDeprecated( __METHOD__ . '( false )', '1.31' );
838  }
839  return $this->setOption( 'wrapclass', $className );
840  }
841 
849  return $this->getOption( 'currentRevisionRecordCallback' );
850  }
851 
859  public function setCurrentRevisionRecordCallback( $x ) {
860  return $this->setOption( 'currentRevisionRecordCallback', $x );
861  }
862 
867  public function getTemplateCallback() {
868  return $this->getOption( 'templateCallback' );
869  }
870 
876  public function setTemplateCallback( $x ) {
877  return $this->setOptionLegacy( 'templateCallback', $x );
878  }
879 
890  public function getSpeculativeRevId() {
891  return $this->getOption( 'speculativeRevId' );
892  }
893 
904  public function getSpeculativePageId() {
905  return $this->getOption( 'speculativePageId' );
906  }
907 
914  private static function initSpeculativeRevId( ParserOptions $popt ) {
915  $cb = $popt->getOption( 'speculativeRevIdCallback' );
916  $id = $cb ? $cb() : null;
917 
918  // returning null would result in this being re-called every access
919  return $id ?? false;
920  }
921 
928  private static function initSpeculativePageId( ParserOptions $popt ) {
929  $cb = $popt->getOption( 'speculativePageIdCallback' );
930  $id = $cb ? $cb() : null;
931 
932  // returning null would result in this being re-called every access
933  return $id ?? false;
934  }
935 
942  public function setSpeculativeRevIdCallback( $x ) {
943  $this->setOption( 'speculativeRevId', null ); // reset
944  return $this->setOption( 'speculativeRevIdCallback', $x );
945  }
946 
953  public function setSpeculativePageIdCallback( $x ) {
954  $this->setOption( 'speculativePageId', null ); // reset
955  return $this->setOption( 'speculativePageIdCallback', $x );
956  }
957 
962  public function getTimestamp() {
963  if ( !isset( $this->mTimestamp ) ) {
964  $this->mTimestamp = wfTimestampNow();
965  }
966  return $this->mTimestamp;
967  }
968 
974  public function setTimestamp( $x ) {
975  return wfSetVar( $this->mTimestamp, $x );
976  }
977 
986  public function setRedirectTarget( $title ) {
987  $this->redirectTarget = $title;
988  }
989 
996  public function getRedirectTarget() {
997  return $this->redirectTarget;
998  }
999 
1006  public function addExtraKey( $key ) {
1007  $this->mExtraKey .= '!' . $key;
1008  }
1009 
1015  public function getUser() {
1016  return MediaWikiServices::getInstance()
1017  ->getUserFactory()
1018  ->newFromUserIdentity( $this->mUser );
1019  }
1020 
1026  public function getUserIdentity(): UserIdentity {
1027  return $this->mUser;
1028  }
1029 
1036  public function __construct( UserIdentity $user, $lang = null ) {
1037  if ( $lang === null ) {
1038  global $wgLang;
1040  $lang = $wgLang;
1041  }
1042  $this->initialiseFromUser( $user, $lang );
1043  }
1044 
1052  public static function newFromAnon() {
1053  return new ParserOptions( new User,
1054  MediaWikiServices::getInstance()->getContentLanguage() );
1055  }
1056 
1066  public static function newFromUser( $user ) {
1067  return new ParserOptions( $user );
1068  }
1069 
1079  public static function newFromUserAndLang( UserIdentity $user, Language $lang ) {
1080  return new ParserOptions( $user, $lang );
1081  }
1082 
1091  public static function newFromContext( IContextSource $context ) {
1092  return new ParserOptions( $context->getUser(), $context->getLanguage() );
1093  }
1094 
1113  public static function newCanonical( $context, $userLang = null ) {
1114  if ( $context instanceof IContextSource ) {
1115  $ret = self::newFromContext( $context );
1116  } elseif ( $context === 'canonical' ) {
1117  $ret = self::newFromAnon();
1118  } elseif ( $context instanceof UserIdentity ) {
1119  $ret = new self( $context, $userLang );
1120  } else {
1121  throw new InvalidArgumentException(
1122  '$context must be an IContextSource, the string "canonical", or a UserIdentity'
1123  );
1124  }
1125 
1126  foreach ( self::getCanonicalOverrides() as $k => $v ) {
1127  $ret->setOption( $k, $v );
1128  }
1129  return $ret;
1130  }
1131 
1136  public static function clearStaticCache() {
1137  if ( !defined( 'MW_PHPUNIT_TEST' ) ) {
1138  throw new RuntimeException( __METHOD__ . ' is just for testing' );
1139  }
1140  self::$defaults = null;
1141  self::$lazyOptions = null;
1142  self::$cacheVaryingOptionsHash = null;
1143  }
1144 
1154  private static function getDefaults() {
1160  $services = MediaWikiServices::getInstance();
1161  $languageConverterFactory = $services->getLanguageConverterFactory();
1162  $userOptionsLookup = $services->getUserOptionsLookup();
1163  $contentLanguage = $services->getContentLanguage();
1164 
1165  if ( self::$defaults === null ) {
1166  // *UPDATE* ParserOptions::matches() if any of this changes as needed
1167  self::$defaults = [
1168  'dateformat' => null,
1169  'interfaceMessage' => false,
1170  'targetLanguage' => null,
1171  'removeComments' => true,
1172  'enableLimitReport' => false,
1173  'preSaveTransform' => true,
1174  'isPreview' => false,
1175  'isSectionPreview' => false,
1176  'printable' => false,
1177  'allowUnsafeRawHtml' => true,
1178  'wrapclass' => 'mw-parser-output',
1179  'currentRevisionRecordCallback' => [ Parser::class, 'statelessFetchRevisionRecord' ],
1180  'templateCallback' => [ Parser::class, 'statelessFetchTemplate' ],
1181  'speculativeRevIdCallback' => null,
1182  'speculativeRevId' => null,
1183  'speculativePageIdCallback' => null,
1184  'speculativePageId' => null,
1185  ];
1186 
1187  self::$cacheVaryingOptionsHash = self::$initialCacheVaryingOptionsHash;
1188  self::$lazyOptions = self::$initialLazyOptions;
1189 
1190  Hooks::runner()->onParserOptionsRegister(
1191  self::$defaults,
1192  self::$cacheVaryingOptionsHash,
1193  self::$lazyOptions
1194  );
1195 
1196  ksort( self::$cacheVaryingOptionsHash );
1197  }
1198 
1199  // Unit tests depend on being able to modify the globals at will
1200  return self::$defaults + [
1201  'interwikiMagic' => $wgInterwikiMagic,
1202  'allowExternalImages' => $wgAllowExternalImages,
1203  'allowExternalImagesFrom' => $wgAllowExternalImagesFrom,
1204  'enableImageWhitelist' => $wgEnableImageWhitelist,
1205  'allowSpecialInclusion' => $wgAllowSpecialInclusion,
1206  'maxIncludeSize' => $wgMaxArticleSize * 1024,
1207  'maxPPNodeCount' => $wgMaxPPNodeCount,
1208  'maxPPExpandDepth' => $wgMaxPPExpandDepth,
1209  'maxTemplateDepth' => $wgMaxTemplateDepth,
1210  'expensiveParserFunctionLimit' => $wgExpensiveParserFunctionLimit,
1211  'externalLinkTarget' => $wgExternalLinkTarget,
1212  'cleanSignatures' => $wgCleanSignatures,
1213  'disableContentConversion' => $languageConverterFactory->isConversionDisabled(),
1214  'disableTitleConversion' => $languageConverterFactory->isLinkConversionDisabled(),
1215  'magicISBNLinks' => $wgEnableMagicLinks['ISBN'],
1216  'magicPMIDLinks' => $wgEnableMagicLinks['PMID'],
1217  'magicRFCLinks' => $wgEnableMagicLinks['RFC'],
1218  'numberheadings' => $userOptionsLookup->getDefaultOption( 'numberheadings' ),
1219  'thumbsize' => $userOptionsLookup->getDefaultOption( 'thumbsize' ),
1220  'stubthreshold' => 0,
1221  'userlang' => $contentLanguage,
1222  ];
1223  }
1224 
1234  private static function getCanonicalOverrides() {
1236 
1237  return [
1238  'enableLimitReport' => $wgEnableParserLimitReporting,
1239  ];
1240  }
1241 
1248  private function initialiseFromUser( UserIdentity $user, Language $lang ) {
1249  $this->options = self::getDefaults();
1250 
1251  $this->mUser = $user;
1252  $services = MediaWikiServices::getInstance();
1253  $optionsLookup = $services->getUserOptionsLookup();
1254  $this->options['numberheadings'] = $optionsLookup->getOption( $user, 'numberheadings' );
1255  $this->options['thumbsize'] = $optionsLookup->getOption( $user, 'thumbsize' );
1256  $userObj = $services->getUserFactory()->newFromUserIdentity( $user );
1257  $this->options['stubthreshold'] = $userObj->getStubThreshold();
1258  $this->options['userlang'] = $lang;
1259  }
1260 
1270  public function matches( ParserOptions $other ) {
1271  // Compare most options
1272  $options = array_keys( $this->options );
1273  $options = array_diff( $options, [
1274  'enableLimitReport', // only affects HTML comments
1275  'tidy', // Has no effect since 1.35; removed in 1.36
1276  ] );
1277  foreach ( $options as $option ) {
1278  // Resolve any lazy options
1279  $this->lazyLoadOption( $option );
1280  $other->lazyLoadOption( $option );
1281 
1282  $o1 = $this->optionToString( $this->options[$option] );
1283  $o2 = $this->optionToString( $other->options[$option] );
1284  if ( $o1 !== $o2 ) {
1285  return false;
1286  }
1287  }
1288 
1289  // Compare most other fields
1290  foreach ( ( new ReflectionClass( $this ) )->getProperties() as $property ) {
1291  $field = $property->getName();
1292  if ( $property->isStatic() ) {
1293  continue;
1294  }
1295  if ( in_array( $field, [
1296  'options', // Already checked above
1297  'onAccessCallback', // only used for ParserOutput option tracking
1298  ] ) ) {
1299  continue;
1300  }
1301 
1302  if ( !is_object( $this->$field ) && $this->$field !== $other->$field ) {
1303  return false;
1304  }
1305  }
1306 
1307  return true;
1308  }
1309 
1315  public function matchesForCacheKey( ParserOptions $other ) {
1316  foreach ( self::allCacheVaryingOptions() as $option ) {
1317  // Populate any lazy options
1318  $this->lazyLoadOption( $option );
1319  $other->lazyLoadOption( $option );
1320 
1321  $o1 = $this->optionToString( $this->options[$option] );
1322  $o2 = $this->optionToString( $other->options[$option] );
1323  if ( $o1 !== $o2 ) {
1324  return false;
1325  }
1326  }
1327 
1328  return true;
1329  }
1330 
1336  public function registerWatcher( $callback ) {
1337  $this->onAccessCallback = $callback;
1338  }
1339 
1348  public function optionUsed( $optionName ) {
1349  if ( $this->onAccessCallback ) {
1350  call_user_func( $this->onAccessCallback, $optionName );
1351  }
1352  }
1353 
1359  public static function allCacheVaryingOptions() {
1360  return array_keys( array_filter( self::getCacheVaryingOptionsHash() ) );
1361  }
1362 
1368  private function optionToString( $value ) {
1369  if ( $value === true ) {
1370  return '1';
1371  } elseif ( $value === false ) {
1372  return '0';
1373  } elseif ( $value === null ) {
1374  return '';
1375  } elseif ( $value instanceof Language ) {
1376  return $value->getCode();
1377  } elseif ( is_array( $value ) ) {
1378  return '[' . implode( ',', array_map( [ $this, 'optionToString' ], $value ) ) . ']';
1379  } else {
1380  return (string)$value;
1381  }
1382  }
1383 
1396  public function optionsHash( $forOptions, $title = null ) {
1397  global $wgRenderHashAppend;
1398 
1399  $inCacheKey = self::allCacheVaryingOptions();
1400 
1401  // Resolve any lazy options
1402  $lazyOpts = array_intersect( $forOptions,
1403  $inCacheKey, array_keys( self::getLazyOptions() ) );
1404  foreach ( $lazyOpts as $k ) {
1405  $this->lazyLoadOption( $k );
1406  }
1407 
1410 
1411  // We only include used options with non-canonical values in the key
1412  // so adding a new option doesn't invalidate the entire parser cache.
1413  // The drawback to this is that changing the default value of an option
1414  // requires manual invalidation of existing cache entries, as mentioned
1415  // in the docs on the relevant methods and hooks.
1416  $values = [];
1417  foreach ( array_intersect( $inCacheKey, $forOptions ) as $option ) {
1418  $v = $this->optionToString( $options[$option] );
1419  $d = $this->optionToString( $defaults[$option] );
1420  if ( $v !== $d ) {
1421  $values[] = "$option=$v";
1422  }
1423  }
1424 
1425  $confstr = $values ? implode( '!', $values ) : 'canonical';
1426 
1427  // add in language specific options, if any
1428  // @todo FIXME: This is just a way of retrieving the url/user preferred variant
1429  $services = MediaWikiServices::getInstance();
1430  $lang = $title ? $title->getPageLanguage() : $services->getContentLanguage();
1431  $converter = $services->getLanguageConverterFactory()->getLanguageConverter( $lang );
1432  $confstr .= $converter->getExtraHashOptions();
1433 
1434  $confstr .= $wgRenderHashAppend;
1435 
1436  if ( $this->mExtraKey != '' ) {
1437  $confstr .= $this->mExtraKey;
1438  }
1439 
1440  // Give a chance for extensions to modify the hash, if they have
1441  // extra options or other effects on the parser cache.
1442  Hooks::runner()->onPageRenderingHash( $confstr, $this->getUser(), $forOptions );
1443 
1444  // Make it a valid memcached key fragment
1445  $confstr = str_replace( ' ', '_', $confstr );
1446 
1447  return $confstr;
1448  }
1449 
1456  public function isSafeToCache( array $usedOptions = null ) {
1458  $inCacheKey = self::getCacheVaryingOptionsHash();
1459  $usedOptions = $usedOptions ?? array_keys( $this->options );
1460  foreach ( $usedOptions as $option ) {
1461  if ( empty( $inCacheKey[$option] ) && empty( self::$callbacks[$option] ) ) {
1462  $v = $this->optionToString( $this->options[$option] ?? null );
1463  $d = $this->optionToString( $defaults[$option] ?? null );
1464  if ( $v !== $d ) {
1465  return false;
1466  }
1467  }
1468  }
1469  return true;
1470  }
1471 
1482  public function setupFakeRevision( $title, $content, $user ) {
1483  $oldCallback = $this->setCurrentRevisionRecordCallback(
1484  static function (
1485  $titleToCheck, $parser = null ) use ( $title, $content, $user, &$oldCallback
1486  ) {
1487  if ( $titleToCheck->equals( $title ) ) {
1488  $revRecord = new MutableRevisionRecord( $title );
1489  $revRecord->setContent( SlotRecord::MAIN, $content )
1490  ->setUser( $user )
1491  ->setTimestamp( MWTimestamp::now( TS_MW ) )
1492  ->setPageId( $title->getArticleID() )
1493  ->setParentId( $title->getLatestRevID() );
1494  return $revRecord;
1495  } else {
1496  return call_user_func( $oldCallback, $titleToCheck, $parser );
1497  }
1498  }
1499  );
1500 
1501  global $wgHooks;
1502  $wgHooks['TitleExists'][] =
1503  static function ( $titleToCheck, &$exists ) use ( $title ) {
1504  if ( $titleToCheck->equals( $title ) ) {
1505  $exists = true;
1506  }
1507  };
1508  end( $wgHooks['TitleExists'] );
1509  $key = key( $wgHooks['TitleExists'] );
1510  $linkCache = MediaWikiServices::getInstance()->getLinkCache();
1511  $linkCache->clearBadLink( $title->getPrefixedDBkey() );
1512  return new ScopedCallback( static function () use ( $title, $key, $linkCache ) {
1513  global $wgHooks;
1514  unset( $wgHooks['TitleExists'][$key] );
1515  $linkCache->clearLink( $title );
1516  } );
1517  }
1518 }
1519 
ParserOptions\setMaxIncludeSize
setMaxIncludeSize( $x)
Maximum size of template expansions, in bytes.
Definition: ParserOptions.php:410
ParserOptions\getMagicPMIDLinks
getMagicPMIDLinks()
Are magic PMID links enabled?
Definition: ParserOptions.php:773
ParserOptions
Set options of the Parser.
Definition: ParserOptions.php:45
ParserOptions\setOptionLegacy
setOptionLegacy( $name, $value)
Legacy implementation.
Definition: ParserOptions.php:223
ParserOptions\getAllowExternalImagesFrom
getAllowExternalImagesFrom()
External images to allow.
Definition: ParserOptions.php:278
ParserOptions\getWrapOutputClass
getWrapOutputClass()
Class to use to wrap output from Parser::parse()
Definition: ParserOptions.php:821
ParserOptions\getExpensiveParserFunctionLimit
getExpensiveParserFunctionLimit()
Maximum number of calls per parse to expensive parser functions.
Definition: ParserOptions.php:461
ParserOptions\setTidy
setTidy( $x)
Use tidy to cleanup output HTML?
Definition: ParserOptions.php:357
ParserOptions\getIsSectionPreview
getIsSectionPreview()
Parsing the page for a "preview" operation on a single section?
Definition: ParserOptions.php:636
$wgMaxArticleSize
$wgMaxArticleSize
Maximum article size in kibibytes.
Definition: DefaultSettings.php:2656
ParserOptions\getRemoveComments
getRemoveComments()
Remove HTML comments.
Definition: ParserOptions.php:480
ParserOptions\setAllowUnsafeRawHtml
setAllowUnsafeRawHtml( $x)
If the wiki is configured to allow raw html ($wgRawHtml = true) is it allowed in the specific case of...
Definition: ParserOptions.php:812
ParserOptions\disableContentConversion
disableContentConversion( $x=true)
Whether content conversion should be disabled.
Definition: ParserOptions.php:560
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:186
$lang
if(!isset( $args[0])) $lang
Definition: testCompression.php:37
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:1512
$wgMaxTemplateDepth
$wgMaxTemplateDepth
Maximum recursion depth for templates within templates.
Definition: DefaultSettings.php:4892
ParserOptions\getIsPreview
getIsPreview()
Parsing the page for a "preview" operation?
Definition: ParserOptions.php:619
ParserOptions\getDisableTitleConversion
getDisableTitleConversion()
Whether title conversion should be disabled.
Definition: ParserOptions.php:568
ParserOptions\setAllowExternalImages
setAllowExternalImages( $x)
Allow all external images inline?
Definition: ParserOptions.php:266
ParserOptions\setTemplateCallback
setTemplateCallback( $x)
Callback for template fetching; first argument to call_user_func().
Definition: ParserOptions.php:876
ParserOptions\setIsPreview
setIsPreview( $x)
Parsing the page for a "preview" operation?
Definition: ParserOptions.php:628
ParserOptions\__construct
__construct(UserIdentity $user, $lang=null)
Definition: ParserOptions.php:1036
ParserOptions\setTargetLanguage
setTargetLanguage( $x)
Target language for the parse.
Definition: ParserOptions.php:393
ParserOptions\getInterfaceMessage
getInterfaceMessage()
Parsing an interface message?
Definition: ParserOptions.php:367
ParserOptions\setIsSectionPreview
setIsSectionPreview( $x)
Parsing the page for a "preview" operation on a single section?
Definition: ParserOptions.php:645
ParserOptions\getSpeculativeRevId
getSpeculativeRevId()
A guess for {{REVISIONID}}, calculated using the callback provided via setSpeculativeRevIdCallback().
Definition: ParserOptions.php:890
ParserOptions\newFromAnon
static newFromAnon()
Get a ParserOptions object for an anonymous user.
Definition: ParserOptions.php:1052
ParserOptions\setEnableImageWhitelist
setEnableImageWhitelist( $x)
Use the on-wiki external image whitelist?
Definition: ParserOptions.php:312
ParserOptions\newFromUserAndLang
static newFromUserAndLang(UserIdentity $user, Language $lang)
Get a ParserOptions object from a given user and language.
Definition: ParserOptions.php:1079
ParserOptions\setWrapOutputClass
setWrapOutputClass( $className)
CSS class to use to wrap output from Parser::parse()
Definition: ParserOptions.php:832
ParserOptions\setSpeculativeRevIdCallback
setSpeculativeRevIdCallback( $x)
Callback to generate a guess for {{REVISIONID}}.
Definition: ParserOptions.php:942
ParserOptions\disableTitleConversion
disableTitleConversion( $x=true)
Whether title conversion should be disabled.
Definition: ParserOptions.php:577
ParserOptions\initDateFormat
static initDateFormat(ParserOptions $popt)
Lazy initializer for dateFormat.
Definition: ParserOptions.php:696
ParserOptions\getIsPrintable
getIsPrintable()
Parsing the printable version of the page?
Definition: ParserOptions.php:653
ParserOptions\setMaxTemplateDepth
setMaxTemplateDepth( $x)
Maximum recursion depth for templates within templates.
Definition: ParserOptions.php:452
$wgLang
$wgLang
Definition: Setup.php:807
MediaWiki\User\UserIdentity
Interface for objects representing user identity.
Definition: UserIdentity.php:39
ParserOptions\getMagicRFCLinks
getMagicRFCLinks()
Are magic RFC links enabled?
Definition: ParserOptions.php:782
ParserOptions\getUserLangObj
getUserLangObj()
Get the user language used by the parser for this page and split the parser cache.
Definition: ParserOptions.php:726
ParserOptions\registerWatcher
registerWatcher( $callback)
Registers a callback for tracking which ParserOptions which are used.
Definition: ParserOptions.php:1336
ParserOptions\setupFakeRevision
setupFakeRevision( $title, $content, $user)
Sets a hook to force that a page exists, and sets a current revision callback to return a revision wi...
Definition: ParserOptions.php:1482
ParserOptions\getDateFormat
getDateFormat()
Date format index.
Definition: ParserOptions.php:687
ParserOptions\setOption
setOption( $name, $value)
Set an option, generically.
Definition: ParserOptions.php:206
ParserOptions\initSpeculativeRevId
static initSpeculativeRevId(ParserOptions $popt)
Callback registered with ParserOptions::$lazyOptions, triggered by getSpeculativeRevId().
Definition: ParserOptions.php:914
ParserOptions\setNumberHeadings
setNumberHeadings( $x)
Automatically number headings?
Definition: ParserOptions.php:330
$wgHooks
$wgHooks
Global list of hooks.
Definition: DefaultSettings.php:8682
ParserOptions\getCanonicalOverrides
static getCanonicalOverrides()
Get "canonical" non-default option values.
Definition: ParserOptions.php:1234
wfDeprecated
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Logs a warning that $function is deprecated.
Definition: GlobalFunctions.php:996
ParserOptions\getRedirectTarget
getRedirectTarget()
Get the previously-set redirect target.
Definition: ParserOptions.php:996
ParserOptions\$mUser
UserIdentity $mUser
Stored user object.
Definition: ParserOptions.php:118
ParserOptions\setUserLang
setUserLang( $x)
Set the user language used by the parser for this page and split the parser cache.
Definition: ParserOptions.php:751
ParserOptions\getAllowSpecialInclusion
getAllowSpecialInclusion()
Allow inclusion of special pages?
Definition: ParserOptions.php:338
$wgAllowExternalImagesFrom
$wgAllowExternalImagesFrom
If the above is false, you can specify an exception here.
Definition: DefaultSettings.php:4938
ParserOptions\getMaxIncludeSize
getMaxIncludeSize()
Maximum size of template expansions, in bytes.
Definition: ParserOptions.php:401
ParserOptions\$mTimestamp
string null $mTimestamp
Timestamp used for {{CURRENTDAY}} etc.
Definition: ParserOptions.php:111
$wgExpensiveParserFunctionLimit
$wgExpensiveParserFunctionLimit
Maximum number of calls per parse to expensive parser functions such as PAGESINCATEGORY.
Definition: DefaultSettings.php:5061
ParserOptions\setThumbSize
setThumbSize( $x)
Thumb size preferred by the user.
Definition: ParserOptions.php:594
ParserOptions\getEnableImageWhitelist
getEnableImageWhitelist()
Use the on-wiki external image whitelist?
Definition: ParserOptions.php:301
$wgInterwikiMagic
$wgInterwikiMagic
Treat language links as magic connectors, not inline links.
Definition: DefaultSettings.php:3467
ParserOptions\setExternalLinkTarget
setExternalLinkTarget( $x)
Target attribute for external links.
Definition: ParserOptions.php:543
ParserOptions\setDateFormat
setDateFormat( $x)
Date format index.
Definition: ParserOptions.php:705
ParserOptions\newCanonical
static newCanonical( $context, $userLang=null)
Creates a "canonical" ParserOptions object.
Definition: ParserOptions.php:1113
ParserOptions\getTargetLanguage
getTargetLanguage()
Target language for the parse.
Definition: ParserOptions.php:384
$title
$title
Definition: testCompression.php:38
ParserOptions\initSpeculativePageId
static initSpeculativePageId(ParserOptions $popt)
Callback registered with ParserOptions::$lazyOptions, triggered by getSpeculativePageId().
Definition: ParserOptions.php:928
ParserOptions\setAllowSpecialInclusion
setAllowSpecialInclusion( $x)
Allow inclusion of special pages?
Definition: ParserOptions.php:347
$wgMaxPPExpandDepth
$wgMaxPPExpandDepth
Definition: DefaultSettings.php:4897
ParserOptions\getDefaults
static getDefaults()
Get default option values.
Definition: ParserOptions.php:1154
ParserOptions\getExternalLinkTarget
getExternalLinkTarget()
Target attribute for external links.
Definition: ParserOptions.php:534
ParserOptions\$onAccessCallback
callable null $onAccessCallback
Function to be called when an option is accessed.
Definition: ParserOptions.php:125
$wgEnableMagicLinks
$wgEnableMagicLinks
Enable the magic links feature of automatically turning ISBN xxx, PMID xxx, RFC xxx into links.
Definition: DefaultSettings.php:5086
wfTimestampNow
wfTimestampNow()
Convenience function; returns MediaWiki timestamp for the present time.
Definition: GlobalFunctions.php:1721
ParserOptions\getStubThreshold
getStubThreshold()
Thumb size preferred by the user.
Definition: ParserOptions.php:602
$wgExternalLinkTarget
$wgExternalLinkTarget
Set a default target for external links, e.g.
Definition: DefaultSettings.php:5008
ParserOptions\$options
array $options
Current values for all options that are relevant for caching.
Definition: ParserOptions.php:104
ParserOptions\getUserLang
getUserLang()
Same as getUserLangObj() but returns a string instead.
Definition: ParserOptions.php:742
ParserOptions\getPreSaveTransform
getPreSaveTransform()
Transform wiki markup when saving the page?
Definition: ParserOptions.php:670
ParserOptions\setStubThreshold
setStubThreshold( $x)
Thumb size preferred by the user.
Definition: ParserOptions.php:611
ParserOptions\$lazyOptions
static callable[] null $lazyOptions
Lazy-loaded options.
Definition: ParserOptions.php:58
ParserOptions\getOption
getOption( $name)
Fetch an option and track that is was accessed.
Definition: ParserOptions.php:146
ParserOptions\$mExtraKey
$mExtraKey
Appended to the options hash.
Definition: ParserOptions.php:138
ParserOptions\getAllowUnsafeRawHtml
getAllowUnsafeRawHtml()
If the wiki is configured to allow raw html ($wgRawHtml = true) is it allowed in the specific case of...
Definition: ParserOptions.php:800
ParserOptions\getDisableContentConversion
getDisableContentConversion()
Whether content conversion should be disabled.
Definition: ParserOptions.php:551
ParserOptions\optionToString
optionToString( $value)
Convert an option to a string value.
Definition: ParserOptions.php:1368
ParserOptions\matchesForCacheKey
matchesForCacheKey(ParserOptions $other)
Definition: ParserOptions.php:1315
ParserOptions\optionUsed
optionUsed( $optionName)
Called when an option is accessed.
Definition: ParserOptions.php:1348
$content
$content
Definition: router.php:76
ParserOptions\getSpeculativePageId
getSpeculativePageId()
A guess for {{PAGEID}}, calculated using the callback provided via setSpeculativeRevPageCallback().
Definition: ParserOptions.php:904
ParserOptions\setTimestamp
setTimestamp( $x)
Timestamp used for {{CURRENTDAY}} etc.
Definition: ParserOptions.php:974
ParserOptions\setSpeculativePageIdCallback
setSpeculativePageIdCallback( $x)
Callback to generate a guess for {{PAGEID}}.
Definition: ParserOptions.php:953
ParserOptions\setCleanSignatures
setCleanSignatures( $x)
Clean up signature texts?
Definition: ParserOptions.php:526
ParserOptions\newFromContext
static newFromContext(IContextSource $context)
Get a ParserOptions object from a IContextSource object.
Definition: ParserOptions.php:1091
MediaWiki\Revision\MutableRevisionRecord
Definition: MutableRevisionRecord.php:45
Hooks\runner
static runner()
Get a HookRunner instance for calling hooks using the new interfaces.
Definition: Hooks.php:173
$wgEnableParserLimitReporting
$wgEnableParserLimitReporting
Whether to include the NewPP limit report as a HTML comment.
Definition: DefaultSettings.php:8537
ParserOptions\getTemplateCallback
getTemplateCallback()
Callback for template fetching; first argument to call_user_func().
Definition: ParserOptions.php:867
ParserOptions\$cacheVaryingOptionsHash
static array null $cacheVaryingOptionsHash
Specify options that are included in the cache key.
Definition: ParserOptions.php:74
ParserOptions\setRemoveComments
setRemoveComments( $x)
Remove HTML comments.
Definition: ParserOptions.php:490
ParserOptions\setInterwikiMagic
setInterwikiMagic( $x)
Specify whether to extract interlanguage links.
Definition: ParserOptions.php:247
IContextSource\getUser
getUser()
ParserOptions\lazyLoadOption
lazyLoadOption( $name)
Definition: ParserOptions.php:159
ParserOptions\setRedirectTarget
setRedirectTarget( $title)
Note that setting or changing this does not make the page a redirect or change its target,...
Definition: ParserOptions.php:986
ParserOptions\setExpensiveParserFunctionLimit
setExpensiveParserFunctionLimit( $x)
Maximum number of calls per parse to expensive parser functions.
Definition: ParserOptions.php:471
ParserOptions\getTimestamp
getTimestamp()
Timestamp used for {{CURRENTDAY}} etc.
Definition: ParserOptions.php:962
ParserOptions\setMaxPPNodeCount
setMaxPPNodeCount( $x)
Maximum number of nodes touched by PPFrame::expand()
Definition: ParserOptions.php:427
IContextSource
Interface for objects which can provide a MediaWiki context on request.
Definition: IContextSource.php:58
ParserOptions\getCleanSignatures
getCleanSignatures()
Clean up signature texts?
Definition: ParserOptions.php:516
ParserOptions\getLazyOptions
static getLazyOptions()
Get lazy-loaded options.
Definition: ParserOptions.php:177
$userOptionsLookup
UserOptionsLookup $userOptionsLookup
Definition: ApiWatchlistTrait.php:33
ParserOptions\$redirectTarget
Title null $redirectTarget
If the page being parsed is a redirect, this should hold the redirect target.
Definition: ParserOptions.php:133
ParserOptions\setAllowExternalImagesFrom
setAllowExternalImagesFrom( $x)
External images to allow.
Definition: ParserOptions.php:292
ParserOptions\matches
matches(ParserOptions $other)
Check if these options match that of another options set.
Definition: ParserOptions.php:1270
ParserOptions\enableLimitReport
enableLimitReport( $x=true)
Enable limit report in an HTML comment on output.
Definition: ParserOptions.php:507
Title
Represents a title within MediaWiki.
Definition: Title.php:49
ParserOptions\getInterwikiMagic
getInterwikiMagic()
Whether to extract interlanguage links.
Definition: ParserOptions.php:238
ParserOptions\getUserIdentity
getUserIdentity()
Get the identity of the user for whom the parse is made.
Definition: ParserOptions.php:1026
ParserOptions\setInterfaceMessage
setInterfaceMessage( $x)
Parsing an interface message?
Definition: ParserOptions.php:376
ParserOptions\$defaults
static array null $defaults
Default values for all options that are relevant for caching.
Definition: ParserOptions.php:52
ParserOptions\allCacheVaryingOptions
static allCacheVaryingOptions()
Return all option keys that vary the options hash.
Definition: ParserOptions.php:1359
$wgCleanSignatures
$wgCleanSignatures
If true, removes (by substituting) templates in signatures.
Definition: DefaultSettings.php:4919
ParserOptions\getUser
getUser()
Current user.
Definition: ParserOptions.php:1015
ParserOptions\getThumbSize
getThumbSize()
Thumb size preferred by the user.
Definition: ParserOptions.php:585
ParserOptions\getMagicISBNLinks
getMagicISBNLinks()
Are magic ISBN links enabled?
Definition: ParserOptions.php:764
ParserOptions\getCacheVaryingOptionsHash
static getCacheVaryingOptionsHash()
Get cache varying options, with the name of the option in the key, and a boolean in the value which i...
Definition: ParserOptions.php:189
ParserOptions\setIsPrintable
setIsPrintable( $x)
Parsing the printable version of the page?
Definition: ParserOptions.php:662
ParserOptions\getMaxPPNodeCount
getMaxPPNodeCount()
Maximum number of nodes touched by PPFrame::expand()
Definition: ParserOptions.php:418
$wgRenderHashAppend
$wgRenderHashAppend
Append a configured value to the parser cache and the sitenotice key so that they can be kept separat...
Definition: DefaultSettings.php:3133
ParserOptions\getCurrentRevisionRecordCallback
getCurrentRevisionRecordCallback()
Callback for current revision fetching; first argument to call_user_func().
Definition: ParserOptions.php:848
ParserOptions\getMaxPPExpandDepth
getMaxPPExpandDepth()
Maximum recursion depth in PPFrame::expand()
Definition: ParserOptions.php:435
ParserOptions\clearStaticCache
static clearStaticCache()
Reset static caches.
Definition: ParserOptions.php:1136
ParserOptions\getEnableLimitReport
getEnableLimitReport()
Enable limit report in an HTML comment on output.
Definition: ParserOptions.php:498
ParserOptions\isSafeToCache
isSafeToCache(array $usedOptions=null)
Test whether these options are safe to cache.
Definition: ParserOptions.php:1456
ParserOptions\getNumberHeadings
getNumberHeadings()
Automatically number headings?
Definition: ParserOptions.php:321
ParserOptions\getMaxTemplateDepth
getMaxTemplateDepth()
Maximum recursion depth for templates within templates.
Definition: ParserOptions.php:443
ParserOptions\setPreSaveTransform
setPreSaveTransform( $x)
Transform wiki markup when saving the page?
Definition: ParserOptions.php:679
ParserOptions\$initialCacheVaryingOptionsHash
static array $initialCacheVaryingOptionsHash
Initial inCacheKey options (before hook)
Definition: ParserOptions.php:80
User
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition: User.php:68
ParserOptions\$callbacks
static array $callbacks
Specify pseudo-options that are actually callbacks.
Definition: ParserOptions.php:93
StubObject\unstub
static unstub(&$obj)
Unstubs an object, if it is a stub object.
Definition: StubObject.php:101
ParserOptions\$initialLazyOptions
static callable[] $initialLazyOptions
Initial lazy-loaded options (before hook)
Definition: ParserOptions.php:64
$wgMaxPPNodeCount
$wgMaxPPNodeCount
A complexity limit on template expansion: the maximum number of nodes visited by PPFrame::expand()
Definition: DefaultSettings.php:4884
ParserOptions\setCurrentRevisionRecordCallback
setCurrentRevisionRecordCallback( $x)
Callback for current revision fetching; first argument to call_user_func().
Definition: ParserOptions.php:859
Language
Internationalisation code See https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation for more...
Definition: Language.php:42
ParserOptions\optionsHash
optionsHash( $forOptions, $title=null)
Generate a hash string with the values set on these ParserOptions for the keys given in the array.
Definition: ParserOptions.php:1396
ParserOptions\initialiseFromUser
initialiseFromUser(UserIdentity $user, Language $lang)
Get user options.
Definition: ParserOptions.php:1248
IContextSource\getLanguage
getLanguage()
MediaWiki\Revision\SlotRecord
Value object representing a content slot associated with a page revision.
Definition: SlotRecord.php:40
ParserOptions\getAllowExternalImages
getAllowExternalImages()
Allow all external images inline?
Definition: ParserOptions.php:255
ParserOptions\newFromUser
static newFromUser( $user)
Get a ParserOptions object from a given user.
Definition: ParserOptions.php:1066
$wgAllowExternalImages
$wgAllowExternalImages
Whether to allow inline image pointing to other websites.
Definition: DefaultSettings.php:4924
$wgEnableImageWhitelist
$wgEnableImageWhitelist
If $wgAllowExternalImages is false, you can allow an on-wiki allow list of regular expression fragmen...
Definition: DefaultSettings.php:4951
ParserOptions\addExtraKey
addExtraKey( $key)
Extra key that should be present in the parser cache key.
Definition: ParserOptions.php:1006
$wgAllowSpecialInclusion
$wgAllowSpecialInclusion
Allow special page inclusions such as {{Special:Allpages}}.
Definition: DefaultSettings.php:9138