Test Setup Failed
Push — master ( 1f25c9...2084e1 )
by Simon
03:27
created

Ban::save()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 54
Code Lines 36

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
eloc 36
dl 0
loc 54
ccs 0
cts 33
cp 0
rs 9.0328
c 0
b 0
f 0
cc 5
nc 5
nop 0
crap 30

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/******************************************************************************
3
 * Wikipedia Account Creation Assistance tool                                 *
4
 *                                                                            *
5
 * All code in this file is released into the public domain by the ACC        *
6
 * Development Team. Please see team.json for a list of contributors.         *
7
 ******************************************************************************/
8
9
namespace Waca\DataObjects;
10
11
use Exception;
12
use PDO;
13
use Waca\DataObject;
14
use Waca\Exceptions\OptimisticLockFailedException;
15
use Waca\PdoDatabase;
16
17
/**
18
 * Ban data object
19
 */
20
class Ban extends DataObject
21
{
22
    const ACTION_BLOCK = 'block';
23
    const ACTION_DROP = 'drop';
24
    const ACTION_DEFER = 'defer';
25
    const ACTION_NONE = 'none';
26
27
    /** @var string|null */
28
    private $name;
29
    /** @var string|null */
30
    private $ip;
31
    /** @var int|null */
32
    private $ipmask;
33
    /** @var string|null */
34
    private $email;
35
    /** @var string|null */
36
    private $useragent;
37
38
    private $user;
39
    private $reason;
40
    private $date;
41
    private $duration;
42
    private $active;
43
    private $action = self::ACTION_BLOCK;
44
    private $targetqueue;
45
    private $visibility = 'user';
46
    private ?int $domain;
47
48
    /**
49
     * Gets all active bans, filtered by the optional target.
50
     *
51
     * @return Ban[]
52
     */
53
    public static function getActiveBans(PdoDatabase $database, int $domain)
54
    {
55
        $query = <<<SQL
56
SELECT * FROM ban 
57
WHERE (duration > UNIX_TIMESTAMP() OR duration is null) 
58
    AND active = 1
59
    AND (domain IS NULL OR domain = :domain);
60
SQL;
61
        $statement = $database->prepare($query);
62
        $statement->execute([':domain' => $domain]);
63
        $result = array();
64
65
        /** @var Ban $v */
66
        foreach ($statement->fetchAll(PDO::FETCH_CLASS, get_called_class()) as $v) {
67
            $v->setDatabase($database);
68
            $result[] = $v;
69
        }
70
71
        return $result;
72
    }
73
74
    /**
75
     * Gets a ban by its ID if it's currently active.
76
     *
77
     * @return Ban|false
78
     */
79
    public static function getActiveId($id, PdoDatabase $database, int $domain)
80
    {
81
        $statement = $database->prepare(<<<SQL
82
SELECT *
83
FROM ban
84
WHERE id = :id  
85
  AND (domain IS NULL OR domain = :domain)
86
  AND (duration > UNIX_TIMESTAMP() OR duration is null) 
87
  AND active = 1;
88
SQL
89
        );
90
        $statement->bindValue(":id", $id);
91
        $statement->bindValue(":domain", $domain);
92
93
        $statement->execute();
94
95
        $resultObject = $statement->fetchObject(get_called_class());
96
97
        if ($resultObject !== false) {
98
            $resultObject->setDatabase($database);
99
        }
100
101
        return $resultObject;
102
    }
103
104
    public static function getByIdList($values, PdoDatabase $database, int $domain): array
105
    {
106
        if (count($values) === 0) {
107
            return [];
108
        }
109
110
        // use the provided array to produce a list of question marks of the same length as the array.
111
        $valueCount = count($values);
112
        $inSection = str_repeat('?,', $valueCount - 1) . '?';
113
114
        // this is still parameterised! It's using positional parameters instead of named ones.
115
        $query = 'SELECT * FROM ban WHERE id IN (' . $inSection . ')';
116
117
        $query .= ' AND (domain IS NULL OR domain = ?)';
118
        $values[] = $domain;
119
120
        $statement = $database->prepare($query);
121
122
        // execute the statement with the provided parameter list.
123
        $statement->execute($values);
124
125
        $result = [];
126
        foreach ($statement->fetchAll(PDO::FETCH_CLASS, get_called_class()) as $v) {
127
            $v->setDatabase($database);
128
            $result[] = $v;
129
        }
130
131
        return $result;
132
    }
133
134
    /**
135
     * @throws Exception
136
     */
137
    public function save()
138
    {
139
        if ($this->isNew()) {
140
            // insert
141
            $statement = $this->dbObject->prepare(<<<SQL
142
INSERT INTO `ban` (name, email, ip, ipmask, useragent, user, reason, date, duration, active, action, targetqueue, visibility, domain)
143
VALUES (:name, :email, :ip, :ipmask, :useragent, :user, :reason, CURRENT_TIMESTAMP(), :duration, :active, :action, :targetqueue, :visibility, :domain);
144
SQL
145
            );
146
147
            $statement->bindValue(":name", $this->name);
148
            $statement->bindValue(":email", $this->email);
149
            $statement->bindValue(":ip", $this->ip);
150
            $statement->bindValue(":ipmask", $this->ipmask);
151
            $statement->bindValue(":useragent", $this->useragent);
152
153
            $statement->bindValue(":user", $this->user);
154
            $statement->bindValue(":reason", $this->reason);
155
            $statement->bindValue(":duration", $this->duration);
156
            $statement->bindValue(":active", $this->active);
157
            $statement->bindValue(":action", $this->action);
158
            $statement->bindValue(":targetqueue", $this->targetqueue);
159
            $statement->bindValue(":visibility", $this->visibility);
160
            $statement->bindValue(":domain", $this->domain);
161
162
            if ($statement->execute()) {
163
                $this->id = (int)$this->dbObject->lastInsertId();
164
            }
165
            else {
166
                throw new Exception($statement->errorInfo());
0 ignored issues
show
Bug introduced by
$statement->errorInfo() of type array is incompatible with the type string expected by parameter $message of Exception::__construct(). ( Ignorable by Annotation )

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

166
                throw new Exception(/** @scrutinizer ignore-type */ $statement->errorInfo());
Loading history...
167
            }
168
        }
169
        else {
170
            // update
171
            $statement = $this->dbObject->prepare(<<<SQL
172
UPDATE `ban`
173
SET active = :active, updateversion = updateversion + 1
174
WHERE id = :id AND updateversion = :updateversion;
175
SQL
176
            );
177
            $statement->bindValue(':id', $this->id);
178
            $statement->bindValue(':updateversion', $this->updateversion);
179
180
            $statement->bindValue(':active', $this->active);
181
182
            if (!$statement->execute()) {
183
                throw new Exception($statement->errorInfo());
184
            }
185
186
            if ($statement->rowCount() !== 1) {
187
                throw new OptimisticLockFailedException();
188
            }
189
190
            $this->updateversion++;
191
        }
192
    }
193
194
    /**
195
     * @return string
196
     */
197
    public function getReason()
198
    {
199
        return $this->reason;
200
    }
201
202
    /**
203
     * @param string $reason
204
     */
205
    public function setReason($reason)
206
    {
207
        $this->reason = $reason;
208
    }
209
210
    /**
211
     * @return mixed
212
     */
213
    public function getDate()
214
    {
215
        return $this->date;
216
    }
217
218
    /**
219
     * @return mixed
220
     */
221
    public function getDuration()
222
    {
223
        return $this->duration;
224
    }
225
226
    /**
227
     * @param mixed $duration
228
     */
229
    public function setDuration($duration)
230
    {
231
        $this->duration = $duration;
232
    }
233
234
    /**
235
     * @return bool
236
     */
237
    public function isActive()
238
    {
239
        return $this->active == 1;
240
    }
241
242
    /**
243
     * @param bool $active
244
     */
245
    public function setActive($active)
246
    {
247
        $this->active = $active ? 1 : 0;
248
    }
249
250
    /**
251
     * @return int
252
     */
253
    public function getUser()
254
    {
255
        return $this->user;
256
    }
257
258
    /**
259
     * @param int $user UserID of user who is setting the ban
260
     */
261
    public function setUser($user)
262
    {
263
        $this->user = $user;
264
    }
265
266
    /**
267
     * @return string
268
     */
269
    public function getAction(): string
270
    {
271
        return $this->action;
272
    }
273
274
    /**
275
     * @param string $action
276
     */
277
    public function setAction(string $action): void
278
    {
279
        $this->action = $action;
280
    }
281
282
    /**
283
     * @return string
284
     */
285
    public function getVisibility() : string
286
    {
287
        return $this->visibility;
288
    }
289
290
    /**
291
     * @param string $visibility
292
     */
293
    public function setVisibility(string $visibility): void
294
    {
295
        $this->visibility = $visibility;
296
    }
297
298
    /**
299
     * @return string|null
300
     */
301
    public function getName(): ?string
302
    {
303
        return $this->name;
304
    }
305
306
    /**
307
     * @param string|null $name
308
     */
309
    public function setName(?string $name): void
310
    {
311
        $this->name = $name;
312
    }
313
314
    /**
315
     * @return string|null
316
     */
317
    public function getIp(): ?string
318
    {
319
        if ($this->ip === null) {
320
            return null;
321
        }
322
323
        return inet_ntop($this->ip);
324
    }
325
326
    /**
327
     * @return int|null
328
     */
329
    public function getIpMask(): ?int
330
    {
331
        return $this->ipmask;
332
    }
333
334
    /**
335
     * @param string|null $ip
336
     * @param int|null    $mask
337
     */
338
    public function setIp(?string $ip, ?int $mask): void
339
    {
340
        if ($ip === null) {
341
            $this->ip = null;
342
        }
343
        else {
344
            $this->ip = inet_pton($ip);
345
        }
346
347
        $this->ipmask = $mask;
348
    }
349
350
    /**
351
     * @return string|null
352
     */
353
    public function getEmail(): ?string
354
    {
355
        return $this->email;
356
    }
357
358
    /**
359
     * @param string|null $email
360
     */
361
    public function setEmail(?string $email): void
362
    {
363
        $this->email = $email;
364
    }
365
366
    /**
367
     * @return string|null
368
     */
369
    public function getUseragent(): ?string
370
    {
371
        return $this->useragent;
372
    }
373
374
    /**
375
     * @param string|null $useragent
376
     */
377
    public function setUseragent(?string $useragent): void
378
    {
379
        $this->useragent = $useragent;
380
    }
381
382
    /**
383
     * @return int|null
384
     */
385
    public function getTargetQueue(): ?int
386
    {
387
        return $this->targetqueue;
388
    }
389
390
    /**
391
     * @return RequestQueue|null
392
     */
393
    public function getTargetQueueObject(): ?RequestQueue
394
    {
395
        /** @var RequestQueue $queue */
396
        $queue = RequestQueue::getById($this->targetqueue, $this->getDatabase());
397
        return $queue === false ? null : $queue;
0 ignored issues
show
introduced by
The condition $queue === false is always false.
Loading history...
398
    }
399
400
    /**
401
     * @param int|null $targetQueue
402
     */
403
    public function setTargetQueue(?int $targetQueue): void
404
    {
405
        $this->targetqueue = $targetQueue;
406
    }
407
408
    public function setDomain(?int $domain): void
409
    {
410
        $this->domain = $domain;
411
    }
412
413
    public function getDomain(): ?int
414
    {
415
        return $this->domain;
416
    }
417
}
418