mConds = $conds;
$this->articleID = $source->getId();
$dbr = $dbProvider->getReplicaDatabase();
$maxtimestamp = $dbr->newSelectQueryBuilder()
->select( 'MIN(rev_timestamp)' )
->from( 'revision' )
->where( [ 'rev_page' => $dest->getId() ] )
->caller( __METHOD__ )->fetchField();
$maxRevId = $dbr->newSelectQueryBuilder()
->select( "MIN(rev_id)" )
->from( 'revision' )
->where( [ 'rev_page' => $dest->getId() ] )
->where( [ 'rev_timestamp' => $maxtimestamp ] )
->caller( __METHOD__ )->fetchField();
$this->maxTimestamp = $maxtimestamp;
$this->maxRevId = $maxRevId;
$this->mergePointTimestamp = $mergePointTimestamp;
// Set database before parent constructor to avoid setting it there
$this->mDb = $dbr;
parent::__construct( $context, $linkRenderer );
$this->linkBatchFactory = $linkBatchFactory;
$this->revisionStore = $revisionStore;
$this->commentFormatter = $commentFormatter;
}
protected function doBatchLookups() {
# Do a link batch query
$this->mResult->seek( 0 );
$batch = $this->linkBatchFactory->newLinkBatch();
# Give some pointers to make (last) links
$this->prevId = [];
$rev_id = null;
foreach ( $this->mResult as $row ) {
$batch->add( NS_USER, $row->rev_user_text );
$batch->add( NS_USER_TALK, $row->rev_user_text );
if ( isset( $rev_id ) ) {
if ( $rev_id > $row->rev_id ) {
$this->prevId[$rev_id] = $row->rev_id;
} elseif ( $rev_id < $row->rev_id ) {
$this->prevId[$row->rev_id] = $rev_id;
}
}
$rev_id = $row->rev_id;
}
$batch->execute();
$this->mResult->seek( 0 );
}
/**
* @inheritDoc
*/
protected function getStartBody() {
return "\n";
}
/**
* @inheritDoc
*/
protected function getEndBody() {
return "\n";
}
public function formatRow( $row ) {
$revRecord = $this->revisionStore->newRevisionFromRow( $row );
$linkRenderer = $this->getLinkRenderer();
$stxt = '';
$last = $this->msg( 'last' )->escaped();
$ts = wfTimestamp( TS_MW, $row->rev_timestamp );
$tsWithId = $ts . "|" . $row->rev_id;
$checkBox = Xml::radio(
'mergepoint', $tsWithId,
$this->mergePointTimestamp === $ts || $this->mergePointTimestamp === $tsWithId
);
$user = $this->getUser();
$pageLink = $linkRenderer->makeKnownLink(
$revRecord->getPageAsLinkTarget(),
$this->getLanguage()->userTimeAndDate( $ts, $user ),
[],
[ 'oldid' => $revRecord->getId() ]
);
if ( $revRecord->isDeleted( RevisionRecord::DELETED_TEXT ) ) {
$class = Linker::getRevisionDeletedClass( $revRecord );
$pageLink = '' . $pageLink . '';
}
# Last link
if ( !$revRecord->userCan( RevisionRecord::DELETED_TEXT, $this->getAuthority() ) ) {
$last = $this->msg( 'last' )->escaped();
} elseif ( isset( $this->prevId[$row->rev_id] ) ) {
$last = $linkRenderer->makeKnownLink(
$revRecord->getPageAsLinkTarget(),
$this->msg( 'last' )->text(),
[],
[
'diff' => $row->rev_id,
'oldid' => $this->prevId[$row->rev_id]
]
);
}
$userLink = Linker::revUserTools( $revRecord );
$size = $row->rev_len;
if ( $size !== null ) {
$stxt = Linker::formatRevisionSize( $size );
}
$comment = $this->commentFormatter->formatRevision( $revRecord, $user );
// Tags, if any.
[ $tagSummary, $classes ] = ChangeTags::formatSummaryRow(
$row->ts_tags,
'mergehistory',
$this->getContext()
);
return Html::rawElement( 'li', $classes,
$this->msg( 'mergehistory-revisionrow' )
->rawParams( $checkBox, $last, $pageLink, $userLink, $stxt, $comment, $tagSummary )->escaped() );
}
public function getQueryInfo() {
$dbr = $this->getDatabase();
$queryBuilder = $this->revisionStore->newSelectQueryBuilder( $dbr )
->joinComment()
->joinPage()
->joinUser()
->where( $this->mConds )
->andWhere( [
'rev_page' => $this->articleID,
$dbr->buildComparison( "<",
[
"rev_timestamp" => $this->maxTimestamp,
"rev_id" => $this->maxRevId
]
)
] );
MediaWikiServices::getInstance()->getChangeTagsStore()->modifyDisplayQueryBuilder( $queryBuilder, 'revision' );
return $queryBuilder->getQueryInfo( 'join_conds' );
}
public function getIndexField() {
return [ [ 'rev_timestamp', 'rev_id' ] ];
}
}
/**
* Retain the old class name for backwards compatibility.
* @deprecated since 1.41
*/
class_alias( MergeHistoryPager::class, 'MergeHistoryPager' );