Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
20 / 20
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
AbuseLogLookup
100.00% covered (success)
100.00%
20 / 20
100.00% covered (success)
100.00%
2 / 2
6
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getHitCountsForUsers
100.00% covered (success)
100.00%
19 / 19
100.00% covered (success)
100.00%
1 / 1
5
1<?php
2
3namespace MediaWiki\Extension\AbuseFilter;
4
5use MediaWiki\Permissions\Authority;
6use Wikimedia\Rdbms\IConnectionProvider;
7
8/**
9 * A service to help with lookups to the abuse log. Currently, it only allows the caller to ask
10 * for the total number of log entries triggered by a specific user.
11 *
12 * @since 1.47
13 */
14class AbuseLogLookup {
15
16    public const string SERVICE_NAME = ServiceNames::AbuseLogLookup;
17
18    public function __construct(
19        private readonly IConnectionProvider $dbProvider,
20        private readonly AbuseFilterPermissionManager $afPermissionManager,
21    ) {
22    }
23
24    /**
25     * Fetches the number of abuse log entries triggered by the users and viewable by the specified authority.
26     *
27     * @param Authority $authority
28     * @param int[] $userIds
29     * @return array<int,int> Map of user ID => hit count. All requested keys will be present in this array
30     *     (i.e. user with no hits will have explicit zero), provided that the authority has permissions to
31     *     view the abuse log.
32     */
33    public function getHitCountsForUsers( Authority $authority, array $userIds ): array {
34        if ( !$this->afPermissionManager->canViewAbuseLog( $authority ) ) {
35            return [];
36        }
37
38        $canSeeHidden = $this->afPermissionManager->canSeeHiddenLogEntries( $authority );
39        $dbr = $this->dbProvider->getReplicaDatabase();
40
41        $counts = array_fill_keys( $userIds, 0 );
42        foreach ( array_chunk( $userIds, 100 ) as $userIdBatch ) {
43            $queryBuilder = $dbr->newSelectQueryBuilder()
44                ->select( [ 'afl_user', 'count' => 'COUNT(*)' ] )
45                ->from( 'abuse_filter_log' )
46                ->where( [
47                    'afl_user' => $userIdBatch
48                ] )
49                ->groupBy( 'afl_user' )
50                ->caller( __METHOD__ );
51
52            // Suppressed (hidden) entries are only counted for viewers allowed to see them
53            if ( !$canSeeHidden ) {
54                $queryBuilder->andWhere( [ 'afl_deleted' => 0 ] );
55            }
56
57            foreach ( $queryBuilder->fetchResultSet() as $row ) {
58                $counts[(int)$row->afl_user] = (int)$row->count;
59            }
60        }
61
62        return $counts;
63    }
64}