Passed
Pull Request — main (#442)
by MusikAnimal
07:52 queued 03:55
created

EditSummary::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 18
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 8
nc 1
nop 8
dl 0
loc 18
rs 10
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
declare(strict_types = 1);
4
5
namespace App\Model;
6
7
use App\Helper\I18nHelper;
8
use App\Repository\EditSummaryRepository;
9
use DateTime;
10
11
/**
12
 * An EditSummary provides statistics about a user's edit summary usage over time.
13
 */
14
class EditSummary extends Model
15
{
16
    protected I18nHelper $i18n;
17
18
    /** @var int Number of edits from present to consider as 'recent'. */
19
    protected int $numEditsRecent;
20
21
    /**
22
     * Counts of summaries, raw edits, and per-month breakdown.
23
     * Keys are underscored because this also is served in the API.
24
     * @var array
25
     */
26
    protected array $data = [
27
        'recent_edits_minor' => 0,
28
        'recent_edits_major' => 0,
29
        'total_edits_minor' => 0,
30
        'total_edits_major' => 0,
31
        'total_edits' => 0,
32
        'recent_summaries_minor' => 0,
33
        'recent_summaries_major' => 0,
34
        'total_summaries_minor' => 0,
35
        'total_summaries_major' => 0,
36
        'total_summaries' => 0,
37
        'month_counts' => [],
38
    ];
39
40
    /**
41
     * EditSummary constructor.
42
     *
43
     * @param EditSummaryRepository $repository
44
     * @param Project $project The project we're working with.
45
     * @param User $user The user to process.
46
     * @param I18nHelper $i18n
47
     * @param int|string $namespace Namespace ID or 'all' for all namespaces.
48
     * @param int|false $start Start date as Unix timestamp.
49
     * @param int|false $end End date as Unix timestamp.
50
     * @param int $numEditsRecent Number of edits from present to consider as 'recent'.
51
     */
52
    public function __construct(
53
        EditSummaryRepository $repository,
54
        Project $project,
55
        User $user,
56
        I18nHelper $i18n,
57
        $namespace,
58
        $start = false,
59
        $end = false,
60
        int $numEditsRecent = 150
61
    ) {
62
        $this->repository = $repository;
63
        $this->project = $project;
64
        $this->user = $user;
65
        $this->i18n = $i18n;
66
        $this->namespace = $namespace;
67
        $this->start = $start;
68
        $this->end = $end;
69
        $this->numEditsRecent = $numEditsRecent;
70
    }
71
72
    /**
73
     * Get the total number of edits.
74
     * @return int
75
     */
76
    public function getTotalEdits(): int
77
    {
78
        return $this->data['total_edits'];
79
    }
80
81
    /**
82
     * Get the total number of minor edits.
83
     * @return int
84
     */
85
    public function getTotalEditsMinor(): int
86
    {
87
        return $this->data['total_edits_minor'];
88
    }
89
90
    /**
91
     * Get the total number of major (non-minor) edits.
92
     * @return int
93
     */
94
    public function getTotalEditsMajor(): int
95
    {
96
        return $this->data['total_edits_major'];
97
    }
98
99
    /**
100
     * Get the total number of recent minor edits.
101
     * @return int
102
     */
103
    public function getRecentEditsMinor(): int
104
    {
105
        return $this->data['recent_edits_minor'];
106
    }
107
108
    /**
109
     * Get the total number of recent major (non-minor) edits.
110
     * @return int
111
     */
112
    public function getRecentEditsMajor(): int
113
    {
114
        return $this->data['recent_edits_major'];
115
    }
116
117
    /**
118
     * Get the total number of edits with summaries.
119
     * @return int
120
     */
121
    public function getTotalSummaries(): int
122
    {
123
        return $this->data['total_summaries'];
124
    }
125
126
    /**
127
     * Get the total number of minor edits with summaries.
128
     * @return int
129
     */
130
    public function getTotalSummariesMinor(): int
131
    {
132
        return $this->data['total_summaries_minor'];
133
    }
134
135
    /**
136
     * Get the total number of major (non-minor) edits with summaries.
137
     * @return int
138
     */
139
    public function getTotalSummariesMajor(): int
140
    {
141
        return $this->data['total_summaries_major'];
142
    }
143
144
    /**
145
     * Get the total number of recent minor edits with with summaries.
146
     * @return int
147
     */
148
    public function getRecentSummariesMinor(): int
149
    {
150
        return $this->data['recent_summaries_minor'];
151
    }
152
153
    /**
154
     * Get the total number of recent major (non-minor) edits with with summaries.
155
     * @return int
156
     */
157
    public function getRecentSummariesMajor(): int
158
    {
159
        return $this->data['recent_summaries_major'];
160
    }
161
162
    /**
163
     * Get the month counts.
164
     * @return array Months as 'YYYY-MM' as the keys,
165
     *   with key 'total' and 'summaries' as the values.
166
     */
167
    public function getMonthCounts(): array
168
    {
169
        return $this->data['month_counts'];
170
    }
171
172
    /**
173
     * Get the whole blob of counts.
174
     * @return array Counts of summaries, raw edits, and per-month breakdown.
175
     * @codeCoverageIgnore
176
     */
177
    public function getData(): array
178
    {
179
        return $this->data;
180
    }
181
182
    /**
183
     * Fetch the data from the database, process, and put in memory.
184
     * @codeCoverageIgnore
185
     */
186
    public function prepareData(): array
187
    {
188
        // Do our database work in the Repository, passing in reference
189
        // to $this->processRow so we can do post-processing here.
190
        $ret = $this->repository->prepareData(
0 ignored issues
show
Bug introduced by
The method prepareData() does not exist on App\Repository\Repository. It seems like you code against a sub-type of App\Repository\Repository such as App\Repository\EditSummaryRepository. ( Ignorable by Annotation )

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

190
        /** @scrutinizer ignore-call */ 
191
        $ret = $this->repository->prepareData(
Loading history...
191
            [$this, 'processRow'],
192
            $this->project,
193
            $this->user,
194
            $this->namespace,
195
            $this->start,
196
            $this->end
197
        );
198
199
        // We want to keep all the default zero values if there are no contributions.
200
        if (count($ret) > 0) {
201
            $this->data = $ret;
202
        }
203
204
        return $ret;
205
    }
206
207
    /**
208
     * Process a single row from the database, updating class properties with counts.
209
     * @param string[] $row As retrieved from the revision table.
210
     * @return string[]
211
     */
212
    public function processRow(array $row): array
213
    {
214
        // Extract the date out of the date field
215
        $timestamp = DateTime::createFromFormat('YmdHis', $row['rev_timestamp']);
216
217
        $monthKey = $this->i18n->dateFormat($timestamp, 'yyyy-MM');
218
219
        // Grand total for number of edits
220
        $this->data['total_edits']++;
221
222
        // Update total edit count for this month.
223
        $this->updateMonthCounts($monthKey, 'total');
224
225
        // Total edit summaries
226
        if ($this->hasSummary($row)) {
227
            $this->data['total_summaries']++;
228
229
            // Update summary count for this month.
230
            $this->updateMonthCounts($monthKey, 'summaries');
231
        }
232
233
        if ($this->isMinor($row)) {
234
            $this->updateMajorMinorCounts($row, 'minor');
235
        } else {
236
            $this->updateMajorMinorCounts($row, 'major');
237
        }
238
239
        return $this->data;
240
    }
241
242
    /**
243
     * Given the row in `revision`, update minor counts.
244
     * @param string[] $row As retrieved from the revision table.
245
     * @param string $type Either 'minor' or 'major'.
246
     * @codeCoverageIgnore
247
     */
248
    private function updateMajorMinorCounts(array $row, string $type): void
249
    {
250
        $this->data['total_edits_'.$type]++;
251
252
        $hasSummary = $this->hasSummary($row);
253
        $isRecent = $this->data['recent_edits_'.$type] < $this->numEditsRecent;
254
255
        if ($hasSummary) {
256
            $this->data['total_summaries_'.$type]++;
257
        }
258
259
        // Update recent edits counts.
260
        if ($isRecent) {
261
            $this->data['recent_edits_'.$type]++;
262
263
            if ($hasSummary) {
264
                $this->data['recent_summaries_'.$type]++;
265
            }
266
        }
267
    }
268
269
    /**
270
     * Was the given row in `revision` marked as a minor edit?
271
     * @param string[] $row As retrieved from the revision table.
272
     * @return boolean
273
     */
274
    private function isMinor(array $row): bool
275
    {
276
        return 1 === (int)$row['rev_minor_edit'];
277
    }
278
279
    /**
280
     * Taking into account automated edit summaries, does the given
281
     * row in `revision` have a user-supplied edit summary?
282
     * @param string[] $row As retrieved from the revision table.
283
     * @return boolean
284
     */
285
    private function hasSummary(array $row): bool
286
    {
287
        $summary = preg_replace("/^\/\* (.*?) \*\/\s*/", '', $row['comment']);
288
        return '' !== $summary;
289
    }
290
291
    /**
292
     * Check and see if the month is set for given $monthKey and $type.
293
     * If it is, increment it, otherwise set it to 1.
294
     * @param string $monthKey In the form 'YYYY-MM'.
295
     * @param string $type     Either 'total' or 'summaries'.
296
     * @codeCoverageIgnore
297
     */
298
    private function updateMonthCounts(string $monthKey, string $type): void
299
    {
300
        if (isset($this->data['month_counts'][$monthKey][$type])) {
301
            $this->data['month_counts'][$monthKey][$type]++;
302
        } else {
303
            $this->data['month_counts'][$monthKey][$type] = 1;
304
        }
305
    }
306
}
307