Completed
Push — master ( cb968d...3d8de1 )
by Artem
02:05
created

SinchService   A

Complexity

Total Complexity 30

Size/Duplication

Total Lines 243
Duplicated Lines 18.11 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 12
Bugs 0 Features 7
Metric Value
wmc 30
c 12
b 0
f 7
lcom 1
cbo 2
dl 44
loc 243
rs 10

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 11 1
D sendSMS() 0 36 9
A getStatusOfSMS() 0 11 3
A smsIsSentSuccessfully() 11 11 3
A smsIsPending() 11 11 3
A smsIsFaulted() 11 11 3
A smsInUnknownStatus() 11 11 3
B sendRequestToCheckStatusOfSMS() 0 26 5

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
/*
3
 * This file is part of the FreshSinchBundle
4
 *
5
 * (c) Artem Genvald <[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\Helper\SinchSmsStatus;
14
use GuzzleHttp\Client;
15
use GuzzleHttp\Exception\ClientException;
16
use GuzzleHttp\Exception\GuzzleException;
17
use Symfony\Component\HttpFoundation\Response;
18
19
/**
20
 * SinchService
21
 *
22
 * @author Artem Genvald <[email protected]>
23
 */
24
class SinchService
25
{
26
    /**
27
     * @var Client $guzzleHTTPClient Guzzle HTTP client
28
     */
29
    private $guzzleHTTPClient;
30
31
    /**
32
     * @var string $host Host
33
     */
34
    private $host;
35
36
    /**
37
     * @var string $key Key
38
     */
39
    private $key;
40
41
    /**
42
     * @var string $secret Secret
43
     */
44
    private $secret;
45
46
    /**
47
     * @var string $from From
48
     */
49
    private $from;
50
51
    /**
52
     * Constructor
53
     *
54
     * @param string      $host   Host
55
     * @param string      $key    Key
56
     * @param string      $secret Secret
57
     * @param string|null $from   From
58
     */
59
    public function __construct($host, $key, $secret, $from = null)
60
    {
61
        $this->host   = $host;
62
        $this->key    = $key;
63
        $this->secret = $secret;
64
        $this->from   = $from;
65
66
        $this->guzzleHTTPClient = new Client([
67
            'base_uri' => rtrim($this->host, '/'),
68
        ]);
69
    }
70
71
    // region Public API
72
73
    /**
74
     * Send SMS
75
     *
76
     * @param string      $phoneNumber Phone number
77
     * @param string      $messageText Message text
78
     * @param string|null $from        From
79
     *
80
     * @return int Message ID
81
     *
82
     * @throws \Fresh\SinchBundle\Exception\SinchException
83
     * @throws GuzzleException
84
     */
85
    public function sendSMS($phoneNumber, $messageText, $from = null)
86
    {
87
        $uri = '/v1/sms/'.$phoneNumber; // @todo validate phone number
88
89
        $body = [
90
            'auth'    => [$this->key, $this->secret],
91
            'headers' => ['X-Timestamp' => (new \DateTime('now'))->format('c')], // ISO 8601 date format
92
            'json'    => ['message' => $messageText],
93
        ];
94
95
        if (null !== $from) {
96
            $body['json']['from'] = $from;
97
        } elseif (null !== $this->from) {
98
            $body['json']['from'] = $this->from;
99
        }
100
101
        try {
102
            $response = $this->guzzleHTTPClient->post($uri, $body);
103
        } catch (ClientException $e) {
104
            throw SinchExceptionResolver::createAppropriateSinchException($e);
105
        }
106
107
        $messageId = null;
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
     * Get status of sent SMS
124
     *
125
     * Available SMS statuses: Successful, Pending, Faulted, Unknown
126
     *
127
     * @param int $messageId Message ID
128
     *
129
     * @return string SMS status
130
     *
131
     * @throws GuzzleException
132
     */
133
    public function getStatusOfSMS($messageId)
134
    {
135
        $response = $this->sendRequestToCheckStatusOfSMS($messageId);
136
        $result = '';
137
138
        if (isset($response['status']) && array_key_exists('status', $response)) {
139
            $result = $response['status'];
140
        }
141
142
        return $result;
143
    }
144
145
    // endregion
146
147
    // region Check status helpers
148
149
    /**
150
     * Returns true if SMS with some ID was sent successfully, otherwise returns false
151
     *
152
     * @param int $messageId Message ID
153
     *
154
     * @return bool True if SMS was sent successfully, otherwise - false
155
     */
156 View Code Duplication
    public function smsIsSentSuccessfully($messageId)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
157
    {
158
        $response = $this->sendRequestToCheckStatusOfSMS($messageId);
159
160
        $result = false;
161
        if (isset($response['status']) && SinchSmsStatus::SUCCESSFUL === $response['status']) {
162
            $result = true;
163
        }
164
165
        return $result;
166
    }
167
168
    /**
169
     * Returns true if SMS with some ID is still pending, otherwise returns false
170
     *
171
     * @param int $messageId Message ID
172
     *
173
     * @return bool True if SMS is still pending, otherwise - false
174
     */
175 View Code Duplication
    public function smsIsPending($messageId)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
176
    {
177
        $response = $this->sendRequestToCheckStatusOfSMS($messageId);
178
179
        $result = false;
180
        if (isset($response['status']) && SinchSmsStatus::PENDING === $response['status']) {
181
            $result = true;
182
        }
183
184
        return $result;
185
    }
186
187
    /**
188
     * Returns true if SMS with some ID was faulted, otherwise returns false
189
     *
190
     * @param int $messageId Message ID
191
     *
192
     * @return bool True if SMS was faulted, otherwise - false
193
     */
194 View Code Duplication
    public function smsIsFaulted($messageId)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
195
    {
196
        $response = $this->sendRequestToCheckStatusOfSMS($messageId);
197
198
        $result = false;
199
        if (isset($response['status']) && SinchSmsStatus::FAULTED === $response['status']) {
200
            $result = true;
201
        }
202
203
        return $result;
204
    }
205
206
    /**
207
     * Returns true if SMS with some ID in unknown status, otherwise returns false
208
     *
209
     * @param int $messageId Message ID
210
     *
211
     * @return bool True if SMS in unknown status, otherwise - false
212
     */
213 View Code Duplication
    public function smsInUnknownStatus($messageId)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
214
    {
215
        $response = $this->sendRequestToCheckStatusOfSMS($messageId);
216
217
        $result = false;
218
        if (isset($response['status']) && SinchSmsStatus::UNKNOWN === $response['status']) {
219
            $result = true;
220
        }
221
222
        return $result;
223
    }
224
225
    // endregion
226
227
    // region Private functions
228
229
    /**
230
     * Send request to check status of SMS
231
     *
232
     * @param int $messageId Message ID
233
     *
234
     * @return array|null
235
     *
236
     * @throws \Fresh\SinchBundle\Exception\SinchException
237
     */
238
    private function sendRequestToCheckStatusOfSMS($messageId)
239
    {
240
        $uri = '/v1/message/status/'.$messageId;
241
242
        $body = [
243
            'auth'    => [$this->key, $this->secret],
244
            'headers' => ['X-Timestamp' => (new \DateTime('now'))->format('c')],
245
        ];
246
247
        try {
248
            $response = $this->guzzleHTTPClient->get($uri, $body);
249
        } catch (ClientException $e) {
250
            throw SinchExceptionResolver::createAppropriateSinchException($e);
251
        }
252
253
        $result = null;
254
255
        if (Response::HTTP_OK === $response->getStatusCode() && $response->hasHeader('Content-Type') &&
256
            'application/json; charset=utf-8' === $response->getHeaderLine('Content-Type')
257
        ) {
258
            $content = $response->getBody()->getContents();
259
            $result = json_decode($content, true);
260
        };
261
262
        return $result;
263
    }
264
265
    // endregion
266
}
267