const TOC_START = '<mw:toc>';
const TOC_END = '</mw:toc>';
+ /** @var int Assume that no output will later be saved this many seconds after parsing */
+ const MAX_TTS = 900;
+
# Persistent:
public $mTagHooks = [];
public $mTransparentTagHooks = [];
// Add on template profiling data in human/machine readable way
$dataByFunc = $this->mProfiler->getFunctionStats();
uasort( $dataByFunc, function ( $a, $b ) {
- return $a['real'] < $b['real']; // descending order
+ return $b['real'] <=> $a['real']; // descending order
} );
$profileReport = [];
foreach ( array_slice( $dataByFunc, 0, 10 ) as $item ) {
}
break;
case 'revisionday':
- # Let the edit saving system know we should parse the page
- # *after* a revision ID has been assigned. This is for null edits.
- $this->mOutput->setFlag( 'vary-revision' );
- wfDebug( __METHOD__ . ": {{REVISIONDAY}} used, setting vary-revision...\n" );
- $value = intval( substr( $this->getRevisionTimestamp(), 6, 2 ) );
+ $value = (int)$this->getRevisionTimestampSubstring( 6, 2, self::MAX_TTS, $index );
break;
case 'revisionday2':
- # Let the edit saving system know we should parse the page
- # *after* a revision ID has been assigned. This is for null edits.
- $this->mOutput->setFlag( 'vary-revision' );
- wfDebug( __METHOD__ . ": {{REVISIONDAY2}} used, setting vary-revision...\n" );
- $value = substr( $this->getRevisionTimestamp(), 6, 2 );
+ $value = $this->getRevisionTimestampSubstring( 6, 2, self::MAX_TTS, $index );
break;
case 'revisionmonth':
- # Let the edit saving system know we should parse the page
- # *after* a revision ID has been assigned. This is for null edits.
- $this->mOutput->setFlag( 'vary-revision' );
- wfDebug( __METHOD__ . ": {{REVISIONMONTH}} used, setting vary-revision...\n" );
- $value = substr( $this->getRevisionTimestamp(), 4, 2 );
+ $value = $this->getRevisionTimestampSubstring( 4, 2, self::MAX_TTS, $index );
break;
case 'revisionmonth1':
- # Let the edit saving system know we should parse the page
- # *after* a revision ID has been assigned. This is for null edits.
- $this->mOutput->setFlag( 'vary-revision' );
- wfDebug( __METHOD__ . ": {{REVISIONMONTH1}} used, setting vary-revision...\n" );
- $value = intval( substr( $this->getRevisionTimestamp(), 4, 2 ) );
+ $value = (int)$this->getRevisionTimestampSubstring( 4, 2, self::MAX_TTS, $index );
break;
case 'revisionyear':
- # Let the edit saving system know we should parse the page
- # *after* a revision ID has been assigned. This is for null edits.
- $this->mOutput->setFlag( 'vary-revision' );
- wfDebug( __METHOD__ . ": {{REVISIONYEAR}} used, setting vary-revision...\n" );
- $value = substr( $this->getRevisionTimestamp(), 0, 4 );
+ $value = $this->getRevisionTimestampSubstring( 0, 4, self::MAX_TTS, $index );
break;
case 'revisiontimestamp':
# Let the edit saving system know we should parse the page
return $value;
}
+ /**
+ * @param int $start
+ * @param int $len
+ * @param int $mtts Max time-till-save; sets vary-revision if result might change by then
+ * @param string $variable Parser variable name
+ * @return string
+ */
+ private function getRevisionTimestampSubstring( $start, $len, $mtts, $variable ) {
+ global $wgContLang;
+
+ # Get the timezone-adjusted timestamp to be used for this revision
+ $resNow = substr( $this->getRevisionTimestamp(), $start, $len );
+ # Possibly set vary-revision if there is not yet an associated revision
+ if ( !$this->getRevisionObject() ) {
+ # Get the timezone-adjusted timestamp $mtts seconds in the future
+ $resThen = substr(
+ $wgContLang->userAdjust( wfTimestamp( TS_MW, time() + $mtts ), '' ),
+ $start,
+ $len
+ );
+
+ if ( $resNow !== $resThen ) {
+ # Let the edit saving system know we should parse the page
+ # *after* a revision ID has been assigned. This is for null edits.
+ $this->mOutput->setFlag( 'vary-revision' );
+ wfDebug( __METHOD__ . ": $variable used, setting vary-revision...\n" );
+ }
+ }
+
+ return $resNow;
+ }
+
/**
* initialise the magic variables (like CURRENTMONTHNAME) and substitution modifiers
*
* 'expansion-depth-exceeded-category')
* @param string|int|null $current Current value
* @param string|int|null $max Maximum allowed, when an explicit limit has been
- * exceeded, provide the values (optional)
+ * exceeded, provide the values (optional)
*/
public function limitationWarn( $limitationType, $current = '', $max = '' ) {
# does no harm if $current and $max are present but are unnecessary for the message
for ( $i = 0; $i < $argsLength; $i++ ) {
$funcArgs[] = $args->item( $i );
}
- try {
- $result = $this->callParserFunction( $frame, $func, $funcArgs );
- } catch ( Exception $ex ) {
- throw $ex;
- }
+
+ $result = $this->callParserFunction( $frame, $func, $funcArgs );
// Extract any forwarded flags
if ( isset( $result['title'] ) ) {
if ( is_string( $stuff['text'] ) ) {
$text = strtr( $text, "\x7f", "?" );
}
- $finalTitle = isset( $stuff['finalTitle'] ) ? $stuff['finalTitle'] : $title;
+ $finalTitle = $stuff['finalTitle'] ?? $title;
if ( isset( $stuff['deps'] ) ) {
foreach ( $stuff['deps'] as $dep ) {
$this->mOutput->addTemplate( $dep['title'], $dep['page_id'], $dep['rev_id'] );
* @param Title $title
* @param array $options Array of options to RepoGroup::findFile
* @return File|bool
+ * @deprecated since 1.32, use fetchFileAndTitle instead
*/
public function fetchFile( $title, $options = [] ) {
+ wfDeprecated( __METHOD__, '1.32' );
return $this->fetchFileAndTitle( $title, $options )[0];
}
if ( preg_match( '/[<>\r\n]/', $tag, $m ) ) {
throw new MWException( "Invalid character {$m[0]} in setHook('$tag', ...) call" );
}
- $oldVal = isset( $this->mTagHooks[$tag] ) ? $this->mTagHooks[$tag] : null;
+ $oldVal = $this->mTagHooks[$tag] ?? null;
$this->mTagHooks[$tag] = $callback;
if ( !in_array( $tag, $this->mStripList ) ) {
$this->mStripList[] = $tag;
if ( preg_match( '/[<>\r\n]/', $tag, $m ) ) {
throw new MWException( "Invalid character {$m[0]} in setTransparentHook('$tag', ...) call" );
}
- $oldVal = isset( $this->mTransparentTagHooks[$tag] ) ? $this->mTransparentTagHooks[$tag] : null;
+ $oldVal = $this->mTransparentTagHooks[$tag] ?? null;
$this->mTransparentTagHooks[$tag] = $callback;
return $oldVal;
if ( preg_match( '/[<>\r\n]/', $tag, $m ) ) {
throw new MWException( "Invalid character {$m[0]} in setFunctionTagHook('$tag', ...) call" );
}
- $old = isset( $this->mFunctionTagHooks[$tag] ) ?
- $this->mFunctionTagHooks[$tag] : null;
+ $old = $this->mFunctionTagHooks[$tag] ?? null;
$this->mFunctionTagHooks[$tag] = [ $callback, $flags ];
if ( !in_array( $tag, $this->mStripList ) ) {
} else {
// Guess not, consider it as caption.
wfDebug( "$parameterMatch failed parameter validation\n" );
- $label = '|' . $parameterMatch;
+ $label = $parameterMatch;
}
}
} else {
// Last pipe wins.
- $label = '|' . $parameterMatch;
+ $label = $parameterMatch;
}
}
- // Remove the pipe.
- $label = substr( $label, 1 );
}
$ig->add( $title, $label, $alt, $link, $handlerOptions );
Hooks::run( 'ParserMakeImageParams', [ $title, $file, &$params, $this ] );
# Linker does the rest
- $time = isset( $options['time'] ) ? $options['time'] : false;
+ $time = $options['time'] ?? false;
$ret = Linker::makeImageLink( $this, $title, $file, $params['frame'], $params['handler'],
$time, $descQuery, $this->mOptions->getThumbSize() );