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
![]() |
|||||
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
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
![]() |
|||||
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
|
|||||
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
$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
![]() |
|||||
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
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.. ![]() |
|||||
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
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.. ![]() |
|||||
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 |