80 $pattern =
false, $conds = [], $year =
false, $month =
false, $day =
false,
81 $tagFilter =
'',
$action =
'', $logId = 0
83 parent::__construct( $list->getContext() );
84 $this->mConds = $conds;
86 $this->mLogEventsList = $list;
95 $this->mTagFilter = $tagFilter;
101 $query = parent::getDefaultQuery();
116 foreach ( $filterTypes as
$type => $hide ) {
118 $this->mConds[] =
'log_type != ' . $this->mDb->addQuotes(
$type );
126 if ( count( $this->types ) ) {
130 $wpfilters = $this->
getRequest()->getArray(
"wpfilters" );
131 $request_filters = $wpfilters ===
null ? [] : $wpfilters;
134 $hide = !in_array(
$type, $request_filters );
137 if ( $wpfilters ===
null ) {
138 $hide = $this->
getRequest()->getBool(
"hide_{$type}_log", $default );
141 $filters[
$type] = $hide;
161 $needReindex =
false;
164 && !MediaWikiServices::getInstance()
165 ->getPermissionManager()
172 if ( $needReindex ) {
180 $audience =
$types ?
'user' :
'public';
182 if ( $hideLogs !==
false ) {
183 $this->mConds[] = $hideLogs;
186 $this->mConds[
'log_type'] =
$types;
188 if ( count(
$types ) == 1 ) {
189 $this->typeCGI =
$types[0];
204 $usertitle = Title::makeTitleSafe(
NS_USER, $name );
205 if ( is_null( $usertitle ) ) {
210 $name = $usertitle->getText();
213 $this->mConds[] = ActorMigration::newMigration()->getWhere(
219 $this->performer = $name;
233 if ( $page instanceof
Title ) {
236 $title = Title::newFromText( $page );
237 if ( strlen( $page ) == 0 || !
$title instanceof
Title ) {
246 $doUserRightsLogLike =
false;
247 if ( $this->types == [
'rights' ] ) {
249 if ( count( $parts ) == 2 ) {
250 list( $name, $database ) = array_map(
'trim', $parts );
251 if ( strstr( $database,
'*' ) ) {
252 $doUserRightsLogLike =
true;
270 $this->mConds[
'log_namespace'] = $ns;
271 if ( $doUserRightsLogLike ) {
273 foreach ( explode(
'*', $database ) as $databasepart ) {
274 $params[] = $databasepart;
275 $params[] = $db->anyString();
277 array_pop( $params );
278 $this->mConds[] =
'log_title' . $db->buildLike( ...$params );
280 $this->mConds[] =
'log_title' . $db->buildLike(
$title->
getDBkey(), $db->anyString() );
297 if (
$type ===
'' ) {
302 if ( isset( $actions[
$type] ) ) {
304 $this->mLogEventsList->setAllowedActions( array_keys( $actions[
$type] ) );
321 $this->mConds[
'log_id'] = $logId;
332 $tables = $basic[
'tables'];
333 $fields = $basic[
'fields'];
334 $conds = $basic[
'conds'];
335 $options = $basic[
'options'];
336 $joins = $basic[
'join_conds'];
338 # Add log_search table if there are conditions on it.
339 # This filters the results to only include log rows that have
340 # log_search records with the specified ls_field and ls_value values.
341 if ( array_key_exists(
'ls_field', $this->mConds ) ) {
342 $tables[] =
'log_search';
343 $options[
'IGNORE INDEX'] = [
'log_search' =>
'ls_log_id' ];
344 $options[
'USE INDEX'] = [
'logging' =>
'PRIMARY' ];
348 # Since (ls_field,ls_value,ls_logid) is unique, if the condition is
349 # to match a specific (ls_field,ls_value) tuple, then there will be
350 # no duplicate log rows. Otherwise, we need to remove the duplicates.
351 $options[] =
'DISTINCT';
354 # Don't show duplicate rows when using log_search
355 $joins[
'log_search'] = [
'JOIN',
'ls_log_id=log_id' ];
361 if ( !$this->mTagFilter && !array_key_exists(
'ls_field', $this->mConds ) ) {
362 $options[] =
'STRAIGHT_JOIN';
364 if ( $this->performer !==
'' ) {
367 $options[
'IGNORE INDEX'] = [
'logging' => [
'times' ] ];
373 'conds' => array_merge( $conds, $this->mConds ),
374 'options' => $options,
375 'join_conds' => $joins,
377 # Add ChangeTags filter query
379 $info[
'join_conds'], $info[
'options'], $this->mTagFilter );
391 array_key_exists( $field, $this->mConds ) &&
392 ( !is_array( $this->mConds[$field] ) || count( $this->mConds[$field] ) == 1 )
397 return 'log_timestamp';
401 # Do a link batch query
404 foreach ( $this->mResult as $row ) {
405 $lb->
add( $row->log_namespace, $row->log_title );
406 $lb->addObj( Title::makeTitleSafe(
NS_USER, $row->user_name ) );
407 $lb->addObj( Title::makeTitleSafe(
NS_USER_TALK, $row->user_name ) );
409 foreach ( $formatter->getPreloadTitles() as
$title ) {
414 $this->mResult->seek( 0 );
421 return $this->mLogEventsList->logLine( $row );
473 $this->mDb->setBigSelects();
475 $this->mDb->setBigSelects(
'default' );
482 if ( $this->actionRestrictionsEnforced ) {
485 $this->actionRestrictionsEnforced =
true;
487 $permissionManager = MediaWikiServices::getInstance()->getPermissionManager();
488 if ( !$permissionManager->userHasRight( $user,
'deletedhistory' ) ) {
490 } elseif ( !$permissionManager->userHasAnyRight( $user,
'suppressrevision',
'viewsuppressed' ) ) {
501 if ( $this->performerRestrictionsEnforced ) {
504 $this->performerRestrictionsEnforced =
true;
506 $permissionManager = MediaWikiServices::getInstance()->getPermissionManager();
507 if ( !$permissionManager->userHasRight( $user,
'deletedhistory' ) ) {
509 } elseif ( !$permissionManager->userHasAnyRight( $user,
'suppressrevision',
'viewsuppressed' ) ) {
$wgUserrightsInterwikiDelimiter
Character used as a delimiter when testing for interwiki userrights (In Special:UserRights,...
$wgLogRestrictions
This restricts log access to those who have a certain right Users without this will not see it in the...
$wgActionFilteredLogs
List of log types that can be filtered by action types.
$wgFilterLogTypes
Show/hide links on Special:Log will be shown for these log types.
$wgMiserMode
Disable database-intensive features.
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
static getSelectQueryData()
Returns array of information that is needed for querying log entries.
Class representing a list of titles The execute() method checks them all for existence and adds them ...
static getExcludeClause( $db, $audience='public', User $user=null)
SQL clause to skip forbidden log types for this user.
Represents a title within MediaWiki.
getNamespace()
Get the namespace index, i.e.
getDBkey()
Get the main part with underscores.
getPrefixedText()
Get the prefixed title with spaces.