Passed
Push — master ( fb9a7c...4fa4cb )
by MusikAnimal
05:25
created

User::existsOnProject()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
ccs 0
cts 2
cp 0
crap 2
1
<?php
2
/**
3
 * This file contains only the User class.
4
 */
5
6
declare(strict_types = 1);
7
8
namespace AppBundle\Model;
9
10
use DateTime;
11
use Exception;
12
13
/**
14
 * A User is a wiki user who has the same username across all projects in an XTools installation.
15
 */
16
class User extends Model
17
{
18
    /** @var string The user's username. */
19
    protected $username;
20
21
    /** @var int Quick cache of edit counts, keyed by project domain. */
22
    protected $editCounts = [];
23
24
    /**
25
     * Create a new User given a username.
26
     * @param string $username
27
     */
28 62
    public function __construct(string $username)
29
    {
30 62
        $this->username = ucfirst(str_replace('_', ' ', trim($username)));
31
32
        // IPv6 address are stored as uppercase in the database.
33 62
        if ($this->isAnon()) {
34 6
            $this->username = strtoupper($this->username);
35
        }
36 62
    }
37
38
    /**
39
     * Get the username.
40
     * @return string
41
     */
42 16
    public function getUsername(): string
43
    {
44 16
        return $this->username;
45
    }
46
47
    /**
48
     * Unique identifier for this User, to be used in cache keys. Use of md5 ensures the cache key does not contain
49
     * reserved characters. You could also use the ID, but that may require an unnecessary DB query.
50
     * @see Repository::getCacheKey()
51
     * @return string
52
     */
53 1
    public function getCacheKey(): string
54
    {
55 1
        return md5($this->username);
56
    }
57
58
    /**
59
     * Get the user's ID on the given project.
60
     * @param Project $project
61
     * @return int
62
     */
63 1
    public function getId(Project $project): int
64
    {
65 1
        $ret = $this->getRepository()->getIdAndRegistration(
0 ignored issues
show
Bug introduced by
The method getIdAndRegistration() does not exist on AppBundle\Repository\Repository. It seems like you code against a sub-type of AppBundle\Repository\Repository such as AppBundle\Repository\UserRepository. ( Ignorable by Annotation )

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

65
        $ret = $this->getRepository()->/** @scrutinizer ignore-call */ getIdAndRegistration(
Loading history...
66 1
            $project->getDatabaseName(),
67 1
            $this->getUsername()
68
        );
69
70 1
        return (int)$ret['userId'];
71
    }
72
73
    /**
74
     * Get the user's actor ID on the given project.
75
     * @param Project $project
76
     * @return int
77
     */
78
    public function getActorId(Project $project): int
79
    {
80
        $ret = $this->getRepository()->getActorId(
0 ignored issues
show
Bug introduced by
The method getActorId() does not exist on AppBundle\Repository\Repository. It seems like you code against a sub-type of AppBundle\Repository\Repository such as AppBundle\Repository\UserRepository. ( Ignorable by Annotation )

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

80
        $ret = $this->getRepository()->/** @scrutinizer ignore-call */ getActorId(
Loading history...
81
            $project->getDatabaseName(),
82
            $this->getUsername()
83
        );
84
85
        return (int)$ret['actorId'];
86
    }
87
88
    /**
89
     * Get the user's registration date on the given project.
90
     * @param Project $project
91
     * @return DateTime|null null if no registration date was found.
92
     */
93 1
    public function getRegistrationDate(Project $project): ?DateTime
94
    {
95 1
        $ret = $this->getRepository()->getIdAndRegistration(
96 1
            $project->getDatabaseName(),
97 1
            $this->getUsername()
98
        );
99
100 1
        return null !== $ret['regDate']
101 1
            ? DateTime::createFromFormat('YmdHis', $ret['regDate'])
102 1
            : null;
103
    }
104
105
    /**
106
     * Get a user's local user rights on the given Project.
107
     * @param Project $project
108
     * @return string[]
109
     */
110 3
    public function getUserRights(Project $project): array
111
    {
112 3
        return $this->getRepository()->getUserRights($project, $this);
0 ignored issues
show
Bug introduced by
The method getUserRights() does not exist on AppBundle\Repository\Repository. It seems like you code against a sub-type of AppBundle\Repository\Repository such as AppBundle\Repository\UserRepository. ( Ignorable by Annotation )

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

112
        return $this->getRepository()->/** @scrutinizer ignore-call */ getUserRights($project, $this);
Loading history...
113
    }
114
115
    /**
116
     * Get a list of this user's global rights.
117
     * @param Project|null $project A project to query; if not provided, the default will be used.
118
     * @return string[]
119
     */
120 1
    public function getGlobalUserRights(?Project $project = null): array
121
    {
122 1
        return $this->getRepository()->getGlobalUserRights($this->getUsername(), $project);
0 ignored issues
show
Bug introduced by
The method getGlobalUserRights() does not exist on AppBundle\Repository\Repository. It seems like you code against a sub-type of AppBundle\Repository\Repository such as AppBundle\Repository\UserRepository. ( Ignorable by Annotation )

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

122
        return $this->getRepository()->/** @scrutinizer ignore-call */ getGlobalUserRights($this->getUsername(), $project);
Loading history...
123
    }
124
125
    /**
126
     * Get the user's (system) edit count.
127
     * @param Project $project
128
     * @return int
129
     */
130 2
    public function getEditCount(Project $project): int
131
    {
132 2
        $domain = $project->getDomain();
133 2
        if (isset($this->editCounts[$domain])) {
134 1
            return $this->editCounts[$domain];
135
        }
136
137 2
        $this->editCounts[$domain] = (int)$this->getRepository()->getEditCount(
0 ignored issues
show
Bug introduced by
The method getEditCount() does not exist on AppBundle\Repository\Repository. It seems like you code against a sub-type of AppBundle\Repository\Repository such as AppBundle\Repository\UserRepository. ( Ignorable by Annotation )

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

137
        $this->editCounts[$domain] = (int)$this->getRepository()->/** @scrutinizer ignore-call */ getEditCount(
Loading history...
138 2
            $project->getDatabaseName(),
139 2
            $this->getUsername()
140
        );
141
142 2
        return $this->editCounts[$domain];
143
    }
144
145
    /**
146
     * Maximum number of edits to process, based on configuration.
147
     * @return int
148
     */
149 1
    public function maxEdits(): int
150
    {
151 1
        return $this->getRepository()->maxEdits();
0 ignored issues
show
Bug introduced by
The method maxEdits() does not exist on AppBundle\Repository\Repository. It seems like you code against a sub-type of AppBundle\Repository\Repository such as AppBundle\Repository\UserRepository. ( Ignorable by Annotation )

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

151
        return $this->getRepository()->/** @scrutinizer ignore-call */ maxEdits();
Loading history...
152
    }
153
154
    /**
155
     * Does this user exist on the given project.
156
     * @param Project $project
157
     * @return bool
158
     */
159
    public function existsOnProject(Project $project): bool
160
    {
161
        return $this->getId($project) > 0;
162
    }
163
164
    /**
165
     * Is this user an Administrator on the given project?
166
     * @param Project $project The project.
167
     * @return bool
168
     */
169 2
    public function isAdmin(Project $project): bool
170
    {
171 2
        return false !== array_search('sysop', $this->getUserRights($project));
172
    }
173
174
    /**
175
     * Is this user an anonymous user (IP)?
176
     * @return bool
177
     */
178 62
    public function isAnon(): bool
179
    {
180 62
        return (bool)filter_var($this->username, FILTER_VALIDATE_IP);
181
    }
182
183
    /**
184
     * Get the expiry of the current block on the user
185
     * @param Project $project The project.
186
     * @return DateTime|bool Expiry as DateTime, true if indefinite, or false if they are not blocked.
187
     */
188 2
    public function getBlockExpiry(Project $project)
189
    {
190 2
        $expiry = $this->getRepository()->getBlockExpiry(
0 ignored issues
show
Bug introduced by
The method getBlockExpiry() does not exist on AppBundle\Repository\Repository. It seems like you code against a sub-type of AppBundle\Repository\Repository such as AppBundle\Repository\UserRepository. ( Ignorable by Annotation )

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

190
        $expiry = $this->getRepository()->/** @scrutinizer ignore-call */ getBlockExpiry(
Loading history...
191 2
            $project->getDatabaseName(),
192 2
            $this->getUsername()
193
        );
194
195 2
        if ('infinity' === $expiry) {
196 1
            return true;
197 1
        } elseif (false === $expiry) {
198
            return false;
199
        } else {
200 1
            return new DateTime($expiry);
201
        }
202
    }
203
204
    /**
205
     * Is this user currently blocked on the given project?
206
     * @param Project $project The project.
207
     * @return bool
208
     */
209 1
    public function isBlocked(Project $project): bool
210
    {
211 1
        return false !== $this->getBlockExpiry($project);
212
    }
213
214
    /**
215
     * Does the user have more edits than maximum amount allowed for processing?
216
     * @param Project $project
217
     * @return bool
218
     */
219 1
    public function hasTooManyEdits(Project $project): bool
220
    {
221 1
        $editCount = $this->getEditCount($project);
222 1
        return $this->maxEdits() > 0 && $editCount > $this->maxEdits();
223
    }
224
225
    /**
226
     * Get edit count within given timeframe and namespace
227
     * @param Project $project
228
     * @param int|string $namespace Namespace ID or 'all' for all namespaces
229
     * @param string $start Start date in a format accepted by strtotime()
230
     * @param string $end End date in a format accepted by strtotime()
231
     * @return int
232
     */
233 2
    public function countEdits(Project $project, $namespace = 'all', $start = '', $end = ''): int
234
    {
235 2
        return (int) $this->getRepository()->countEdits($project, $this, $namespace, $start, $end);
0 ignored issues
show
Bug introduced by
The method countEdits() does not exist on AppBundle\Repository\Repository. It seems like you code against a sub-type of AppBundle\Repository\Repository such as AppBundle\Repository\UserRepository. ( Ignorable by Annotation )

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

235
        return (int) $this->getRepository()->/** @scrutinizer ignore-call */ countEdits($project, $this, $namespace, $start, $end);
Loading history...
236
    }
237
238
    /**
239
     * Is this user the same as the current XTools user?
240
     * @return bool
241
     */
242 2
    public function isCurrentlyLoggedIn(): bool
243
    {
244
        try {
245 2
            $ident = $this->getRepository()->getXtoolsUserInfo();
0 ignored issues
show
Bug introduced by
The method getXtoolsUserInfo() does not exist on AppBundle\Repository\Repository. It seems like you code against a sub-type of AppBundle\Repository\Repository such as AppBundle\Repository\UserRepository. ( Ignorable by Annotation )

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

245
            $ident = $this->getRepository()->/** @scrutinizer ignore-call */ getXtoolsUserInfo();
Loading history...
246 2
        } catch (Exception $exception) {
247 2
            return false;
248
        }
249
        return isset($ident->username) && $ident->username === $this->getUsername();
250
    }
251
}
252