3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 * http://www.gnu.org/copyleft/gpl.html
22 namespace MediaWiki\Pager
;
25 use MediaWiki\Cache\LinkBatchFactory
;
26 use MediaWiki\CommentFormatter\CommentFormatter
;
27 use MediaWiki\Context\IContextSource
;
28 use MediaWiki\Html\Html
;
29 use MediaWiki\Linker\Linker
;
30 use MediaWiki\Linker\LinkRenderer
;
31 use MediaWiki\MediaWikiServices
;
32 use MediaWiki\Page\PageIdentity
;
33 use MediaWiki\Revision\RevisionRecord
;
34 use MediaWiki\Revision\RevisionStore
;
35 use MediaWiki\Xml\Xml
;
36 use Wikimedia\Rdbms\IConnectionProvider
;
41 class MergeHistoryPager
extends ReverseChronologicalPager
{
44 public $mGroupByDate = true;
53 private $maxTimestamp;
59 private $mergePointTimestamp;
64 private LinkBatchFactory
$linkBatchFactory;
65 private RevisionStore
$revisionStore;
66 private CommentFormatter
$commentFormatter;
69 * @param IContextSource $context
70 * @param LinkRenderer $linkRenderer
71 * @param LinkBatchFactory $linkBatchFactory
72 * @param IConnectionProvider $dbProvider
73 * @param RevisionStore $revisionStore
74 * @param CommentFormatter $commentFormatter
76 * @param PageIdentity $source
77 * @param PageIdentity $dest
78 * @param string $mergePointTimestamp
80 public function __construct(
81 IContextSource
$context,
82 LinkRenderer
$linkRenderer,
83 LinkBatchFactory
$linkBatchFactory,
84 IConnectionProvider
$dbProvider,
85 RevisionStore
$revisionStore,
86 CommentFormatter
$commentFormatter,
92 $this->mConds
= $conds;
93 $this->articleID
= $source->getId();
95 $dbr = $dbProvider->getReplicaDatabase();
96 $maxtimestamp = $dbr->newSelectQueryBuilder()
97 ->select( 'MIN(rev_timestamp)' )
99 ->where( [ 'rev_page' => $dest->getId() ] )
100 ->caller( __METHOD__
)->fetchField();
101 $maxRevId = $dbr->newSelectQueryBuilder()
102 ->select( "MIN(rev_id)" )
104 ->where( [ 'rev_page' => $dest->getId() ] )
105 ->where( [ 'rev_timestamp' => $maxtimestamp ] )
106 ->caller( __METHOD__
)->fetchField();
107 $this->maxTimestamp
= $maxtimestamp;
108 $this->maxRevId
= $maxRevId;
109 $this->mergePointTimestamp
= $mergePointTimestamp;
111 // Set database before parent constructor to avoid setting it there
113 parent
::__construct( $context, $linkRenderer );
114 $this->linkBatchFactory
= $linkBatchFactory;
115 $this->revisionStore
= $revisionStore;
116 $this->commentFormatter
= $commentFormatter;
119 protected function doBatchLookups() {
120 # Do a link batch query
121 $this->mResult
->seek( 0 );
122 $batch = $this->linkBatchFactory
->newLinkBatch();
123 # Give some pointers to make (last) links
126 foreach ( $this->mResult
as $row ) {
127 $batch->add( NS_USER
, $row->rev_user_text
);
128 $batch->add( NS_USER_TALK
, $row->rev_user_text
);
130 if ( $rev_id !== null ) {
131 if ( $rev_id > $row->rev_id
) {
132 $this->prevId
[$rev_id] = $row->rev_id
;
133 } elseif ( $rev_id < $row->rev_id
) {
134 $this->prevId
[$row->rev_id
] = $rev_id;
138 $rev_id = $row->rev_id
;
142 $this->mResult
->seek( 0 );
148 protected function getStartBody() {
149 return "<section class='mw-pager-body'>\n";
155 protected function getEndBody() {
156 return "</section>\n";
159 public function formatRow( $row ) {
160 $revRecord = $this->revisionStore
->newRevisionFromRow( $row );
162 $linkRenderer = $this->getLinkRenderer();
165 $last = $this->msg( 'last' )->escaped();
167 $ts = wfTimestamp( TS_MW
, $row->rev_timestamp
);
168 $tsWithId = $ts . "|" . $row->rev_id
;
169 $checkBox = Xml
::radio(
170 'mergepoint', $tsWithId,
171 $this->mergePointTimestamp
=== $ts ||
$this->mergePointTimestamp
=== $tsWithId
174 $user = $this->getUser();
176 $pageLink = $linkRenderer->makeKnownLink(
177 $revRecord->getPageAsLinkTarget(),
178 $this->getLanguage()->userTimeAndDate( $ts, $user ),
180 [ 'oldid' => $revRecord->getId() ]
182 if ( $revRecord->isDeleted( RevisionRecord
::DELETED_TEXT
) ) {
183 $class = Linker
::getRevisionDeletedClass( $revRecord );
184 $pageLink = '<span class=" ' . $class . '">' . $pageLink . '</span>';
188 if ( !$revRecord->userCan( RevisionRecord
::DELETED_TEXT
, $this->getAuthority() ) ) {
189 $last = $this->msg( 'last' )->escaped();
190 } elseif ( isset( $this->prevId
[$row->rev_id
] ) ) {
191 $last = $linkRenderer->makeKnownLink(
192 $revRecord->getPageAsLinkTarget(),
193 $this->msg( 'last' )->text(),
196 'diff' => $row->rev_id
,
197 'oldid' => $this->prevId
[$row->rev_id
]
202 $userLink = Linker
::revUserTools( $revRecord );
204 $size = $row->rev_len
;
205 if ( $size !== null ) {
206 $stxt = Linker
::formatRevisionSize( $size );
208 $comment = $this->commentFormatter
->formatRevision( $revRecord, $user );
211 [ $tagSummary, $classes ] = ChangeTags
::formatSummaryRow(
217 return Html
::rawElement( 'li', $classes,
218 $this->msg( 'mergehistory-revisionrow' )
219 ->rawParams( $checkBox, $last, $pageLink, $userLink, $stxt, $comment, $tagSummary )->escaped() );
222 public function getQueryInfo() {
223 $dbr = $this->getDatabase();
224 $queryBuilder = $this->revisionStore
->newSelectQueryBuilder( $dbr )
228 ->where( $this->mConds
)
230 'rev_page' => $this->articleID
,
231 $dbr->buildComparison( "<",
233 "rev_timestamp" => $this->maxTimestamp
,
234 "rev_id" => $this->maxRevId
238 MediaWikiServices
::getInstance()->getChangeTagsStore()->modifyDisplayQueryBuilder( $queryBuilder, 'revision' );
240 return $queryBuilder->getQueryInfo( 'join_conds' );
243 public function getIndexField() {
244 return [ [ 'rev_timestamp', 'rev_id' ] ];
249 * Retain the old class name for backwards compatibility.
250 * @deprecated since 1.41
252 class_alias( MergeHistoryPager
::class, 'MergeHistoryPager' );