|
1
|
|
|
<?php |
|
2
|
|
|
/** |
|
3
|
|
|
* This file is part of the login-cidadao project or it's bundles. |
|
4
|
|
|
* |
|
5
|
|
|
* (c) Guilherme Donato <guilhermednt on github> |
|
6
|
|
|
* |
|
7
|
|
|
* For the full copyright and license information, please view the LICENSE |
|
8
|
|
|
* file that was distributed with this source code. |
|
9
|
|
|
*/ |
|
10
|
|
|
|
|
11
|
|
|
namespace LoginCidadao\PhoneVerificationBundle\Service; |
|
12
|
|
|
|
|
13
|
|
|
use Doctrine\ORM\EntityManagerInterface; |
|
14
|
|
|
use LoginCidadao\PhoneVerificationBundle\Entity\SentVerificationRepository; |
|
15
|
|
|
use LoginCidadao\PhoneVerificationBundle\Event\UpdateStatusEvent; |
|
16
|
|
|
use LoginCidadao\PhoneVerificationBundle\Model\SentVerificationInterface; |
|
17
|
|
|
use LoginCidadao\PhoneVerificationBundle\Model\SmsStatusInterface; |
|
18
|
|
|
use LoginCidadao\PhoneVerificationBundle\PhoneVerificationEvents; |
|
19
|
|
|
use Symfony\Component\Console\Style\SymfonyStyle; |
|
20
|
|
|
use Symfony\Component\EventDispatcher\EventDispatcherInterface; |
|
21
|
|
|
|
|
22
|
|
|
class SmsStatusService |
|
23
|
|
|
{ |
|
24
|
|
|
/** @var EntityManagerInterface */ |
|
25
|
|
|
private $em; |
|
26
|
|
|
|
|
27
|
|
|
/** @var EventDispatcherInterface */ |
|
28
|
|
|
private $dispatcher; |
|
29
|
|
|
|
|
30
|
|
|
/** @var SentVerificationRepository */ |
|
31
|
|
|
private $sentVerificationRepo; |
|
32
|
|
|
|
|
33
|
|
|
/** @var SymfonyStyle */ |
|
34
|
|
|
private $io; |
|
35
|
|
|
|
|
36
|
|
|
/** |
|
37
|
|
|
* SmsStatusUpdater constructor. |
|
38
|
|
|
* @param EntityManagerInterface $em |
|
39
|
|
|
* @param EventDispatcherInterface $dispatcher |
|
40
|
|
|
* @param SentVerificationRepository $sentVerificationRepo |
|
41
|
|
|
*/ |
|
42
|
9 |
|
public function __construct( |
|
43
|
|
|
EntityManagerInterface $em, |
|
44
|
|
|
EventDispatcherInterface $dispatcher, |
|
45
|
|
|
SentVerificationRepository $sentVerificationRepo |
|
46
|
|
|
) { |
|
47
|
9 |
|
$this->em = $em; |
|
48
|
9 |
|
$this->dispatcher = $dispatcher; |
|
49
|
9 |
|
$this->sentVerificationRepo = $sentVerificationRepo; |
|
50
|
9 |
|
} |
|
51
|
|
|
|
|
52
|
|
|
/** |
|
53
|
|
|
* @param SymfonyStyle $io |
|
54
|
|
|
* @return SmsStatusService |
|
55
|
|
|
*/ |
|
56
|
8 |
|
public function setSymfonyStyle(SymfonyStyle $io) |
|
57
|
|
|
{ |
|
58
|
8 |
|
$this->io = $io; |
|
59
|
|
|
|
|
60
|
8 |
|
return $this; |
|
61
|
|
|
} |
|
62
|
|
|
|
|
63
|
|
|
/** |
|
64
|
|
|
* @param $transactionId |
|
65
|
|
|
* @return SmsStatusInterface |
|
66
|
|
|
*/ |
|
67
|
1 |
|
public function getSmsStatus($transactionId) |
|
68
|
|
|
{ |
|
69
|
1 |
|
$event = $this->getStatus($transactionId); |
|
70
|
|
|
|
|
71
|
1 |
|
return $event->getDeliveryStatus(); |
|
72
|
|
|
} |
|
73
|
|
|
|
|
74
|
5 |
|
public function updateSentVerificationStatus($batchSize = 1) |
|
75
|
|
|
{ |
|
76
|
5 |
|
$count = $this->sentVerificationRepo->countPendingUpdateSentVerification(); |
|
77
|
|
|
|
|
78
|
5 |
|
if ($count === 0) { |
|
79
|
1 |
|
$this->comment('No messages pending update.'); |
|
80
|
|
|
|
|
81
|
1 |
|
return []; |
|
82
|
|
|
} |
|
83
|
|
|
|
|
84
|
4 |
|
$query = $this->sentVerificationRepo->getPendingUpdateSentVerificationQuery(); |
|
85
|
4 |
|
$sentVerifications = $query->iterate(); |
|
86
|
|
|
|
|
87
|
|
|
//$this->em->getConnection()->getConfiguration()->setSQLLogger(null); |
|
|
|
|
|
|
88
|
4 |
|
gc_enable(); |
|
89
|
4 |
|
$this->progressStart($count); |
|
90
|
4 |
|
$transactionsUpdated = []; |
|
91
|
4 |
|
foreach ($sentVerifications as $row) { |
|
92
|
|
|
/** @var SentVerificationInterface $sentVerification */ |
|
93
|
3 |
|
$sentVerification = $row[0]; |
|
94
|
3 |
|
$event = $this->getStatus($sentVerification->getTransactionId()); |
|
95
|
3 |
|
if (false === $event->isUpdated()) { |
|
96
|
2 |
|
$this->progressAdvance(1); |
|
97
|
2 |
|
unset($event); |
|
98
|
2 |
|
unset($sentVerification); |
|
99
|
2 |
|
gc_collect_cycles(); |
|
100
|
2 |
|
continue; |
|
101
|
|
|
} |
|
102
|
|
|
|
|
103
|
1 |
|
$deliveredAt = $event->getDeliveredAt(); |
|
104
|
1 |
|
$sentVerification->setActuallySentAt($event->getSentAt()) |
|
105
|
1 |
|
->setDeliveredAt($deliveredAt) |
|
106
|
1 |
|
->setFinished($deliveredAt instanceof \DateTime || $event->getDeliveryStatus()->isFinal()); |
|
107
|
1 |
|
$transactionsUpdated[] = $sentVerification->getTransactionId(); |
|
108
|
1 |
|
unset($event); |
|
109
|
1 |
|
unset($sentVerification); |
|
110
|
1 |
|
if ((count($transactionsUpdated) % $batchSize) === 0) { |
|
111
|
1 |
|
$this->em->flush(); |
|
112
|
1 |
|
$this->em->clear(); |
|
113
|
1 |
|
gc_collect_cycles(); |
|
114
|
|
|
} |
|
115
|
1 |
|
$this->progressAdvance(1); |
|
116
|
|
|
} |
|
117
|
4 |
|
$this->em->flush(); |
|
118
|
4 |
|
$this->em->clear(); |
|
119
|
4 |
|
$this->progressFinish(); |
|
120
|
|
|
|
|
121
|
4 |
|
$countUpdated = count($transactionsUpdated); |
|
122
|
4 |
|
$this->comment("Updated {$countUpdated} transactions."); |
|
123
|
|
|
|
|
124
|
4 |
|
if ($countUpdated === 0) { |
|
125
|
3 |
|
$this->comment("It's possible the SMS-sending service you are using doesn't implement status updates."); |
|
126
|
|
|
} |
|
127
|
|
|
|
|
128
|
4 |
|
return $transactionsUpdated; |
|
129
|
|
|
} |
|
130
|
|
|
|
|
131
|
|
|
/** |
|
132
|
|
|
* @param $amount |
|
133
|
|
|
* @return float average delivery time in seconds (abs value) |
|
134
|
|
|
*/ |
|
135
|
3 |
|
public function getAverageDeliveryTime($amount) |
|
136
|
|
|
{ |
|
137
|
|
|
/** @var SentVerificationInterface[] $sentVerifications */ |
|
138
|
3 |
|
$sentVerifications = $this->sentVerificationRepo->getLastDeliveredVerifications($amount); |
|
139
|
|
|
|
|
140
|
3 |
|
if (count($sentVerifications) === 0) { |
|
141
|
2 |
|
return 0; |
|
142
|
|
|
} |
|
143
|
|
|
|
|
144
|
1 |
|
$times = []; |
|
145
|
1 |
|
foreach ($sentVerifications as $sentVerification) { |
|
146
|
1 |
|
$times[] = abs( |
|
147
|
1 |
|
$sentVerification->getDeliveredAt()->format('U') - $sentVerification->getSentAt()->format('U') |
|
148
|
|
|
); |
|
149
|
|
|
} |
|
150
|
1 |
|
$sum = array_sum($times); |
|
151
|
|
|
|
|
152
|
1 |
|
$avg = $sum / count($times); |
|
153
|
|
|
|
|
154
|
1 |
|
return $avg; |
|
155
|
|
|
} |
|
156
|
|
|
|
|
157
|
|
|
/** |
|
158
|
|
|
* @param int $maxDeliverySeconds |
|
159
|
|
|
* @return array |
|
160
|
|
|
*/ |
|
161
|
1 |
|
public function getDelayedDeliveryTransactions($maxDeliverySeconds = 0) |
|
162
|
|
|
{ |
|
163
|
1 |
|
$date = new \DateTime("-{$maxDeliverySeconds} seconds"); |
|
164
|
1 |
|
$notDelivered = $this->sentVerificationRepo->getNotDeliveredSince($date); |
|
165
|
|
|
|
|
166
|
1 |
|
$transactions = []; |
|
167
|
1 |
|
foreach ($notDelivered as $sentVerification) { |
|
168
|
1 |
|
$transactions[] = [ |
|
169
|
1 |
|
'transaction_id' => $sentVerification->getTransactionId(), |
|
170
|
1 |
|
'sent_at' => $sentVerification->getSentAt()->format('c'), |
|
171
|
|
|
]; |
|
172
|
|
|
} |
|
173
|
|
|
|
|
174
|
1 |
|
return $transactions; |
|
175
|
|
|
} |
|
176
|
|
|
|
|
177
|
|
|
/** |
|
178
|
|
|
* @param $transactionId |
|
179
|
|
|
* @return UpdateStatusEvent |
|
180
|
|
|
*/ |
|
181
|
4 |
|
private function getStatus($transactionId) |
|
182
|
|
|
{ |
|
183
|
4 |
|
$event = new UpdateStatusEvent($transactionId); |
|
184
|
4 |
|
$this->dispatcher->dispatch(PhoneVerificationEvents::PHONE_VERIFICATION_GET_SENT_VERIFICATION_STATUS, $event); |
|
185
|
|
|
|
|
186
|
4 |
|
return $event; |
|
187
|
|
|
} |
|
188
|
|
|
|
|
189
|
5 |
|
private function comment($message) |
|
190
|
|
|
{ |
|
191
|
5 |
|
if (!$this->io) { |
|
192
|
1 |
|
return; |
|
193
|
|
|
} |
|
194
|
4 |
|
$this->io->comment($message); |
|
195
|
4 |
|
} |
|
196
|
|
|
|
|
197
|
4 |
|
private function progressStart($max = 0) |
|
198
|
|
|
{ |
|
199
|
4 |
|
if (!$this->io) { |
|
200
|
1 |
|
return; |
|
201
|
|
|
} |
|
202
|
3 |
|
$this->io->progressStart($max); |
|
203
|
3 |
|
} |
|
204
|
|
|
|
|
205
|
3 |
|
private function progressAdvance($step = 1) |
|
206
|
|
|
{ |
|
207
|
3 |
|
if (!$this->io) { |
|
208
|
1 |
|
return; |
|
209
|
|
|
} |
|
210
|
2 |
|
$this->io->progressAdvance($step); |
|
211
|
2 |
|
} |
|
212
|
|
|
|
|
213
|
4 |
|
private function progressFinish() |
|
214
|
|
|
{ |
|
215
|
4 |
|
if (!$this->io) { |
|
216
|
1 |
|
return; |
|
217
|
|
|
} |
|
218
|
3 |
|
$this->io->progressFinish(); |
|
219
|
3 |
|
} |
|
220
|
|
|
} |
|
221
|
|
|
|
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.