use MediaWiki\Revision\RevisionRenderer;
use MediaWiki\Revision\RevisionSlots;
use MediaWiki\Revision\RevisionStore;
+use MediaWiki\Revision\SlotRoleRegistry;
use MediaWiki\Revision\SlotRecord;
use MediaWiki\User\UserIdentity;
use MessageCache;
*/
private $options = [
'changed' => true,
+ // newrev is true if prepareUpdate is handling the creation of a new revision,
+ // as opposed to a null edit or a forced update.
+ 'newrev' => false,
'created' => false,
'moved' => false,
'restored' => false,
*/
private $revisionRenderer;
+ /** @var SlotRoleRegistry */
+ private $slotRoleRegistry;
+
/**
* A stage identifier for managing the life cycle of this instance.
* Possible stages are 'new', 'knows-current', 'has-content', 'has-revision', and 'done'.
* @param WikiPage $wikiPage ,
* @param RevisionStore $revisionStore
* @param RevisionRenderer $revisionRenderer
+ * @param SlotRoleRegistry $slotRoleRegistry
* @param ParserCache $parserCache
* @param JobQueueGroup $jobQueueGroup
* @param MessageCache $messageCache
WikiPage $wikiPage,
RevisionStore $revisionStore,
RevisionRenderer $revisionRenderer,
+ SlotRoleRegistry $slotRoleRegistry,
ParserCache $parserCache,
JobQueueGroup $jobQueueGroup,
MessageCache $messageCache,
$this->parserCache = $parserCache;
$this->revisionStore = $revisionStore;
$this->revisionRenderer = $revisionRenderer;
+ $this->slotRoleRegistry = $slotRoleRegistry;
$this->jobQueueGroup = $jobQueueGroup;
$this->messageCache = $messageCache;
$this->contLang = $contLang;
$hasLinks = null;
if ( $this->articleCountMethod === 'link' ) {
+ // NOTE: it would be more appropriate to determine for each slot separately
+ // whether it has links, and use that information with that slot's
+ // isCountable() method. However, that would break parity with
+ // WikiPage::isCountable, which uses the pagelinks table to determine
+ // whether the current revision has links.
$hasLinks = (bool)count( $this->getCanonicalParserOutput()->getLinks() );
}
- // TODO: MCR: ask all slots if they have links [SlotHandler/PageTypeHandler]
- $mainContent = $this->getRawContent( SlotRecord::MAIN );
- return $mainContent->isCountable( $hasLinks );
+ foreach ( $this->getModifiedSlotRoles() as $role ) {
+ $roleHandler = $this->slotRoleRegistry->getRoleHandler( $role );
+ if ( $roleHandler->supportsArticleCount() ) {
+ $content = $this->getRawContent( $role );
+
+ if ( $content->isCountable( $hasLinks ) ) {
+ return true;
+ }
+ }
+ }
+
+ return false;
}
/**
*/
public function isRedirect() {
// NOTE: main slot determines redirect status
+ // TODO: MCR: this should be controlled by a PageTypeHandler
$mainContent = $this->getRawContent( SlotRecord::MAIN );
return $mainContent->isRedirect();
$stashedEdit = ApiStashEdit::checkCache( $title, $mainContent, $legacyUser );
}
- if ( $stashedEdit ) {
- /** @var ParserOutput $output */
- $output = $stashedEdit->output;
-
- // TODO: this should happen when stashing the ParserOutput, not now!
- $output->setCacheTime( $stashedEdit->timestamp );
-
- // TODO: MCR: allow output for all slots to be stashed.
- $this->canonicalParserOutput = $output;
- }
-
$userPopts = ParserOptions::newFromUserAndLang( $user, $this->contLang );
Hooks::run( 'ArticlePrepareTextForEdit', [ $wikiPage, $userPopts ] );
} else {
$this->parentRevision = $parentRevision;
}
+
+ $renderHints = [ 'use-master' => $this->useMaster(), 'audience' => RevisionRecord::RAW ];
+
+ if ( $stashedEdit ) {
+ /** @var ParserOutput $output */
+ $output = $stashedEdit->output;
+
+ // TODO: this should happen when stashing the ParserOutput, not now!
+ $output->setCacheTime( $stashedEdit->timestamp );
+
+ $renderHints['known-revision-output'] = $output;
+ }
+
+ // NOTE: we want a canonical rendering, so don't pass $this->user or ParserOptions
+ // NOTE: the revision is either new or current, so we can bypass audience checks.
+ $this->renderedRevision = $this->revisionRenderer->getRenderedRevision(
+ $this->revision,
+ null,
+ null,
+ $renderHints
+ );
}
/**
* @return RenderedRevision
*/
public function getRenderedRevision() {
- if ( !$this->renderedRevision ) {
- $this->assertPrepared( __METHOD__ );
-
- // NOTE: we want a canonical rendering, so don't pass $this->user or ParserOptions
- // NOTE: the revision is either new or current, so we can bypass audience checks.
- $this->renderedRevision = $this->revisionRenderer->getRenderedRevision(
- $this->revision,
- null,
- null,
- [ 'use-master' => $this->useMaster(), 'audience' => RevisionRecord::RAW ]
- );
- }
+ $this->assertPrepared( __METHOD__ );
return $this->renderedRevision;
}
// Override fields defined in $this->options with values from $options.
$this->options = array_intersect_key( $options, $this->options ) + $this->options;
- if ( isset( $this->pageState['oldId'] ) ) {
- $oldId = $this->pageState['oldId'];
+ if ( $this->revision ) {
+ $oldId = $this->pageState['oldId'] ?? 0;
+ $this->options['newrev'] = ( $revision->getId() !== $oldId );
} elseif ( isset( $this->options['oldrevision'] ) ) {
/** @var Revision|RevisionRecord $oldRev */
$oldRev = $this->options['oldrevision'];
$oldId = $oldRev->getId();
+ $this->options['newrev'] = ( $revision->getId() !== $oldId );
} else {
$oldId = $revision->getParentId();
}
// Prune any output that depends on the revision ID.
if ( $this->renderedRevision ) {
$this->renderedRevision->updateRevision( $revision );
+ } else {
+
+ // NOTE: we want a canonical rendering, so don't pass $this->user or ParserOptions
+ // NOTE: the revision is either new or current, so we can bypass audience checks.
+ $this->renderedRevision = $this->revisionRenderer->getRenderedRevision(
+ $this->revision,
+ null,
+ null,
+ [ 'use-master' => $this->useMaster(), 'audience' => RevisionRecord::RAW ]
+ );
+
+ // XXX: Since we presumably are dealing with the current revision,
+ // we could try to get the ParserOutput from the parser cache.
}
// TODO: optionally get ParserOutput from the ParserCache here.
// the recent change entry (also done via deferred updates) and carry over any
// bot/deletion/IP flags, ect.
$this->jobQueueGroup->lazyPush(
- new CategoryMembershipChangeJob(
+ CategoryMembershipChangeJob::newSpec(
$this->getTitle(),
- [
- 'pageId' => $this->getPageId(),
- 'revTimestamp' => $this->revision->getTimestamp(),
- ]
+ $this->revision->getTimestamp()
)
);
}
// Save it to the parser cache. Use the revision timestamp in the case of a
// freshly saved edit, as that matches page_touched and a mismatch would trigger an
// unnecessary reparse.
- $timestamp = $this->options['changed'] ? $this->revision->getTimestamp()
- : $output->getTimestamp();
+ $timestamp = $this->options['newrev'] ? $this->revision->getTimestamp()
+ : $output->getCacheTime();
$this->parserCache->save(
$output, $wikiPage, $this->getCanonicalParserOptions(),
$timestamp, $this->revision->getId()