Split logging classes to individual files
[lhc/web/wiklou.git] / includes / logging / DatabaseLogEntry.php
1 <?php
2 /**
3 * Contains a class for dealing with database log entries
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * http://www.gnu.org/copyleft/gpl.html
19 *
20 * @file
21 * @author Niklas Laxström
22 * @license GPL-2.0-or-later
23 * @since 1.19
24 */
25
26 use Wikimedia\Rdbms\IDatabase;
27
28 /**
29 * A value class to process existing log entries. In other words, this class caches a log
30 * entry from the database and provides an immutable object-oriented representation of it.
31 *
32 * @since 1.19
33 */
34 class DatabaseLogEntry extends LogEntryBase {
35
36 /**
37 * Returns array of information that is needed for querying
38 * log entries. Array contains the following keys:
39 * tables, fields, conds, options and join_conds
40 *
41 * @return array
42 */
43 public static function getSelectQueryData() {
44 $commentQuery = CommentStore::getStore()->getJoin( 'log_comment' );
45 $actorQuery = ActorMigration::newMigration()->getJoin( 'log_user' );
46
47 $tables = array_merge(
48 [ 'logging' ], $commentQuery['tables'], $actorQuery['tables'], [ 'user' ]
49 );
50 $fields = [
51 'log_id', 'log_type', 'log_action', 'log_timestamp',
52 'log_namespace', 'log_title', // unused log_page
53 'log_params', 'log_deleted',
54 'user_id', 'user_name', 'user_editcount',
55 ] + $commentQuery['fields'] + $actorQuery['fields'];
56
57 $joins = [
58 // IPs don't have an entry in user table
59 'user' => [ 'LEFT JOIN', 'user_id=' . $actorQuery['fields']['log_user'] ],
60 ] + $commentQuery['joins'] + $actorQuery['joins'];
61
62 return [
63 'tables' => $tables,
64 'fields' => $fields,
65 'conds' => [],
66 'options' => [],
67 'join_conds' => $joins,
68 ];
69 }
70
71 /**
72 * Constructs new LogEntry from database result row.
73 * Supports rows from both logging and recentchanges table.
74 *
75 * @param stdClass|array $row
76 * @return DatabaseLogEntry
77 */
78 public static function newFromRow( $row ) {
79 $row = (object)$row;
80 if ( isset( $row->rc_logid ) ) {
81 return new RCDatabaseLogEntry( $row );
82 } else {
83 return new self( $row );
84 }
85 }
86
87 /**
88 * Loads a LogEntry with the given id from database
89 *
90 * @param int $id
91 * @param IDatabase $db
92 * @return DatabaseLogEntry|null
93 */
94 public static function newFromId( $id, IDatabase $db ) {
95 $queryInfo = self::getSelectQueryData();
96 $queryInfo['conds'] += [ 'log_id' => $id ];
97 $row = $db->selectRow(
98 $queryInfo['tables'],
99 $queryInfo['fields'],
100 $queryInfo['conds'],
101 __METHOD__,
102 $queryInfo['options'],
103 $queryInfo['join_conds']
104 );
105 if ( !$row ) {
106 return null;
107 }
108 return self::newFromRow( $row );
109 }
110
111 /** @var stdClass Database result row. */
112 protected $row;
113
114 /** @var User */
115 protected $performer;
116
117 /** @var array Parameters for log entry */
118 protected $params;
119
120 /** @var int A rev id associated to the log entry */
121 protected $revId = null;
122
123 /** @var bool Whether the parameters for this log entry are stored in new or old format. */
124 protected $legacy;
125
126 protected function __construct( $row ) {
127 $this->row = $row;
128 }
129
130 /**
131 * Returns the unique database id.
132 *
133 * @return int
134 */
135 public function getId() {
136 return (int)$this->row->log_id;
137 }
138
139 /**
140 * Returns whatever is stored in the database field.
141 *
142 * @return string
143 */
144 protected function getRawParameters() {
145 return $this->row->log_params;
146 }
147
148 public function isLegacy() {
149 // This extracts the property
150 $this->getParameters();
151 return $this->legacy;
152 }
153
154 public function getType() {
155 return $this->row->log_type;
156 }
157
158 public function getSubtype() {
159 return $this->row->log_action;
160 }
161
162 public function getParameters() {
163 if ( !isset( $this->params ) ) {
164 $blob = $this->getRawParameters();
165 Wikimedia\suppressWarnings();
166 $params = LogEntryBase::extractParams( $blob );
167 Wikimedia\restoreWarnings();
168 if ( $params !== false ) {
169 $this->params = $params;
170 $this->legacy = false;
171 } else {
172 $this->params = LogPage::extractParams( $blob );
173 $this->legacy = true;
174 }
175
176 if ( isset( $this->params['associated_rev_id'] ) ) {
177 $this->revId = $this->params['associated_rev_id'];
178 unset( $this->params['associated_rev_id'] );
179 }
180 }
181
182 return $this->params;
183 }
184
185 public function getAssociatedRevId() {
186 // This extracts the property
187 $this->getParameters();
188 return $this->revId;
189 }
190
191 public function getPerformer() {
192 if ( !$this->performer ) {
193 $actorId = isset( $this->row->log_actor ) ? (int)$this->row->log_actor : 0;
194 $userId = (int)$this->row->log_user;
195 if ( $userId !== 0 || $actorId !== 0 ) {
196 // logged-in users
197 if ( isset( $this->row->user_name ) ) {
198 $this->performer = User::newFromRow( $this->row );
199 } elseif ( $actorId !== 0 ) {
200 $this->performer = User::newFromActorId( $actorId );
201 } else {
202 $this->performer = User::newFromId( $userId );
203 }
204 } else {
205 // IP users
206 $userText = $this->row->log_user_text;
207 $this->performer = User::newFromName( $userText, false );
208 }
209 }
210
211 return $this->performer;
212 }
213
214 public function getTarget() {
215 $namespace = $this->row->log_namespace;
216 $page = $this->row->log_title;
217 return Title::makeTitle( $namespace, $page );
218 }
219
220 public function getTimestamp() {
221 return wfTimestamp( TS_MW, $this->row->log_timestamp );
222 }
223
224 public function getComment() {
225 return CommentStore::getStore()->getComment( 'log_comment', $this->row )->text;
226 }
227
228 public function getDeleted() {
229 return $this->row->log_deleted;
230 }
231 }