Passed
Push — master ( 50087e...da76b1 )
by Nico
13:40
created

PlayerCreator::createWithMobileNumber()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 24
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1.485

Importance

Changes 0
Metric Value
cc 1
eloc 13
c 0
b 0
f 0
nc 1
nop 5
dl 0
loc 24
ccs 3
cts 14
cp 0.2143
crap 1.485
rs 9.8333
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 Override;
0 ignored issues
show
Bug introduced by
The type Override was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
10
use Stu\Component\Player\Register\Exception\EmailAddressInvalidException;
11
use Stu\Component\Player\Register\Exception\LoginNameInvalidException;
12
use Stu\Component\Player\Register\Exception\MobileNumberInvalidException;
13
use Stu\Component\Player\Register\Exception\PlayerDuplicateException;
14
use Stu\Module\Control\StuHashInterface;
15
use Stu\Module\PlayerSetting\Lib\UserEnum;
0 ignored issues
show
Bug introduced by
The type Stu\Module\PlayerSetting\Lib\UserEnum was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
16
use Stu\Orm\Entity\FactionInterface;
17
use Stu\Orm\Entity\UserInterface;
18
use Stu\Orm\Repository\UserRepositoryInterface;
19
use Stu\Orm\Repository\UserRefererRepositoryInterface;
20
21
/**
22
 * Creates players with registration and optional sms validation
23
 */
24
class PlayerCreator implements PlayerCreatorInterface
25
{
26 7
    public function __construct(protected UserRepositoryInterface $userRepository, protected PlayerDefaultsCreatorInterface $playerDefaultsCreator, private RegistrationEmailSenderInterface $registrationEmailSender, private SmsVerificationCodeSenderInterface $smsVerificationCodeSender, private StuHashInterface $stuHash, private PasswordGeneratorInterface $passwordGenerator, private EntityManagerInterface $entityManager, private UserRefererRepositoryInterface $userRefererRepository) {}
27
28 4
    #[Override]
29
    public function createWithMobileNumber(
30
        string $loginName,
31
        string $emailAddress,
32
        FactionInterface $faction,
33
        string $mobile,
34
        ?string $referer = null
35
    ): void {
36 4
        $mobileWithDoubleZero = str_replace('+', '00', $mobile);
37 4
        $this->checkForException($loginName, $emailAddress, $mobileWithDoubleZero);
38
39
        $randomHash = substr(md5(uniqid((string) random_int(0, mt_getrandmax()), true)), 16, 6);
40
41
        $player = $this->createPlayer(
42
            $loginName,
43
            $emailAddress,
44
            $faction,
45
            $this->passwordGenerator->generatePassword(),
46
            $mobileWithDoubleZero,
47
            $randomHash,
48
            $referer
49
        );
50
51
        $this->smsVerificationCodeSender->send($player, $randomHash);
52
    }
53
54 4
    private function checkForException(string $loginName, string $emailAddress, ?string $mobile = null): void
55
    {
56
        if (
57 4
            !preg_match('/^[a-zA-Z0-9]+$/i', $loginName) ||
58 4
            mb_strlen($loginName) < 6
59
        ) {
60 1
            throw new LoginNameInvalidException();
61
        }
62 3
        if (!filter_var($emailAddress, FILTER_VALIDATE_EMAIL)) {
63 1
            throw new EmailAddressInvalidException();
64
        }
65 2
        if ($this->userRepository->getByLogin($loginName) || $this->userRepository->getByEmail($emailAddress)) {
66 2
            throw new PlayerDuplicateException();
67
        }
68
        if ($mobile !== null && $this->userRepository->getByMobile($mobile, $this->stuHash->hash($mobile))) {
69
            throw new PlayerDuplicateException();
70
        }
71
        if ($mobile !== null && (!$this->isMobileNumberCountryAllowed($mobile) || !$this->isMobileFormatCorrect($mobile))) {
72
            throw new MobileNumberInvalidException();
73
        }
74
    }
75
76
    private function isMobileNumberCountryAllowed(string $mobile): bool
77
    {
78
        return strpos($mobile, '0049') === 0 || strpos($mobile, '0041') === 0 || strpos($mobile, '0043') === 0;
79
    }
80
81
    private function isMobileFormatCorrect(string $mobile): bool
82
    {
83
        return (bool) preg_match('/00..[1-9]\d/', $mobile);
84
    }
85
86 1
    #[Override]
87
    public function createPlayer(
88
        string $loginName,
89
        string $emailAddress,
90
        FactionInterface $faction,
91
        string $password,
92
        ?string $mobile = null,
93
        ?string $smsCode = null,
94
        ?string $referer = null
95
    ): UserInterface {
96 1
        $player = $this->userRepository->prototype();
97 1
        $player->setLogin($loginName);
98 1
        $player->setEmail($emailAddress);
99 1
        $player->setFaction($faction);
100
101 1
        $this->userRepository->save($player);
102 1
        $this->entityManager->flush();
103
104 1
        $player->setUsername('Siedler ' . $player->getId());
105 1
        $player->setTick(1);
106 1
        $player->setCreationDate(time());
107 1
        $player->setPassword(password_hash($password, PASSWORD_DEFAULT));
108
109
        // set player state to awaiting sms code
110 1
        if ($mobile !== null) {
111
            $player->setMobile($mobile);
112
            $player->setSmsCode($smsCode);
113
            $player->setState(UserEnum::USER_STATE_SMS_VERIFICATION);
114
        }
115
116 1
        if ($referer !== null) {
117
            $this->saveReferer($player, $referer);
118
        }
119
120 1
        $this->userRepository->save($player);
121
122 1
        $this->playerDefaultsCreator->createDefault($player);
123 1
        $this->registrationEmailSender->send($player, $password);
124
125 1
        return $player;
126
    }
127
    private function saveReferer(UserInterface $user, ?string $referer): void
128
    {
129
        if ($referer !== null) {
130
131
            $sanitizedReferer = preg_replace('/[^\p{L}\p{N}\s]/u', '', $referer);
132
            $sanitizedReferer = $sanitizedReferer !== null ? substr($sanitizedReferer, 0, 2000) : '';
133
134
            $userReferer = $this->userRefererRepository->prototype();
135
            $userReferer->setUser($user);
136
            $userReferer->setReferer($sanitizedReferer);
137
138
            $this->userRefererRepository->save($userReferer);
139
        }
140
    }
141
}
142