AbstractNetgsmMessage::setEndDate()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 2
c 0
b 0
f 0
dl 0
loc 5
rs 10
cc 1
nc 1
nop 1
1
<?php
2
3
namespace TarfinLabs\Netgsm\Sms;
4
5
use Exception;
6
use GuzzleHttp\Exception\GuzzleException;
7
use Illuminate\Support\Carbon;
8
use Psr\Http\Message\ResponseInterface;
9
use TarfinLabs\Netgsm\Exceptions\CouldNotSendNotification;
10
use TarfinLabs\Netgsm\Exceptions\IncorrectPhoneNumberFormatException;
11
use TarfinLabs\Netgsm\Exceptions\NetgsmException;
12
use TarfinLabs\Netgsm\NetgsmApiClient;
13
use TarfinLabs\Netgsm\NetgsmErrors;
14
15
abstract class AbstractNetgsmMessage extends NetgsmApiClient
16
{
17
    private const SUCCESS_CODES = [
18
        '00', '01', '02',
19
    ];
20
21
    protected $sendMethods = ['xml', 'get'];
22
23
    /**
24
     * @var string
25
     */
26
    protected $sendMethod;
27
28
    /**
29
     * @var string[]
30
     */
31
    protected $recipients = [];
32
33
    /**
34
     * @var null
35
     */
36
    protected $header = null;
37
38
    /**
39
     * @var Carbon
40
     */
41
    protected $startDate;
42
43
    /**
44
     * @var Carbon
45
     */
46
    protected $endDate;
47
48
    /**
49
     * @var string
50
     */
51
    protected $code;
52
53
    /**
54
     * @var string
55
     */
56
    protected $jobId;
57
58
    /**
59
     * @var array
60
     */
61
    protected $defaults = [];
62
63
    /**
64
     * @var string message
65
     */
66
    protected $message;
67
68
    /**
69
     * authorized data parameter.
70
     *
71
     * @see https://www.netgsm.com.tr/dokuman/#http-get-sms-g%C3%B6nderme
72
     * @see https://www.netgsm.com.tr/dokuman/#xml-post-sms-g%C3%B6nderme
73
     *
74
     * @var bool
75
     */
76
    protected $authorizedData = false;
77
78
    /**
79
     * @var ResponseInterface
80
     */
81
    protected $response;
82
83
    /**
84
     * @var array
85
     */
86
    protected $fields = [];
87
88
    /**
89
     * @var array
90
     */
91
    protected $errorCodes;
92
93
    /**
94
     * @param  string  $message
95
     * @param  array  $defaults
96
     * @return static
97
     */
98
    public static function create(string $message = null, array $defaults = [])
99
    {
100
        return new static($message, $defaults);
101
    }
102
103
    /**
104
     * AbstractNetgsmMessage constructor.
105
     * @param  array  $defaults
106
     * @param  string  $message
107
     */
108
    public function __construct(string $message = null, array $defaults = [])
109
    {
110
        $this->defaults = $defaults;
111
        $this->message = $message;
112
    }
113
114
    /**
115
     * @return array
116
     */
117
    abstract protected function mappers(): array;
118
119
    /**
120
     * @return string
121
     */
122
    abstract protected function createXmlPost(): string;
123
124
    /**
125
     * set's the sms recipients
126
     * it can be array or string.
127
     *
128
     * @param  string|array|$recipients
129
     * @return $this
130
     */
131
    public function setRecipients($recipients)
132
    {
133
        if (! is_array($recipients)) {
134
            $this->recipients = explode(',', $recipients);
135
        } else {
136
            $this->recipients = $recipients;
137
        }
138
139
        return $this;
140
    }
141
142
    /**
143
     * @return string[]
144
     */
145
    public function getRecipients(): array
146
    {
147
        return $this->recipients;
148
    }
149
150
    /**
151
     * set's the sms origin.
152
     * @see https://www.netgsm.com.tr/dokuman/#g%C3%B6nderici-ad%C4%B1-sorgulama
153
     *
154
     * @param  null  $header
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $header is correct as it would always require null to be passed?
Loading history...
155
     * @return AbstractNetgsmMessage
156
     */
157
    public function setHeader($header): self
158
    {
159
        $this->header = $header;
160
161
        return $this;
162
    }
163
164
    /**
165
     * @return string
166
     */
167
    public function getHeader(): string
168
    {
169
        return $this->header ?? $this->defaults['header'];
170
    }
171
172
    /**
173
     * set's the message body.
174
     *
175
     * @param  string  $message
176
     * @return AbstractNetgsmMessage
177
     */
178
    public function setMessage(string $message): self
179
    {
180
        $this->message = $message;
181
182
        return $this;
183
    }
184
185
    /**
186
     * @return string
187
     */
188
    public function getMessage(): string
189
    {
190
        return $this->message;
191
    }
192
193
    /**
194
     * @return string
195
     */
196
    public function getSendMethod(): string
197
    {
198
        return $this->sendMethod ?? $this->defaults['sms_sending_method'];
199
    }
200
201
    /**
202
     * set's the sms sending method
203
     * allowed send methods are (xml, get).
204
     *
205
     * @param  string  $sendMethod
206
     * @return $this
207
     * @throws Exception
208
     */
209
    public function setSendMethod(string $sendMethod): self
210
    {
211
        if (! in_array($sendMethod, $this->sendMethods)) {
212
            throw new Exception(trans('method_not_allowed', ['method' => $sendMethod]));
0 ignored issues
show
Bug introduced by
It seems like trans('method_not_allowe...ethod' => $sendMethod)) can also be of type array and array; however, parameter $message of Exception::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

212
            throw new Exception(/** @scrutinizer ignore-type */ trans('method_not_allowed', ['method' => $sendMethod]));
Loading history...
213
        }
214
215
        $this->sendMethod = $sendMethod;
216
217
        return $this;
218
    }
219
220
    /**
221
     * @return bool
222
     */
223
    public function isAuthorizedData(): bool
224
    {
225
        return $this->authorizedData;
226
    }
227
228
    /**
229
     * @param  bool  $authorizedData
230
     * @return AbstractNetgsmMessage
231
     */
232
    public function setAuthorizedData(bool $authorizedData): self
233
    {
234
        $this->authorizedData = $authorizedData;
235
236
        return $this;
237
    }
238
239
    /**
240
     * @return string
241
     */
242
    public function getUrl(): string
243
    {
244
        return $this->url.'/'.$this->getSendMethod();
245
    }
246
247
    /**
248
     * validates the sms recipients.
249
     *
250
     * @throws IncorrectPhoneNumberFormatException
251
     */
252
    protected function validateRecipients(): void
253
    {
254
        if (count($this->recipients) == 0) {
255
            throw new IncorrectPhoneNumberFormatException();
256
        }
257
        foreach ($this->recipients as $recipient) {
258
            if (strstr($recipient, ' ') || strlen($recipient) < 10) {
259
                throw new IncorrectPhoneNumberFormatException();
260
            }
261
        }
262
    }
263
264
    /**
265
     * generates the request body for append sms sending endpoint.
266
     *
267
     * @return string
268
     */
269
    public function body(): array
270
    {
271
        return array_merge(array_flip($this->fields), array_filter($this->mappers()));
0 ignored issues
show
Bug Best Practice introduced by
The expression return array_merge(array...lter($this->mappers())) returns the type array which is incompatible with the documented return type string.
Loading history...
272
    }
273
274
    /**
275
     * @param  array  $defaults
276
     * @return AbstractNetgsmMessage
277
     */
278
    public function setDefaults(array $defaults): self
279
    {
280
        $this->defaults = $defaults;
281
282
        return $this;
283
    }
284
285
    /**
286
     * @param  Carbon  $startDate
287
     * @return AbstractNetgsmMessage
288
     */
289
    public function setStartDate(Carbon $startDate): self
290
    {
291
        $this->startDate = $startDate;
292
293
        return $this;
294
    }
295
296
    /**
297
     * @param  Carbon  $endDate
298
     * @return AbstractNetgsmMessage
299
     */
300
    public function setEndDate(Carbon $endDate): self
301
    {
302
        $this->endDate = $endDate;
303
304
        return $this;
305
    }
306
307
    /**
308
     * @return mixed
309
     */
310
    public function getJobId(): string
311
    {
312
        return $this->jobId;
313
    }
314
315
    /**
316
     * parses the response from api and returns job id.
317
     *
318
     * @return $this
319
     * @throws CouldNotSendNotification
320
     * @throws NetgsmException
321
     */
322
    public function parseResponse(): self
323
    {
324
        $result = explode(' ', $this->response);
0 ignored issues
show
Bug introduced by
$this->response of type Psr\Http\Message\ResponseInterface is incompatible with the type string expected by parameter $string of explode(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

324
        $result = explode(' ', /** @scrutinizer ignore-type */ $this->response);
Loading history...
325
326
        if (! isset($result[0])) {
327
            throw new CouldNotSendNotification(NetgsmErrors::NETGSM_GENERAL_ERROR);
328
        }
329
330
        $code = $result[0];
331
        if (! in_array($code, self::SUCCESS_CODES)) {
332
            $message = $this->errorCodes[$code] ?? NetgsmErrors::SYSTEM_ERROR;
333
            throw new CouldNotSendNotification($message);
334
        }
335
336
        if (! isset($result[1])) {
337
            throw new NetgsmException(NetgsmErrors::JOB_ID_NOT_FOUND);
338
        }
339
340
        $this->code = $code;
341
        $this->jobId = $result[1];
342
343
        return $this;
344
    }
345
346
    /**
347
     * sends a sms via get method.
348
     *
349
     * @return $this
350
     * @throws CouldNotSendNotification
351
     * @throws GuzzleException
352
     * @throws NetgsmException
353
     */
354
    protected function sendViaGet(): self
355
    {
356
        $this->response = $this->callApi('GET', $this->getUrl(), $this->body());
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->callApi('GET', $t...etUrl(), $this->body()) of type string is incompatible with the declared type Psr\Http\Message\ResponseInterface of property $response.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
357
358
        return $this->parseResponse();
359
    }
360
361
    /**
362
     * sends a sms via xml method.
363
     *
364
     * @return $this
365
     * @throws CouldNotSendNotification
366
     * @throws GuzzleException
367
     * @throws NetgsmException
368
     */
369
    protected function sendViaXml(): self
370
    {
371
        $this->response = $this->callApi('POST', $this->getUrl(), $this->createXmlPost(), [
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->callApi('POST', $...xt/xml; charset=UTF8')) of type string is incompatible with the declared type Psr\Http\Message\ResponseInterface of property $response.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
372
            'Content-Type' => 'text/xml; charset=UTF8',
373
        ]);
374
375
        return $this->parseResponse();
376
    }
377
378
    /**
379
     * sends a sms via specified sending method.
380
     *
381
     * @return $this
382
     * @throws IncorrectPhoneNumberFormatException
383
     */
384
    public function send()
385
    {
386
        $this->validateRecipients();
387
        $method = 'sendVia'.$this->getSendMethod();
388
389
        return call_user_func([$this, $method]);
390
    }
391
}
392