Passed
Push — master ( 885c2d...cbeb5d )
by MusikAnimal
05:30
created

User::getId()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
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 66
    public function __construct($username)
34
    {
35 66
        $this->username = ucfirst(str_replace('_', ' ', trim($username)));
36
37
        // IPv6 address are stored as uppercased in the database.
38 66
        if ($this->isAnon()) {
39 6
            $this->username = strtoupper($this->username);
40
        }
41 66
    }
42
43
    /**
44
     * Get the username.
45
     * @return string
46
     */
47 17
    public function getUsername()
48
    {
49 17
        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
        return $this->getRepository()->getId($project->getDatabaseName(), $this->getUsername());
72
    }
73
74
    /**
75
     * Get the user's registration date on the given project.
76
     * @param Project $project
77
     * @return DateTime|false False if no registration date was found.
78
     */
79 1
    public function getRegistrationDate(Project $project)
80
    {
81 1
        $registrationDate = $this->getRepository()->getRegistrationDate(
82 1
            $project->getDatabaseName(),
83 1
            $this->getUsername()
84
        );
85
86 1
        return DateTime::createFromFormat('YmdHis', $registrationDate);
87
    }
88
89
    /**
90
     * Get a user's local user rights on the given Project.
91
     * @param  Project $project
92
     * @return string[]
93
     */
94 1
    public function getUserRights(Project $project)
95
    {
96 1
        return $this->getRepository()->getUserRights($project, $this);
97
    }
98
99
    /**
100
     * Get the user's (system) edit count.
101
     * @param Project $project
102
     * @return int
103
     */
104 2
    public function getEditCount(Project $project)
105
    {
106 2
        $domain = $project->getDomain();
107 2
        if (isset($this->editCounts[$domain])) {
108 1
            return $this->editCounts[$domain];
109
        }
110
111 2
        $this->editCounts[$domain] = (int) $this->getRepository()->getEditCount(
112 2
            $project->getDatabaseName(),
113 2
            $this->getUsername()
114
        );
115
116 2
        return $this->editCounts[$domain];
117
    }
118
119
    /**
120
     * Maximum number of edits to process, based on configuration.
121
     * @return int
122
     */
123 1
    public function maxEdits()
124
    {
125 1
        return $this->getRepository()->maxEdits();
126
    }
127
128
    /**
129
     * Get a list of this user's groups on the given project.
130
     * @param Project $project The project.
131
     * @return string[]
132
     */
133 2
    public function getGroups(Project $project)
134
    {
135 2
        $groupsData = $this->getRepository()->getGroups($project, $this->getUsername());
136 2
        $groups = preg_grep('/\*/', $groupsData, PREG_GREP_INVERT);
137 2
        sort($groups);
138 2
        return $groups;
139
    }
140
141
    /**
142
     * Get a list of this user's groups on all projects.
143
     * @param Project $project A project to query; if not provided, the default will be used.
144
     */
145
    public function getGlobalGroups(Project $project = null)
146
    {
147
        return $this->getRepository()->getGlobalGroups($this->getUsername(), $project);
148
    }
149
150
    /**
151
     * Does this user exist on the given project.
152
     * @param Project $project
153
     * @return bool
154
     */
155
    public function existsOnProject(Project $project)
156
    {
157
        $id = $this->getId($project);
158
        return $id > 0;
159
    }
160
161
    /**
162
     * Is this user an Administrator on the given project?
163
     * @param Project $project The project.
164
     * @return bool
165
     */
166 2
    public function isAdmin(Project $project)
167
    {
168 2
        return (false !== array_search('sysop', $this->getGroups($project)));
169
    }
170
171
    /**
172
     * Is this user an anonymous user (IP)?
173
     * @return bool
174
     */
175 66
    public function isAnon()
176
    {
177 66
        return (bool) filter_var($this->username, FILTER_VALIDATE_IP);
178
    }
179
180
    /**
181
     * Get the expiry of the current block on the user
182
     * @param Project $project The project.
183
     * @return DateTime|bool Expiry as DateTime, true if indefinite,
184
     *                       or false if they are not blocked.
185
     */
186 2
    public function getBlockExpiry(Project $project)
187
    {
188 2
        if (isset($this->blockExpiry)) {
189
            return $this->blockExpiry;
190
        }
191
192 2
        $expiry = $this->getRepository()->getBlockExpiry(
193 2
            $project->getDatabaseName(),
194 2
            $this->getUsername()
195
        );
196
197 2
        if ($expiry === 'infinity') {
198 1
            $this->blockExpiry = true;
199 1
        } elseif ($expiry === false) {
200
            $this->blockExpiry = false;
201
        } else {
202 1
            $this->blockExpiry = new DateTime($expiry);
203
        }
204
205 2
        return $this->blockExpiry;
206
    }
207
208
    /**
209
     * Is this user currently blocked on the given project?
210
     * @param Project $project The project.
211
     * @return bool
212
     */
213 1
    public function isBlocked(Project $project)
214
    {
215 1
        return $this->getBlockExpiry($project) !== false;
216
    }
217
218
    /**
219
     * Does the user have more edits than maximum amount allowed for processing?
220
     * @param Project $project
221
     * @return bool
222
     */
223 1
    public function hasTooManyEdits(Project $project)
224
    {
225 1
        $editCount = $this->getEditCount($project);
226 1
        return $this->maxEdits() > 0 && $editCount > $this->maxEdits();
227
    }
228
229
    /**
230
     * Get edit count within given timeframe and namespace
231
     * @param Project $project
232
     * @param int|string $namespace Namespace ID or 'all' for all namespaces
233
     * @param string $start Start date in a format accepted by strtotime()
234
     * @param string $end End date in a format accepted by strtotime()
235
     * @return int
236
     */
237 2
    public function countEdits(Project $project, $namespace = 'all', $start = '', $end = '')
238
    {
239 2
        return (int) $this->getRepository()->countEdits($project, $this, $namespace, $start, $end);
240
    }
241
242
    /**
243
     * Is this user the same as the current XTools user?
244
     * @return bool
245
     */
246 2
    public function isCurrentlyLoggedIn()
247
    {
248
        try {
249 2
            $ident = $this->getRepository()->getXtoolsUserInfo();
250 2
        } catch (Exception $exception) {
251 2
            return false;
252
        }
253
        return isset($ident->username) && $ident->username === $this->getUsername();
254
    }
255
}
256