MediaWiki  master
CoreParserFunctions.php
Go to the documentation of this file.
1 <?php
24 
34  public static function register( $parser ) {
36 
37  # Syntax for arguments (see Parser::setFunctionHook):
38  # "name for lookup in localized magic words array",
39  # function callback,
40  # optional Parser::SFH_NO_HASH to omit the hash from calls (e.g. {{int:...}}
41  # instead of {{#int:...}})
42  $noHashFunctions = [
43  'ns', 'nse', 'urlencode', 'lcfirst', 'ucfirst', 'lc', 'uc',
44  'localurl', 'localurle', 'fullurl', 'fullurle', 'canonicalurl',
45  'canonicalurle', 'formatnum', 'grammar', 'gender', 'plural', 'bidi',
46  'numberofpages', 'numberofusers', 'numberofactiveusers',
47  'numberofarticles', 'numberoffiles', 'numberofadmins',
48  'numberingroup', 'numberofedits', 'language',
49  'padleft', 'padright', 'anchorencode', 'defaultsort', 'filepath',
50  'pagesincategory', 'pagesize', 'protectionlevel', 'protectionexpiry',
51  'namespacee', 'namespacenumber', 'talkspace', 'talkspacee',
52  'subjectspace', 'subjectspacee', 'pagename', 'pagenamee',
53  'fullpagename', 'fullpagenamee', 'rootpagename', 'rootpagenamee',
54  'basepagename', 'basepagenamee', 'subpagename', 'subpagenamee',
55  'talkpagename', 'talkpagenamee', 'subjectpagename',
56  'subjectpagenamee', 'pageid', 'revisionid', 'revisionday',
57  'revisionday2', 'revisionmonth', 'revisionmonth1', 'revisionyear',
58  'revisiontimestamp', 'revisionuser', 'cascadingsources',
59  ];
60  foreach ( $noHashFunctions as $func ) {
61  $parser->setFunctionHook( $func, [ __CLASS__, $func ], Parser::SFH_NO_HASH );
62  }
63 
64  $parser->setFunctionHook(
65  'namespace',
66  [ __CLASS__, 'mwnamespace' ],
68  );
69  $parser->setFunctionHook( 'int', [ __CLASS__, 'intFunction' ], Parser::SFH_NO_HASH );
70  $parser->setFunctionHook( 'special', [ __CLASS__, 'special' ] );
71  $parser->setFunctionHook( 'speciale', [ __CLASS__, 'speciale' ] );
72  $parser->setFunctionHook( 'tag', [ __CLASS__, 'tagObj' ], Parser::SFH_OBJECT_ARGS );
73  $parser->setFunctionHook( 'formatdate', [ __CLASS__, 'formatDate' ] );
74 
75  if ( $wgAllowDisplayTitle ) {
76  $parser->setFunctionHook(
77  'displaytitle',
78  [ __CLASS__, 'displaytitle' ],
80  );
81  }
82  if ( $wgAllowSlowParserFunctions ) {
83  $parser->setFunctionHook(
84  'pagesinnamespace',
85  [ __CLASS__, 'pagesinnamespace' ],
87  );
88  }
89  }
90 
97  public static function intFunction( $parser, $part1 = '', ...$params ) {
98  if ( strval( $part1 ) !== '' ) {
99  $message = wfMessage( $part1, $params )
100  ->inLanguage( $parser->getOptions()->getUserLangObj() );
101  return [ $message->plain(), 'noparse' => false ];
102  } else {
103  return [ 'found' => false ];
104  }
105  }
106 
114  public static function formatDate( $parser, $date, $defaultPref = null ) {
115  $lang = $parser->getFunctionLang();
116  $df = MediaWikiServices::getInstance()->getDateFormatterFactory()->get( $lang );
117 
118  $date = trim( $date );
119 
120  $pref = $parser->getOptions()->getDateFormat();
121 
122  // Specify a different default date format other than the normal default
123  // if the user has 'default' for their setting
124  if ( $pref == 'default' && $defaultPref ) {
125  $pref = $defaultPref;
126  }
127 
128  $date = $df->reformat( $pref, $date, [ 'match-whole' ] );
129  return $date;
130  }
131 
132  public static function ns( $parser, $part1 = '' ) {
133  if ( intval( $part1 ) || $part1 == "0" ) {
134  $index = intval( $part1 );
135  } else {
136  $index = $parser->getContentLanguage()->getNsIndex( str_replace( ' ', '_', $part1 ) );
137  }
138  if ( $index !== false ) {
139  return $parser->getContentLanguage()->getFormattedNsText( $index );
140  } else {
141  return [ 'found' => false ];
142  }
143  }
144 
145  public static function nse( $parser, $part1 = '' ) {
146  $ret = self::ns( $parser, $part1 );
147  if ( is_string( $ret ) ) {
148  $ret = wfUrlencode( str_replace( ' ', '_', $ret ) );
149  }
150  return $ret;
151  }
152 
165  public static function urlencode( $parser, $s = '', $arg = null ) {
166  static $magicWords = null;
167  if ( is_null( $magicWords ) ) {
168  $magicWords =
169  $parser->getMagicWordFactory()->newArray( [ 'url_path', 'url_query', 'url_wiki' ] );
170  }
171  switch ( $magicWords->matchStartToEnd( $arg ) ) {
172  // Encode as though it's a wiki page, '_' for ' '.
173  case 'url_wiki':
174  $func = 'wfUrlencode';
175  $s = str_replace( ' ', '_', $s );
176  break;
177 
178  // Encode for an HTTP Path, '%20' for ' '.
179  case 'url_path':
180  $func = 'rawurlencode';
181  break;
182 
183  // Encode for HTTP query, '+' for ' '.
184  case 'url_query':
185  default:
186  $func = 'urlencode';
187  }
188  // See T105242, where the choice to kill markers and various
189  // other options were discussed.
190  return $func( $parser->killMarkers( $s ) );
191  }
192 
193  public static function lcfirst( $parser, $s = '' ) {
194  return $parser->getContentLanguage()->lcfirst( $s );
195  }
196 
197  public static function ucfirst( $parser, $s = '' ) {
198  return $parser->getContentLanguage()->ucfirst( $s );
199  }
200 
206  public static function lc( $parser, $s = '' ) {
207  return $parser->markerSkipCallback( $s, [ $parser->getContentLanguage(), 'lc' ] );
208  }
209 
215  public static function uc( $parser, $s = '' ) {
216  return $parser->markerSkipCallback( $s, [ $parser->getContentLanguage(), 'uc' ] );
217  }
218 
219  public static function localurl( $parser, $s = '', $arg = null ) {
220  return self::urlFunction( 'getLocalURL', $s, $arg );
221  }
222 
223  public static function localurle( $parser, $s = '', $arg = null ) {
224  $temp = self::urlFunction( 'getLocalURL', $s, $arg );
225  if ( !is_string( $temp ) ) {
226  return $temp;
227  } else {
228  return htmlspecialchars( $temp );
229  }
230  }
231 
232  public static function fullurl( $parser, $s = '', $arg = null ) {
233  return self::urlFunction( 'getFullURL', $s, $arg );
234  }
235 
236  public static function fullurle( $parser, $s = '', $arg = null ) {
237  $temp = self::urlFunction( 'getFullURL', $s, $arg );
238  if ( !is_string( $temp ) ) {
239  return $temp;
240  } else {
241  return htmlspecialchars( $temp );
242  }
243  }
244 
245  public static function canonicalurl( $parser, $s = '', $arg = null ) {
246  return self::urlFunction( 'getCanonicalURL', $s, $arg );
247  }
248 
249  public static function canonicalurle( $parser, $s = '', $arg = null ) {
250  $temp = self::urlFunction( 'getCanonicalURL', $s, $arg );
251  if ( !is_string( $temp ) ) {
252  return $temp;
253  } else {
254  return htmlspecialchars( $temp );
255  }
256  }
257 
258  public static function urlFunction( $func, $s = '', $arg = null ) {
260  # Due to order of execution of a lot of bits, the values might be encoded
261  # before arriving here; if that's true, then the title can't be created
262  # and the variable will fail. If we can't get a decent title from the first
263  # attempt, url-decode and try for a second.
264  if ( is_null( $title ) ) {
265  $title = Title::newFromURL( urldecode( $s ) );
266  }
267  if ( !is_null( $title ) ) {
268  # Convert NS_MEDIA -> NS_FILE
269  if ( $title->inNamespace( NS_MEDIA ) ) {
270  $title = Title::makeTitle( NS_FILE, $title->getDBkey() );
271  }
272  if ( !is_null( $arg ) ) {
273  $text = $title->$func( $arg );
274  } else {
275  $text = $title->$func();
276  }
277  return $text;
278  } else {
279  return [ 'found' => false ];
280  }
281  }
282 
289  public static function formatnum( $parser, $num = '', $arg = null ) {
290  if ( self::matchAgainstMagicword( $parser->getMagicWordFactory(), 'rawsuffix', $arg ) ) {
291  $func = [ $parser->getFunctionLang(), 'parseFormattedNumber' ];
292  } elseif (
293  self::matchAgainstMagicword( $parser->getMagicWordFactory(), 'nocommafysuffix', $arg )
294  ) {
295  $func = [ $parser->getFunctionLang(), 'formatNumNoSeparators' ];
296  } else {
297  $func = [ $parser->getFunctionLang(), 'formatNum' ];
298  }
299  return $parser->markerSkipCallback( $num, $func );
300  }
301 
308  public static function grammar( $parser, $case = '', $word = '' ) {
309  $word = $parser->killMarkers( $word );
310  return $parser->getFunctionLang()->convertGrammar( $word, $case );
311  }
312 
319  public static function gender( $parser, $username, ...$forms ) {
320  // Some shortcuts to avoid loading user data unnecessarily
321  if ( count( $forms ) === 0 ) {
322  return '';
323  } elseif ( count( $forms ) === 1 ) {
324  return $forms[0];
325  }
326 
327  $username = trim( $username );
328 
329  $gender = User::getDefaultOption( 'gender' );
330 
331  // allow prefix and normalize (e.g. "&#42;foo" -> "*foo" ).
332  $title = Title::newFromText( $username, NS_USER );
333 
334  if ( $title && $title->inNamespace( NS_USER ) ) {
335  $username = $title->getText();
336  }
337 
338  // check parameter, or use the ParserOptions if in interface message
339  $user = User::newFromName( $username );
340  $genderCache = MediaWikiServices::getInstance()->getGenderCache();
341  if ( $user ) {
342  $gender = $genderCache->getGenderOf( $user, __METHOD__ );
343  } elseif ( $username === '' && $parser->getOptions()->getInterfaceMessage() ) {
344  $gender = $genderCache->getGenderOf( $parser->getOptions()->getUser(), __METHOD__ );
345  }
346  $ret = $parser->getFunctionLang()->gender( $gender, $forms );
347  return $ret;
348  }
349 
356  public static function plural( $parser, $text = '', ...$forms ) {
357  $text = $parser->getFunctionLang()->parseFormattedNumber( $text );
358  settype( $text, ctype_digit( $text ) ? 'int' : 'float' );
359  return $parser->getFunctionLang()->convertPlural( $text, $forms );
360  }
361 
367  public static function bidi( $parser, $text = '' ) {
368  return $parser->getFunctionLang()->embedBidi( $text );
369  }
370 
380  public static function displaytitle( $parser, $text = '', $uarg = '' ) {
382 
383  static $magicWords = null;
384  if ( is_null( $magicWords ) ) {
385  $magicWords = $parser->getMagicWordFactory()->newArray(
386  [ 'displaytitle_noerror', 'displaytitle_noreplace' ] );
387  }
388  $arg = $magicWords->matchStartToEnd( $uarg );
389 
390  // parse a limited subset of wiki markup (just the single quote items)
391  $text = $parser->doQuotes( $text );
392 
393  // remove stripped text (e.g. the UNIQ-QINU stuff) that was generated by tag extensions/whatever
394  $text = $parser->killMarkers( $text );
395 
396  // list of disallowed tags for DISPLAYTITLE
397  // these will be escaped even though they are allowed in normal wiki text
398  $bad = [ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'blockquote', 'ol', 'ul', 'li', 'hr',
399  'table', 'tr', 'th', 'td', 'dl', 'dd', 'caption', 'p', 'ruby', 'rb', 'rt', 'rtc', 'rp', 'br' ];
400 
401  // disallow some styles that could be used to bypass $wgRestrictDisplayTitle
402  if ( $wgRestrictDisplayTitle ) {
403  $htmlTagsCallback = function ( &$params ) {
404  $decoded = Sanitizer::decodeTagAttributes( $params );
405 
406  if ( isset( $decoded['style'] ) ) {
407  // this is called later anyway, but we need it right now for the regexes below to be safe
408  // calling it twice doesn't hurt
409  $decoded['style'] = Sanitizer::checkCss( $decoded['style'] );
410 
411  if ( preg_match( '/(display|user-select|visibility)\s*:/i', $decoded['style'] ) ) {
412  $decoded['style'] = '/* attempt to bypass $wgRestrictDisplayTitle */';
413  }
414  }
415 
416  $params = Sanitizer::safeEncodeTagAttributes( $decoded );
417  };
418  } else {
419  $htmlTagsCallback = null;
420  }
421 
422  // only requested titles that normalize to the actual title are allowed through
423  // if $wgRestrictDisplayTitle is true (it is by default)
424  // mimic the escaping process that occurs in OutputPage::setPageTitle
426  $text,
427  $htmlTagsCallback,
428  [],
429  [],
430  $bad
431  ) );
433 
434  if ( !$wgRestrictDisplayTitle ||
435  ( $title instanceof Title
436  && !$title->hasFragment()
437  && $title->equals( $parser->getTitle() ) )
438  ) {
439  $old = $parser->mOutput->getProperty( 'displaytitle' );
440  if ( $old === false || $arg !== 'displaytitle_noreplace' ) {
441  $parser->mOutput->setDisplayTitle( $text );
442  }
443  if ( $old !== false && $old !== $text && !$arg ) {
444  $converter = $parser->getTargetLanguage()->getConverter();
445  return '<span class="error">' .
446  wfMessage( 'duplicate-displaytitle',
447  // Message should be parsed, but these params should only be escaped.
448  $converter->markNoConversion( wfEscapeWikiText( $old ) ),
449  $converter->markNoConversion( wfEscapeWikiText( $text ) )
450  )->inContentLanguage()->text() .
451  '</span>';
452  } else {
453  return '';
454  }
455  } else {
456  $parser->getOutput()->addWarning(
457  wfMessage( 'restricted-displaytitle',
458  // Message should be parsed, but this param should only be escaped.
459  wfEscapeWikiText( $text )
460  )->text()
461  );
462  $parser->addTrackingCategory( 'restricted-displaytitle-ignored' );
463  }
464  }
465 
475  private static function matchAgainstMagicword(
476  MagicWordFactory $magicWordFactory, $magicword, $value
477  ) {
478  $value = trim( strval( $value ) );
479  if ( $value === '' ) {
480  return false;
481  }
482  $mwObject = $magicWordFactory->get( $magicword );
483  return $mwObject->matchStartToEnd( $value );
484  }
485 
495  public static function formatRaw(
496  $num, $raw, $language, MagicWordFactory $magicWordFactory = null
497  ) {
498  if ( $raw !== null && !$magicWordFactory ) {
499  $magicWordFactory = MediaWikiServices::getInstance()->getMagicWordFactory();
500  }
501  if (
502  $raw !== null && self::matchAgainstMagicword( $magicWordFactory, 'rawsuffix', $raw )
503  ) {
504  return $num;
505  } else {
506  return $language->formatNum( $num );
507  }
508  }
509 
510  public static function numberofpages( $parser, $raw = null ) {
511  return self::formatRaw( SiteStats::pages(), $raw, $parser->getFunctionLang() );
512  }
513 
514  public static function numberofusers( $parser, $raw = null ) {
515  return self::formatRaw( SiteStats::users(), $raw, $parser->getFunctionLang() );
516  }
517 
518  public static function numberofactiveusers( $parser, $raw = null ) {
519  return self::formatRaw( SiteStats::activeUsers(), $raw, $parser->getFunctionLang() );
520  }
521 
522  public static function numberofarticles( $parser, $raw = null ) {
523  return self::formatRaw( SiteStats::articles(), $raw, $parser->getFunctionLang() );
524  }
525 
526  public static function numberoffiles( $parser, $raw = null ) {
527  return self::formatRaw( SiteStats::images(), $raw, $parser->getFunctionLang() );
528  }
529 
530  public static function numberofadmins( $parser, $raw = null ) {
531  return self::formatRaw(
532  SiteStats::numberingroup( 'sysop' ),
533  $raw,
534  $parser->getFunctionLang()
535  );
536  }
537 
538  public static function numberofedits( $parser, $raw = null ) {
539  return self::formatRaw( SiteStats::edits(), $raw, $parser->getFunctionLang() );
540  }
541 
542  public static function pagesinnamespace( $parser, $namespace = 0, $raw = null ) {
543  return self::formatRaw(
544  SiteStats::pagesInNs( intval( $namespace ) ),
545  $raw,
546  $parser->getFunctionLang()
547  );
548  }
549 
550  public static function numberingroup( $parser, $name = '', $raw = null ) {
551  return self::formatRaw(
552  SiteStats::numberingroup( strtolower( $name ) ),
553  $raw,
554  $parser->getFunctionLang()
555  );
556  }
557 
567  public static function mwnamespace( $parser, $title = null ) {
569  if ( is_null( $t ) ) {
570  return '';
571  }
572  return str_replace( '_', ' ', $t->getNsText() );
573  }
574 
575  public static function namespacee( $parser, $title = null ) {
577  if ( is_null( $t ) ) {
578  return '';
579  }
580  return wfUrlencode( $t->getNsText() );
581  }
582 
583  public static function namespacenumber( $parser, $title = null ) {
585  if ( is_null( $t ) ) {
586  return '';
587  }
588  return $t->getNamespace();
589  }
590 
591  public static function talkspace( $parser, $title = null ) {
593  if ( is_null( $t ) || !$t->canHaveTalkPage() ) {
594  return '';
595  }
596  return str_replace( '_', ' ', $t->getTalkNsText() );
597  }
598 
599  public static function talkspacee( $parser, $title = null ) {
601  if ( is_null( $t ) || !$t->canHaveTalkPage() ) {
602  return '';
603  }
604  return wfUrlencode( $t->getTalkNsText() );
605  }
606 
607  public static function subjectspace( $parser, $title = null ) {
609  if ( is_null( $t ) ) {
610  return '';
611  }
612  return str_replace( '_', ' ', $t->getSubjectNsText() );
613  }
614 
615  public static function subjectspacee( $parser, $title = null ) {
617  if ( is_null( $t ) ) {
618  return '';
619  }
620  return wfUrlencode( $t->getSubjectNsText() );
621  }
622 
630  public static function pagename( $parser, $title = null ) {
632  if ( is_null( $t ) ) {
633  return '';
634  }
635  return wfEscapeWikiText( $t->getText() );
636  }
637 
638  public static function pagenamee( $parser, $title = null ) {
640  if ( is_null( $t ) ) {
641  return '';
642  }
643  return wfEscapeWikiText( $t->getPartialURL() );
644  }
645 
646  public static function fullpagename( $parser, $title = null ) {
648  if ( is_null( $t ) || !$t->canHaveTalkPage() ) {
649  return '';
650  }
651  return wfEscapeWikiText( $t->getPrefixedText() );
652  }
653 
654  public static function fullpagenamee( $parser, $title = null ) {
656  if ( is_null( $t ) || !$t->canHaveTalkPage() ) {
657  return '';
658  }
659  return wfEscapeWikiText( $t->getPrefixedURL() );
660  }
661 
662  public static function subpagename( $parser, $title = null ) {
664  if ( is_null( $t ) ) {
665  return '';
666  }
667  return wfEscapeWikiText( $t->getSubpageText() );
668  }
669 
670  public static function subpagenamee( $parser, $title = null ) {
672  if ( is_null( $t ) ) {
673  return '';
674  }
675  return wfEscapeWikiText( $t->getSubpageUrlForm() );
676  }
677 
678  public static function rootpagename( $parser, $title = null ) {
680  if ( is_null( $t ) ) {
681  return '';
682  }
683  return wfEscapeWikiText( $t->getRootText() );
684  }
685 
686  public static function rootpagenamee( $parser, $title = null ) {
688  if ( is_null( $t ) ) {
689  return '';
690  }
691  return wfEscapeWikiText( wfUrlencode( str_replace( ' ', '_', $t->getRootText() ) ) );
692  }
693 
694  public static function basepagename( $parser, $title = null ) {
696  if ( is_null( $t ) ) {
697  return '';
698  }
699  return wfEscapeWikiText( $t->getBaseText() );
700  }
701 
702  public static function basepagenamee( $parser, $title = null ) {
704  if ( is_null( $t ) ) {
705  return '';
706  }
707  return wfEscapeWikiText( wfUrlencode( str_replace( ' ', '_', $t->getBaseText() ) ) );
708  }
709 
710  public static function talkpagename( $parser, $title = null ) {
712  if ( is_null( $t ) || !$t->canHaveTalkPage() ) {
713  return '';
714  }
715  return wfEscapeWikiText( $t->getTalkPage()->getPrefixedText() );
716  }
717 
718  public static function talkpagenamee( $parser, $title = null ) {
720  if ( is_null( $t ) || !$t->canHaveTalkPage() ) {
721  return '';
722  }
723  return wfEscapeWikiText( $t->getTalkPage()->getPrefixedURL() );
724  }
725 
726  public static function subjectpagename( $parser, $title = null ) {
728  if ( is_null( $t ) ) {
729  return '';
730  }
731  return wfEscapeWikiText( $t->getSubjectPage()->getPrefixedText() );
732  }
733 
734  public static function subjectpagenamee( $parser, $title = null ) {
736  if ( is_null( $t ) ) {
737  return '';
738  }
739  return wfEscapeWikiText( $t->getSubjectPage()->getPrefixedURL() );
740  }
741 
752  public static function pagesincategory( $parser, $name = '', $arg1 = null, $arg2 = null ) {
753  static $magicWords = null;
754  if ( is_null( $magicWords ) ) {
755  $magicWords = $parser->getMagicWordFactory()->newArray( [
756  'pagesincategory_all',
757  'pagesincategory_pages',
758  'pagesincategory_subcats',
759  'pagesincategory_files'
760  ] );
761  }
762  static $cache = [];
763 
764  // split the given option to its variable
765  if ( self::matchAgainstMagicword( $parser->getMagicWordFactory(), 'rawsuffix', $arg1 ) ) {
766  // {{pagesincategory:|raw[|type]}}
767  $raw = $arg1;
768  $type = $magicWords->matchStartToEnd( $arg2 );
769  } else {
770  // {{pagesincategory:[|type[|raw]]}}
771  $type = $magicWords->matchStartToEnd( $arg1 );
772  $raw = $arg2;
773  }
774  if ( !$type ) { // backward compatibility
775  $type = 'pagesincategory_all';
776  }
777 
779  if ( !$title ) { # invalid title
780  return self::formatRaw( 0, $raw, $parser->getFunctionLang() );
781  }
782  $parser->getContentLanguage()->findVariantLink( $name, $title, true );
783 
784  // Normalize name for cache
785  $name = $title->getDBkey();
786 
787  if ( !isset( $cache[$name] ) ) {
788  $category = Category::newFromTitle( $title );
789 
790  $allCount = $subcatCount = $fileCount = $pagesCount = 0;
791  if ( $parser->incrementExpensiveFunctionCount() ) {
792  // $allCount is the total number of cat members,
793  // not the count of how many members are normal pages.
794  $allCount = (int)$category->getPageCount();
795  $subcatCount = (int)$category->getSubcatCount();
796  $fileCount = (int)$category->getFileCount();
797  $pagesCount = $allCount - $subcatCount - $fileCount;
798  }
799  $cache[$name]['pagesincategory_all'] = $allCount;
800  $cache[$name]['pagesincategory_pages'] = $pagesCount;
801  $cache[$name]['pagesincategory_subcats'] = $subcatCount;
802  $cache[$name]['pagesincategory_files'] = $fileCount;
803  }
804 
805  $count = $cache[$name][$type];
806  return self::formatRaw( $count, $raw, $parser->getFunctionLang() );
807  }
808 
818  public static function pagesize( $parser, $page = '', $raw = null ) {
819  $title = Title::newFromText( $page );
820 
821  if ( !is_object( $title ) ) {
822  return self::formatRaw( 0, $raw, $parser->getFunctionLang() );
823  }
824 
825  // fetch revision from cache/database and return the value
826  $rev = self::getCachedRevisionObject( $parser, $title, 'vary-revision-sha1' );
827  $length = $rev ? $rev->getSize() : 0;
828  if ( $length === null ) {
829  // We've had bugs where rev_len was not being recorded for empty pages, see T135414
830  $length = 0;
831  }
832  return self::formatRaw( $length, $raw, $parser->getFunctionLang() );
833  }
834 
847  public static function protectionlevel( $parser, $type = '', $title = '' ) {
848  $titleObject = Title::newFromText( $title ) ?? $parser->getTitle();
849  if ( $titleObject->areRestrictionsLoaded() || $parser->incrementExpensiveFunctionCount() ) {
850  $restrictions = $titleObject->getRestrictions( strtolower( $type ) );
851  # Title::getRestrictions returns an array, its possible it may have
852  # multiple values in the future
853  return implode( ',', $restrictions );
854  }
855  return '';
856  }
857 
870  public static function protectionexpiry( $parser, $type = '', $title = '' ) {
871  $titleObject = Title::newFromText( $title ) ?? $parser->getTitle();
872  if ( $titleObject->areRestrictionsLoaded() || $parser->incrementExpensiveFunctionCount() ) {
873  $expiry = $titleObject->getRestrictionExpiry( strtolower( $type ) );
874  // getRestrictionExpiry() returns false on invalid type; trying to
875  // match protectionlevel() function that returns empty string instead
876  if ( $expiry === false ) {
877  $expiry = '';
878  }
879  return $expiry;
880  }
881  return '';
882  }
883 
891  public static function language( $parser, $code = '', $inLanguage = '' ) {
892  $code = strtolower( $code );
893  $inLanguage = strtolower( $inLanguage );
894  $lang = Language::fetchLanguageName( $code, $inLanguage );
895  return $lang !== '' ? $lang : LanguageCode::bcp47( $code );
896  }
897 
907  public static function pad(
908  $parser, $string, $length, $padding = '0', $direction = STR_PAD_RIGHT
909  ) {
910  $padding = $parser->killMarkers( $padding );
911  $lengthOfPadding = mb_strlen( $padding );
912  if ( $lengthOfPadding == 0 ) {
913  return $string;
914  }
915 
916  # The remaining length to add counts down to 0 as padding is added
917  $length = min( (int)$length, 500 ) - mb_strlen( $string );
918  if ( $length <= 0 ) {
919  // Nothing to add
920  return $string;
921  }
922 
923  # $finalPadding is just $padding repeated enough times so that
924  # mb_strlen( $string ) + mb_strlen( $finalPadding ) == $length
925  $finalPadding = '';
926  while ( $length > 0 ) {
927  # If $length < $lengthofPadding, truncate $padding so we get the
928  # exact length desired.
929  $finalPadding .= mb_substr( $padding, 0, $length );
930  $length -= $lengthOfPadding;
931  }
932 
933  if ( $direction == STR_PAD_LEFT ) {
934  return $finalPadding . $string;
935  } else {
936  return $string . $finalPadding;
937  }
938  }
939 
940  public static function padleft( $parser, $string = '', $length = 0, $padding = '0' ) {
941  return self::pad( $parser, $string, $length, $padding, STR_PAD_LEFT );
942  }
943 
944  public static function padright( $parser, $string = '', $length = 0, $padding = '0' ) {
945  return self::pad( $parser, $string, $length, $padding );
946  }
947 
953  public static function anchorencode( $parser, $text ) {
954  $text = $parser->killMarkers( $text );
955  $section = (string)substr( $parser->guessSectionNameFromWikiText( $text ), 1 );
956  return Sanitizer::safeEncodeAttribute( $section );
957  }
958 
959  public static function special( $parser, $text ) {
960  list( $page, $subpage ) = MediaWikiServices::getInstance()->getSpecialPageFactory()->
961  resolveAlias( $text );
962  if ( $page ) {
963  $title = SpecialPage::getTitleFor( $page, $subpage );
964  return $title->getPrefixedText();
965  } else {
966  // unknown special page, just use the given text as its title, if at all possible
968  return $title ? $title->getPrefixedText() : self::special( $parser, 'Badtitle' );
969  }
970  }
971 
972  public static function speciale( $parser, $text ) {
973  return wfUrlencode( str_replace( ' ', '_', self::special( $parser, $text ) ) );
974  }
975 
984  public static function defaultsort( $parser, $text, $uarg = '' ) {
985  static $magicWords = null;
986  if ( is_null( $magicWords ) ) {
987  $magicWords = $parser->getMagicWordFactory()->newArray(
988  [ 'defaultsort_noerror', 'defaultsort_noreplace' ] );
989  }
990  $arg = $magicWords->matchStartToEnd( $uarg );
991 
992  $text = trim( $text );
993  if ( strlen( $text ) == 0 ) {
994  return '';
995  }
996  $old = $parser->getCustomDefaultSort();
997  if ( $old === false || $arg !== 'defaultsort_noreplace' ) {
998  $parser->setDefaultSort( $text );
999  }
1000 
1001  if ( $old === false || $old == $text || $arg ) {
1002  return '';
1003  } else {
1004  $converter = $parser->getTargetLanguage()->getConverter();
1005  return '<span class="error">' .
1006  wfMessage( 'duplicate-defaultsort',
1007  // Message should be parsed, but these params should only be escaped.
1008  $converter->markNoConversion( wfEscapeWikiText( $old ) ),
1009  $converter->markNoConversion( wfEscapeWikiText( $text ) )
1010  )->inContentLanguage()->text() .
1011  '</span>';
1012  }
1013  }
1014 
1026  public static function filepath( $parser, $name = '', $argA = '', $argB = '' ) {
1027  $file = MediaWikiServices::getInstance()->getRepoGroup()->findFile( $name );
1028 
1029  if ( $argA == 'nowiki' ) {
1030  // {{filepath: | option [| size] }}
1031  $isNowiki = true;
1032  $parsedWidthParam = Parser::parseWidthParam( $argB );
1033  } else {
1034  // {{filepath: [| size [|option]] }}
1035  $parsedWidthParam = Parser::parseWidthParam( $argA );
1036  $isNowiki = ( $argB == 'nowiki' );
1037  }
1038 
1039  if ( $file ) {
1040  $url = $file->getFullUrl();
1041 
1042  // If a size is requested...
1043  if ( count( $parsedWidthParam ) ) {
1044  $mto = $file->transform( $parsedWidthParam );
1045  // ... and we can
1046  if ( $mto && !$mto->isError() ) {
1047  // ... change the URL to point to a thumbnail.
1048  $url = wfExpandUrl( $mto->getUrl(), PROTO_RELATIVE );
1049  }
1050  }
1051  if ( $isNowiki ) {
1052  return [ $url, 'nowiki' => true ];
1053  }
1054  return $url;
1055  } else {
1056  return '';
1057  }
1058  }
1059 
1067  public static function tagObj( $parser, $frame, $args ) {
1068  if ( !count( $args ) ) {
1069  return '';
1070  }
1071  $tagName = strtolower( trim( $frame->expand( array_shift( $args ) ) ) );
1072 
1073  if ( count( $args ) ) {
1074  $inner = $frame->expand( array_shift( $args ) );
1075  } else {
1076  $inner = null;
1077  }
1078 
1079  $attributes = [];
1080  foreach ( $args as $arg ) {
1081  $bits = $arg->splitArg();
1082  if ( strval( $bits['index'] ) === '' ) {
1083  $name = trim( $frame->expand( $bits['name'], PPFrame::STRIP_COMMENTS ) );
1084  $value = trim( $frame->expand( $bits['value'] ) );
1085  if ( preg_match( '/^(?:["\'](.+)["\']|""|\'\')$/s', $value, $m ) ) {
1086  $value = $m[1] ?? '';
1087  }
1088  $attributes[$name] = $value;
1089  }
1090  }
1091 
1092  $stripList = $parser->getStripList();
1093  if ( !in_array( $tagName, $stripList ) ) {
1094  // we can't handle this tag (at least not now), so just re-emit it as an ordinary tag
1095  $attrText = '';
1096  foreach ( $attributes as $name => $value ) {
1097  $attrText .= ' ' . htmlspecialchars( $name ) . '="' . htmlspecialchars( $value ) . '"';
1098  }
1099  if ( $inner === null ) {
1100  return "<$tagName$attrText/>";
1101  }
1102  return "<$tagName$attrText>$inner</$tagName>";
1103  }
1104 
1105  $params = [
1106  'name' => $tagName,
1107  'inner' => $inner,
1108  'attributes' => $attributes,
1109  'close' => "</$tagName>",
1110  ];
1111  return $parser->extensionSubstitution( $params, $frame );
1112  }
1113 
1127  private static function getCachedRevisionObject( $parser, $title, $vary ) {
1128  if ( !$title ) {
1129  return null;
1130  }
1131 
1132  $revision = null;
1133 
1134  $isSelfReferential = $title->equals( $parser->getTitle() );
1135  if ( $isSelfReferential ) {
1136  // Revision is for the same title that is currently being parsed. Only use the last
1137  // saved revision, regardless of Parser::getRevisionId() or fake revision injection
1138  // callbacks against the current title.
1139  $parserRevision = $parser->getRevisionObject();
1140  if ( $parserRevision && $parserRevision->isCurrent() ) {
1141  $revision = $parserRevision;
1142  wfDebug( __METHOD__ . ": used current revision, setting $vary" );
1143  }
1144  }
1145 
1146  $parserOutput = $parser->getOutput();
1147  if ( !$revision ) {
1148  if (
1149  !$parser->isCurrentRevisionOfTitleCached( $title ) &&
1150  !$parser->incrementExpensiveFunctionCount()
1151  ) {
1152  return null; // not allowed
1153  }
1154  // Get the current revision, ignoring Parser::getRevisionId() being null/old
1155  $revision = $parser->fetchCurrentRevisionOfTitle( $title );
1156  // Register dependency in templatelinks
1157  $parserOutput->addTemplate(
1158  $title,
1159  $revision ? $revision->getPage() : 0,
1160  $revision ? $revision->getId() : 0
1161  );
1162  }
1163 
1164  if ( $isSelfReferential ) {
1165  // Upon page save, the result of the parser function using this might change
1166  $parserOutput->setFlag( $vary );
1167  if ( $vary === 'vary-revision-sha1' && $revision ) {
1168  $parserOutput->setRevisionUsedSha1Base36( $revision->getSha1() );
1169  }
1170  }
1171 
1172  return $revision;
1173  }
1174 
1182  public static function pageid( $parser, $title = null ) {
1184  if ( !$t ) {
1185  return '';
1186  } elseif ( !$t->canExist() || $t->isExternal() ) {
1187  return 0; // e.g. special page or interwiki link
1188  }
1189 
1190  $parserOutput = $parser->getOutput();
1191 
1192  if ( $t->equals( $parser->getTitle() ) ) {
1193  // Revision is for the same title that is currently being parsed.
1194  // Use the title from Parser in case a new page ID was injected into it.
1195  $parserOutput->setFlag( 'vary-page-id' );
1196  $id = $parser->getTitle()->getArticleID();
1197  if ( $id ) {
1198  $parserOutput->setSpeculativePageIdUsed( $id );
1199  }
1200 
1201  return $id;
1202  }
1203 
1204  // Check the link cache for the title
1205  $linkCache = MediaWikiServices::getInstance()->getLinkCache();
1206  $pdbk = $t->getPrefixedDBkey();
1207  $id = $linkCache->getGoodLinkID( $pdbk );
1208  if ( $id != 0 || $linkCache->isBadLink( $pdbk ) ) {
1209  $parserOutput->addLink( $t, $id );
1210 
1211  return $id;
1212  }
1213 
1214  // We need to load it from the DB, so mark expensive
1215  if ( $parser->incrementExpensiveFunctionCount() ) {
1216  $id = $t->getArticleID();
1217  $parserOutput->addLink( $t, $id );
1218 
1219  return $id;
1220  }
1221 
1222  return null;
1223  }
1224 
1232  public static function revisionid( $parser, $title = null ) {
1234  if ( is_null( $t ) ) {
1235  return '';
1236  }
1237  // fetch revision from cache/database and return the value
1238  $rev = self::getCachedRevisionObject( $parser, $t, 'vary-revision-id' );
1239  return $rev ? $rev->getId() : '';
1240  }
1241 
1249  public static function revisionday( $parser, $title = null ) {
1251  if ( is_null( $t ) ) {
1252  return '';
1253  }
1254  // fetch revision from cache/database and return the value
1255  $rev = self::getCachedRevisionObject( $parser, $t, 'vary-revision-timestamp' );
1256  return $rev ? MWTimestamp::getLocalInstance( $rev->getTimestamp() )->format( 'j' ) : '';
1257  }
1258 
1266  public static function revisionday2( $parser, $title = null ) {
1268  if ( is_null( $t ) ) {
1269  return '';
1270  }
1271  // fetch revision from cache/database and return the value
1272  $rev = self::getCachedRevisionObject( $parser, $t, 'vary-revision-timestamp' );
1273  return $rev ? MWTimestamp::getLocalInstance( $rev->getTimestamp() )->format( 'd' ) : '';
1274  }
1275 
1283  public static function revisionmonth( $parser, $title = null ) {
1285  if ( is_null( $t ) ) {
1286  return '';
1287  }
1288  // fetch revision from cache/database and return the value
1289  $rev = self::getCachedRevisionObject( $parser, $t, 'vary-revision-timestamp' );
1290  return $rev ? MWTimestamp::getLocalInstance( $rev->getTimestamp() )->format( 'm' ) : '';
1291  }
1292 
1300  public static function revisionmonth1( $parser, $title = null ) {
1302  if ( is_null( $t ) ) {
1303  return '';
1304  }
1305  // fetch revision from cache/database and return the value
1306  $rev = self::getCachedRevisionObject( $parser, $t, 'vary-revision-timestamp' );
1307  return $rev ? MWTimestamp::getLocalInstance( $rev->getTimestamp() )->format( 'n' ) : '';
1308  }
1309 
1317  public static function revisionyear( $parser, $title = null ) {
1319  if ( is_null( $t ) ) {
1320  return '';
1321  }
1322  // fetch revision from cache/database and return the value
1323  $rev = self::getCachedRevisionObject( $parser, $t, 'vary-revision-timestamp' );
1324  return $rev ? MWTimestamp::getLocalInstance( $rev->getTimestamp() )->format( 'Y' ) : '';
1325  }
1326 
1334  public static function revisiontimestamp( $parser, $title = null ) {
1336  if ( is_null( $t ) ) {
1337  return '';
1338  }
1339  // fetch revision from cache/database and return the value
1340  $rev = self::getCachedRevisionObject( $parser, $t, 'vary-revision-timestamp' );
1341  return $rev ? MWTimestamp::getLocalInstance( $rev->getTimestamp() )->format( 'YmdHis' ) : '';
1342  }
1343 
1351  public static function revisionuser( $parser, $title = null ) {
1353  if ( is_null( $t ) ) {
1354  return '';
1355  }
1356  // fetch revision from cache/database and return the value
1357  $rev = self::getCachedRevisionObject( $parser, $t, 'vary-user' );
1358  return $rev ? $rev->getUserText() : '';
1359  }
1360 
1373  public static function cascadingsources( $parser, $title = '' ) {
1374  $titleObject = Title::newFromText( $title ) ?? $parser->getTitle();
1375  if ( $titleObject->areCascadeProtectionSourcesLoaded()
1376  || $parser->incrementExpensiveFunctionCount()
1377  ) {
1378  $names = [];
1379  $sources = $titleObject->getCascadeProtectionSources();
1380  foreach ( $sources[0] as $sourceTitle ) {
1381  $names[] = $sourceTitle->getPrefixedText();
1382  }
1383  return implode( '|', $names );
1384  }
1385  return '';
1386  }
1387 
1388 }
static intFunction( $parser, $part1='',... $params)
static revisionday( $parser, $title=null)
Get the day from the last revision of a specified page.
static special( $parser, $text)
static subpagenamee( $parser, $title=null)
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
Definition: router.php:42
wfEscapeWikiText( $text)
Escapes the given text so that it may be output using addWikiText() without any linking, formatting, etc.
static grammar( $parser, $case='', $word='')
static getLocalInstance( $ts=false)
Get a timestamp instance in the server local timezone ($wgLocaltimezone)
static numberofusers( $parser, $raw=null)
static rootpagename( $parser, $title=null)
static fullpagename( $parser, $title=null)
static pagename( $parser, $title=null)
Functions to get and normalize pagenames, corresponding to the magic words of the same names...
static newFromTitle( $title)
Factory function.
Definition: Category.php:146
static getCachedRevisionObject( $parser, $title, $vary)
Fetched the current revision of the given title and return this.
static revisiontimestamp( $parser, $title=null)
Get the timestamp from the last revision of a specified page.
wfExpandUrl( $url, $defaultProto=PROTO_CURRENT)
Expand a potentially local URL to a fully-qualified URL.
if(!isset( $args[0])) $lang
static nse( $parser, $part1='')
static revisionday2( $parser, $title=null)
Get the day with leading zeros from the last revision of a specified page.
static talkpagename( $parser, $title=null)
static namespacee( $parser, $title=null)
const NS_SPECIAL
Definition: Defines.php:49
static basepagenamee( $parser, $title=null)
static talkspace( $parser, $title=null)
static localurl( $parser, $s='', $arg=null)
static language( $parser, $code='', $inLanguage='')
Gives language names.
static gender( $parser, $username,... $forms)
static activeUsers()
Definition: SiteStats.php:130
$wgRestrictDisplayTitle
For consistency, restrict DISPLAYTITLE to text that normalizes to the same canonical DB key...
static anchorencode( $parser, $text)
static uc( $parser, $s='')
static subjectspacee( $parser, $title=null)
static pagesize( $parser, $page='', $raw=null)
Return the size of the given page, or 0 if it&#39;s nonexistent.
const SFH_NO_HASH
Definition: Parser.php:89
static fullpagenamee( $parser, $title=null)
static padleft( $parser, $string='', $length=0, $padding='0')
$magicWords
Definition: MessagesAb.php:71
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.
if( $line===false) $args
Definition: cdb.php:64
static numberingroup( $group)
Find the number of users in a given user group.
Definition: SiteStats.php:150
static revisionmonth1( $parser, $title=null)
Get the month from the last revision of a specified page.
static formatDate( $parser, $date, $defaultPref=null)
static edits()
Definition: SiteStats.php:94
static pagesincategory( $parser, $name='', $arg1=null, $arg2=null)
Return the number of pages, files or subcats in the given category, or 0 if it&#39;s nonexistent.
static parseWidthParam( $value, $parseHeight=true)
Parsed a width param of imagelink like 300px or 200x300px.
Definition: Parser.php:6445
static stripAllTags( $html)
Take a fragment of (potentially invalid) HTML and return a version with any tags removed, encoded as plain text.
Definition: Sanitizer.php:2041
static revisionyear( $parser, $title=null)
Get the year from the last revision of a specified page.
wfUrlencode( $s)
We want some things to be included as literal characters in our title URLs for prettiness, which urlencode encodes by default.
static pagesInNs( $ns)
Definition: SiteStats.php:201
static numberofpages( $parser, $raw=null)
static fullurl( $parser, $s='', $arg=null)
const NS_MEDIA
Definition: Defines.php:48
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
static localurle( $parser, $s='', $arg=null)
static pagenamee( $parser, $title=null)
$cache
Definition: mcc.php:33
static bidi( $parser, $text='')
const NS_CATEGORY
Definition: Defines.php:74
static numberofadmins( $parser, $raw=null)
static urlencode( $parser, $s='', $arg=null)
urlencodes a string according to one of three patterns: (T24474)
static fullurle( $parser, $s='', $arg=null)
Various core parser functions, registered in Parser::firstCallInit()
static displaytitle( $parser, $text='', $uarg='')
Override the title of the page when viewed, provided we&#39;ve been given a title which will normalise to...
static decodeTagAttributes( $text)
Return an associative array of attribute names and values from a partial tag string.
Definition: Sanitizer.php:1450
const PROTO_RELATIVE
Definition: Defines.php:201
static numberoffiles( $parser, $raw=null)
static talkspacee( $parser, $title=null)
const NS_FILE
Definition: Defines.php:66
static getTitleFor( $name, $subpage=false, $fragment='')
Get a localised Title object for a specified special page name If you don&#39;t need a full Title object...
Definition: SpecialPage.php:83
static rootpagenamee( $parser, $title=null)
static normalizeCharReferences( $text)
Ensure that any entities and character references are legal for XML and XHTML specifically.
Definition: Sanitizer.php:1569
static subjectpagename( $parser, $title=null)
static padright( $parser, $string='', $length=0, $padding='0')
static speciale( $parser, $text)
static getDefaultOption( $opt)
Get a given default option value.
Definition: User.php:1708
static makeTitleSafe( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:612
static images()
Definition: SiteStats.php:139
static formatRaw( $num, $raw, $language, MagicWordFactory $magicWordFactory=null)
Formats a number according to a language.
static filepath( $parser, $name='', $argA='', $argB='')
Usage {{filepath|300}}, {{filepath|nowiki}}, {{filepath|nowiki|300}} or {{filepath|300|nowiki}} or {{...
static makeTitle( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:586
static fetchLanguageName( $code, $inLanguage=self::AS_AUTONYMS, $include=self::ALL)
Definition: Language.php:828
static ns( $parser, $part1='')
static matchAgainstMagicword(MagicWordFactory $magicWordFactory, $magicword, $value)
Matches the given value against the value of given magic word.
static talkpagenamee( $parser, $title=null)
static safeEncodeTagAttributes( $assoc_array)
Build a partial tag string from an associative array of attribute names and values as returned by dec...
Definition: Sanitizer.php:1492
static lcfirst( $parser, $s='')
static defaultsort( $parser, $text, $uarg='')
static numberofactiveusers( $parser, $raw=null)
static newFromURL( $url)
THIS IS NOT THE FUNCTION YOU WANT.
Definition: Title.php:404
static numberofedits( $parser, $raw=null)
static urlFunction( $func, $s='', $arg=null)
static lc( $parser, $s='')
static subjectspace( $parser, $title=null)
static articles()
Definition: SiteStats.php:103
static pages()
Definition: SiteStats.php:112
static namespacenumber( $parser, $title=null)
const SFH_OBJECT_ARGS
Definition: Parser.php:90
static protectionlevel( $parser, $type='', $title='')
Returns the requested protection level for the current page.
$wgAllowSlowParserFunctions
Enable slow parser functions.
static plural( $parser, $text='',... $forms)
static checkCss( $value)
Pick apart some CSS and check it for forbidden or unsafe structures.
Definition: Sanitizer.php:1065
static tagObj( $parser, $frame, $args)
Parser function to extension tag adaptor.
static revisionid( $parser, $title=null)
Get the id from the last revision of a specified page.
static removeHTMLtags( $text, $processCallback=null, $args=[], $extratags=[], $removetags=[], $warnCallback=null)
Cleans up HTML, removes dangerous tags and attributes, and removes HTML comments. ...
Definition: Sanitizer.php:497
static formatnum( $parser, $num='', $arg=null)
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
static mwnamespace( $parser, $title=null)
Given a title, return the namespace name that would be given by the corresponding magic word Note: fu...
static newFromName( $name, $validate='valid')
Static factory method for creation from username.
Definition: User.php:533
const STRIP_COMMENTS
Definition: PPFrame.php:31
static revisionuser( $parser, $title=null)
Get the user from the last revision of a specified page.
static subpagename( $parser, $title=null)
static cascadingsources( $parser, $title='')
Returns the sources of any cascading protection acting on a specified page.
static revisionmonth( $parser, $title=null)
Get the month with leading zeros from the last revision of a specified page.
static numberingroup( $parser, $name='', $raw=null)
$wgAllowDisplayTitle
Allow DISPLAYTITLE to change title display.
static pageid( $parser, $title=null)
Get the pageid of a specified page.
static basepagename( $parser, $title=null)
static canonicalurle( $parser, $s='', $arg=null)
static ucfirst( $parser, $s='')
static numberofarticles( $parser, $raw=null)
static subjectpagenamee( $parser, $title=null)
get( $id)
Factory: creates an object representing an ID.
static users()
Definition: SiteStats.php:121
static pagesinnamespace( $parser, $namespace=0, $raw=null)
static protectionexpiry( $parser, $type='', $title='')
Returns the requested protection expiry for the current page.
return true
Definition: router.php:92
static bcp47( $code)
Get the normalised IETF language tag See unit test for examples.
static canonicalurl( $parser, $s='', $arg=null)
static safeEncodeAttribute( $text)
Encode an attribute value for HTML tags, with extra armoring against further wiki processing...
Definition: Sanitizer.php:1199
static newFromText( $text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Definition: Title.php:319