Passed
Push — master ( a61c57...8dbe0a )
by MusikAnimal
10:33
created

AutoEdits::__construct()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 16
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 7
nc 4
nop 7
dl 0
loc 16
ccs 8
cts 8
cp 1
crap 3
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * This file contains only the AutoEdits class.
4
 */
5
6
declare(strict_types = 1);
7
8
namespace AppBundle\Model;
9
10
/**
11
 * AutoEdits returns statistics about automated edits made by a user.
12
 */
13
class AutoEdits extends Model
14
{
15
    /** @var null|string The tool we're searching for when fetching (semi-)automated edits. */
16
    protected $tool;
17
18
    /** @var Edit[] The list of non-automated contributions. */
19
    protected $nonAutomatedEdits;
20
21
    /** @var Edit[] The list of automated contributions. */
22
    protected $automatedEdits;
23
24
    /** @var int Total number of edits. */
25
    protected $editCount;
26
27
    /** @var int Total number of non-automated edits. */
28
    protected $automatedCount;
29
30
    /** @var array Counts of known automated tools used by the given user. */
31
    protected $toolCounts;
32
33
    /** @var int Total number of edits made with the tools. */
34
    protected $toolsTotal;
35
36
    /**
37
     * Constructor for the AutoEdits class.
38
     * @param Project $project
39
     * @param User $user
40
     * @param int|string $namespace Namespace ID or 'all'
41
     * @param int|false $start Start date in a format accepted by strtotime()
42
     * @param int|false $end End date in a format accepted by strtotime()
43
     * @param string $tool The tool we're searching for when fetching (semi-)automated edits.
44
     * @param int|string $offset Used for pagination, offset results by N edits.
45
     */
46 5
    public function __construct(
47
        Project $project,
48
        User $user,
49
        $namespace = 0,
50
        $start = false,
51
        $end = false,
52
        $tool = null,
53
        $offset = 0
54
    ) {
55 5
        $this->project = $project;
56 5
        $this->user = $user;
57 5
        $this->namespace = $namespace;
58 5
        $this->start = false === $start ? '' : date('Y-m-d', $start);
59 5
        $this->end = false === $end ? '' : date('Y-m-d', $end);
60 5
        $this->tool = $tool;
61 5
        $this->offset = $offset;
0 ignored issues
show
Documentation Bug introduced by
It seems like $offset can also be of type string. However, the property $offset is declared as type integer. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
62 5
    }
63
64
    /**
65
     * The tool we're limiting the results to when fetching
66
     * (semi-)automated contributions.
67
     * @return null|string
68
     */
69 1
    public function getTool(): ?string
70
    {
71 1
        return $this->tool;
72
    }
73
74
    /**
75
     * Get the raw edit count of the user.
76
     * @return int
77
     */
78 1
    public function getEditCount(): int
79
    {
80 1
        if (!is_int($this->editCount)) {
0 ignored issues
show
introduced by
The condition is_int($this->editCount) is always true.
Loading history...
81 1
            $this->editCount = $this->user->countEdits(
82 1
                $this->project,
83 1
                $this->namespace,
84 1
                $this->start,
85 1
                $this->end
86
            );
87
        }
88
89 1
        return $this->editCount;
90
    }
91
92
    /**
93
     * Get the number of edits this user made using semi-automated tools.
94
     * This is not the same as self::getToolCounts because the regex can overlap.
95
     * @return int Result of query, see below.
96
     */
97 1
    public function getAutomatedCount(): int
98
    {
99 1
        if (is_int($this->automatedCount)) {
0 ignored issues
show
introduced by
The condition is_int($this->automatedCount) is always true.
Loading history...
100 1
            return $this->automatedCount;
101
        }
102
103 1
        $this->automatedCount = (int)$this->getRepository()->countAutomatedEdits(
104 1
            $this->project,
105 1
            $this->user,
106 1
            $this->namespace,
107 1
            $this->start,
108 1
            $this->end
109
        );
110
111 1
        return $this->automatedCount;
112
    }
113
114
    /**
115
     * Get the percentage of all edits made using automated tools.
116
     * @return float
117
     */
118 1
    public function getAutomatedPercentage(): float
119
    {
120 1
        return $this->getEditCount() > 0
121 1
            ? ($this->getAutomatedCount() / $this->getEditCount()) * 100
122 1
            : 0;
123
    }
124
125
    /**
126
     * Get non-automated contributions for this user.
127
     * @param bool $raw Wether to return raw data from the database, or get Edit objects.
128
     * @return string[]|Edit[]
129
     */
130 1
    public function getNonAutomatedEdits(bool $raw = false)
131
    {
132 1
        if (is_array($this->nonAutomatedEdits)) {
0 ignored issues
show
introduced by
The condition is_array($this->nonAutomatedEdits) is always true.
Loading history...
133 1
            return $this->nonAutomatedEdits;
134
        }
135
136 1
        $revs = $this->getRepository()->getNonAutomatedEdits(
137 1
            $this->project,
138 1
            $this->user,
139 1
            $this->namespace,
140 1
            $this->start,
141 1
            $this->end,
142 1
            $this->offset
143
        );
144
145 1
        if ($raw) {
146 1
            return $revs;
147
        }
148
149 1
        $this->nonAutomatedEdits = Edit::getEditsFromRevs($this->project, $this->user, $revs);
150
151 1
        return $this->nonAutomatedEdits;
152
    }
153
154
    /**
155
     * Get automated contributions for this user.
156
     * @param bool $raw Whether to return raw data from the database, or get Edit objects.
157
     * @return Edit[]
158
     */
159 1
    public function getAutomatedEdits(bool $raw = false): array
160
    {
161 1
        if (is_array($this->automatedEdits)) {
0 ignored issues
show
introduced by
The condition is_array($this->automatedEdits) is always true.
Loading history...
162 1
            return $this->automatedEdits;
163
        }
164
165 1
        $revs = $this->getRepository()->getAutomatedEdits(
166 1
            $this->project,
167 1
            $this->user,
168 1
            $this->namespace,
169 1
            $this->start,
170 1
            $this->end,
171 1
            $this->tool,
172 1
            $this->offset
173
        );
174
175 1
        if ($raw) {
176 1
            return $revs;
177
        }
178
179 1
        $this->automatedEdits = Edit::getEditsFromRevs($this->project, $this->user, $revs);
180
181 1
        return $this->automatedEdits;
182
    }
183
184
    /**
185
     * Get counts of known automated tools used by the given user.
186
     * @return array Each tool that they used along with the count and link:
187
     *                  [
188
     *                      'Twinkle' => [
189
     *                          'count' => 50,
190
     *                          'link' => 'Wikipedia:Twinkle',
191
     *                      ],
192
     *                  ]
193
     */
194 1
    public function getToolCounts(): array
195
    {
196 1
        if (is_array($this->toolCounts)) {
0 ignored issues
show
introduced by
The condition is_array($this->toolCounts) is always true.
Loading history...
197 1
            return $this->toolCounts;
198
        }
199
200 1
        $this->toolCounts = $this->getRepository()->getToolCounts(
201 1
            $this->project,
202 1
            $this->user,
203 1
            $this->namespace,
204 1
            $this->start,
205 1
            $this->end
206
        );
207
208 1
        return $this->toolCounts;
209
    }
210
211
    /**
212
     * Get a list of all available tools for the Project.
213
     * @return array
214
     */
215
    public function getAllTools(): array
216
    {
217
        return $this->getRepository()->getTools($this->project);
0 ignored issues
show
Bug introduced by
The method getTools() does not exist on AppBundle\Repository\Repository. Did you maybe mean getToolsConnection()? ( Ignorable by Annotation )

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

217
        return $this->getRepository()->/** @scrutinizer ignore-call */ getTools($this->project);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
218
    }
219
220
    /**
221
     * Get the combined number of edits made with each tool. This is calculated separately from
222
     * self::getAutomatedCount() because the regex can sometimes overlap, and the counts are actually different.
223
     * @return int
224
     */
225 1
    public function getToolsTotal(): int
226
    {
227 1
        if (!is_int($this->toolsTotal)) {
0 ignored issues
show
introduced by
The condition is_int($this->toolsTotal) is always true.
Loading history...
228 1
            $this->toolsTotal = array_reduce($this->getToolCounts(), function ($a, $b) {
229 1
                return $a + $b['count'];
230 1
            });
231
        }
232
233
        return $this->toolsTotal;
234
    }
235
}
236