Completed
Push — master ( e6f403...c36869 )
by Massimiliano
06:07
created

Client::normalizePhoneNumber()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3.2098

Importance

Changes 0
Metric Value
dl 0
loc 10
ccs 5
cts 7
cp 0.7143
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 6
nc 3
nop 1
crap 3.2098
1
<?php
2
3
namespace Fazland\SkebbyRestClient\Client;
4
5
use Fazland\SkebbyRestClient\DataStructure\Response;
6
use Fazland\SkebbyRestClient\DataStructure\Sms;
7
use Fazland\SkebbyRestClient\Exception\NoRecipientsSpecifiedException;
8
use Fazland\SkebbyRestClient\Constant\Charsets;
9
use Fazland\SkebbyRestClient\Constant\EncodingSchemas;
10
use Fazland\SkebbyRestClient\Constant\Endpoints;
11
use Fazland\SkebbyRestClient\Constant\Recipients;
12
use Fazland\SkebbyRestClient\Constant\SendMethods;
13
use Fazland\SkebbyRestClient\Constant\ValidityPeriods;
14
use Symfony\Component\OptionsResolver\OptionsResolver;
15
16
/**
17
 * @author Massimiliano Braglia <[email protected]>
18
 */
19
class Client
20
{
21
    /**
22
     * @var array
23
     */
24
    private $config;
25
26
    /**
27
     * @param array $options
28
     */
29 6
    public function __construct(array $options)
30
    {
31 6
        $resolver = new OptionsResolver();
32 6
        $this->configureOptions($resolver);
33 6
        $this->config = $resolver->resolve($options);
34 6
    }
35
36
    /**
37
     * @param Sms $sms
38
     *
39
     * @return Response[]
40
     */
41 6
    public function send(Sms $sms)
42 1
    {
43 6
        $messages = [];
44
45 6
        $recipients = $sms->getRecipients();
46 6
        if (count($recipients) > Recipients::MAX) {
47
            foreach (array_chunk($recipients, Recipients::MAX) as $chunk) {
48 1
                $message = clone $sms;
49
                $message
50
                    ->setRecipients($chunk)
51
                    ->clearRecipientVariables()
52
                ;
53
54
                foreach ($chunk as $recipient) {
55
                    foreach ($sms->getRecipientVariables()[$recipient] as $variable => $value) {
56
                        $message->addRecipientVariable($recipient, $variable, $value);
57
                    }
58
                }
59
60
                $messages[] = $message;
61
            }
62
        } else {
63 6
            $messages[] = $sms;
64
        }
65
66 6
        $responses = [];
67 6
        foreach ($messages as $message) {
68 6
            $request = $this->prepareRequest($message);
69
70 5
            $responses[] = $this->executeRequest($request);
71 3
        }
72
73 3
        return $responses;
74
    }
75
76
    /**
77
     * @param OptionsResolver $resolver
78
     */
79 6
    private function configureOptions(OptionsResolver $resolver)
80
    {
81
        $resolver
82 6
            ->setRequired([
83 6
                'username',
84 6
                'password',
85 6
                'sender_number',
86 6
                'method',
87 6
            ])
88 6
            ->setDefined([
89 6
                'delivery_start',
90 6
                'validity_period',
91 6
                'encoding_schema',
92 6
                'charset',
93 6
                'endpoint_uri',
94 6
            ])
95 6
            ->setAllowedTypes('username', 'string')
96 6
            ->setAllowedTypes('password', 'string')
97 6
            ->setAllowedTypes('sender_number', 'string')
98 6
            ->setAllowedTypes('method', 'string')
99 6
            ->setAllowedTypes('delivery_start', 'string')
100 6
            ->setAllowedTypes('validity_period', 'int')
101 6
            ->setAllowedTypes('encoding_schema', 'string')
102 6
            ->setAllowedTypes('charset', 'string')
103 6
            ->setAllowedTypes('endpoint_uri', 'string')
104 6
            ->setAllowedValues('method', [
105 6
                SendMethods::CLASSIC,
106 6
                SendMethods::CLASSIC_PLUS,
107 6
                SendMethods::BASIC,
108 6
                SendMethods::TEST_CLASSIC,
109 6
                SendMethods::TEST_CLASSIC_PLUS,
110 6
                SendMethods::TEST_BASIC,
111 6
            ])
112
            ->setAllowedValues('delivery_start', function ($value) {
113
                $d = \DateTime::createFromFormat(\DateTime::RFC2822, $value);
114
                return $d && $d->format('Y-m-d') === $value;
115 6
            })
116
            ->setAllowedValues('validity_period', function ($value) {
117 6
                return $value >= ValidityPeriods::MIN && $value <= ValidityPeriods::MAX;
118 6
            })
119 6
            ->setAllowedValues('encoding_schema', [
120 6
                EncodingSchemas::NORMAL,
121 6
                EncodingSchemas::UCS2,
122 6
            ])
123 6
            ->setAllowedValues('charset', [
124 6
                Charsets::ISO_8859_1,
125 6
                Charsets::UTF8,
126 6
            ])
127 6
            ->setDefaults([
128 6
                'charset' => Charsets::UTF8,
129 6
                'validity_period' => ValidityPeriods::MAX,
130 6
                'encoding_schema' => EncodingSchemas::NORMAL,
131
                'endpoint_uri' => Endpoints::REST_HTTPS
132 6
            ])
133
        ;
134 6
    }
135
136
    /**
137
     * @param Sms $sms
138
     *
139
     * @return array
140
     *
141
     * @throws NoRecipientsSpecifiedException
142
     */
143 6
    private function prepareRequest(Sms $sms)
144
    {
145 6
        if (! $sms->hasRecipients()) {
146 1
            throw new NoRecipientsSpecifiedException();
147
        }
148
149
        $request = [
150 5
            'username' => $this->config['username'],
151 5
            'password' => $this->config['password'],
152 5
            'method' => $this->config['method'],
153 5
            'sender_number' => '"' . $this->normalizePhoneNumber($this->config['sender_number']) . '"',
154 5
            'recipients' => $this->prepareRecipients($sms),
155 5
            'text' => str_replace(' ', '+', $sms->getText()),
156 5
            'user_reference' => $sms->getUserReference(),
157 5
            'delivery_start' => isset($this->config['delivery_start']) ? $this->config['delivery_start'] : null,
158 5
            'validity_period' => isset($this->config['validity_period']) ? $this->config['validity_period'] : null,
159 5
            'encoding_scheme' => isset($this->config['encoding_schema']) ? $this->config['encoding_schema'] : null,
160 5
            'charset' => isset($this->config['charset']) ? $this->config['charset'] : null,
161 5
        ];
162
163 5
        $serializedRequest = "";
164 5
        foreach ($request as $key => $value) {
165 5
            $serializedRequest .= $key . '=' . $value . '&';
166 5
        }
167
168 5
        return rtrim($serializedRequest, '&');
169
    }
170
171
    /**
172
     * @param Sms $sms
173
     *
174
     * @return string
175
     */
176 5
    private function prepareRecipients(Sms $sms)
177
    {
178 5
        $recipients = $sms->getRecipients();
179
180 5
        $recipientVariables = $sms->getRecipientVariables();
181
182 5
        if (0 === count($recipientVariables)) {
183 3
            $recipients = array_map([$this, 'normalizePhoneNumber'], $recipients);
184 3
            return json_encode($recipients);
185
        }
186
187 2
        return json_encode(array_map(function ($recipient) use ($recipientVariables) {
188 2
            $targetVariables = $recipientVariables[$recipient];
189
190 2
            return array_merge(['recipient' => $this->normalizePhoneNumber($recipient)], $targetVariables);
191 2
        }, $recipients));
192
    }
193
194
    /**
195
     * @param string $phoneNumber
196
     *
197
     * @return string
198
     */
199 5
    private function normalizePhoneNumber($phoneNumber)
200
    {
201 5
        if ("+" === $phoneNumber[0]) {
202 5
            $phoneNumber = substr($phoneNumber, 1);
203 5
        } elseif ("00" === substr($phoneNumber, 0, 2)) {
204
            $phoneNumber = substr($phoneNumber, 2);
205
        }
206
207 5
        return $phoneNumber;
208
    }
209
210
    /**
211
     * @param string $request
212
     *
213
     * @return Response
214
     */
215 5
    private function executeRequest($request)
216
    {
217 5
        $curl = curl_init();
218
219 5
        curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 10);
220 5
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
221 5
        curl_setopt($curl, CURLOPT_TIMEOUT, 60);
222 5
        curl_setopt($curl, CURLOPT_POST, 1);
223 5
        curl_setopt($curl, CURLOPT_POSTFIELDS, $request);
224 5
        curl_setopt($curl, CURLOPT_URL, $this->config['endpoint_uri']);
225
226 5
        $response = curl_exec($curl);
227
228 5
        curl_close($curl);
229
230 5
        return new Response($response);
231
    }
232
}
233