// the stash request finishes parsing. For the lock acquisition below, there is not much
// need to duplicate parsing of the same content/user/summary bundle, so try to avoid
// blocking at all here.
- $dbw = $this->lb->getConnection( DB_MASTER );
+ $dbw = $this->lb->getConnectionRef( DB_MASTER );
if ( !$dbw->lock( $key, $fname, 0 ) ) {
// De-duplicate requests on the same key
return self::ERROR_BUSY;
if ( $editInfo->output->getFlag( 'vary-revision' ) ) {
// This can be used for the initial parse, e.g. for filters or doEditContent(),
- // but a second parse will be triggered in doEditUpdates(). This is not optimal.
+ // but a second parse will be triggered in doEditUpdates() no matter what
$logger->info(
- "Cache for key '{key}' has vary_revision; post-insertion parse inevitable.",
- $context
- );
- } elseif ( $editInfo->output->getFlag( 'vary-revision-id' ) ) {
- // Similar to the above if we didn't guess the ID correctly.
- $logger->debug(
- "Cache for key '{key}' has vary_revision_id; post-insertion parse possible.",
- $context
- );
- } elseif ( $editInfo->output->getFlag( 'vary-revision-timestamp' ) ) {
- // Similar to the above if we didn't guess the timestamp correctly.
- $logger->debug(
- "Cache for key '{key}' has vary_revision_timestamp; post-insertion parse possible.",
+ "Cache for key '{key}' has 'vary-revision'; post-insertion parse inevitable.",
$context
);
+ } else {
+ static $flagsMaybeReparse = [
+ // Similar to the above if we didn't guess the ID correctly
+ 'vary-revision-id',
+ // Similar to the above if we didn't guess the timestamp correctly
+ 'vary-revision-timestamp',
+ // Similar to the above if we didn't guess the content correctly
+ 'vary-revision-sha1'
+ ];
+ foreach ( $flagsMaybeReparse as $flag ) {
+ if ( $editInfo->output->getFlag( $flag ) ) {
+ $logger->debug(
+ "Cache for key '{key}' has $flag; post-insertion parse possible.",
+ $context
+ );
+ }
+ }
}
return $editInfo;
* @return string|null TS_MW timestamp or null
*/
private function lastEditTime( User $user ) {
- $db = $this->lb->getConnection( DB_REPLICA );
+ $db = $this->lb->getConnectionRef( DB_REPLICA );
+
$actorQuery = ActorMigration::newMigration()->getWhere( $db, 'rc_user', $user, false );
$time = $db->selectField(
[ 'recentchanges' ] + $actorQuery['tables'],
public $mLinkID;
public $mIncludeSizes, $mPPNodeCount, $mGeneratedPPNodeCount, $mHighestExpansionDepth;
public $mDefaultSort;
- public $mTplRedirCache, $mTplDomCache, $mHeadings, $mDoubleUnderscores;
+ public $mTplRedirCache, $mHeadings, $mDoubleUnderscores;
public $mExpensiveFunctionCount; # number of expensive parser function calls
public $mShowToc, $mForceTocPosition;
+ /** @var array */
+ public $mTplDomCache;
/**
* @var User
* self::OT_HTML: all templates and extension tags
*
* @param string $text The text to transform
- * @param bool|PPFrame $frame Object describing the arguments passed to the
+ * @param false|PPFrame|array $frame Object describing the arguments passed to the
* template. Arguments may also be provided as an associative array, as
* was the usual case before MW1.12. Providing arguments this way may be
* useful for extensions wishing to perform variable replacement
* $piece['lineStart']: whether the brace was at the start of a line
* @param PPFrame $frame The current frame, contains template arguments
* @throws Exception
- * @return string The text of the template
+ * @return string|array The text of the template
*/
public function braceSubstitution( $piece, $frame ) {
// Flags
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
+ // Self-transclusion; final result may change based on the new page version
$this->mOutput->setFlag( 'vary-revision' );
wfDebug( __METHOD__ . ": self transclusion, setting vary-revision" );
}
* @file
* @ingroup Testing
*/
+
use Wikimedia\Rdbms\IDatabase;
use MediaWiki\MediaWikiServices;
use MediaWiki\Tidy\TidyDriverBase;
*/
private $keepUploads;
+ /** @var Title */
+ private $defaultTitle;
+
/**
* @param TestRecorder $recorder
* @param array $options
if ( isset( $options['upload-dir'] ) ) {
$this->uploadDir = $options['upload-dir'];
}
+
+ $this->defaultTitle = Title::newFromText( 'Parser test' );
}
/**
$setup['wgNoFollowDomainExceptions'] = [ 'no-nofollow.org' ];
$setup['wgExternalLinkTarget'] = false;
$setup['wgLocaltimezone'] = 'UTC';
- $setup['wgHtml5'] = true;
$setup['wgDisableLangConversion'] = false;
$setup['wgDisableTitleConversion'] = false;
$options->setTidy( true );
}
- if ( isset( $opts['title'] ) ) {
- $titleText = $opts['title'];
- } else {
- $titleText = 'Parser test';
+ $revId = 1337; // see Parser::getRevisionId()
+ $title = isset( $opts['title'] )
+ ? Title::newFromText( $opts['title'] )
+ : $this->defaultTitle;
+
+ if ( isset( $opts['lastsavedrevision'] ) ) {
+ $content = new WikitextContent( $test['input'] );
+ $title = Title::newFromRow( (object)[
+ 'page_id' => 187,
+ 'page_len' => $content->getSize(),
+ 'page_latest' => 1337,
+ 'page_namespace' => $title->getNamespace(),
+ 'page_title' => $title->getDBkey(),
+ 'page_is_redirect' => 0
+ ] );
+ $rev = new Revision(
+ [
+ 'id' => $title->getLatestRevID(),
+ 'page' => $title->getArticleID(),
+ 'user' => $user,
+ 'content' => $content,
+ 'timestamp' => $this->getFakeTimestamp(),
+ 'title' => $title
+ ],
+ Revision::READ_LATEST,
+ $title
+ );
+ $oldCallback = $options->getCurrentRevisionCallback();
+ $options->setCurrentRevisionCallback(
+ function ( Title $t, $parser ) use ( $title, $rev, $oldCallback ) {
+ if ( $t->equals( $title ) ) {
+ return $rev;
+ } else {
+ return call_user_func( $oldCallback, $t, $parser );
+ }
+ }
+ );
}
if ( isset( $opts['maxincludesize'] ) ) {
$local = isset( $opts['local'] );
$preprocessor = $opts['preprocessor'] ?? null;
$parser = $this->getParser( $preprocessor );
- $title = Title::newFromText( $titleText );
if ( isset( $opts['styletag'] ) ) {
// For testing the behavior of <style> (including those deduplicated
} elseif ( isset( $opts['preload'] ) ) {
$out = $parser->getPreloadText( $test['input'], $title, $options );
} else {
- $output = $parser->parse( $test['input'], $title, $options, true, true, 1337 );
+ $output = $parser->parse( $test['input'], $title, $options, true, true, $revId );
$out = $output->getText( [
'allowTOC' => !isset( $opts['notoc'] ),
'unwrap' => !isset( $opts['wrap'] ),
// Wipe WANObjectCache process cache, which is invalidated by article insertion
// due to T144706
- ObjectCache::getMainWANInstance()->clearProcessCache();
+ MediaWikiServices::getInstance()->getMainWANObjectCache()->clearProcessCache();
$this->executeSetupSnippets( $teardown );
}