Passed
Push — feature/uploadable ( 7c6d25...a7ed20 )
by Daniel
11:07
created

UserListener::postUpdate()   B

Complexity

Conditions 7
Paths 16

Size

Total Lines 16
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 56

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 8
dl 0
loc 16
ccs 0
cts 9
cp 0
rs 8.8333
c 1
b 0
f 0
cc 7
nc 16
nop 1
crap 56
1
<?php
2
3
/*
4
 * This file is part of the Silverback API Components Bundle Project
5
 *
6
 * (c) Daniel West <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Silverback\ApiComponentsBundle\EventListener\Doctrine;
15
16
use Doctrine\ORM\Event\LifecycleEventArgs;
17
use Doctrine\ORM\Mapping\ClassMetadata;
18
use Doctrine\ORM\UnitOfWork;
19
use Silverback\ApiComponentsBundle\Entity\User\AbstractUser;
20
use Silverback\ApiComponentsBundle\Mailer\UserMailer;
21
use Silverback\ApiComponentsBundle\Security\TokenGenerator;
22
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
23
24
/**
25
 * @author Daniel West <[email protected]>
26
 */
27
class UserListener
28
{
29
    private UserPasswordEncoderInterface $passwordEncoder;
30
    private UserMailer $userMailer;
31
    private bool $initialEmailVerifiedState;
32
    private bool $verifyEmailOnRegister;
33
    private bool $verifyEmailOnChange;
34
    private array $changeSet = [];
35
36 5
    public function __construct(
37
        UserPasswordEncoderInterface $passwordEncoder,
38
        UserMailer $userMailer,
39
        bool $initialEmailVerifiedState,
40
        bool $verifyEmailOnRegister,
41
        bool $verifyEmailOnChange
42
    ) {
43 5
        $this->passwordEncoder = $passwordEncoder;
44 5
        $this->userMailer = $userMailer;
45 5
        $this->initialEmailVerifiedState = $initialEmailVerifiedState;
46 5
        $this->verifyEmailOnRegister = $verifyEmailOnRegister;
47 5
        $this->verifyEmailOnChange = $verifyEmailOnChange;
48 5
    }
49
50 5
    public function prePersist(AbstractUser $user): void
51
    {
52 5
        $this->encodePassword($user);
53 5
        $user->setEmailAddressVerified($this->initialEmailVerifiedState);
54 5
        if (!$this->initialEmailVerifiedState) {
55 5
            $user->setNewEmailAddress($user->getEmailAddress());
56 5
            if (!$this->verifyEmailOnRegister) {
57
                $user->setNewEmailVerificationToken(TokenGenerator::generateToken());
58
            }
59
        }
60 5
    }
61
62 5
    public function postPersist(AbstractUser $user): void
63
    {
64 5
        $this->userMailer->sendWelcomeEmail($user);
65 5
    }
66
67
    public function preUpdate(AbstractUser $user, LifecycleEventArgs $args): void
68
    {
69
        $manager = $args->getEntityManager();
70
        $uow = $manager->getUnitOfWork();
71
        $userClassMetadata = $manager->getClassMetadata(AbstractUser::class);
72
73
        $passwordEncoded = $this->encodePassword($user);
74
        if ($passwordEncoded) {
75
            $this->recomputeUserChangeSet($uow, $userClassMetadata, $user);
76
        }
77
78
        $this->changeSet = $uow->getEntityChangeSet($user);
79
80
        if (isset($this->changeSet['newEmailAddress'])) {
81
            if (false === $this->verifyEmailOnChange) {
82
                $user->setEmailAddress($user->getNewEmailAddress());
83
                $user->setNewEmailAddress(null);
84
            } else {
85
                $user->setNewEmailVerificationToken(TokenGenerator::generateToken());
86
            }
87
            $this->recomputeUserChangeSet($uow, $userClassMetadata, $user);
88
            $this->changeSet = $uow->getEntityChangeSet($user);
89
        }
90
    }
91
92
    public function postUpdate(AbstractUser $user): void
93
    {
94
        if (isset($this->changeSet['enabled']) && !$this->changeSet['enabled'][0] && $user->isEnabled()) {
95
            $this->userMailer->sendUserEnabledEmail($user);
96
        }
97
98
        if (isset($this->changeSet['username'])) {
99
            $this->userMailer->sendUsernameChangedEmail($user);
100
        }
101
102
        if (isset($this->changeSet['password'])) {
103
            $this->userMailer->sendPasswordChangedEmail($user);
104
        }
105
106
        if (isset($this->changeSet['newEmailAddress'])) {
107
            $this->userMailer->sendChangeEmailVerificationEmail($user);
108
        }
109
    }
110
111
    private function recomputeUserChangeSet(UnitOfWork $uow, ClassMetadata $userClassMetadata, AbstractUser $user): void
112
    {
113
        $uow->recomputeSingleEntityChangeSet($userClassMetadata, $user);
114
    }
115
116 5
    private function encodePassword(AbstractUser $entity): bool
117
    {
118 5
        if (!$entity->getPlainPassword()) {
119 5
            return false;
120
        }
121
        $encoded = $this->passwordEncoder->encodePassword(
122
            $entity,
123
            $entity->getPlainPassword()
124
        );
125
        $entity->setPassword($encoded);
126
        $entity->eraseCredentials();
127
128
        return true;
129
    }
130
}
131