Passed
Pull Request — master (#1801)
by Nico
23:50
created

PlayerCreator::createPlayer()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 34
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 2.0157

Importance

Changes 0
Metric Value
cc 2
eloc 18
c 0
b 0
f 0
nc 2
nop 6
dl 0
loc 34
ccs 16
cts 19
cp 0.8421
crap 2.0157
rs 9.6666
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stu\Component\Player\Register;
6
7
use Doctrine\ORM\EntityManagerInterface;
8
use Hackzilla\PasswordGenerator\Generator\PasswordGeneratorInterface;
9
use Stu\Component\Player\Register\Exception\EmailAddressInvalidException;
10
use Stu\Component\Player\Register\Exception\LoginNameInvalidException;
11
use Stu\Component\Player\Register\Exception\MobileNumberInvalidException;
12
use Stu\Component\Player\Register\Exception\PlayerDuplicateException;
13
use Stu\Module\Control\StuHashInterface;
14
use Stu\Module\PlayerSetting\Lib\UserEnum;
15
use Stu\Orm\Entity\FactionInterface;
16
use Stu\Orm\Entity\UserInterface;
17
use Stu\Orm\Repository\UserRepositoryInterface;
18
19
/**
20
 * Creates players with registration and optional sms validation
21
 */
22
class PlayerCreator implements PlayerCreatorInterface
23
{
24
    protected UserRepositoryInterface $userRepository;
25
26
    protected PlayerDefaultsCreatorInterface $playerDefaultsCreator;
27
28
    private RegistrationEmailSenderInterface $registrationEmailSender;
29
30
    private SmsVerificationCodeSenderInterface $smsVerificationCodeSender;
31
32
    private StuHashInterface $stuHash;
33
34
    private PasswordGeneratorInterface $passwordGenerator;
35
36
    private EntityManagerInterface $entityManager;
37
38 6
    public function __construct(
39
        UserRepositoryInterface $userRepository,
40
        PlayerDefaultsCreatorInterface $playerDefaultsCreator,
41
        RegistrationEmailSenderInterface $registrationEmailSender,
42
        SmsVerificationCodeSenderInterface $smsVerificationCodeSender,
43
        StuHashInterface $stuHash,
44
        PasswordGeneratorInterface $passwordGenerator,
45
        EntityManagerInterface $entityManager
46
    ) {
47 6
        $this->userRepository = $userRepository;
48 6
        $this->playerDefaultsCreator = $playerDefaultsCreator;
49 6
        $this->registrationEmailSender = $registrationEmailSender;
50 6
        $this->smsVerificationCodeSender = $smsVerificationCodeSender;
51 6
        $this->stuHash = $stuHash;
52 6
        $this->passwordGenerator = $passwordGenerator;
53 6
        $this->entityManager = $entityManager;
54
    }
55
56 4
    public function createWithMobileNumber(
57
        string $loginName,
58
        string $emailAddress,
59
        FactionInterface $faction,
60
        string $mobile
61
    ): void {
62 4
        $mobileWithDoubleZero = str_replace('+', '00', $mobile);
63 4
        $this->checkForException($loginName, $emailAddress, $mobileWithDoubleZero);
64
65
        $randomHash = substr(md5(uniqid((string) random_int(0, mt_getrandmax()), true)), 16, 6);
66
67
        $player = $this->createPlayer(
68
            $loginName,
69
            $emailAddress,
70
            $faction,
71
            $this->passwordGenerator->generatePassword(),
72
            $mobileWithDoubleZero,
73
            $randomHash
74
        );
75
76
        $this->smsVerificationCodeSender->send($player, $randomHash);
77
    }
78
79 4
    private function checkForException(string $loginName, string $emailAddress, ?string $mobile = null): void
80
    {
81
        if (
82 4
            !preg_match('/^[a-zA-Z0-9]+$/i', $loginName) ||
83 4
            mb_strlen($loginName) < 6
84
        ) {
85 1
            throw new LoginNameInvalidException();
86
        }
87 3
        if (!filter_var($emailAddress, FILTER_VALIDATE_EMAIL)) {
88 1
            throw new EmailAddressInvalidException();
89
        }
90 2
        if ($this->userRepository->getByLogin($loginName) || $this->userRepository->getByEmail($emailAddress)) {
91 2
            throw new PlayerDuplicateException();
92
        }
93
        if ($mobile !== null && $this->userRepository->getByMobile($mobile, $this->stuHash->hash($mobile))) {
94
            throw new PlayerDuplicateException();
95
        }
96
        if ($mobile !== null && (!$this->isMobileNumberCountryAllowed($mobile) || !$this->isMobileFormatCorrect($mobile))) {
97
            throw new MobileNumberInvalidException();
98
        }
99
    }
100
101
    private function isMobileNumberCountryAllowed(string $mobile): bool
102
    {
103
        return strpos($mobile, '0049') === 0 || strpos($mobile, '0041') === 0 || strpos($mobile, '0043') === 0;
104
    }
105
106
    private function isMobileFormatCorrect(string $mobile): bool
107
    {
108
        return (bool) preg_match('/00..[1-9]\d/', $mobile);
109
    }
110
111 1
    public function createPlayer(
112
        string $loginName,
113
        string $emailAddress,
114
        FactionInterface $faction,
115
        string $password,
116
        string $mobile = null,
117
        string $smsCode = null
118
    ): UserInterface {
119 1
        $player = $this->userRepository->prototype();
120 1
        $player->setLogin($loginName);
121 1
        $player->setEmail($emailAddress);
122 1
        $player->setFaction($faction);
123
124 1
        $this->userRepository->save($player);
125 1
        $this->entityManager->flush();
126
127 1
        $player->setUsername('Siedler ' . $player->getId());
128 1
        $player->setTick(1);
129 1
        $player->setCreationDate(time());
130 1
        $player->setPassword(password_hash($password, PASSWORD_DEFAULT));
131
132
        // set player state to awaiting sms code
133 1
        if ($mobile !== null) {
134
            $player->setMobile($mobile);
135
            $player->setSmsCode($smsCode);
136
            $player->setState(UserEnum::USER_STATE_SMS_VERIFICATION);
137
        }
138
139 1
        $this->userRepository->save($player);
140
141 1
        $this->playerDefaultsCreator->createDefault($player);
142 1
        $this->registrationEmailSender->send($player, $password);
143
144 1
        return $player;
145
    }
146
}
147