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' );