Passed
Push — main ( da216f...2844ef )
by MusikAnimal
03:21
created

EditCounterRepository::getPairData()   B

Complexity

Conditions 4
Paths 5

Size

Total Lines 97
Code Lines 61

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 61
c 0
b 0
f 0
nc 5
nop 2
dl 0
loc 97
rs 8.8509

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
declare(strict_types = 1);
4
5
namespace App\Repository;
6
7
use App\Model\Project;
8
use App\Model\User;
9
use Doctrine\Persistence\ManagerRegistry;
10
use GuzzleHttp\Client;
11
use Psr\Cache\CacheItemPoolInterface;
12
use Psr\Log\LoggerInterface;
13
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
14
use Wikimedia\IPUtils;
15
16
/**
17
 * An EditCounterRepository is responsible for retrieving edit count information from the
18
 * databases and API. It doesn't do any post-processing of that information.
19
 * @codeCoverageIgnore
20
 */
21
class EditCounterRepository extends Repository
22
{
23
    protected AutoEditsRepository $autoEditsRepo;
24
    protected ProjectRepository $projectRepo;
25
26
    public function __construct(
27
        ManagerRegistry $managerRegistry,
28
        CacheItemPoolInterface $cache,
29
        Client $guzzle,
30
        LoggerInterface $logger,
31
        ParameterBagInterface $parameterBag,
32
        bool $isWMF,
33
        int $queryTimeout,
34
        ProjectRepository $projectRepo,
35
        AutoEditsRepository $autoEditsRepo
36
    ) {
37
        $this->projectRepo = $projectRepo;
38
        $this->autoEditsRepo = $autoEditsRepo;
39
        parent::__construct($managerRegistry, $cache, $guzzle, $logger, $parameterBag, $isWMF, $queryTimeout);
40
    }
41
42
    /**
43
     * Get data about revisions, pages, etc.
44
     * @param Project $project The project.
45
     * @param User $user The user.
46
     * @return string[] With keys: 'deleted', 'live', 'total', '24h', '7d', '30d',
47
     * '365d', 'small', 'large', 'with_comments', and 'minor_edits', ...
48
     */
49
    public function getPairData(Project $project, User $user): array
50
    {
51
        // Set up cache.
52
        $cacheKey = $this->getCacheKey(func_get_args(), 'ec_pairdata');
53
        if ($this->cache->hasItem($cacheKey)) {
54
            return $this->cache->getItem($cacheKey)->get();
55
        }
56
57
        // Prepare the queries and execute them.
58
        $archiveTable = $project->getTableName('archive');
59
        $revisionTable = $project->getTableName('revision');
60
        $pageTable = $project->getTableName('page');
61
62
        // Always JOIN on page, see T355027
63
        $pageJoin = "JOIN $pageTable ON rev_page = page_id";
64
65
        if ($user->isIpRange()) {
66
            $ipcTable = $project->getTableName('ip_changes');
67
            $ipcJoin = "JOIN $ipcTable ON ipc_rev_id = rev_id";
68
            $whereClause = "ipc_hex BETWEEN :startIp AND :endIp";
69
            $archiveQueries = '';
70
            $params = [];
71
            [$params['startIp'], $params['endIp']] = IPUtils::parseRange($user->getUsername());
72
        } else {
73
            $ipcJoin = '';
74
            $whereClause = 'rev_actor = :actorId';
75
            $params = ['actorId' => $user->getActorId($project)];
76
            $archiveQueries = "
77
                SELECT 'deleted' AS `key`, COUNT(ar_id) AS val FROM $archiveTable
78
                    WHERE ar_actor = :actorId
79
                ) UNION (
80
                SELECT 'edited-deleted' AS `key`, COUNT(DISTINCT ar_page_id) AS `val` FROM $archiveTable
81
                    WHERE ar_actor = :actorId
82
                ) UNION (
83
                SELECT 'created-deleted' AS `key`, COUNT(DISTINCT ar_page_id) AS `val` FROM $archiveTable
84
                    WHERE ar_actor = :actorId AND ar_parent_id = 0
85
                ) UNION (";
86
        }
87
88
        $sql = "
89
            ($archiveQueries
90
91
            -- Revision counts.
92
            SELECT 'live' AS `key`, COUNT(rev_id) AS val FROM $revisionTable
93
                $pageJoin
94
                $ipcJoin
95
                WHERE $whereClause
96
            ) UNION (
97
            SELECT 'day' AS `key`, COUNT(rev_id) AS val FROM $revisionTable
98
                $pageJoin
99
                $ipcJoin
100
                WHERE $whereClause AND rev_timestamp >= DATE_SUB(NOW(), INTERVAL 1 DAY)
101
            ) UNION (
102
            SELECT 'week' AS `key`, COUNT(rev_id) AS val FROM $revisionTable
103
                $pageJoin
104
                $ipcJoin
105
                WHERE $whereClause AND rev_timestamp >= DATE_SUB(NOW(), INTERVAL 1 WEEK)
106
            ) UNION (
107
            SELECT 'month' AS `key`, COUNT(rev_id) AS val FROM $revisionTable
108
                $pageJoin
109
                $ipcJoin
110
                WHERE $whereClause AND rev_timestamp >= DATE_SUB(NOW(), INTERVAL 1 MONTH)
111
            ) UNION (
112
            SELECT 'year' AS `key`, COUNT(rev_id) AS val FROM $revisionTable
113
                $pageJoin
114
                $ipcJoin
115
                WHERE $whereClause AND rev_timestamp >= DATE_SUB(NOW(), INTERVAL 1 YEAR)
116
            ) UNION (
117
            SELECT 'minor' AS `key`, COUNT(rev_id) AS val FROM $revisionTable
118
                $pageJoin
119
                $ipcJoin
120
                WHERE $whereClause AND rev_minor_edit = 1
121
122
            -- Page counts.
123
            ) UNION (
124
            SELECT 'edited-live' AS `key`, COUNT(DISTINCT rev_page) AS `val`
125
                FROM $revisionTable
126
                $pageJoin
127
                $ipcJoin
128
                WHERE $whereClause
129
            ) UNION (
130
            SELECT 'created-live' AS `key`, COUNT(DISTINCT rev_page) AS `val`
131
                FROM $revisionTable
132
                $pageJoin
133
                $ipcJoin
134
                WHERE $whereClause AND rev_parent_id = 0
135
            )";
136
137
        $resultQuery = $this->executeProjectsQuery($project, $sql, $params);
138
139
        $revisionCounts = [];
140
        while ($result = $resultQuery->fetchAssociative()) {
141
            $revisionCounts[$result['key']] = (int)$result['val'];
142
        }
143
144
        // Cache and return.
145
        return $this->setCache($cacheKey, $revisionCounts);
146
    }
147
148
    /**
149
     * Get log totals for a user.
150
     * @param Project $project The project.
151
     * @param User $user The user.
152
     * @return int[] Keys are "<log>-<action>" strings, values are counts.
153
     */
154
    public function getLogCounts(Project $project, User $user): array
155
    {
156
        // Set up cache.
157
        $cacheKey = $this->getCacheKey(func_get_args(), 'ec_logcounts');
158
        if ($this->cache->hasItem($cacheKey)) {
159
            return $this->cache->getItem($cacheKey)->get();
160
        }
161
162
        // Query.
163
        $loggingTable = $this->getTableName($project->getDatabaseName(), 'logging');
164
        $sql = "
165
        (SELECT CONCAT(log_type, '-', log_action) AS source, COUNT(log_id) AS value
166
            FROM $loggingTable
167
            WHERE log_actor = :actorId
168
            GROUP BY log_type, log_action
169
        )";
170
171
        $results = $this->executeProjectsQuery($project, $sql, [
172
            'actorId' => $user->getActorId($project),
173
        ])->fetchAllAssociative();
174
175
        $logCounts = array_combine(
176
            array_map(function ($e) {
177
                return $e['source'];
178
            }, $results),
179
            array_map(function ($e) {
180
                return (int)$e['value'];
181
            }, $results)
182
        );
183
184
        // Make sure there is some value for each of the wanted counts.
185
        $requiredCounts = [
186
            'thanks-thank',
187
            'review-approve',
188
            'newusers-create2',
189
            'newusers-byemail',
190
            'patrol-patrol',
191
            'block-block',
192
            'block-reblock',
193
            'block-unblock',
194
            'protect-protect',
195
            'protect-modify',
196
            'protect-unprotect',
197
            'rights-rights',
198
            'move-move',
199
            'delete-delete',
200
            'delete-revision',
201
            'delete-restore',
202
            'import-import',
203
            'import-interwiki',
204
            'import-upload',
205
            'upload-upload',
206
            'upload-overwrite',
207
            'abusefilter-modify',
208
            'merge-merge',
209
            'contentmodel-change',
210
            'contentmodel-new',
211
        ];
212
        foreach ($requiredCounts as $req) {
213
            if (!isset($logCounts[$req])) {
214
                $logCounts[$req] = 0;
215
            }
216
        }
217
218
        // Cache and return.
219
        return $this->setCache($cacheKey, $logCounts);
220
    }
221
222
    /**
223
     * Get counts of files moved, and files moved/uploaded on Commons.
224
     * Local file uploads are counted in getLogCounts() since we're querying the same rows anyway.
225
     * @param Project $project
226
     * @param User $user
227
     * @return array
228
     */
229
    public function getFileCounts(Project $project, User $user): array
230
    {
231
        // Anons can't upload or move files.
232
        if ($user->isAnon()) {
233
            return [];
234
        }
235
236
        // Set up cache.
237
        $cacheKey = $this->getCacheKey(func_get_args(), 'ec_filecounts');
238
        if ($this->cache->hasItem($cacheKey)) {
239
            return $this->cache->getItem($cacheKey)->get();
240
        }
241
242
        $loggingTable = $project->getTableName('logging');
243
244
        $sql = "SELECT 'files_moved' AS `key`, COUNT(log_id) AS `val`
245
                FROM $loggingTable
246
                WHERE log_actor = :actorId
247
                    AND log_type = 'move'
248
                    AND log_action = 'move'
249
                    AND log_namespace = 6";
250
        $results = $this->executeProjectsQuery($project, $sql, [
251
            'actorId' => $user->getActorId($project),
252
        ])->fetchAllAssociative();
253
254
        if ($this->isWMF && 'commons.wikimedia.org' !== $project->getDomain()) {
255
            $results = array_merge($results, $this->getFileCountsCommons($user));
256
        }
257
258
        $counts = array_combine(
259
            array_map(function ($e) {
260
                return $e['key'];
261
            }, $results),
262
            array_map(function ($e) {
263
                return (int)$e['val'];
264
            }, $results)
265
        );
266
267
        // Cache and return.
268
        return $this->setCache($cacheKey, $counts);
269
    }
270
271
    /**
272
     * Get count of files moved and uploaded on Commons.
273
     * @param User $user
274
     * @return array
275
     */
276
    protected function getFileCountsCommons(User $user): array
277
    {
278
        $commonsProject = $this->projectRepo->getProject('commonswiki');
279
        $loggingTableCommons = $commonsProject->getTableName('logging');
280
        $sql = "(SELECT 'files_moved_commons' AS `key`, COUNT(log_id) AS `val`
281
                 FROM $loggingTableCommons
282
                 WHERE log_actor = :actorId AND log_type = 'move'
283
                 AND log_action = 'move' AND log_namespace = 6
284
                ) UNION (
285
                 SELECT 'files_uploaded_commons' AS `key`, COUNT(log_id) AS `val`
286
                 FROM $loggingTableCommons
287
                 WHERE log_actor = :actorId AND log_type = 'upload' AND log_action = 'upload')";
288
        return $this->executeProjectsQuery($commonsProject, $sql, [
289
            'actorId' => $user->getActorId($commonsProject),
290
        ])->fetchAllAssociative();
291
    }
292
293
    /**
294
     * Get the IDs and timestamps of the latest edit and logged action by the given user.
295
     * @param Project $project
296
     * @param User $user
297
     * @return string[] With keys 'rev_first', 'rev_latest', 'log_latest'.
298
     */
299
    public function getFirstAndLatestActions(Project $project, User $user): array
300
    {
301
        $cacheKey = $this->getCacheKey(func_get_args(), 'ec_first_latest_actions');
302
        if ($this->cache->hasItem($cacheKey)) {
303
            return $this->cache->getItem($cacheKey)->get();
304
        }
305
306
        $loggingTable = $project->getTableName('logging', 'userindex');
307
        if ($user->isIpRange()) {
308
            $fromTable = $project->getTableName('ip_changes');
309
            $idColumn = 'ipc_rev_id';
310
            $timestampColumn = 'ipc_rev_timestamp';
311
            $whereClause = "ipc_hex BETWEEN :startIp AND :endIp";
312
            $params = [];
313
            [$params['startIp'], $params['endIp']] = IPUtils::parseRange($user->getUsername());
314
            $logQuery = '';
315
        } else {
316
            $fromTable = $project->getTableName('revision');
317
            $idColumn = 'rev_id';
318
            $timestampColumn = 'rev_timestamp';
319
            $whereClause = 'rev_actor = :actorId';
320
            $params = ['actorId' => $user->getActorId($project)];
321
            $logQuery = "
322
                SELECT 'log_latest' AS `key`, log_id AS `id`,
323
                        log_timestamp AS `timestamp`, log_type AS `type`
324
                    FROM $loggingTable
325
                    WHERE log_actor = :actorId
326
                    ORDER BY log_timestamp DESC LIMIT 1
327
                ) UNION (";
328
        }
329
330
        $sql = "(
331
                $logQuery
332
                    SELECT 'rev_first' AS `key`, $idColumn AS `id`,
333
                        $timestampColumn AS `timestamp`, NULL as `type`
334
                    FROM $fromTable
335
                    WHERE $whereClause
336
                    ORDER BY $timestampColumn ASC LIMIT 1
337
                ) UNION (
338
                    SELECT 'rev_latest' AS `key`, $idColumn AS `id`,
339
                        $timestampColumn AS `timestamp`, NULL as `type`
340
                    FROM $fromTable
341
                    WHERE $whereClause
342
                    ORDER BY $timestampColumn DESC LIMIT 1
343
                )";
344
345
        $resultQuery = $this->executeProjectsQuery($project, $sql, $params);
346
347
        $actions = [];
348
        while ($result = $resultQuery->fetchAssociative()) {
349
            $actions[$result['key']] = [
350
                'id' => $result['id'],
351
                'timestamp' => $result['timestamp'],
352
                'type' => $result['type'],
353
            ];
354
        }
355
356
        return $this->setCache($cacheKey, $actions);
357
    }
358
359
    /**
360
     * Get data for all blocks set on the given user.
361
     * @param Project $project
362
     * @param User $user
363
     * @return array
364
     */
365
    public function getBlocksReceived(Project $project, User $user): array
366
    {
367
        $loggingTable = $this->getTableName($project->getDatabaseName(), 'logging', 'logindex');
368
        $sql = "SELECT log_action, log_timestamp, log_params FROM $loggingTable
369
                WHERE log_type = 'block'
370
                AND log_action IN ('block', 'reblock', 'unblock')
371
                AND log_timestamp > 0
372
                AND log_title = :username
373
                AND log_namespace = 2
374
                ORDER BY log_timestamp ASC";
375
        $username = str_replace(' ', '_', $user->getUsername());
376
377
        return $this->executeProjectsQuery($project, $sql, [
378
            'username' => $username,
379
        ])->fetchAllAssociative();
380
    }
381
382
    /**
383
     * Get the number of times the user was thanked.
384
     * @param Project $project
385
     * @param User $user
386
     * @return int
387
     */
388
    public function getThanksReceived(Project $project, User $user): int
389
    {
390
        $cacheKey = $this->getCacheKey(func_get_args(), 'ec_thanksreceived');
391
        if ($this->cache->hasItem($cacheKey)) {
392
            return $this->cache->getItem($cacheKey)->get();
393
        }
394
395
        $loggingTable = $project->getTableName('logging', 'logindex');
396
        $sql = "SELECT COUNT(log_id)
397
                FROM $loggingTable
398
                WHERE log_type = 'thanks'
399
                AND log_title = :username
400
                AND log_namespace = 2";
401
        $username = str_replace(' ', '_', $user->getUsername());
402
403
        return $this->setCache($cacheKey, (int)$this->executeProjectsQuery($project, $sql, [
0 ignored issues
show
Deprecated Code introduced by
The function Doctrine\DBAL\ForwardCom...y\Result::fetchColumn() has been deprecated: Use fetchOne() instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

403
        return $this->setCache($cacheKey, (int)/** @scrutinizer ignore-deprecated */ $this->executeProjectsQuery($project, $sql, [

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
404
            'username' => $username,
405
        ])->fetchColumn());
406
    }
407
408
    /**
409
     * Get the given user's total edit counts per namespace on the given project.
410
     * @param Project $project The project.
411
     * @param User $user The user.
412
     * @return array Array keys are namespace IDs, values are the edit counts.
413
     */
414
    public function getNamespaceTotals(Project $project, User $user): array
415
    {
416
        // Cache?
417
        $cacheKey = $this->getCacheKey(func_get_args(), 'ec_namespacetotals');
418
        if ($this->cache->hasItem($cacheKey)) {
419
            return $this->cache->getItem($cacheKey)->get();
420
        }
421
422
        // Query.
423
        $revisionTable = $project->getTableName('revision');
424
        $pageTable = $project->getTableName('page');
425
        $ipcJoin = '';
426
        $whereClause = 'r.rev_actor = :actorId';
427
        $params = ['actorId' => $user->getActorId($project)];
428
429
        if ($user->isIpRange()) {
430
            $ipcTable = $project->getTableName('ip_changes');
431
            $ipcJoin = "JOIN $ipcTable ON ipc_rev_id = rev_id";
432
            [$params['startIp'], $params['endIp']] = IPUtils::parseRange($user->getUsername());
433
            $whereClause = 'ipc_hex BETWEEN :startIp AND :endIp';
434
        }
435
436
        $sql = "SELECT page_namespace AS `namespace`, COUNT(rev_id) AS `total`
437
            FROM $pageTable p JOIN $revisionTable r ON (r.rev_page = p.page_id)
438
            $ipcJoin
439
            WHERE $whereClause
440
            GROUP BY `namespace`";
441
442
        $results = $this->executeProjectsQuery($project, $sql, $params)->fetchAll();
0 ignored issues
show
Deprecated Code introduced by
The function Doctrine\DBAL\ForwardCom...lity\Result::fetchAll() has been deprecated: Use fetchAllNumeric(), fetchAllAssociative() or fetchFirstColumn() instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

442
        $results = /** @scrutinizer ignore-deprecated */ $this->executeProjectsQuery($project, $sql, $params)->fetchAll();

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
443
444
        $namespaceTotals = array_combine(array_map(function ($e) {
445
            return $e['namespace'];
446
        }, $results), array_map(function ($e) {
447
            return (int)$e['total'];
448
        }, $results));
449
450
        // Cache and return.
451
        return $this->setCache($cacheKey, $namespaceTotals);
452
    }
453
454
    /**
455
     * Get data for a bar chart of monthly edit totals per namespace.
456
     * @param Project $project The project.
457
     * @param User $user The user.
458
     * @return string[] [
459
     *                      [
460
     *                          'year' => <year>,
461
     *                          'month' => <month>,
462
     *                          'namespace' => <namespace>,
463
     *                          'count' => <count>,
464
     *                      ],
465
     *                      ...
466
     *                  ]
467
     */
468
    public function getMonthCounts(Project $project, User $user): array
469
    {
470
        $cacheKey = $this->getCacheKey(func_get_args(), 'ec_monthcounts');
471
        if ($this->cache->hasItem($cacheKey)) {
472
            return $this->cache->getItem($cacheKey)->get();
473
        }
474
475
        $revisionTable = $project->getTableName('revision');
476
        $pageTable = $project->getTableName('page');
477
        $ipcJoin = '';
478
        $whereClause = 'rev_actor = :actorId';
479
        $params = ['actorId' => $user->getActorId($project)];
480
481
        if ($user->isIpRange()) {
482
            $ipcTable = $project->getTableName('ip_changes');
483
            $ipcJoin = "JOIN $ipcTable ON ipc_rev_id = rev_id";
484
            [$params['startIp'], $params['endIp']] = IPUtils::parseRange($user->getUsername());
485
            $whereClause = 'ipc_hex BETWEEN :startIp AND :endIp';
486
        }
487
488
        $sql = "
489
            SELECT YEAR(rev_timestamp) AS `year`,
490
                MONTH(rev_timestamp) AS `month`,
491
                page_namespace AS `namespace`,
492
                COUNT(rev_id) AS `count`
493
            FROM $revisionTable JOIN $pageTable ON (rev_page = page_id)
494
            $ipcJoin
495
            WHERE $whereClause
496
            GROUP BY YEAR(rev_timestamp), MONTH(rev_timestamp), `namespace`";
497
498
        $totals = $this->executeProjectsQuery($project, $sql, $params)->fetchAll();
0 ignored issues
show
Deprecated Code introduced by
The function Doctrine\DBAL\ForwardCom...lity\Result::fetchAll() has been deprecated: Use fetchAllNumeric(), fetchAllAssociative() or fetchFirstColumn() instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

498
        $totals = /** @scrutinizer ignore-deprecated */ $this->executeProjectsQuery($project, $sql, $params)->fetchAll();

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
499
500
        // Cache and return.
501
        return $this->setCache($cacheKey, $totals);
502
    }
503
504
    /**
505
     * Get data for the timecard chart, with totals grouped by day and to the nearest two-hours.
506
     * @param Project $project
507
     * @param User $user
508
     * @return string[][]
509
     */
510
    public function getTimeCard(Project $project, User $user): array
511
    {
512
        $cacheKey = $this->getCacheKey(func_get_args(), 'ec_timecard');
513
        if ($this->cache->hasItem($cacheKey)) {
514
            return $this->cache->getItem($cacheKey)->get();
515
        }
516
517
        $hourInterval = 1;
518
        $revisionTable = $project->getTableName('revision');
519
        // Always JOIN on page, see T325492
520
        $pageTable = $project->getTableName('page');
521
522
        if ($user->isIpRange()) {
523
            $column = 'ipc_rev_timestamp';
524
            $table = $project->getTableName('ip_changes');
525
            [$params['startIp'], $params['endIp']] = IPUtils::parseRange($user->getUsername());
526
            $whereClause = 'ipc_hex BETWEEN :startIp AND :endIp';
527
            $joinClause = "JOIN $revisionTable ON rev_id = ipc_rev_id
528
                JOIN $pageTable ON rev_page = page_id";
529
        } else {
530
            $column = 'rev_timestamp';
531
            $table = $revisionTable;
532
            $whereClause = 'rev_actor = :actorId';
533
            $params = ['actorId' => $user->getActorId($project)];
534
            $joinClause = "JOIN $pageTable ON rev_page = page_id";
535
        }
536
537
        $xCalc = "ROUND(HOUR($column)/$hourInterval) * $hourInterval";
538
539
        $sql = "
540
            SELECT DAYOFWEEK($column) AS `day_of_week`,
541
                $xCalc AS `hour`,
542
                COUNT($column) AS `value`
543
            FROM $table
544
            $joinClause
545
            WHERE $whereClause
546
            GROUP BY DAYOFWEEK($column), $xCalc";
547
548
        $totals = $this->executeProjectsQuery($project, $sql, $params)->fetchAll();
0 ignored issues
show
Deprecated Code introduced by
The function Doctrine\DBAL\ForwardCom...lity\Result::fetchAll() has been deprecated: Use fetchAllNumeric(), fetchAllAssociative() or fetchFirstColumn() instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

548
        $totals = /** @scrutinizer ignore-deprecated */ $this->executeProjectsQuery($project, $sql, $params)->fetchAll();

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
549
550
        // Cache and return.
551
        return $this->setCache($cacheKey, $totals);
552
    }
553
554
    /**
555
     * Get various data about edit sizes of the past 5,000 edits.
556
     * Will cache the result for 10 minutes.
557
     * @param Project $project The project.
558
     * @param User $user The user.
559
     * @return string[] With keys 'average_size', 'small_edits' and 'large_edits'
560
     */
561
    public function getEditSizeData(Project $project, User $user): array
562
    {
563
        // Set up cache.
564
        $cacheKey = $this->getCacheKey(func_get_args(), 'ec_editsizes');
565
        if ($this->cache->hasItem($cacheKey)) {
566
            return $this->cache->getItem($cacheKey)->get();
567
        }
568
569
        // Prepare the queries and execute them.
570
        $revisionTable = $project->getTableName('revision');
571
        $pageTable = $project->getTableName('page');
572
        $ipcJoin = '';
573
        $whereClause = 'revs.rev_actor = :actorId';
574
        $params = ['actorId' => $user->getActorId($project)];
575
576
        if ($user->isIpRange()) {
577
            $ipcTable = $project->getTableName('ip_changes');
578
            $ipcJoin = "JOIN $ipcTable ON ipc_rev_id = revs.rev_id";
579
            [$params['startIp'], $params['endIp']] = IPUtils::parseRange($user->getUsername());
580
            $whereClause = 'ipc_hex BETWEEN :startIp AND :endIp';
581
        }
582
583
        $sql = "SELECT AVG(sizes.size) AS average_size,
584
                COUNT(CASE WHEN sizes.size < 20 THEN 1 END) AS small_edits,
585
                COUNT(CASE WHEN sizes.size > 1000 THEN 1 END) AS large_edits
586
                FROM (
587
                    SELECT (CAST(revs.rev_len AS SIGNED) - IFNULL(parentrevs.rev_len, 0)) AS size
588
                    FROM $revisionTable AS revs
589
                    JOIN $pageTable ON revs.rev_page = page_id
590
                    $ipcJoin
591
                    LEFT JOIN $revisionTable AS parentrevs ON (revs.rev_parent_id = parentrevs.rev_id)
592
                    WHERE $whereClause
593
                    ORDER BY revs.rev_timestamp DESC
594
                    LIMIT 5000
595
                ) sizes";
596
        $results = $this->executeProjectsQuery($project, $sql, $params)->fetchAssociative();
597
598
        // Cache and return.
599
        return $this->setCache($cacheKey, $results);
600
    }
601
602
    /**
603
     * Get the number of edits this user made using semi-automated tools.
604
     * @param Project $project
605
     * @param User $user
606
     * @return int Result of query, see below.
607
     * @deprecated Inject AutoEditsRepository and call the countAutomatedEdits directly.
608
     */
609
    public function countAutomatedEdits(Project $project, User $user): int
610
    {
611
        return $this->autoEditsRepo->countAutomatedEdits($project, $user);
612
    }
613
}
614