Completed
Pull Request — master (#1)
by Artem
01:44
created

Sinch::getStatusOfSMS()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 6
nc 2
nop 1
1
<?php
2
/*
3
 * This file is part of the FreshSinchBundle
4
 *
5
 * (c) Artem Henvald <[email protected]>
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 Fresh\SinchBundle\Service;
12
13
use Fresh\SinchBundle\Event\SinchEvents;
14
use Fresh\SinchBundle\Event\SmsEvent;
15
use Fresh\SinchBundle\Exception\SinchException;
16
use Fresh\SinchBundle\Helper\SinchSmsStatus;
17
use GuzzleHttp\Client;
18
use GuzzleHttp\Exception\ClientException;
19
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
20
use Symfony\Component\HttpFoundation\Response;
21
22
/**
23
 * Sinch Service.
24
 *
25
 * @author Artem Henvald <[email protected]>
26
 */
27
class Sinch
28
{
29
    const URL_FOR_SENDING_SMS = '/v1/sms/';
30
    const URL_FOR_CHECKING_SMS_STATUS = '/v1/message/status/';
31
32
    /** @var Client */
33
    private $guzzleHTTPClient;
34
35
    /** @var EventDispatcherInterface */
36
    private $dispatcher;
37
38
    /** @var string */
39
    private $host;
40
41
    /** @var string */
42
    private $key;
43
44
    /** @var string */
45
    private $secret;
46
47
    /** @var string */
48
    private $from;
49
50
    /**
51
     * @param EventDispatcherInterface $dispatcher
52
     * @param string                   $host
53
     * @param string                   $key
54
     * @param string                   $secret
55
     * @param string|null              $from
56
     */
57
    public function __construct(EventDispatcherInterface $dispatcher, $host, $key, $secret, $from = null)
58
    {
59
        $this->dispatcher = $dispatcher;
60
        $this->host = $host;
61
        $this->key = $key;
62
        $this->secret = $secret;
63
        $this->from = $from;
64
65
        $this->guzzleHTTPClient = new Client([
66
            'base_uri' => \rtrim($this->host, '/'),
67
        ]);
68
    }
69
70
    /**
71
     * @param string      $phoneNumber
72
     * @param string      $messageText
73
     * @param string|null $from
74
     *
75
     * @return int Message ID
76
     *
77
     * @throws SinchException
78
     */
79
    public function sendSMS(string $phoneNumber, string $messageText, ?string $from = null): ?int
80
    {
81
        // @todo validate phone number
82
83
        $body = [
84
            'auth' => [$this->key, $this->secret],
85
            'headers' => ['X-Timestamp' => (new \DateTime('now'))->format('c')], // ISO 8601 date format
86
            'json' => ['message' => $messageText],
87
        ];
88
89
        if (null !== $from) {
90
            $body['json']['from'] = $from;
91
        } elseif (null !== $this->from) {
92
            $from = $this->from;
93
            $body['json']['from'] = $from;
94
        }
95
96
        try {
97
            $smsEvent = new SmsEvent($phoneNumber, $messageText, $from);
98
99
            $this->dispatcher->dispatch(SinchEvents::PRE_SMS_SEND, $smsEvent);
100
            $response = $this->guzzleHTTPClient->post(self::URL_FOR_SENDING_SMS.$phoneNumber, $body);
101
            $this->dispatcher->dispatch(SinchEvents::POST_SMS_SEND, $smsEvent);
102
        } catch (ClientException $e) {
103
            throw SinchExceptionResolver::createAppropriateSinchException($e);
104
        }
105
106
        $messageId = null;
107
108
        if (Response::HTTP_OK === $response->getStatusCode() && $response->hasHeader('Content-Type')
109
            && 'application/json; charset=utf-8' === $response->getHeaderLine('Content-Type')
110
        ) {
111
            $content = $response->getBody()->getContents();
112
            $content = \json_decode($content, true);
113
114
            if (isset($content['messageId']) && \array_key_exists('messageId', $content)) {
115
                $messageId = $content['messageId'];
116
            }
117
        }
118
119
        return $messageId;
120
    }
121
122
    /**
123
     * @param int $messageId
124
     *
125
     * @return string
126
     */
127
    public function getStatusOfSMS(int $messageId): string
128
    {
129
        $response = $this->sendRequestToCheckStatusOfSMS($messageId);
130
        $result = '';
131
132
        if (isset($response['status']) && \array_key_exists('status', $response)) {
133
            $result = $response['status'];
134
        }
135
136
        return $result;
137
    }
138
139
    /**
140
     * @param int $messageId
141
     *
142
     * @return bool
143
     */
144
    public function smsIsSentSuccessfully(int $messageId): bool
145
    {
146
        $response = $this->sendRequestToCheckStatusOfSMS($messageId);
147
148
        $result = false;
149
        if (isset($response['status']) && SinchSmsStatus::SUCCESSFUL === $response['status']) {
150
            $result = true;
151
        }
152
153
        return $result;
154
    }
155
156
    /**
157
     * @param int $messageId
158
     *
159
     * @return bool
160
     */
161
    public function smsIsPending(int $messageId): bool
162
    {
163
        $response = $this->sendRequestToCheckStatusOfSMS($messageId);
164
165
        $result = false;
166
        if (isset($response['status']) && SinchSmsStatus::PENDING === $response['status']) {
167
            $result = true;
168
        }
169
170
        return $result;
171
    }
172
173
    /**
174
     * @param int $messageId
175
     *
176
     * @return bool
177
     */
178
    public function smsIsFaulted(int $messageId): bool
179
    {
180
        $response = $this->sendRequestToCheckStatusOfSMS($messageId);
181
182
        $result = false;
183
        if (isset($response['status']) && SinchSmsStatus::FAULTED === $response['status']) {
184
            $result = true;
185
        }
186
187
        return $result;
188
    }
189
190
    /**
191
     * @param int $messageId
192
     *
193
     * @return bool
194
     */
195
    public function smsInUnknownStatus(int $messageId): bool
196
    {
197
        $response = $this->sendRequestToCheckStatusOfSMS($messageId);
198
199
        $result = false;
200
        if (isset($response['status']) && SinchSmsStatus::UNKNOWN === $response['status']) {
201
            $result = true;
202
        }
203
204
        return $result;
205
    }
206
207
    /**
208
     * @param int $messageId
209
     *
210
     * @return array|null
211
     */
212
    private function sendRequestToCheckStatusOfSMS(int $messageId): ?array
213
    {
214
        $body = [
215
            'auth' => [$this->key, $this->secret],
216
            'headers' => ['X-Timestamp' => (new \DateTime('now'))->format('c')],
217
        ];
218
219
        try {
220
            $response = $this->guzzleHTTPClient->get(self::URL_FOR_CHECKING_SMS_STATUS.$messageId, $body);
221
        } catch (ClientException $e) {
222
            throw SinchExceptionResolver::createAppropriateSinchException($e);
223
        }
224
225
        $result = null;
226
227
        if (Response::HTTP_OK === $response->getStatusCode() && $response->hasHeader('Content-Type')
228
            && 'application/json; charset=utf-8' === $response->getHeaderLine('Content-Type')
229
        ) {
230
            $content = $response->getBody()->getContents();
231
            $result = \json_decode($content, true);
232
        }
233
234
        return $result;
235
    }
236
}
237