44
55namespace App \Service ;
66
7- use App \Dto \Request \GetPhoneCodeDto ;
7+ use App \Dto \Request \RequestPhoneCodeDto ;
8+ use App \Dto \Response \AuthDto ;
89use App \Dto \Response \PhoneCodeDto ;
910use App \Entity \PhoneVerificationCode ;
1011use App \Entity \User ;
1112use App \Repository \PhoneVerificationCodeRepository ;
13+ use App \Repository \UserRepository ;
1214use Doctrine \ORM \EntityManagerInterface ;
1315
1416class PhoneVerificationService
@@ -18,19 +20,22 @@ class PhoneVerificationService
1820
1921 private EntityManagerInterface $ em ;
2022 private PhoneVerificationCodeRepository $ codeRepository ;
23+ private UserRepository $ userRepository ;
2124
2225 public function __construct (
2326 EntityManagerInterface $ em ,
2427 PhoneVerificationCodeRepository $ codeRepository ,
28+ UserRepository $ userRepository ,
2529 ) {
2630 $ this ->em = $ em ;
2731 $ this ->codeRepository = $ codeRepository ;
32+ $ this ->userRepository = $ userRepository ;
2833 }
2934
3035 /**
3136 * @throws \Exception
3237 */
33- public function getPhoneCode (GetPhoneCodeDto $ getPhoneCodeDto ): PhoneCodeDto
38+ public function getPhoneCode (RequestPhoneCodeDto $ getPhoneCodeDto ): PhoneCodeDto
3439 {
3540 $ phoneNumber = $ getPhoneCodeDto ->getPhoneNumber ();
3641
@@ -96,20 +101,20 @@ private function blockPhoneNumber(string $phoneNumber): void
96101 }
97102
98103 /**
99- * @param array<string, mixed> $code
104+ * @param array<string, mixed> $codeData
100105 *
101106 * @throws \Exception
102107 */
103- private function isActualExistedCode (array $ code ): bool
108+ private function isActualExistedCode (array $ codeData ): bool
104109 {
105110 /** @var string $codeCreatedAt */
106- $ codeCreatedAt = $ code ['created_at ' ];
111+ $ codeCreatedAt = $ codeData ['created_at ' ];
107112
108113 // TODO:
109114 // Возникли проблемы с временем, пришлось сделать костыль с timezone,
110115 // надо будет с этим разобраться. Возможно в docker контейнере все наладится
111- $ createdAt = new \DateTimeImmutable ($ codeCreatedAt, new \ DateTimeZone ( ' Europe/Moscow ' ) );
112- $ now = new \DateTimeImmutable ('-1 minute ' , new \ DateTimeZone ( ' Europe/Moscow ' ) );
116+ $ createdAt = new \DateTimeImmutable ($ codeCreatedAt );
117+ $ now = new \DateTimeImmutable ('-1 minute ' );
113118
114119 return $ createdAt > $ now ;
115120 }
@@ -121,11 +126,67 @@ private function generateCode(): string
121126
122127 private function createPhoneVerificationCode (string $ phoneNumber , string $ newVerificationCode ): void
123128 {
124- $ verificationCode = new PhoneVerificationCode ();
125- $ verificationCode ->setPhoneNumber ($ phoneNumber );
126- $ verificationCode ->setCode ($ newVerificationCode );
129+ $ verificationCode = PhoneVerificationCode::create (
130+ $ phoneNumber ,
131+ $ newVerificationCode
132+ );
127133
128134 $ this ->em ->persist ($ verificationCode );
129135 $ this ->em ->flush ();
130136 }
137+
138+ /**
139+ * @throws \Exception
140+ */
141+ public function verifyCode (string $ phoneNumber , string $ code ): AuthDto
142+ {
143+ $ lastCodeData = $ this ->codeRepository ->getLastCode ($ phoneNumber );
144+
145+ if ($ lastCodeData === false ) {
146+ throw new \Exception ('Код не найден ' );
147+ }
148+
149+ if (!$ this ->isActualExistedCode ($ lastCodeData )) {
150+ throw new \Exception ('Код истек, запросите новый ' );
151+ }
152+
153+ /** @var PhoneVerificationCode $verificationCode */
154+ $ verificationCode = $ this ->codeRepository ->find ($ lastCodeData ['id ' ]);
155+
156+ if ($ lastCodeData ['is_used ' ]) {
157+ throw new \Exception ('Код уже использован ' );
158+ }
159+
160+ if ($ lastCodeData ['code ' ] !== $ code ) {
161+ throw new \Exception ('Код неверный ' );
162+ }
163+
164+ $ user = $ this ->userRepository ->findOneBy (['phoneNumber ' => $ lastCodeData ['phone_number ' ]]);
165+
166+ if ($ user !== null ) {
167+ return new AuthDto ('Authorise success ' , $ user ->getId ());
168+ }
169+
170+ /*
171+ * Тут, думаю, стоит использовать в транзакцию,
172+ * чтобы не получилось, что юзер создался, а код не пометился как использованный
173+ */
174+ $ this ->em ->beginTransaction ();
175+
176+ try {
177+ $ user = User::create ($ phoneNumber );
178+ $ this ->em ->persist ($ user );
179+
180+ $ verificationCode ->setIsUsed (true );
181+
182+ $ this ->em ->flush ();
183+ $ this ->em ->commit ();
184+ } catch (\Exception $ e ) {
185+ $ this ->em ->rollback ();
186+
187+ throw $ e ;
188+ }
189+
190+ return new AuthDto ('Registration success ' , $ user ->getId ());
191+ }
131192}
0 commit comments