use MediaWiki\Linker\LinkTarget;
use MediaWiki\MediaWikiServices;
use MediaWiki\Special\SpecialPageFactory;
+use Psr\Log\NullLogger;
use Wikimedia\ScopedCallback;
+use Psr\Log\LoggerInterface;
/**
* @defgroup Parser Parser
/** @var NamespaceInfo */
private $nsInfo;
+ /** @var LoggerInterface */
+ private $logger;
+
/**
* TODO Make this a const when HHVM support is dropped (T192166)
*
* @param SpecialPageFactory|null $spFactory
* @param LinkRendererFactory|null $linkRendererFactory
* @param NamespaceInfo|null $nsInfo
+ * @param LoggerInterface|null $logger
*/
public function __construct(
- $svcOptions = null, MagicWordFactory $magicWordFactory = null,
- Language $contLang = null, ParserFactory $factory = null, $urlProtocols = null,
- SpecialPageFactory $spFactory = null, $linkRendererFactory = null, $nsInfo = null
+ $svcOptions = null,
+ MagicWordFactory $magicWordFactory = null,
+ Language $contLang = null,
+ ParserFactory $factory = null,
+ $urlProtocols = null,
+ SpecialPageFactory $spFactory = null,
+ $linkRendererFactory = null,
+ $nsInfo = null,
+ $logger = null
) {
$services = MediaWikiServices::getInstance();
if ( !$svcOptions || is_array( $svcOptions ) ) {
$this->specialPageFactory = $spFactory ?? $services->getSpecialPageFactory();
$this->linkRendererFactory = $linkRendererFactory ?? $services->getLinkRendererFactory();
$this->nsInfo = $nsInfo ?? $services->getNamespaceInfo();
+ $this->logger = $logger ?: new NullLogger();
}
/**
/**
* Accessor for the Title object
*
- * @return Title
+ * @return Title|null
*/
public function getTitle() {
return $this->mTitle;
$value = wfEscapeWikiText( $subjPage->getPrefixedURL() );
break;
case 'pageid': // requested in T25427
- $pageid = $this->getTitle()->getArticleID();
- if ( $pageid == 0 ) {
- # 0 means the page doesn't exist in the database,
- # which means the user is previewing a new page.
- # The vary-revision flag must be set, because the magic word
- # will have a different value once the page is saved.
- $this->mOutput->setFlag( 'vary-revision' );
- wfDebug( __METHOD__ . ": {{PAGEID}} used in a new page, setting vary-revision" );
+ # Inform the edit saving system that getting the canonical output
+ # after page insertion requires a parse that used that exact page ID
+ $this->setOutputFlag( 'vary-page-id', '{{PAGEID}} used' );
+ $value = $this->mTitle->getArticleID();
+ if ( !$value ) {
+ $value = $this->mOptions->getSpeculativePageId();
+ if ( $value ) {
+ $this->mOutput->setSpeculativePageIdUsed( $value );
+ }
}
- $value = $pageid ?: null;
break;
case 'revisionid':
if (
if ( $this->getRevisionId() || $this->mOptions->getSpeculativeRevId() ) {
$value = '-';
} else {
- $this->mOutput->setFlag( 'vary-revision-exists' );
- wfDebug( __METHOD__ . ": {{REVISIONID}} used, setting vary-revision-exists" );
+ $this->setOutputFlag( 'vary-revision-exists', '{{REVISIONID}} used' );
$value = '';
}
} else {
# Inform the edit saving system that getting the canonical output after
- # revision insertion requires another parse using the actual revision ID
- $this->mOutput->setFlag( 'vary-revision-id' );
- wfDebug( __METHOD__ . ": {{REVISIONID}} used, setting vary-revision-id" );
+ # revision insertion requires a parse that used that exact revision ID
+ $this->setOutputFlag( 'vary-revision-id', '{{REVISIONID}} used' );
$value = $this->getRevisionId();
if ( $value === 0 ) {
$rev = $this->getRevisionObject();
case 'revisionuser':
# Inform the edit saving system that getting the canonical output after
# revision insertion requires a parse that used the actual user ID
- $this->mOutput->setFlag( 'vary-user' );
- wfDebug( __METHOD__ . ": {{REVISIONUSER}} used, setting vary-user" );
+ $this->setOutputFlag( 'vary-user', '{{REVISIONUSER}} used' );
$value = $this->getRevisionUser();
break;
case 'revisionsize':
if ( $resNow !== $resThen ) {
# Inform the edit saving system that getting the canonical output after
# revision insertion requires a parse that used an actual revision timestamp
- $this->mOutput->setFlag( 'vary-revision-timestamp' );
- wfDebug( __METHOD__ . ": $variable used, setting vary-revision-timestamp" );
+ $this->setOutputFlag( 'vary-revision-timestamp', "$variable used" );
}
}
if ( $frame === false ) {
$frame = $this->getPreprocessor()->newFrame();
} elseif ( !( $frame instanceof PPFrame ) ) {
- wfDebug( __METHOD__ . " called using plain parameters instead of "
- . "a PPFrame instance. Creating custom frame.\n" );
+ $this->logger->debug(
+ __METHOD__ . " called using plain parameters instead of " .
+ "a PPFrame instance. Creating custom frame."
+ );
$frame = $this->getPreprocessor()->newCustomFrame( $frame );
}
}
} elseif ( $this->nsInfo->isNonincludable( $title->getNamespace() ) ) {
$found = false; # access denied
- wfDebug( __METHOD__ . ": template inclusion denied for " .
- $title->getPrefixedDBkey() . "\n" );
+ $this->logger->debug(
+ __METHOD__ .
+ ": template inclusion denied for " . $title->getPrefixedDBkey()
+ );
} else {
list( $text, $title ) = $this->getTemplateDom( $title );
if ( $text !== false ) {
$this->addTrackingCategory( 'template-loop-category' );
$this->mOutput->addWarning( wfMessage( 'template-loop-warning',
wfEscapeWikiText( $titleText ) )->text() );
- wfDebug( __METHOD__ . ": template loop broken at '$titleText'\n" );
+ $this->logger->debug( __METHOD__ . ": template loop broken at '$titleText'" );
}
}
return $this->currentRevisionCache->get( $cacheKey );
}
+ /**
+ * @param Title $title
+ * @return bool
+ * @since 1.34
+ */
+ public function isCurrentRevisionOfTitleCached( $title ) {
+ return (
+ $this->currentRevisionCache &&
+ $this->currentRevisionCache->has( $title->getPrefixedText() )
+ );
+ }
+
/**
* Wrapper around Revision::newFromTitle to allow passing additional parameters
* without passing them on to it.
foreach ( $stuff['deps'] as $dep ) {
$this->mOutput->addTemplate( $dep['title'], $dep['page_id'], $dep['rev_id'] );
if ( $dep['title']->equals( $this->getTitle() ) ) {
- // If we transclude ourselves, the final result
- // will change based on the new version of the page
- $this->mOutput->setFlag( 'vary-revision' );
- wfDebug( __METHOD__ . ": self transclusion, setting vary-revision" );
+ // Self-transclusion; final result may change based on the new page version
+ $this->setOutputFlag( 'vary-revision', 'Self transclusion' );
}
}
}
'~~~' => $sigText
] );
# The main two signature forms used above are time-sensitive
- $this->mOutput->setFlag( 'user-signature' );
+ $this->setOutputFlag( 'user-signature', 'User signature detected' );
}
# Context links ("pipe tricks"): [[|name]] and [[name (context)|]]
if ( mb_strlen( $nickname ) > $this->svcOptions->get( 'MaxSigChars' ) ) {
$nickname = $username;
- wfDebug( __METHOD__ . ": $username has overlong signature.\n" );
+ $this->logger->debug( __METHOD__ . ": $username has overlong signature." );
} elseif ( $fancySig !== false ) {
# Sig. might contain markup; validate this
if ( $this->validateSig( $nickname ) !== false ) {
} else {
# Failed to validate; fall back to the default
$nickname = $username;
- wfDebug( __METHOD__ . ": $username has bad XML tags in signature.\n" );
+ $this->logger->debug( __METHOD__ . ": $username has bad XML tags in signature." );
}
}
$handlerOptions[$paramName] = $match;
} else {
// Guess not, consider it as caption.
- wfDebug( "$parameterMatch failed parameter validation\n" );
+ $this->logger->debug(
+ "$parameterMatch failed parameter validation" );
$label = $parameterMatch;
}
}
* @deprecated since 1.28; use getOutput()->updateCacheExpiry()
*/
public function disableCache() {
- wfDebug( "Parser output marked as uncacheable.\n" );
+ $this->logger->debug( "Parser output marked as uncacheable." );
if ( !$this->mOutput ) {
throw new MWException( __METHOD__ .
" can only be called when actually parsing something" );
* @since 1.23 (public since 1.23)
*/
public function getRevisionObject() {
- if ( !is_null( $this->mRevisionObject ) ) {
+ if ( $this->mRevisionObject ) {
return $this->mRevisionObject;
}
// NOTE: try to get the RevisionObject even if mRevisionId is null.
- // This is useful when parsing revision that has not yet been saved.
+ // This is useful when parsing a revision that has not yet been saved.
// However, if we get back a saved revision even though we are in
// preview mode, we'll have to ignore it, see below.
// NOTE: This callback may be used to inject an OLD revision that was
// already loaded, so "current" is a bit of a misnomer. We can't just
// skip it if mRevisionId is set.
$rev = call_user_func(
- $this->mOptions->getCurrentRevisionCallback(), $this->getTitle(), $this
+ $this->mOptions->getCurrentRevisionCallback(),
+ $this->getTitle(),
+ $this
);
if ( $this->mRevisionId === null && $rev && $rev->getId() ) {
OutputPage::setupOOUI();
$this->mOutput->setEnableOOUI( true );
}
+
+ /**
+ * @param string $flag
+ * @param string $reason
+ */
+ protected function setOutputFlag( $flag, $reason ) {
+ $this->mOutput->setFlag( $flag );
+ $name = $this->mTitle->getPrefixedText();
+ $this->logger->debug( __METHOD__ . ": set $flag flag on '$name'; $reason" );
+ }
}