Passed
Push — master ( 2c2c70...ced8c1 )
by MusikAnimal
04:22
created

Pages::formatPages()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 32
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 3
eloc 12
c 1
b 0
f 1
nc 3
nop 1
dl 0
loc 32
ccs 13
cts 13
cp 1
crap 3
rs 8.8571
1
<?php
2
/**
3
 * This file contains only the Pages class.
4
 */
5
6
namespace Xtools;
7
8
use Xtools\Project;
9
use Xtools\User;
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
    const RESULTS_LIMIT_SINGLE_NAMESPACE = 1000;
18
    const RESULTS_LIMIT_ALL_NAMESPACES = 100;
19
20
    /** @var Project The project. */
21
    protected $project;
22
23
    /** @var User The user. */
24
    protected $user;
25
26
    /** @var string Which namespace we are querying for. */
27
    protected $namespace;
28
29
    /** @var string One of 'noredirects', 'onlyredirects' or blank for both. */
30
    protected $redirects;
31
32
    /** @var int Pagination offset. */
33
    protected $offset;
34
35
    /** @var array The list of pages including various statistics. */
36
    protected $pages;
37
38
    /** @var array Number of redirects/pages that were created/deleted, broken down by namespace. */
39
    protected $countsByNamespace;
40
41
    /** @var bool Whether or not the Project supports page assessments. */
42
    protected $hasPageAssessments;
43
44
    /**
45
     * Pages constructor.
46
     * @param Project    $project
47
     * @param User       $user
48
     * @param string|int $namespace Namespace ID or 'all'.
49
     * @param string     $redirects One of 'noredirects', 'onlyredirects' or blank for both.
50
     * @param int        $offset    Pagination offset.
51
     */
52 2 View Code Duplication
    public function __construct(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
53
        Project $project,
54
        User $user,
55
        $namespace = 0,
56
        $redirects = 'noredirects',
57
        $offset = 0
58
    ) {
59 2
        $this->project = $project;
60 2
        $this->user = $user;
61 2
        $this->namespace = $namespace === 'all' ? 'all' : (string)$namespace;
62 2
        $this->redirects = $redirects;
63 2
        $this->offset = $offset;
64 2
    }
65
66
    /**
67
     * The project associated with this Pages instance.
68
     * @return Project
69
     */
70 1
    public function getProject()
71
    {
72 1
        return $this->project;
73
    }
74
75
    /**
76
     * The user associated with this Pages instance.
77
     * @return User
78
     */
79 1
    public function getUser()
80
    {
81 1
        return $this->user;
82
    }
83
84
    /**
85
     * The namespace associated with this Pages instance.
86
     * @return int|string
87
     */
88 1
    public function getNamespace()
89
    {
90 1
        return $this->namespace;
91
    }
92
93
    /**
94
     * The redirects option associated with this Pages instance.
95
     * @return string
96
     */
97 1
    public function getRedirects()
98
    {
99 1
        return $this->redirects;
100
    }
101
102
    /**
103
     * The pagination offset associated with this Pages instance.
104
     * @return int
105
     */
106 1
    public function getOffset()
107
    {
108 1
        return $this->offset;
109
    }
110
111
    /**
112
     * Fetch and prepare the pages created by the user.
113
     * @codeCoverageIgnore
114
     */
115
    public function prepareData()
116
    {
117
        $this->pages = [];
118
119
        foreach ($this->getNamespaces() as $ns) {
120
            $data = $this->fetchPagesCreated($ns);
121
            $this->pages[$ns] = $this->formatPages($data)[$ns];
122
        }
123
124
        return $this->pages;
125
    }
126
127
    /**
128
     * The public function to get the list of all pages created by the user,
129
     * up to self::resultsPerPage(), across all namespaces.
130
     * @return array
131
     */
132 1
    public function getResults()
133
    {
134 1
        if ($this->pages === null) {
135
            $this->prepareData();
136
        }
137 1
        return $this->pages;
138
    }
139
140
    /**
141
     * Get the total number of pages the user has created.
142
     * @return int
143
     */
144
    public function getNumPages()
145
    {
146
        $total = 0;
147
        foreach ($this->getCounts() as $ns => $values) {
148
            $total += $values['count'];
149
        }
150
        return $total;
151
    }
152
153
    /**
154
     * Get the total number of pages we're showing data for.
155
     * @return int
156
     */
157 1
    public function getNumResults()
158
    {
159 1
        $total = 0;
160 1
        foreach ($this->getResults() as $ns => $pages) {
161 1
            $total += count($pages);
162
        }
163 1
        return $total;
164
    }
165
166
    /**
167
     * Get the total number of pages that are currently deleted.
168
     * @return int
169
     */
170 1
    public function getNumDeleted()
171
    {
172 1
        $total = 0;
173 1
        foreach ($this->getCounts() as $ns => $values) {
174 1
            $total += $values['deleted'];
175
        }
176 1
        return $total;
177
    }
178
179
    /**
180
     * Get the total number of pages that are currently redirects.
181
     * @return int
182
     */
183 1
    public function getNumRedirects()
184
    {
185 1
        $total = 0;
186 1
        foreach ($this->getCounts() as $ns => $values) {
187 1
            $total += $values['redirects'];
188
        }
189 1
        return $total;
190
    }
191
192
    /**
193
     * Get the namespaces in which this user has created pages.
194
     * @return string[] The IDs.
195
     */
196 1
    public function getNamespaces()
197
    {
198 1
        return array_keys($this->getCounts());
199
    }
200
201
    /**
202
     * Number of namespaces being reported.
203
     * @return int
204
     */
205
    public function getNumNamespaces()
206
    {
207
        return count(array_keys($this->getCounts()));
208
    }
209
210
    /**
211
     * Number of redirects/pages that were created/deleted, broken down by namespace.
212
     * @return array Namespace IDs as the keys, with values 'count', 'deleted' and 'redirects'.
213
     */
214 1
    public function getCounts()
215
    {
216 1
        if ($this->countsByNamespace !== null) {
217 1
            return $this->countsByNamespace;
218
        }
219
220 1
        $counts = [];
221
222 1
        foreach ($this->countPagesCreated() as $row) {
223 1
            $counts[$row['namespace']] = [
224 1
                'count' => (int)$row['count'],
225 1
                'deleted' => (int)$row['deleted'],
226
            ];
227
228 1
            if (!in_array($this->redirects, ['noredirects', 'onlyredirects'])) {
229 1
                $counts[$row['namespace']]['redirects'] = (int)$row['redirects'];
230
            }
231
        }
232
233 1
        $this->countsByNamespace = $counts;
234 1
        return $this->countsByNamespace;
235
    }
236
237
    /**
238
     * Number of results to show, depending on the namespace.
239
     * @return int
240
     */
241 1
    public function resultsPerPage()
242
    {
243 1
        if ($this->namespace === 'all') {
244
            return self::RESULTS_LIMIT_ALL_NAMESPACES;
245
        }
246 1
        return self::RESULTS_LIMIT_SINGLE_NAMESPACE;
247
    }
248
249
    /**
250
     * Whether or not the results include page assessments.
251
     * @return bool
252
     */
253 1
    public function hasPageAssessments()
254
    {
255 1
        if ($this->hasPageAssessments === null) {
256 1
            $this->hasPageAssessments = $this->project->hasPageAssessments();
257
        }
258 1
        return $this->hasPageAssessments;
259
    }
260
261
    /**
262
     * Run the query to get pages created by the user with options.
263
     * This is ran independently for each namespace if $this->namespace is 'all'.
264
     * @param string $namespace Namespace ID.
265
     * @return array
266
     */
267 1
    private function fetchPagesCreated($namespace)
268
    {
269 1
        return $this->user->getRepository()->getPagesCreated(
1 ignored issue
show
Bug introduced by
The method getPagesCreated() does not exist on Xtools\Repository. It seems like you code against a sub-type of Xtools\Repository such as Xtools\UserRepository. ( Ignorable by Annotation )

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

269
        return $this->user->getRepository()->/** @scrutinizer ignore-call */ getPagesCreated(
Loading history...
270 1
            $this->project,
271 1
            $this->user,
272 1
            $namespace,
273 1
            $this->redirects,
274 1
            $this->resultsPerPage(),
275 1
            $this->offset * $this->resultsPerPage()
276
        );
277
    }
278
279
    /**
280
     * Run the query to get the number of pages created by the user
281
     * with given options.
282
     * @return array
283
     */
284 1
    private function countPagesCreated()
285
    {
286 1
        return $this->user->getRepository()->countPagesCreated(
1 ignored issue
show
Bug introduced by
The method countPagesCreated() does not exist on Xtools\Repository. It seems like you code against a sub-type of Xtools\Repository such as Xtools\UserRepository. ( Ignorable by Annotation )

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

286
        return $this->user->getRepository()->/** @scrutinizer ignore-call */ countPagesCreated(
Loading history...
287 1
            $this->project,
288 1
            $this->user,
289 1
            $this->namespace,
290 1
            $this->redirects
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($pages)
301
    {
302 1
        $results = [];
303
304 1
        foreach ($pages as $row) {
305
            // if (!isset($results[$row['namespace']])) {
306
            //     $results[$row['namespace']] = [];
307
            // }
308
309 1
            $datetime = DateTime::createFromFormat('YmdHis', $row['rev_timestamp']);
310 1
            $datetimeHuman = $datetime->format('Y-m-d H:i');
311
312 1
            $pageData = array_merge($row, [
313 1
                'raw_time' => $row['rev_timestamp'],
314 1
                'human_time' => $datetimeHuman,
315 1
                'page_title' => str_replace('_', ' ', $row['page_title'])
316
            ]);
317
318 1
            if ($this->hasPageAssessments()) {
319 1
                $pageData['badge'] = $this->project->getAssessmentBadgeURL($pageData['pa_class']);
320
            }
321
322 1
            $results[$row['namespace']][] = $pageData;
323
        }
324
325
        // ksort($results);
326
327
        // foreach (array_keys($results) as $key) {
328
        //     krsort($results[$key]);
329
        // }
330
331 1
        return $results;
332
    }
333
}
334