Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 87
0.00% covered (danger)
0.00%
0 / 12
CRAP
0.00% covered (danger)
0.00%
0 / 1
RevDelLogItem
0.00% covered (danger)
0.00%
0 / 86
0.00% covered (danger)
0.00%
0 / 12
306
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 getIdField
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getTimestampField
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getAuthorIdField
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getAuthorNameField
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getAuthorActorField
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 canView
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 canViewContent
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getBits
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setBits
0.00% covered (danger)
0.00%
0 / 23
0.00% covered (danger)
0.00%
0 / 1
6
 getHTML
0.00% covered (danger)
0.00%
0 / 27
0.00% covered (danger)
0.00%
0 / 1
6
 getApiData
0.00% covered (danger)
0.00%
0 / 22
0.00% covered (danger)
0.00%
0 / 1
20
1<?php
2/**
3 * @license GPL-2.0-or-later
4 * @file
5 * @ingroup RevisionDelete
6 */
7
8namespace MediaWiki\RevisionDelete;
9
10use MediaWiki\Api\ApiResult;
11use MediaWiki\ChangeTags\ChangeTags;
12use MediaWiki\CommentStore\CommentStore;
13use MediaWiki\Html\Html;
14use MediaWiki\Logging\DatabaseLogEntry;
15use MediaWiki\Logging\LogEventsList;
16use MediaWiki\Logging\LogFormatter;
17use MediaWiki\Logging\LogFormatterFactory;
18use MediaWiki\Logging\LogPage;
19use MediaWiki\RecentChanges\RecentChange;
20use MediaWiki\RevisionList\RevisionListBase;
21use MediaWiki\SpecialPage\SpecialPage;
22use MediaWiki\Title\Title;
23use stdClass;
24use Wikimedia\Rdbms\IConnectionProvider;
25
26/**
27 * Item class for a logging table row
28 */
29class RevDelLogItem extends RevDelItem {
30
31    /** @var CommentStore */
32    private $commentStore;
33    private IConnectionProvider $dbProvider;
34    private LogFormatterFactory $logFormatterFactory;
35
36    /**
37     * @param RevisionListBase $list
38     * @param stdClass $row DB result row
39     * @param CommentStore $commentStore
40     * @param IConnectionProvider $dbProvider
41     * @param LogFormatterFactory $logFormatterFactory
42     */
43    public function __construct(
44        RevisionListBase $list,
45        $row,
46        CommentStore $commentStore,
47        IConnectionProvider $dbProvider,
48        LogFormatterFactory $logFormatterFactory
49    ) {
50        parent::__construct( $list, $row );
51        $this->commentStore = $commentStore;
52        $this->dbProvider = $dbProvider;
53        $this->logFormatterFactory = $logFormatterFactory;
54    }
55
56    /** @inheritDoc */
57    public function getIdField() {
58        return 'log_id';
59    }
60
61    /** @inheritDoc */
62    public function getTimestampField() {
63        return 'log_timestamp';
64    }
65
66    /** @inheritDoc */
67    public function getAuthorIdField() {
68        return 'log_user';
69    }
70
71    /** @inheritDoc */
72    public function getAuthorNameField() {
73        return 'log_user_text';
74    }
75
76    /** @inheritDoc */
77    public function getAuthorActorField() {
78        return 'log_actor';
79    }
80
81    /** @inheritDoc */
82    public function canView() {
83        return LogEventsList::userCan(
84            $this->row, LogPage::DELETED_RESTRICTED, $this->list->getAuthority()
85        );
86    }
87
88    /** @inheritDoc */
89    public function canViewContent() {
90        return true; // none
91    }
92
93    /** @inheritDoc */
94    public function getBits() {
95        return (int)$this->row->log_deleted;
96    }
97
98    /** @inheritDoc */
99    public function setBits( $bits ) {
100        $dbw = $this->dbProvider->getPrimaryDatabase();
101
102        $dbw->newUpdateQueryBuilder()
103            ->update( 'logging' )
104            ->set( [ 'log_deleted' => $bits ] )
105            ->where( [
106                'log_id' => $this->row->log_id,
107                'log_deleted' => $this->getBits() // cas
108            ] )
109            ->caller( __METHOD__ )->execute();
110
111        if ( !$dbw->affectedRows() ) {
112            // Concurrent fail!
113            return false;
114        }
115
116        $dbw->newUpdateQueryBuilder()
117            ->update( 'recentchanges' )
118            ->set( [
119                'rc_deleted' => $bits,
120                'rc_patrolled' => RecentChange::PRC_AUTOPATROLLED
121            ] )
122            ->where( [
123                'rc_logid' => $this->row->log_id,
124                'rc_timestamp' => $this->row->log_timestamp // index
125            ] )
126            ->caller( __METHOD__ )->execute();
127
128        return true;
129    }
130
131    /** @inheritDoc */
132    public function getHTML() {
133        $date = htmlspecialchars( $this->list->getLanguage()->userTimeAndDate(
134            $this->row->log_timestamp, $this->list->getUser() ) );
135        $title = Title::makeTitle( $this->row->log_namespace, $this->row->log_title );
136        $formatter = $this->logFormatterFactory->newFromRow( $this->row );
137        $formatter->setContext( $this->list->getContext() );
138        $formatter->setAudience( LogFormatter::FOR_THIS_USER );
139
140        // Log link for this page
141        $loglink = $this->getLinkRenderer()->makeLink(
142            SpecialPage::getTitleFor( 'Log' ),
143            $this->list->msg( 'log' )->text(),
144            [],
145            [ 'page' => $title->getPrefixedText() ]
146        );
147        $loglink = $this->list->msg( 'parentheses' )->rawParams( $loglink )->escaped();
148        // User links and action text
149        $action = $formatter->getActionText();
150
151        $dir = $this->list->getLanguage()->getDir();
152        $comment = Html::rawElement( 'bdi', [ 'dir' => $dir ], $formatter->getComment() );
153
154        $content = "$loglink $date $action $comment";
155        $attribs = [];
156        if ( $this->row->ts_tags ) {
157            [ $tagSummary, $classes ] = ChangeTags::formatSummaryRow(
158                $this->row->ts_tags,
159                'revisiondelete',
160                $this->list->getContext()
161            );
162            $content .= " $tagSummary";
163            $attribs['class'] = $classes;
164        }
165        return Html::rawElement( 'li', $attribs, $content );
166    }
167
168    /** @inheritDoc */
169    public function getApiData( ApiResult $result ) {
170        $logEntry = DatabaseLogEntry::newFromRow( $this->row );
171        $user = $this->list->getAuthority();
172        $ret = [
173            'id' => $logEntry->getId(),
174            'type' => $logEntry->getType(),
175            'action' => $logEntry->getSubtype(),
176            'userhidden' => (bool)$logEntry->isDeleted( LogPage::DELETED_USER ),
177            'commenthidden' => (bool)$logEntry->isDeleted( LogPage::DELETED_COMMENT ),
178            'actionhidden' => (bool)$logEntry->isDeleted( LogPage::DELETED_ACTION ),
179        ];
180
181        if ( LogEventsList::userCan( $this->row, LogPage::DELETED_ACTION, $user ) ) {
182            $ret['params'] = $this->logFormatterFactory->newFromEntry( $logEntry )->formatParametersForApi();
183        }
184        if ( LogEventsList::userCan( $this->row, LogPage::DELETED_USER, $user ) ) {
185            $ret += [
186                'userid' => $this->row->log_user ?? 0,
187                'user' => $this->row->log_user_text,
188            ];
189        }
190        if ( LogEventsList::userCan( $this->row, LogPage::DELETED_COMMENT, $user ) ) {
191            $ret += [
192                'comment' => $this->commentStore->getComment( 'log_comment', $this->row )->text,
193            ];
194        }
195
196        return $ret;
197    }
198}
199
200/** @deprecated class alias since 1.46 */
201class_alias( RevDelLogItem::class, 'RevDelLogItem' );