WebhookQueueItem   A
last analyzed

Complexity

Total Complexity 29

Size/Duplication

Total Lines 359
Duplicated Lines 0 %

Coupling/Cohesion

Components 4
Dependencies 1

Importance

Changes 0
Metric Value
wmc 29
lcom 4
cbo 1
dl 0
loc 359
rs 10
c 0
b 0
f 0

25 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 1
A getStatuses() 0 8 1
A markAsSuccess() 0 6 1
A markAsError() 0 10 2
A getId() 0 4 1
A setId() 0 6 1
A getContent() 0 4 1
A setContent() 0 6 1
A getRequest() 0 4 1
A setRequest() 0 10 2
A getResponse() 0 4 1
A setResponse() 0 10 2
A getTries() 0 4 1
A setTries() 0 6 1
A getNextTry() 0 4 1
A setNextTry() 0 6 1
A getStatus() 0 4 1
A setStatus() 0 6 1
A isStatus() 0 4 1
A getError() 0 4 1
A setError() 0 6 1
A getWebhookExchange() 0 4 1
A setWebhookExchange() 0 6 1
A incrementTries() 0 6 1
A updateNextTry() 0 15 2
1
<?php
2
3
namespace Loevgaard\DandomainAltapayBundle\Entity;
4
5
use Doctrine\ORM\Mapping as ORM;
6
use GuzzleHttp\Psr7;
7
use Knp\DoctrineBehaviors\Model as ORMBehaviors;
8
use Psr\Http\Message\RequestInterface;
9
use Psr\Http\Message\ResponseInterface;
10
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
11
use Symfony\Component\Validator\Constraints as Assert;
12
13
/**
14
 * The webhook queue is where events are inserted/produced and later consumed.
15
 *
16
 * @ORM\Table(name="dandomain_altapay_webhook_queue")
17
 * @ORM\Entity()
18
 * @UniqueEntity("url")
19
 */
20
class WebhookQueueItem
21
{
22
    use ORMBehaviors\Timestampable\Timestampable;
23
24
    const STATUS_PENDING = 'pending';
25
    const STATUS_ERROR = 'error';
26
    const STATUS_SUCCESS = 'success';
27
28
    /**
29
     * @var int
30
     *
31
     * @ORM\Id
32
     * @ORM\Column(name="id", type="integer")
33
     * @ORM\GeneratedValue(strategy="AUTO")
34
     */
35
    private $id;
36
37
    /**
38
     * This is the content that will be posted to the $url
39
     * This will be JSON.
40
     *
41
     * @var string
42
     *
43
     * @Assert\NotBlank()
44
     *
45
     * @ORM\Column(type="text")
46
     */
47
    private $content;
48
49
    /**
50
     * This will hold a string representation of the request sent to the $url.
51
     *
52
     * @var string|null
53
     *
54
     * @ORM\Column(type="text", nullable=true)
55
     */
56
    private $request;
57
58
    /**
59
     * This will hold a string representation of the response received from the $url.
60
     *
61
     * @var string|null
62
     *
63
     * @ORM\Column(type="text", nullable=true)
64
     */
65
    private $response;
66
67
    /**
68
     * @var int
69
     *
70
     * @Assert\GreaterThanOrEqual(0)
71
     *
72
     * @ORM\Column(type="integer")
73
     */
74
    private $tries;
75
76
    /**
77
     * This is the time when we try to consume this item.
78
     *
79
     * @var \DateTimeImmutable
80
     *
81
     * @Assert\NotBlank()
82
     *
83
     * @ORM\Column(type="datetime_immutable")
84
     */
85
    private $nextTry;
86
87
    /**
88
     * @var string
89
     *
90
     * @Assert\Choice(callback="getStatuses")
91
     *
92
     * @ORM\Column(type="string")
93
     */
94
    private $status;
95
96
    /**
97
     * @var string
98
     *
99
     * @ORM\Column(type="text", nullable=true)
100
     */
101
    private $error;
102
103
    /**
104
     * @var WebhookExchange
105
     *
106
     * @ORM\ManyToOne(targetEntity="WebhookExchange", inversedBy="webhookQueueItems")
107
     * @ORM\JoinColumn(onDelete="CASCADE")
108
     */
109
    private $webhookExchange;
110
111
    /**
112
     * @param string          $content
113
     * @param WebhookExchange $webhookExchange
114
     */
115
    public function __construct(string $content, WebhookExchange $webhookExchange)
116
    {
117
        $this->setContent($content);
118
        $this->setTries(0);
119
        $this->setNextTry(new \DateTimeImmutable());
120
        $this->setStatus(self::STATUS_PENDING);
121
        $this->setWebhookExchange($webhookExchange);
122
    }
123
124
    public static function getStatuses(): array
125
    {
126
        return [
127
            self::STATUS_PENDING => self::STATUS_PENDING,
128
            self::STATUS_ERROR => self::STATUS_ERROR,
129
            self::STATUS_SUCCESS => self::STATUS_SUCCESS,
130
        ];
131
    }
132
133
    public function markAsSuccess()
134
    {
135
        $this->incrementTries();
136
        $this->setStatus(self::STATUS_SUCCESS);
137
        $this->setError(null);
138
    }
139
140
    public function markAsError($error)
141
    {
142
        if ($error instanceof \Exception) {
143
            $error = '['.get_class($error).'] '.$error->getMessage().' on line '.$error->getLine().' in file `'.$error->getFile().'`';
144
        }
145
        $this->incrementTries();
146
        $this->setStatus(self::STATUS_ERROR);
147
        $this->setError($error);
148
        $this->updateNextTry();
149
    }
150
151
    /**
152
     * @return int
153
     */
154
    public function getId(): int
155
    {
156
        return (int) $this->id;
157
    }
158
159
    /**
160
     * @param int $id
161
     *
162
     * @return WebhookQueueItem
163
     */
164
    public function setId(int $id): self
165
    {
166
        $this->id = $id;
167
168
        return $this;
169
    }
170
171
    /**
172
     * @return string
173
     */
174
    public function getContent(): string
175
    {
176
        return $this->content;
177
    }
178
179
    /**
180
     * @param string $content
181
     *
182
     * @return WebhookQueueItem
183
     */
184
    public function setContent(string $content): self
185
    {
186
        $this->content = $content;
187
188
        return $this;
189
    }
190
191
    /**
192
     * @return null|string
193
     */
194
    public function getRequest(): ?string
195
    {
196
        return $this->request;
197
    }
198
199
    /**
200
     * @param null|string $request
201
     *
202
     * @return WebhookQueueItem
203
     */
204
    public function setRequest($request): self
205
    {
206
        if ($request instanceof RequestInterface) {
207
            $request = Psr7\str($request);
208
        }
209
210
        $this->request = $request;
211
212
        return $this;
213
    }
214
215
    /**
216
     * @return null|string
217
     */
218
    public function getResponse(): ?string
219
    {
220
        return $this->response;
221
    }
222
223
    /**
224
     * @param ResponseInterface|string $response
225
     *
226
     * @return WebhookQueueItem
227
     */
228
    public function setResponse($response): self
229
    {
230
        if ($response instanceof ResponseInterface) {
231
            $response = Psr7\str($response);
232
        }
233
234
        $this->response = $response;
235
236
        return $this;
237
    }
238
239
    /**
240
     * @return int
241
     */
242
    public function getTries(): int
243
    {
244
        return $this->tries;
245
    }
246
247
    /**
248
     * @param int $tries
249
     *
250
     * @return WebhookQueueItem
251
     */
252
    public function setTries(int $tries): self
253
    {
254
        $this->tries = $tries;
255
256
        return $this;
257
    }
258
259
    /**
260
     * @return \DateTimeImmutable
261
     */
262
    public function getNextTry(): \DateTimeImmutable
263
    {
264
        return $this->nextTry;
265
    }
266
267
    /**
268
     * @param \DateTimeImmutable $nextTry
269
     *
270
     * @return WebhookQueueItem
271
     */
272
    public function setNextTry(\DateTimeImmutable $nextTry): self
273
    {
274
        $this->nextTry = $nextTry;
275
276
        return $this;
277
    }
278
279
    /**
280
     * @return string
281
     */
282
    public function getStatus(): string
283
    {
284
        return $this->status;
285
    }
286
287
    /**
288
     * @param string $status
289
     *
290
     * @return WebhookQueueItem
291
     */
292
    public function setStatus(string $status): self
293
    {
294
        $this->status = $status;
295
296
        return $this;
297
    }
298
299
    /**
300
     * Returns true if the status equals $status.
301
     *
302
     * @param string $status
303
     *
304
     * @return bool
305
     */
306
    public function isStatus(string $status): bool
307
    {
308
        return $this->status === $status;
309
    }
310
311
    /**
312
     * @return string
313
     */
314
    public function getError(): ?string
315
    {
316
        return $this->error;
317
    }
318
319
    /**
320
     * @param string|null $error
321
     *
322
     * @return WebhookQueueItem
323
     */
324
    public function setError(?string $error): self
325
    {
326
        $this->error = $error;
327
328
        return $this;
329
    }
330
331
    /**
332
     * @return WebhookExchange
333
     */
334
    public function getWebhookExchange(): WebhookExchange
335
    {
336
        return $this->webhookExchange;
337
    }
338
339
    /**
340
     * @param WebhookExchange $webhookExchange
341
     *
342
     * @return WebhookQueueItem
343
     */
344
    public function setWebhookExchange(WebhookExchange $webhookExchange): self
345
    {
346
        $this->webhookExchange = $webhookExchange;
347
348
        return $this;
349
    }
350
351
    private function incrementTries(): self
352
    {
353
        ++$this->tries;
354
355
        return $this;
356
    }
357
358
    /**
359
     * This method will compute the next try and set the nextTry property.
360
     *
361
     * @return WebhookQueueItem
362
     */
363
    private function updateNextTry(): self
364
    {
365
        $minutesToWait = 2 ** $this->tries;
366
367
        if ($minutesToWait > 120) {
368
            $minutesToWait = 120;
369
        }
370
371
        $nextTry = \DateTimeImmutable::createFromMutable($this->getUpdatedAt() ?? new \DateTime());
372
        $nextTry = $nextTry->add(new \DateInterval('PT'.$minutesToWait.'M'));
373
374
        $this->setNextTry($nextTry);
375
376
        return $this;
377
    }
378
}
379