79 return $this->historyPage->getArticle();
84 return 'history page filtered';
86 return 'history page unfiltered';
95 'conds' => array_merge(
98 'options' => [
'USE INDEX' => [
'revision' =>
'page_timestamp' ] ],
102 $queryInfo[
'tables'],
103 $queryInfo[
'fields'],
105 $queryInfo[
'join_conds'],
106 $queryInfo[
'options'],
111 $historyPager = $this;
112 Hooks::run(
'PageHistoryPager::getQueryInfo', [ &$historyPager, &$queryInfo ] );
118 return 'rev_timestamp';
126 if ( $this->lastRow ) {
127 $firstInList = $this->counter == 1;
130 $notifTimestamp = $this->
getConfig()->get(
'ShowUpdatedMarker' )
134 $s = $this->
historyLine( $this->lastRow, $row, $notifTimestamp,
false, $firstInList );
138 $this->lastRow = $row;
144 if ( !
Hooks::run(
'PageHistoryPager::doBatchLookups', [ $this, $this->mResult ] ) ) {
148 # Do a link batch query
149 $this->mResult->seek( 0 );
152 foreach ( $this->mResult as $row ) {
153 if ( $row->rev_parent_id ) {
154 $revIds[] = $row->rev_parent_id;
156 if ( $row->user_name !==
null ) {
157 $batch->add(
NS_USER, $row->user_name );
159 }
else { #
for anons or usernames of imported revisions
160 $batch->add(
NS_USER, $row->rev_user_text );
166 $this->mResult->seek( 0 );
175 $permissionManager = MediaWikiServices::getInstance()->getPermissionManager();
176 $this->lastRow =
false;
178 $this->oldIdChecked = 0;
180 $this->
getOutput()->wrapWikiMsg(
"<div class='mw-history-legend'>\n$1\n</div>",
'histlegend' );
181 $s = Html::openElement(
'form', [
'action' =>
wfScript(),
182 'id' =>
'mw-history-compare' ] ) .
"\n";
183 $s .= Html::hidden(
'title', $this->
getTitle()->getPrefixedDBkey() ) .
"\n";
184 $s .= Html::hidden(
'action',
'historysubmit' ) .
"\n";
185 $s .= Html::hidden(
'type',
'revision' ) .
"\n";
190 $this->buttons .= Html::openElement(
191 'div', [
'class' =>
'mw-history-compareselectedversions' ] );
192 $className =
'historysubmit mw-history-compareselectedversions-button';
193 $attrs = [
'class' => $className ]
195 $this->buttons .= $this->
submitButton( $this->
msg(
'compareselectedversions' )->text(),
201 if ( $permissionManager->userHasRight( $user,
'deleterevision' ) ) {
203 'revisiondelete',
'showhideselectedversions' );
205 if ( $this->showTagEditUI ) {
207 'editchangetags',
'history-edit-tags' );
209 if ( $actionButtons ) {
210 $this->buttons .=
Xml::tags(
'div', [
'class' =>
211 'mw-history-revisionactions' ], $actionButtons );
218 $this->buttons .=
'</div>';
222 $s .=
'<ul id="pagehistory">' .
"\n";
229 # Note T22966, <button> is non-standard in IE<8
230 $element = Html::element(
236 'class' =>
"historysubmit mw-history-$name-button",
238 $this->
msg( $msg )->text()
244 if ( $this->lastRow ) {
245 $firstInList = $this->counter == 1;
246 if ( $this->mIsBackwards ) {
247 # Next row is unknown, but for UI reasons, probably exists if an offset has been specified
248 if ( $this->mOffset ==
'' ) {
254 # The next row is the past-the-end row
259 $notifTimestamp = $this->
getConfig()->get(
'ShowUpdatedMarker' )
263 $s = $this->
historyLine( $this->lastRow, $next, $notifTimestamp,
false, $firstInList );
268 # Add second buttons only if there is more than one rev
285 # Disable submit button if history has 1 revision only
287 return Html::submitButton( $message, $attributes );
307 function historyLine( $row, $next, $notificationtimestamp =
false,
308 $dummy =
false, $firstInList =
false ) {
309 $permissionManager = MediaWikiServices::getInstance()->getPermissionManager();
312 if ( is_object( $next ) ) {
318 $latest = $rev->getId() === $this->
getWikiPage()->getLatest();
319 $curlink = $this->
curLink( $rev );
320 $lastlink = $this->
lastLink( $rev, $next );
321 $curLastlinks = Html::rawElement(
'span', [], $curlink ) .
322 Html::rawElement(
'span', [], $lastlink );
323 $histLinks = Html::rawElement(
325 [
'class' =>
'mw-history-histlinks mw-changeslist-links' ],
329 $diffButtons = $this->
diffButtons( $rev, $firstInList );
330 $s = $histLinks . $diffButtons;
332 $link = $this->
revLink( $rev );
337 $canRevDelete = $permissionManager->userHasRight( $user,
'deleterevision' );
340 if ( $canRevDelete || $this->showTagEditUI ) {
344 if ( !$this->showTagEditUI
345 && !$rev->userCan( RevisionRecord::DELETED_RESTRICTED, $user )
347 $del =
Xml::check(
'deleterevisions',
false, [
'disabled' =>
'disabled' ] );
350 $del =
Xml::check(
'showhiderevisions',
false,
351 [
'name' =>
'ids[' . $rev->getId() .
']' ] );
354 } elseif ( $rev->getVisibility() &&
355 $permissionManager->userHasRight( $user,
'deletedhistory' ) ) {
357 if ( !$rev->userCan( RevisionRecord::DELETED_RESTRICTED, $user ) ) {
361 $query = [
'type' =>
'revision',
362 'target' => $this->
getTitle()->getPrefixedDBkey(),
'ids' => $rev->getId() ];
364 $rev->isDeleted( RevisionRecord::DELETED_RESTRICTED ), false );
372 $dirmark =
$lang->getDirMark();
376 $s .=
" <span class='history-user'>" .
380 if ( $rev->isMinor() ) {
384 # Sometimes rev_len isn't populated
385 if ( $rev->getSize() !== null ) {
386 # Size is always public data
387 $prevSize = $this->parentLens[$row->rev_parent_id] ?? 0;
390 $s .=
' <span class="mw-changeslist-separator"></span> ' .
"$fSize $sDiff";
393 # Text following the character difference is added just before running hooks
396 if ( $notificationtimestamp && ( $row->rev_timestamp >= $notificationtimestamp ) ) {
397 $s2 .=
' <span class="updatedmarker">' . $this->
msg(
'updatedmarker' )->escaped() .
'</span>';
398 $classes[] =
'mw-history-line-updated';
403 # Rollback and undo links
405 if ( $prevRev && $permissionManager->quickUserCan(
'edit', $user, $this->getTitle() ) ) {
406 if ( $latest && $permissionManager->quickUserCan(
'rollback',
407 $user, $this->getTitle() )
413 [
'verify',
'noBrackets' ]
415 if ( $rollbackLink ) {
417 $tools[] = $rollbackLink;
421 if ( !$rev->isDeleted( RevisionRecord::DELETED_TEXT )
422 && !$prevRev->isDeleted( RevisionRecord::DELETED_TEXT )
424 # Create undo tooltip for the first (=latest) line only
425 $undoTooltip = $latest
426 ? [
'title' => $this->
msg(
'tooltip-undo' )->text() ]
430 $this->
msg(
'editundo' )->text(),
434 'undoafter' => $prevRev->getId(),
435 'undo' => $rev->getId()
438 $tools[] =
"<span class=\"mw-history-undo\">{$undolink}</span>";
442 Hooks::run(
'HistoryRevisionTools', [ $rev, &$tools, $prevRev, $user ] );
445 $s2 .=
' ' . Html::openElement(
'span', [
'class' =>
'mw-changeslist-links' ] );
446 foreach ( $tools as $tool ) {
447 $s2 .= Html::rawElement(
'span', [], $tool );
449 $s2 .= Html::closeElement(
'span' );
458 $classes = array_merge( $classes, $newClasses );
459 if ( $tagSummary !==
'' ) {
460 $s2 .=
" $tagSummary";
463 # Include separator between character difference and following text
465 $s .=
' <span class="mw-changeslist-separator"></span> ' . $s2;
468 $attribs = [
'data-mw-revid' => $rev->getId() ];
470 Hooks::run(
'PageHistoryLineEnding', [ $this, &$row, &
$s, &$classes, &$attribs ] );
471 $attribs = array_filter( $attribs,
472 [ Sanitizer::class,
'isReservedDataAttribute' ],
477 $attribs[
'class'] = implode(
' ', $classes );
501 $cur = $this->historyPage->message[
'cur'];
503 if ( $latest === $rev->getId()
504 || !$rev->userCan( RevisionRecord::DELETED_TEXT, $this->
getUser() )
514 'oldid' => $rev->getId()
530 $last = $this->historyPage->message[
'last'];
532 if ( $next ===
null ) {
533 # Probably no next row
538 if ( $next ===
'unknown' ) {
539 # Next row probably exists but is unknown, use an oldid=prev link
545 'diff' => $prevRev->getId(),
553 if ( !$prevRev->userCan( RevisionRecord::DELETED_TEXT, $this->getUser() )
554 || !$nextRev->userCan( RevisionRecord::DELETED_TEXT, $this->getUser() )
564 'diff' => $prevRev->getId(),
565 'oldid' => $next->rev_id
581 $radio = [
'type' =>
'radio',
'value' => $id ];
583 if ( $firstInList ) {
585 array_merge( $radio, [
586 'style' =>
'visibility:hidden',
588 'id' =>
'mw-oldid-null' ] )
590 $checkmark = [
'checked' =>
'checked' ];
592 # Check visibility of old revisions
593 if ( !$rev->userCan( RevisionRecord::DELETED_TEXT, $this->getUser() ) ) {
594 $radio[
'disabled'] =
'disabled';
596 } elseif ( !$this->oldIdChecked ) {
597 $checkmark = [
'checked' =>
'checked' ];
598 $this->oldIdChecked = $id;
603 array_merge( $radio, $checkmark, [
605 'id' =>
"mw-oldid-$id" ] ) );
609 array_merge( $radio, $checkmark, [
611 'id' =>
"mw-diff-$id" ] ) );
613 return $first . $second;
623 parent::getDefaultQuery();
624 unset( $this->mDefaultQuery[
'date-range-to'] );