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  'thumbsize' => true,
83  'printable' => true,
84  'userlang' => true,
85  ];
86 
92  private static $callbacks = [
93  'currentRevisionRecordCallback' => true,
94  'templateCallback' => true,
95  'speculativeRevIdCallback' => true,
96  'speculativePageIdCallback' => true,
97  ];
98 
103  private $options;
104 
110  private $mTimestamp;
111 
117  private $mUser;
118 
124  private $onAccessCallback = null;
125 
132  private $redirectTarget = null;
133 
137  private $mExtraKey = '';
138 
145  public function getOption( $name ) {
146  if ( !array_key_exists( $name, $this->options ) ) {
147  throw new InvalidArgumentException( "Unknown parser option $name" );
148  }
149 
150  $this->lazyLoadOption( $name );
151  $this->optionUsed( $name );
152  return $this->options[$name];
153  }
154 
158  private function lazyLoadOption( $name ) {
160  if ( isset( $lazyOptions[$name] ) && $this->options[$name] === null ) {
161  $this->options[$name] = call_user_func( $lazyOptions[$name], $this, $name );
162  }
163  }
164 
170  private function nullifyLazyOption( array $options ): array {
171  return array_fill_keys( array_keys( self::getLazyOptions() ), null ) + $options;
172  }
173 
185  public static function getLazyOptions(): array {
186  // Trigger a call to the 'ParserOptionsRegister' hook if it hasn't
187  // already been called.
188  if ( self::$lazyOptions === null ) {
190  }
191  return self::$lazyOptions;
192  }
193 
202  private static function getCacheVaryingOptionsHash(): array {
203  // Trigger a call to the 'ParserOptionsRegister' hook if it hasn't
204  // already been called.
205  if ( self::$cacheVaryingOptionsHash === null ) {
207  }
209  }
210 
219  public function setOption( $name, $value ) {
220  if ( !array_key_exists( $name, $this->options ) ) {
221  throw new InvalidArgumentException( "Unknown parser option $name" );
222  }
223  $old = $this->options[$name];
224  $this->options[$name] = $value;
225  return $old;
226  }
227 
236  protected function setOptionLegacy( $name, $value ) {
237  if ( !array_key_exists( $name, $this->options ) ) {
238  throw new InvalidArgumentException( "Unknown parser option $name" );
239  }
240  return wfSetVar( $this->options[$name], $value );
241  }
242 
251  public function getInterwikiMagic() {
252  return $this->getOption( 'interwikiMagic' );
253  }
254 
260  public function setInterwikiMagic( $x ) {
261  return $this->setOptionLegacy( 'interwikiMagic', $x );
262  }
263 
268  public function getAllowExternalImages() {
269  return $this->getOption( 'allowExternalImages' );
270  }
271 
279  public function setAllowExternalImages( $x ) {
280  wfDeprecated( __METHOD__, '1.35' );
281  return $this->setOptionLegacy( 'allowExternalImages', $x );
282  }
283 
291  public function getAllowExternalImagesFrom() {
292  return $this->getOption( 'allowExternalImagesFrom' );
293  }
294 
305  public function setAllowExternalImagesFrom( $x ) {
306  wfDeprecated( __METHOD__, '1.35' );
307  return $this->setOptionLegacy( 'allowExternalImagesFrom', $x );
308  }
309 
314  public function getEnableImageWhitelist() {
315  return $this->getOption( 'enableImageWhitelist' );
316  }
317 
325  public function setEnableImageWhitelist( $x ) {
326  wfDeprecated( __METHOD__, '1.35' );
327  return $this->setOptionLegacy( 'enableImageWhitelist', $x );
328  }
329 
334  public function getAllowSpecialInclusion() {
335  return $this->getOption( 'allowSpecialInclusion' );
336  }
337 
343  public function setAllowSpecialInclusion( $x ) {
344  return $this->setOptionLegacy( 'allowSpecialInclusion', $x );
345  }
346 
351  public function getInterfaceMessage() {
352  return $this->getOption( 'interfaceMessage' );
353  }
354 
360  public function setInterfaceMessage( $x ) {
361  return $this->setOptionLegacy( 'interfaceMessage', $x );
362  }
363 
368  public function getTargetLanguage() {
369  return $this->getOption( 'targetLanguage' );
370  }
371 
377  public function setTargetLanguage( $x ) {
378  return $this->setOption( 'targetLanguage', $x );
379  }
380 
385  public function getMaxIncludeSize() {
386  return $this->getOption( 'maxIncludeSize' );
387  }
388 
394  public function setMaxIncludeSize( $x ) {
395  return $this->setOptionLegacy( 'maxIncludeSize', $x );
396  }
397 
402  public function getMaxPPNodeCount() {
403  return $this->getOption( 'maxPPNodeCount' );
404  }
405 
411  public function setMaxPPNodeCount( $x ) {
412  return $this->setOptionLegacy( 'maxPPNodeCount', $x );
413  }
414 
419  public function getMaxPPExpandDepth() {
420  return $this->getOption( 'maxPPExpandDepth' );
421  }
422 
427  public function getMaxTemplateDepth() {
428  return $this->getOption( 'maxTemplateDepth' );
429  }
430 
436  public function setMaxTemplateDepth( $x ) {
437  return $this->setOptionLegacy( 'maxTemplateDepth', $x );
438  }
439 
446  return $this->getOption( 'expensiveParserFunctionLimit' );
447  }
448 
455  public function setExpensiveParserFunctionLimit( $x ) {
456  return $this->setOptionLegacy( 'expensiveParserFunctionLimit', $x );
457  }
458 
464  public function getRemoveComments() {
465  return $this->getOption( 'removeComments' );
466  }
467 
474  public function setRemoveComments( $x ) {
475  return $this->setOptionLegacy( 'removeComments', $x );
476  }
477 
485  public function getEnableLimitReport() {
486  return false;
487  }
488 
497  public function enableLimitReport( $x = true ) {
498  return false;
499  }
500 
506  public function getCleanSignatures() {
507  return $this->getOption( 'cleanSignatures' );
508  }
509 
516  public function setCleanSignatures( $x ) {
517  return $this->setOptionLegacy( 'cleanSignatures', $x );
518  }
519 
524  public function getExternalLinkTarget() {
525  return $this->getOption( 'externalLinkTarget' );
526  }
527 
533  public function setExternalLinkTarget( $x ) {
534  return $this->setOptionLegacy( 'externalLinkTarget', $x );
535  }
536 
541  public function getDisableContentConversion() {
542  return $this->getOption( 'disableContentConversion' );
543  }
544 
550  public function disableContentConversion( $x = true ) {
551  return $this->setOptionLegacy( 'disableContentConversion', $x );
552  }
553 
558  public function getDisableTitleConversion() {
559  return $this->getOption( 'disableTitleConversion' );
560  }
561 
567  public function disableTitleConversion( $x = true ) {
568  return $this->setOptionLegacy( 'disableTitleConversion', $x );
569  }
570 
575  public function getThumbSize() {
576  return $this->getOption( 'thumbsize' );
577  }
578 
584  public function setThumbSize( $x ) {
585  return $this->setOptionLegacy( 'thumbsize', $x );
586  }
587 
593  public function getStubThreshold() {
594  wfDeprecated( __METHOD__, '1.37' );
595  return 0;
596  }
597 
604  public function setStubThreshold( $x ) {
605  wfDeprecated( __METHOD__, '1.37' );
606  return 0;
607  }
608 
613  public function getIsPreview() {
614  return $this->getOption( 'isPreview' );
615  }
616 
622  public function setIsPreview( $x ) {
623  return $this->setOptionLegacy( 'isPreview', $x );
624  }
625 
630  public function getIsSectionPreview() {
631  return $this->getOption( 'isSectionPreview' );
632  }
633 
639  public function setIsSectionPreview( $x ) {
640  return $this->setOptionLegacy( 'isSectionPreview', $x );
641  }
642 
647  public function getIsPrintable() {
648  return $this->getOption( 'printable' );
649  }
650 
656  public function setIsPrintable( $x ) {
657  return $this->setOptionLegacy( 'printable', $x );
658  }
659 
664  public function getPreSaveTransform() {
665  return $this->getOption( 'preSaveTransform' );
666  }
667 
673  public function setPreSaveTransform( $x ) {
674  return $this->setOptionLegacy( 'preSaveTransform', $x );
675  }
676 
681  public function getDateFormat() {
682  return $this->getOption( 'dateformat' );
683  }
684 
690  private static function initDateFormat( ParserOptions $popt ) {
691  $userFactory = MediaWikiServices::getInstance()->getUserFactory();
692  return $userFactory->newFromUserIdentity( $popt->getUserIdentity() )->getDatePreference();
693  }
694 
700  public function setDateFormat( $x ) {
701  return $this->setOptionLegacy( 'dateformat', $x );
702  }
703 
721  public function getUserLangObj() {
722  return $this->getOption( 'userlang' );
723  }
724 
737  public function getUserLang() {
738  return $this->getUserLangObj()->getCode();
739  }
740 
746  public function setUserLang( $x ) {
747  if ( is_string( $x ) ) {
748  $x = MediaWikiServices::getInstance()->getLanguageFactory()->getLanguage( $x );
749  }
750 
751  return $this->setOptionLegacy( 'userlang', $x );
752  }
753 
759  public function getMagicISBNLinks() {
760  return $this->getOption( 'magicISBNLinks' );
761  }
762 
768  public function getMagicPMIDLinks() {
769  return $this->getOption( 'magicPMIDLinks' );
770  }
771 
777  public function getMagicRFCLinks() {
778  return $this->getOption( 'magicRFCLinks' );
779  }
780 
795  public function getAllowUnsafeRawHtml() {
796  return $this->getOption( 'allowUnsafeRawHtml' );
797  }
798 
807  public function setAllowUnsafeRawHtml( $x ) {
808  return $this->setOptionLegacy( 'allowUnsafeRawHtml', $x );
809  }
810 
816  public function getWrapOutputClass() {
817  return $this->getOption( 'wrapclass' );
818  }
819 
827  public function setWrapOutputClass( $className ) {
828  if ( $className === true ) { // DWIM, they probably want the default class name
829  $className = 'mw-parser-output';
830  }
831  if ( $className === false ) {
832  wfDeprecated( __METHOD__ . '( false )', '1.31' );
833  }
834  return $this->setOption( 'wrapclass', $className );
835  }
836 
844  return $this->getOption( 'currentRevisionRecordCallback' );
845  }
846 
854  public function setCurrentRevisionRecordCallback( $x ) {
855  return $this->setOption( 'currentRevisionRecordCallback', $x );
856  }
857 
862  public function getTemplateCallback() {
863  return $this->getOption( 'templateCallback' );
864  }
865 
871  public function setTemplateCallback( $x ) {
872  return $this->setOptionLegacy( 'templateCallback', $x );
873  }
874 
885  public function getSpeculativeRevId() {
886  return $this->getOption( 'speculativeRevId' );
887  }
888 
899  public function getSpeculativePageId() {
900  return $this->getOption( 'speculativePageId' );
901  }
902 
909  private static function initSpeculativeRevId( ParserOptions $popt ) {
910  $cb = $popt->getOption( 'speculativeRevIdCallback' );
911  $id = $cb ? $cb() : null;
912 
913  // returning null would result in this being re-called every access
914  return $id ?? false;
915  }
916 
923  private static function initSpeculativePageId( ParserOptions $popt ) {
924  $cb = $popt->getOption( 'speculativePageIdCallback' );
925  $id = $cb ? $cb() : null;
926 
927  // returning null would result in this being re-called every access
928  return $id ?? false;
929  }
930 
937  public function setSpeculativeRevIdCallback( $x ) {
938  $this->setOption( 'speculativeRevId', null ); // reset
939  return $this->setOption( 'speculativeRevIdCallback', $x );
940  }
941 
948  public function setSpeculativePageIdCallback( $x ) {
949  $this->setOption( 'speculativePageId', null ); // reset
950  return $this->setOption( 'speculativePageIdCallback', $x );
951  }
952 
957  public function getTimestamp() {
958  if ( !isset( $this->mTimestamp ) ) {
959  $this->mTimestamp = wfTimestampNow();
960  }
961  return $this->mTimestamp;
962  }
963 
969  public function setTimestamp( $x ) {
970  return wfSetVar( $this->mTimestamp, $x );
971  }
972 
981  public function setRedirectTarget( $title ) {
982  $this->redirectTarget = $title;
983  }
984 
991  public function getRedirectTarget() {
992  return $this->redirectTarget;
993  }
994 
1001  public function addExtraKey( $key ) {
1002  $this->mExtraKey .= '!' . $key;
1003  }
1004 
1010  public function getUserIdentity(): UserIdentity {
1011  return $this->mUser;
1012  }
1013 
1018  public function __construct( UserIdentity $user, $lang = null ) {
1019  if ( $lang === null ) {
1020  global $wgLang;
1022  $lang = $wgLang;
1023  }
1024  $this->initialiseFromUser( $user, $lang );
1025  }
1026 
1032  public static function newFromAnon() {
1033  return new ParserOptions( new User,
1034  MediaWikiServices::getInstance()->getContentLanguage() );
1035  }
1036 
1044  public static function newFromUser( $user ) {
1045  return new ParserOptions( $user );
1046  }
1047 
1055  public static function newFromUserAndLang( UserIdentity $user, Language $lang ) {
1056  return new ParserOptions( $user, $lang );
1057  }
1058 
1065  public static function newFromContext( IContextSource $context ) {
1066  return new ParserOptions( $context->getUser(), $context->getLanguage() );
1067  }
1068 
1089  public static function newCanonical( $context, $userLang = null ) {
1090  if ( $context instanceof IContextSource ) {
1091  $ret = self::newFromContext( $context );
1092  } elseif ( $context === 'canonical' ) {
1093  $ret = self::newFromAnon();
1094  } elseif ( $context instanceof UserIdentity ) {
1095  $ret = new self( $context, $userLang );
1096  } else {
1097  throw new InvalidArgumentException(
1098  '$context must be an IContextSource, the string "canonical", or a UserIdentity'
1099  );
1100  }
1101  return $ret;
1102  }
1103 
1108  public static function clearStaticCache() {
1109  if ( !defined( 'MW_PHPUNIT_TEST' ) && !defined( 'MW_PARSER_TEST' ) ) {
1110  throw new RuntimeException( __METHOD__ . ' is just for testing' );
1111  }
1112  self::$defaults = null;
1113  self::$lazyOptions = null;
1114  self::$cacheVaryingOptionsHash = null;
1115  }
1116 
1125  private static function getDefaults() {
1131  $services = MediaWikiServices::getInstance();
1132  $languageConverterFactory = $services->getLanguageConverterFactory();
1133  $userOptionsLookup = $services->getUserOptionsLookup();
1134  $contentLanguage = $services->getContentLanguage();
1135 
1136  if ( self::$defaults === null ) {
1137  // *UPDATE* ParserOptions::matches() if any of this changes as needed
1138  self::$defaults = [
1139  'dateformat' => null,
1140  'interfaceMessage' => false,
1141  'targetLanguage' => null,
1142  'removeComments' => true,
1143  'enableLimitReport' => false,
1144  'preSaveTransform' => true,
1145  'isPreview' => false,
1146  'isSectionPreview' => false,
1147  'printable' => false,
1148  'allowUnsafeRawHtml' => true,
1149  'wrapclass' => 'mw-parser-output',
1150  'currentRevisionRecordCallback' => [ Parser::class, 'statelessFetchRevisionRecord' ],
1151  'templateCallback' => [ Parser::class, 'statelessFetchTemplate' ],
1152  'speculativeRevIdCallback' => null,
1153  'speculativeRevId' => null,
1154  'speculativePageIdCallback' => null,
1155  'speculativePageId' => null,
1156  ];
1157 
1158  self::$cacheVaryingOptionsHash = self::$initialCacheVaryingOptionsHash;
1159  self::$lazyOptions = self::$initialLazyOptions;
1160 
1161  Hooks::runner()->onParserOptionsRegister(
1162  self::$defaults,
1163  self::$cacheVaryingOptionsHash,
1164  self::$lazyOptions
1165  );
1166 
1167  ksort( self::$cacheVaryingOptionsHash );
1168  }
1169 
1170  // Unit tests depend on being able to modify the globals at will
1171  return self::$defaults + [
1172  'interwikiMagic' => $wgInterwikiMagic,
1173  'allowExternalImages' => $wgAllowExternalImages,
1174  'allowExternalImagesFrom' => $wgAllowExternalImagesFrom,
1175  'enableImageWhitelist' => $wgEnableImageWhitelist,
1176  'allowSpecialInclusion' => $wgAllowSpecialInclusion,
1177  'maxIncludeSize' => $wgMaxArticleSize * 1024,
1178  'maxPPNodeCount' => $wgMaxPPNodeCount,
1179  'maxPPExpandDepth' => $wgMaxPPExpandDepth,
1180  'maxTemplateDepth' => $wgMaxTemplateDepth,
1181  'expensiveParserFunctionLimit' => $wgExpensiveParserFunctionLimit,
1182  'externalLinkTarget' => $wgExternalLinkTarget,
1183  'cleanSignatures' => $wgCleanSignatures,
1184  'disableContentConversion' => $languageConverterFactory->isConversionDisabled(),
1185  'disableTitleConversion' => $languageConverterFactory->isLinkConversionDisabled(),
1186  'magicISBNLinks' => $wgEnableMagicLinks['ISBN'],
1187  'magicPMIDLinks' => $wgEnableMagicLinks['PMID'],
1188  'magicRFCLinks' => $wgEnableMagicLinks['RFC'],
1189  'thumbsize' => $userOptionsLookup->getDefaultOption( 'thumbsize' ),
1190  'userlang' => $contentLanguage,
1191  ];
1192  }
1193 
1200  private function initialiseFromUser( UserIdentity $user, Language $lang ) {
1201  // Initially lazy loaded option defaults must not be taken into account,
1202  // otherwise lazy loading does not work. Setting a default for lazy option
1203  // is useful for matching with canonical options.
1204  $this->options = $this->nullifyLazyOption( self::getDefaults() );
1205 
1206  $this->mUser = $user;
1207  $services = MediaWikiServices::getInstance();
1208  $optionsLookup = $services->getUserOptionsLookup();
1209  $this->options['thumbsize'] = $optionsLookup->getOption( $user, 'thumbsize' );
1210  $this->options['userlang'] = $lang;
1211  }
1212 
1222  public function matches( ParserOptions $other ) {
1223  // Compare most options
1224  $options = array_keys( $this->options );
1225  $options = array_diff( $options, [
1226  'enableLimitReport', // only affects HTML comments
1227  'tidy', // Has no effect since 1.35; removed in 1.36
1228  ] );
1229  foreach ( $options as $option ) {
1230  // Resolve any lazy options
1231  $this->lazyLoadOption( $option );
1232  $other->lazyLoadOption( $option );
1233 
1234  $o1 = $this->optionToString( $this->options[$option] );
1235  $o2 = $this->optionToString( $other->options[$option] );
1236  if ( $o1 !== $o2 ) {
1237  return false;
1238  }
1239  }
1240 
1241  // Compare most other fields
1242  foreach ( ( new ReflectionClass( $this ) )->getProperties() as $property ) {
1243  $field = $property->getName();
1244  if ( $property->isStatic() ) {
1245  continue;
1246  }
1247  if ( in_array( $field, [
1248  'options', // Already checked above
1249  'onAccessCallback', // only used for ParserOutput option tracking
1250  ] ) ) {
1251  continue;
1252  }
1253 
1254  if ( !is_object( $this->$field ) && $this->$field !== $other->$field ) {
1255  return false;
1256  }
1257  }
1258 
1259  return true;
1260  }
1261 
1267  public function matchesForCacheKey( ParserOptions $other ) {
1268  foreach ( self::allCacheVaryingOptions() as $option ) {
1269  // Populate any lazy options
1270  $this->lazyLoadOption( $option );
1271  $other->lazyLoadOption( $option );
1272 
1273  $o1 = $this->optionToString( $this->options[$option] );
1274  $o2 = $this->optionToString( $other->options[$option] );
1275  if ( $o1 !== $o2 ) {
1276  return false;
1277  }
1278  }
1279 
1280  return true;
1281  }
1282 
1289  public function registerWatcher( $callback ) {
1290  $this->onAccessCallback = $callback;
1291  }
1292 
1302  private function optionUsed( $optionName ) {
1303  if ( $this->onAccessCallback ) {
1304  call_user_func( $this->onAccessCallback, $optionName );
1305  }
1306  }
1307 
1313  public static function allCacheVaryingOptions() {
1314  return array_keys( array_filter( self::getCacheVaryingOptionsHash() ) );
1315  }
1316 
1322  private function optionToString( $value ) {
1323  if ( $value === true ) {
1324  return '1';
1325  } elseif ( $value === false ) {
1326  return '0';
1327  } elseif ( $value === null ) {
1328  return '';
1329  } elseif ( $value instanceof Language ) {
1330  return $value->getCode();
1331  } elseif ( is_array( $value ) ) {
1332  return '[' . implode( ',', array_map( [ $this, 'optionToString' ], $value ) ) . ']';
1333  } else {
1334  return (string)$value;
1335  }
1336  }
1337 
1350  public function optionsHash( $forOptions, $title = null ) {
1351  global $wgRenderHashAppend;
1352 
1353  $inCacheKey = self::allCacheVaryingOptions();
1354 
1355  // Resolve any lazy options
1356  $lazyOpts = array_intersect( $forOptions,
1357  $inCacheKey, array_keys( self::getLazyOptions() ) );
1358  foreach ( $lazyOpts as $k ) {
1359  $this->lazyLoadOption( $k );
1360  }
1361 
1364 
1365  // We only include used options with non-canonical values in the key
1366  // so adding a new option doesn't invalidate the entire parser cache.
1367  // The drawback to this is that changing the default value of an option
1368  // requires manual invalidation of existing cache entries, as mentioned
1369  // in the docs on the relevant methods and hooks.
1370  $values = [];
1371  foreach ( array_intersect( $inCacheKey, $forOptions ) as $option ) {
1372  $v = $this->optionToString( $options[$option] );
1373  $d = $this->optionToString( $defaults[$option] );
1374  if ( $v !== $d ) {
1375  $values[] = "$option=$v";
1376  }
1377  }
1378 
1379  $confstr = $values ? implode( '!', $values ) : 'canonical';
1380 
1381  // add in language specific options, if any
1382  // @todo FIXME: This is just a way of retrieving the url/user preferred variant
1383  $services = MediaWikiServices::getInstance();
1384  $lang = $title ? $title->getPageLanguage() : $services->getContentLanguage();
1385  $converter = $services->getLanguageConverterFactory()->getLanguageConverter( $lang );
1386  $confstr .= $converter->getExtraHashOptions();
1387 
1388  $confstr .= $wgRenderHashAppend;
1389 
1390  if ( $this->mExtraKey != '' ) {
1391  $confstr .= $this->mExtraKey;
1392  }
1393 
1394  $user = $services->getUserFactory()->newFromUserIdentity( $this->getUserIdentity() );
1395  // Give a chance for extensions to modify the hash, if they have
1396  // extra options or other effects on the parser cache.
1397  Hooks::runner()->onPageRenderingHash(
1398  $confstr,
1399  $user,
1400  $forOptions
1401  );
1402 
1403  // Make it a valid memcached key fragment
1404  $confstr = str_replace( ' ', '_', $confstr );
1405 
1406  return $confstr;
1407  }
1408 
1415  public function isSafeToCache( array $usedOptions = null ) {
1417  $inCacheKey = self::getCacheVaryingOptionsHash();
1418  $usedOptions = $usedOptions ?? array_keys( $this->options );
1419  foreach ( $usedOptions as $option ) {
1420  if ( empty( $inCacheKey[$option] ) && empty( self::$callbacks[$option] ) ) {
1421  $v = $this->optionToString( $this->options[$option] ?? null );
1422  $d = $this->optionToString( $defaults[$option] ?? null );
1423  if ( $v !== $d ) {
1424  return false;
1425  }
1426  }
1427  }
1428  return true;
1429  }
1430 
1441  public function setupFakeRevision( $title, $content, $user ) {
1442  $oldCallback = $this->setCurrentRevisionRecordCallback(
1443  static function (
1444  $titleToCheck, $parser = null ) use ( $title, $content, $user, &$oldCallback
1445  ) {
1446  if ( $titleToCheck->equals( $title ) ) {
1447  $revRecord = new MutableRevisionRecord( $title );
1448  $revRecord->setContent( SlotRecord::MAIN, $content )
1449  ->setUser( $user )
1450  ->setTimestamp( MWTimestamp::now( TS_MW ) )
1451  ->setPageId( $title->getArticleID() )
1452  ->setParentId( $title->getLatestRevID() );
1453  return $revRecord;
1454  } else {
1455  return call_user_func( $oldCallback, $titleToCheck, $parser );
1456  }
1457  }
1458  );
1459 
1460  global $wgHooks;
1461  $wgHooks['TitleExists'][] =
1462  static function ( $titleToCheck, &$exists ) use ( $title ) {
1463  if ( $titleToCheck->equals( $title ) ) {
1464  $exists = true;
1465  }
1466  };
1467  end( $wgHooks['TitleExists'] );
1468  $key = key( $wgHooks['TitleExists'] );
1469  $linkCache = MediaWikiServices::getInstance()->getLinkCache();
1470  $linkCache->clearBadLink( $title->getPrefixedDBkey() );
1471  return new ScopedCallback( static function () use ( $title, $key, $linkCache ) {
1472  global $wgHooks;
1473  unset( $wgHooks['TitleExists'][$key] );
1474  $linkCache->clearLink( $title );
1475  } );
1476  }
1477 }
1478 
ParserOptions\setMaxIncludeSize
setMaxIncludeSize( $x)
Maximum size of template expansions, in bytes.
Definition: ParserOptions.php:394
ParserOptions\getMagicPMIDLinks
getMagicPMIDLinks()
Are magic PMID links enabled?
Definition: ParserOptions.php:768
ParserOptions
Set options of the Parser.
Definition: ParserOptions.php:45
ParserOptions\setOptionLegacy
setOptionLegacy( $name, $value)
Legacy implementation.
Definition: ParserOptions.php:236
ParserOptions\getAllowExternalImagesFrom
getAllowExternalImagesFrom()
External images to allow.
Definition: ParserOptions.php:291
ParserOptions\getWrapOutputClass
getWrapOutputClass()
Class to use to wrap output from Parser::parse()
Definition: ParserOptions.php:816
ParserOptions\getExpensiveParserFunctionLimit
getExpensiveParserFunctionLimit()
Maximum number of calls per parse to expensive parser functions.
Definition: ParserOptions.php:445
ParserOptions\getIsSectionPreview
getIsSectionPreview()
Parsing the page for a "preview" operation on a single section?
Definition: ParserOptions.php:630
$wgMaxArticleSize
$wgMaxArticleSize
Maximum article size in kibibytes.
Definition: DefaultSettings.php:2672
ParserOptions\getRemoveComments
getRemoveComments()
Remove HTML comments.
Definition: ParserOptions.php:464
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:807
ParserOptions\disableContentConversion
disableContentConversion( $x=true)
Whether content conversion should be disabled.
Definition: ParserOptions.php:550
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:203
$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:1496
$wgMaxTemplateDepth
$wgMaxTemplateDepth
Maximum recursion depth for templates within templates.
Definition: DefaultSettings.php:4885
ParserOptions\nullifyLazyOption
nullifyLazyOption(array $options)
Resets lazy loaded options to null in the provided $options array.
Definition: ParserOptions.php:170
ParserOptions\getIsPreview
getIsPreview()
Parsing the page for a "preview" operation?
Definition: ParserOptions.php:613
ParserOptions\getDisableTitleConversion
getDisableTitleConversion()
Whether title conversion should be disabled.
Definition: ParserOptions.php:558
ParserOptions\setAllowExternalImages
setAllowExternalImages( $x)
Allow all external images inline?
Definition: ParserOptions.php:279
ParserOptions\setTemplateCallback
setTemplateCallback( $x)
Callback for template fetching; first argument to call_user_func().
Definition: ParserOptions.php:871
ParserOptions\setIsPreview
setIsPreview( $x)
Parsing the page for a "preview" operation?
Definition: ParserOptions.php:622
ParserOptions\__construct
__construct(UserIdentity $user, $lang=null)
Definition: ParserOptions.php:1018
ParserOptions\setTargetLanguage
setTargetLanguage( $x)
Target language for the parse.
Definition: ParserOptions.php:377
ParserOptions\getInterfaceMessage
getInterfaceMessage()
Parsing an interface message?
Definition: ParserOptions.php:351
ParserOptions\setIsSectionPreview
setIsSectionPreview( $x)
Parsing the page for a "preview" operation on a single section?
Definition: ParserOptions.php:639
ParserOptions\getSpeculativeRevId
getSpeculativeRevId()
A guess for {{REVISIONID}}, calculated using the callback provided via setSpeculativeRevIdCallback().
Definition: ParserOptions.php:885
ParserOptions\newFromAnon
static newFromAnon()
Get a ParserOptions object for an anonymous user.
Definition: ParserOptions.php:1032
ParserOptions\setEnableImageWhitelist
setEnableImageWhitelist( $x)
Use the on-wiki external image whitelist?
Definition: ParserOptions.php:325
ParserOptions\newFromUserAndLang
static newFromUserAndLang(UserIdentity $user, Language $lang)
Get a ParserOptions object from a given user and language.
Definition: ParserOptions.php:1055
ParserOptions\setWrapOutputClass
setWrapOutputClass( $className)
CSS class to use to wrap output from Parser::parse()
Definition: ParserOptions.php:827
ParserOptions\setSpeculativeRevIdCallback
setSpeculativeRevIdCallback( $x)
Callback to generate a guess for {{REVISIONID}}.
Definition: ParserOptions.php:937
ParserOptions\disableTitleConversion
disableTitleConversion( $x=true)
Whether title conversion should be disabled.
Definition: ParserOptions.php:567
ParserOptions\initDateFormat
static initDateFormat(ParserOptions $popt)
Lazy initializer for dateFormat.
Definition: ParserOptions.php:690
ParserOptions\getIsPrintable
getIsPrintable()
Parsing the printable version of the page?
Definition: ParserOptions.php:647
ParserOptions\setMaxTemplateDepth
setMaxTemplateDepth( $x)
Maximum recursion depth for templates within templates.
Definition: ParserOptions.php:436
$wgLang
$wgLang
Definition: Setup.php:861
MediaWiki\User\UserIdentity
Interface for objects representing user identity.
Definition: UserIdentity.php:39
ParserOptions\getMagicRFCLinks
getMagicRFCLinks()
Are magic RFC links enabled?
Definition: ParserOptions.php:777
ParserOptions\getUserLangObj
getUserLangObj()
Get the user language used by the parser for this page and split the parser cache.
Definition: ParserOptions.php:721
ParserOptions\registerWatcher
registerWatcher( $callback)
Registers a callback for tracking which ParserOptions which are used.
Definition: ParserOptions.php:1289
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:1441
ParserOptions\getDateFormat
getDateFormat()
Date format index.
Definition: ParserOptions.php:681
ParserOptions\setOption
setOption( $name, $value)
Set an option, generically.
Definition: ParserOptions.php:219
ParserOptions\initSpeculativeRevId
static initSpeculativeRevId(ParserOptions $popt)
Callback registered with ParserOptions::$lazyOptions, triggered by getSpeculativeRevId().
Definition: ParserOptions.php:909
$wgHooks
$wgHooks
Global list of hooks.
Definition: DefaultSettings.php:8678
wfDeprecated
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Logs a warning that a deprecated feature was used.
Definition: GlobalFunctions.php:997
ParserOptions\getRedirectTarget
getRedirectTarget()
Get the previously-set redirect target.
Definition: ParserOptions.php:991
ParserOptions\$mUser
UserIdentity $mUser
Stored user object.
Definition: ParserOptions.php:117
ParserOptions\setUserLang
setUserLang( $x)
Set the user language used by the parser for this page and split the parser cache.
Definition: ParserOptions.php:746
ParserOptions\getAllowSpecialInclusion
getAllowSpecialInclusion()
Allow inclusion of special pages?
Definition: ParserOptions.php:334
$wgAllowExternalImagesFrom
$wgAllowExternalImagesFrom
If the above is false, you can specify an exception here.
Definition: DefaultSettings.php:4931
ParserOptions\getMaxIncludeSize
getMaxIncludeSize()
Maximum size of template expansions, in bytes.
Definition: ParserOptions.php:385
ParserOptions\$mTimestamp
string null $mTimestamp
Timestamp used for {{CURRENTDAY}} etc.
Definition: ParserOptions.php:110
$wgExpensiveParserFunctionLimit
$wgExpensiveParserFunctionLimit
Maximum number of calls per parse to expensive parser functions such as PAGESINCATEGORY.
Definition: DefaultSettings.php:5063
ParserOptions\setThumbSize
setThumbSize( $x)
Thumb size preferred by the user.
Definition: ParserOptions.php:584
ParserOptions\getEnableImageWhitelist
getEnableImageWhitelist()
Use the on-wiki external image whitelist?
Definition: ParserOptions.php:314
$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:533
ParserOptions\setDateFormat
setDateFormat( $x)
Date format index.
Definition: ParserOptions.php:700
ParserOptions\newCanonical
static newCanonical( $context, $userLang=null)
Creates a "canonical" ParserOptions object.
Definition: ParserOptions.php:1089
ParserOptions\getTargetLanguage
getTargetLanguage()
Target language for the parse.
Definition: ParserOptions.php:368
$title
$title
Definition: testCompression.php:38
ParserOptions\initSpeculativePageId
static initSpeculativePageId(ParserOptions $popt)
Callback registered with ParserOptions::$lazyOptions, triggered by getSpeculativePageId().
Definition: ParserOptions.php:923
ParserOptions\setAllowSpecialInclusion
setAllowSpecialInclusion( $x)
Allow inclusion of special pages?
Definition: ParserOptions.php:343
$wgMaxPPExpandDepth
$wgMaxPPExpandDepth
Definition: DefaultSettings.php:4890
ParserOptions\getDefaults
static getDefaults()
Get default option values.
Definition: ParserOptions.php:1125
ParserOptions\getExternalLinkTarget
getExternalLinkTarget()
Target attribute for external links.
Definition: ParserOptions.php:524
ParserOptions\$onAccessCallback
callable null $onAccessCallback
Function to be called when an option is accessed.
Definition: ParserOptions.php:124
$wgEnableMagicLinks
$wgEnableMagicLinks
Enable the magic links feature of automatically turning ISBN xxx, PMID xxx, RFC xxx into links.
Definition: DefaultSettings.php:5088
wfTimestampNow
wfTimestampNow()
Convenience function; returns MediaWiki timestamp for the present time.
Definition: GlobalFunctions.php:1678
ParserOptions\getStubThreshold
getStubThreshold()
Thumb size preferred by the user.
Definition: ParserOptions.php:593
$wgExternalLinkTarget
$wgExternalLinkTarget
Set a default target for external links, e.g.
Definition: DefaultSettings.php:5010
ParserOptions\$options
array $options
Current values for all options that are relevant for caching.
Definition: ParserOptions.php:103
ParserOptions\getUserLang
getUserLang()
Same as getUserLangObj() but returns a string instead.
Definition: ParserOptions.php:737
ParserOptions\getPreSaveTransform
getPreSaveTransform()
Transform wiki markup when saving the page?
Definition: ParserOptions.php:664
ParserOptions\setStubThreshold
setStubThreshold( $x)
Thumb size preferred by the user.
Definition: ParserOptions.php:604
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:145
ParserOptions\$mExtraKey
$mExtraKey
Appended to the options hash.
Definition: ParserOptions.php:137
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:795
ParserOptions\getDisableContentConversion
getDisableContentConversion()
Whether content conversion should be disabled.
Definition: ParserOptions.php:541
ParserOptions\optionToString
optionToString( $value)
Convert an option to a string value.
Definition: ParserOptions.php:1322
ParserOptions\matchesForCacheKey
matchesForCacheKey(ParserOptions $other)
Definition: ParserOptions.php:1267
ParserOptions\optionUsed
optionUsed( $optionName)
Record that an option was internally accessed.
Definition: ParserOptions.php:1302
$content
$content
Definition: router.php:76
ParserOptions\getSpeculativePageId
getSpeculativePageId()
A guess for {{PAGEID}}, calculated using the callback provided via setSpeculativeRevPageCallback().
Definition: ParserOptions.php:899
ParserOptions\setTimestamp
setTimestamp( $x)
Timestamp used for {{CURRENTDAY}} etc.
Definition: ParserOptions.php:969
ParserOptions\setSpeculativePageIdCallback
setSpeculativePageIdCallback( $x)
Callback to generate a guess for {{PAGEID}}.
Definition: ParserOptions.php:948
ParserOptions\setCleanSignatures
setCleanSignatures( $x)
Clean up signature texts?
Definition: ParserOptions.php:516
ParserOptions\newFromContext
static newFromContext(IContextSource $context)
Get a ParserOptions object from a IContextSource object.
Definition: ParserOptions.php:1065
MediaWiki\Revision\MutableRevisionRecord
Definition: MutableRevisionRecord.php:44
Hooks\runner
static runner()
Get a HookRunner instance for calling hooks using the new interfaces.
Definition: Hooks.php:173
ParserOptions\getTemplateCallback
getTemplateCallback()
Callback for template fetching; first argument to call_user_func().
Definition: ParserOptions.php:862
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:474
ParserOptions\setInterwikiMagic
setInterwikiMagic( $x)
Specify whether to extract interlanguage links.
Definition: ParserOptions.php:260
IContextSource\getUser
getUser()
ParserOptions\lazyLoadOption
lazyLoadOption( $name)
Definition: ParserOptions.php:158
ParserOptions\setRedirectTarget
setRedirectTarget( $title)
Note that setting or changing this does not make the page a redirect or change its target,...
Definition: ParserOptions.php:981
ParserOptions\setExpensiveParserFunctionLimit
setExpensiveParserFunctionLimit( $x)
Maximum number of calls per parse to expensive parser functions.
Definition: ParserOptions.php:455
ParserOptions\getTimestamp
getTimestamp()
Timestamp used for {{CURRENTDAY}} etc.
Definition: ParserOptions.php:957
ParserOptions\setMaxPPNodeCount
setMaxPPNodeCount( $x)
Maximum number of nodes touched by PPFrame::expand()
Definition: ParserOptions.php:411
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:506
ParserOptions\getLazyOptions
static getLazyOptions()
Get lazy-loaded options.
Definition: ParserOptions.php:185
$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:132
ParserOptions\setAllowExternalImagesFrom
setAllowExternalImagesFrom( $x)
External images to allow.
Definition: ParserOptions.php:305
ParserOptions\matches
matches(ParserOptions $other)
Check if these options match that of another options set.
Definition: ParserOptions.php:1222
ParserOptions\enableLimitReport
enableLimitReport( $x=true)
Definition: ParserOptions.php:497
Title
Represents a title within MediaWiki.
Definition: Title.php:47
ParserOptions\getInterwikiMagic
getInterwikiMagic()
Whether to extract interlanguage links.
Definition: ParserOptions.php:251
ParserOptions\getUserIdentity
getUserIdentity()
Get the identity of the user for whom the parse is made.
Definition: ParserOptions.php:1010
ParserOptions\setInterfaceMessage
setInterfaceMessage( $x)
Parsing an interface message?
Definition: ParserOptions.php:360
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:1313
$wgCleanSignatures
$wgCleanSignatures
If true, removes (by substituting) templates in signatures.
Definition: DefaultSettings.php:4912
ParserOptions\getThumbSize
getThumbSize()
Thumb size preferred by the user.
Definition: ParserOptions.php:575
ParserOptions\getMagicISBNLinks
getMagicISBNLinks()
Are magic ISBN links enabled?
Definition: ParserOptions.php:759
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:202
ParserOptions\setIsPrintable
setIsPrintable( $x)
Parsing the printable version of the page?
Definition: ParserOptions.php:656
ParserOptions\getMaxPPNodeCount
getMaxPPNodeCount()
Maximum number of nodes touched by PPFrame::expand()
Definition: ParserOptions.php:402
$wgRenderHashAppend
$wgRenderHashAppend
Append a configured value to the parser cache and the sitenotice key so that they can be kept separat...
Definition: DefaultSettings.php:3148
ParserOptions\getCurrentRevisionRecordCallback
getCurrentRevisionRecordCallback()
Callback for current revision fetching; first argument to call_user_func().
Definition: ParserOptions.php:843
ParserOptions\getMaxPPExpandDepth
getMaxPPExpandDepth()
Maximum recursion depth in PPFrame::expand()
Definition: ParserOptions.php:419
ParserOptions\clearStaticCache
static clearStaticCache()
Reset static caches.
Definition: ParserOptions.php:1108
ParserOptions\getEnableLimitReport
getEnableLimitReport()
Definition: ParserOptions.php:485
ParserOptions\isSafeToCache
isSafeToCache(array $usedOptions=null)
Test whether these options are safe to cache.
Definition: ParserOptions.php:1415
ParserOptions\getMaxTemplateDepth
getMaxTemplateDepth()
Maximum recursion depth for templates within templates.
Definition: ParserOptions.php:427
ParserOptions\setPreSaveTransform
setPreSaveTransform( $x)
Transform wiki markup when saving the page?
Definition: ParserOptions.php:673
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:67
ParserOptions\$callbacks
static array $callbacks
Specify pseudo-options that are actually callbacks.
Definition: ParserOptions.php:92
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:4877
ParserOptions\setCurrentRevisionRecordCallback
setCurrentRevisionRecordCallback( $x)
Callback for current revision fetching; first argument to call_user_func().
Definition: ParserOptions.php:854
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:1350
ParserOptions\initialiseFromUser
initialiseFromUser(UserIdentity $user, Language $lang)
Get user options.
Definition: ParserOptions.php:1200
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:268
ParserOptions\newFromUser
static newFromUser( $user)
Get a ParserOptions object from a given user.
Definition: ParserOptions.php:1044
$wgAllowExternalImages
$wgAllowExternalImages
Whether to allow inline image pointing to other websites.
Definition: DefaultSettings.php:4917
$wgEnableImageWhitelist
$wgEnableImageWhitelist
If $wgAllowExternalImages is false, you can allow an on-wiki allow list of regular expression fragmen...
Definition: DefaultSettings.php:4944
ParserOptions\addExtraKey
addExtraKey( $key)
Extra key that should be present in the parser cache key.
Definition: ParserOptions.php:1001
$wgAllowSpecialInclusion
$wgAllowSpecialInclusion
Allow special page inclusions such as {{Special:Allpages}}.
Definition: DefaultSettings.php:9140