MediaWiki master
DeleteLogFormatter.php
Go to the documentation of this file.
1<?php
12namespace MediaWiki\Logging;
13
18
26 private $parsedParametersDeleteLog;
27
31 protected function getMessageKey() {
32 $key = parent::getMessageKey();
33 if ( in_array( $this->entry->getSubtype(), [ 'event', 'revision' ] ) ) {
34 if ( count( $this->getMessageParameters() ) < 5 ) {
35 // Messages: logentry-delete-event-legacy, logentry-delete-revision-legacy,
36 // logentry-suppress-event-legacy, logentry-suppress-revision-legacy
37 return "$key-legacy";
38 }
39 } elseif ( $this->entry->getSubtype() === 'restore' ) {
40 $rawParams = $this->entry->getParameters();
41 if ( !isset( $rawParams[':assoc:count'] ) ) {
42 // Message: logentry-delete-restore-nocount
43 return $key . '-nocount';
44 }
45 }
46
47 return $key;
48 }
49
53 protected function getMessageParameters() {
54 if ( $this->parsedParametersDeleteLog !== null ) {
55 return $this->parsedParametersDeleteLog;
56 }
57
58 $params = parent::getMessageParameters();
59 $subtype = $this->entry->getSubtype();
60 if ( in_array( $subtype, [ 'event', 'revision' ] ) ) {
61 // $params[3] here is 'revision' or 'archive' for page revisions, 'oldimage' or
62 // 'filearchive' for file versions, or a comma-separated list of log_ids for log
63 // entries. $subtype here is 'revision' for page revisions and file
64 // versions, or 'event' for log entries.
65 if (
66 ( $subtype === 'event' && count( $params ) === 6 )
67 || (
68 $subtype === 'revision' && isset( $params[3] ) && count( $params ) === 7
69 && in_array( $params[3], [ 'revision', 'archive', 'oldimage', 'filearchive' ] )
70 )
71 ) {
72 // See RevDelList::getLogParams()/RevDelLogList::getLogParams()
73 $paramStart = $subtype === 'revision' ? 4 : 3;
74
75 $old = $this->parseBitField( $params[$paramStart + 1] );
76 $new = $this->parseBitField( $params[$paramStart + 2] );
77 [ $hid, $unhid, $extra ] = RevisionDeleter::getChanges( $new, $old );
78 $changes = [];
79 // messages used: revdelete-content-hid, revdelete-summary-hid, revdelete-uname-hid
80 foreach ( $hid as $v ) {
81 $changes[] = $this->msg( "$v-hid" )->plain();
82 }
83 // messages used: revdelete-content-unhid, revdelete-summary-unhid,
84 // revdelete-uname-unhid
85 foreach ( $unhid as $v ) {
86 $changes[] = $this->msg( "$v-unhid" )->plain();
87 }
88 foreach ( $extra as $v ) {
89 $changes[] = $this->msg( $v )->plain();
90 }
91 $changeText = $this->context->getLanguage()->listToText( $changes );
92
93 $newParams = array_slice( $params, 0, 3 );
94 $newParams[3] = $changeText;
95 $ids = is_array( $params[$paramStart] )
96 ? $params[$paramStart]
97 : explode( ',', $params[$paramStart] );
98 $newParams[4] = $this->context->getLanguage()->formatNum( count( $ids ) );
99
100 $this->parsedParametersDeleteLog = $newParams;
101 return $this->parsedParametersDeleteLog;
102 } else {
103 $this->parsedParametersDeleteLog = array_slice( $params, 0, 3 );
104 return $this->parsedParametersDeleteLog;
105 }
106 } elseif ( $subtype === 'restore' ) {
107 $rawParams = $this->entry->getParameters();
108 if ( isset( $rawParams[':assoc:count'] ) ) {
109 $countList = [];
110 foreach ( $rawParams[':assoc:count'] as $type => $count ) {
111 if ( $count ) {
112 // Messages: restore-count-revisions, restore-count-files
113 $countList[] = $this->context->msg( 'restore-count-' . $type )
114 ->numParams( $count )->plain();
115 }
116 }
117 $params[3] = $this->context->getLanguage()->listToText( $countList );
118 }
119 }
120
121 $this->parsedParametersDeleteLog = $params;
122 return $this->parsedParametersDeleteLog;
123 }
124
125 protected function parseBitField( string $string ): int {
126 // Input is like ofield=2134 or just the number
127 if ( strpos( $string, 'field=' ) === 1 ) {
128 [ , $field ] = explode( '=', $string );
129
130 return (int)$field;
131 } else {
132 return (int)$string;
133 }
134 }
135
137 public function getActionLinks() {
138 $linkRenderer = $this->getLinkRenderer();
139 if ( !$this->context->getAuthority()->isAllowed( 'deletedhistory' )
140 || $this->entry->isDeleted( LogPage::DELETED_ACTION )
141 ) {
142 return '';
143 }
144
145 switch ( $this->entry->getSubtype() ) {
146 case 'delete': // Show undelete link
147 case 'delete_redir':
148 case 'delete_redir2':
149 if ( $this->context->getAuthority()->isAllowed( 'undelete' ) ) {
150 $message = 'undeletelink';
151 } else {
152 $message = 'undeleteviewlink';
153 }
154 $revert = $linkRenderer->makeKnownLink(
155 SpecialPage::getTitleFor( 'Undelete' ),
156 $this->msg( $message )->text(),
157 [],
158 [ 'target' => $this->entry->getTarget()->getPrefixedDBkey() ]
159 );
160
161 return $this->msg( 'parentheses' )->rawParams( $revert )->escaped();
162
163 case 'revision': // If an edit was hidden from a page give a review link to the history
164 $params = $this->extractParameters();
165 if ( !isset( $params[3] ) || !isset( $params[4] ) ) {
166 return '';
167 }
168
169 // Different revision types use different URL params...
170 $key = $params[3];
171 // This is a array or CSV of the IDs
172 $ids = is_array( $params[4] )
173 ? $params[4]
174 : explode( ',', $params[4] );
175
176 $links = [];
177
178 // If there's only one item, we can show a diff link
179 if ( count( $ids ) == 1 ) {
180 // Live revision diffs...
181 if ( $key == 'oldid' || $key == 'revision' ) {
182 $links[] = $linkRenderer->makeKnownLink(
183 $this->entry->getTarget(),
184 $this->msg( 'diff' )->text(),
185 [],
186 [
187 'diff' => intval( $ids[0] ),
188 'unhide' => 1
189 ]
190 );
191 // Deleted revision diffs...
192 } elseif ( $key == 'artimestamp' || $key == 'archive' ) {
193 $links[] = $linkRenderer->makeKnownLink(
194 SpecialPage::getTitleFor( 'Undelete' ),
195 $this->msg( 'diff' )->text(),
196 [],
197 [
198 'target' => $this->entry->getTarget()->getPrefixedDBkey(),
199 'diff' => 'prev',
200 'timestamp' => $ids[0]
201 ]
202 );
203 }
204 }
205
206 // View/modify link...
207 $links[] = $linkRenderer->makeKnownLink(
208 SpecialPage::getTitleFor( 'Revisiondelete' ),
209 $this->msg( 'revdel-restore' )->text(),
210 [],
211 [
212 'target' => $this->entry->getTarget()->getPrefixedText(),
213 'type' => $key,
214 'ids' => implode( ',', $ids ),
215 ]
216 );
217
218 return $this->msg( 'parentheses' )->rawParams(
219 $this->context->getLanguage()->pipeList( $links ) )->escaped();
220
221 case 'event': // Hidden log items, give review link
222 $params = $this->extractParameters();
223 if ( !isset( $params[3] ) ) {
224 return '';
225 }
226 // This is a CSV of the IDs
227 $query = $params[3];
228 if ( is_array( $query ) ) {
229 $query = implode( ',', $query );
230 }
231 // Link to each hidden object ID, $params[1] is the url param
232 $revert = $linkRenderer->makeKnownLink(
233 SpecialPage::getTitleFor( 'Revisiondelete' ),
234 $this->msg( 'revdel-restore' )->text(),
235 [],
236 [
237 'target' => $this->entry->getTarget()->getPrefixedText(),
238 'type' => 'logging',
239 'ids' => $query
240 ]
241 );
242
243 return $this->msg( 'parentheses' )->rawParams( $revert )->escaped();
244 default:
245 return '';
246 }
247 }
248
250 protected function getParametersForApi() {
251 $entry = $this->entry;
252 $params = [];
253
254 $subtype = $this->entry->getSubtype();
255 if ( in_array( $subtype, [ 'event', 'revision' ] ) ) {
256 $rawParams = $entry->getParameters();
257 if ( $subtype === 'event' ) {
258 array_unshift( $rawParams, 'logging' );
259 }
260
261 static $map = [
262 '4::type',
263 '5::ids',
264 '6::ofield',
265 '7::nfield',
266 '4::ids' => '5::ids',
267 '5::ofield' => '6::ofield',
268 '6::nfield' => '7::nfield',
269 ];
270 foreach ( $map as $index => $key ) {
271 if ( isset( $rawParams[$index] ) ) {
272 $rawParams[$key] = $rawParams[$index];
273 unset( $rawParams[$index] );
274 }
275 }
276
277 if ( !is_array( $rawParams['5::ids'] ) ) {
278 $rawParams['5::ids'] = explode( ',', $rawParams['5::ids'] );
279 }
280
281 $params = [
282 '::type' => $rawParams['4::type'],
283 ':array:ids' => $rawParams['5::ids'],
284 ];
285
286 static $fields = [
287 RevisionRecord::DELETED_TEXT => 'content',
288 RevisionRecord::DELETED_COMMENT => 'comment',
289 RevisionRecord::DELETED_USER => 'user',
290 RevisionRecord::DELETED_RESTRICTED => 'restricted',
291 ];
292
293 if ( isset( $rawParams['6::ofield'] ) ) {
294 $old = $this->parseBitField( $rawParams['6::ofield'] );
295 $params[':assoc:old'] = [ 'bitmask' => $old ];
296 foreach ( $fields as $bit => $key ) {
297 $params[':assoc:old'][$key] = (bool)( $old & $bit );
298 }
299 }
300 if ( isset( $rawParams['7::nfield'] ) ) {
301 $new = $this->parseBitField( $rawParams['7::nfield'] );
302 $params[':assoc:new'] = [ 'bitmask' => $new ];
303 foreach ( $fields as $bit => $key ) {
304 $params[':assoc:new'][$key] = (bool)( $new & $bit );
305 }
306 }
307 } elseif ( $subtype === 'restore' ) {
308 $rawParams = $entry->getParameters();
309 if ( isset( $rawParams[':assoc:count'] ) ) {
310 $params[':assoc:count'] = $rawParams[':assoc:count'];
311 }
312 }
313
314 return $params;
315 }
316
318 public function formatParametersForApi() {
319 $ret = parent::formatParametersForApi();
320 if ( isset( $ret['ids'] ) ) {
321 ApiResult::setIndexedTagName( $ret['ids'], 'id' );
322 }
323 return $ret;
324 }
325}
326
328class_alias( DeleteLogFormatter::class, 'DeleteLogFormatter' );
if(!defined('MW_SETUP_CALLBACK'))
Definition WebStart.php:69
This class represents the result of the API operations.
Definition ApiResult.php:34
This class formats delete log entries.
getMessageParameters()
Formats parameters intended for action message from array of all parameters.There are three hardcoded...
getMessageKey()
Returns a key to be used for formatting the action sentence.Default is logentry-TYPE-SUBTYPE for mode...
getParametersForApi()
Get the array of parameters, converted from legacy format if necessary.1.25 to override array
getActionLinks()
Returns extra links that comes after the action text, like "revert", etc.to override string
formatParametersForApi()
Format parameters for API output.The result array should generally map named keys to values....
Implements the default log formatting.
msg( $key,... $params)
Shortcut for wfMessage which honors local context.
General controller for RevDel, used by both SpecialRevisiondelete and ApiRevisionDelete.
Page revision base class.
Parent class for all special pages.
static getTitleFor( $name, $subpage=false, $fragment='')
Get a localised Title object for a specified special page name If you don't need a full Title object,...