diff --git a/includes/pagers/AbuseLogPager.php b/includes/pagers/AbuseLogPager.php index e5e8fe3df..95ae85432 100644 --- a/includes/pagers/AbuseLogPager.php +++ b/includes/pagers/AbuseLogPager.php @@ -17,16 +17,26 @@ class AbuseLogPager extends ReverseChronologicalPager { /** @var LinkBatchFactory */ private $linkBatchFactory; + /** @var bool */ + private $joinWithArchive; + /** * @param SpecialAbuseLog $form * @param array $conds * @param LinkBatchFactory $linkBatchFactory + * @param bool $joinWithArchive */ - public function __construct( SpecialAbuseLog $form, array $conds, LinkBatchFactory $linkBatchFactory ) { + public function __construct( + SpecialAbuseLog $form, + array $conds, + LinkBatchFactory $linkBatchFactory, + bool $joinWithArchive = false + ) { parent::__construct( $form->getContext(), $form->getLinkRenderer() ); $this->mForm = $form; $this->mConds = $conds; $this->linkBatchFactory = $linkBatchFactory; + $this->joinWithArchive = $joinWithArchive; } /** @@ -67,6 +77,20 @@ class AbuseLogPager extends ReverseChronologicalPager { ], ]; + if ( $this->joinWithArchive ) { + $info['tables'][] = 'archive'; + $info['fields'][] = 'ar_timestamp'; + $info['join_conds']['archive'] = [ + 'LEFT JOIN', + [ + 'afl_wiki IS NULL', + 'afl_rev_id IS NOT NULL', + 'rev_id IS NULL', + 'ar_rev_id=afl_rev_id', + ] + ]; + } + if ( !$this->mForm->canSeeHidden( $this->getUser() ) ) { $info['conds']['afl_deleted'] = 0; } diff --git a/includes/special/SpecialAbuseLog.php b/includes/special/SpecialAbuseLog.php index 3f7ea75ac..621bbcc81 100644 --- a/includes/special/SpecialAbuseLog.php +++ b/includes/special/SpecialAbuseLog.php @@ -1,6 +1,7 @@ linkBatchFactory ); + $pager = new AbuseLogPager( + $this, + $conds, + $this->linkBatchFactory, + $this->canSeeUndeleteDiffs() + ); $pager->doQuery(); $result = $pager->getResult(); if ( $result && $result->numRows() !== 0 ) { @@ -623,7 +629,12 @@ class SpecialAbuseLog extends AbuseFilterSpecialPage { $out = $this->getOutput(); $user = $this->getUser(); - $pager = new AbuseLogPager( $this, [], $this->linkBatchFactory ); + $pager = new AbuseLogPager( + $this, + [], + $this->linkBatchFactory, + $this->canSeeUndeleteDiffs() + ); [ 'tables' => $tables, @@ -737,6 +748,44 @@ class SpecialAbuseLog extends AbuseFilterSpecialPage { $out->addHTML( Xml::tags( 'fieldset', null, $output ) ); } + /** + * Can this user see diffs generated by Special:Undelete? + * @see \SpecialUndelete + * + * @return bool + */ + private function canSeeUndeleteDiffs() : bool { + if ( !$this->permissionManager->userHasRight( $this->getUser(), 'deletedhistory' ) ) { + return false; + } + + return $this->permissionManager->userHasAnyRight( + $this->getUser(), 'deletedtext', 'undelete' ); + } + + /** + * Can this user see diffs generated by Special:Undelete for the page? + * @see \SpecialUndelete + * @param LinkTarget $page + * + * @return bool + */ + private function canSeeUndeleteDiffForPage( LinkTarget $page ) : bool { + if ( !$this->canSeeUndeleteDiffs() ) { + return false; + } + + foreach ( [ 'deletedtext', 'undelete' ] as $action ) { + if ( $this->permissionManager->userCan( + $action, $this->getUser(), $page, PermissionManager::RIGOR_QUICK + ) ) { + return true; + } + } + + return false; + } + /** * Helper function to select a row with private details and some more context * for an AbuseLog entry. @@ -1088,6 +1137,20 @@ class SpecialAbuseLog extends AbuseFilterSpecialPage { [], [ 'diff' => 'prev', 'oldid' => $row->rev_id ] ); + } elseif ( + isset( $row->ar_timestamp ) && $row->ar_timestamp + && $this->canSeeUndeleteDiffForPage( $title ) + ) { + $diffLink = $linkRenderer->makeKnownLink( + SpecialPage::getTitleFor( 'Undelete' ), + new HtmlArmor( $this->msg( 'abusefilter-log-diff' )->parse() ), + [], + [ + 'diff' => 'prev', + 'target' => $title->getPrefixedText(), + 'timestamp' => $row->ar_timestamp, + ] + ); } } else { $pageLink = WikiMap::makeForeignLink( $row->afl_wiki, $row->afl_title );