69 private $formattedComments = [];
72 private $revisions = [];
101 parent::__construct( $context, $linkRenderer );
103 $msgs = [
'deletionlog',
'undeleteviewlink',
'diff' ];
104 foreach ( $msgs as $msg ) {
105 $this->messages[$msg] = $this->
msg( $msg )->text();
108 $this->
namespace = $namespace;
109 $this->hookRunner =
new HookRunner( $hookContainer );
110 $this->revisionFactory = $revisionFactory;
111 $this->commentFormatter = $commentFormatter;
112 $this->linkBatchFactory = $linkBatchFactory;
116 $query = parent::getDefaultQuery();
124 $queryBuilder = $this->revisionFactory->newArchiveSelectQueryBuilder( $dbr )
126 ->where( [
'actor_name' => $this->target ] )
127 ->andWhere( $this->getNamespaceCond() );
129 if ( !$this->
getAuthority()->isAllowed(
'deletedhistory' ) ) {
130 $queryBuilder->andWhere(
131 $dbr->bitAnd(
'ar_deleted', RevisionRecord::DELETED_USER ) .
' = 0'
133 } elseif ( !$this->
getAuthority()->isAllowedAny(
'suppressrevision',
'viewsuppressed' ) ) {
134 $queryBuilder->andWhere(
135 $dbr->bitAnd(
'ar_deleted', RevisionRecord::SUPPRESSED_USER ) .
136 ' != ' . RevisionRecord::SUPPRESSED_USER
142 return $queryBuilder->getQueryInfo(
'join_conds' );
147 $this->mResult->seek( 0 );
149 $linkBatch = $this->linkBatchFactory->newLinkBatch();
152 foreach ( $this->mResult as $row ) {
153 if ( $this->revisionFactory->isRevisionRow( $row,
'archive' ) ) {
154 $revisionRows[] = $row;
155 $linkBatch->add( $row->ar_namespace, $row->ar_title );
160 $linkBatch->execute();
162 foreach ( $revisionRows as $row ) {
163 $revisions[$row->ar_rev_id] = $this->revisionFactory->newRevisionFromArchiveRow(
165 IDBAccessObject::READ_NORMAL,
166 Title::makeTitle( $row->ar_namespace, $row->ar_title )
170 $this->formattedComments = $this->commentFormatter->createRevisionBatch()
172 ->revisions( $revisions )
179 $this->revisions += $revisions;
192 $data = [ parent::reallyDoQuery( $offset, $limit, $order ) ];
196 $this->hookRunner->onDeletedContribsPager__reallyDoQuery(
197 $data, $this, $offset, $limit, $order );
202 foreach ( $data as $query ) {
203 foreach ( $query as $i => $row ) {
210 if ( $order === self::QUERY_ASCENDING ) {
217 $result = array_slice( $result, 0, $limit );
220 $result = array_values( $result );
222 return new FakeResultWrapper( $result );
233 return 'ar_timestamp';
240 return $this->target;
247 return $this->namespace;
254 return "<section class='mw-pager-body'>\n";
261 return "</section>\n";
264 private function getNamespaceCond() {
265 if ( $this->
namespace !==
'' ) {
266 return [
'ar_namespace' => (int)$this->
namespace ];
284 if ( $this->revisionFactory->isRevisionRow( $row,
'archive' ) ) {
285 $attribs[
'data-mw-revid'] = $row->ar_rev_id;
286 [ $ret, $classes ] = $this->formatRevisionRow( $row );
290 $this->hookRunner->onDeletedContributionsLineEnding(
291 $this, $ret, $row, $classes, $attribs );
292 $attribs = array_filter( $attribs,
293 [ Sanitizer::class,
'isReservedDataAttribute' ],
297 if ( $classes === [] && $attribs === [] && $ret ===
'' ) {
298 wfDebug(
"Dropping Special:DeletedContribution row that could not be formatted" );
299 $ret =
"<!-- Could not format Special:DeletedContribution row. -->\n";
301 $attribs[
'class'] = $classes;
302 $ret = Html::rawElement(
'li', $attribs, $ret ) .
"\n";
320 private function formatRevisionRow( $row ) {
321 $page = Title::makeTitle( $row->ar_namespace, $row->ar_title );
323 $linkRenderer = $this->getLinkRenderer();
325 $revRecord = $this->revisions[$row->ar_rev_id] ?? $this->revisionFactory->newRevisionFromArchiveRow(
327 IDBAccessObject::READ_NORMAL,
334 $dellog = $linkRenderer->makeKnownLink(
336 $this->messages[
'deletionlog'],
340 'page' => $page->getPrefixedText()
344 $reviewlink = $linkRenderer->makeKnownLink(
346 $this->messages[
'undeleteviewlink']
351 if ( $this->
getAuthority()->isAllowed(
'deletedtext' ) ) {
352 $last = $linkRenderer->makeKnownLink(
354 $this->messages[
'diff'],
357 'target' => $page->getPrefixedText(),
358 'timestamp' => $revRecord->getTimestamp(),
363 $last = htmlspecialchars( $this->messages[
'diff'] );
366 $comment = $row->ar_rev_id
367 ? $this->formattedComments[$row->ar_rev_id]
368 : $this->commentFormatter->formatRevision( $revRecord, $user );
369 $date = $this->getLanguage()->userTimeAndDate( $revRecord->getTimestamp(), $user );
372 !$revRecord->userCan( RevisionRecord::DELETED_TEXT, $this->getAuthority() )
374 $link = htmlspecialchars( $date );
376 $link = $linkRenderer->makeKnownLink(
379 [
'class' =>
'mw-changeslist-date' ],
381 'target' => $page->getPrefixedText(),
382 'timestamp' => $revRecord->getTimestamp()
387 if ( $revRecord->isDeleted( RevisionRecord::DELETED_TEXT ) ) {
388 $class = Linker::getRevisionDeletedClass( $revRecord );
389 $link =
'<span class="' . $class .
'">' . $link .
'</span>';
392 $pagelink = $linkRenderer->makeLink(
395 [
'class' =>
'mw-changeslist-title' ]
398 if ( $revRecord->isMinor() ) {
405 $del = Linker::getRevDeleteLink( $user, $revRecord, $page );
410 $tools = Html::rawElement(
412 [
'class' =>
'mw-deletedcontribs-tools' ],
413 $this->msg(
'parentheses' )->rawParams( $this->getLanguage()->pipeList(
414 [ $last, $dellog, $reviewlink ] ) )->escaped()
420 'deletedcontributions',
424 $separator =
'<span class="mw-changeslist-separator">. .</span>';
425 $ret =
"{$del}{$link} {$tools} {$separator} {$mflag} {$pagelink} {$comment} {$tagSummary}";
427 # Denote if username is redacted for this edit
428 if ( $revRecord->isDeleted( RevisionRecord::DELETED_USER ) ) {
429 $ret .=
" <strong>" . $this->msg(
'rev-deleted-user-contribs' )->escaped() .
"</strong>";
432 return [ $ret, $classes ];
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.