MediaWiki REL1_35
ParserOptions.php
Go to the documentation of this file.
1<?php
27use Wikimedia\ScopedCallback;
28
45
51 private static $defaults = null;
52
57 private static $lazyOptions = [
58 'dateformat' => [ __CLASS__, 'initDateFormat' ],
59 'speculativeRevId' => [ __CLASS__, 'initSpeculativeRevId' ],
60 'speculativePageId' => [ __CLASS__, 'initSpeculativePageId' ],
61 ];
62
67 private static $inCacheKey = [
68 'dateformat' => true,
69 'numberheadings' => true,
70 'thumbsize' => true,
71 'stubthreshold' => true,
72 'printable' => true,
73 'userlang' => true,
74 ];
75
80 private $options;
81
87 private $mTimestamp;
88
94 private $mUser;
95
101 private $onAccessCallback = null;
102
109 private $redirectTarget = null;
110
114 private $mExtraKey = '';
115
122 public function getOption( $name ) {
123 if ( !array_key_exists( $name, $this->options ) ) {
124 throw new InvalidArgumentException( "Unknown parser option $name" );
125 }
126
127 $this->lazyLoadOption( $name );
128 $this->optionUsed( $name );
129 return $this->options[$name];
130 }
131
135 private function lazyLoadOption( $name ) {
136 if ( isset( self::$lazyOptions[$name] ) && $this->options[$name] === null ) {
137 $this->options[$name] = call_user_func( self::$lazyOptions[$name], $this, $name );
138 }
139 }
140
149 public function setOption( $name, $value ) {
150 if ( !array_key_exists( $name, $this->options ) ) {
151 throw new InvalidArgumentException( "Unknown parser option $name" );
152 }
153 $old = $this->options[$name];
154 $this->options[$name] = $value;
155 return $old;
156 }
157
166 protected function setOptionLegacy( $name, $value ) {
167 if ( !array_key_exists( $name, $this->options ) ) {
168 throw new InvalidArgumentException( "Unknown parser option $name" );
169 }
170 return wfSetVar( $this->options[$name], $value );
171 }
172
181 public function getInterwikiMagic() {
182 return $this->getOption( 'interwikiMagic' );
183 }
184
190 public function setInterwikiMagic( $x ) {
191 return $this->setOptionLegacy( 'interwikiMagic', $x );
192 }
193
198 public function getAllowExternalImages() {
199 return $this->getOption( 'allowExternalImages' );
200 }
201
209 public function setAllowExternalImages( $x ) {
210 wfDeprecated( __METHOD__, '1.35' );
211 return $this->setOptionLegacy( 'allowExternalImages', $x );
212 }
213
221 public function getAllowExternalImagesFrom() {
222 return $this->getOption( 'allowExternalImagesFrom' );
223 }
224
235 public function setAllowExternalImagesFrom( $x ) {
236 wfDeprecated( __METHOD__, '1.35' );
237 return $this->setOptionLegacy( 'allowExternalImagesFrom', $x );
238 }
239
244 public function getEnableImageWhitelist() {
245 return $this->getOption( 'enableImageWhitelist' );
246 }
247
255 public function setEnableImageWhitelist( $x ) {
256 wfDeprecated( __METHOD__, '1.35' );
257 return $this->setOptionLegacy( 'enableImageWhitelist', $x );
258 }
259
264 public function getNumberHeadings() {
265 return $this->getOption( 'numberheadings' );
266 }
267
273 public function setNumberHeadings( $x ) {
274 return $this->setOptionLegacy( 'numberheadings', $x );
275 }
276
281 public function getAllowSpecialInclusion() {
282 return $this->getOption( 'allowSpecialInclusion' );
283 }
284
290 public function setAllowSpecialInclusion( $x ) {
291 return $this->setOptionLegacy( 'allowSpecialInclusion', $x );
292 }
293
299 public function getTidy() {
300 wfDeprecated( __METHOD__, '1.35' );
301 return $this->getOption( 'tidy' );
302 }
303
310 public function setTidy( $x ) {
311 if ( !$x ) {
312 wfDeprecatedMsg( 'Disabling tidy is deprecated since MediaWiki 1.33', '1.33' );
313 }
314 return $this->setOptionLegacy( 'tidy', $x );
315 }
316
321 public function getInterfaceMessage() {
322 return $this->getOption( 'interfaceMessage' );
323 }
324
330 public function setInterfaceMessage( $x ) {
331 return $this->setOptionLegacy( 'interfaceMessage', $x );
332 }
333
338 public function getTargetLanguage() {
339 return $this->getOption( 'targetLanguage' );
340 }
341
347 public function setTargetLanguage( $x ) {
348 return $this->setOption( 'targetLanguage', $x );
349 }
350
355 public function getMaxIncludeSize() {
356 return $this->getOption( 'maxIncludeSize' );
357 }
358
364 public function setMaxIncludeSize( $x ) {
365 return $this->setOptionLegacy( 'maxIncludeSize', $x );
366 }
367
372 public function getMaxPPNodeCount() {
373 return $this->getOption( 'maxPPNodeCount' );
374 }
375
381 public function setMaxPPNodeCount( $x ) {
382 return $this->setOptionLegacy( 'maxPPNodeCount', $x );
383 }
384
389 public function getMaxPPExpandDepth() {
390 return $this->getOption( 'maxPPExpandDepth' );
391 }
392
397 public function getMaxTemplateDepth() {
398 return $this->getOption( 'maxTemplateDepth' );
399 }
400
406 public function setMaxTemplateDepth( $x ) {
407 return $this->setOptionLegacy( 'maxTemplateDepth', $x );
408 }
409
416 return $this->getOption( 'expensiveParserFunctionLimit' );
417 }
418
425 public function setExpensiveParserFunctionLimit( $x ) {
426 return $this->setOptionLegacy( 'expensiveParserFunctionLimit', $x );
427 }
428
434 public function getRemoveComments() {
435 return $this->getOption( 'removeComments' );
436 }
437
444 public function setRemoveComments( $x ) {
445 return $this->setOptionLegacy( 'removeComments', $x );
446 }
447
452 public function getEnableLimitReport() {
453 return $this->getOption( 'enableLimitReport' );
454 }
455
461 public function enableLimitReport( $x = true ) {
462 return $this->setOptionLegacy( 'enableLimitReport', $x );
463 }
464
470 public function getCleanSignatures() {
471 return $this->getOption( 'cleanSignatures' );
472 }
473
480 public function setCleanSignatures( $x ) {
481 return $this->setOptionLegacy( 'cleanSignatures', $x );
482 }
483
488 public function getExternalLinkTarget() {
489 return $this->getOption( 'externalLinkTarget' );
490 }
491
497 public function setExternalLinkTarget( $x ) {
498 return $this->setOptionLegacy( 'externalLinkTarget', $x );
499 }
500
505 public function getDisableContentConversion() {
506 return $this->getOption( 'disableContentConversion' );
507 }
508
514 public function disableContentConversion( $x = true ) {
515 return $this->setOptionLegacy( 'disableContentConversion', $x );
516 }
517
522 public function getDisableTitleConversion() {
523 return $this->getOption( 'disableTitleConversion' );
524 }
525
531 public function disableTitleConversion( $x = true ) {
532 return $this->setOptionLegacy( 'disableTitleConversion', $x );
533 }
534
539 public function getThumbSize() {
540 return $this->getOption( 'thumbsize' );
541 }
542
548 public function setThumbSize( $x ) {
549 return $this->setOptionLegacy( 'thumbsize', $x );
550 }
551
556 public function getStubThreshold() {
557 return $this->getOption( 'stubthreshold' );
558 }
559
565 public function setStubThreshold( $x ) {
566 return $this->setOptionLegacy( 'stubthreshold', $x );
567 }
568
573 public function getIsPreview() {
574 return $this->getOption( 'isPreview' );
575 }
576
582 public function setIsPreview( $x ) {
583 return $this->setOptionLegacy( 'isPreview', $x );
584 }
585
590 public function getIsSectionPreview() {
591 return $this->getOption( 'isSectionPreview' );
592 }
593
599 public function setIsSectionPreview( $x ) {
600 return $this->setOptionLegacy( 'isSectionPreview', $x );
601 }
602
607 public function getIsPrintable() {
608 return $this->getOption( 'printable' );
609 }
610
616 public function setIsPrintable( $x ) {
617 return $this->setOptionLegacy( 'printable', $x );
618 }
619
624 public function getPreSaveTransform() {
625 return $this->getOption( 'preSaveTransform' );
626 }
627
633 public function setPreSaveTransform( $x ) {
634 return $this->setOptionLegacy( 'preSaveTransform', $x );
635 }
636
641 public function getDateFormat() {
642 return $this->getOption( 'dateformat' );
643 }
644
650 private static function initDateFormat( ParserOptions $popt ) {
651 return $popt->mUser->getDatePreference();
652 }
653
659 public function setDateFormat( $x ) {
660 return $this->setOptionLegacy( 'dateformat', $x );
661 }
662
680 public function getUserLangObj() {
681 return $this->getOption( 'userlang' );
682 }
683
696 public function getUserLang() {
697 return $this->getUserLangObj()->getCode();
698 }
699
705 public function setUserLang( $x ) {
706 if ( is_string( $x ) ) {
707 $x = MediaWikiServices::getInstance()->getLanguageFactory()->getLanguage( $x );
708 }
709
710 return $this->setOptionLegacy( 'userlang', $x );
711 }
712
718 public function getMagicISBNLinks() {
719 return $this->getOption( 'magicISBNLinks' );
720 }
721
727 public function getMagicPMIDLinks() {
728 return $this->getOption( 'magicPMIDLinks' );
729 }
730
736 public function getMagicRFCLinks() {
737 return $this->getOption( 'magicRFCLinks' );
738 }
739
754 public function getAllowUnsafeRawHtml() {
755 return $this->getOption( 'allowUnsafeRawHtml' );
756 }
757
766 public function setAllowUnsafeRawHtml( $x ) {
767 return $this->setOptionLegacy( 'allowUnsafeRawHtml', $x );
768 }
769
775 public function getWrapOutputClass() {
776 return $this->getOption( 'wrapclass' );
777 }
778
786 public function setWrapOutputClass( $className ) {
787 if ( $className === true ) { // DWIM, they probably want the default class name
788 $className = 'mw-parser-output';
789 }
790 if ( $className === false ) {
791 wfDeprecated( __METHOD__ . '( false )', '1.31' );
792 }
793 return $this->setOption( 'wrapclass', $className );
794 }
795
802 public function getCurrentRevisionCallback() {
803 wfDeprecated( __METHOD__, '1.35' );
804 $revCb = $this->getOption( 'currentRevisionCallback' );
805
806 // As a temporary measure, while both currentRevisionCallback and
807 // currentRevisionRecordCallback are supported, retrieving one that is
808 // not set first checks if the other is set, so that the end result works
809 // regardless of which setter was used, since one extension may set a
810 // RevisionCallback and another may ask for the RevisionRecordCallback
811 if ( $revCb === [ Parser::class, 'statelessFetchRevision' ] ) {
812 // currentRevisionCallback is set to the default, check if
813 // currentRevisionRecordCallback is set (and not the default)
814 $revRecordCb = $this->getOption( 'currentRevisionRecordCallback' );
815 if ( $revRecordCb !== [ Parser::class, 'statelessFetchRevisionRecord' ] ) {
816 // currentRevisionRecordCallback is set and not the default,
817 // convert it
818 $revCb = function ( Title $title, $parser = false ) use ( $revRecordCb ) {
819 $revRecord = call_user_func(
820 $revRecordCb,
821 $title,
822 $parser ?: null
823 );
824 if ( $revRecord ) {
825 return new Revision( $revRecord );
826 }
827 return false;
828 };
829 }
830 }
831 return $revCb;
832 }
833
841 $revRecordCb = $this->getOption( 'currentRevisionRecordCallback' );
842
843 // See explanation above
844 if ( $revRecordCb === [ Parser::class, 'statelessFetchRevisionRecord' ] ) {
845 // currentRevisionRecordCallback is set to the default, check if
846 // currentRevisionCallback is set (and not the default)
847 $revCb = $this->getOption( 'currentRevisionCallback' );
848 if ( $revCb !== [ Parser::class, 'statelessFetchRevision' ] ) {
849 // currentRevisionCallback is set and not the default, convert it
850 $revRecordCb = function ( Title $title, $parser = null ) use ( $revCb ) {
851 $rev = call_user_func( $revCb, $title, $parser ?? false );
852 if ( $rev ) {
853 return $rev->getRevisionRecord();
854 }
855 return false;
856 };
857 }
858 }
859 return $revRecordCb;
860 }
861
869 public function setCurrentRevisionCallback( $x ) {
870 wfDeprecated( __METHOD__, '1.35' );
871 return $this->setOptionLegacy( 'currentRevisionCallback', $x );
872 }
873
881 public function setCurrentRevisionRecordCallback( $x ) {
882 return $this->setOption( 'currentRevisionRecordCallback', $x );
883 }
884
889 public function getTemplateCallback() {
890 return $this->getOption( 'templateCallback' );
891 }
892
898 public function setTemplateCallback( $x ) {
899 return $this->setOptionLegacy( 'templateCallback', $x );
900 }
901
912 public function getSpeculativeRevId() {
913 return $this->getOption( 'speculativeRevId' );
914 }
915
926 public function getSpeculativePageId() {
927 return $this->getOption( 'speculativePageId' );
928 }
929
936 private static function initSpeculativeRevId( ParserOptions $popt ) {
937 $cb = $popt->getOption( 'speculativeRevIdCallback' );
938 $id = $cb ? $cb() : null;
939
940 // returning null would result in this being re-called every access
941 return $id ?? false;
942 }
943
950 private static function initSpeculativePageId( ParserOptions $popt ) {
951 $cb = $popt->getOption( 'speculativePageIdCallback' );
952 $id = $cb ? $cb() : null;
953
954 // returning null would result in this being re-called every access
955 return $id ?? false;
956 }
957
964 public function setSpeculativeRevIdCallback( $x ) {
965 $this->setOption( 'speculativeRevId', null ); // reset
966 return $this->setOption( 'speculativeRevIdCallback', $x );
967 }
968
975 public function setSpeculativePageIdCallback( $x ) {
976 $this->setOption( 'speculativePageId', null ); // reset
977 return $this->setOption( 'speculativePageIdCallback', $x );
978 }
979
984 public function getTimestamp() {
985 if ( !isset( $this->mTimestamp ) ) {
986 $this->mTimestamp = wfTimestampNow();
987 }
988 return $this->mTimestamp;
989 }
990
996 public function setTimestamp( $x ) {
997 return wfSetVar( $this->mTimestamp, $x );
998 }
999
1010 public function setRedirectTarget( $title ) {
1011 $this->redirectTarget = $title;
1012 }
1013
1020 public function getRedirectTarget() {
1021 return $this->redirectTarget;
1022 }
1023
1030 public function addExtraKey( $key ) {
1031 $this->mExtraKey .= '!' . $key;
1032 }
1033
1038 public function getUser() {
1039 return $this->mUser;
1040 }
1041
1048 public function __construct( $user = null, $lang = null ) {
1049 if ( $user === null ) {
1050 global $wgUser;
1051 if ( $wgUser === null ) {
1052 $user = new User;
1053 } else {
1054 $user = $wgUser;
1055 }
1056 }
1057 if ( $lang === null ) {
1058 global $wgLang;
1060 $lang = $wgLang;
1061 }
1062 $this->initialiseFromUser( $user, $lang );
1063 }
1064
1072 public static function newFromAnon() {
1073 return new ParserOptions( new User,
1074 MediaWikiServices::getInstance()->getContentLanguage() );
1075 }
1076
1086 public static function newFromUser( $user ) {
1087 return new ParserOptions( $user );
1088 }
1089
1099 public static function newFromUserAndLang( User $user, Language $lang ) {
1100 return new ParserOptions( $user, $lang );
1101 }
1102
1111 public static function newFromContext( IContextSource $context ) {
1112 return new ParserOptions( $context->getUser(), $context->getLanguage() );
1113 }
1114
1133 public static function newCanonical( $context = null, $userLang = null ) {
1134 if ( $context instanceof IContextSource ) {
1135 $ret = self::newFromContext( $context );
1136 } elseif ( $context === 'canonical' ) {
1137 $ret = self::newFromAnon();
1138 } elseif ( $context instanceof User || $context === null ) {
1139 if ( $context === null ) {
1140 wfDeprecated( __METHOD__ . ' with no user', '1.35' );
1141 }
1142 $ret = new self( $context, $userLang );
1143 } else {
1144 throw new InvalidArgumentException(
1145 '$context must be an IContextSource, the string "canonical", a User, or null'
1146 );
1147 }
1148
1149 foreach ( self::getCanonicalOverrides() as $k => $v ) {
1150 $ret->setOption( $k, $v );
1151 }
1152 return $ret;
1153 }
1154
1164 private static function getDefaults() {
1171
1172 if ( self::$defaults === null ) {
1173 // *UPDATE* ParserOptions::matches() if any of this changes as needed
1174 self::$defaults = [
1175 'dateformat' => null,
1176 'tidy' => true,
1177 'interfaceMessage' => false,
1178 'targetLanguage' => null,
1179 'removeComments' => true,
1180 'enableLimitReport' => false,
1181 'preSaveTransform' => true,
1182 'isPreview' => false,
1183 'isSectionPreview' => false,
1184 'printable' => false,
1185 'allowUnsafeRawHtml' => true,
1186 'wrapclass' => 'mw-parser-output',
1187 'currentRevisionCallback' => [ Parser::class, 'statelessFetchRevision' ],
1188 'currentRevisionRecordCallback' => [ Parser::class, 'statelessFetchRevisionRecord' ],
1189 'templateCallback' => [ Parser::class, 'statelessFetchTemplate' ],
1190 'speculativeRevIdCallback' => null,
1191 'speculativeRevId' => null,
1192 'speculativePageIdCallback' => null,
1193 'speculativePageId' => null,
1194 ];
1195
1196 Hooks::runner()->onParserOptionsRegister(
1197 self::$defaults,
1198 self::$inCacheKey,
1199 self::$lazyOptions
1200 );
1201
1202 ksort( self::$inCacheKey );
1203 }
1204
1205 // Unit tests depend on being able to modify the globals at will
1206 return self::$defaults + [
1207 'interwikiMagic' => $wgInterwikiMagic,
1208 'allowExternalImages' => $wgAllowExternalImages,
1209 'allowExternalImagesFrom' => $wgAllowExternalImagesFrom,
1210 'enableImageWhitelist' => $wgEnableImageWhitelist,
1211 'allowSpecialInclusion' => $wgAllowSpecialInclusion,
1212 'maxIncludeSize' => $wgMaxArticleSize * 1024,
1213 'maxPPNodeCount' => $wgMaxPPNodeCount,
1214 'maxPPExpandDepth' => $wgMaxPPExpandDepth,
1215 'maxTemplateDepth' => $wgMaxTemplateDepth,
1216 'expensiveParserFunctionLimit' => $wgExpensiveParserFunctionLimit,
1217 'externalLinkTarget' => $wgExternalLinkTarget,
1218 'cleanSignatures' => $wgCleanSignatures,
1219 'disableContentConversion' => $wgDisableLangConversion,
1220 'disableTitleConversion' => $wgDisableLangConversion || $wgDisableTitleConversion,
1221 'magicISBNLinks' => $wgEnableMagicLinks['ISBN'],
1222 'magicPMIDLinks' => $wgEnableMagicLinks['PMID'],
1223 'magicRFCLinks' => $wgEnableMagicLinks['RFC'],
1224 'numberheadings' => User::getDefaultOption( 'numberheadings' ),
1225 'thumbsize' => User::getDefaultOption( 'thumbsize' ),
1226 'stubthreshold' => 0,
1227 'userlang' => MediaWikiServices::getInstance()->getContentLanguage(),
1228 ];
1229 }
1230
1240 private static function getCanonicalOverrides() {
1242
1243 return [
1244 'enableLimitReport' => $wgEnableParserLimitReporting,
1245 ];
1246 }
1247
1254 private function initialiseFromUser( $user, $lang ) {
1255 $this->options = self::getDefaults();
1256
1257 $this->mUser = $user;
1258 $this->options['numberheadings'] = $user->getOption( 'numberheadings' );
1259 $this->options['thumbsize'] = $user->getOption( 'thumbsize' );
1260 $this->options['stubthreshold'] = $user->getStubThreshold();
1261 $this->options['userlang'] = $lang;
1262 }
1263
1273 public function matches( ParserOptions $other ) {
1274 // Compare most options
1275 $options = array_keys( $this->options );
1276 $options = array_diff( $options, [
1277 'enableLimitReport', // only affects HTML comments
1278 ] );
1279 foreach ( $options as $option ) {
1280 // Resolve any lazy options
1281 $this->lazyLoadOption( $option );
1282 $other->lazyLoadOption( $option );
1283
1284 $o1 = $this->optionToString( $this->options[$option] );
1285 $o2 = $this->optionToString( $other->options[$option] );
1286 if ( $o1 !== $o2 ) {
1287 return false;
1288 }
1289 }
1290
1291 // Compare most other fields
1292 $fields = array_keys( get_class_vars( __CLASS__ ) );
1293 $fields = array_diff( $fields, [
1294 'defaults', // static
1295 'lazyOptions', // static
1296 'inCacheKey', // static
1297 'options', // Already checked above
1298 'onAccessCallback', // only used for ParserOutput option tracking
1299 ] );
1300 foreach ( $fields as $field ) {
1301 if ( !is_object( $this->$field ) && $this->$field !== $other->$field ) {
1302 return false;
1303 }
1304 }
1305
1306 return true;
1307 }
1308
1314 public function matchesForCacheKey( ParserOptions $other ) {
1315 foreach ( self::allCacheVaryingOptions() as $option ) {
1316 // Populate any lazy options
1317 $this->lazyLoadOption( $option );
1318 $other->lazyLoadOption( $option );
1319
1320 $o1 = $this->optionToString( $this->options[$option] );
1321 $o2 = $this->optionToString( $other->options[$option] );
1322 if ( $o1 !== $o2 ) {
1323 return false;
1324 }
1325 }
1326
1327 return true;
1328 }
1329
1335 public function registerWatcher( $callback ) {
1336 $this->onAccessCallback = $callback;
1337 }
1338
1347 public function optionUsed( $optionName ) {
1348 if ( $this->onAccessCallback ) {
1349 call_user_func( $this->onAccessCallback, $optionName );
1350 }
1351 }
1352
1358 public static function allCacheVaryingOptions() {
1359 // Trigger a call to the 'ParserOptionsRegister' hook if it hasn't
1360 // already been called.
1361 if ( self::$defaults === null ) {
1362 self::getDefaults();
1363 }
1364 return array_keys( array_filter( self::$inCacheKey ) );
1365 }
1366
1372 private function optionToString( $value ) {
1373 if ( $value === true ) {
1374 return '1';
1375 } elseif ( $value === false ) {
1376 return '0';
1377 } elseif ( $value === null ) {
1378 return '';
1379 } elseif ( $value instanceof Language ) {
1380 return $value->getCode();
1381 } elseif ( is_array( $value ) ) {
1382 return '[' . implode( ',', array_map( [ $this, 'optionToString' ], $value ) ) . ']';
1383 } else {
1384 return (string)$value;
1385 }
1386 }
1387
1400 public function optionsHash( $forOptions, $title = null ) {
1401 global $wgRenderHashAppend;
1402
1403 $inCacheKey = self::allCacheVaryingOptions();
1404
1405 // Resolve any lazy options
1406 $lazyOpts = array_intersect( $forOptions, $inCacheKey, array_keys( self::$lazyOptions ) );
1407 foreach ( $lazyOpts as $k ) {
1408 $this->lazyLoadOption( $k );
1409 }
1410
1411 $options = $this->options;
1412 $defaults = self::getCanonicalOverrides() + self::getDefaults();
1413
1414 // We only include used options with non-canonical values in the key
1415 // so adding a new option doesn't invalidate the entire parser cache.
1416 // The drawback to this is that changing the default value of an option
1417 // requires manual invalidation of existing cache entries, as mentioned
1418 // in the docs on the relevant methods and hooks.
1419 $values = [];
1420 foreach ( array_intersect( $inCacheKey, $forOptions ) as $option ) {
1421 $v = $this->optionToString( $options[$option] );
1422 $d = $this->optionToString( $defaults[$option] );
1423 if ( $v !== $d ) {
1424 $values[] = "$option=$v";
1425 }
1426 }
1427
1428 $confstr = $values ? implode( '!', $values ) : 'canonical';
1429
1430 // add in language specific options, if any
1431 // @todo FIXME: This is just a way of retrieving the url/user preferred variant
1432
1433 $lang = $title ? $title->getPageLanguage() :
1434 MediaWikiServices::getInstance()->getContentLanguage();
1435 $converter = MediaWikiServices::getInstance()->getLanguageConverterFactory()
1436 ->getLanguageConverter( $lang );
1437 $confstr .= $converter->getExtraHashOptions();
1438
1439 $confstr .= $wgRenderHashAppend;
1440
1441 if ( $this->mExtraKey != '' ) {
1442 $confstr .= $this->mExtraKey;
1443 }
1444
1445 // Give a chance for extensions to modify the hash, if they have
1446 // extra options or other effects on the parser cache.
1447 Hooks::runner()->onPageRenderingHash( $confstr, $this->getUser(), $forOptions );
1448
1449 // Make it a valid memcached key fragment
1450 $confstr = str_replace( ' ', '_', $confstr );
1451
1452 return $confstr;
1453 }
1454
1460 public function isSafeToCache() {
1461 $defaults = self::getCanonicalOverrides() + self::getDefaults();
1462 foreach ( $this->options as $option => $value ) {
1463 if ( empty( self::$inCacheKey[$option] ) ) {
1464 $v = $this->optionToString( $value );
1465 $d = $this->optionToString( $defaults[$option] );
1466 if ( $v !== $d ) {
1467 return false;
1468 }
1469 }
1470 }
1471 return true;
1472 }
1473
1484 public function setupFakeRevision( $title, $content, $user ) {
1485 $oldCallback = $this->setCurrentRevisionRecordCallback(
1486 function (
1487 $titleToCheck, $parser = null ) use ( $title, $content, $user, &$oldCallback
1488 ) {
1489 if ( $titleToCheck->equals( $title ) ) {
1490 $revRecord = new MutableRevisionRecord( $title );
1491 $revRecord->setContent( SlotRecord::MAIN, $content );
1492 $revRecord->setUser( $user );
1493 $revRecord->setTimestamp( MWTimestamp::now( TS_MW ) );
1494 $revRecord->setPageId( $title->getArticleID() );
1495 $revRecord->setParentId( $title->getLatestRevID() );
1496 return $revRecord;
1497 } else {
1498 return call_user_func( $oldCallback, $titleToCheck, $parser );
1499 }
1500 }
1501 );
1502
1503 global $wgHooks;
1504 $wgHooks['TitleExists'][] =
1505 function ( $titleToCheck, &$exists ) use ( $title ) {
1506 if ( $titleToCheck->equals( $title ) ) {
1507 $exists = true;
1508 }
1509 };
1510 end( $wgHooks['TitleExists'] );
1511 $key = key( $wgHooks['TitleExists'] );
1512 $linkCache = MediaWikiServices::getInstance()->getLinkCache();
1513 $linkCache->clearBadLink( $title->getPrefixedDBkey() );
1514 return new ScopedCallback( function () use ( $title, $key, $linkCache ) {
1515 global $wgHooks;
1516 unset( $wgHooks['TitleExists'][$key] );
1517 $linkCache->clearLink( $title );
1518 } );
1519 }
1520}
1521
getUser()
$wgMaxTemplateDepth
Maximum recursion depth for templates within templates.
$wgMaxPPNodeCount
A complexity limit on template expansion: the maximum number of nodes visited by PPFrame::expand()
$wgMaxArticleSize
Maximum article size in kilobytes.
$wgEnableParserLimitReporting
Whether to include the NewPP limit report as a HTML comment.
$wgEnableImageWhitelist
If $wgAllowExternalImages is false, you can allow an on-wiki allow list of regular expression fragmen...
$wgCleanSignatures
If true, removes (by substituting) templates in signatures.
$wgRenderHashAppend
Append a configured value to the parser cache and the sitenotice key so that they can be kept separat...
$wgMaxPPExpandDepth
$wgDisableLangConversion
Whether to enable language variant conversion.
$wgAllowSpecialInclusion
Allow special page inclusions such as {{Special:Allpages}}.
$wgAllowExternalImagesFrom
If the above is false, you can specify an exception here.
$wgHooks
Global list of hooks.
$wgInterwikiMagic
Treat language links as magic connectors, not inline links.
$wgAllowExternalImages
Whether to allow inline image pointing to other websites.
$wgEnableMagicLinks
Enable the magic links feature of automatically turning ISBN xxx, PMID xxx, RFC xxx into links.
$wgExternalLinkTarget
Set a default target for external links, e.g.
$wgExpensiveParserFunctionLimit
Maximum number of calls per parse to expensive parser functions such as PAGESINCATEGORY.
$wgDisableTitleConversion
Whether to enable language variant conversion for links.
wfTimestampNow()
Convenience function; returns MediaWiki timestamp for the present time.
wfDeprecatedMsg( $msg, $version=false, $component=false, $callerOffset=2)
Log a deprecation warning with arbitrary message text.
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...
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Logs a warning that $function is deprecated.
$wgLang
Definition Setup.php:781
Internationalisation code See https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation for more...
Definition Language.php:41
MediaWikiServices is the service locator for the application scope of MediaWiki.
Value object representing a content slot associated with a page revision.
Set options of the Parser.
setAllowExternalImagesFrom( $x)
External images to allow.
disableTitleConversion( $x=true)
Whether title conversion should be disabled.
setIsSectionPreview( $x)
Parsing the page for a "preview" operation on a single section?
setIsPrintable( $x)
Parsing the printable version of the page?
getRedirectTarget()
Get the previously-set redirect target.
getCurrentRevisionRecordCallback()
Callback for current revision fetching; first argument to call_user_func().
setAllowUnsafeRawHtml( $x)
If the wiki is configured to allow raw html ($wgRawHtml = true) is it allowed in the specific case of...
static callable[] $lazyOptions
Lazy-loaded options.
matchesForCacheKey(ParserOptions $other)
getTidy()
Use tidy to cleanup output HTML?
static initSpeculativeRevId(ParserOptions $popt)
Callback registered with ParserOptions::$lazyOptions, triggered by getSpeculativeRevId().
setIsPreview( $x)
Parsing the page for a "preview" operation?
setDateFormat( $x)
Date format index.
enableLimitReport( $x=true)
Enable limit report in an HTML comment on output.
setTidy( $x)
Use tidy to cleanup output HTML?
optionToString( $value)
Convert an option to a string value.
callable null $onAccessCallback
Function to be called when an option is accessed.
getAllowExternalImages()
Allow all external images inline?
static initDateFormat(ParserOptions $popt)
Lazy initializer for dateFormat.
setNumberHeadings( $x)
Automatically number headings?
static initSpeculativePageId(ParserOptions $popt)
Callback registered with ParserOptions::$lazyOptions, triggered by getSpeculativePageId().
matches(ParserOptions $other)
Check if these options match that of another options set.
getMaxIncludeSize()
Maximum size of template expansions, in bytes.
setStubThreshold( $x)
Thumb size preferred by the user.
setTemplateCallback( $x)
Callback for template fetching; first argument to call_user_func().
setAllowExternalImages( $x)
Allow all external images inline?
getUserLangObj()
Get the user language used by the parser for this page and split the parser cache.
setMaxIncludeSize( $x)
Maximum size of template expansions, in bytes.
static newCanonical( $context=null, $userLang=null)
Creates a "canonical" ParserOptions object.
static getCanonicalOverrides()
Get "canonical" non-default option values.
getEnableImageWhitelist()
Use the on-wiki external image whitelist?
getTargetLanguage()
Target language for the parse.
getAllowExternalImagesFrom()
External images to allow.
getCurrentRevisionCallback()
Callback for current revision fetching; first argument to call_user_func().
getIsSectionPreview()
Parsing the page for a "preview" operation on a single section?
getDisableContentConversion()
Whether content conversion should be disabled.
setInterfaceMessage( $x)
Parsing an interface message?
setTimestamp( $x)
Timestamp used for {{CURRENTDAY}} etc.
getMaxPPExpandDepth()
Maximum recursion depth in PPFrame::expand()
getExpensiveParserFunctionLimit()
Maximum number of calls per parse to expensive parser functions.
getAllowUnsafeRawHtml()
If the wiki is configured to allow raw html ($wgRawHtml = true) is it allowed in the specific case of...
getNumberHeadings()
Automatically number headings?
setCurrentRevisionCallback( $x)
Callback for current revision fetching; first argument to call_user_func().
getIsPreview()
Parsing the page for a "preview" operation?
static getDefaults()
Get default option values.
setOptionLegacy( $name, $value)
Legacy implementation.
setCurrentRevisionRecordCallback( $x)
Callback for current revision fetching; first argument to call_user_func().
getSpeculativePageId()
A guess for {{PAGEID}}, calculated using the callback provided via setSpeculativeRevPageCallback().
setMaxTemplateDepth( $x)
Maximum recursion depth for templates within templates.
setEnableImageWhitelist( $x)
Use the on-wiki external image whitelist?
getPreSaveTransform()
Transform wiki markup when saving the page?
setWrapOutputClass( $className)
CSS class to use to wrap output from Parser::parse()
User $mUser
Stored user object.
getUser()
Current user.
optionUsed( $optionName)
Called when an option is accessed.
setRedirectTarget( $title)
Set the redirect target.
getWrapOutputClass()
Class to use to wrap output from Parser::parse()
getIsPrintable()
Parsing the printable version of the page?
getStubThreshold()
Thumb size preferred by the user.
disableContentConversion( $x=true)
Whether content conversion should be disabled.
initialiseFromUser( $user, $lang)
Get user options.
getOption( $name)
Fetch an option and track that is was accessed.
setThumbSize( $x)
Thumb size preferred by the user.
optionsHash( $forOptions, $title=null)
Generate a hash string with the values set on these ParserOptions for the keys given in the array.
$mExtraKey
Appended to the options hash.
setAllowSpecialInclusion( $x)
Allow inclusion of special pages?
setOption( $name, $value)
Set an option, generically.
getMaxTemplateDepth()
Maximum recursion depth for templates within templates.
getAllowSpecialInclusion()
Allow inclusion of special pages?
setTargetLanguage( $x)
Target language for the parse.
string null $mTimestamp
Timestamp used for {{CURRENTDAY}} etc.
getMagicRFCLinks()
Are magic RFC links enabled?
setupFakeRevision( $title, $content, $user)
Sets a hook to force that a page exists, and sets a current revision callback to return a revision wi...
getMagicPMIDLinks()
Are magic PMID links enabled?
static array $inCacheKey
Specify options that are included in the cache key.
static newFromContext(IContextSource $context)
Get a ParserOptions object from a IContextSource object.
registerWatcher( $callback)
Registers a callback for tracking which ParserOptions which are used.
getCleanSignatures()
Clean up signature texts?
addExtraKey( $key)
Extra key that should be present in the parser cache key.
setInterwikiMagic( $x)
Specify whether to extract interlanguage links.
static newFromAnon()
Get a ParserOptions object for an anonymous user.
setUserLang( $x)
Set the user language used by the parser for this page and split the parser cache.
static newFromUser( $user)
Get a ParserOptions object from a given user.
getUserLang()
Same as getUserLangObj() but returns a string instead.
getDateFormat()
Date format index.
setExternalLinkTarget( $x)
Target attribute for external links.
lazyLoadOption( $name)
array $options
Current values for all options that are relevant for caching.
getRemoveComments()
Remove HTML comments.
setRemoveComments( $x)
Remove HTML comments.
Title null $redirectTarget
If the page being parsed is a redirect, this should hold the redirect target.
getMaxPPNodeCount()
Maximum number of nodes touched by PPFrame::expand()
static newFromUserAndLang(User $user, Language $lang)
Get a ParserOptions object from a given user and language.
getEnableLimitReport()
Enable limit report in an HTML comment on output.
getExternalLinkTarget()
Target attribute for external links.
getMagicISBNLinks()
Are magic ISBN links enabled?
getThumbSize()
Thumb size preferred by the user.
getInterwikiMagic()
Whether to extract interlanguage links.
__construct( $user=null, $lang=null)
getTimestamp()
Timestamp used for {{CURRENTDAY}} etc.
getTemplateCallback()
Callback for template fetching; first argument to call_user_func().
getSpeculativeRevId()
A guess for {{REVISIONID}}, calculated using the callback provided via setSpeculativeRevIdCallback().
setSpeculativeRevIdCallback( $x)
Callback to generate a guess for {{REVISIONID}}.
isSafeToCache()
Test whether these options are safe to cache.
getDisableTitleConversion()
Whether title conversion should be disabled.
getInterfaceMessage()
Parsing an interface message?
static allCacheVaryingOptions()
Return all option keys that vary the options hash.
setExpensiveParserFunctionLimit( $x)
Maximum number of calls per parse to expensive parser functions.
setPreSaveTransform( $x)
Transform wiki markup when saving the page?
setMaxPPNodeCount( $x)
Maximum number of nodes touched by PPFrame::expand()
static array null $defaults
Default values for all options that are relevant for caching.
setCleanSignatures( $x)
Clean up signature texts?
setSpeculativePageIdCallback( $x)
Callback to generate a guess for {{PAGEID}}.
static unstub(&$obj)
Unstubs an object, if it is a stub object.
Represents a title within MediaWiki.
Definition Title.php:42
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition User.php:60
static getDefaultOption( $opt)
Get a given default option value.
Definition User.php:1553
Interface for objects which can provide a MediaWiki context on request.
$content
Definition router.php:76
if(!isset( $args[0])) $lang