42 $wgHooks[
'ParserClearState'][] =
function () {
43 self::$mTimeChars = 0;
53 if ( !isset( self::$mExprParser ) ) {
68 public static function expr(
Parser $parser, $expr =
'' ) {
88 $then =
$args[1] ??
'';
89 $else =
$args[2] ??
'';
93 if ( is_numeric( $result ) ) {
94 $result = (float)$result;
96 $result = $result ? $then : $else;
101 if ( is_object( $result ) ) {
102 $result = trim( $frame->
expand( $result ) );
120 if ( $test !==
'' ) {
143 if ( $left == $right ) {
165 $then =
$args[1] ??
false;
166 $else =
$args[2] ??
false;
169 '/<(?:strong|span|p|div)\s(?:[^\s>]*\s+)*?class="(?:[^"\s>]*\s+)*?error(?:\s[^">]*)?"/',
173 } elseif ( $else ===
false ) {
178 if ( $result ===
false ) {
182 return trim( $frame->
expand( $result ) );
201 if ( count(
$args ) === 0 ) {
205 $found = $defaultFound =
false;
207 $lastItemHadNoEquals =
false;
210 foreach (
$args as $arg ) {
211 $bits = $arg->splitArg();
212 $nameNode = $bits[
'name'];
213 $index = $bits[
'index'];
214 $valueNode = $bits[
'value'];
216 if ( $index ===
'' ) {
218 $lastItemHadNoEquals =
false;
220 # Multiple input match
221 return trim( $frame->
expand( $valueNode ) );
225 if ( $test == $primary ) {
226 # Found a match, return now
227 return trim( $frame->
expand( $valueNode ) );
228 } elseif ( $defaultFound || $mwDefault->matchStartToEnd( $test ) ) {
229 $default = $valueNode;
230 $defaultFound =
false;
231 } #
else wrong
case,
continue
234 # Multiple input, single output
235 # If the value matches, set a flag and continue
236 $lastItemHadNoEquals =
true;
240 if ( $decodedTest == $primary ) {
242 } elseif ( $mwDefault->matchStartToEnd( $decodedTest ) ) {
243 $defaultFound =
true;
248 # Check if the last item had no = sign, thus specifying the default case
249 if ( $lastItemHadNoEquals ) {
251 } elseif ( !is_null( $default ) ) {
252 return trim( $frame->
expand( $default ) );
276 $from = trim( $from );
277 if ( $from ===
'' ) {
278 $from = $parser->
getTitle()->getPrefixedText();
281 $to = rtrim( $to,
' /' );
284 if ( $to ===
'' || $to ===
'.' ) {
289 if ( substr( $to, 0, 1 ) !==
'/' &&
290 substr( $to, 0, 2 ) !==
'./' &&
291 substr( $to, 0, 3 ) !==
'../' &&
297 $fullPath =
'/' . $from .
'/' . $to .
'/';
300 $fullPath = preg_replace(
'!/(\./)+!',
'/', $fullPath );
303 $fullPath = preg_replace(
'!/{2,}!',
'/', $fullPath );
306 $fullPath = trim( $fullPath,
'/' );
307 $exploded = explode(
'/', $fullPath );
310 foreach ( $exploded as $current ) {
311 if ( $current ===
'..' ) {
312 if ( !count( $newExploded ) ) {
314 $msg =
wfMessage(
'pfunc_rel2abs_invalid_depth', $fullPath )
315 ->inContentLanguage()->escaped();
316 return '<strong class="error">' . $msg .
'</strong>';
319 array_pop( $newExploded );
322 $newExploded[] = $current;
327 return implode(
'/', $newExploded );
340 Parser $parser,
PPFrame $frame, $titletext =
'', $then =
'', $else =
''
342 $title = Title::newFromText( $titletext );
356 $parser->mOutput->addImage(
358 return $file->exists() ? $then : $else;
359 } elseif (
$title->isSpecialPage() ) {
365 ->exists(
$title->getDBkey() ) ? $then : $else;
366 } elseif (
$title->isExternal() ) {
373 $pdbk =
$title->getPrefixedDBkey();
375 $id = $lc->getGoodLinkID( $pdbk );
377 $parser->mOutput->addLink(
$title, $id );
379 } elseif ( $lc->isBadLink( $pdbk ) ) {
380 $parser->mOutput->addLink(
$title, 0 );
386 $id =
$title->getArticleID();
387 $parser->mOutput->addLink(
$title, $id );
410 $then =
$args[1] ??
null;
411 $else =
$args[2] ??
null;
414 if ( $result ===
null ) {
417 return trim( $frame->
expand( $result ) );
433 Parser $parser,
PPFrame $frame =
null, $format =
'', $date =
'', $language =
'', $local =
false
437 if ( $date ===
'' ) {
438 $cacheKey = $parser->
getOptions()->getTimestamp();
440 $date = $timestamp->getTimestamp( TS_ISO_8601 );
446 if ( isset( self::$mTimeCache[$format][$cacheKey][$language][$local] ) ) {
447 $cachedVal = self::$mTimeCache[$format][$cacheKey][$language][$local];
448 if ( $useTTL && $cachedVal[1] !==
null && $frame ) {
449 $frame->
setTTL( $cachedVal[1] );
451 return $cachedVal[0];
454 # compute the timestamp string $ts
455 # PHP >= 5.2 can handle dates before 1970 or after 2038 using the DateTime object
457 $invalidTime =
false;
459 # the DateTime constructor must be used because it throws exceptions
460 # when errors occur, whereas date_create appears to just output a warning
461 # that can't really be detected from within the code
464 # Default input timezone is UTC.
465 $utc =
new DateTimeZone(
'UTC' );
467 # Correct for DateTime interpreting 'XXXX' as XX:XX o'clock
468 if ( preg_match(
'/^[0-9]{4}$/', $date ) ) {
469 $date =
'00:00 ' . $date;
473 # UTC is a default input timezone.
474 $dateObject =
new DateTime( $date, $utc );
476 # Set output timezone.
481 $tz =
new DateTimeZone( date_default_timezone_get() );
486 $dateObject->setTimezone( $tz );
488 $ts = $dateObject->format(
'YmdHis' );
490 }
catch ( Exception $ex ) {
495 # format the timestamp and return the result
496 if ( $invalidTime ) {
497 $result =
'<strong class="error">' .
498 wfMessage(
'pfunc_time_error' )->inContentLanguage()->escaped() .
501 self::$mTimeChars += strlen( $format );
502 if ( self::$mTimeChars > self::MAX_TIME_CHARS ) {
503 return '<strong class="error">' .
504 wfMessage(
'pfunc_time_too_long' )->inContentLanguage()->escaped() .
508 return '<strong class="error">' .
509 wfMessage(
'pfunc_time_too_small' )->inContentLanguage()->escaped() .
511 } elseif ( $ts < 100000000000000 ) {
521 $result = $langObject->sprintfDate( $format, $ts, $tz, $ttl );
523 return '<strong class="error">' .
524 wfMessage(
'pfunc_time_too_big' )->inContentLanguage()->escaped() .
529 self::$mTimeCache[$format][$cacheKey][$language][$local] = [ $result, $ttl ];
530 if ( $useTTL && $ttl !==
null && $frame ) {
553 return self::timeCommon( $parser, $frame, $format, $date, $language, $local );
573 return self::timeCommon( $parser, $frame, $format, $date, $language,
true );
589 $parts = (int)$parts;
590 $offset = (int)$offset;
591 $ntitle = Title::newFromText(
$title );
592 if ( $ntitle instanceof
Title ) {
593 $bits = explode(
'/', $ntitle->getPrefixedText(), 25 );
594 if ( count( $bits ) <= 0 ) {
595 return $ntitle->getPrefixedText();
600 if ( $parts === 0 ) {
601 return implode(
'/', array_slice( $bits, $offset ) );
603 return implode(
'/', array_slice( $bits, $offset, $parts ) );
618 global $wgPFStringLengthLimit;
619 return ( mb_strlen( $text ) < $wgPFStringLengthLimit );
627 global $wgPFStringLengthLimit;
628 $msg =
wfMessage(
'pfunc_string_too_long' )->numParams( $wgPFStringLengthLimit );
629 return '<strong class="error">' . $msg->inContentLanguage()->escaped() .
'</strong>';
643 return mb_strlen( $inStr );
659 public static function runPos(
Parser $parser, $inStr =
'', $inNeedle =
'', $inOffset = 0 ) {
661 $inNeedle = $parser->
killMarkers( (
string)$inNeedle );
663 if ( !self::checkLength( $inStr ) ||
664 !self::checkLength( $inNeedle ) ) {
668 if ( $inNeedle ===
'' ) {
672 $pos = mb_strpos( $inStr, $inNeedle, min( (
int)$inOffset, mb_strlen( $inStr ) ) );
673 if ( $pos ===
false ) {
692 public static function runRPos(
Parser $parser, $inStr =
'', $inNeedle =
'' ) {
694 $inNeedle = $parser->
killMarkers( (
string)$inNeedle );
696 if ( !self::checkLength( $inStr ) ||
697 !self::checkLength( $inNeedle ) ) {
701 if ( $inNeedle ===
'' ) {
705 $pos = mb_strrpos( $inStr, $inNeedle );
706 if ( $pos ===
false ) {
731 public static function runSub(
Parser $parser, $inStr =
'', $inStart = 0, $inLength = 0 ) {
734 if ( !self::checkLength( $inStr ) ) {
738 if ( (
int)$inLength === 0 ) {
739 $result = mb_substr( $inStr, (
int)$inStart );
741 $result = mb_substr( $inStr, (
int)$inStart, (
int)$inLength );
761 $inSubStr = $parser->
killMarkers( (
string)$inSubStr );
763 if ( !self::checkLength( $inStr ) ||
764 !self::checkLength( $inSubStr ) ) {
768 if ( $inSubStr ===
'' ) {
772 $result = mb_substr_count( $inStr, $inSubStr );
794 $inReplaceFrom =
'', $inReplaceTo =
'', $inLimit = -1 ) {
795 global $wgPFStringLengthLimit;
798 $inReplaceFrom = $parser->
killMarkers( (
string)$inReplaceFrom );
799 $inReplaceTo = $parser->
killMarkers( (
string)$inReplaceTo );
801 if ( !self::checkLength( $inStr ) ||
802 !self::checkLength( $inReplaceFrom ) ||
803 !self::checkLength( $inReplaceTo ) ) {
807 if ( $inReplaceFrom ===
'' ) {
808 $inReplaceFrom =
' ';
812 $diff = mb_strlen( $inReplaceTo ) - mb_strlen( $inReplaceFrom );
814 $limit = ( ( $wgPFStringLengthLimit - mb_strlen( $inStr ) ) / $diff ) + 1;
819 $inLimit = (int)$inLimit;
820 if ( $inLimit >= 0 ) {
821 if ( $limit > $inLimit || $limit == -1 ) {
827 $inReplaceFrom = preg_quote( $inReplaceFrom,
'/' );
830 $result = preg_replace(
'/' . $inReplaceFrom .
'/u',
831 $inReplaceTo, $inStr, $limit );
833 if ( !self::checkLength( $result ) ) {
858 Parser $parser, $inStr =
'', $inDiv =
'', $inPos = 0, $inLim =
null
863 if ( $inDiv ===
'' ) {
867 if ( !self::checkLength( $inStr ) ||
868 !self::checkLength( $inDiv ) ) {
872 $inDiv = preg_quote( $inDiv,
'/' );
874 $matches = preg_split(
'/' . $inDiv .
'/u', $inStr, $inLim );
876 if ( $inPos >= 0 && isset(
$matches[$inPos] ) ) {
898 if ( !self::checkLength( $inStr ) ) {
902 return urldecode( $inStr );
918 $expanded = $frame->
expand( $obj );
919 $trimExpanded = trim( $expanded );
$wgLocaltimezone
Fake out the timezone that the server thinks it's in.
wfFindFile( $title, $options=[])
Find a file.
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
Internationalisation code.
static isValidBuiltInCode( $code)
Returns true if a language code is of a valid form for the purposes of internal customisation of Medi...
static factory( $code)
Get a cached or new language object for a given language code.
Cache for article titles (prefixed DB keys) and ids linked from one source.
static singleton()
Get an instance of this class.
Library for creating and parsing MW-style timestamps.
PHP Parser - Processes wiki markup (which uses a more user-friendly syntax, such as "[[link]]" for ma...
getMagicWordFactory()
Get the MagicWordFactory that this Parser is using.
getOptions()
Get the ParserOptions object.
getTitle()
Accessor for the Title object.
getFunctionLang()
Get a language object for use in parser functions such as {{FORMATNUM:}}.
getContentLanguage()
Get the content language that this Parser is using.
incrementExpensiveFunctionCount()
Increment the expensive function count.
killMarkers( $text)
Remove any strip markers found in the given text.
HTML sanitizer for MediaWiki.
static decodeCharReferences( $text)
Decode any character references, numeric or named entities, in the text and return a UTF-8 string.
A collection of static methods to play with strings.
static escapeRegexReplacement( $string)
Escape a string to make it suitable for inclusion in a preg_replace() replacement parameter.
Class to implement stub globals, which are globals that delay loading the their associated module cod...
static unstub(&$obj)
Unstubs an object, if it is a stub object.
Represents a title within MediaWiki.
setTTL( $ttl)
Set the TTL of the output of this frame and all of its ancestors.
expand( $root, $flags=0)
Expand a document tree node.
There are three types of nodes:
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.