Completed
Push — master ( 9401a4...e6f403 )
by Massimiliano
07:00
created

Client::normalizePhoneNumber()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 3

Importance

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