Completed
Push — master ( 7b9bb5...85222f )
by Massimiliano
02:50
created

Client::prepareRequest()   B

Complexity

Conditions 6
Paths 17

Size

Total Lines 22
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 6

Importance

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