Passed
Push — master ( 249321...cafa97 )
by MusikAnimal
05:17
created

User   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 233
Duplicated Lines 0 %

Test Coverage

Coverage 90.63%

Importance

Changes 0
Metric Value
dl 0
loc 233
ccs 58
cts 64
cp 0.9063
rs 10
c 0
b 0
f 0
wmc 25

17 Methods

Rating   Name   Duplication   Size   Complexity  
A getCacheKey() 0 3 1
A getUsername() 0 3 1
A __construct() 0 7 2
A getId() 0 8 1
A getRegistrationDate() 0 8 1
A getUserRights() 0 3 1
A getGlobalUserRights() 0 3 1
A maxEdits() 0 3 1
A countEdits() 0 3 1
A isAdmin() 0 3 1
A getBlockExpiry() 0 20 4
A isCurrentlyLoggedIn() 0 8 3
A isAnon() 0 3 1
A getEditCount() 0 13 2
A hasTooManyEdits() 0 4 2
A isBlocked() 0 3 1
A existsOnProject() 0 4 1
1
<?php
2
/**
3
 * This file contains only the User class.
4
 */
5
6
namespace Xtools;
7
8
use Exception;
9
use DateTime;
10
11
/**
12
 * A User is a wiki user who has the same username across all projects in an XTools installation.
13
 */
14
class User extends Model
15
{
16
17
    /** @var int The user's ID. */
18
    protected $id;
19
20
    /** @var string The user's username. */
21
    protected $username;
22
23
    /** @var DateTime|bool Expiry of the current block of the user. */
24
    protected $blockExpiry;
25
26
    /** @var int Quick cache of edit counts, keyed by project domain. */
27
    protected $editCounts = [];
28
29
    /**
30
     * Create a new User given a username.
31
     * @param string $username
32
     */
33 65
    public function __construct($username)
34
    {
35 65
        $this->username = ucfirst(str_replace('_', ' ', trim($username)));
36
37
        // IPv6 address are stored as uppercased in the database.
38 65
        if ($this->isAnon()) {
39 6
            $this->username = strtoupper($this->username);
40
        }
41 65
    }
42
43
    /**
44
     * Get the username.
45
     * @return string
46
     */
47 16
    public function getUsername()
48
    {
49 16
        return $this->username;
50
    }
51
52
    /**
53
     * Unique identifier for this User, to be used in cache keys.
54
     * Use of md5 ensures the cache key does not contain reserved characters.
55
     * You could also use the ID, but that may require an unnecessary DB query.
56
     * @see Repository::getCacheKey()
57
     * @return string
58
     */
59 1
    public function getCacheKey()
60
    {
61 1
        return md5($this->username);
62
    }
63
64
    /**
65
     * Get the user's ID on the given project.
66
     * @param Project $project
67
     * @return int
68
     */
69 1
    public function getId(Project $project)
70
    {
71 1
        $ret = $this->getRepository()->getIdAndRegistration(
72 1
            $project->getDatabaseName(),
73 1
            $this->getUsername()
74
        );
75
76 1
        return (int)$ret['userId'];
77
    }
78
79
    /**
80
     * Get the user's registration date on the given project.
81
     * @param Project $project
82
     * @return DateTime|false False if no registration date was found.
83
     */
84 1
    public function getRegistrationDate(Project $project)
85
    {
86 1
        $ret = $this->getRepository()->getIdAndRegistration(
87 1
            $project->getDatabaseName(),
88 1
            $this->getUsername()
89
        );
90
91 1
        return DateTime::createFromFormat('YmdHis', $ret['regDate']);
92
    }
93
94
    /**
95
     * Get a user's local user rights on the given Project.
96
     * @param  Project $project
97
     * @return string[]
98
     */
99 3
    public function getUserRights(Project $project)
100
    {
101 3
        return $this->getRepository()->getUserRights($project, $this);
102
    }
103
104
    /**
105
     * Get a list of this user's global rights.
106
     * @param Project $project A project to query; if not provided, the default will be used.
107
     * @return string[]
108
     */
109 1
    public function getGlobalUserRights(Project $project = null)
110
    {
111 1
        return $this->getRepository()->getGlobalUserRights($this->getUsername(), $project);
112
    }
113
114
    /**
115
     * Get the user's (system) edit count.
116
     * @param Project $project
117
     * @return int
118
     */
119 2
    public function getEditCount(Project $project)
120
    {
121 2
        $domain = $project->getDomain();
122 2
        if (isset($this->editCounts[$domain])) {
123 1
            return $this->editCounts[$domain];
124
        }
125
126 2
        $this->editCounts[$domain] = (int) $this->getRepository()->getEditCount(
127 2
            $project->getDatabaseName(),
128 2
            $this->getUsername()
129
        );
130
131 2
        return $this->editCounts[$domain];
132
    }
133
134
    /**
135
     * Maximum number of edits to process, based on configuration.
136
     * @return int
137
     */
138 1
    public function maxEdits()
139
    {
140 1
        return $this->getRepository()->maxEdits();
141
    }
142
143
    /**
144
     * Does this user exist on the given project.
145
     * @param Project $project
146
     * @return bool
147
     */
148
    public function existsOnProject(Project $project)
149
    {
150
        $id = $this->getId($project);
151
        return $id > 0;
152
    }
153
154
    /**
155
     * Is this user an Administrator on the given project?
156
     * @param Project $project The project.
157
     * @return bool
158
     */
159 2
    public function isAdmin(Project $project)
160
    {
161 2
        return (false !== array_search('sysop', $this->getUserRights($project)));
162
    }
163
164
    /**
165
     * Is this user an anonymous user (IP)?
166
     * @return bool
167
     */
168 65
    public function isAnon()
169
    {
170 65
        return (bool) filter_var($this->username, FILTER_VALIDATE_IP);
171
    }
172
173
    /**
174
     * Get the expiry of the current block on the user
175
     * @param Project $project The project.
176
     * @return DateTime|bool Expiry as DateTime, true if indefinite,
177
     *                       or false if they are not blocked.
178
     */
179 2
    public function getBlockExpiry(Project $project)
180
    {
181 2
        if (isset($this->blockExpiry)) {
182
            return $this->blockExpiry;
183
        }
184
185 2
        $expiry = $this->getRepository()->getBlockExpiry(
186 2
            $project->getDatabaseName(),
187 2
            $this->getUsername()
188
        );
189
190 2
        if ($expiry === 'infinity') {
191 1
            $this->blockExpiry = true;
192 1
        } elseif ($expiry === false) {
193
            $this->blockExpiry = false;
194
        } else {
195 1
            $this->blockExpiry = new DateTime($expiry);
196
        }
197
198 2
        return $this->blockExpiry;
199
    }
200
201
    /**
202
     * Is this user currently blocked on the given project?
203
     * @param Project $project The project.
204
     * @return bool
205
     */
206 1
    public function isBlocked(Project $project)
207
    {
208 1
        return $this->getBlockExpiry($project) !== false;
209
    }
210
211
    /**
212
     * Does the user have more edits than maximum amount allowed for processing?
213
     * @param Project $project
214
     * @return bool
215
     */
216 1
    public function hasTooManyEdits(Project $project)
217
    {
218 1
        $editCount = $this->getEditCount($project);
219 1
        return $this->maxEdits() > 0 && $editCount > $this->maxEdits();
220
    }
221
222
    /**
223
     * Get edit count within given timeframe and namespace
224
     * @param Project $project
225
     * @param int|string $namespace Namespace ID or 'all' for all namespaces
226
     * @param string $start Start date in a format accepted by strtotime()
227
     * @param string $end End date in a format accepted by strtotime()
228
     * @return int
229
     */
230 2
    public function countEdits(Project $project, $namespace = 'all', $start = '', $end = '')
231
    {
232 2
        return (int) $this->getRepository()->countEdits($project, $this, $namespace, $start, $end);
233
    }
234
235
    /**
236
     * Is this user the same as the current XTools user?
237
     * @return bool
238
     */
239 2
    public function isCurrentlyLoggedIn()
240
    {
241
        try {
242 2
            $ident = $this->getRepository()->getXtoolsUserInfo();
243 2
        } catch (Exception $exception) {
244 2
            return false;
245
        }
246
        return isset($ident->username) && $ident->username === $this->getUsername();
247
    }
248
}
249