Completed
Push — master ( bd02ec...4ff445 )
by Dmytro
04:14
created

Webhook::setStrategy()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 5
ccs 4
cts 4
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 1
crap 1
1
<?php
2
declare(strict_types=1);
3
4
5
namespace Webhook\Domain\Model;
6
7
use Ramsey\Uuid\Uuid;
8
use Webhook\Domain\Infrastructure\Strategy\AbstractStrategy;
9
use Webhook\Domain\Infrastructure\Strategy\LinearStrategy;
10
use Webhook\Domain\Infrastructure\Strategy\StrategyInterface;
11
12
/**
13
 * Class Webhook
14
 *
15
 * @package Webhook\Domain\Model
16
 */
17
class Webhook implements \JsonSerializable
18
{
19
    const STATUS_QUEUED = 'queued';
20
    const STATUS_DONE = 'done';
21
    const STATUS_FAILED = 'failed';
22
    /**
23
     * @var string
24
     */
25
    private $id;
26
    /**
27
     * @var string
28
     */
29
    private $url;
30
    /**
31
     * @var string
32
     */
33
    private $status;
34
35
    /** @var array */
36
    private $body;
37
    /**
38
     * We can send body as raw json or array form data
39
     *
40
     * @var bool
41
     */
42
    private $raw = true;
43
    /**
44
     * @var \DateTime
45
     */
46
    private $created;
47
    /**
48
     * Time at what webhook was processed to final state OK|FAIL
49
     *
50
     * @var \DateTime|null
51
     */
52
    private $processed;
53
    /**
54
     * @var \DateTime
55
     */
56
    private $nextAttempt;
57
58
    /** @var int */
59
    private $attempt = 1;
60
61
    /** @var int */
62
    private $maxAttempts = 10;
63
64
    /** @var int */
65
    private $expectedCode = 200;
66
67
    /** @var  string|null */
68
    private $expectedContent;
69
70
    /** @var  string|null */
71
    private $userAgent;
72
73
    /** @var  StrategyInterface|AbstractStrategy */
74
    private $strategy;
75
76
    /** @var  string|null */
77
    private $statusDetails;
78
79
    /** @var  array */
80
    private $metadata = [];
81
82
    /** @var  null|string */
83
    private $callbackUrl;
84
85
    /**
86
     * Webhook constructor.
87
     *
88
     * @param string $url
89
     * @param $body
90
     */
91 10
    public function __construct(string $url, $body)
92
    {
93 10
        $this->id = Uuid::getFactory()->uuid4()->toString();
94 10
        $this->url = $url;
95 10
        $this->body = $body;
96 10
        $this->created = new \DateTime();
97 10
        $this->status = self::STATUS_QUEUED;
98 10
        $this->setStrategy(new LinearStrategy(60));
99 10
    }
100
101
    public function retry()
102
    {
103
        $this->attempt++;
104
        $this->calculateNextRetry();
105
106
        if ($this->attempt === $this->maxAttempts) {
107
            $this->status = self::STATUS_FAILED;
108
            $this->processed();
109
        } else {
110
            $this->status = self::STATUS_QUEUED;
111
        }
112
    }
113
114 10
    private function calculateNextRetry()
115
    {
116 10
        $interval = $this->strategy->process($this->attempt);
117 10
        $int = new \DateInterval('PT' . $interval . 'S');
118 10
        $nextAttempt = (new \DateTime())->add($int);
119
120 10
        $this->setNextAttempt($nextAttempt);
121 10
    }
122
123
    /**
124
     * @param \DateTime $nextAttempt
125
     */
126 10
    private function setNextAttempt(\DateTime $nextAttempt)
127
    {
128 10
        $this->nextAttempt = $nextAttempt;
129 10
    }
130
131
    private function processed()
132
    {
133
        $this->processed = new \DateTime();
134
    }
135
136
    /**
137
     * If data is raw we will send it as html form
138
     *
139
     * @return bool
140
     */
141 11
    public function isRaw(): bool
142
    {
143 11
        return $this->raw;
144
    }
145
146
    /**
147
     * @param bool $raw
148
     */
149 1
    public function setRaw(bool $raw)
150
    {
151 1
        $this->raw = $raw;
152 1
    }
153
154
    /**
155
     * @return string
156
     */
157
    public function getId(): string
158
    {
159
        return $this->id;
160
    }
161
162
    /**
163
     * @return string
164
     */
165 11
    public function getUrl(): string
166
    {
167 11
        return $this->url;
168
    }
169
170
    /**
171
     * @return mixed
172
     */
173 11
    public function getBody()
174
    {
175 11
        return $this->body;
176
    }
177
178
    /**
179
     * @return int
180
     */
181 9
    public function getExpectedCode(): int
182
    {
183 9
        return $this->expectedCode;
184
    }
185
186
    /**
187
     * @param int $expectedCode
188
     */
189 9
    public function setExpectedCode(int $expectedCode)
190
    {
191 9
        $this->expectedCode = $expectedCode;
192 9
    }
193
194
    /**
195
     * @return mixed
196
     */
197 7
    public function getExpectedContent()
198
    {
199 7
        return $this->expectedContent;
200
    }
201
202
    /**
203
     * @param mixed $expectedContent
204
     */
205 9
    public function setExpectedContent($expectedContent)
206
    {
207 9
        $this->expectedContent = $expectedContent;
208 9
    }
209
210
    /**
211
     * @return string
212
     */
213 11
    public function getUserAgent()
214
    {
215 11
        return $this->userAgent;
216
    }
217
218
    /**
219
     * @return \DateTime
220
     */
221
    public function getProcessed(): \DateTime
222
    {
223
        return $this->processed;
224
    }
225
226
    /**
227
     * @return int
228
     */
229
    public function getMaxAttempts(): int
230
    {
231
        return $this->maxAttempts;
232
    }
233
234
    public function done()
235
    {
236
        $this->status = self::STATUS_DONE;
237
        $this->processed();
238
    }
239
240
    /**
241
     * @return array
242
     */
243
    public function jsonSerialize(): array
244
    {
245
        $result = [];
246
        foreach (get_object_vars($this) as $k => $v) {
247
            if ($v instanceof \DateTime) {
248
                $v = $v->format('U');
249
            }
250
251
            $result[$k] = $v;
252
        }
253
254
        return $result;
255
    }
256
257
    /**
258
     * @return string
259
     */
260
    public function getStatus(): string
261
    {
262
        return $this->status;
263
    }
264
265
    /**
266
     * @param string $status
267
     */
268
    public function setStatus(string $status)
269
    {
270
        $this->status = $status;
271
    }
272
273
    /**
274
     * @return \DateTime
275
     */
276
    public function getCreated(): \DateTime
277
    {
278
        return $this->created;
279
    }
280
281
    /**
282
     * @return int
283
     */
284 11
    public function getAttempt(): int
285
    {
286 11
        return $this->attempt;
287
    }
288
289
    /**
290
     * @return \DateTime
291
     */
292 11
    public function getNextAttempt(): \DateTime
293
    {
294 11
        return $this->nextAttempt;
295
    }
296
297
    /**
298
     * @return string
299
     */
300
    public function getStatusDetails(): string
301
    {
302
        return $this->statusDetails;
303
    }
304
305
    /**
306
     * @param string $statusDetails
307
     */
308
    public function setStatusDetails(string $statusDetails)
309
    {
310
        $this->statusDetails = $statusDetails;
311
    }
312
313
    /**
314
     * @return AbstractStrategy|StrategyInterface
315
     */
316
    public function getStrategy()
317
    {
318
        return $this->strategy;
319
    }
320
321
    /**
322
     * @param StrategyInterface $strategy
323
     */
324 10
    public function setStrategy(StrategyInterface $strategy)
325
    {
326 10
        $this->strategy = $strategy;
327 10
        $this->calculateNextRetry();
328 10
    }
329
330
    /**
331
     * @return array
332
     */
333
    public function getMetadata(): array
334
    {
335
        return $this->metadata;
336
    }
337
338
    /**
339
     * @param array $metadata
340
     */
341
    public function setMetadata(array $metadata)
342
    {
343
        $this->metadata = $metadata;
344
    }
345
346
    /**
347
     * @return null|string
348
     */
349
    public function getCallbackUrl()
350
    {
351
        return $this->callbackUrl;
352
    }
353
354
    /**
355
     * @param null|string $callbackUrl
356
     */
357
    public function setCallbackUrl($callbackUrl)
358
    {
359
        $this->callbackUrl = $callbackUrl;
360
    }
361
}