14 self::$mTimeChars = 0;
27 $wgHooks[
'ParserClearState'][] = __CLASS__ .
'::clearState';
36 if ( !isset( self::$mExprParser ) ) {
51 return '<strong class="error">' . htmlspecialchars(
$e->getMessage() ) .
'</strong>';
62 public static function ifexpr(
$parser, $expr =
'', $then =
'', $else =
'' ) {
65 if ( is_numeric(
$ret ) ) {
74 return '<strong class="error">' . htmlspecialchars(
$e->getMessage() ) .
'</strong>';
85 $expr = isset(
$args[0] ) ? trim( $frame->expand(
$args[0] ) ) :
'';
89 if ( is_object( $result ) ) {
90 $result = trim( $frame->expand( $result ) );
102 $test = isset(
$args[0] ) ? trim( $frame->expand(
$args[0] ) ) :
'';
103 if ( $test !==
'' ) {
104 return isset(
$args[1] ) ? trim( $frame->expand(
$args[1] ) ) :
'';
106 return isset(
$args[2] ) ? trim( $frame->expand(
$args[2] ) ) :
'';
122 if ( $left == $right ) {
123 return isset(
$args[2] ) ? trim( $frame->expand(
$args[2] ) ) :
'';
125 return isset(
$args[3] ) ? trim( $frame->expand(
$args[3] ) ) :
'';
136 public static function iferror(
$parser, $test =
'', $then =
'', $else =
false ) {
138 '/<(?:strong|span|p|div)\s(?:[^\s>]*\s+)*?class="(?:[^"\s>]*\s+)*?error(?:\s[^">]*)?"/',
142 } elseif ( $else ===
false ) {
156 $test = isset(
$args[0] ) ? trim( $frame->expand(
$args[0] ) ) :
'';
160 if ( $result ===
false ) {
163 return trim( $frame->expand( $result ) );
174 if ( count(
$args ) === 0 ) {
178 $found = $defaultFound =
false;
180 $lastItemHadNoEquals =
false;
183 foreach (
$args as $arg ) {
184 $bits = $arg->splitArg();
185 $nameNode = $bits[
'name'];
186 $index = $bits[
'index'];
187 $valueNode = $bits[
'value'];
189 if ( $index ===
'' ) {
191 $lastItemHadNoEquals =
false;
193 # Multiple input match
194 return trim( $frame->expand( $valueNode ) );
198 if ( $test == $primary ) {
199 # Found a match, return now
200 return trim( $frame->expand( $valueNode ) );
201 } elseif ( $defaultFound || $mwDefault->matchStartToEnd( $test ) ) {
202 $default = $valueNode;
203 $defaultFound =
false;
204 } #
else wrong
case,
continue
207 # Multiple input, single output
208 # If the value matches, set a flag and continue
209 $lastItemHadNoEquals =
true;
213 if ( $decodedTest == $primary ) {
215 } elseif ( $mwDefault->matchStartToEnd( $decodedTest ) ) {
216 $defaultFound =
true;
221 # Check if the last item had no = sign, thus specifying the default case
222 if ( $lastItemHadNoEquals ) {
224 } elseif ( !is_null( $default ) ) {
225 return trim( $frame->expand( $default ) );
245 $from = trim( $from );
246 if ( $from ===
'' ) {
247 $from =
$parser->getTitle()->getPrefixedText();
250 $to = rtrim( $to,
' /' );
253 if ( $to ===
'' || $to ===
'.' ) {
258 if ( substr( $to, 0, 1 ) !==
'/' &&
259 substr( $to, 0, 2 ) !==
'./' &&
260 substr( $to, 0, 3 ) !==
'../' &&
266 $fullPath =
'/' . $from .
'/' . $to .
'/';
269 $fullPath = preg_replace(
'!/(\./)+!',
'/', $fullPath );
272 $fullPath = preg_replace(
'!/{2,}!',
'/', $fullPath );
275 $fullPath = trim( $fullPath,
'/' );
276 $exploded = explode(
'/', $fullPath );
279 foreach ( $exploded as $current ) {
280 if ( $current ===
'..' ) {
281 if ( !count( $newExploded ) ) {
283 $msg =
wfMessage(
'pfunc_rel2abs_invalid_depth', $fullPath )
284 ->inContentLanguage()->escaped();
285 return '<strong class="error">' . $msg .
'</strong>';
288 array_pop( $newExploded );
291 $newExploded[] = $current;
296 return implode(
'/', $newExploded );
309 $parser, $frame, $titletext =
'', $then =
'', $else =
''
312 $title = Title::newFromText( $titletext );
313 $wgContLang->findVariantLink( $titletext, $title,
true );
315 if ( $title->getNamespace() ===
NS_MEDIA ) {
319 if ( !
$parser->incrementExpensiveFunctionCount() ) {
327 $file->getName(), $file->getTimestamp(), $file->getSha1() );
328 return $file->exists() ? $then : $else;
329 } elseif ( $title->getNamespace() ===
NS_SPECIAL ) {
335 } elseif ( $title->isExternal() ) {
342 $pdbk = $title->getPrefixedDBkey();
343 $lc = LinkCache::singleton();
344 $id = $lc->getGoodLinkID( $pdbk );
346 $parser->mOutput->addLink( $title, $id );
348 } elseif ( $lc->isBadLink( $pdbk ) ) {
349 $parser->mOutput->addLink( $title, 0 );
352 if ( !
$parser->incrementExpensiveFunctionCount() ) {
355 $id = $title->getArticleID();
356 $parser->mOutput->addLink( $title, $id );
359 if ( $title->exists() ) {
374 $title = isset(
$args[0] ) ? trim( $frame->expand(
$args[0] ) ) :
'';
379 if ( $result ===
null ) {
382 return trim( $frame->expand( $result ) );
396 $parser, $frame =
null, $format =
'', $date =
'', $language =
'', $local =
false
400 if ( $date ===
'' ) {
401 $cacheKey =
$parser->getOptions()->getTimestamp();
403 $date = $timestamp->getTimestamp( TS_ISO_8601 );
409 if ( isset( self::$mTimeCache[$format][$cacheKey][$language][$local] ) ) {
410 $cachedVal = self::$mTimeCache[$format][$cacheKey][$language][$local];
412 && $cachedVal[1] !==
null && $frame && is_callable( [ $frame,
'setTTL' ] )
414 $frame->setTTL( $cachedVal[1] );
416 return $cachedVal[0];
419 # compute the timestamp string $ts
420 # PHP >= 5.2 can handle dates before 1970 or after 2038 using the DateTime object
422 $invalidTime =
false;
424 # the DateTime constructor must be used because it throws exceptions
425 # when errors occur, whereas date_create appears to just output a warning
426 # that can't really be detected from within the code
429 # Default input timezone is UTC.
430 $utc =
new DateTimeZone(
'UTC' );
432 # Correct for DateTime interpreting 'XXXX' as XX:XX o'clock
433 if ( preg_match(
'/^[0-9]{4}$/', $date ) ) {
434 $date =
'00:00 '.$date;
438 # UTC is a default input timezone.
439 $dateObject =
new DateTime( $date, $utc );
441 # Set output timezone.
446 $tz =
new DateTimeZone( date_default_timezone_get() );
451 $dateObject->setTimezone( $tz );
453 $ts = $dateObject->format(
'YmdHis' );
455 }
catch ( Exception $ex ) {
460 # format the timestamp and return the result
461 if ( $invalidTime ) {
462 $result =
'<strong class="error">' .
463 wfMessage(
'pfunc_time_error' )->inContentLanguage()->escaped() .
466 self::$mTimeChars += strlen( $format );
467 if ( self::$mTimeChars > self::$mMaxTimeChars ) {
468 return '<strong class="error">' .
469 wfMessage(
'pfunc_time_too_long' )->inContentLanguage()->escaped() .
473 return '<strong class="error">' .
474 wfMessage(
'pfunc_time_too_small' )->inContentLanguage()->escaped() .
476 } elseif ( $ts < 100000000000000 ) {
477 if ( $language !==
'' && Language::isValidBuiltInCode( $language ) ) {
479 $langObject = Language::factory( $language );
482 $langObject =
$parser->getFunctionLang();
486 $result = $langObject->sprintfDate( $format, $ts, $tz, $ttl );
488 return '<strong class="error">' .
489 wfMessage(
'pfunc_time_too_big' )->inContentLanguage()->escaped() .
494 self::$mTimeCache[$format][$cacheKey][$language][$local] = [
$result, $ttl ];
495 if ( $useTTL && $ttl !==
null && $frame && is_callable( [ $frame,
'setTTL' ] ) ) {
496 $frame->setTTL( $ttl );
510 $parser, $format =
'', $date =
'', $language =
'', $local =
false
522 $format = isset(
$args[0] ) ? trim( $frame->expand(
$args[0] ) ) :
'';
523 $date = isset(
$args[1] ) ? trim( $frame->expand(
$args[1] ) ) :
'';
524 $language = isset(
$args[2] ) ? trim( $frame->expand(
$args[2] ) ) :
'';
525 $local = isset(
$args[3] ) && trim( $frame->expand(
$args[3] ) );
547 $format = isset(
$args[0] ) ? trim( $frame->expand(
$args[0] ) ) :
'';
548 $date = isset(
$args[1] ) ? trim( $frame->expand(
$args[1] ) ) :
'';
549 $language = isset(
$args[2] ) ? trim( $frame->expand(
$args[2] ) ) :
'';
564 $parts = (int)$parts;
565 $offset = (int)$offset;
566 $ntitle = Title::newFromText( $title );
567 if ( $ntitle instanceof
Title ) {
568 $bits = explode(
'/', $ntitle->getPrefixedText(), 25 );
569 if ( count( $bits ) <= 0 ) {
570 return $ntitle->getPrefixedText();
575 if ( $parts === 0 ) {
576 return implode(
'/', array_slice( $bits, $offset ) );
578 return implode(
'/', array_slice( $bits, $offset, $parts ) );
592 global $wgPFStringLengthLimit;
593 return ( mb_strlen( $text ) < $wgPFStringLengthLimit );
601 global $wgPFStringLengthLimit;
602 $msg =
wfMessage(
'pfunc_string_too_long' )->numParams( $wgPFStringLengthLimit );
603 return '<strong class="error">' . $msg->inContentLanguage()->escaped() .
'</strong>';
615 $inStr =
$parser->killMarkers( (
string)$inStr );
616 return mb_strlen( $inStr );
632 public static function runPos(
$parser, $inStr =
'', $inNeedle =
'', $inOffset = 0 ) {
633 $inStr =
$parser->killMarkers( (
string)$inStr );
634 $inNeedle =
$parser->killMarkers( (
string)$inNeedle );
636 if ( !self::checkLength( $inStr ) ||
637 !self::checkLength( $inNeedle ) ) {
641 if ( $inNeedle ===
'' ) {
645 $pos = mb_strpos( $inStr, $inNeedle, (
int)$inOffset );
646 if ( $pos ===
false ) {
666 $inStr =
$parser->killMarkers( (
string)$inStr );
667 $inNeedle =
$parser->killMarkers( (
string)$inNeedle );
669 if ( !self::checkLength( $inStr ) ||
670 !self::checkLength( $inNeedle ) ) {
674 if ( $inNeedle ===
'' ) {
678 $pos = mb_strrpos( $inStr, $inNeedle );
679 if ( $pos ===
false ) {
704 public static function runSub(
$parser, $inStr =
'', $inStart = 0, $inLength = 0 ) {
705 $inStr =
$parser->killMarkers( (
string)$inStr );
707 if ( !self::checkLength( $inStr ) ) {
711 if ( (
int)$inLength === 0 ) {
712 $result = mb_substr( $inStr, (
int)$inStart );
714 $result = mb_substr( $inStr, (
int)$inStart, (
int)$inLength );
732 $inStr =
$parser->killMarkers( (
string)$inStr );
733 $inSubStr =
$parser->killMarkers( (
string)$inSubStr );
735 if ( !self::checkLength( $inStr ) ||
736 !self::checkLength( $inSubStr ) ) {
740 if ( $inSubStr ===
'' ) {
744 $result = mb_substr_count( $inStr, $inSubStr );
765 $inReplaceFrom =
'', $inReplaceTo =
'', $inLimit = -1 ) {
766 global $wgPFStringLengthLimit;
768 $inStr =
$parser->killMarkers( (
string)$inStr );
769 $inReplaceFrom =
$parser->killMarkers( (
string)$inReplaceFrom );
770 $inReplaceTo =
$parser->killMarkers( (
string)$inReplaceTo );
772 if ( !self::checkLength( $inStr ) ||
773 !self::checkLength( $inReplaceFrom ) ||
774 !self::checkLength( $inReplaceTo ) ) {
778 if ( $inReplaceFrom ===
'' ) {
779 $inReplaceFrom =
' ';
783 $diff = mb_strlen( $inReplaceTo ) - mb_strlen( $inReplaceFrom );
785 $limit = ( ( $wgPFStringLengthLimit - mb_strlen( $inStr ) ) / $diff ) + 1;
790 $inLimit = (int)$inLimit;
791 if ( $inLimit >= 0 ) {
792 if ( $limit > $inLimit || $limit == -1 ) {
798 $inReplaceFrom = preg_quote( $inReplaceFrom,
'/' );
801 $result = preg_replace(
'/' . $inReplaceFrom .
'/u',
802 $inReplaceTo, $inStr, $limit );
804 if ( !self::checkLength( $result ) ) {
828 $parser, $inStr =
'', $inDiv =
'', $inPos = 0, $inLim =
null
830 $inStr =
$parser->killMarkers( (
string)$inStr );
831 $inDiv =
$parser->killMarkers( (
string)$inDiv );
833 if ( $inDiv ===
'' ) {
837 if ( !self::checkLength( $inStr ) ||
838 !self::checkLength( $inDiv ) ) {
842 $inDiv = preg_quote( $inDiv,
'/' );
844 $matches = preg_split(
'/' . $inDiv .
'/u', $inStr, $inLim );
846 if ( $inPos >= 0 && isset(
$matches[$inPos] ) ) {
866 $inStr =
$parser->killMarkers( (
string)$inStr );
867 if ( !self::checkLength( $inStr ) ) {
871 return urldecode( $inStr );
887 $expanded = $frame->expand( $obj );
888 $trimExpanded = trim( $expanded );
889 return trim( Sanitizer::decodeCharReferences( $expanded ) );
$wgLocaltimezone
Fake out the timezone that the server thinks it's in.
wfFindFile( $title, $options=[])
Find a file.
static ifeqObj( $parser, $frame, $args)
static runUrlDecode( $parser, $inStr='')
{{#urldecode:string}}
static runRPos( $parser, $inStr='', $inNeedle='')
{{#rpos: string | needle}}
static checkLength( $text)
Verifies parameter is less than max string length.
static ifexistCommon( $parser, $frame, $titletext='', $then='', $else='')
static iferrorObj( $parser, $frame, $args)
static expr( $parser, $expr='')
static titleparts( $parser, $title='', $parts=0, $offset=0)
Obtain a specified number of slash-separated parts of a title, e.g.
static ifObj( $parser, $frame, $args)
static runReplace( $parser, $inStr='', $inReplaceFrom='', $inReplaceTo='', $inLimit=-1)
{{replace:string | from | to | limit }}
static switchObj( $parser, $frame, $args)
static runPos( $parser, $inStr='', $inNeedle='', $inOffset=0)
{{#pos: string | needle | offset}}
static tooLongError()
Generates error message.
static runSub( $parser, $inStr='', $inStart=0, $inLength=0)
{{#sub: string | start | length }}
static localTime( $parser, $format='', $date='', $language='')
static rel2abs( $parser, $to='', $from='')
Returns the absolute path to a subpage, relative to the current article title.
static time( $parser, $format='', $date='', $language='', $local=false)
static runLen( $parser, $inStr='')
{{#len:string}}
static runExplode( $parser, $inStr='', $inDiv='', $inPos=0, $inLim=null)
{{#explode:string | delimiter | position | limit}}
static registerClearHook()
Register ParserClearState hook.
static decodeTrimExpand( $obj, $frame, &$trimExpanded=null)
Take a PPNode (-ish thing), expand it, remove entities, and trim.
static timeObj( $parser, $frame, $args)
static runCount( $parser, $inStr='', $inSubStr='')
{{#count: string | substr }}
static ifexpr( $parser, $expr='', $then='', $else='')
static localTimeObj( $parser, $frame, $args)
static iferror( $parser, $test='', $then='', $else=false)
static clearState( $parser)
static ifexistObj( $parser, $frame, $args)
static ifexprObj( $parser, $frame, $args)
static timeCommon( $parser, $frame=null, $format='', $date='', $language='', $local=false)
Library for creating and parsing MW-style timestamps.
static & get( $id)
Factory: creates an object representing an ID.
static exists( $name)
Check if a given name exist as a special page or as a special page alias.
static escapeRegexReplacement( $string)
Escape a string to make it suitable for inclusion in a preg_replace() replacement parameter.
static unstub(&$obj)
Unstubs an object, if it is a stub object.
Represents a title within MediaWiki.
this class mediates it Skin Encapsulates a look and feel for the wiki All of the functions that render HTML and make choices about how to render it are here and are called from various other places when and is meant to be subclassed with other skins that may override some of its functions The User object contains a reference to a and so rather than having a global skin object we just rely on the global User and get the skin with $wgUser and also has some character encoding functions and other locale stuff The current user interface language is instantiated as and the local content language as $wgContLang
namespace being checked & $result
do that in ParserLimitReportFormat instead $parser
namespace and then decline to actually register it file or subcat img or subcat $title
either a unescaped string or a HtmlArmor object after in associative array form externallinks including delete and has completed for all link tables whether this was an auto creation default is conds Array Extra conditions for the No matching items in log is displayed if loglist is empty msgKey Array If you want a nice box with a set this to the key of the message First element is the message additional optional elements are parameters for the key that are processed with wfMessage() -> params() ->parseAsBlock() - offset Set to overwrite offset parameter in $wgRequest set to '' to unset offset - wrap String Wrap the message in html(usually something like "<div ...>$1</div>"). - flags Integer display flags(NO_ACTION_LINK, NO_EXTRA_USER_LINKS) 'LogException':Called before an exception(or PHP error) is logged. This is meant for integration with external error aggregation services
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses & $ret
$wgHooks['ArticleShow'][]
returning false will NOT prevent logging $e