Completed
Pull Request — master (#5)
by
unknown
09:17
created

AbstractMethod::validateAndSend()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 30
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 5.7629

Importance

Changes 0
Metric Value
cc 5
eloc 17
nc 4
nop 3
dl 0
loc 30
ccs 11
cts 16
cp 0.6875
crap 5.7629
rs 8.439
c 0
b 0
f 0
1
<?php
2
3
namespace ZpgRtf\Methods;
4
5
use GuzzleHttp\Exception\ClientException;
6
use GuzzleHttp\Client;
7
use GuzzleHttp\Psr7\Response;
8
use League\JsonGuard\Validator;
9
use League\JsonReference\Dereferencer;
10
11
/**
12
 * The listing method allows you to list, update or delete listings on the ZPG rtf.
13
 */
14
abstract class AbstractMethod
15
{
16
    /** @var array */
17
    private $baseUri = [
18
        'sandbox' => 'https://realtime-listings-api.webservices.zpg.co.uk/sandbox/v1/',
19
        'live' => 'https://realtime-listings-api.webservices.zpg.co.uk/live/v1/',
20
    ];
21
22
    /** @var Client */
23
    private $client;
24
25
    /**
26
     * @param string $certificate
27
     * @param string $env
28
     *
29
     * @throws \Exception You will get an exception if you use an invalid environment variable.
30
     */
31 8
    public function __construct(string $certificate, string $env = 'sandbox')
32
    {
33 8
        if (!in_array($env, ['sandbox', 'live'])) {
34
            throw new \Exception(sprintf('Invalid environment. %s is not in [sandbox, live]', $env));
35
        }
36
37 8
        $this->client = new Client([
38 8
            'base_uri' => $this->baseUri[$env],
39 8
            'cert' => $certificate
40
        ]);
41 8
    }
42
43
    /**
44
     * @return Client
45
     */
46 4
    public function getClient(): Client
47
    {
48 4
        return $this->client;
49
    }
50
51
    /**
52
     * @param Client $client
53
     *
54
     * @return static
55
     */
56 8
    public function setClient(Client $client): self
57
    {
58 8
        $this->client = $client;
59
60 8
        return $this;
61
    }
62
63
    /**
64
     * @param string $schemaUri
65
     * @param string $uri
66
     * @param \JsonSerializable $object
67
     *
68
     * @return \GuzzleHttp\Psr7\Response
69
     *
70
     * @throws \Exception If validation fails. Needs a custom exception type.
71
     */
72 8
    protected function validateAndSend(string $schemaUri, string $uri, \JsonSerializable $object): Response
73
    {
74 8
        $payload = json_encode($object);
75 8
        $schema = Dereferencer::draft4()->dereference($schemaUri);
76 8
        $validator = new Validator(json_decode($payload), $schema);
77
78
        // Let's improve this with some sort of factory method to handle the response into a custom response type
79
        // whether it's a normal response, validation error or guzzle exception.
80 8
        if ($validator->fails()) {
81 4
            throw new \Exception('Fails validation');
82
        }
83
84
        try {
85 4
            $response = $this->getClient()->request('POST', $uri, [
86 4
                'body' => $payload,
87
                'headers' => [
88 4
                    'Content-Type' => 'application/json; profile=' . $schemaUri,
89 4
                    'ZPG-Listing-ETag' => md5($payload),
90
                ],
91
            ]);
92
93 4
            return $response;
94
        } catch (ClientException $e) {
95
            $responseContents = json_decode($e->getResponse()->getBody()->getContents(), true);
96
97
            if (false !== $responseContents && !empty($responseContents['error_advice'])) {
98
                throw new \Exception($responseContents['error_advice']);
99
            }
100
101
            throw new \Exception($e->getMessage());
102
        }
103
    }
104
}
105