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