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     * @return RevisionRecord
60     */
61    protected function getRevisionRecord(): RevisionRecord {
62        return $this->revisionRecord;
63    }
64
65    public function getIdField() {
66        return 'rev_id';
67    }
68
69    public function getTimestampField() {
70        return 'rev_timestamp';
71    }
72
73    public function getAuthorIdField() {
74        return 'rev_user';
75    }
76
77    public function getAuthorNameField() {
78        return 'rev_user_text';
79    }
80
81    public function getAuthorActorField() {
82        return 'rev_actor';
83    }
84
85    public function canView() {
86        return $this->getRevisionRecord()->userCan(
87            RevisionRecord::DELETED_RESTRICTED,
88            $this->list->getAuthority()
89        );
90    }
91
92    public function canViewContent() {
93        return $this->getRevisionRecord()->userCan(
94            RevisionRecord::DELETED_TEXT,
95            $this->list->getAuthority()
96        );
97    }
98
99    public function getBits() {
100        return $this->getRevisionRecord()->getVisibility();
101    }
102
103    public function setBits( $bits ) {
104        $revRecord = $this->getRevisionRecord();
105
106        $dbw = MediaWikiServices::getInstance()->getConnectionProvider()->getPrimaryDatabase();
107        // Update revision table
108        $dbw->newUpdateQueryBuilder()
109            ->update( 'revision' )
110            ->set( [ 'rev_deleted' => $bits ] )
111            ->where( [
112                'rev_id' => $revRecord->getId(),
113                'rev_page' => $revRecord->getPageId(),
114                'rev_deleted' => $this->getBits() // cas
115            ] )
116            ->caller( __METHOD__ )->execute();
117
118        if ( !$dbw->affectedRows() ) {
119            // Concurrent fail!
120            return false;
121        }
122        // Update recentchanges table
123        $dbw->newUpdateQueryBuilder()
124            ->update( 'recentchanges' )
125            ->set( [
126                'rc_deleted' => $bits,
127                'rc_patrolled' => RecentChange::PRC_AUTOPATROLLED
128            ] )
129            ->where( [ 'rc_this_oldid' => $revRecord->getId() ] )
130            ->caller( __METHOD__ )->execute();
131
132        return true;
133    }
134
135    public function isDeleted() {
136        return $this->getRevisionRecord()->isDeleted( RevisionRecord::DELETED_TEXT );
137    }
138
139    public function isHideCurrentOp( $newBits ) {
140        return ( $newBits & RevisionRecord::DELETED_TEXT )
141            && $this->list->getCurrent() == $this->getId();
142    }
143
144    /**
145     * Get the HTML link to the revision text.
146     * Overridden by RevDelArchiveItem.
147     * @return string
148     */
149    protected function getRevisionLink() {
150        $date = $this->list->getLanguage()->userTimeAndDate(
151            $this->getRevisionRecord()->getTimestamp(),
152            $this->list->getUser()
153        );
154
155        if ( $this->isDeleted() && !$this->canViewContent() ) {
156            return htmlspecialchars( $date );
157        }
158
159        return $this->getLinkRenderer()->makeKnownLink(
160            $this->list->getPage(),
161            $date,
162            [],
163            [
164                'oldid' => $this->getRevisionRecord()->getId(),
165                'unhide' => 1
166            ]
167        );
168    }
169
170    /**
171     * Get the HTML link to the diff.
172     * Overridden by RevDelArchiveItem
173     * @return string
174     */
175    protected function getDiffLink() {
176        if ( $this->isDeleted() && !$this->canViewContent() ) {
177            return $this->list->msg( 'diff' )->escaped();
178        } else {
179            return $this->getLinkRenderer()->makeKnownLink(
180                $this->list->getPage(),
181                $this->list->msg( 'diff' )->text(),
182                [],
183                [
184                    'diff' => $this->getRevisionRecord()->getId(),
185                    'oldid' => 'prev',
186                    'unhide' => 1
187                ]
188            );
189        }
190    }
191
192    /**
193     * @return string A HTML <li> element representing this revision, showing
194     * change tags and everything
195     */
196    public function getHTML() {
197        $revRecord = $this->getRevisionRecord();
198
199        $difflink = $this->list->msg( 'parentheses' )
200            ->rawParams( $this->getDiffLink() )->escaped();
201        $revlink = $this->getRevisionLink();
202        $userlink = Linker::revUserLink( $revRecord );
203        $comment = MediaWikiServices::getInstance()->getCommentFormatter()
204            ->formatRevision( $revRecord, $this->list->getAuthority() );
205        if ( $this->isDeleted() ) {
206            $class = Linker::getRevisionDeletedClass( $revRecord );
207            $revlink = "<span class=\"$class\">$revlink</span>";
208        }
209        $content = "$difflink $revlink $userlink $comment";
210        $attribs = [];
211        $tags = $this->getTags();
212        if ( $tags ) {
213            [ $tagSummary, $classes ] = ChangeTags::formatSummaryRow(
214                $tags,
215                'revisiondelete',
216                $this->list->getContext()
217            );
218            $content .= " $tagSummary";
219            $attribs['class'] = implode( ' ', $classes );
220        }
221        return Xml::tags( 'li', $attribs, $content );
222    }
223
224    /**
225     * @return string Comma-separated list of tags
226     */
227    public function getTags() {
228        return $this->row->ts_tags;
229    }
230
231    public function getApiData( ApiResult $result ) {
232        $revRecord = $this->getRevisionRecord();
233        $authority = $this->list->getAuthority();
234        $ret = [
235            'id' => $revRecord->getId(),
236            'timestamp' => wfTimestamp( TS_ISO_8601, $revRecord->getTimestamp() ),
237            'userhidden' => (bool)$revRecord->isDeleted( RevisionRecord::DELETED_USER ),
238            'commenthidden' => (bool)$revRecord->isDeleted( RevisionRecord::DELETED_COMMENT ),
239            'texthidden' => (bool)$revRecord->isDeleted( RevisionRecord::DELETED_TEXT ),
240        ];
241        if ( $revRecord->userCan( RevisionRecord::DELETED_USER, $authority ) ) {
242            $revUser = $revRecord->getUser( RevisionRecord::FOR_THIS_USER, $authority );
243            $ret += [
244                'userid' => $revUser ? $revUser->getId() : 0,
245                'user' => $revUser ? $revUser->getName() : '',
246            ];
247        }
248        if ( $revRecord->userCan( RevisionRecord::DELETED_COMMENT, $authority ) ) {
249            $revComment = $revRecord->getComment( RevisionRecord::FOR_THIS_USER, $authority );
250            $ret += [
251                'comment' => $revComment ? $revComment->text : ''
252            ];
253        }
254
255        return $ret;
256    }
257}