Passed
Push — master ( 2f87b4...a0f968 )
by MusikAnimal
05:26
created

Pages::prepareData()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

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