Passed
Push — master ( 09bbf5...1b30d6 )
by MusikAnimal
05:04
created

Pages::getNumRedirects()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 2
eloc 4
c 1
b 0
f 1
nc 2
nop 0
dl 0
loc 7
ccs 5
cts 5
cp 1
crap 2
rs 9.4285
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 'all' for both. */
30
    protected $redirects;
31
32
    /** @var string One of 'live', 'deleted' or 'all' for both. */
33
    protected $deleted;
34
35
    /** @var int Pagination offset. */
36
    protected $offset;
37
38
    /** @var array The list of pages including various statistics. */
39
    protected $pages;
40
41
    /** @var array Number of redirects/pages that were created/deleted, broken down by namespace. */
42
    protected $countsByNamespace;
43
44
    /** @var bool Whether or not the Project supports page assessments. */
45
    protected $hasPageAssessments;
46
47
    /**
48
     * Pages constructor.
49
     * @param Project $project
50
     * @param User $user
51
     * @param string|int $namespace Namespace ID or 'all'.
52
     * @param string $redirects One of 'noredirects', 'onlyredirects' or 'all' for both.
53
     * @param string $deleted One of 'live', 'deleted' or 'all' for both.
54
     * @param int $offset Pagination offset.
55
     */
56 2
    public function __construct(
57
        Project $project,
58
        User $user,
59
        $namespace = 0,
60
        $redirects = 'noredirects',
61
        $deleted = 'all',
62
        $offset = 0
63
    ) {
64 2
        $this->project = $project;
65 2
        $this->user = $user;
66 2
        $this->namespace = $namespace === 'all' ? 'all' : (string)$namespace;
67 2
        $this->redirects = $redirects ?: 'noredirects';
68 2
        $this->deleted = $deleted ?: 'all';
69 2
        $this->offset = $offset;
70 2
    }
71
72
    /**
73
     * The project associated with this Pages instance.
74
     * @return Project
75
     */
76 1
    public function getProject()
77
    {
78 1
        return $this->project;
79
    }
80
81
    /**
82
     * The user associated with this Pages instance.
83
     * @return User
84
     */
85 1
    public function getUser()
86
    {
87 1
        return $this->user;
88
    }
89
90
    /**
91
     * The namespace associated with this Pages instance.
92
     * @return int|string
93
     */
94 1
    public function getNamespace()
95
    {
96 1
        return $this->namespace;
97
    }
98
99
    /**
100
     * The redirects option associated with this Pages instance.
101
     * @return string
102
     */
103 1
    public function getRedirects()
104
    {
105 1
        return $this->redirects;
106
    }
107
108
    /**
109
     * The deleted pages option associated with this Page instance.
110
     * @return string
111
     */
112
    public function getDeleted()
113
    {
114
        return $this->deleted;
115
    }
116
117
    /**
118
     * The pagination offset associated with this Pages instance.
119
     * @return int
120
     */
121 1
    public function getOffset()
122
    {
123 1
        return $this->offset;
124
    }
125
126
    /**
127
     * Fetch and prepare the pages created by the user.
128
     * @param bool $all Whether to get *all* results. This should only be used for
129
     *     export options. HTTP and JSON should paginate.
130
     * @codeCoverageIgnore
131
     */
132
    public function prepareData($all = false)
133
    {
134
        $this->pages = [];
135
136
        foreach ($this->getNamespaces() as $ns) {
137
            $data = $this->fetchPagesCreated($ns, $all);
138
            $this->pages[$ns] = $this->formatPages($data)[$ns];
139
        }
140
141
        return $this->pages;
142
    }
143
144
    /**
145
     * The public function to get the list of all pages created by the user,
146
     * up to self::resultsPerPage(), across all namespaces.
147
     * @param bool $all Whether to get *all* results. This should only be used for
148
     *     export options. HTTP and JSON should paginate.
149
     * @return array
150
     */
151 1
    public function getResults($all = false)
152
    {
153 1
        if ($this->pages === null) {
154
            $this->prepareData($all);
155
        }
156 1
        return $this->pages;
157
    }
158
159
    /**
160
     * Get the total number of pages the user has created.
161
     * @return int
162
     */
163
    public function getNumPages()
164
    {
165
        $total = 0;
166
        foreach ($this->getCounts() as $ns => $values) {
167
            $total += $values['count'];
168
        }
169
        return $total;
170
    }
171
172
    /**
173
     * Get the total number of pages we're showing data for.
174
     * @return int
175
     */
176 1
    public function getNumResults()
177
    {
178 1
        $total = 0;
179 1
        foreach ($this->getResults() as $ns => $pages) {
180 1
            $total += count($pages);
181
        }
182 1
        return $total;
183
    }
184
185
    /**
186
     * Get the total number of pages that are currently deleted.
187
     * @return int
188
     */
189 1
    public function getNumDeleted()
190
    {
191 1
        $total = 0;
192 1
        foreach ($this->getCounts() as $ns => $values) {
193 1
            $total += $values['deleted'];
194
        }
195 1
        return $total;
196
    }
197
198
    /**
199
     * Get the total number of pages that are currently redirects.
200
     * @return int
201
     */
202 1
    public function getNumRedirects()
203
    {
204 1
        $total = 0;
205 1
        foreach ($this->getCounts() as $ns => $values) {
206 1
            $total += $values['redirects'];
207
        }
208 1
        return $total;
209
    }
210
211
    /**
212
     * Get the namespaces in which this user has created pages.
213
     * @return string[] The IDs.
214
     */
215 1
    public function getNamespaces()
216
    {
217 1
        return array_keys($this->getCounts());
218
    }
219
220
    /**
221
     * Number of namespaces being reported.
222
     * @return int
223
     */
224
    public function getNumNamespaces()
225
    {
226
        return count(array_keys($this->getCounts()));
227
    }
228
229
    /**
230
     * Number of redirects/pages that were created/deleted, broken down by namespace.
231
     * @return array Namespace IDs as the keys, with values 'count', 'deleted' and 'redirects'.
232
     */
233 1
    public function getCounts()
234
    {
235 1
        if ($this->countsByNamespace !== null) {
236 1
            return $this->countsByNamespace;
237
        }
238
239 1
        $counts = [];
240
241 1
        foreach ($this->countPagesCreated() as $row) {
242 1
            $counts[$row['namespace']] = [
243 1
                'count' => (int)$row['count'],
244 1
                'deleted' => (int)$row['deleted'],
245 1
                'redirects' => (int)$row['redirects']
246
            ];
247
        }
248
249 1
        $this->countsByNamespace = $counts;
250 1
        return $this->countsByNamespace;
251
    }
252
253
    /**
254
     * Number of results to show, depending on the namespace.
255
     * @param bool $all Whether to get *all* results. This should only be used for
256
     *     export options. HTTP and JSON should paginate.
257
     * @return int
258
     */
259 1
    public function resultsPerPage($all = false)
260
    {
261 1
        if ($all === true) {
262
            return false;
263
        }
264 1
        if ($this->namespace === 'all') {
265
            return self::RESULTS_LIMIT_ALL_NAMESPACES;
266
        }
267 1
        return self::RESULTS_LIMIT_SINGLE_NAMESPACE;
268
    }
269
270
    /**
271
     * Whether or not the results include page assessments.
272
     * @return bool
273
     */
274 1
    public function hasPageAssessments()
275
    {
276 1
        if ($this->hasPageAssessments === null) {
277 1
            $this->hasPageAssessments = $this->project->hasPageAssessments();
278
        }
279 1
        return $this->hasPageAssessments;
280
    }
281
282
    /**
283
     * Run the query to get pages created by the user with options.
284
     * This is ran independently for each namespace if $this->namespace is 'all'.
285
     * @param string $namespace Namespace ID.
286
     * @param bool $all Whether to get *all* results. This should only be used for
287
     *     export options. HTTP and JSON should paginate.
288
     * @return array
289
     */
290 1
    private function fetchPagesCreated($namespace, $all = false)
291
    {
292 1
        return $this->user->getRepository()->getPagesCreated(
293 1
            $this->project,
294 1
            $this->user,
295 1
            $namespace,
296 1
            $this->redirects,
297 1
            $this->deleted,
298 1
            $this->resultsPerPage($all),
299 1
            $this->offset * $this->resultsPerPage()
300
        );
301
    }
302
303
    /**
304
     * Run the query to get the number of pages created by the user
305
     * with given options.
306
     * @return array
307
     */
308 1
    private function countPagesCreated()
309
    {
310 1
        return $this->user->getRepository()->countPagesCreated(
311 1
            $this->project,
312 1
            $this->user,
313 1
            $this->namespace,
314 1
            $this->redirects,
315 1
            $this->deleted
316
        );
317
    }
318
319
    /**
320
     * Format the data, adding humanized timestamps, page titles, assessment badges,
321
     * and sorting by namespace and then timestamp.
322
     * @param  array $pages As returned by self::fetchPagesCreated()
323
     * @return array
324
     */
325 1
    private function formatPages($pages)
326
    {
327 1
        $results = [];
328
329 1
        foreach ($pages as $row) {
330 1
            $datetime = DateTime::createFromFormat('YmdHis', $row['rev_timestamp']);
331 1
            $datetimeHuman = $datetime->format('Y-m-d H:i');
332
333 1
            $pageData = array_merge($row, [
334 1
                'raw_time' => $row['rev_timestamp'],
335 1
                'human_time' => $datetimeHuman,
336 1
                'page_title' => str_replace('_', ' ', $row['page_title'])
337
            ]);
338
339 1
            if ($this->hasPageAssessments()) {
340 1
                $pageData['badge'] = $this->project->getAssessmentBadgeURL($pageData['pa_class']);
341
            }
342
343 1
            $results[$row['namespace']][] = $pageData;
344
        }
345
346 1
        return $results;
347
    }
348
}
349