ApiQueryLogEvents::getAllowedParams()   A
last analyzed

Complexity

Conditions 3
Paths 4

Size

Total Lines 70
Code Lines 52

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 52
nc 4
nop 1
dl 0
loc 70
rs 9.1724
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 *
4
 *
5
 * Created on Oct 16, 2006
6
 *
7
 * Copyright © 2006 Yuri Astrakhan "<Firstname><Lastname>@gmail.com"
8
 *
9
 * This program is free software; you can redistribute it and/or modify
10
 * it under the terms of the GNU General Public License as published by
11
 * the Free Software Foundation; either version 2 of the License, or
12
 * (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License along
20
 * with this program; if not, write to the Free Software Foundation, Inc.,
21
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22
 * http://www.gnu.org/copyleft/gpl.html
23
 *
24
 * @file
25
 */
26
27
/**
28
 * Query action to List the log events, with optional filtering by various parameters.
29
 *
30
 * @ingroup API
31
 */
32
class ApiQueryLogEvents extends ApiQueryBase {
33
34
	public function __construct( ApiQuery $query, $moduleName ) {
35
		parent::__construct( $query, $moduleName, 'le' );
36
	}
37
38
	private $fld_ids = false, $fld_title = false, $fld_type = false,
0 ignored issues
show
Coding Style introduced by
It is generally advisable to only define one property per statement.

Only declaring a single property per statement allows you to later on add doc comments more easily.

It is also recommended by PSR2, so it is a common style that many people expect.

Loading history...
39
		$fld_user = false, $fld_userid = false,
40
		$fld_timestamp = false, $fld_comment = false, $fld_parsedcomment = false,
41
		$fld_details = false, $fld_tags = false;
42
43
	public function execute() {
44
		$params = $this->extractRequestParams();
45
		$db = $this->getDB();
46
		$this->requireMaxOneParameter( $params, 'title', 'prefix', 'namespace' );
47
48
		$prop = array_flip( $params['prop'] );
49
50
		$this->fld_ids = isset( $prop['ids'] );
51
		$this->fld_title = isset( $prop['title'] );
52
		$this->fld_type = isset( $prop['type'] );
53
		$this->fld_user = isset( $prop['user'] );
54
		$this->fld_userid = isset( $prop['userid'] );
55
		$this->fld_timestamp = isset( $prop['timestamp'] );
56
		$this->fld_comment = isset( $prop['comment'] );
57
		$this->fld_parsedcomment = isset( $prop['parsedcomment'] );
58
		$this->fld_details = isset( $prop['details'] );
59
		$this->fld_tags = isset( $prop['tags'] );
60
61
		$hideLogs = LogEventsList::getExcludeClause( $db, 'user', $this->getUser() );
62
		if ( $hideLogs !== false ) {
63
			$this->addWhere( $hideLogs );
64
		}
65
66
		// Order is significant here
67
		$this->addTables( [ 'logging', 'user', 'page' ] );
68
		$this->addJoinConds( [
69
			'user' => [ 'LEFT JOIN',
70
				'user_id=log_user' ],
71
			'page' => [ 'LEFT JOIN',
72
				[ 'log_namespace=page_namespace',
73
					'log_title=page_title' ] ] ] );
74
75
		$this->addFields( [
76
			'log_id',
77
			'log_type',
78
			'log_action',
79
			'log_timestamp',
80
			'log_deleted',
81
		] );
82
83
		$this->addFieldsIf( 'page_id', $this->fld_ids );
84
		// log_page is the page_id saved at log time, whereas page_id is from a
85
		// join at query time.  This leads to different results in various
86
		// scenarios, e.g. deletion, recreation.
87
		$this->addFieldsIf( 'log_page', $this->fld_ids );
88
		$this->addFieldsIf( [ 'log_user', 'log_user_text', 'user_name' ], $this->fld_user );
89
		$this->addFieldsIf( 'log_user', $this->fld_userid );
90
		$this->addFieldsIf(
91
			[ 'log_namespace', 'log_title' ],
92
			$this->fld_title || $this->fld_parsedcomment
93
		);
94
		$this->addFieldsIf( 'log_comment', $this->fld_comment || $this->fld_parsedcomment );
95
		$this->addFieldsIf( 'log_params', $this->fld_details );
96
97 View Code Duplication
		if ( $this->fld_tags ) {
98
			$this->addTables( 'tag_summary' );
99
			$this->addJoinConds( [ 'tag_summary' => [ 'LEFT JOIN', 'log_id=ts_log_id' ] ] );
100
			$this->addFields( 'ts_tags' );
101
		}
102
103 View Code Duplication
		if ( !is_null( $params['tag'] ) ) {
104
			$this->addTables( 'change_tag' );
105
			$this->addJoinConds( [ 'change_tag' => [ 'INNER JOIN',
106
				[ 'log_id=ct_log_id' ] ] ] );
107
			$this->addWhereFld( 'ct_tag', $params['tag'] );
108
		}
109
110
		if ( !is_null( $params['action'] ) ) {
111
			// Do validation of action param, list of allowed actions can contains wildcards
112
			// Allow the param, when the actions is in the list or a wildcard version is listed.
113
			$logAction = $params['action'];
114
			if ( strpos( $logAction, '/' ) === false ) {
115
				// all items in the list have a slash
116
				$valid = false;
117
			} else {
118
				$logActions = array_flip( $this->getAllowedLogActions() );
119
				list( $type, $action ) = explode( '/', $logAction, 2 );
120
				$valid = isset( $logActions[$logAction] ) || isset( $logActions[$type . '/*'] );
121
			}
122
123
			if ( !$valid ) {
124
				$valueName = $this->encodeParamName( 'action' );
125
				$this->dieUsage(
126
					"Unrecognized value for parameter '$valueName': {$logAction}",
127
					"unknown_$valueName"
128
				);
129
			}
130
131
			$this->addWhereFld( 'log_type', $type );
0 ignored issues
show
Bug introduced by
The variable $type does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
132
			$this->addWhereFld( 'log_action', $action );
0 ignored issues
show
Bug introduced by
The variable $action does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
133
		} elseif ( !is_null( $params['type'] ) ) {
134
			$this->addWhereFld( 'log_type', $params['type'] );
135
		}
136
137
		$this->addTimestampWhereRange(
138
			'log_timestamp',
139
			$params['dir'],
140
			$params['start'],
141
			$params['end']
142
		);
143
		// Include in ORDER BY for uniqueness
144
		$this->addWhereRange( 'log_id', $params['dir'], null, null );
145
146
		if ( !is_null( $params['continue'] ) ) {
147
			$cont = explode( '|', $params['continue'] );
148
			$this->dieContinueUsageIf( count( $cont ) != 2 );
149
			$op = ( $params['dir'] === 'newer' ? '>' : '<' );
150
			$continueTimestamp = $db->addQuotes( $db->timestamp( $cont[0] ) );
151
			$continueId = (int)$cont[1];
152
			$this->dieContinueUsageIf( $continueId != $cont[1] );
153
			$this->addWhere( "log_timestamp $op $continueTimestamp OR " .
154
				"(log_timestamp = $continueTimestamp AND " .
155
				"log_id $op= $continueId)"
156
			);
157
		}
158
159
		$limit = $params['limit'];
160
		$this->addOption( 'LIMIT', $limit + 1 );
161
162
		$user = $params['user'];
163
		if ( !is_null( $user ) ) {
164
			$userid = User::idFromName( $user );
165
			if ( $userid ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $userid of type integer|null is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
166
				$this->addWhereFld( 'log_user', $userid );
167
			} else {
168
				$this->addWhereFld( 'log_user_text', $user );
169
			}
170
		}
171
172
		$title = $params['title'];
173
		if ( !is_null( $title ) ) {
174
			$titleObj = Title::newFromText( $title );
175
			if ( is_null( $titleObj ) ) {
176
				$this->dieUsage( "Bad title value '$title'", 'param_title' );
177
			}
178
			$this->addWhereFld( 'log_namespace', $titleObj->getNamespace() );
179
			$this->addWhereFld( 'log_title', $titleObj->getDBkey() );
180
		}
181
182
		if ( $params['namespace'] !== null ) {
183
			$this->addWhereFld( 'log_namespace', $params['namespace'] );
184
		}
185
186
		$prefix = $params['prefix'];
187
188
		if ( !is_null( $prefix ) ) {
189
			if ( $this->getConfig()->get( 'MiserMode' ) ) {
190
				$this->dieUsage( 'Prefix search disabled in Miser Mode', 'prefixsearchdisabled' );
191
			}
192
193
			$title = Title::newFromText( $prefix );
194
			if ( is_null( $title ) ) {
195
				$this->dieUsage( "Bad title value '$prefix'", 'param_prefix' );
196
			}
197
			$this->addWhereFld( 'log_namespace', $title->getNamespace() );
198
			$this->addWhere( 'log_title ' . $db->buildLike( $title->getDBkey(), $db->anyString() ) );
199
		}
200
201
		// Paranoia: avoid brute force searches (bug 17342)
202
		if ( $params['namespace'] !== null || !is_null( $title ) || !is_null( $user ) ) {
203
			if ( !$this->getUser()->isAllowed( 'deletedhistory' ) ) {
204
				$titleBits = LogPage::DELETED_ACTION;
205
				$userBits = LogPage::DELETED_USER;
206
			} elseif ( !$this->getUser()->isAllowedAny( 'suppressrevision', 'viewsuppressed' ) ) {
207
				$titleBits = LogPage::DELETED_ACTION | LogPage::DELETED_RESTRICTED;
208
				$userBits = LogPage::DELETED_USER | LogPage::DELETED_RESTRICTED;
209
			} else {
210
				$titleBits = 0;
211
				$userBits = 0;
212
			}
213
			if ( ( $params['namespace'] !== null || !is_null( $title ) ) && $titleBits ) {
214
				$this->addWhere( $db->bitAnd( 'log_deleted', $titleBits ) . " != $titleBits" );
215
			}
216
			if ( !is_null( $user ) && $userBits ) {
217
				$this->addWhere( $db->bitAnd( 'log_deleted', $userBits ) . " != $userBits" );
218
			}
219
		}
220
221
		$count = 0;
222
		$res = $this->select( __METHOD__ );
223
		$result = $this->getResult();
224 View Code Duplication
		foreach ( $res as $row ) {
225
			if ( ++$count > $limit ) {
226
				// We've reached the one extra which shows that there are
227
				// additional pages to be had. Stop here...
228
				$this->setContinueEnumParameter( 'continue', "$row->log_timestamp|$row->log_id" );
229
				break;
230
			}
231
232
			$vals = $this->extractRowInfo( $row );
233
			$fit = $result->addValue( [ 'query', $this->getModuleName() ], null, $vals );
234
			if ( !$fit ) {
235
				$this->setContinueEnumParameter( 'continue', "$row->log_timestamp|$row->log_id" );
236
				break;
237
			}
238
		}
239
		$result->addIndexedTagName( [ 'query', $this->getModuleName() ], 'item' );
240
	}
241
242
	/**
243
	 * @deprecated since 1.25 Use LogFormatter::formatParametersForApi instead
244
	 * @param ApiResult $result
245
	 * @param array $vals
246
	 * @param string $params
247
	 * @param string $type
248
	 * @param string $action
249
	 * @param string $ts
250
	 * @param bool $legacy
251
	 * @return array
252
	 */
253
	public static function addLogParams( $result, &$vals, $params, $type,
254
		$action, $ts, $legacy = false
255
	) {
256
		wfDeprecated( __METHOD__, '1.25' );
257
258
		$entry = new ManualLogEntry( $type, $action );
259
		$entry->setParameters( $params );
260
		$entry->setTimestamp( $ts );
261
		$entry->setLegacy( $legacy );
262
		$formatter = LogFormatter::newFromEntry( $entry );
263
		$vals['params'] = $formatter->formatParametersForApi();
264
265
		return $vals;
266
	}
267
268
	private function extractRowInfo( $row ) {
269
		$logEntry = DatabaseLogEntry::newFromRow( $row );
270
		$vals = [
271
			ApiResult::META_TYPE => 'assoc',
272
		];
273
		$anyHidden = false;
274
		$user = $this->getUser();
275
276
		if ( $this->fld_ids ) {
277
			$vals['logid'] = intval( $row->log_id );
278
		}
279
280
		if ( $this->fld_title || $this->fld_parsedcomment ) {
281
			$title = Title::makeTitle( $row->log_namespace, $row->log_title );
282
		}
283
284
		if ( $this->fld_title || $this->fld_ids || $this->fld_details && $row->log_params !== '' ) {
285 View Code Duplication
			if ( LogEventsList::isDeleted( $row, LogPage::DELETED_ACTION ) ) {
286
				$vals['actionhidden'] = true;
287
				$anyHidden = true;
288
			}
289
			if ( LogEventsList::userCan( $row, LogPage::DELETED_ACTION, $user ) ) {
290
				if ( $this->fld_title ) {
291
					ApiQueryBase::addTitleInfo( $vals, $title );
0 ignored issues
show
Bug introduced by
The variable $title does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
292
				}
293
				if ( $this->fld_ids ) {
294
					$vals['pageid'] = intval( $row->page_id );
295
					$vals['logpage'] = intval( $row->log_page );
296
				}
297
				if ( $this->fld_details ) {
298
					$vals['params'] = LogFormatter::newFromEntry( $logEntry )->formatParametersForApi();
299
				}
300
			}
301
		}
302
303
		if ( $this->fld_type ) {
304
			$vals['type'] = $row->log_type;
305
			$vals['action'] = $row->log_action;
306
		}
307
308
		if ( $this->fld_user || $this->fld_userid ) {
309 View Code Duplication
			if ( LogEventsList::isDeleted( $row, LogPage::DELETED_USER ) ) {
310
				$vals['userhidden'] = true;
311
				$anyHidden = true;
312
			}
313
			if ( LogEventsList::userCan( $row, LogPage::DELETED_USER, $user ) ) {
314
				if ( $this->fld_user ) {
315
					$vals['user'] = $row->user_name === null ? $row->log_user_text : $row->user_name;
316
				}
317
				if ( $this->fld_userid ) {
318
					$vals['userid'] = intval( $row->log_user );
319
				}
320
321
				if ( !$row->log_user ) {
322
					$vals['anon'] = true;
323
				}
324
			}
325
		}
326
		if ( $this->fld_timestamp ) {
327
			$vals['timestamp'] = wfTimestamp( TS_ISO_8601, $row->log_timestamp );
328
		}
329
330
		if ( ( $this->fld_comment || $this->fld_parsedcomment ) && isset( $row->log_comment ) ) {
331 View Code Duplication
			if ( LogEventsList::isDeleted( $row, LogPage::DELETED_COMMENT ) ) {
332
				$vals['commenthidden'] = true;
333
				$anyHidden = true;
334
			}
335
			if ( LogEventsList::userCan( $row, LogPage::DELETED_COMMENT, $user ) ) {
336
				if ( $this->fld_comment ) {
337
					$vals['comment'] = $row->log_comment;
338
				}
339
340
				if ( $this->fld_parsedcomment ) {
341
					$vals['parsedcomment'] = Linker::formatComment( $row->log_comment, $title );
342
				}
343
			}
344
		}
345
346 View Code Duplication
		if ( $this->fld_tags ) {
347
			if ( $row->ts_tags ) {
348
				$tags = explode( ',', $row->ts_tags );
349
				ApiResult::setIndexedTagName( $tags, 'tag' );
350
				$vals['tags'] = $tags;
351
			} else {
352
				$vals['tags'] = [];
353
			}
354
		}
355
356
		if ( $anyHidden && LogEventsList::isDeleted( $row, LogPage::DELETED_RESTRICTED ) ) {
357
			$vals['suppressed'] = true;
358
		}
359
360
		return $vals;
361
	}
362
363
	/**
364
	 * @return array
365
	 */
366
	private function getAllowedLogActions() {
367
		$config = $this->getConfig();
368
		return array_keys( array_merge(
369
			$config->get( 'LogActions' ),
370
			$config->get( 'LogActionsHandlers' )
371
		) );
372
	}
373
374
	public function getCacheMode( $params ) {
375
		if ( $this->userCanSeeRevDel() ) {
376
			return 'private';
377
		}
378
		if ( !is_null( $params['prop'] ) && in_array( 'parsedcomment', $params['prop'] ) ) {
379
			// formatComment() calls wfMessage() among other things
380
			return 'anon-public-user-private';
381
		} elseif ( LogEventsList::getExcludeClause( $this->getDB(), 'user', $this->getUser() )
382
			=== LogEventsList::getExcludeClause( $this->getDB(), 'public' )
383
		) { // Output can only contain public data.
384
			return 'public';
385
		} else {
386
			return 'anon-public-user-private';
387
		}
388
	}
389
390
	public function getAllowedParams( $flags = 0 ) {
391
		$config = $this->getConfig();
392
		$ret = [
393
			'prop' => [
394
				ApiBase::PARAM_ISMULTI => true,
395
				ApiBase::PARAM_DFLT => 'ids|title|type|user|timestamp|comment|details',
396
				ApiBase::PARAM_TYPE => [
397
					'ids',
398
					'title',
399
					'type',
400
					'user',
401
					'userid',
402
					'timestamp',
403
					'comment',
404
					'parsedcomment',
405
					'details',
406
					'tags'
407
				],
408
				ApiBase::PARAM_HELP_MSG_PER_VALUE => [],
409
			],
410
			'type' => [
411
				ApiBase::PARAM_TYPE => $config->get( 'LogTypes' )
412
			],
413
			'action' => [
414
				// validation on request is done in execute()
415
				ApiBase::PARAM_TYPE => ( $flags & ApiBase::GET_VALUES_FOR_HELP )
416
					? $this->getAllowedLogActions()
417
					: null
418
			],
419
			'start' => [
420
				ApiBase::PARAM_TYPE => 'timestamp'
421
			],
422
			'end' => [
423
				ApiBase::PARAM_TYPE => 'timestamp'
424
			],
425
			'dir' => [
426
				ApiBase::PARAM_DFLT => 'older',
427
				ApiBase::PARAM_TYPE => [
428
					'newer',
429
					'older'
430
				],
431
				ApiBase::PARAM_HELP_MSG => 'api-help-param-direction',
432
			],
433
			'user' => [
434
				ApiBase::PARAM_TYPE => 'user',
435
			],
436
			'title' => null,
437
			'namespace' => [
438
				ApiBase::PARAM_TYPE => 'namespace'
439
			],
440
			'prefix' => [],
441
			'tag' => null,
442
			'limit' => [
443
				ApiBase::PARAM_DFLT => 10,
444
				ApiBase::PARAM_TYPE => 'limit',
445
				ApiBase::PARAM_MIN => 1,
446
				ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
447
				ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
448
			],
449
			'continue' => [
450
				ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
451
			],
452
		];
453
454
		if ( $config->get( 'MiserMode' ) ) {
455
			$ret['prefix'][ApiBase::PARAM_HELP_MSG] = 'api-help-param-disabled-in-miser-mode';
456
		}
457
458
		return $ret;
459
	}
460
461
	protected function getExamplesMessages() {
462
		return [
463
			'action=query&list=logevents'
464
				=> 'apihelp-query+logevents-example-simple',
465
		];
466
	}
467
468
	public function getHelpUrls() {
469
		return 'https://www.mediawiki.org/wiki/API:Logevents';
470
	}
471
}
472