Passed
Push — master ( 9c530b...98dfb9 )
by MusikAnimal
06:42
created

Pages::prepareData()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
eloc 6
nc 3
nop 1
dl 0
loc 14
ccs 0
cts 0
cp 0
crap 12
rs 10
c 0
b 0
f 0
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 $offset Pagination offset.
43
     */
44 2
    public function __construct(
45
        Project $project,
46
        User $user,
47
        $namespace = 0,
48
        $redirects = 'noredirects',
49
        $deleted = 'all',
50
        $offset = 0
51
    ) {
52 2
        $this->project = $project;
53 2
        $this->user = $user;
54 2
        $this->namespace = 'all' === $namespace ? 'all' : (string)$namespace;
55 2
        $this->redirects = $redirects ?: 'noredirects';
56 2
        $this->deleted = $deleted ?: 'all';
57 2
        $this->offset = $offset;
58 2
    }
59
60
    /**
61
     * The redirects option associated with this Pages instance.
62
     * @return string
63
     */
64 1
    public function getRedirects(): string
65
    {
66 1
        return $this->redirects;
67
    }
68
69
    /**
70
     * The deleted pages option associated with this Page instance.
71
     * @return string
72
     */
73
    public function getDeleted(): string
74
    {
75
        return $this->deleted;
76
    }
77
78
    /**
79
     * Fetch and prepare the pages created by the user.
80
     * @param bool $all Whether to get *all* results. This should only be used for
81
     *     export options. HTTP and JSON should paginate.
82
     * @return array
83
     * @codeCoverageIgnore
84
     */
85
    public function prepareData(bool $all = false): array
86
    {
87
        $this->pages = [];
88
89
        foreach ($this->getNamespaces() as $ns) {
90
            $data = $this->fetchPagesCreated($ns, $all);
91
            $this->pages[$ns] = count($data) > 0
92
                ? $this->formatPages($data)[$ns]
93
                : [];
94
        }
95
96
        // $this->recreatedPages = $this->fetchRecreatedPages();
97
98
        return $this->pages;
99
    }
100
101
    /**
102
     * The public function to get the list of all pages created by the user,
103
     * up to self::resultsPerPage(), across all namespaces.
104
     * @param bool $all Whether to get *all* results. This should only be used for
105
     *     export options. HTTP and JSON should paginate.
106
     * @return array
107
     */
108 1
    public function getResults(bool $all = false): array
109
    {
110 1
        if (null === $this->pages) {
111
            $this->prepareData($all);
112
        }
113 1
        return $this->pages;
114
    }
115
116
    /**
117
     * Get the total number of pages the user has created.
118
     * @return int
119
     */
120
    public function getNumPages(): int
121
    {
122
        $total = 0;
123
        foreach (array_values($this->getCounts()) as $values) {
124
            $total += $values['count'];
125
        }
126
        return $total;
127
    }
128
129
    /**
130
     * Get the total number of pages we're showing data for.
131
     * @return int
132
     */
133 1
    public function getNumResults(): int
134
    {
135 1
        $total = 0;
136 1
        foreach (array_values($this->getResults()) as $pages) {
137 1
            $total += count($pages);
138
        }
139 1
        return $total;
140
    }
141
142
    /**
143
     * Get the total number of pages that are currently deleted.
144
     * @return int
145
     */
146 1
    public function getNumDeleted(): int
147
    {
148 1
        $total = 0;
149 1
        foreach (array_values($this->getCounts()) as $values) {
150 1
            $total += $values['deleted'];
151
        }
152 1
        return $total;
153
    }
154
155
    /**
156
     * Get the total number of pages that are currently redirects.
157
     * @return int
158
     */
159 1
    public function getNumRedirects(): int
160
    {
161 1
        $total = 0;
162 1
        foreach (array_values($this->getCounts()) as $values) {
163 1
            $total += $values['redirects'];
164
        }
165 1
        return $total;
166
    }
167
168
    /**
169
     * Get the namespaces in which this user has created pages.
170
     * @return string[] The IDs.
171
     */
172 1
    public function getNamespaces(): array
173
    {
174 1
        return array_keys($this->getCounts());
175
    }
176
177
    /**
178
     * Number of namespaces being reported.
179
     * @return int
180
     */
181
    public function getNumNamespaces(): int
182
    {
183
        return count(array_keys($this->getCounts()));
184
    }
185
186
    /**
187
     * Number of redirects/pages that were created/deleted, broken down by namespace.
188
     * @return array Namespace IDs as the keys, with values 'count', 'deleted' and 'redirects'.
189
     */
190 1
    public function getCounts(): array
191
    {
192 1
        if (null !== $this->countsByNamespace) {
193 1
            return $this->countsByNamespace;
194
        }
195
196 1
        $counts = [];
197
198 1
        foreach ($this->countPagesCreated() as $row) {
199 1
            $counts[$row['namespace']] = [
200 1
                'count' => (int)$row['count'],
201 1
                'deleted' => (int)$row['deleted'],
202 1
                'redirects' => (int)$row['redirects'],
203
            ];
204
        }
205
206 1
        $this->countsByNamespace = $counts;
207 1
        return $this->countsByNamespace;
208
    }
209
210
    /**
211
     * Get the number of pages the user created by assessment.
212
     * @return array Keys are the assessment class, values are the counts.
213
     */
214
    public function getAssessmentCounts(): array
215
    {
216
        if ($this->getNumPages() > $this->resultsPerPage()) {
217
            $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

217
            $counts = $this->getRepository()->/** @scrutinizer ignore-call */ getAssessmentCounts(
Loading history...
218
                $this->project,
219
                $this->user,
220
                $this->namespace,
221
                $this->redirects
222
            );
223
        } else {
224
            $counts = [];
225
            foreach ($this->pages as $nsPages) {
226
                foreach ($nsPages as $page) {
227
                    if (!isset($counts[$page['pa_class']])) {
228
                        $counts[$page['pa_class']] = 1;
229
                    } else {
230
                        $counts[$page['pa_class']]++;
231
                    }
232
                }
233
            }
234
        }
235
236
        arsort($counts);
237
238
        return $counts;
239
    }
240
241
    /**
242
     * Number of results to show, depending on the namespace.
243
     * @param bool $all Whether to get *all* results. This should only be used for
244
     *     export options. HTTP and JSON should paginate.
245
     * @return int|false
246
     */
247 1
    public function resultsPerPage(bool $all = false)
248
    {
249 1
        if (true === $all) {
250
            return false;
251
        }
252 1
        if ('all' === $this->namespace) {
253
            return self::RESULTS_LIMIT_ALL_NAMESPACES;
254
        }
255 1
        return self::RESULTS_LIMIT_SINGLE_NAMESPACE;
256
    }
257
258
    /**
259
     * Run the query to get pages created by the user with options.
260
     * This is ran independently for each namespace if $this->namespace is 'all'.
261
     * @param int $namespace Namespace ID.
262
     * @param bool $all Whether to get *all* results. This should only be used for
263
     *     export options. HTTP and JSON should paginate.
264
     * @return array
265
     */
266 1
    private function fetchPagesCreated(int $namespace, bool $all = false): array
267
    {
268 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

268
        return $this->getRepository()->/** @scrutinizer ignore-call */ getPagesCreated(
Loading history...
269 1
            $this->project,
270 1
            $this->user,
271 1
            $namespace,
272 1
            $this->redirects,
273 1
            $this->deleted,
274 1
            $this->resultsPerPage($all),
275 1
            $this->offset * $this->resultsPerPage()
276
        );
277
    }
278
279
    /**
280
     * Run the query to get the number of pages created by the user with given options.
281
     * @return array
282
     */
283 1
    private function countPagesCreated(): array
284
    {
285 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

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