Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 117
0.00% covered (danger)
0.00%
0 / 19
CRAP
0.00% covered (danger)
0.00%
0 / 1
RevDelRevisionItem
0.00% covered (danger)
0.00%
0 / 116
0.00% covered (danger)
0.00%
0 / 19
1056
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 initRevisionRecord
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 getRevisionRecord
0.00% covered (danger)
0.00%
0 / 1
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 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 canViewContent
0.00% covered (danger)
0.00%
0 / 4
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 / 22
0.00% covered (danger)
0.00%
0 / 1
6
 isDeleted
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 isHideCurrentOp
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 getRevisionLink
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
12
 getDiffLink
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
12
 getHTML
0.00% covered (danger)
0.00%
0 / 22
0.00% covered (danger)
0.00%
0 / 1
12
 getTags
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getApiData
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 1
42
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\Html\Html;
13use MediaWiki\Linker\Linker;
14use MediaWiki\MediaWikiServices;
15use MediaWiki\RecentChanges\RecentChange;
16use MediaWiki\Revision\RevisionRecord;
17use MediaWiki\RevisionList\RevisionListBase;
18use Wikimedia\Timestamp\TimestampFormat as TS;
19
20/**
21 * Item class for a live revision table row
22 *
23 * @property RevDelRevisionList $list
24 */
25class RevDelRevisionItem extends RevDelItem {
26    /** @var RevisionRecord */
27    public $revisionRecord;
28
29    /** @inheritDoc */
30    public function __construct( RevisionListBase $list, $row ) {
31        parent::__construct( $list, $row );
32        $this->revisionRecord = static::initRevisionRecord( $list, $row );
33    }
34
35    /**
36     * Create RevisionRecord object from $row sourced from $list
37     *
38     * @param RevisionListBase $list
39     * @param mixed $row
40     * @return RevisionRecord
41     */
42    protected static function initRevisionRecord( $list, $row ) {
43        return MediaWikiServices::getInstance()
44            ->getRevisionFactory()
45            ->newRevisionFromRow( $row );
46    }
47
48    /**
49     * Get the RevisionRecord for the item
50     */
51    protected function getRevisionRecord(): RevisionRecord {
52        return $this->revisionRecord;
53    }
54
55    /** @inheritDoc */
56    public function getIdField() {
57        return 'rev_id';
58    }
59
60    /** @inheritDoc */
61    public function getTimestampField() {
62        return 'rev_timestamp';
63    }
64
65    /** @inheritDoc */
66    public function getAuthorIdField() {
67        return 'rev_user';
68    }
69
70    /** @inheritDoc */
71    public function getAuthorNameField() {
72        return 'rev_user_text';
73    }
74
75    /** @inheritDoc */
76    public function getAuthorActorField() {
77        return 'rev_actor';
78    }
79
80    /** @inheritDoc */
81    public function canView() {
82        return $this->getRevisionRecord()->userCan(
83            RevisionRecord::DELETED_RESTRICTED,
84            $this->list->getAuthority()
85        );
86    }
87
88    /** @inheritDoc */
89    public function canViewContent() {
90        return $this->getRevisionRecord()->userCan(
91            RevisionRecord::DELETED_TEXT,
92            $this->list->getAuthority()
93        );
94    }
95
96    /** @inheritDoc */
97    public function getBits() {
98        return $this->getRevisionRecord()->getVisibility();
99    }
100
101    /** @inheritDoc */
102    public function setBits( $bits ) {
103        $revRecord = $this->getRevisionRecord();
104
105        $dbw = MediaWikiServices::getInstance()->getConnectionProvider()->getPrimaryDatabase();
106        // Update revision table
107        $dbw->newUpdateQueryBuilder()
108            ->update( 'revision' )
109            ->set( [ 'rev_deleted' => $bits ] )
110            ->where( [
111                'rev_id' => $revRecord->getId(),
112                'rev_page' => $revRecord->getPageId(),
113                'rev_deleted' => $this->getBits() // cas
114            ] )
115            ->caller( __METHOD__ )->execute();
116
117        if ( !$dbw->affectedRows() ) {
118            // Concurrent fail!
119            return false;
120        }
121        // Update recentchanges table
122        $dbw->newUpdateQueryBuilder()
123            ->update( 'recentchanges' )
124            ->set( [
125                'rc_deleted' => $bits,
126                'rc_patrolled' => RecentChange::PRC_AUTOPATROLLED
127            ] )
128            ->where( [ 'rc_this_oldid' => $revRecord->getId() ] )
129            ->caller( __METHOD__ )->execute();
130
131        return true;
132    }
133
134    /**
135     * @return bool
136     */
137    public function isDeleted() {
138        return $this->getRevisionRecord()->isDeleted( RevisionRecord::DELETED_TEXT );
139    }
140
141    /** @inheritDoc */
142    public function isHideCurrentOp( $newBits ) {
143        return ( $newBits & RevisionRecord::DELETED_TEXT )
144            && $this->list->getCurrent() == $this->getId();
145    }
146
147    /**
148     * Get the HTML link to the revision text.
149     * Overridden by RevDelArchiveItem.
150     * @return string
151     */
152    protected function getRevisionLink() {
153        $date = $this->list->getLanguage()->userTimeAndDate(
154            $this->getRevisionRecord()->getTimestamp(),
155            $this->list->getUser()
156        );
157
158        if ( $this->isDeleted() && !$this->canViewContent() ) {
159            return htmlspecialchars( $date );
160        }
161
162        return $this->getLinkRenderer()->makeKnownLink(
163            $this->list->getPage(),
164            $date,
165            [],
166            [
167                'oldid' => $this->getRevisionRecord()->getId(),
168                'unhide' => 1
169            ]
170        );
171    }
172
173    /**
174     * Get the HTML link to the diff.
175     * Overridden by RevDelArchiveItem
176     * @return string
177     */
178    protected function getDiffLink() {
179        if ( $this->isDeleted() && !$this->canViewContent() ) {
180            return $this->list->msg( 'diff' )->escaped();
181        } else {
182            return $this->getLinkRenderer()->makeKnownLink(
183                $this->list->getPage(),
184                $this->list->msg( 'diff' )->text(),
185                [],
186                [
187                    'diff' => $this->getRevisionRecord()->getId(),
188                    'oldid' => 'prev',
189                    'unhide' => 1
190                ]
191            );
192        }
193    }
194
195    /**
196     * @return string A HTML <li> element representing this revision, showing
197     * change tags and everything
198     */
199    public function getHTML() {
200        $revRecord = $this->getRevisionRecord();
201
202        $difflink = $this->list->msg( 'parentheses' )
203            ->rawParams( $this->getDiffLink() )->escaped();
204        $revlink = $this->getRevisionLink();
205        $userlink = Linker::revUserLink( $revRecord );
206        $comment = MediaWikiServices::getInstance()->getCommentFormatter()
207            ->formatRevision( $revRecord, $this->list->getAuthority() );
208        if ( $this->isDeleted() ) {
209            $class = Linker::getRevisionDeletedClass( $revRecord );
210            $revlink = "<span class=\"$class\">$revlink</span>";
211        }
212        $content = "$difflink $revlink $userlink $comment";
213        $attribs = [];
214        $tags = $this->getTags();
215        if ( $tags ) {
216            [ $tagSummary, $classes ] = ChangeTags::formatSummaryRow(
217                $tags,
218                'revisiondelete',
219                $this->list->getContext()
220            );
221            $content .= " $tagSummary";
222            $attribs['class'] = $classes;
223        }
224        return Html::rawElement( 'li', $attribs, $content );
225    }
226
227    /**
228     * @return string Comma-separated list of tags
229     */
230    public function getTags() {
231        return $this->row->ts_tags;
232    }
233
234    /** @inheritDoc */
235    public function getApiData( ApiResult $result ) {
236        $revRecord = $this->getRevisionRecord();
237        $authority = $this->list->getAuthority();
238        $ret = [
239            'id' => $revRecord->getId(),
240            'timestamp' => wfTimestamp( TS::ISO_8601, $revRecord->getTimestamp() ),
241            'userhidden' => (bool)$revRecord->isDeleted( RevisionRecord::DELETED_USER ),
242            'commenthidden' => (bool)$revRecord->isDeleted( RevisionRecord::DELETED_COMMENT ),
243            'texthidden' => (bool)$revRecord->isDeleted( RevisionRecord::DELETED_TEXT ),
244        ];
245        if ( $revRecord->userCan( RevisionRecord::DELETED_USER, $authority ) ) {
246            $revUser = $revRecord->getUser( RevisionRecord::FOR_THIS_USER, $authority );
247            $ret += [
248                'userid' => $revUser ? $revUser->getId() : 0,
249                'user' => $revUser ? $revUser->getName() : '',
250            ];
251        }
252        if ( $revRecord->userCan( RevisionRecord::DELETED_COMMENT, $authority ) ) {
253            $revComment = $revRecord->getComment( RevisionRecord::FOR_THIS_USER, $authority );
254            $ret += [
255                'comment' => $revComment ? $revComment->text : ''
256            ];
257        }
258
259        return $ret;
260    }
261}
262
263/** @deprecated class alias since 1.46 */
264class_alias( RevDelRevisionItem::class, 'RevDelRevisionItem' );