38 parent::__construct( $query, $moduleName,
'le' );
49 $this->commentStore = CommentStore::getStore();
52 $prop = array_flip( $params[
'prop'] );
54 $this->fld_ids = isset( $prop[
'ids'] );
55 $this->fld_title = isset( $prop[
'title'] );
56 $this->fld_type = isset( $prop[
'type'] );
57 $this->fld_user = isset( $prop[
'user'] );
58 $this->fld_userid = isset( $prop[
'userid'] );
59 $this->fld_timestamp = isset( $prop[
'timestamp'] );
60 $this->fld_comment = isset( $prop[
'comment'] );
61 $this->fld_parsedcomment = isset( $prop[
'parsedcomment'] );
62 $this->fld_details = isset( $prop[
'details'] );
63 $this->fld_tags = isset( $prop[
'tags'] );
65 $hideLogs = LogEventsList::getExcludeClause( $db,
'user', $this->
getUser() );
66 if ( $hideLogs !==
false ) {
70 $actorMigration = ActorMigration::newMigration();
71 $actorQuery = $actorMigration->getJoin(
'log_user' );
73 $this->
addTables( $actorQuery[
'tables'] );
77 'user' => [
'LEFT JOIN',
78 'user_id=' . $actorQuery[
'fields'][
'log_user'] ],
79 'page' => [
'LEFT JOIN',
80 [
'log_namespace=page_namespace',
81 'log_title=page_title' ] ] ] );
96 $this->
addFieldsIf( $actorQuery[
'fields'] + [
'user_name' ], $this->fld_user );
97 $this->
addFieldsIf( $actorQuery[
'fields'], $this->fld_userid );
99 [
'log_namespace',
'log_title' ],
100 $this->fld_title || $this->fld_parsedcomment
102 $this->
addFieldsIf(
'log_params', $this->fld_details );
104 if ( $this->fld_comment || $this->fld_parsedcomment ) {
105 $commentQuery = $this->commentStore->getJoin(
'log_comment' );
106 $this->
addTables( $commentQuery[
'tables'] );
107 $this->
addFields( $commentQuery[
'fields'] );
111 if ( $this->fld_tags ) {
115 if ( $params[
'tag'] !==
null ) {
118 [
'log_id=ct_log_id' ] ] ] );
119 $changeTagDefStore = MediaWikiServices::getInstance()->getChangeTagDefStore();
121 $this->
addWhereFld(
'ct_tag_id', $changeTagDefStore->getId( $params[
'tag'] ) );
128 if ( $params[
'action'] !==
null ) {
131 $logAction = $params[
'action'];
132 if ( strpos( $logAction,
'/' ) ===
false ) {
137 list(
$type, $action ) = explode(
'/', $logAction, 2 );
138 $valid = isset( $logActions[$logAction] ) || isset( $logActions[
$type .
'/*'] );
144 [
'apierror-unrecognizedvalue', $encParamName,
wfEscapeWikiText( $logAction ) ],
145 "unknown_$encParamName"
151 } elseif ( $params[
'type'] !==
null ) {
162 $this->
addWhereRange(
'log_id', $params[
'dir'],
null,
null );
164 if ( $params[
'continue'] !==
null ) {
165 $cont = explode(
'|', $params[
'continue'] );
167 $op = ( $params[
'dir'] ===
'newer' ?
'>' :
'<' );
168 $continueTimestamp = $db->addQuotes( $db->timestamp( $cont[0] ) );
169 $continueId = (int)$cont[1];
171 $this->
addWhere(
"log_timestamp $op $continueTimestamp OR " .
172 "(log_timestamp = $continueTimestamp AND " .
173 "log_id $op= $continueId)"
177 $limit = $params[
'limit'];
180 $user = $params[
'user'];
181 if ( $user !==
null ) {
184 $q = $actorMigration->getWhere( $db,
'log_user', $params[
'user'] );
190 $this->
addOption(
'IGNORE INDEX', [
'logging' => [
'times' ] ] );
193 $title = $params[
'title'];
195 $titleObj = Title::newFromText(
$title );
196 if ( $titleObj ===
null ) {
199 $this->
addWhereFld(
'log_namespace', $titleObj->getNamespace() );
200 $this->
addWhereFld(
'log_title', $titleObj->getDBkey() );
203 if ( $params[
'namespace'] !==
null ) {
204 $this->
addWhereFld(
'log_namespace', $params[
'namespace'] );
207 $prefix = $params[
'prefix'];
209 if ( $prefix !==
null ) {
210 if ( $this->
getConfig()->
get(
'MiserMode' ) ) {
214 $title = Title::newFromText( $prefix );
219 $this->
addWhere(
'log_title ' . $db->buildLike(
$title->getDBkey(), $db->anyString() ) );
223 if ( $params[
'namespace'] !==
null ||
$title !==
null || $user !==
null ) {
228 ->userHasAnyRight( $this->
getUser(),
'suppressrevision',
'viewsuppressed' )
236 if ( ( $params[
'namespace'] !==
null ||
$title !==
null ) && $titleBits ) {
237 $this->
addWhere( $db->bitAnd(
'log_deleted', $titleBits ) .
" != $titleBits" );
239 if ( $user !==
null && $userBits ) {
240 $this->
addWhere( $db->bitAnd(
'log_deleted', $userBits ) .
" != $userBits" );
248 if ( $params[
'tag'] ===
null ) {
253 'MAX_EXECUTION_TIME',
254 $this->
getConfig()->
get(
'MaxExecutionTimeForExpensiveQueries' )
260 if ( $this->fld_title ) {
265 foreach (
$res as $row ) {
266 if ( ++$count > $limit ) {
274 $fit = $result->addValue( [
'query', $this->
getModuleName() ],
null, $vals );
280 $result->addIndexedTagName( [
'query', $this->
getModuleName() ],
'item' );
284 $logEntry = DatabaseLogEntry::newFromRow( $row );
286 ApiResult::META_TYPE =>
'assoc',
291 if ( $this->fld_ids ) {
292 $vals[
'logid'] = (int)$row->log_id;
295 if ( $this->fld_title || $this->fld_parsedcomment ) {
296 $title = Title::makeTitle( $row->log_namespace, $row->log_title );
299 if ( $this->fld_title || $this->fld_ids || $this->fld_details && $row->log_params !==
'' ) {
301 $vals[
'actionhidden'] =
true;
305 if ( $this->fld_title ) {
308 if ( $this->fld_ids ) {
309 $vals[
'pageid'] = (int)$row->page_id;
310 $vals[
'logpage'] = (int)$row->log_page;
312 if ( $this->fld_details ) {
318 if ( $this->fld_type ) {
319 $vals[
'type'] = $row->log_type;
320 $vals[
'action'] = $row->log_action;
323 if ( $this->fld_user || $this->fld_userid ) {
325 $vals[
'userhidden'] =
true;
329 if ( $this->fld_user ) {
330 $vals[
'user'] = $row->user_name ?? $row->log_user_text;
332 if ( $this->fld_userid ) {
333 $vals[
'userid'] = (int)$row->log_user;
336 if ( !$row->log_user ) {
337 $vals[
'anon'] =
true;
341 if ( $this->fld_timestamp ) {
342 $vals[
'timestamp'] =
wfTimestamp( TS_ISO_8601, $row->log_timestamp );
345 if ( $this->fld_comment || $this->fld_parsedcomment ) {
347 $vals[
'commenthidden'] =
true;
351 $comment = $this->commentStore->getComment(
'log_comment', $row )->text;
352 if ( $this->fld_comment ) {
353 $vals[
'comment'] = $comment;
356 if ( $this->fld_parsedcomment ) {
362 if ( $this->fld_tags ) {
363 if ( $row->ts_tags ) {
364 $tags = explode(
',', $row->ts_tags );
365 ApiResult::setIndexedTagName( $tags,
'tag' );
366 $vals[
'tags'] = $tags;
373 $vals[
'suppressed'] =
true;
384 return array_keys( array_merge(
385 $config->get(
'LogActions' ),
386 $config->get(
'LogActionsHandlers' )
394 if ( $params[
'prop'] !==
null && in_array(
'parsedcomment', $params[
'prop'] ) ) {
396 return 'anon-public-user-private';
397 } elseif ( LogEventsList::getExcludeClause( $this->
getDB(),
'user', $this->
getUser() )
398 === LogEventsList::getExcludeClause( $this->
getDB(),
'public' )
402 return 'anon-public-user-private';
455 UserDef::PARAM_ALLOWED_USER_TYPES => [
'name',
'ip',
'id',
'interwiki' ],
456 UserDef::PARAM_RETURN_OBJECT =>
true,
477 if ( $config->get(
'MiserMode' ) ) {
486 'action=query&list=logevents'
487 =>
'apihelp-query+logevents-example-simple',
492 return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Logevents';
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
wfEscapeWikiText( $text)
Escapes the given text so that it may be output using addWikiText() without any linking,...
dieWithError( $msg, $code=null, $data=null, $httpCode=0)
Abort execution with an error.
encodeParamName( $paramName)
This method mangles parameter name based on the prefix supplied to the constructor.
dieContinueUsageIf( $condition)
Die with the 'badcontinue' error.
getPermissionManager()
Obtain a PermissionManager instance that subclasses may use in their authorization checks.
const PARAM_HELP_MSG_PER_VALUE
((string|array|Message)[]) When PARAM_TYPE is an array, this is an array mapping those values to $msg...
const LIMIT_BIG1
Fast query, standard limit.
requireMaxOneParameter( $params,... $required)
Die if more than one of a certain set of parameters is set and not false.
getResult()
Get the result object.
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
const PARAM_EXTRA_NAMESPACES
const PARAM_HELP_MSG
(string|array|Message) Specify an alternative i18n documentation message for this parameter.
const GET_VALUES_FOR_HELP
getAllowedParams() flag: When set, the result could take longer to generate, but should be more thoro...
const LIMIT_BIG2
Fast query, apihighlimits limit.
getModuleName()
Get the name of the module being executed by this instance.
This is a base class for all Query modules.
static addTitleInfo(&$arr, $title, $prefix='')
Add information (title and namespace) about a Title object to a result array.
setContinueEnumParameter( $paramName, $paramValue)
Set a query-continue value.
addWhereRange( $field, $dir, $start, $end, $sort=true)
Add a WHERE clause corresponding to a range, and an ORDER BY clause to sort in the right direction.
addFields( $value)
Add a set of fields to select to the internal array.
addOption( $name, $value=null)
Add an option such as LIMIT or USE INDEX.
addTables( $tables, $alias=null)
Add a set of tables to the internal array.
addTimestampWhereRange( $field, $dir, $start, $end, $sort=true)
Add a WHERE clause corresponding to a range, similar to addWhereRange, but converts $start and $end t...
getDB()
Get the Query database connection (read-only) Stable to override.
executeGenderCacheFromResultWrapper(IResultWrapper $res, $fname=__METHOD__, $fieldPrefix='page')
Preprocess the result set to fill the GenderCache with the necessary information before using self::a...
select( $method, $extraQuery=[], array &$hookData=null)
Execute a SELECT query based on the values in the internal arrays.
addFieldsIf( $value, $condition)
Same as addFields(), but add the fields only if a condition is met.
addJoinConds( $join_conds)
Add a set of JOIN conditions to the internal array.
addWhereFld( $field, $value)
Equivalent to addWhere( [ $field => $value ] )
addWhere( $value)
Add a set of WHERE clauses to the internal array.
userCanSeeRevDel()
Check whether the current user has permission to view revision-deleted fields.
Query action to List the log events, with optional filtering by various parameters.
CommentStore $commentStore
getExamplesMessages()
Returns usage examples for this module.
execute()
Evaluates the parameters, performs the requested query, and sets up the result.
getAllowedParams( $flags=0)
__construct(ApiQuery $query, $moduleName)
getCacheMode( $params)
Get the cache mode for the data generated by this module.
getHelpUrls()
Return links to more detailed help pages about the module.
This is the main query class.
getUser()
Stable to override.
static formatComment( $comment, $title=null, $local=false, $wikiId=null)
This function is called by all recent changes variants, by the page history, and by the user contribu...
static validTypes()
Get the list of valid log types.