Passed
Push — master ( 95d2e4...8875f5 )
by MusikAnimal
05:41
created

CategoryEdits   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 208
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 72
dl 0
loc 208
ccs 75
cts 75
cp 1
rs 10
c 0
b 0
f 0
wmc 20

11 Methods

Rating   Name   Duplication   Size   Complexity  
A getEditCount() 0 12 2
A getCategoriesNormalized() 0 5 1
A getCategoryEditCount() 0 15 2
A getEditsFromRevs() 0 9 1
A getPageFromRev() 0 12 2
A getCategories() 0 3 1
A getCategoryPercentage() 0 5 2
A getCategoryCounts() 0 17 2
A __construct() 0 16 3
A getCategoriesPiped() 0 3 1
A getCategoryEdits() 0 22 3
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
        $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 1
    public function getCategoriesNormalized()
78
    {
79
        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 contributions made to the categories.
136
     * @param bool $raw Wether to return raw data from the database, or get Edit objects.
137
     * @return string[]|Edit[]
138
     */
139 1
    public function getCategoryEdits($raw = false)
140
    {
141 1
        if (is_array($this->categoryEdits)) {
0 ignored issues
show
introduced by
The condition is_array($this->categoryEdits) is always true.
Loading history...
142 1
            return $this->categoryEdits;
143
        }
144
145 1
        $revs = $this->getRepository()->getCategoryEdits(
146 1
            $this->project,
147 1
            $this->user,
148 1
            $this->categories,
149 1
            $this->start,
150 1
            $this->end,
151 1
            $this->offset
152
        );
153
154 1
        if ($raw) {
155 1
            return $revs;
156
        }
157
158 1
        $this->categoryEdits = $this->getEditsFromRevs($revs);
159
160 1
        return $this->categoryEdits;
161
    }
162
163
    /**
164
     * Transform database rows into Edit objects.
165
     * @param string[] $revs
166
     * @return Edit[]
167
     */
168
    private function getEditsFromRevs(array $revs)
169
    {
170 1
        return array_map(function ($rev) {
171
            /* @var Page Page object to be passed to the Edit contructor. */
172 1
            $page = $this->getPageFromRev($rev);
173 1
            $rev['user'] = $this->user;
174
175 1
            return new Edit($page, $rev);
176 1
        }, $revs);
177
    }
178
179
    /**
180
     * Get a Page object given a revision row.
181
     * @param array $rev Revision as retrieved from the database.
182
     * @return Page
183
     */
184 1
    private function getPageFromRev(array $rev)
185
    {
186 1
        $namespaces = $this->project->getNamespaces();
187 1
        $pageTitle = $rev['page_title'];
188
189 1
        if ((int)$rev['page_namespace'] === 0) {
190 1
            $fullPageTitle = $pageTitle;
191
        } else {
192 1
            $fullPageTitle = $namespaces[$rev['page_namespace']].":$pageTitle";
193
        }
194
195 1
        return new Page($this->project, $fullPageTitle);
196
    }
197
198
    /**
199
     * Get counts of edits made to each individual category.
200
     * @return array Counts, keyed by category name.
201
     */
202 1
    public function getCategoryCounts()
203
    {
204 1
        if (is_array($this->categoryCounts)) {
0 ignored issues
show
introduced by
The condition is_array($this->categoryCounts) is always true.
Loading history...
205 1
            return $this->categoryCounts;
206
        }
207
208 1
        $this->categoryCounts = $this->getRepository()->getCategoryCounts(
209 1
            $this->project,
210 1
            $this->user,
211 1
            $this->categories,
212 1
            $this->start,
213 1
            $this->end
214
        );
215
216 1
        arsort($this->categoryCounts);
217
218 1
        return $this->categoryCounts;
219
    }
220
}
221