Passed
Push — master ( de0b45...c22c4c )
by Teye
12:46
created

DynadotApi::setRenewOption()   A

Complexity

Conditions 5
Paths 7

Size

Total Lines 45
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 25
CRAP Score 5

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 23
c 1
b 0
f 0
dl 0
loc 45
ccs 25
cts 25
cp 1
rs 9.2408
cc 5
nc 7
nop 2
crap 5
1
<?php
2
3
namespace Level23\Dynadot;
4
5
use Psr\Log\LogLevel;
6
use Sabre\Xml\Reader;
7
use GuzzleHttp\Client;
8
use Sabre\Xml\Service;
9
use Psr\Log\LoggerInterface;
10
use Psr\Http\Message\StreamInterface;
11
use Level23\Dynadot\ResultObjects\SetNsResponse;
12
use Level23\Dynadot\ResultObjects\DomainResponse;
13
use Level23\Dynadot\Exception\DynadotApiException;
14
use Level23\Dynadot\ResultObjects\GeneralResponse;
15
use Level23\Dynadot\ResultObjects\DomainInfoResponse;
16
use Level23\Dynadot\ResultObjects\GetContactResponse;
17
use Level23\Dynadot\Exception\ApiHttpCallFailedException;
18
use Level23\Dynadot\ResultObjects\ListDomainInfoResponse;
19
use Level23\Dynadot\Exception\ApiLimitationExceededException;
20
use Level23\Dynadot\ResultObjects\RenewOptionResponse\SetRenewOptionHeader;
21
use Level23\Dynadot\ResultObjects\RenewOptionResponse\SetRenewOptionResponse;
22
23
/**
24
 * Class DynadotApi
25
 *
26
 * @package Level23\Dynadot
27
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
28
 */
29
class DynadotApi
30
{
31
    const DYNADOT_API_URL = 'https://api.dynadot.com/api3.xml';
32
33
    /**
34
     * This options array is used by Guzzle.
35
     *
36
     * We currently use it to set the Mock Handler in unit testing.
37
     *
38
     * @var array
39
     */
40
    protected $guzzleOptions = [];
41
42
    /**
43
     * Dynadot's API key we should use for HTTP calls.
44
     *
45
     * @var string
46
     */
47
    protected $apiKey;
48
49
    /**
50
     * Logger for writing debug info
51
     *
52
     * @var LoggerInterface|null
53
     */
54
    protected $logger;
55
56
    /**
57
     * Changes boolean values like "no" and "yes" into false and true.
58
     *
59
     * @return bool
60
     * @throws DynadotApiException
61
     * @var \Closure
62
     */
63
    protected $booleanDeserializer;
64
65
    /**
66
     * Return the contact id
67
     *
68
     * @param Reader $reader
69
     *
70
     * @return int
71
     * @var \Closure
72
     */
73
    protected $contactIdDeserializer;
74
75
    /**
76
     * DynadotApi constructor.
77
     *
78
     * @param string                        $apiKey The API key we should use while communicating with the Dynadot API.
79
     * @param \Psr\Log\LoggerInterface|null $logger
80
     *
81
     * @internal param $Logger
82
     */
83 28
    public function __construct(string $apiKey, LoggerInterface $logger = null)
84
    {
85 28
        $this->setApiKey($apiKey);
86 28
        $this->logger = $logger;
87
88
        /**
89
         * Set the default guzzle options
90
         */
91 28
        $this->setGuzzleOptions([
92 28
            'max'             => 5,
93 28
            'referer'         => false,
94 28
            'protocols'       => ['https'],
95 28
            'connect_timeout' => 30,
96 28
        ]);
97
98
        /**
99
         * Changes boolean values like "no" and "yes" into false and true.
100
         *
101
         * @param \Sabre\Xml\Reader $reader
102
         *
103
         * @return bool
104
         * @throws \Level23\Dynadot\Exception\DynadotApiException
105
         * @throws \Sabre\Xml\LibXMLException
106
         * @throws \Sabre\Xml\ParseException
107
         */
108 28
        $this->booleanDeserializer = function (Reader $reader) {
109 3
            $value = $reader->parseInnerTree();
110 3
            if (is_string($value)) {
111 3
                $value = strtolower($value);
112
            }
113
114 3
            if ($value != 'yes' && $value != 'no') {
115
                throw new DynadotApiException('Error, received incorrect boolean value ' . var_export($value, true));
116
            }
117
118 3
            return ($value !== 'no');
119 28
        };
120
121
        /**
122
         * Return the contact id
123
         *
124
         * @param Reader $reader
125
         *
126
         * @return int
127
         * @throws \Sabre\Xml\LibXMLException
128
         * @throws \Sabre\Xml\ParseException
129
         */
130 28
        $this->contactIdDeserializer = function (Reader $reader) {
131 3
            $children = (array)$reader->parseInnerTree();
132
133 3
            return $children[0]['value'];
134 28
        };
135
    }
136
137
    /**
138
     * @param array $optionsArray
139
     */
140 28
    public function setGuzzleOptions(array $optionsArray): void
141
    {
142 28
        $this->guzzleOptions = $optionsArray;
143
    }
144
145
    /**
146
     * Get info about a domain
147
     *
148
     * @param string $domain
149
     *
150
     * @return DomainResponse\Domain
151
     * @throws \Level23\Dynadot\Exception\ApiHttpCallFailedException
152
     * @throws \Level23\Dynadot\Exception\DynadotApiException
153
     * @throws \Sabre\Xml\ParseException
154
     * @throws \GuzzleHttp\Exception\GuzzleException
155
     */
156 7
    public function getDomainInfo(string $domain): DomainResponse\Domain
157
    {
158 7
        $this->log(LogLevel::INFO, 'Retrieve info for domain: ' . $domain);
159
160 7
        $requestData = [
161 7
            'domain'  => $domain,
162 7
            'command' => 'domain_info',
163 7
        ];
164
165
        // perform the API call
166 7
        $response = $this->performRawApiCall($requestData);
167
168
        // start parsing XML data using Sabre
169 6
        $sabreService = new Service();
170
171
        // set mapping
172 6
        $sabreService->elementMap = [
173 6
            '{}Registrant'           => $this->contactIdDeserializer,
174 6
            '{}Admin'                => $this->contactIdDeserializer,
175 6
            '{}Technical'            => $this->contactIdDeserializer,
176 6
            '{}Billing'              => $this->contactIdDeserializer,
177 6
            '{}isForSale'            => $this->booleanDeserializer,
178 6
            '{}Hold'                 => $this->booleanDeserializer,
179 6
            '{}RegistrantUnverified' => $this->booleanDeserializer,
180 6
            '{}UdrpLocked'           => $this->booleanDeserializer,
181 6
            '{}Disabled'             => $this->booleanDeserializer,
182 6
            '{}Locked'               => $this->booleanDeserializer,
183 6
            '{}WithAds'              => $this->booleanDeserializer,
184 6
        ];
185
186
        // map certain values to objects
187 6
        $sabreService->mapValueObject('{}DomainInfoResponse', DomainInfoResponse\DomainInfoResponse::class);
188 6
        $sabreService->mapValueObject('{}DomainInfoHeader', DomainInfoResponse\DomainInfoHeader::class);
189 6
        $sabreService->mapValueObject('{}DomainInfoContent', DomainInfoResponse\DomainInfoContent::class);
190 6
        $sabreService->mapValueObject('{}Domain', DomainResponse\Domain::class);
191 6
        $sabreService->mapValueObject('{}NameServerSettings', DomainResponse\NameServerSettings::class);
192 6
        $sabreService->mapValueObject('{}NameServer', DomainResponse\NameServer::class);
193 6
        $sabreService->mapValueObject('{}Whois', DomainResponse\Whois::class);
194 6
        $sabreService->mapValueObject('{}Folder', DomainResponse\Folder::class);
195 6
        $sabreService->mapValueObject('{}Response', GeneralResponse\Response::class);
196 6
        $sabreService->mapValueObject('{}ResponseHeader', GeneralResponse\ResponseHeader::class);
197
198 6
        $this->log(LogLevel::DEBUG, 'Start parsing response XML');
199
200 6
        $contents = $response->getContents();
201
202
        // parse the data
203 6
        $resultData = $sabreService->parse($contents);
204
205 5
        if (!$resultData instanceof DomainInfoResponse\DomainInfoResponse) {
206 2
            throw new DynadotApiException('We failed to parse the response');
207
        }
208
209 3
        $code = $resultData->DomainInfoHeader->ResponseCode ?? $resultData->DomainInfoHeader->SuccessCode;
0 ignored issues
show
Bug introduced by
The property ResponseCode does not seem to exist on Level23\Dynadot\ResultOb...sponse\DomainInfoHeader.
Loading history...
210 3
        if ($code != GeneralResponse\ResponseHeader::RESPONSECODE_OK) {
211 1
            throw new DynadotApiException($resultData->DomainInfoHeader->Error);
212
        }
213
214 2
        if ($resultData->DomainInfoHeader !== null) {
215
            /**
216
             * Check if the API call was successful. If not, return the error
217
             */
218 2
            $code = $resultData->DomainInfoHeader->SuccessCode;
219 2
            if ($code != DomainInfoResponse\DomainInfoHeader::SUCCESSCODE_OK) {
220
                throw new DynadotApiException($resultData->DomainInfoHeader->Error);
221
            }
222
        }
223
224 2
        $this->log(LogLevel::DEBUG, 'Returning domain info');
225
226
        // Here we know our API call was succesful, return the domain info.
227 2
        return $resultData->DomainInfoContent->Domain;
228
    }
229
230
    /**
231
     * Log a message to our logger, if we have any.
232
     *
233
     * @param string $level
234
     * @param string $message
235
     */
236 27
    protected function log(string $level, string $message): void
237
    {
238 27
        if ($this->logger instanceof LoggerInterface) {
239 1
            $this->logger->log($level, $message);
240
        }
241
    }
242
243
    /**
244
     * Performs the actual API call (internal method)
245
     *
246
     * @param array $requestData
247
     *
248
     * @return \Psr\Http\Message\StreamInterface
249
     * @throws \GuzzleHttp\Exception\GuzzleException
250
     * @throws \Level23\Dynadot\Exception\ApiHttpCallFailedException
251
     */
252 26
    protected function performRawApiCall(array $requestData): StreamInterface
253
    {
254 26
        $this->log(LogLevel::DEBUG, 'Perform raw call: ' . var_export($requestData, true));
255
256
        // transform the request data into a valid query string
257 26
        $requestDataHttp = http_build_query($requestData);
258
259
        // spawn Guzzle
260 26
        $client = new Client($this->guzzleOptions);
261
262 26
        $url = self::DYNADOT_API_URL .
263 26
            '?key=' . urlencode($this->getApiKey()) .
264 26
            ($requestDataHttp ? '&' . $requestDataHttp : '');
265
266 26
        $this->log(LogLevel::DEBUG, 'Start new guzzle request with URL: ' . $url);
267
268
        // start a request with out API key and optionally our request data
269 26
        $response = $client->request('GET', $url);
270
271 26
        $this->log(LogLevel::DEBUG, 'Received response with status code ' . $response->getStatusCode());
272
273
        // if we did not get a HTTP 200 response, our HTTP call failed (which is different from a failed API call)
274 26
        if ($response->getStatusCode() != 200) {
275 1
            $this->log(LogLevel::ALERT, 'Received wrong HTTP status code: ' . $response->getStatusCode());
276
            // not ok
277 1
            throw new ApiHttpCallFailedException(
278 1
                'HTTP API call failed, expected 200 status, got ' . $response->getStatusCode()
279 1
            );
280
        }
281
282
        // Return the response body (which is a stream coming from Guzzle).
283
        // Sabre XML semi-handles streams (it will just get the contents of the stream using stream_get_contents) so
284
        // this should work! ;)
285 25
        return $response->getBody();
286
    }
287
288
    /**
289
     * @return string
290
     */
291 27
    public function getApiKey(): string
292
    {
293 27
        return $this->apiKey;
294
    }
295
296
    /**
297
     * @param string $apiKey
298
     */
299 28
    public function setApiKey(string $apiKey): void
300
    {
301 28
        $this->apiKey = $apiKey;
302
    }
303
304
    /**
305
     * Set nameservers for a domain (max 13). An exception will be thrown in case of an error.
306
     *
307
     * @param string $domain The domain where to set the nameservers for.
308
     * @param array  $nameservers
309
     *
310
     * @throws \GuzzleHttp\Exception\GuzzleException
311
     * @throws \Level23\Dynadot\Exception\ApiHttpCallFailedException
312
     * @throws \Level23\Dynadot\Exception\ApiLimitationExceededException
313
     * @throws \Level23\Dynadot\Exception\DynadotApiException
314
     * @throws \Sabre\Xml\ParseException
315
     */
316 6
    public function setNameserversForDomain(string $domain, array $nameservers): void
317
    {
318 6
        $this->log(LogLevel::DEBUG, 'Set ' . sizeof($nameservers) . ' nameservers for domain ' . $domain);
319 6
        $requestData = [
320 6
            'command' => 'set_ns',
321 6
            'domain'  => $domain,
322 6
        ];
323
324 6
        if (sizeof($nameservers) > 13) {
325
            // index starts at 0, so we should check if the index is greater than 12 (which is 13 nameservers)
326 1
            throw new ApiLimitationExceededException(
327 1
                'Can not define more than 13 nameservers through the API'
328 1
            );
329
        }
330
331 5
        $idx = 0;
332
        // check if there are more than 13 nameservers defined
333 5
        foreach ($nameservers as $nameserver) {
334 5
            $requestData['ns' . $idx++] = $nameserver;
335
        }
336
337
        // perform the API call
338 5
        $response = $this->performRawApiCall($requestData);
339
340 5
        $this->log(LogLevel::DEBUG, 'API call executed, parsing response...');
341
342
        // start parsing XML data using Sabre
343 5
        $sabreService = new Service();
344
345
        // map certain values to objects
346 5
        $sabreService->mapValueObject('{}SetNsResponse', SetNsResponse\SetNsResponse::class);
347 5
        $sabreService->mapValueObject('{}SetNsHeader', SetNsResponse\SetNsHeader::class);
348 5
        $sabreService->mapValueObject('{}Response', GeneralResponse\Response::class);
349 5
        $sabreService->mapValueObject('{}ResponseHeader', GeneralResponse\ResponseHeader::class);
350
351
        // parse the data
352 5
        $resultData = $sabreService->parse($response->getContents());
353
354
        // General error, like incorrect api key
355 4
        if ($resultData instanceof GeneralResponse\Response) {
356 1
            $code = $resultData->ResponseHeader->ResponseCode;
357 1
            if ($code != GeneralResponse\ResponseHeader::RESPONSECODE_OK) {
358 1
                throw new DynadotApiException($resultData->ResponseHeader->Error);
359
            }
360
        }
361
362 3
        if (!$resultData instanceof SetNsResponse\SetNsResponse) {
363 1
            throw new DynadotApiException('We failed to parse the response');
364
        }
365
366
        /**
367
         * Check if the API call was successful. If not, return the error
368
         */
369 2
        $code = $resultData->SetNsHeader->SuccessCode;
370 2
        if ($code != SetNsResponse\SetNsHeader::SUCCESSCODE_OK) {
371 1
            throw new DynadotApiException($resultData->SetNsHeader->Error);
372
        }
373
374 1
        $this->log(LogLevel::DEBUG, 'Received correct response. Everything is ok!');
375
    }
376
377
    /**
378
     * List all domains in the account. We will return an array with Domain objects
379
     *
380
     * @return DomainResponse\Domain[]
381
     * @throws \GuzzleHttp\Exception\GuzzleException
382
     * @throws \Level23\Dynadot\Exception\ApiHttpCallFailedException
383
     * @throws \Level23\Dynadot\Exception\DynadotApiException
384
     * @throws \Sabre\Xml\ParseException
385
     */
386 5
    public function getDomainList(): array
387
    {
388 5
        $this->log(LogLevel::DEBUG, 'Start retrieving all domains');
389 5
        $requestData = [
390 5
            'command' => 'list_domain',
391 5
        ];
392
393
        // perform the API call
394 5
        $response = $this->performRawApiCall($requestData);
395
396 5
        $this->log(LogLevel::DEBUG, 'Start parsing response XML');
397
398
        // start parsing XML data using Sabre
399 5
        $sabreService = new Service();
400
401
        // set mapping
402 5
        $sabreService->elementMap = [
403 5
            '{}NameServers'          => function (Reader $reader) {
404
405
                $nameservers = [];
406
                $id          = '';
407
408
                $children = (array)$reader->parseInnerTree();
409
410
                foreach ($children as $child) {
411
                    if ($child['name'] == '{}ServerId') {
412
                        $id = $child['value'];
413
                    } elseif ($child['name'] == '{}ServerName') {
414
                        if (!empty($id) && !empty($child['value'])) {
415
                            $nameserver             = new DomainResponse\NameServer();
416
                            $nameserver->ServerId   = $id;
0 ignored issues
show
Documentation Bug introduced by
The property $ServerId was declared of type integer, but $id is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
417
                            $nameserver->ServerName = $child['value'];
418
419
                            $nameservers[] = $nameserver;
420
                        }
421
                        $id = null;
422
                    }
423
                }
424
425
                return $nameservers;
426 5
            },
427 5
            '{}DomainInfoList'       => function (Reader $reader) {
428 1
                $domains = [];
429
430 1
                $tree = (array)$reader->parseInnerTree();
431
432 1
                foreach ($tree as $item) {
433 1
                    foreach ($item['value'] as $domain) {
434 1
                        $domains[] = $domain['value'];
435
                    }
436
                }
437
438 1
                return $domains;
439 5
            },
440 5
            '{}Registrant'           => $this->contactIdDeserializer,
441 5
            '{}Admin'                => $this->contactIdDeserializer,
442 5
            '{}Technical'            => $this->contactIdDeserializer,
443 5
            '{}Billing'              => $this->contactIdDeserializer,
444 5
            '{}isForSale'            => $this->booleanDeserializer,
445 5
            '{}Hold'                 => $this->booleanDeserializer,
446 5
            '{}RegistrantUnverified' => $this->booleanDeserializer,
447 5
            '{}UdrpLocked'           => $this->booleanDeserializer,
448 5
            '{}Disabled'             => $this->booleanDeserializer,
449 5
            '{}Locked'               => $this->booleanDeserializer,
450 5
            '{}WithAds'              => $this->booleanDeserializer,
451 5
        ];
452
453
        // map certain values to objects
454 5
        $sabreService->mapValueObject('{}ListDomainInfoResponse', ListDomainInfoResponse\ListDomainInfoResponse::class);
455 5
        $sabreService->mapValueObject('{}ListDomainInfoHeader', ListDomainInfoResponse\ListDomainInfoHeader::class);
456 5
        $sabreService->mapValueObject('{}ListDomainInfoContent', ListDomainInfoResponse\ListDomainInfoContent::class);
457 5
        $sabreService->mapValueObject('{}Domain', DomainResponse\Domain::class);
458 5
        $sabreService->mapValueObject('{}NameServerSettings', DomainResponse\NameServerSettings::class);
459 5
        $sabreService->mapValueObject('{}Whois', DomainResponse\Whois::class);
460 5
        $sabreService->mapValueObject('{}Folder', DomainResponse\Folder::class);
461 5
        $sabreService->mapValueObject('{}Response', GeneralResponse\Response::class);
462 5
        $sabreService->mapValueObject('{}ResponseHeader', GeneralResponse\ResponseHeader::class);
463
464
        // parse the data
465 5
        $resultData = $sabreService->parse($response->getContents());
466
467
        // General error, like incorrect api key
468 4
        if ($resultData instanceof GeneralResponse\Response) {
469 1
            $code = $resultData->ResponseHeader->ResponseCode;
470 1
            if ($code != GeneralResponse\ResponseHeader::RESPONSECODE_OK) {
471 1
                throw new DynadotApiException($resultData->ResponseHeader->Error);
472
            }
473
        }
474
475 3
        if (!$resultData instanceof ListDomainInfoResponse\ListDomainInfoResponse) {
476 1
            throw new DynadotApiException('We failed to parse the response');
477
        }
478
479
        /**
480
         * Check if the API call was successful. If not, return the error
481
         */
482 2
        $code = $resultData->ListDomainInfoHeader->ResponseCode;
483 2
        if ($code != ListDomainInfoResponse\ListDomainInfoHeader::RESPONSECODE_OK) {
484 1
            throw new DynadotApiException($resultData->ListDomainInfoHeader->Error);
485
        }
486
487 1
        return $resultData->ListDomainInfoContent->DomainInfoList;
488
    }
489
490
    /**
491
     * Get contact information for a specific contact ID
492
     *
493
     * @param int $contactId The contact ID we should request
494
     *
495
     * @return GetContactResponse\Contact
496
     * @throws \GuzzleHttp\Exception\GuzzleException
497
     * @throws \Level23\Dynadot\Exception\ApiHttpCallFailedException
498
     * @throws \Level23\Dynadot\Exception\DynadotApiException
499
     * @throws \Sabre\Xml\ParseException
500
     */
501 5
    public function getContactInfo(int $contactId): GetContactResponse\Contact
502
    {
503 5
        $this->log(LogLevel::DEBUG, 'Fetch contact details for id ' . $contactId);
504
505 5
        $requestData = [
506 5
            'command'    => 'get_contact',
507 5
            'contact_id' => $contactId,
508 5
        ];
509
510
        // perform the API call
511 5
        $response = $this->performRawApiCall($requestData);
512
513 5
        $this->log(LogLevel::DEBUG, 'Start parsing result');
514
515
        // start parsing XML data using Sabre
516 5
        $sabreService = new Service();
517
518
        // map certain values to objects
519 5
        $sabreService->mapValueObject('{}GetContactResponse', GetContactResponse\GetContactResponse::class);
520 5
        $sabreService->mapValueObject('{}GetContactHeader', GetContactResponse\GetContactHeader::class);
521 5
        $sabreService->mapValueObject('{}GetContactContent', GetContactResponse\GetContactContent::class);
522 5
        $sabreService->mapValueObject('{}Contact', GetContactResponse\Contact::class);
523 5
        $sabreService->mapValueObject('{}Response', GeneralResponse\Response::class);
524 5
        $sabreService->mapValueObject('{}ResponseHeader', GeneralResponse\ResponseHeader::class);
525
526
        // parse the data
527 5
        $resultData = $sabreService->parse($response->getContents());
528
529
        // General error, like incorrect api key
530 4
        if ($resultData instanceof GeneralResponse\Response) {
531 1
            $code = $resultData->ResponseHeader->ResponseCode;
532 1
            if ($code != GeneralResponse\ResponseHeader::RESPONSECODE_OK) {
533 1
                throw new DynadotApiException($resultData->ResponseHeader->Error);
534
            }
535
        }
536
537 3
        if (!$resultData instanceof GetContactResponse\GetContactResponse) {
538 1
            throw new DynadotApiException('We failed to parse the response');
539
        }
540
541
        /**
542
         * Check if the API call was successful. If not, return the error
543
         */
544 2
        $code = $resultData->GetContactHeader->ResponseCode;
545 2
        if ($code != GetContactResponse\GetContactHeader::RESPONSECODE_OK) {
546 1
            throw new DynadotApiException($resultData->GetContactHeader->Error);
547
        }
548
549 1
        return $resultData->GetContactContent->Contact;
550
    }
551
552
    /**
553
     * @throws \Level23\Dynadot\Exception\DynadotApiException
554
     * @throws \Sabre\Xml\ParseException
555
     * @throws \GuzzleHttp\Exception\GuzzleException
556
     * @throws \Level23\Dynadot\Exception\ApiHttpCallFailedException
557
     */
558 4
    public function setRenewOption(string $domain, string $renewOption): bool
559
    {
560 4
        $this->log(LogLevel::INFO, 'Set auto renew for: ' . $domain . ' to: ' . $renewOption);
561
562 4
        $requestData = [
563 4
            'command'      => 'set_renew_option',
564 4
            'domain'       => $domain,
565 4
            'renew_option' => $renewOption,
566 4
        ];
567
568
        // perform the API call
569 4
        $response = $this->performRawApiCall($requestData);
570
571 4
        $this->log(LogLevel::DEBUG, 'Start parsing result');
572
573
        // start parsing XML data using Sabre
574 4
        $sabreService = new Service();
575
576
        // map certain values to objects
577 4
        $sabreService->mapValueObject('{}SetRenewOptionResponse', SetRenewOptionResponse::class);
578 4
        $sabreService->mapValueObject('{}SetRenewOptionHeader', SetRenewOptionHeader::class);
579 4
        $sabreService->mapValueObject('{}Response', GeneralResponse\Response::class);
580 4
        $sabreService->mapValueObject('{}ResponseHeader', GeneralResponse\ResponseHeader::class);
581
582
        // parse the data
583 4
        $resultData = $sabreService->parse($response->getContents());
584
585
        // General error, like incorrect api key
586 4
        if ($resultData instanceof GeneralResponse\Response) {
587 1
            $code = $resultData->ResponseHeader->ResponseCode;
588 1
            if ($code != GeneralResponse\ResponseHeader::RESPONSECODE_OK) {
589 1
                throw new DynadotApiException($resultData->ResponseHeader->Error);
590
            }
591
        }
592
593 3
        if (!$resultData instanceof SetRenewOptionResponse) {
594 1
            throw new DynadotApiException('We failed to parse the response');
595
        }
596
597 2
        $code = $resultData->SetRenewOptionHeader->SuccessCode;
598 2
        if ($code != SetRenewOptionHeader::SUCCESSCODE_OK) {
599 1
            throw new DynadotApiException((string)$resultData->SetRenewOptionHeader->Error);
600
        }
601
602 1
        return true;
603
    }
604
}
605