AbstractMethod::validateAndSend()   B
last analyzed

Complexity

Conditions 5
Paths 1

Size

Total Lines 29
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 5.9256

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 5
eloc 16
nc 1
nop 3
dl 0
loc 29
ccs 10
cts 15
cp 0.6667
crap 5.9256
rs 8.439
c 2
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
                ],
90
            ]);
91
92 4
            return $response;
93
        } catch (ClientException $e) {
94
            $responseContents = json_decode($e->getResponse()->getBody()->getContents(), true);
95
96
            if (false !== $responseContents && !empty($responseContents['error_advice'])) {
97
                throw new \Exception($responseContents['error_advice']);
98
            }
99
100
            throw new \Exception($e->getMessage());
101
        }
102
    }
103
}
104