]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blob - includes/logging/DeleteLogFormatter.php
MediaWiki 1.30.2
[autoinstallsdev/mediawiki.git] / includes / logging / DeleteLogFormatter.php
1 <?php
2 /**
3  * Formatter for delete 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 http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
23  * @since 1.22
24  */
25
26 use MediaWiki\MediaWikiServices;
27
28 /**
29  * This class formats delete log entries.
30  *
31  * @since 1.19
32  */
33 class DeleteLogFormatter extends LogFormatter {
34         protected function getMessageKey() {
35                 $key = parent::getMessageKey();
36                 if ( in_array( $this->entry->getSubtype(), [ 'event', 'revision' ] ) ) {
37                         if ( count( $this->getMessageParameters() ) < 5 ) {
38                                 // Messages: logentry-delete-event-legacy, logentry-delete-revision-legacy,
39                                 // logentry-suppress-event-legacy, logentry-suppress-revision-legacy
40                                 return "$key-legacy";
41                         }
42                 } elseif ( $this->entry->getSubtype() === 'restore' ) {
43                         $rawParams = $this->entry->getParameters();
44                         if ( !isset( $rawParams[':assoc:count'] ) ) {
45                                 // Message: logentry-delete-restore-nocount
46                                 return $key . '-nocount';
47                         }
48                 }
49
50                 return $key;
51         }
52
53         protected function getMessageParameters() {
54                 if ( isset( $this->parsedParametersDeleteLog ) ) {
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] )
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                                 list( $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 ) {
126                 // Input is like ofield=2134 or just the number
127                 if ( strpos( $string, 'field=' ) === 1 ) {
128                         list( , $field ) = explode( '=', $string );
129
130                         return (int)$field;
131                 } else {
132                         return (int)$string;
133                 }
134         }
135
136         public function getActionLinks() {
137                 $user = $this->context->getUser();
138                 $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
139                 if ( !$user->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                                 if ( $user->isAllowed( 'undelete' ) ) {
149                                         $message = 'undeletelink';
150                                 } else {
151                                         $message = 'undeleteviewlink';
152                                 }
153                                 $revert = $linkRenderer->makeKnownLink(
154                                         SpecialPage::getTitleFor( 'Undelete' ),
155                                         $this->msg( $message )->text(),
156                                         [],
157                                         [ 'target' => $this->entry->getTarget()->getPrefixedDBkey() ]
158                                 );
159
160                                 return $this->msg( 'parentheses' )->rawParams( $revert )->escaped();
161
162                         case 'revision': // If an edit was hidden from a page give a review link to the history
163                                 $params = $this->extractParameters();
164                                 if ( !isset( $params[3] ) || !isset( $params[4] ) ) {
165                                         return '';
166                                 }
167
168                                 // Different revision types use different URL params...
169                                 $key = $params[3];
170                                 // This is a array or CSV of the IDs
171                                 $ids = is_array( $params[4] )
172                                         ? $params[4]
173                                         : explode( ',', $params[4] );
174
175                                 $links = [];
176
177                                 // If there's only one item, we can show a diff link
178                                 if ( count( $ids ) == 1 ) {
179                                         // Live revision diffs...
180                                         if ( $key == 'oldid' || $key == 'revision' ) {
181                                                 $links[] = $linkRenderer->makeKnownLink(
182                                                         $this->entry->getTarget(),
183                                                         $this->msg( 'diff' )->text(),
184                                                         [],
185                                                         [
186                                                                 'diff' => intval( $ids[0] ),
187                                                                 'unhide' => 1
188                                                         ]
189                                                 );
190                                                 // Deleted revision diffs...
191                                         } elseif ( $key == 'artimestamp' || $key == 'archive' ) {
192                                                 $links[] = $linkRenderer->makeKnownLink(
193                                                         SpecialPage::getTitleFor( 'Undelete' ),
194                                                         $this->msg( 'diff' )->text(),
195                                                         [],
196                                                         [
197                                                                 'target' => $this->entry->getTarget()->getPrefixedDBkey(),
198                                                                 'diff' => 'prev',
199                                                                 'timestamp' => $ids[0]
200                                                         ]
201                                                 );
202                                         }
203                                 }
204
205                                 // View/modify link...
206                                 $links[] = $linkRenderer->makeKnownLink(
207                                         SpecialPage::getTitleFor( 'Revisiondelete' ),
208                                         $this->msg( 'revdel-restore' )->text(),
209                                         [],
210                                         [
211                                                 'target' => $this->entry->getTarget()->getPrefixedText(),
212                                                 'type' => $key,
213                                                 'ids' => implode( ',', $ids ),
214                                         ]
215                                 );
216
217                                 return $this->msg( 'parentheses' )->rawParams(
218                                         $this->context->getLanguage()->pipeList( $links ) )->escaped();
219
220                         case 'event': // Hidden log items, give review link
221                                 $params = $this->extractParameters();
222                                 if ( !isset( $params[3] ) ) {
223                                         return '';
224                                 }
225                                 // This is a CSV of the IDs
226                                 $query = $params[3];
227                                 if ( is_array( $query ) ) {
228                                         $query = implode( ',', $query );
229                                 }
230                                 // Link to each hidden object ID, $params[1] is the url param
231                                 $revert = $linkRenderer->makeKnownLink(
232                                         SpecialPage::getTitleFor( 'Revisiondelete' ),
233                                         $this->msg( 'revdel-restore' )->text(),
234                                         [],
235                                         [
236                                                 'target' => $this->entry->getTarget()->getPrefixedText(),
237                                                 'type' => 'logging',
238                                                 'ids' => $query
239                                         ]
240                                 );
241
242                                 return $this->msg( 'parentheses' )->rawParams( $revert )->escaped();
243                         default:
244                                 return '';
245                 }
246         }
247
248         protected function getParametersForApi() {
249                 $entry = $this->entry;
250                 $params = [];
251
252                 $subtype = $this->entry->getSubtype();
253                 if ( in_array( $subtype, [ 'event', 'revision' ] ) ) {
254                         $rawParams = $entry->getParameters();
255                         if ( $subtype === 'event' ) {
256                                 array_unshift( $rawParams, 'logging' );
257                         }
258
259                         static $map = [
260                                 '4::type',
261                                 '5::ids',
262                                 '6::ofield',
263                                 '7::nfield',
264                                 '4::ids' => '5::ids',
265                                 '5::ofield' => '6::ofield',
266                                 '6::nfield' => '7::nfield',
267                         ];
268                         foreach ( $map as $index => $key ) {
269                                 if ( isset( $rawParams[$index] ) ) {
270                                         $rawParams[$key] = $rawParams[$index];
271                                         unset( $rawParams[$index] );
272                                 }
273                         }
274
275                         $old = $this->parseBitField( $rawParams['6::ofield'] );
276                         $new = $this->parseBitField( $rawParams['7::nfield'] );
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                                 ':assoc:old' => [ 'bitmask' => $old ],
285                                 ':assoc:new' => [ 'bitmask' => $new ],
286                         ];
287
288                         static $fields = [
289                                 Revision::DELETED_TEXT => 'content',
290                                 Revision::DELETED_COMMENT => 'comment',
291                                 Revision::DELETED_USER => 'user',
292                                 Revision::DELETED_RESTRICTED => 'restricted',
293                         ];
294                         foreach ( $fields as $bit => $key ) {
295                                 $params[':assoc:old'][$key] = (bool)( $old & $bit );
296                                 $params[':assoc:new'][$key] = (bool)( $new & $bit );
297                         }
298                 } elseif ( $subtype === 'restore' ) {
299                         $rawParams = $entry->getParameters();
300                         if ( isset( $rawParams[':assoc:count'] ) ) {
301                                 $params[':assoc:count'] = $rawParams[':assoc:count'];
302                         }
303                 }
304
305                 return $params;
306         }
307
308         public function formatParametersForApi() {
309                 $ret = parent::formatParametersForApi();
310                 if ( isset( $ret['ids'] ) ) {
311                         ApiResult::setIndexedTagName( $ret['ids'], 'id' );
312                 }
313                 return $ret;
314         }
315 }