Completed
Pull Request — master (#2737)
by Jeroen
17:30 queued 02:36
created

BaseUser::setEnabled()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 0
cts 0
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 2
1
<?php
2
3
namespace Kunstmaan\AdminBundle\Entity;
4
5
use DateTime;
6
use Doctrine\Common\Collections\ArrayCollection;
7
use Doctrine\ORM\Mapping as ORM;
8
use FOS\UserBundle\Model\GroupInterface;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Kunstmaan\AdminBundle\Entity\GroupInterface.

Let’s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let’s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
9
use Kunstmaan\AdminBundle\Validator\Constraints\PasswordRestrictions;
10
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
11
use Symfony\Component\Validator\Constraints\Email;
12
use Symfony\Component\Validator\Constraints\NotBlank;
13
use Symfony\Component\Validator\Mapping\ClassMetadata;
14
15
abstract class BaseUser implements UserInterface
16
{
17
    /**
18
     * @ORM\Id
19
     * @ORM\Column(type="integer")
20
     * @ORM\GeneratedValue(strategy="AUTO")
21
     */
22
    protected $id;
23
24
    /**
25
     * @var string
26
     *
27
     * @ORM\Column(type="string", length=180, unique=true)
28
     */
29
    protected $username;
30
31
    /**
32
     * Next Major: Remove attribute
33
     *
34
     * @var string
35
     *
36
     * @ORM\Column(type="string", length=180, unique=true)
37
     */
38
    protected $usernameCanonical;
39
40
    /**
41
     * The doctrine metadata is set dynamically in Kunstmaan\AdminBundle\EventListener\MappingListener
42
     */
43
    protected $groups;
44
45
    /**
46
     * @ORM\Column(type="string", name="admin_locale", length=5, nullable=true)
47
     */
48
    protected $adminLocale;
49
50
    /**
51
     * @ORM\Column(type="boolean", name="password_changed", nullable=true)
52
     */
53
    protected $passwordChanged;
54
55
    /**
56
     * @ORM\Column(name="google_id", type="string", length=255, nullable=true)
57
     */
58
    protected $googleId;
59 35
60
    /**
61 35
     * @var string
62 35
     *
63 35
     * @ORM\Column(type="string", length=180, unique=true)
64 35
     */
65
    protected $email;
66
67
    /**
68
     * Next Major: Remove attribute
69
     *
70
     * @var string
71 3
     *
72
     * @ORM\Column(type="string", length=180, unique=true)
73 3
     */
74
    protected $emailCanonical;
75
76
    /**
77
     * @var string
78
     *
79
     * @ORM\Column(name="password", type="string", length=100)
80
     */
81
    protected $password;
82
83 8
    /**
84
     * @var string|null
85 8
     */
86
    protected $plainPassword;
87 8
88
    /**
89
     * @var string|null
90
     *
91
     * @ORM\Column(type="string", length=255, nullable=true)
92
     */
93
    protected $confirmationToken;
94
95 1
    /**
96
     * @var string
97 1
     *
98
     * @ORM\Column(name="salt", type="string", length=100)
99 1
     */
100 1
    protected $salt;
101
102 1
    /**
103 1
     * @var \DateTime
104
     *
105
     * @ORM\Column(name="last_login", type="datetime", nullable=true)
106
     */
107 1
    protected $lastLogin;
108
109
    /**
110
     * @var array
111
     *
112
     * @ORM\Column(name="roles", type="array")
113
     */
114
    protected $roles;
115 6
116
    /**
117 6
     * @ORM\Column(name="enabled", type="boolean")
118
     */
119
    protected $enabled;
120
121
    /**
122
     * @var \DateTimeImmutable|null
123
     * @ORM\Column(name="created_at", type="datetime_immutable", nullable=true)
124
     */
125 1
    protected $createdAt;
126
127 1
    /**
128
     * @var string|null
129
     * @ORM\Column(name="created_by", type="string", nullable=true)
130
     */
131
    protected $createdBy;
132
133
    /**
134
     * Construct a new user
135
     */
136
    public function __construct()
137 2
    {
138
        $this->groups = new ArrayCollection();
139 2
        $this->roles = [];
140
        $this->createdAt = new \DateTimeImmutable();
141 2
    }
142
143
    /**
144
     * Get id
145
     *
146
     * @return int
147
     */
148
    public function getId()
149 1
    {
150
        return $this->id;
151 1
    }
152
153
    /**
154
     * Set id
155
     *
156
     * @param int $id
157
     *
158
     * @return BaseUser
159
     */
160
    public function setId($id)
161 2
    {
162
        $this->id = $id;
163 2
164
        return $this;
165 2
    }
166
167
    /**
168
     * Gets the groupIds for the user.
169
     *
170
     * @return array
171 1
     */
172
    public function getGroupIds()
173 1
    {
174
        $groups = $this->groups;
175
176
        $groupIds = [];
177
        if (\count($groups) > 0) {
178
            /* @var $group GroupInterface */
179 3
            foreach ($groups as $group) {
180
                $groupIds[] = $group->getId();
181 3
            }
182 3
        }
183
184
        return $groupIds;
185
    }
186
187 1
    /**
188
     * Gets the groups the user belongs to.
189 1
     *
190 1
     * @return ArrayCollection
191 1
     */
192
    public function getGroups()
193 1
    {
194 1
        return $this->groups;
195
    }
196
197 1
    /**
198 1
     * Get adminLocale
199 1
     *
200 1
     * @return string
201
     */
202
    public function getAdminLocale()
203 1
    {
204 1
        return $this->adminLocale;
205
    }
206
207 1
    /**
208
     * {@inheritdoc}
209
     */
210
    public function setEnabled($boolean)
211
    {
212
        $this->enabled = (bool) $boolean;
213
214
        return $this;
215
    }
216
217
    /**
218
     * Set adminLocale
219 1
     *
220
     * @param string $adminLocale
221 1
     *
222
     * @return BaseUser
223
     */
224
    public function setAdminLocale($adminLocale)
225
    {
226
        $this->adminLocale = $adminLocale;
227
228
        return $this;
229
    }
230
231
    /**
232
     * is passwordChanged
233
     *
234
     * @return bool
235
     */
236
    public function isPasswordChanged()
237
    {
238
        return $this->passwordChanged;
239
    }
240
241
    public function setPasswordChanged($passwordChanged)
242
    {
243
        $this->passwordChanged = $passwordChanged;
244
245
        return $this;
246
    }
247
248
    /**
249
     * @return mixed
250
     */
251
    public function getGoogleId()
252
    {
253
        return $this->googleId;
254
    }
255
256
    /**
257
     * @param mixed $googleId
258
     */
259
    public function setGoogleId($googleId)
260
    {
261
        $this->googleId = $googleId;
262
    }
263
264
    public static function loadValidatorMetadata(ClassMetadata $metadata)
265
    {
266
        $metadata->addPropertyConstraint('username', new NotBlank());
267
        $metadata->addPropertyConstraints(
268
            'plainPassword',
269
            [
270
                new NotBlank(['groups' => ['Registration']]),
271
                new PasswordRestrictions(['groups' => ['Registration', 'Default']]),
272
            ]
273
        );
274
        $metadata->addPropertyConstraint('email', new NotBlank());
275
        $metadata->addPropertyConstraint('email', new Email());
276
        $metadata->addConstraint(new UniqueEntity([
277
            'fields' => 'username',
278
            'message' => 'errors.user.loginexists',
279
        ]));
280
        $metadata->addConstraint(new UniqueEntity([
281
            'fields' => 'email',
282
            'message' => 'errors.user.emailexists',
283
        ]));
284
    }
285
286
    /**
287
     * Return class name of form type used to add & edit users
288
     *
289
     * @return string
290
     */
291
    abstract public function getFormTypeClass();
292
293
    /**
294
     * {@inheritdoc}
295
     */
296
    public function isAccountNonLocked()
297
    {
298
        return $this->isEnabled();
299
    }
300
301
    public function getEmail(): string
302
    {
303
        return $this->email;
304
    }
305
306
    public function setEmail($email)
307
    {
308
        $this->email = $email;
309
310
        return $this;
311
    }
312
313
    public function getPassword(): string
314
    {
315
        return $this->password;
316
    }
317
318
    public function setPassword($password)
319
    {
320
        $this->password = $password;
321
322
        return $this;
323
    }
324
325
    public function getPlainPassword(): ?string
326
    {
327
        return $this->plainPassword;
328
    }
329
330
    public function setPlainPassword($plainPassword)
331
    {
332
        $this->plainPassword = $plainPassword;
333
334
        return $this;
335
    }
336
337
    /**
338
     * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use string[].

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
339
     */
340
    public function getRoles()
341
    {
342
        $roles = $this->roles;
343
344
        foreach ($this->getGroups() as $group) {
345
            $roles = array_merge($roles, $group->getRoles());
346
        }
347
348
        // we need to make sure to have at least one role
349
        $roles[] = static::ROLE_DEFAULT;
350
351
        return array_unique($roles);
352
    }
353
354
    public function hasRole($role)
355
    {
356
        return in_array(strtoupper($role), $this->getRoles(), true);
357
    }
358
359
    /**
360
     * {@inheritdoc}
361
     */
362
    public function setRoles(array $roles)
363
    {
364
        $this->roles = [];
365
366
        foreach ($roles as $role) {
367
            $this->addRole($role);
368
        }
369
370
        return $this;
371
    }
372
373
    public function removeRole($role)
374
    {
375
        if (false !== $key = array_search(strtoupper($role), $this->roles, true)) {
376
            unset($this->roles[$key]);
377
            $this->roles = array_values($this->roles);
378
        }
379
380
        return $this;
381
    }
382
383
    public function getSalt(): ?string
384
    {
385
        return $this->salt;
386
    }
387
388
    public function setSalt($salt)
389
    {
390
        $this->salt = $salt;
391
392
        return $this;
393
    }
394
395
    public function isEnabled()
396
    {
397
        return $this->enabled;
398
    }
399
400
    /**
401
     * @return string The username
402
     */
403
    public function getUsername(): string
404
    {
405
        return $this->username;
406
    }
407
408
    public function setUsername($username)
409
    {
410
        $this->username = $username;
411
412
        return $this;
413
    }
414
415
    /**
416
     * Removes sensitive data from the user.
417
     */
418
    public function eraseCredentials(): void
419
    {
420
        $this->plainPassword = null;
421
    }
422
423
    /**
424
     * {@inheritdoc}
425
     */
426
    public function addRole($role)
427
    {
428
        $role = strtoupper($role);
429
        if ($role === static::ROLE_DEFAULT) {
430
            return $this;
431
        }
432
433
        if (!in_array($role, $this->roles, true)) {
434
            $this->roles[] = $role;
435
        }
436
437
        return $this;
438
    }
439
440
    /**
441
     * {@inheritdoc}
442
     */
443
    public function getGroupNames()
444
    {
445
        $names = [];
446
        foreach ($this->getGroups() as $group) {
447
            $names[] = $group->getName();
448
        }
449
450
        return $names;
451
    }
452
453
    /**
454
     * {@inheritdoc}
455
     */
456
    public function hasGroup($name)
457
    {
458
        return in_array($name, $this->getGroupNames());
459
    }
460
461
    /**
462
     * {@inheritdoc}
463
     */
464
    public function addGroup(GroupInterface $group)
465
    {
466
        if (!$this->getGroups()->contains($group)) {
467
            $this->getGroups()->add($group);
468
        }
469
470
        return $this;
471
    }
472
473
    /**
474
     * {@inheritdoc}
475
     */
476
    public function removeGroup(GroupInterface $group)
477
    {
478
        if ($this->getGroups()->contains($group)) {
479
            $this->getGroups()->removeElement($group);
480
        }
481
482
        return $this;
483
    }
484
485
    public function __toString()
486
    {
487
        return (string) $this->getUsername();
488
    }
489
490
    public function getUsernameCanonical()
491
    {
492
        // NEXT_MAJOR remove method
493
        @trigger_error(sprintf('Using method %s from class %s is deprecated since KunstmaanAdminBundle 5.8 and will be removed in KunstmaanAdminBundle 6.0.', __METHOD__, BaseUser::class), E_USER_DEPRECATED);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
494
495
        return $this->usernameCanonical;
496
    }
497
498
    public function setUsernameCanonical($usernameCanonical)
499
    {
500
        // NEXT_MAJOR remove method
501
        @trigger_error(sprintf('Using method %s from class %s is deprecated since KunstmaanAdminBundle 5.8 and will be removed in KunstmaanAdminBundle 6.0.', __METHOD__, BaseUser::class), E_USER_DEPRECATED);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
502
503
        $this->usernameCanonical = $usernameCanonical;
504
    }
505
506
    public function getEmailCanonical()
507
    {
508
        // NEXT_MAJOR remove method
509
        @trigger_error(sprintf('Using method %s from class %s is deprecated since KunstmaanAdminBundle 5.8 and will be removed in KunstmaanAdminBundle 6.0.', __METHOD__, BaseUser::class), E_USER_DEPRECATED);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
510
511
        return $this->emailCanonical;
512
    }
513
514
    public function setEmailCanonical($emailCanonical)
515
    {
516
        // NEXT_MAJOR remove method
517
        @trigger_error(sprintf('Using method %s from class %s is deprecated since KunstmaanAdminBundle 5.8 and will be removed in KunstmaanAdminBundle 6.0.', __METHOD__, BaseUser::class), E_USER_DEPRECATED);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
518
519
        $this->emailCanonical = $emailCanonical;
520
    }
521
522
    public function isSuperAdmin()
523
    {
524
        // NEXT_MAJOR remove method
525
        @trigger_error(sprintf('Using method %s from class %s is deprecated since KunstmaanAdminBundle 5.8 and will be removed in KunstmaanAdminBundle 6.0.', __METHOD__, BaseUser::class), E_USER_DEPRECATED);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
526
    }
527
528
    public function setSuperAdmin($boolean)
529
    {
530
        // NEXT_MAJOR remove method
531
        @trigger_error(sprintf('Using method %s from class %s is deprecated since KunstmaanAdminBundle 5.8 and will be removed in KunstmaanAdminBundle 6.0.', __METHOD__, BaseUser::class), E_USER_DEPRECATED);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
532
    }
533
534
    public function getConfirmationToken()
535
    {
536
        return $this->confirmationToken;
537
    }
538
539
    public function setConfirmationToken($confirmationToken)
540
    {
541
        $this->confirmationToken = $confirmationToken;
542
    }
543
544
    public function setPasswordRequestedAt(DateTime $date = null)
545
    {
546
        // NEXT_MAJOR remove method
547
        @trigger_error(sprintf('Using method %s from class %s is deprecated since KunstmaanAdminBundle 5.8 and will be removed in KunstmaanAdminBundle 6.0.', __METHOD__, BaseUser::class), E_USER_DEPRECATED);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
548
    }
549
550
    public function getLastLogin()
551
    {
552
        return $this->lastLogin;
553
    }
554
555
    public function setLastLogin(?DateTime $lastLogin = null)
556
    {
557
        $this->lastLogin = $lastLogin;
558
559
        return $this;
560
    }
561
562
    public function getCreatedAt(): ?\DateTimeImmutable
563
    {
564
        return $this->createdAt;
565
    }
566
567
    public function getCreatedBy(): ?string
568
    {
569
        return $this->createdBy;
570
    }
571
572
    public function setCreatedBy(string $createdBy): void
573
    {
574
        $this->createdBy = $createdBy;
575
    }
576
577
    /**
578
     * NEXT_MAJOR remove method
579
     *
580
     * @deprecated since KunstmaanAdminBundle 5.8 and will be removed in KunstmaanAdminBundle 6.0.
581
     */
582
    public function isAccountNonExpired()
583
    {
584
        return true;
585
    }
586
587
    /**
588
     * NEXT_MAJOR remove method
589
     *
590
     * @deprecated since KunstmaanAdminBundle 5.8 and will be removed in KunstmaanAdminBundle 6.0.
591
     */
592
    public function isCredentialsNonExpired()
593
    {
594
        return true;
595
    }
596
597
    /**
598
     * NEXT_MAJOR remove method
599
     *
600
     * @deprecated since KunstmaanAdminBundle 5.8 and will be removed in KunstmaanAdminBundle 6.0.
601
     */
602
    public function isPasswordRequestNonExpired($ttl)
603
    {
604
        return false;
605
    }
606
607
    /**
608
     * {@inheritdoc}
609
     */
610
    public function serialize()
611
    {
612
        return serialize([
613
            $this->password,
614
            $this->salt,
615
            $this->username,
616
            $this->enabled,
617
            $this->id,
618
            $this->email,
619
        ]);
620
    }
621
622
    /**
623
     * {@inheritdoc}
624
     */
625
    public function unserialize($serialized)
626
    {
627
        $data = unserialize($serialized);
628
629
        [
630
            $this->password,
631
            $this->salt,
632
            $this->username,
633
            $this->enabled,
634
            $this->id,
635
            $this->email,
636
        ] = $data;
637
    }
638
}
639