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\Revision\RevisionRecord;
23
24/**
25 * Item class for a logging table row
26 */
27class RevDelLogItem extends RevDelItem {
28
29	/** @var CommentStore */
30	private $commentStore;
31
32	/**
33	 * @param RevisionListBase $list
34	 * @param stdClass $row DB result row
35	 * @param CommentStore $commentStore
36	 */
37	public function __construct(
38		RevisionListBase $list,
39		$row,
40		CommentStore $commentStore
41	) {
42		parent::__construct( $list, $row );
43		$this->commentStore = $commentStore;
44	}
45
46	public function getIdField() {
47		return 'log_id';
48	}
49
50	public function getTimestampField() {
51		return 'log_timestamp';
52	}
53
54	public function getAuthorIdField() {
55		return 'log_user';
56	}
57
58	public function getAuthorNameField() {
59		return 'log_user_text';
60	}
61
62	public function getAuthorActorField() {
63		return 'log_actor';
64	}
65
66	public function canView() {
67		return LogEventsList::userCan(
68			$this->row, RevisionRecord::DELETED_RESTRICTED, $this->list->getUser()
69		);
70	}
71
72	public function canViewContent() {
73		return true; // none
74	}
75
76	public function getBits() {
77		return (int)$this->row->log_deleted;
78	}
79
80	public function setBits( $bits ) {
81		$dbw = wfGetDB( DB_PRIMARY );
82
83		$dbw->update( 'logging',
84			[ 'log_deleted' => $bits ],
85			[
86				'log_id' => $this->row->log_id,
87				'log_deleted' => $this->getBits() // cas
88			],
89			__METHOD__
90		);
91
92		if ( !$dbw->affectedRows() ) {
93			// Concurrent fail!
94			return false;
95		}
96
97		$dbw->update( 'recentchanges',
98			[
99				'rc_deleted' => $bits,
100				'rc_patrolled' => RecentChange::PRC_AUTOPATROLLED
101			],
102			[
103				'rc_logid' => $this->row->log_id,
104				'rc_timestamp' => $this->row->log_timestamp // index
105			],
106			__METHOD__
107		);
108
109		return true;
110	}
111
112	public function getHTML() {
113		$date = htmlspecialchars( $this->list->getLanguage()->userTimeAndDate(
114			$this->row->log_timestamp, $this->list->getUser() ) );
115		$title = Title::makeTitle( $this->row->log_namespace, $this->row->log_title );
116		$formatter = LogFormatter::newFromRow( $this->row );
117		$formatter->setContext( $this->list->getContext() );
118		$formatter->setAudience( LogFormatter::FOR_THIS_USER );
119
120		// Log link for this page
121		$loglink = $this->getLinkRenderer()->makeLink(
122			SpecialPage::getTitleFor( 'Log' ),
123			$this->list->msg( 'log' )->text(),
124			[],
125			[ 'page' => $title->getPrefixedText() ]
126		);
127		$loglink = $this->list->msg( 'parentheses' )->rawParams( $loglink )->escaped();
128		// User links and action text
129		$action = $formatter->getActionText();
130
131		$comment = $this->commentStore->getComment( 'log_comment', $this->row )->text;
132		$comment = $this->list->getLanguage()->getDirMark()
133			. Linker::commentBlock( $comment );
134
135		if ( LogEventsList::isDeleted( $this->row, LogPage::DELETED_COMMENT ) ) {
136			$comment = '<span class="history-deleted">' . $comment . '</span>';
137		}
138
139		return "<li>$loglink $date $action $comment</li>";
140	}
141
142	public function getApiData( ApiResult $result ) {
143		$logEntry = DatabaseLogEntry::newFromRow( $this->row );
144		$user = $this->list->getUser();
145		$ret = [
146			'id' => $logEntry->getId(),
147			'type' => $logEntry->getType(),
148			'action' => $logEntry->getSubtype(),
149			'userhidden' => (bool)$logEntry->isDeleted( LogPage::DELETED_USER ),
150			'commenthidden' => (bool)$logEntry->isDeleted( LogPage::DELETED_COMMENT ),
151			'actionhidden' => (bool)$logEntry->isDeleted( LogPage::DELETED_ACTION ),
152		];
153
154		if ( LogEventsList::userCan( $this->row, LogPage::DELETED_ACTION, $user ) ) {
155			$ret['params'] = LogFormatter::newFromEntry( $logEntry )->formatParametersForApi();
156		}
157		if ( LogEventsList::userCan( $this->row, LogPage::DELETED_USER, $user ) ) {
158			$ret += [
159				'userid' => $this->row->log_user ?? 0,
160				'user' => $this->row->log_user_text,
161			];
162		}
163		if ( LogEventsList::userCan( $this->row, LogPage::DELETED_COMMENT, $user ) ) {
164			$ret += [
165				'comment' => $this->commentStore->getComment( 'log_comment', $this->row )->text,
166			];
167		}
168
169		return $ret;
170	}
171}
172