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