253 lines
6.8 KiB
PHP
253 lines
6.8 KiB
PHP
<?php
|
|
/**
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
* http://www.gnu.org/copyleft/gpl.html
|
|
*
|
|
* @file
|
|
* @ingroup Pager
|
|
*/
|
|
|
|
namespace MediaWiki\Pager;
|
|
|
|
use ChangeTags;
|
|
use MediaWiki\Cache\LinkBatchFactory;
|
|
use MediaWiki\CommentFormatter\CommentFormatter;
|
|
use MediaWiki\Context\IContextSource;
|
|
use MediaWiki\Html\Html;
|
|
use MediaWiki\Linker\Linker;
|
|
use MediaWiki\Linker\LinkRenderer;
|
|
use MediaWiki\MediaWikiServices;
|
|
use MediaWiki\Page\PageIdentity;
|
|
use MediaWiki\Revision\RevisionRecord;
|
|
use MediaWiki\Revision\RevisionStore;
|
|
use MediaWiki\Xml\Xml;
|
|
use Wikimedia\Rdbms\IConnectionProvider;
|
|
|
|
/**
|
|
* @ingroup Pager
|
|
*/
|
|
class MergeHistoryPager extends ReverseChronologicalPager {
|
|
|
|
/** @inheritDoc */
|
|
public $mGroupByDate = true;
|
|
|
|
/** @var array */
|
|
public $mConds;
|
|
|
|
/** @var int */
|
|
private $articleID;
|
|
|
|
/** @var string */
|
|
private $maxTimestamp;
|
|
|
|
/** @var string */
|
|
private $maxRevId;
|
|
|
|
/** @var string */
|
|
private $mergePointTimestamp;
|
|
|
|
/** @var int[] */
|
|
public $prevId;
|
|
|
|
private LinkBatchFactory $linkBatchFactory;
|
|
private RevisionStore $revisionStore;
|
|
private CommentFormatter $commentFormatter;
|
|
|
|
/**
|
|
* @param IContextSource $context
|
|
* @param LinkRenderer $linkRenderer
|
|
* @param LinkBatchFactory $linkBatchFactory
|
|
* @param IConnectionProvider $dbProvider
|
|
* @param RevisionStore $revisionStore
|
|
* @param CommentFormatter $commentFormatter
|
|
* @param array $conds
|
|
* @param PageIdentity $source
|
|
* @param PageIdentity $dest
|
|
* @param string $mergePointTimestamp
|
|
*/
|
|
public function __construct(
|
|
IContextSource $context,
|
|
LinkRenderer $linkRenderer,
|
|
LinkBatchFactory $linkBatchFactory,
|
|
IConnectionProvider $dbProvider,
|
|
RevisionStore $revisionStore,
|
|
CommentFormatter $commentFormatter,
|
|
$conds,
|
|
PageIdentity $source,
|
|
PageIdentity $dest,
|
|
$mergePointTimestamp
|
|
) {
|
|
$this->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 "<section class='mw-pager-body'>\n";
|
|
}
|
|
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
protected function getEndBody() {
|
|
return "</section>\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 = '<span class=" ' . $class . '">' . $pageLink . '</span>';
|
|
}
|
|
|
|
# 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' );
|