Passed
Push — master ( c88656...e5f428 )
by MusikAnimal
08:08
created

CategoryEdits::getCategoryEdits()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 22
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 13
nc 3
nop 1
dl 0
loc 22
ccs 14
cts 14
cp 1
crap 3
rs 9.8333
c 0
b 0
f 0
1
<?php
2
/**
3
 * This file contains only the CategoryEdits class.
4
 */
5
6
namespace Xtools;
7
8
/**
9
 * CategoryEdits returns statistics about edits made by a user to pages in given categories.
10
 */
11
class CategoryEdits extends Model
12
{
13
    /** @var string[] The categories. */
14
    protected $categories;
15
16
    /** @var Edit[] The list of contributions. */
17
    protected $categoryEdits;
18
19
    /** @var int Total number of edits. */
20
    protected $editCount;
21
22
    /** @var int Total number of edits within the category. */
23
    protected $categoryEditCount;
24
25
    /** @var array Counts of edits within each category, keyed by category name. */
26
    protected $categoryCounts;
27
28
    /**
29
     * Constructor for the CategoryEdits class.
30
     * @param Project $project
31
     * @param User $user
32
     * @param array $categories
33
     * @param int|false $start As Unix timestamp.
34
     * @param int|false $end As Unix timestamp.
35
     * @param int $offset Used for pagination, offset results by N edits.
36
     */
37 3
    public function __construct(
38
        Project $project,
39
        User $user,
40
        array $categories,
41
        $start = false,
42
        $end = false,
43
        $offset = 0
44
    ) {
45 3
        $this->project = $project;
46 3
        $this->user = $user;
47 3
        $this->categories = array_map(function ($category) {
48 3
            return str_replace(' ', '_', $category);
49 3
        }, $categories);
50 3
        $this->start = false === $start ? '' : date('Y-m-d', $start);
51 3
        $this->end = false === $end ? '' : date('Y-m-d', $end);
52 3
        $this->offset = (int)$offset;
53 3
    }
54
55
    /**
56
     * Get the categories.
57
     * @return string[]
58
     */
59 1
    public function getCategories()
60
    {
61 1
        return $this->categories;
62
    }
63
64
    /**
65
     * Get the categories as a piped string.
66
     * @return string
67
     */
68 1
    public function getCategoriesPiped()
69
    {
70 1
        return implode('|', $this->categories);
71
    }
72
73
    /**
74
     * Get the categories as an array of normalized strings (without namespace).
75
     * @return string
76
     */
77
    public function getCategoriesNormalized()
78
    {
79 1
        return array_map(function ($category) {
80 1
            return str_replace('_', ' ', $category);
81 1
        }, $this->categories);
82
    }
83
84
    /**
85
     * Get the raw edit count of the user.
86
     * @return int
87
     */
88 1
    public function getEditCount()
89
    {
90 1
        if (!is_int($this->editCount)) {
0 ignored issues
show
introduced by
The condition is_int($this->editCount) is always true.
Loading history...
91 1
            $this->editCount = $this->user->countEdits(
92 1
                $this->project,
93 1
                'all',
94 1
                $this->start,
95 1
                $this->end
96
            );
97
        }
98
99 1
        return $this->editCount;
100
    }
101
102
    /**
103
     * Get the number of edits this user made within the categories.
104
     * @return int Result of query, see below.
105
     */
106 1
    public function getCategoryEditCount()
107
    {
108 1
        if (is_int($this->categoryEditCount)) {
0 ignored issues
show
introduced by
The condition is_int($this->categoryEditCount) is always true.
Loading history...
109 1
            return $this->categoryEditCount;
110
        }
111
112 1
        $this->categoryEditCount = (int)$this->getRepository()->countCategoryEdits(
113 1
            $this->project,
114 1
            $this->user,
115 1
            $this->categories,
116 1
            $this->start,
117 1
            $this->end
118
        );
119
120 1
        return $this->categoryEditCount;
121
    }
122
123
    /**
124
     * Get the percentage of all edits made to the categories.
125
     * @return float
126
     */
127 1
    public function getCategoryPercentage()
128
    {
129 1
        return $this->getEditCount() > 0
130 1
            ? ($this->getCategoryEditCount() / $this->getEditCount()) * 100
131 1
            : 0;
132
    }
133
134
    /**
135
     * Get the number of pages edited.
136
     * @return int
137
     */
138
    public function getCategoryPageCount()
139
    {
140
        $pageCount = 0;
141
        foreach ($this->getCategoryCounts() as $categoryCount) {
142
            $pageCount += $categoryCount['pageCount'];
143
        }
144
145
        return $pageCount;
146
    }
147
148
    /**
149
     * Get contributions made to the categories.
150
     * @param bool $raw Wether to return raw data from the database, or get Edit objects.
151
     * @return string[]|Edit[]
152
     */
153 1
    public function getCategoryEdits($raw = false)
154
    {
155 1
        if (is_array($this->categoryEdits)) {
0 ignored issues
show
introduced by
The condition is_array($this->categoryEdits) is always true.
Loading history...
156 1
            return $this->categoryEdits;
157
        }
158
159 1
        $revs = $this->getRepository()->getCategoryEdits(
160 1
            $this->project,
161 1
            $this->user,
162 1
            $this->categories,
163 1
            $this->start,
164 1
            $this->end,
165 1
            $this->offset
166
        );
167
168 1
        if ($raw) {
169 1
            return $revs;
170
        }
171
172 1
        $this->categoryEdits = $this->getEditsFromRevs($revs);
173
174 1
        return $this->categoryEdits;
175
    }
176
177
    /**
178
     * Transform database rows into Edit objects.
179
     * @param string[] $revs
180
     * @return Edit[]
181
     */
182
    private function getEditsFromRevs(array $revs)
183
    {
184 1
        return array_map(function ($rev) {
185
            /* @var Page Page object to be passed to the Edit contructor. */
186 1
            $page = $this->getPageFromRev($rev);
187 1
            $rev['user'] = $this->user;
188
189 1
            return new Edit($page, $rev);
190 1
        }, $revs);
191
    }
192
193
    /**
194
     * Get a Page object given a revision row.
195
     * @param array $rev Revision as retrieved from the database.
196
     * @return Page
197
     */
198 1
    private function getPageFromRev(array $rev)
199
    {
200 1
        $namespaces = $this->project->getNamespaces();
201 1
        $pageTitle = $rev['page_title'];
202
203 1
        if ((int)$rev['page_namespace'] === 0) {
204 1
            $fullPageTitle = $pageTitle;
205
        } else {
206 1
            $fullPageTitle = $namespaces[$rev['page_namespace']].":$pageTitle";
207
        }
208
209 1
        return new Page($this->project, $fullPageTitle);
210
    }
211
212
    /**
213
     * Get counts of edits made to each individual category.
214
     * @return array Counts, keyed by category name.
215
     */
216 1
    public function getCategoryCounts()
217
    {
218 1
        if (is_array($this->categoryCounts)) {
0 ignored issues
show
introduced by
The condition is_array($this->categoryCounts) is always true.
Loading history...
219 1
            return $this->categoryCounts;
220
        }
221
222 1
        $this->categoryCounts = $this->getRepository()->getCategoryCounts(
223 1
            $this->project,
224 1
            $this->user,
225 1
            $this->categories,
226 1
            $this->start,
227 1
            $this->end
228
        );
229
230 1
        return $this->categoryCounts;
231
    }
232
}
233