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