MediaWiki fundraising/REL1_35
CoreParserFunctions.php
Go to the documentation of this file.
1<?php
27
37 public static function register( $parser ) {
39
40 # Syntax for arguments (see Parser::setFunctionHook):
41 # "name for lookup in localized magic words array",
42 # function callback,
43 # optional Parser::SFH_NO_HASH to omit the hash from calls (e.g. {{int:...}}
44 # instead of {{#int:...}})
45 $noHashFunctions = [
46 'ns', 'nse', 'urlencode', 'lcfirst', 'ucfirst', 'lc', 'uc',
47 'localurl', 'localurle', 'fullurl', 'fullurle', 'canonicalurl',
48 'canonicalurle', 'formatnum', 'grammar', 'gender', 'plural', 'bidi',
49 'numberofpages', 'numberofusers', 'numberofactiveusers',
50 'numberofarticles', 'numberoffiles', 'numberofadmins',
51 'numberingroup', 'numberofedits', 'language',
52 'padleft', 'padright', 'anchorencode', 'defaultsort', 'filepath',
53 'pagesincategory', 'pagesize', 'protectionlevel', 'protectionexpiry',
54 'namespacee', 'namespacenumber', 'talkspace', 'talkspacee',
55 'subjectspace', 'subjectspacee', 'pagename', 'pagenamee',
56 'fullpagename', 'fullpagenamee', 'rootpagename', 'rootpagenamee',
57 'basepagename', 'basepagenamee', 'subpagename', 'subpagenamee',
58 'talkpagename', 'talkpagenamee', 'subjectpagename',
59 'subjectpagenamee', 'pageid', 'revisionid', 'revisionday',
60 'revisionday2', 'revisionmonth', 'revisionmonth1', 'revisionyear',
61 'revisiontimestamp', 'revisionuser', 'cascadingsources',
62 ];
63 foreach ( $noHashFunctions as $func ) {
64 $parser->setFunctionHook( $func, [ __CLASS__, $func ], Parser::SFH_NO_HASH );
65 }
66
67 $parser->setFunctionHook(
68 'namespace',
69 [ __CLASS__, 'mwnamespace' ],
70 Parser::SFH_NO_HASH
71 );
72 $parser->setFunctionHook( 'int', [ __CLASS__, 'intFunction' ], Parser::SFH_NO_HASH );
73 $parser->setFunctionHook( 'special', [ __CLASS__, 'special' ] );
74 $parser->setFunctionHook( 'speciale', [ __CLASS__, 'speciale' ] );
75 $parser->setFunctionHook( 'tag', [ __CLASS__, 'tagObj' ], Parser::SFH_OBJECT_ARGS );
76 $parser->setFunctionHook( 'formatdate', [ __CLASS__, 'formatDate' ] );
77
79 $parser->setFunctionHook(
80 'displaytitle',
81 [ __CLASS__, 'displaytitle' ],
82 Parser::SFH_NO_HASH
83 );
84 }
86 $parser->setFunctionHook(
87 'pagesinnamespace',
88 [ __CLASS__, 'pagesinnamespace' ],
89 Parser::SFH_NO_HASH
90 );
91 }
92 }
93
100 public static function intFunction( $parser, $part1 = '', ...$params ) {
101 if ( strval( $part1 ) !== '' ) {
102 $message = wfMessage( $part1, $params )
103 ->inLanguage( $parser->getOptions()->getUserLangObj() );
104 return [ $message->plain(), 'noparse' => false ];
105 } else {
106 return [ 'found' => false ];
107 }
108 }
109
117 public static function formatDate( $parser, $date, $defaultPref = null ) {
118 $lang = $parser->getFunctionLang();
119 $df = MediaWikiServices::getInstance()->getDateFormatterFactory()->get( $lang );
120
121 $date = trim( $date );
122
123 $pref = $parser->getOptions()->getDateFormat();
124
125 // Specify a different default date format other than the normal default
126 // if the user has 'default' for their setting
127 if ( $pref == 'default' && $defaultPref ) {
128 $pref = $defaultPref;
129 }
130
131 $date = $df->reformat( $pref, $date, [ 'match-whole' ] );
132 return $date;
133 }
134
135 public static function ns( $parser, $part1 = '' ) {
136 if ( intval( $part1 ) || $part1 == "0" ) {
137 $index = intval( $part1 );
138 } else {
139 $index = $parser->getContentLanguage()->getNsIndex( str_replace( ' ', '_', $part1 ) );
140 }
141 if ( $index !== false ) {
142 return $parser->getContentLanguage()->getFormattedNsText( $index );
143 } else {
144 return [ 'found' => false ];
145 }
146 }
147
148 public static function nse( $parser, $part1 = '' ) {
149 $ret = self::ns( $parser, $part1 );
150 if ( is_string( $ret ) ) {
151 $ret = wfUrlencode( str_replace( ' ', '_', $ret ) );
152 }
153 return $ret;
154 }
155
168 public static function urlencode( $parser, $s = '', $arg = null ) {
169 static $magicWords = null;
170 if ( $magicWords === null ) {
172 $parser->getMagicWordFactory()->newArray( [ 'url_path', 'url_query', 'url_wiki' ] );
173 }
174 switch ( $magicWords->matchStartToEnd( $arg ?? '' ) ) {
175 // Encode as though it's a wiki page, '_' for ' '.
176 case 'url_wiki':
177 $func = 'wfUrlencode';
178 $s = str_replace( ' ', '_', $s );
179 break;
180
181 // Encode for an HTTP Path, '%20' for ' '.
182 case 'url_path':
183 $func = 'rawurlencode';
184 break;
185
186 // Encode for HTTP query, '+' for ' '.
187 case 'url_query':
188 default:
189 $func = 'urlencode';
190 }
191 // See T105242, where the choice to kill markers and various
192 // other options were discussed.
193 return $func( $parser->killMarkers( $s ) );
194 }
195
196 public static function lcfirst( $parser, $s = '' ) {
197 return $parser->getContentLanguage()->lcfirst( $s );
198 }
199
200 public static function ucfirst( $parser, $s = '' ) {
201 return $parser->getContentLanguage()->ucfirst( $s );
202 }
203
209 public static function lc( $parser, $s = '' ) {
210 return $parser->markerSkipCallback( $s, [ $parser->getContentLanguage(), 'lc' ] );
211 }
212
218 public static function uc( $parser, $s = '' ) {
219 return $parser->markerSkipCallback( $s, [ $parser->getContentLanguage(), 'uc' ] );
220 }
221
222 public static function localurl( $parser, $s = '', $arg = null ) {
223 return self::urlFunction( 'getLocalURL', $s, $arg );
224 }
225
226 public static function localurle( $parser, $s = '', $arg = null ) {
227 $temp = self::urlFunction( 'getLocalURL', $s, $arg );
228 if ( !is_string( $temp ) ) {
229 return $temp;
230 } else {
231 return htmlspecialchars( $temp );
232 }
233 }
234
235 public static function fullurl( $parser, $s = '', $arg = null ) {
236 return self::urlFunction( 'getFullURL', $s, $arg );
237 }
238
239 public static function fullurle( $parser, $s = '', $arg = null ) {
240 $temp = self::urlFunction( 'getFullURL', $s, $arg );
241 if ( !is_string( $temp ) ) {
242 return $temp;
243 } else {
244 return htmlspecialchars( $temp );
245 }
246 }
247
248 public static function canonicalurl( $parser, $s = '', $arg = null ) {
249 return self::urlFunction( 'getCanonicalURL', $s, $arg );
250 }
251
252 public static function canonicalurle( $parser, $s = '', $arg = null ) {
253 $temp = self::urlFunction( 'getCanonicalURL', $s, $arg );
254 if ( !is_string( $temp ) ) {
255 return $temp;
256 } else {
257 return htmlspecialchars( $temp );
258 }
259 }
260
261 public static function urlFunction( $func, $s = '', $arg = null ) {
262 $title = Title::newFromText( $s );
263 # Due to order of execution of a lot of bits, the values might be encoded
264 # before arriving here; if that's true, then the title can't be created
265 # and the variable will fail. If we can't get a decent title from the first
266 # attempt, url-decode and try for a second.
267 if ( $title === null ) {
268 $title = Title::newFromURL( urldecode( $s ) );
269 }
270 if ( $title !== null ) {
271 # Convert NS_MEDIA -> NS_FILE
272 if ( $title->inNamespace( NS_MEDIA ) ) {
273 $title = Title::makeTitle( NS_FILE, $title->getDBkey() );
274 }
275 if ( $arg !== null ) {
276 $text = $title->$func( $arg );
277 } else {
278 $text = $title->$func();
279 }
280 return $text;
281 } else {
282 return [ 'found' => false ];
283 }
284 }
285
292 public static function formatnum( $parser, $num = '', $arg = null ) {
293 if ( self::matchAgainstMagicword( $parser->getMagicWordFactory(), 'rawsuffix', $arg ) ) {
294 $func = [ $parser->getFunctionLang(), 'parseFormattedNumber' ];
295 } elseif (
296 self::matchAgainstMagicword( $parser->getMagicWordFactory(), 'nocommafysuffix', $arg )
297 ) {
298 $func = [ $parser->getFunctionLang(), 'formatNumNoSeparators' ];
299 } else {
300 $func = [ $parser->getFunctionLang(), 'formatNum' ];
301 }
302 return $parser->markerSkipCallback( $num, $func );
303 }
304
311 public static function grammar( $parser, $case = '', $word = '' ) {
312 $word = $parser->killMarkers( $word );
313 return $parser->getFunctionLang()->convertGrammar( $word, $case );
314 }
315
322 public static function gender( $parser, $username, ...$forms ) {
323 // Some shortcuts to avoid loading user data unnecessarily
324 if ( count( $forms ) === 0 ) {
325 return '';
326 } elseif ( count( $forms ) === 1 ) {
327 return $forms[0];
328 }
329
330 $username = trim( $username );
331
332 $gender = User::getDefaultOption( 'gender' );
333
334 // allow prefix and normalize (e.g. "&#42;foo" -> "*foo" ).
335 $title = Title::newFromText( $username, NS_USER );
336
337 if ( $title && $title->inNamespace( NS_USER ) ) {
338 $username = $title->getText();
339 }
340
341 // check parameter, or use the ParserOptions if in interface message
342 $user = User::newFromName( $username );
343 $genderCache = MediaWikiServices::getInstance()->getGenderCache();
344 if ( $user ) {
345 $gender = $genderCache->getGenderOf( $user, __METHOD__ );
346 } elseif ( $username === '' && $parser->getOptions()->getInterfaceMessage() ) {
347 $gender = $genderCache->getGenderOf( $parser->getOptions()->getUser(), __METHOD__ );
348 }
349 $ret = $parser->getFunctionLang()->gender( $gender, $forms );
350 return $ret;
351 }
352
359 public static function plural( $parser, $text = '', ...$forms ) {
360 $text = $parser->getFunctionLang()->parseFormattedNumber( $text );
361 settype( $text, ctype_digit( $text ) ? 'int' : 'float' );
362 return $parser->getFunctionLang()->convertPlural( $text, $forms );
363 }
364
370 public static function bidi( $parser, $text = '' ) {
371 return $parser->getFunctionLang()->embedBidi( $text );
372 }
373
379 private static function getTargetLanguageConverter( Parser $parser ) : ILanguageConverter {
380 return MediaWikiServices::getInstance()->getLanguageConverterFactory()
381 ->getLanguageConverter( $parser->getTargetLanguage() );
382 }
383
393 public static function displaytitle( $parser, $text = '', $uarg = '' ) {
395
396 static $magicWords = null;
397 if ( $magicWords === null ) {
398 $magicWords = $parser->getMagicWordFactory()->newArray(
399 [ 'displaytitle_noerror', 'displaytitle_noreplace' ] );
400 }
401 $arg = $magicWords->matchStartToEnd( $uarg );
402
403 // parse a limited subset of wiki markup (just the single quote items)
404 $text = $parser->doQuotes( $text );
405
406 // remove stripped text (e.g. the UNIQ-QINU stuff) that was generated by tag extensions/whatever
407 $text = $parser->killMarkers( $text );
408
409 // list of disallowed tags for DISPLAYTITLE
410 // these will be escaped even though they are allowed in normal wiki text
411 $bad = [ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'blockquote', 'ol', 'ul', 'li', 'hr',
412 'table', 'tr', 'th', 'td', 'dl', 'dd', 'caption', 'p', 'ruby', 'rb', 'rt', 'rtc', 'rp', 'br' ];
413
414 // disallow some styles that could be used to bypass $wgRestrictDisplayTitle
416 $htmlTagsCallback = function ( &$params ) {
417 $decoded = Sanitizer::decodeTagAttributes( $params );
418
419 if ( isset( $decoded['style'] ) ) {
420 // this is called later anyway, but we need it right now for the regexes below to be safe
421 // calling it twice doesn't hurt
422 $decoded['style'] = Sanitizer::checkCss( $decoded['style'] );
423
424 if ( preg_match( '/(display|user-select|visibility)\s*:/i', $decoded['style'] ) ) {
425 $decoded['style'] = '/* attempt to bypass $wgRestrictDisplayTitle */';
426 }
427 }
428
429 $params = Sanitizer::safeEncodeTagAttributes( $decoded );
430 };
431 } else {
432 $htmlTagsCallback = null;
433 }
434
435 // only requested titles that normalize to the actual title are allowed through
436 // if $wgRestrictDisplayTitle is true (it is by default)
437 // mimic the escaping process that occurs in OutputPage::setPageTitle
438 $text = Sanitizer::normalizeCharReferences( Sanitizer::removeHTMLtags(
439 $text,
440 $htmlTagsCallback,
441 [],
442 [],
443 $bad
444 ) );
445 $title = Title::newFromText( Sanitizer::stripAllTags( $text ) );
446
448 ( $title instanceof Title
449 && !$title->hasFragment()
450 && $title->equals( $parser->getTitle() ) )
451 ) {
452 $old = $parser->mOutput->getProperty( 'displaytitle' );
453 if ( $old === false || $arg !== 'displaytitle_noreplace' ) {
454 $parser->mOutput->setDisplayTitle( $text );
455 }
456 if ( $old !== false && $old !== $text && !$arg ) {
457
458 $converter = self::getTargetLanguageConverter( $parser );
459 return '<span class="error">' .
460 wfMessage( 'duplicate-displaytitle',
461 // Message should be parsed, but these params should only be escaped.
462 $converter->markNoConversion( wfEscapeWikiText( $old ) ),
463 $converter->markNoConversion( wfEscapeWikiText( $text ) )
464 )->inContentLanguage()->text() .
465 '</span>';
466 } else {
467 return '';
468 }
469 } else {
470 $parser->getOutput()->addWarning(
471 wfMessage( 'restricted-displaytitle',
472 // Message should be parsed, but this param should only be escaped.
473 wfEscapeWikiText( $text )
474 )->text()
475 );
476 $parser->addTrackingCategory( 'restricted-displaytitle-ignored' );
477 }
478 }
479
489 private static function matchAgainstMagicword(
490 MagicWordFactory $magicWordFactory, $magicword, $value
491 ) {
492 $value = trim( strval( $value ) );
493 if ( $value === '' ) {
494 return false;
495 }
496 $mwObject = $magicWordFactory->get( $magicword );
497 return $mwObject->matchStartToEnd( $value );
498 }
499
509 public static function formatRaw(
510 $num, $raw, $language, MagicWordFactory $magicWordFactory = null
511 ) {
512 if ( $raw !== null && !$magicWordFactory ) {
513 $magicWordFactory = MediaWikiServices::getInstance()->getMagicWordFactory();
514 }
515 if (
516 $raw !== null && self::matchAgainstMagicword( $magicWordFactory, 'rawsuffix', $raw )
517 ) {
518 return $num;
519 } else {
520 return $language->formatNum( $num );
521 }
522 }
523
524 public static function numberofpages( $parser, $raw = null ) {
525 return self::formatRaw( SiteStats::pages(), $raw, $parser->getFunctionLang() );
526 }
527
528 public static function numberofusers( $parser, $raw = null ) {
529 return self::formatRaw( SiteStats::users(), $raw, $parser->getFunctionLang() );
530 }
531
532 public static function numberofactiveusers( $parser, $raw = null ) {
533 return self::formatRaw( SiteStats::activeUsers(), $raw, $parser->getFunctionLang() );
534 }
535
536 public static function numberofarticles( $parser, $raw = null ) {
537 return self::formatRaw( SiteStats::articles(), $raw, $parser->getFunctionLang() );
538 }
539
540 public static function numberoffiles( $parser, $raw = null ) {
541 return self::formatRaw( SiteStats::images(), $raw, $parser->getFunctionLang() );
542 }
543
544 public static function numberofadmins( $parser, $raw = null ) {
545 return self::formatRaw(
546 SiteStats::numberingroup( 'sysop' ),
547 $raw,
548 $parser->getFunctionLang()
549 );
550 }
551
552 public static function numberofedits( $parser, $raw = null ) {
553 return self::formatRaw( SiteStats::edits(), $raw, $parser->getFunctionLang() );
554 }
555
556 public static function pagesinnamespace( $parser, $namespace = 0, $raw = null ) {
557 return self::formatRaw(
558 SiteStats::pagesInNs( intval( $namespace ) ),
559 $raw,
560 $parser->getFunctionLang()
561 );
562 }
563
564 public static function numberingroup( $parser, $name = '', $raw = null ) {
565 return self::formatRaw(
566 SiteStats::numberingroup( strtolower( $name ) ),
567 $raw,
568 $parser->getFunctionLang()
569 );
570 }
571
581 public static function mwnamespace( $parser, $title = null ) {
582 $t = Title::newFromText( $title );
583 if ( $t === null ) {
584 return '';
585 }
586 return str_replace( '_', ' ', $t->getNsText() );
587 }
588
589 public static function namespacee( $parser, $title = null ) {
590 $t = Title::newFromText( $title );
591 if ( $t === null ) {
592 return '';
593 }
594 return wfUrlencode( $t->getNsText() );
595 }
596
597 public static function namespacenumber( $parser, $title = null ) {
598 $t = Title::newFromText( $title );
599 if ( $t === null ) {
600 return '';
601 }
602 return $t->getNamespace();
603 }
604
605 public static function talkspace( $parser, $title = null ) {
606 $t = Title::newFromText( $title );
607 if ( $t === null || !$t->canHaveTalkPage() ) {
608 return '';
609 }
610 return str_replace( '_', ' ', $t->getTalkNsText() );
611 }
612
613 public static function talkspacee( $parser, $title = null ) {
614 $t = Title::newFromText( $title );
615 if ( $t === null || !$t->canHaveTalkPage() ) {
616 return '';
617 }
618 return wfUrlencode( $t->getTalkNsText() );
619 }
620
621 public static function subjectspace( $parser, $title = null ) {
622 $t = Title::newFromText( $title );
623 if ( $t === null ) {
624 return '';
625 }
626 return str_replace( '_', ' ', $t->getSubjectNsText() );
627 }
628
629 public static function subjectspacee( $parser, $title = null ) {
630 $t = Title::newFromText( $title );
631 if ( $t === null ) {
632 return '';
633 }
634 return wfUrlencode( $t->getSubjectNsText() );
635 }
636
644 public static function pagename( $parser, $title = null ) {
645 $t = Title::newFromText( $title );
646 if ( $t === null ) {
647 return '';
648 }
649 return wfEscapeWikiText( $t->getText() );
650 }
651
652 public static function pagenamee( $parser, $title = null ) {
653 $t = Title::newFromText( $title );
654 if ( $t === null ) {
655 return '';
656 }
657 return wfEscapeWikiText( $t->getPartialURL() );
658 }
659
660 public static function fullpagename( $parser, $title = null ) {
661 $t = Title::newFromText( $title );
662 if ( $t === null || !$t->canHaveTalkPage() ) {
663 return '';
664 }
665 return wfEscapeWikiText( $t->getPrefixedText() );
666 }
667
668 public static function fullpagenamee( $parser, $title = null ) {
669 $t = Title::newFromText( $title );
670 if ( $t === null || !$t->canHaveTalkPage() ) {
671 return '';
672 }
673 return wfEscapeWikiText( $t->getPrefixedURL() );
674 }
675
676 public static function subpagename( $parser, $title = null ) {
677 $t = Title::newFromText( $title );
678 if ( $t === null ) {
679 return '';
680 }
681 return wfEscapeWikiText( $t->getSubpageText() );
682 }
683
684 public static function subpagenamee( $parser, $title = null ) {
685 $t = Title::newFromText( $title );
686 if ( $t === null ) {
687 return '';
688 }
689 return wfEscapeWikiText( $t->getSubpageUrlForm() );
690 }
691
692 public static function rootpagename( $parser, $title = null ) {
693 $t = Title::newFromText( $title );
694 if ( $t === null ) {
695 return '';
696 }
697 return wfEscapeWikiText( $t->getRootText() );
698 }
699
700 public static function rootpagenamee( $parser, $title = null ) {
701 $t = Title::newFromText( $title );
702 if ( $t === null ) {
703 return '';
704 }
705 return wfEscapeWikiText( wfUrlencode( str_replace( ' ', '_', $t->getRootText() ) ) );
706 }
707
708 public static function basepagename( $parser, $title = null ) {
709 $t = Title::newFromText( $title );
710 if ( $t === null ) {
711 return '';
712 }
713 return wfEscapeWikiText( $t->getBaseText() );
714 }
715
716 public static function basepagenamee( $parser, $title = null ) {
717 $t = Title::newFromText( $title );
718 if ( $t === null ) {
719 return '';
720 }
721 return wfEscapeWikiText( wfUrlencode( str_replace( ' ', '_', $t->getBaseText() ) ) );
722 }
723
724 public static function talkpagename( $parser, $title = null ) {
725 $t = Title::newFromText( $title );
726 if ( $t === null || !$t->canHaveTalkPage() ) {
727 return '';
728 }
729 return wfEscapeWikiText( $t->getTalkPage()->getPrefixedText() );
730 }
731
732 public static function talkpagenamee( $parser, $title = null ) {
733 $t = Title::newFromText( $title );
734 if ( $t === null || !$t->canHaveTalkPage() ) {
735 return '';
736 }
737 return wfEscapeWikiText( $t->getTalkPage()->getPrefixedURL() );
738 }
739
740 public static function subjectpagename( $parser, $title = null ) {
741 $t = Title::newFromText( $title );
742 if ( $t === null ) {
743 return '';
744 }
745 return wfEscapeWikiText( $t->getSubjectPage()->getPrefixedText() );
746 }
747
748 public static function subjectpagenamee( $parser, $title = null ) {
749 $t = Title::newFromText( $title );
750 if ( $t === null ) {
751 return '';
752 }
753 return wfEscapeWikiText( $t->getSubjectPage()->getPrefixedURL() );
754 }
755
766 public static function pagesincategory( $parser, $name = '', $arg1 = '', $arg2 = '' ) {
767 static $magicWords = null;
768 if ( $magicWords === null ) {
769 $magicWords = $parser->getMagicWordFactory()->newArray( [
770 'pagesincategory_all',
771 'pagesincategory_pages',
772 'pagesincategory_subcats',
773 'pagesincategory_files'
774 ] );
775 }
776 static $cache = [];
777
778 // split the given option to its variable
779 if ( self::matchAgainstMagicword( $parser->getMagicWordFactory(), 'rawsuffix', $arg1 ) ) {
780 // {{pagesincategory:|raw[|type]}}
781 $raw = $arg1;
782 $type = $magicWords->matchStartToEnd( $arg2 );
783 } else {
784 // {{pagesincategory:[|type[|raw]]}}
785 $type = $magicWords->matchStartToEnd( $arg1 );
786 $raw = $arg2;
787 }
788 if ( !$type ) { // backward compatibility
789 $type = 'pagesincategory_all';
790 }
791
792 $title = Title::makeTitleSafe( NS_CATEGORY, $name );
793 if ( !$title ) { # invalid title
794 return self::formatRaw( 0, $raw, $parser->getFunctionLang() );
795 }
796 $parser->getContentLanguage()->findVariantLink( $name, $title, true );
797
798 // Normalize name for cache
799 $name = $title->getDBkey();
800
801 if ( !isset( $cache[$name] ) ) {
802 $category = Category::newFromTitle( $title );
803
804 $allCount = $subcatCount = $fileCount = $pagesCount = 0;
805 if ( $parser->incrementExpensiveFunctionCount() ) {
806 // $allCount is the total number of cat members,
807 // not the count of how many members are normal pages.
808 $allCount = (int)$category->getPageCount();
809 $subcatCount = (int)$category->getSubcatCount();
810 $fileCount = (int)$category->getFileCount();
811 $pagesCount = $allCount - $subcatCount - $fileCount;
812 }
813 $cache[$name]['pagesincategory_all'] = $allCount;
814 $cache[$name]['pagesincategory_pages'] = $pagesCount;
815 $cache[$name]['pagesincategory_subcats'] = $subcatCount;
816 $cache[$name]['pagesincategory_files'] = $fileCount;
817 }
818
819 $count = $cache[$name][$type];
820 return self::formatRaw( $count, $raw, $parser->getFunctionLang() );
821 }
822
832 public static function pagesize( $parser, $page = '', $raw = null ) {
833 $title = Title::newFromText( $page );
834
835 if ( !is_object( $title ) ) {
836 return self::formatRaw( 0, $raw, $parser->getFunctionLang() );
837 }
838
839 // fetch revision from cache/database and return the value
840 $rev = self::getCachedRevisionObject( $parser, $title, 'vary-revision-sha1' );
841 $length = $rev ? $rev->getSize() : 0;
842 if ( $length === null ) {
843 // We've had bugs where rev_len was not being recorded for empty pages, see T135414
844 $length = 0;
845 }
846 return self::formatRaw( $length, $raw, $parser->getFunctionLang() );
847 }
848
861 public static function protectionlevel( $parser, $type = '', $title = '' ) {
862 $titleObject = Title::newFromText( $title ) ?? $parser->getTitle();
863 if ( $titleObject->areRestrictionsLoaded() || $parser->incrementExpensiveFunctionCount() ) {
864 $restrictions = $titleObject->getRestrictions( strtolower( $type ) );
865 # Title::getRestrictions returns an array, its possible it may have
866 # multiple values in the future
867 return implode( ',', $restrictions );
868 }
869 return '';
870 }
871
884 public static function protectionexpiry( $parser, $type = '', $title = '' ) {
885 $titleObject = Title::newFromText( $title ) ?? $parser->getTitle();
886 if ( $titleObject->areRestrictionsLoaded() || $parser->incrementExpensiveFunctionCount() ) {
887 $expiry = $titleObject->getRestrictionExpiry( strtolower( $type ) );
888 // getRestrictionExpiry() returns false on invalid type; trying to
889 // match protectionlevel() function that returns empty string instead
890 if ( $expiry === false ) {
891 $expiry = '';
892 }
893 return $expiry;
894 }
895 return '';
896 }
897
905 public static function language( $parser, $code = '', $inLanguage = '' ) {
906 $code = strtolower( $code );
907 $inLanguage = strtolower( $inLanguage );
908 $lang = MediaWikiServices::getInstance()
909 ->getLanguageNameUtils()
910 ->getLanguageName( $code, $inLanguage );
911 return $lang !== '' ? $lang : LanguageCode::bcp47( $code );
912 }
913
923 public static function pad(
924 $parser, $string, $length, $padding = '0', $direction = STR_PAD_RIGHT
925 ) {
926 $padding = $parser->killMarkers( $padding );
927 $lengthOfPadding = mb_strlen( $padding );
928 if ( $lengthOfPadding == 0 ) {
929 return $string;
930 }
931
932 # The remaining length to add counts down to 0 as padding is added
933 $length = min( (int)$length, 500 ) - mb_strlen( $string );
934 if ( $length <= 0 ) {
935 // Nothing to add
936 return $string;
937 }
938
939 # $finalPadding is just $padding repeated enough times so that
940 # mb_strlen( $string ) + mb_strlen( $finalPadding ) == $length
941 $finalPadding = '';
942 while ( $length > 0 ) {
943 # If $length < $lengthofPadding, truncate $padding so we get the
944 # exact length desired.
945 $finalPadding .= mb_substr( $padding, 0, $length );
946 $length -= $lengthOfPadding;
947 }
948
949 if ( $direction == STR_PAD_LEFT ) {
950 return $finalPadding . $string;
951 } else {
952 return $string . $finalPadding;
953 }
954 }
955
956 public static function padleft( $parser, $string = '', $length = 0, $padding = '0' ) {
957 return self::pad( $parser, $string, $length, $padding, STR_PAD_LEFT );
958 }
959
960 public static function padright( $parser, $string = '', $length = 0, $padding = '0' ) {
961 return self::pad( $parser, $string, $length, $padding );
962 }
963
969 public static function anchorencode( $parser, $text ) {
970 $text = $parser->killMarkers( $text );
971 $section = (string)substr( $parser->guessSectionNameFromWikiText( $text ), 1 );
972 return Sanitizer::safeEncodeAttribute( $section );
973 }
974
975 public static function special( $parser, $text ) {
976 list( $page, $subpage ) = MediaWikiServices::getInstance()->getSpecialPageFactory()->
977 resolveAlias( $text );
978 if ( $page ) {
979 $title = SpecialPage::getTitleFor( $page, $subpage );
980 return $title->getPrefixedText();
981 } else {
982 // unknown special page, just use the given text as its title, if at all possible
983 $title = Title::makeTitleSafe( NS_SPECIAL, $text );
984 return $title ? $title->getPrefixedText() : self::special( $parser, 'Badtitle' );
985 }
986 }
987
988 public static function speciale( $parser, $text ) {
989 return wfUrlencode( str_replace( ' ', '_', self::special( $parser, $text ) ) );
990 }
991
1000 public static function defaultsort( $parser, $text, $uarg = '' ) {
1001 static $magicWords = null;
1002 if ( $magicWords === null ) {
1003 $magicWords = $parser->getMagicWordFactory()->newArray(
1004 [ 'defaultsort_noerror', 'defaultsort_noreplace' ] );
1005 }
1006 $arg = $magicWords->matchStartToEnd( $uarg );
1007
1008 $text = trim( $text );
1009 if ( strlen( $text ) == 0 ) {
1010 return '';
1011 }
1012 $old = $parser->getCustomDefaultSort();
1013 if ( $old === false || $arg !== 'defaultsort_noreplace' ) {
1014 $parser->setDefaultSort( $text );
1015 }
1016
1017 if ( $old === false || $old == $text || $arg ) {
1018 return '';
1019 } else {
1020 $converter = $parser->getTargetLanguage()->getConverter();
1021 return '<span class="error">' .
1022 wfMessage( 'duplicate-defaultsort',
1023 // Message should be parsed, but these params should only be escaped.
1024 $converter->markNoConversion( wfEscapeWikiText( $old ) ),
1025 $converter->markNoConversion( wfEscapeWikiText( $text ) )
1026 )->inContentLanguage()->text() .
1027 '</span>';
1028 }
1029 }
1030
1042 public static function filepath( $parser, $name = '', $argA = '', $argB = '' ) {
1043 $file = MediaWikiServices::getInstance()->getRepoGroup()->findFile( $name );
1044
1045 if ( $argA == 'nowiki' ) {
1046 // {{filepath: | option [| size] }}
1047 $isNowiki = true;
1048 $parsedWidthParam = Parser::parseWidthParam( $argB );
1049 } else {
1050 // {{filepath: [| size [|option]] }}
1051 $parsedWidthParam = Parser::parseWidthParam( $argA );
1052 $isNowiki = ( $argB == 'nowiki' );
1053 }
1054
1055 if ( $file ) {
1056 $url = $file->getFullUrl();
1057
1058 // If a size is requested...
1059 if ( count( $parsedWidthParam ) ) {
1060 $mto = $file->transform( $parsedWidthParam );
1061 // ... and we can
1062 if ( $mto && !$mto->isError() ) {
1063 // ... change the URL to point to a thumbnail.
1064 $url = wfExpandUrl( $mto->getUrl(), PROTO_RELATIVE );
1065 }
1066 }
1067 if ( $isNowiki ) {
1068 return [ $url, 'nowiki' => true ];
1069 }
1070 return $url;
1071 } else {
1072 return '';
1073 }
1074 }
1075
1083 public static function tagObj( $parser, $frame, $args ) {
1084 if ( !count( $args ) ) {
1085 return '';
1086 }
1087 $tagName = strtolower( trim( $frame->expand( array_shift( $args ) ) ) );
1088
1089 if ( count( $args ) ) {
1090 $inner = $frame->expand( array_shift( $args ) );
1091 } else {
1092 $inner = null;
1093 }
1094
1095 $attributes = [];
1096 foreach ( $args as $arg ) {
1097 $bits = $arg->splitArg();
1098 if ( strval( $bits['index'] ) === '' ) {
1099 $name = trim( $frame->expand( $bits['name'], PPFrame::STRIP_COMMENTS ) );
1100 $value = trim( $frame->expand( $bits['value'] ) );
1101 if ( preg_match( '/^(?:["\'](.+)["\']|""|\'\')$/s', $value, $m ) ) {
1102 $value = $m[1] ?? '';
1103 }
1104 $attributes[$name] = $value;
1105 }
1106 }
1107
1108 $stripList = $parser->getStripList();
1109 if ( !in_array( $tagName, $stripList ) ) {
1110 // we can't handle this tag (at least not now), so just re-emit it as an ordinary tag
1111 $attrText = '';
1112 foreach ( $attributes as $name => $value ) {
1113 $attrText .= ' ' . htmlspecialchars( $name ) . '="' . htmlspecialchars( $value ) . '"';
1114 }
1115 if ( $inner === null ) {
1116 return "<$tagName$attrText/>";
1117 }
1118 return "<$tagName$attrText>$inner</$tagName>";
1119 }
1120
1121 $params = [
1122 'name' => $tagName,
1123 'inner' => $inner,
1124 'attributes' => $attributes,
1125 'close' => "</$tagName>",
1126 ];
1127 return $parser->extensionSubstitution( $params, $frame );
1128 }
1129
1143 private static function getCachedRevisionObject( $parser, $title, $vary ) {
1144 if ( !$title ) {
1145 return null;
1146 }
1147
1148 $revisionRecord = null;
1149
1150 $isSelfReferential = $title->equals( $parser->getTitle() );
1151 if ( $isSelfReferential ) {
1152 // Revision is for the same title that is currently being parsed. Only use the last
1153 // saved revision, regardless of Parser::getRevisionId() or fake revision injection
1154 // callbacks against the current title.
1155 $parserRevisionRecord = $parser->getRevisionRecordObject();
1156 if ( $parserRevisionRecord && $parserRevisionRecord->isCurrent() ) {
1157 $revisionRecord = $parserRevisionRecord;
1158 }
1159 }
1160
1161 $parserOutput = $parser->getOutput();
1162 if ( !$revisionRecord ) {
1163 if (
1164 !$parser->isCurrentRevisionOfTitleCached( $title ) &&
1165 !$parser->incrementExpensiveFunctionCount()
1166 ) {
1167 return null; // not allowed
1168 }
1169 // Get the current revision, ignoring Parser::getRevisionId() being null/old
1170 $revisionRecord = $parser->fetchCurrentRevisionRecordOfTitle( $title );
1171 if ( !$revisionRecord ) {
1172 // Convert `false` error return to `null`
1173 $revisionRecord = null;
1174 }
1175 // Register dependency in templatelinks
1176 $parserOutput->addTemplate(
1177 $title,
1178 $revisionRecord ? $revisionRecord->getPageId() : 0,
1179 $revisionRecord ? $revisionRecord->getId() : 0
1180 );
1181 }
1182
1183 if ( $isSelfReferential ) {
1184 wfDebug( __METHOD__ . ": used current revision, setting $vary" );
1185 // Upon page save, the result of the parser function using this might change
1186 $parserOutput->setFlag( $vary );
1187 if ( $vary === 'vary-revision-sha1' && $revisionRecord ) {
1188 try {
1189 $sha1 = $revisionRecord->getSha1();
1190 } catch ( RevisionAccessException $e ) {
1191 $sha1 = null;
1192 }
1193 $parserOutput->setRevisionUsedSha1Base36( $sha1 );
1194 }
1195 }
1196
1197 return $revisionRecord;
1198 }
1199
1207 public static function pageid( $parser, $title = null ) {
1208 $t = Title::newFromText( $title );
1209 if ( !$t ) {
1210 return '';
1211 } elseif ( !$t->canExist() || $t->isExternal() ) {
1212 return 0; // e.g. special page or interwiki link
1213 }
1214
1215 $parserOutput = $parser->getOutput();
1216
1217 if ( $t->equals( $parser->getTitle() ) ) {
1218 // Revision is for the same title that is currently being parsed.
1219 // Use the title from Parser in case a new page ID was injected into it.
1220 $parserOutput->setFlag( 'vary-page-id' );
1221 $id = $parser->getTitle()->getArticleID();
1222 if ( $id ) {
1223 $parserOutput->setSpeculativePageIdUsed( $id );
1224 }
1225
1226 return $id;
1227 }
1228
1229 // Check the link cache for the title
1230 $linkCache = MediaWikiServices::getInstance()->getLinkCache();
1231 $pdbk = $t->getPrefixedDBkey();
1232 $id = $linkCache->getGoodLinkID( $pdbk );
1233 if ( $id != 0 || $linkCache->isBadLink( $pdbk ) ) {
1234 $parserOutput->addLink( $t, $id );
1235
1236 return $id;
1237 }
1238
1239 // We need to load it from the DB, so mark expensive
1240 if ( $parser->incrementExpensiveFunctionCount() ) {
1241 $id = $t->getArticleID();
1242 $parserOutput->addLink( $t, $id );
1243
1244 return $id;
1245 }
1246
1247 return null;
1248 }
1249
1257 public static function revisionid( $parser, $title = null ) {
1258 $t = Title::newFromText( $title );
1259 if ( $t === null ) {
1260 return '';
1261 }
1262
1263 $services = MediaWikiServices::getInstance();
1264 if (
1265 $t->equals( $parser->getTitle() ) &&
1266 $services->getMainConfig()->get( 'MiserMode' ) &&
1267 !$parser->getOptions()->getInterfaceMessage() &&
1268 // @TODO: disallow this word on all namespaces (T235957)
1269 $services->getNamespaceInfo()->isSubject( $t->getNamespace() )
1270 ) {
1271 // Use a stub result instead of the actual revision ID in order to avoid
1272 // double parses on page save but still allow preview detection (T137900)
1273 if ( $parser->getRevisionId() || $parser->getOptions()->getSpeculativeRevId() ) {
1274 return '-';
1275 } else {
1276 $parser->getOutput()->setFlag( 'vary-revision-exists' );
1277 return '';
1278 }
1279 }
1280 // fetch revision from cache/database and return the value
1281 $rev = self::getCachedRevisionObject( $parser, $t, 'vary-revision-id' );
1282 return $rev ? $rev->getId() : '';
1283 }
1284
1292 public static function revisionday( $parser, $title = null ) {
1293 $t = Title::newFromText( $title );
1294 if ( $t === null ) {
1295 return '';
1296 }
1297 // fetch revision from cache/database and return the value
1298 $rev = self::getCachedRevisionObject( $parser, $t, 'vary-revision-timestamp' );
1299 return $rev ? MWTimestamp::getLocalInstance( $rev->getTimestamp() )->format( 'j' ) : '';
1300 }
1301
1309 public static function revisionday2( $parser, $title = null ) {
1310 $t = Title::newFromText( $title );
1311 if ( $t === null ) {
1312 return '';
1313 }
1314 // fetch revision from cache/database and return the value
1315 $rev = self::getCachedRevisionObject( $parser, $t, 'vary-revision-timestamp' );
1316 return $rev ? MWTimestamp::getLocalInstance( $rev->getTimestamp() )->format( 'd' ) : '';
1317 }
1318
1326 public static function revisionmonth( $parser, $title = null ) {
1327 $t = Title::newFromText( $title );
1328 if ( $t === null ) {
1329 return '';
1330 }
1331 // fetch revision from cache/database and return the value
1332 $rev = self::getCachedRevisionObject( $parser, $t, 'vary-revision-timestamp' );
1333 return $rev ? MWTimestamp::getLocalInstance( $rev->getTimestamp() )->format( 'm' ) : '';
1334 }
1335
1343 public static function revisionmonth1( $parser, $title = null ) {
1344 $t = Title::newFromText( $title );
1345 if ( $t === null ) {
1346 return '';
1347 }
1348 // fetch revision from cache/database and return the value
1349 $rev = self::getCachedRevisionObject( $parser, $t, 'vary-revision-timestamp' );
1350 return $rev ? MWTimestamp::getLocalInstance( $rev->getTimestamp() )->format( 'n' ) : '';
1351 }
1352
1360 public static function revisionyear( $parser, $title = null ) {
1361 $t = Title::newFromText( $title );
1362 if ( $t === null ) {
1363 return '';
1364 }
1365 // fetch revision from cache/database and return the value
1366 $rev = self::getCachedRevisionObject( $parser, $t, 'vary-revision-timestamp' );
1367 return $rev ? MWTimestamp::getLocalInstance( $rev->getTimestamp() )->format( 'Y' ) : '';
1368 }
1369
1377 public static function revisiontimestamp( $parser, $title = null ) {
1378 $t = Title::newFromText( $title );
1379 if ( $t === null ) {
1380 return '';
1381 }
1382 // fetch revision from cache/database and return the value
1383 $rev = self::getCachedRevisionObject( $parser, $t, 'vary-revision-timestamp' );
1384 return $rev ? MWTimestamp::getLocalInstance( $rev->getTimestamp() )->format( 'YmdHis' ) : '';
1385 }
1386
1394 public static function revisionuser( $parser, $title = null ) {
1395 $t = Title::newFromText( $title );
1396 if ( $t === null ) {
1397 return '';
1398 }
1399 // fetch revision from cache/database and return the value
1400 $rev = self::getCachedRevisionObject( $parser, $t, 'vary-user' );
1401 if ( $rev === null ) {
1402 return '';
1403 }
1404 $user = $rev->getUser();
1405 return $user ? $user->getName() : '';
1406 }
1407
1420 public static function cascadingsources( $parser, $title = '' ) {
1421 $titleObject = Title::newFromText( $title ) ?? $parser->getTitle();
1422 if ( $titleObject->areCascadeProtectionSourcesLoaded()
1423 || $parser->incrementExpensiveFunctionCount()
1424 ) {
1425 $names = [];
1426 $sources = $titleObject->getCascadeProtectionSources();
1427 foreach ( $sources[0] as $sourceTitle ) {
1428 $names[] = $sourceTitle->getPrefixedText();
1429 }
1430 return implode( '|', $names );
1431 }
1432 return '';
1433 }
1434
1435}
$wgAllowDisplayTitle
Allow DISPLAYTITLE to change title display.
$wgRestrictDisplayTitle
For consistency, restrict DISPLAYTITLE to text that normalizes to the same canonical DB key.
$wgAllowSlowParserFunctions
Enable slow parser functions.
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
wfUrlencode( $s)
We want some things to be included as literal characters in our title URLs for prettiness,...
wfExpandUrl( $url, $defaultProto=PROTO_CURRENT)
Expand a potentially local URL to a fully-qualified URL.
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
wfEscapeWikiText( $text)
Escapes the given text so that it may be output using addWikiText() without any linking,...
return[ 'abap'=> true, 'abl'=> true, 'abnf'=> true, 'aconf'=> true, 'actionscript'=> true, 'actionscript3'=> true, 'ada'=> true, 'ada2005'=> true, 'ada95'=> true, 'adl'=> true, 'agda'=> true, 'aheui'=> true, 'ahk'=> true, 'alloy'=> true, 'ambienttalk'=> true, 'ambienttalk/2'=> true, 'ampl'=> true, 'antlr'=> true, 'antlr-actionscript'=> true, 'antlr-as'=> true, 'antlr-c#'=> true, 'antlr-cpp'=> true, 'antlr-csharp'=> true, 'antlr-java'=> true, 'antlr-objc'=> true, 'antlr-perl'=> true, 'antlr-python'=> true, 'antlr-rb'=> true, 'antlr-ruby'=> true, 'apache'=> true, 'apacheconf'=> true, 'apl'=> true, 'applescript'=> true, 'arduino'=> true, 'arexx'=> true, 'arrow'=> true, 'as'=> true, 'as3'=> true, 'asm'=> true, 'aspectj'=> true, 'aspx-cs'=> true, 'aspx-vb'=> true, 'asy'=> true, 'asymptote'=> true, 'at'=> true, 'augeas'=> true, 'autohotkey'=> true, 'autoit'=> true, 'awk'=> true, 'b3d'=> true, 'bare'=> true, 'basemake'=> true, 'bash'=> true, 'basic'=> true, 'bat'=> true, 'batch'=> true, 'bbcbasic'=> true, 'bbcode'=> true, 'bc'=> true, 'befunge'=> true, 'bf'=> true, 'bib'=> true, 'bibtex'=> true, 'blitzbasic'=> true, 'blitzmax'=> true, 'bmax'=> true, 'bnf'=> true, 'boa'=> true, 'boo'=> true, 'boogie'=> true, 'bplus'=> true, 'brainfuck'=> true, 'bro'=> true, 'bsdmake'=> true, 'bst'=> true, 'bst-pybtex'=> true, 'bugs'=> true, 'c'=> true, 'c#'=> true, 'c++'=> true, 'c++-objdumb'=> true, 'c-objdump'=> true, 'ca65'=> true, 'cadl'=> true, 'camkes'=> true, 'capdl'=> true, 'capnp'=> true, 'cbmbas'=> true, 'ceylon'=> true, 'cf3'=> true, 'cfc'=> true, 'cfengine3'=> true, 'cfg'=> true, 'cfm'=> true, 'cfs'=> true, 'chai'=> true, 'chaiscript'=> true, 'chapel'=> true, 'charmci'=> true, 'cheetah'=> true, 'chpl'=> true, 'cirru'=> true, 'cl'=> true, 'clay'=> true, 'clean'=> true, 'clipper'=> true, 'clj'=> true, 'cljs'=> true, 'clojure'=> true, 'clojurescript'=> true, 'cmake'=> true, 'cobol'=> true, 'cobolfree'=> true, 'coffee'=> true, 'coffee-script'=> true, 'coffeescript'=> true, 'common-lisp'=> true, 'componentpascal'=> true, 'console'=> true, 'control'=> true, 'coq'=> true, 'cp'=> true, 'cpp'=> true, 'cpp-objdump'=> true, 'cpsa'=> true, 'cr'=> true, 'crmsh'=> true, 'croc'=> true, 'cry'=> true, 'cryptol'=> true, 'crystal'=> true, 'csh'=> true, 'csharp'=> true, 'csound'=> true, 'csound-csd'=> true, 'csound-document'=> true, 'csound-orc'=> true, 'csound-sco'=> true, 'csound-score'=> true, 'css'=> true, 'css+django'=> true, 'css+erb'=> true, 'css+genshi'=> true, 'css+genshitext'=> true, 'css+jinja'=> true, 'css+lasso'=> true, 'css+mako'=> true, 'css+mozpreproc'=> true, 'css+myghty'=> true, 'css+php'=> true, 'css+ruby'=> true, 'css+smarty'=> true, 'cu'=> true, 'cucumber'=> true, 'cuda'=> true, 'cxx-objdump'=> true, 'cypher'=> true, 'cython'=> true, 'd'=> true, 'd-objdump'=> true, 'dart'=> true, 'dasm16'=> true, 'debcontrol'=> true, 'debsources'=> true, 'delphi'=> true, 'devicetree'=> true, 'dg'=> true, 'diff'=> true, 'django'=> true, 'dmesg'=> true, 'do'=> true, 'docker'=> true, 'dockerfile'=> true, 'dosbatch'=> true, 'doscon'=> true, 'dosini'=> true, 'dpatch'=> true, 'dtd'=> true, 'dts'=> true, 'duby'=> true, 'duel'=> true, 'dylan'=> true, 'dylan-console'=> true, 'dylan-lid'=> true, 'dylan-repl'=> true, 'earl-grey'=> true, 'earlgrey'=> true, 'easytrieve'=> true, 'ebnf'=> true, 'ec'=> true, 'ecl'=> true, 'eg'=> true, 'eiffel'=> true, 'elisp'=> true, 'elixir'=> true, 'elm'=> true, 'emacs'=> true, 'emacs-lisp'=> true, 'email'=> true, 'eml'=> true, 'erb'=> true, 'erl'=> true, 'erlang'=> true, 'evoque'=> true, 'ex'=> true, 'execline'=> true, 'exs'=> true, 'extempore'=> true, 'ezhil'=> true, 'f#'=> true, 'factor'=> true, 'fan'=> true, 'fancy'=> true, 'felix'=> true, 'fennel'=> true, 'fish'=> true, 'fishshell'=> true, 'flatline'=> true, 'flo'=> true, 'floscript'=> true, 'flx'=> true, 'fnl'=> true, 'forth'=> true, 'fortran'=> true, 'fortranfixed'=> true, 'foxpro'=> true, 'freefem'=> true, 'fsharp'=> true, 'fstar'=> true, 'fy'=> true, 'gap'=> true, 'gas'=> true, 'gawk'=> true, 'gd'=> true, 'gdscript'=> true, 'genshi'=> true, 'genshitext'=> true, 'gherkin'=> true, 'glsl'=> true, 'gnuplot'=> true, 'go'=> true, 'golo'=> true, 'gooddata-cl'=> true, 'gosu'=> true, 'groff'=> true, 'groovy'=> true, 'gst'=> true, 'haml'=> true, 'handlebars'=> true, 'haskell'=> true, 'haxe'=> true, 'haxeml'=> true, 'hexdump'=> true, 'hlsl'=> true, 'hs'=> true, 'hsa'=> true, 'hsail'=> true, 'hspec'=> true, 'html'=> true, 'html+cheetah'=> true, 'html+django'=> true, 'html+erb'=> true, 'html+evoque'=> true, 'html+genshi'=> true, 'html+handlebars'=> true, 'html+jinja'=> true, 'html+kid'=> true, 'html+lasso'=> true, 'html+mako'=> true, 'html+myghty'=> true, 'html+ng2'=> true, 'html+php'=> true, 'html+ruby'=> true, 'html+smarty'=> true, 'html+spitfire'=> true, 'html+twig'=> true, 'html+velocity'=> true, 'htmlcheetah'=> true, 'htmldjango'=> true, 'http'=> true, 'hx'=> true, 'hxml'=> true, 'hxsl'=> true, 'hy'=> true, 'hybris'=> true, 'hylang'=> true, 'i6'=> true, 'i6t'=> true, 'i7'=> true, 'icon'=> true, 'idl'=> true, 'idl4'=> true, 'idr'=> true, 'idris'=> true, 'iex'=> true, 'igor'=> true, 'igorpro'=> true, 'ik'=> true, 'inform6'=> true, 'inform7'=> true, 'ini'=> true, 'io'=> true, 'ioke'=> true, 'irb'=> true, 'irc'=> true, 'isabelle'=> true, 'j'=> true, 'jade'=> true, 'jags'=> true, 'jasmin'=> true, 'jasminxt'=> true, 'java'=> true, 'javascript'=> true, 'javascript+cheetah'=> true, 'javascript+django'=> true, 'javascript+erb'=> true, 'javascript+genshi'=> true, 'javascript+genshitext'=> true, 'javascript+jinja'=> true, 'javascript+lasso'=> true, 'javascript+mako'=> true, 'javascript+mozpreproc'=> true, 'javascript+myghty'=> true, 'javascript+php'=> true, 'javascript+ruby'=> true, 'javascript+smarty'=> true, 'javascript+spitfire'=> true, 'jbst'=> true, 'jcl'=> true, 'jinja'=> true, 'jl'=> true, 'jlcon'=> true, 'jproperties'=> true, 'js'=> true, 'js+cheetah'=> true, 'js+django'=> true, 'js+erb'=> true, 'js+genshi'=> true, 'js+genshitext'=> true, 'js+jinja'=> true, 'js+lasso'=> true, 'js+mako'=> true, 'js+myghty'=> true, 'js+php'=> true, 'js+ruby'=> true, 'js+smarty'=> true, 'js+spitfire'=> true, 'jsgf'=> true, 'json'=> true, 'json-ld'=> true, 'json-object'=> true, 'jsonld'=> true, 'jsonml+bst'=> true, 'jsp'=> true, 'julia'=> true, 'juttle'=> true, 'kal'=> true, 'kconfig'=> true, 'kernel-config'=> true, 'kid'=> true, 'kmsg'=> true, 'koka'=> true, 'kotlin'=> true, 'ksh'=> true, 'lagda'=> true, 'lasso'=> true, 'lassoscript'=> true, 'latex'=> true, 'lcry'=> true, 'lcryptol'=> true, 'lean'=> true, 'less'=> true, 'lhaskell'=> true, 'lhs'=> true, 'lid'=> true, 'lidr'=> true, 'lidris'=> true, 'lighttpd'=> true, 'lighty'=> true, 'limbo'=> true, 'linux-config'=> true, 'liquid'=> true, 'lisp'=> true, 'literate-agda'=> true, 'literate-cryptol'=> true, 'literate-haskell'=> true, 'literate-idris'=> true, 'live-script'=> true, 'livescript'=> true, 'llvm'=> true, 'llvm-mir'=> true, 'llvm-mir-body'=> true, 'logos'=> true, 'logtalk'=> true, 'lsl'=> true, 'lua'=> true, 'm2'=> true, 'make'=> true, 'makefile'=> true, 'mako'=> true, 'man'=> true, 'maql'=> true, 'mask'=> true, 'mason'=> true, 'mathematica'=> true, 'matlab'=> true, 'matlabsession'=> true, 'mawk'=> true, 'md'=> true, 'menuconfig'=> true, 'mf'=> true, 'mime'=> true, 'minid'=> true, 'miniscript'=> true, 'mma'=> true, 'modelica'=> true, 'modula2'=> true, 'moin'=> true, 'monkey'=> true, 'monte'=> true, 'moo'=> true, 'moocode'=> true, 'moon'=> true, 'moonscript'=> true, 'mosel'=> true, 'mozhashpreproc'=> true, 'mozpercentpreproc'=> true, 'mq4'=> true, 'mq5'=> true, 'mql'=> true, 'mql4'=> true, 'mql5'=> true, 'ms'=> true, 'msc'=> true, 'mscgen'=> true, 'mupad'=> true, 'mxml'=> true, 'myghty'=> true, 'mysql'=> true, 'nasm'=> true, 'nawk'=> true, 'nb'=> true, 'ncl'=> true, 'nemerle'=> true, 'nesc'=> true, 'newlisp'=> true, 'newspeak'=> true, 'ng2'=> true, 'nginx'=> true, 'nim'=> true, 'nimrod'=> true, 'nit'=> true, 'nix'=> true, 'nixos'=> true, 'notmuch'=> true, 'nroff'=> true, 'nsh'=> true, 'nsi'=> true, 'nsis'=> true, 'numpy'=> true, 'nusmv'=> true, 'obj-c'=> true, 'obj-c++'=> true, 'obj-j'=> true, 'objc'=> true, 'objc++'=> true, 'objdump'=> true, 'objdump-nasm'=> true, 'objective-c'=> true, 'objective-c++'=> true, 'objective-j'=> true, 'objectivec'=> true, 'objectivec++'=> true, 'objectivej'=> true, 'objectpascal'=> true, 'objj'=> true, 'ocaml'=> true, 'octave'=> true, 'odin'=> true, 'ooc'=> true, 'opa'=> true, 'openbugs'=> true, 'openedge'=> true, 'pacmanconf'=> true, 'pan'=> true, 'parasail'=> true, 'pas'=> true, 'pascal'=> true, 'pawn'=> true, 'pcmk'=> true, 'peg'=> true, 'perl'=> true, 'perl6'=> true, 'php'=> true, 'php3'=> true, 'php4'=> true, 'php5'=> true, 'pig'=> true, 'pike'=> true, 'pkgconfig'=> true, 'pl'=> true, 'pl6'=> true, 'plpgsql'=> true, 'po'=> true, 'pointless'=> true, 'pony'=> true, 'posh'=> true, 'postgres'=> true, 'postgres-console'=> true, 'postgresql'=> true, 'postgresql-console'=> true, 'postscr'=> true, 'postscript'=> true, 'pot'=> true, 'pov'=> true, 'powershell'=> true, 'praat'=> true, 'progress'=> true, 'prolog'=> true, 'promql'=> true, 'properties'=> true, 'proto'=> true, 'protobuf'=> true, 'ps1'=> true, 'ps1con'=> true, 'psm1'=> true, 'psql'=> true, 'psysh'=> true, 'pug'=> true, 'puppet'=> true, 'py'=> true, 'py2'=> true, 'py2tb'=> true, 'py3'=> true, 'py3tb'=> true, 'pycon'=> true, 'pypy'=> true, 'pypylog'=> true, 'pyrex'=> true, 'pytb'=> true, 'python'=> true, 'python2'=> true, 'python3'=> true, 'pyx'=> true, 'qbasic'=> true, 'qbs'=> true, 'qml'=> true, 'qvt'=> true, 'qvto'=> true, 'r'=> true, 'racket'=> true, 'ragel'=> true, 'ragel-c'=> true, 'ragel-cpp'=> true, 'ragel-d'=> true, 'ragel-em'=> true, 'ragel-java'=> true, 'ragel-objc'=> true, 'ragel-rb'=> true, 'ragel-ruby'=> true, 'raku'=> true, 'raw'=> true, 'rb'=> true, 'rbcon'=> true, 'rconsole'=> true, 'rd'=> true, 'reason'=> true, 'reasonml'=> true, 'rebol'=> true, 'red'=> true, 'red/system'=> true, 'redcode'=> true, 'registry'=> true, 'resource'=> true, 'resourcebundle'=> true, 'rest'=> true, 'restructuredtext'=> true, 'rexx'=> true, 'rhtml'=> true, 'ride'=> true, 'rkt'=> true, 'rnc'=> true, 'rng-compact'=> true, 'roboconf-graph'=> true, 'roboconf-instances'=> true, 'robotframework'=> true, 'rout'=> true, 'rql'=> true, 'rs'=> true, 'rsl'=> true, 'rst'=> true, 'rts'=> true, 'ruby'=> true, 'rust'=> true, 's'=> true, 'sage'=> true, 'salt'=> true, 'sarl'=> true, 'sas'=> true, 'sass'=> true, 'sbatch'=> true, 'sc'=> true, 'scala'=> true, 'scaml'=> true, 'scd'=> true, 'scdoc'=> true, 'scheme'=> true, 'scilab'=> true, 'scm'=> true, 'scss'=> true, 'sgf'=> true, 'sh'=> true, 'shell'=> true, 'shell-session'=> true, 'shen'=> true, 'shex'=> true, 'shexc'=> true, 'sieve'=> true, 'silver'=> true, 'singularity'=> true, 'slash'=> true, 'slim'=> true, 'sls'=> true, 'slurm'=> true, 'smali'=> true, 'smalltalk'=> true, 'smarty'=> true, 'sml'=> true, 'snobol'=> true, 'snowball'=> true, 'solidity'=> true, 'sources.list'=> true, 'sourceslist'=> true, 'sp'=> true, 'sparql'=> true, 'spec'=> true, 'spitfire'=> true, 'splus'=> true, 'sql'=> true, 'sqlite3'=> true, 'squeak'=> true, 'squid'=> true, 'squid.conf'=> true, 'squidconf'=> true, 'ssp'=> true, 'st'=> true, 'stan'=> true, 'stata'=> true, 'supercollider'=> true, 'sv'=> true, 'swift'=> true, 'swig'=> true, 'systemverilog'=> true, 't-sql'=> true, 'tads3'=> true, 'tap'=> true, 'tasm'=> true, 'tcl'=> true, 'tcsh'=> true, 'tcshcon'=> true, 'tea'=> true, 'teraterm'=> true, 'teratermmacro'=> true, 'termcap'=> true, 'terminfo'=> true, 'terraform'=> true, 'tex'=> true, 'text'=> true, 'tf'=> true, 'thrift'=> true, 'tid'=> true, 'tnt'=> true, 'todotxt'=> true, 'toml'=> true, 'trac-wiki'=> true, 'trafficscript'=> true, 'treetop'=> true, 'ts'=> true, 'tsql'=> true, 'ttl'=> true, 'turtle'=> true, 'twig'=> true, 'typescript'=> true, 'typoscript'=> true, 'typoscriptcssdata'=> true, 'typoscripthtmldata'=> true, 'ucode'=> true, 'udiff'=> true, 'unicon'=> true, 'urbiscript'=> true, 'usd'=> true, 'usda'=> true, 'v'=> true, 'vala'=> true, 'vapi'=> true, 'vb.net'=> true, 'vbnet'=> true, 'vbscript'=> true, 'vcl'=> true, 'vclsnippet'=> true, 'vclsnippets'=> true, 'vctreestatus'=> true, 'velocity'=> true, 'verilog'=> true, 'vfp'=> true, 'vgl'=> true, 'vhdl'=> true, 'vim'=> true, 'wdiff'=> true, 'webidl'=> true, 'whiley'=> true, 'winbatch'=> true, 'winbugs'=> true, 'x10'=> true, 'xbase'=> true, 'xml'=> true, 'xml+cheetah'=> true, 'xml+django'=> true, 'xml+erb'=> true, 'xml+evoque'=> true, 'xml+genshi'=> true, 'xml+jinja'=> true, 'xml+kid'=> true, 'xml+lasso'=> true, 'xml+mako'=> true, 'xml+myghty'=> true, 'xml+php'=> true, 'xml+ruby'=> true, 'xml+smarty'=> true, 'xml+spitfire'=> true, 'xml+velocity'=> true, 'xorg.conf'=> true, 'xq'=> true, 'xql'=> true, 'xqm'=> true, 'xquery'=> true, 'xqy'=> true, 'xslt'=> true, 'xten'=> true, 'xtend'=> true, 'xul+mozpreproc'=> true, 'yaml'=> true, 'yaml+jinja'=> true, 'yang'=> true, 'zeek'=> true, 'zephir'=> true, 'zig'=> true, 'zsh'=> true,]
Various core parser functions, registered in Parser::firstCallInit()
static language( $parser, $code='', $inLanguage='')
Gives language names.
static numberingroup( $parser, $name='', $raw=null)
static rootpagename( $parser, $title=null)
static localurl( $parser, $s='', $arg=null)
static formatnum( $parser, $num='', $arg=null)
static ns( $parser, $part1='')
static protectionexpiry( $parser, $type='', $title='')
Returns the requested protection expiry for the current page.
static pagenamee( $parser, $title=null)
static padleft( $parser, $string='', $length=0, $padding='0')
static fullurle( $parser, $s='', $arg=null)
static revisionmonth( $parser, $title=null)
Get the month with leading zeros from the last revision of a specified page.
static fullpagename( $parser, $title=null)
static revisionid( $parser, $title=null)
Get the id from the last revision of a specified page.
static pagesinnamespace( $parser, $namespace=0, $raw=null)
static numberofusers( $parser, $raw=null)
static special( $parser, $text)
static nse( $parser, $part1='')
static pagesize( $parser, $page='', $raw=null)
Return the size of the given page, or 0 if it's nonexistent.
static canonicalurl( $parser, $s='', $arg=null)
static basepagenamee( $parser, $title=null)
static subjectspacee( $parser, $title=null)
static numberofedits( $parser, $raw=null)
static numberoffiles( $parser, $raw=null)
static ucfirst( $parser, $s='')
static getTargetLanguageConverter(Parser $parser)
Shorthand for getting a Language Converter for Target language.
static basepagename( $parser, $title=null)
static gender( $parser, $username,... $forms)
static numberofpages( $parser, $raw=null)
static lcfirst( $parser, $s='')
static urlFunction( $func, $s='', $arg=null)
static plural( $parser, $text='',... $forms)
static formatRaw( $num, $raw, $language, MagicWordFactory $magicWordFactory=null)
Formats a number according to a language.
static talkspacee( $parser, $title=null)
static bidi( $parser, $text='')
static revisionuser( $parser, $title=null)
Get the user from the last revision of a specified page.
static anchorencode( $parser, $text)
static subjectpagenamee( $parser, $title=null)
static namespacee( $parser, $title=null)
static subjectpagename( $parser, $title=null)
static filepath( $parser, $name='', $argA='', $argB='')
Usage {{filepath|300}}, {{filepath|nowiki}}, {{filepath|nowiki|300}} or {{filepath|300|nowiki}} or {{...
static padright( $parser, $string='', $length=0, $padding='0')
static pad( $parser, $string, $length, $padding='0', $direction=STR_PAD_RIGHT)
Unicode-safe str_pad with the restriction that $length is forced to be <= 500.
static canonicalurle( $parser, $s='', $arg=null)
static cascadingsources( $parser, $title='')
Returns the sources of any cascading protection acting on a specified page.
static numberofactiveusers( $parser, $raw=null)
static displaytitle( $parser, $text='', $uarg='')
Override the title of the page when viewed, provided we've been given a title which will normalise to...
static pageid( $parser, $title=null)
Get the pageid of a specified page.
static formatDate( $parser, $date, $defaultPref=null)
static urlencode( $parser, $s='', $arg=null)
urlencodes a string according to one of three patterns: (T24474)
static grammar( $parser, $case='', $word='')
static subpagenamee( $parser, $title=null)
static tagObj( $parser, $frame, $args)
Parser function to extension tag adaptor.
static revisionmonth1( $parser, $title=null)
Get the month from the last revision of a specified page.
static rootpagenamee( $parser, $title=null)
static protectionlevel( $parser, $type='', $title='')
Returns the requested protection level for the current page.
static namespacenumber( $parser, $title=null)
static revisionday( $parser, $title=null)
Get the day from the last revision of a specified page.
static subjectspace( $parser, $title=null)
static getCachedRevisionObject( $parser, $title, $vary)
Fetched the current revision of the given title and return this.
static lc( $parser, $s='')
static pagesincategory( $parser, $name='', $arg1='', $arg2='')
Return the number of pages, files or subcats in the given category, or 0 if it's nonexistent.
static talkpagename( $parser, $title=null)
static fullurl( $parser, $s='', $arg=null)
static mwnamespace( $parser, $title=null)
Given a title, return the namespace name that would be given by the corresponding magic word Note: fu...
static matchAgainstMagicword(MagicWordFactory $magicWordFactory, $magicword, $value)
Matches the given value against the value of given magic word.
static pagename( $parser, $title=null)
Functions to get and normalize pagenames, corresponding to the magic words of the same names.
static intFunction( $parser, $part1='',... $params)
static numberofadmins( $parser, $raw=null)
static numberofarticles( $parser, $raw=null)
static revisionyear( $parser, $title=null)
Get the year from the last revision of a specified page.
static revisionday2( $parser, $title=null)
Get the day with leading zeros from the last revision of a specified page.
static uc( $parser, $s='')
static talkpagenamee( $parser, $title=null)
static revisiontimestamp( $parser, $title=null)
Get the timestamp from the last revision of a specified page.
static subpagename( $parser, $title=null)
static localurle( $parser, $s='', $arg=null)
static defaultsort( $parser, $text, $uarg='')
static fullpagenamee( $parser, $title=null)
static talkspace( $parser, $title=null)
static speciale( $parser, $text)
A factory that stores information about MagicWords, and creates them on demand with caching.
get( $id)
Factory: creates an object representing an ID.
MediaWikiServices is the service locator for the application scope of MediaWiki.
Exception representing a failure to look up a revision.
Page revision base class.
static articles()
static pagesInNs( $ns)
static images()
static edits()
Definition SiteStats.php:94
static users()
static pages()
static numberingroup( $group)
Find the number of users in a given user group.
static activeUsers()
static getTitleFor( $name, $subpage=false, $fragment='')
Get a localised Title object for a specified special page name If you don't need a full Title object,...
Represents a title within MediaWiki.
Definition Title.php:42
hasFragment()
Check if a Title fragment is set.
Definition Title.php:1758
const NS_USER
Definition Defines.php:72
const NS_FILE
Definition Defines.php:76
const NS_SPECIAL
Definition Defines.php:59
const NS_MEDIA
Definition Defines.php:58
const PROTO_RELATIVE
Definition Defines.php:211
const NS_CATEGORY
Definition Defines.php:84
The shared interface for all language converters.
$cache
Definition mcc.php:33
if( $line===false) $args
Definition mcc.php:124
return true
Definition router.php:92
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
Definition router.php:42
if(!isset( $args[0])) $lang