Completed
Push — master ( 85222f...c3043f )
by Massimiliano
03:15
created

Client::prepareRecipients()   B

Complexity

Conditions 4
Paths 2

Size

Total Lines 27
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 4.026

Importance

Changes 0
Metric Value
dl 0
loc 27
ccs 15
cts 17
cp 0.8824
rs 8.5806
c 0
b 0
f 0
cc 4
eloc 16
nc 2
nop 1
crap 4.026
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_scheme',
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_scheme', '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_scheme', [
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->config['sender_number'],
154 4
            'recipients' => $this->prepareRecipients($sms),
155 4
            'text' => $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_scheme']) ? $this->config['encoding_scheme'] : null,
160 4
            'charset' => isset($this->config['charset']) ? $this->config['charset'] : null,
161 4
        ];
162
163 4
        return $request;
164
    }
165
166
    /**
167
     * @param Sms $sms
168
     *
169
     * @return string
170
     */
171 4
    private function prepareRecipients(Sms $sms)
172
    {
173 4
        $recipients = $sms->getRecipients();
174
175
        $normalizeRecipientCallable = function ($recipient) {
176 4
            if ("+" === $recipient[0]) {
177 4
                $recipient = substr($recipient, 1);
178 4
            } elseif ("00" === substr($recipient, 0, 2)) {
179
                $recipient = substr($recipient, 2);
180
            }
181
182 4
            return $recipient;
183 4
        };
184
185 4
        $recipientVariables = $sms->getRecipientVariables();
186
187 4
        if (0 === count($recipientVariables)) {
188 3
            $recipients = array_map($normalizeRecipientCallable, $recipients);
189 3
            return json_encode($recipients);
190
        }
191
192 1
        return json_encode(array_map(function ($recipient) use ($recipientVariables, $normalizeRecipientCallable) {
193 1
            $targetVariables = $recipientVariables[$recipient];
194
195 1
            return array_merge(['recipient' => $normalizeRecipientCallable($recipient)], $targetVariables);
196 1
        }, $recipients));
197
    }
198
199
    /**
200
     * @param array $request
201
     *
202
     * @return Response
203
     */
204 4
    private function executeRequest(array $request)
205
    {
206 4
        $curl = curl_init();
207
208 4
        curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 10);
209 4
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
210 4
        curl_setopt($curl, CURLOPT_TIMEOUT, 60);
211 4
        curl_setopt($curl, CURLOPT_POST, 1);
212 4
        curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($request));
213 4
        curl_setopt($curl, CURLOPT_URL, $this->config['endpoint_uri']);
214
215 4
        $response = curl_exec($curl);
216
217 4
        curl_close($curl);
218
219 4
        return new Response($response);
220
    }
221
}
222