Passed
Push — master ( 98dfb9...fc72f2 )
by MusikAnimal
06:46
created

Pages::__construct()   A

Complexity

Conditions 6
Paths 8

Size

Total Lines 18
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 6

Importance

Changes 0
Metric Value
cc 6
eloc 8
nc 8
nop 8
dl 0
loc 18
rs 9.2222
c 0
b 0
f 0
ccs 9
cts 9
cp 1
crap 6

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
 * This file contains only the Pages class.
4
 */
5
6
declare(strict_types = 1);
7
8
namespace AppBundle\Model;
9
10
use DateTime;
11
12
/**
13
 * A Pages provides statistics about the pages created by a given User.
14
 */
15
class Pages extends Model
16
{
17
    private const RESULTS_LIMIT_SINGLE_NAMESPACE = 1000;
18
    private const RESULTS_LIMIT_ALL_NAMESPACES = 100;
19
20
    /** @var string One of 'noredirects', 'onlyredirects' or 'all' for both. */
21
    protected $redirects;
22
23
    /** @var string One of 'live', 'deleted' or 'all' for both. */
24
    protected $deleted;
25
26
    /** @var int Pagination offset. */
27
    protected $offset;
28
29
    /** @var mixed[] The list of pages including various statistics, keyed by namespace. */
30
    protected $pages;
31
32
    /** @var mixed[] Number of redirects/pages that were created/deleted, broken down by namespace. */
33
    protected $countsByNamespace;
34
35
    /**
36
     * Pages constructor.
37
     * @param Project $project
38
     * @param User $user
39
     * @param string|int $namespace Namespace ID or 'all'.
40
     * @param string $redirects One of 'noredirects', 'onlyredirects' or 'all' for both.
41
     * @param string $deleted One of 'live', 'deleted' or 'all' for both.
42
     * @param int|false $start Start date in a format accepted by strtotime()
43
     * @param int|false $end End date in a format accepted by strtotime()
44
     * @param int $offset Pagination offset.
45
     */
46 2
    public function __construct(
47
        Project $project,
48
        User $user,
49
        $namespace = 0,
50
        $redirects = 'noredirects',
51
        $deleted = 'all',
52
        $start = false,
53
        $end = false,
54
        $offset = 0
55
    ) {
56 2
        $this->project = $project;
57 2
        $this->user = $user;
58 2
        $this->namespace = 'all' === $namespace ? 'all' : (string)$namespace;
59 2
        $this->start = false === $start ? '' : date('Y-m-d', $start);
60 2
        $this->end = false === $end ? '' : date('Y-m-d', $end);
61 2
        $this->redirects = $redirects ?: 'noredirects';
62 2
        $this->deleted = $deleted ?: 'all';
63 2
        $this->offset = $offset;
64 2
    }
65
66
    /**
67
     * The redirects option associated with this Pages instance.
68
     * @return string
69
     */
70 1
    public function getRedirects(): string
71
    {
72 1
        return $this->redirects;
73
    }
74
75
    /**
76
     * The deleted pages option associated with this Page instance.
77
     * @return string
78
     */
79
    public function getDeleted(): string
80
    {
81
        return $this->deleted;
82
    }
83
84
    /**
85
     * Fetch and prepare the pages created by the user.
86
     * @param bool $all Whether to get *all* results. This should only be used for
87
     *     export options. HTTP and JSON should paginate.
88
     * @return array
89
     * @codeCoverageIgnore
90
     */
91
    public function prepareData(bool $all = false): array
92
    {
93
        $this->pages = [];
94
95
        foreach ($this->getNamespaces() as $ns) {
96
            $data = $this->fetchPagesCreated($ns, $all);
97
            $this->pages[$ns] = count($data) > 0
98
                ? $this->formatPages($data)[$ns]
99
                : [];
100
        }
101
102
        // $this->recreatedPages = $this->fetchRecreatedPages();
103
104
        return $this->pages;
105
    }
106
107
    /**
108
     * The public function to get the list of all pages created by the user,
109
     * up to self::resultsPerPage(), across all namespaces.
110
     * @param bool $all Whether to get *all* results. This should only be used for
111
     *     export options. HTTP and JSON should paginate.
112
     * @return array
113
     */
114 1
    public function getResults(bool $all = false): array
115
    {
116 1
        if (null === $this->pages) {
117
            $this->prepareData($all);
118
        }
119 1
        return $this->pages;
120
    }
121
122
    /**
123
     * Get the total number of pages the user has created.
124
     * @return int
125
     */
126
    public function getNumPages(): int
127
    {
128
        $total = 0;
129
        foreach (array_values($this->getCounts()) as $values) {
130
            $total += $values['count'];
131
        }
132
        return $total;
133
    }
134
135
    /**
136
     * Get the total number of pages we're showing data for.
137
     * @return int
138
     */
139 1
    public function getNumResults(): int
140
    {
141 1
        $total = 0;
142 1
        foreach (array_values($this->getResults()) as $pages) {
143 1
            $total += count($pages);
144
        }
145 1
        return $total;
146
    }
147
148
    /**
149
     * Get the total number of pages that are currently deleted.
150
     * @return int
151
     */
152 1
    public function getNumDeleted(): int
153
    {
154 1
        $total = 0;
155 1
        foreach (array_values($this->getCounts()) as $values) {
156 1
            $total += $values['deleted'];
157
        }
158 1
        return $total;
159
    }
160
161
    /**
162
     * Get the total number of pages that are currently redirects.
163
     * @return int
164
     */
165 1
    public function getNumRedirects(): int
166
    {
167 1
        $total = 0;
168 1
        foreach (array_values($this->getCounts()) as $values) {
169 1
            $total += $values['redirects'];
170
        }
171 1
        return $total;
172
    }
173
174
    /**
175
     * Get the namespaces in which this user has created pages.
176
     * @return string[] The IDs.
177
     */
178 1
    public function getNamespaces(): array
179
    {
180 1
        return array_keys($this->getCounts());
181
    }
182
183
    /**
184
     * Number of namespaces being reported.
185
     * @return int
186
     */
187
    public function getNumNamespaces(): int
188
    {
189
        return count(array_keys($this->getCounts()));
190
    }
191
192
    /**
193
     * Number of redirects/pages that were created/deleted, broken down by namespace.
194
     * @return array Namespace IDs as the keys, with values 'count', 'deleted' and 'redirects'.
195
     */
196 1
    public function getCounts(): array
197
    {
198 1
        if (null !== $this->countsByNamespace) {
199 1
            return $this->countsByNamespace;
200
        }
201
202 1
        $counts = [];
203
204 1
        foreach ($this->countPagesCreated() as $row) {
205 1
            $counts[$row['namespace']] = [
206 1
                'count' => (int)$row['count'],
207 1
                'deleted' => (int)$row['deleted'],
208 1
                'redirects' => (int)$row['redirects'],
209
            ];
210
        }
211
212 1
        $this->countsByNamespace = $counts;
213 1
        return $this->countsByNamespace;
214
    }
215
216
    /**
217
     * Get the number of pages the user created by assessment.
218
     * @return array Keys are the assessment class, values are the counts.
219
     */
220
    public function getAssessmentCounts(): array
221
    {
222
        if ($this->getNumPages() > $this->resultsPerPage()) {
223
            $counts = $this->getRepository()->getAssessmentCounts(
0 ignored issues
show
Bug introduced by
The method getAssessmentCounts() does not exist on AppBundle\Repository\Repository. It seems like you code against a sub-type of AppBundle\Repository\Repository such as AppBundle\Repository\PagesRepository. ( Ignorable by Annotation )

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

223
            $counts = $this->getRepository()->/** @scrutinizer ignore-call */ getAssessmentCounts(
Loading history...
224
                $this->project,
225
                $this->user,
226
                $this->namespace,
227
                $this->redirects
228
            );
229
        } else {
230
            $counts = [];
231
            foreach ($this->pages as $nsPages) {
232
                foreach ($nsPages as $page) {
233
                    if (!isset($counts[$page['pa_class']])) {
234
                        $counts[$page['pa_class']] = 1;
235
                    } else {
236
                        $counts[$page['pa_class']]++;
237
                    }
238
                }
239
            }
240
        }
241
242
        arsort($counts);
243
244
        return $counts;
245
    }
246
247
    /**
248
     * Number of results to show, depending on the namespace.
249
     * @param bool $all Whether to get *all* results. This should only be used for
250
     *     export options. HTTP and JSON should paginate.
251
     * @return int|false
252
     */
253 1
    public function resultsPerPage(bool $all = false)
254
    {
255 1
        if (true === $all) {
256
            return false;
257
        }
258 1
        if ('all' === $this->namespace) {
259
            return self::RESULTS_LIMIT_ALL_NAMESPACES;
260
        }
261 1
        return self::RESULTS_LIMIT_SINGLE_NAMESPACE;
262
    }
263
264
    /**
265
     * Run the query to get pages created by the user with options.
266
     * This is ran independently for each namespace if $this->namespace is 'all'.
267
     * @param int $namespace Namespace ID.
268
     * @param bool $all Whether to get *all* results. This should only be used for
269
     *     export options. HTTP and JSON should paginate.
270
     * @return array
271
     */
272 1
    private function fetchPagesCreated(int $namespace, bool $all = false): array
273
    {
274 1
        return $this->getRepository()->getPagesCreated(
0 ignored issues
show
Bug introduced by
The method getPagesCreated() does not exist on AppBundle\Repository\Repository. It seems like you code against a sub-type of AppBundle\Repository\Repository such as AppBundle\Repository\PagesRepository. ( Ignorable by Annotation )

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

274
        return $this->getRepository()->/** @scrutinizer ignore-call */ getPagesCreated(
Loading history...
275 1
            $this->project,
276 1
            $this->user,
277 1
            $namespace,
278 1
            $this->redirects,
279 1
            $this->deleted,
280 1
            $this->start,
281 1
            $this->end,
282 1
            $this->resultsPerPage($all),
283 1
            $this->offset * $this->resultsPerPage()
284
        );
285
    }
286
287
    /**
288
     * Run the query to get the number of pages created by the user with given options.
289
     * @return array
290
     */
291 1
    private function countPagesCreated(): array
292
    {
293 1
        return $this->getRepository()->countPagesCreated(
0 ignored issues
show
Bug introduced by
The method countPagesCreated() does not exist on AppBundle\Repository\Repository. It seems like you code against a sub-type of AppBundle\Repository\Repository such as AppBundle\Repository\PagesRepository. ( Ignorable by Annotation )

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

293
        return $this->getRepository()->/** @scrutinizer ignore-call */ countPagesCreated(
Loading history...
294 1
            $this->project,
295 1
            $this->user,
296 1
            $this->namespace,
297 1
            $this->redirects,
298 1
            $this->deleted,
299 1
            $this->start,
300 1
            $this->end
301
        );
302
    }
303
304
    /**
305
     * Format the data, adding humanized timestamps, page titles, assessment badges,
306
     * and sorting by namespace and then timestamp.
307
     * @param array $pages As returned by self::fetchPagesCreated()
308
     * @return array
309
     */
310 1
    private function formatPages(array $pages): array
311
    {
312 1
        $results = [];
313
314 1
        foreach ($pages as $row) {
315 1
            $datetime = DateTime::createFromFormat('YmdHis', $row['rev_timestamp']);
316 1
            $datetimeHuman = $datetime->format('Y-m-d H:i');
317
318 1
            $pageData = array_merge($row, [
319 1
                'raw_time' => $row['rev_timestamp'],
320 1
                'human_time' => $datetimeHuman,
321 1
                'page_title' => str_replace('_', ' ', $row['page_title']),
322
            ]);
323
324 1
            if ($this->project->hasPageAssessments()) {
325
                $pageData['badge'] = $this->project
326
                    ->getPageAssessments()
327
                    ->getBadgeURL($pageData['pa_class']);
328
                $pageData['badgeFile'] = $this->project
329
                    ->getPageAssessments()
330
                    ->getBadgeURL($pageData['pa_class'], true);
331
            }
332
333 1
            $results[$row['namespace']][] = $pageData;
334
        }
335
336 1
        return $results;
337
    }
338
}
339