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