Completed
Push — master ( f78acb...054d08 )
by Massimiliano
03:15
created

Client::prepareRequest()   F

Complexity

Conditions 11
Paths 513

Size

Total Lines 37
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 24
CRAP Score 11.353

Importance

Changes 0
Metric Value
dl 0
loc 37
ccs 24
cts 28
cp 0.8571
rs 3.1764
c 0
b 0
f 0
cc 11
eloc 25
nc 513
nop 1
crap 11.353

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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