APIClient   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 100
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 36
dl 0
loc 100
rs 10
c 0
b 0
f 0
wmc 13

6 Methods

Rating   Name   Duplication   Size   Complexity  
A getPackage() 0 3 1
A getClientOptions() 0 7 1
A getSearchData() 0 3 1
B getData() 0 37 8
A getGuzzleClient() 0 3 1
A setGuzzleClient() 0 4 1
1
<?php
2
3
namespace SilverStripe\CKANRegistry\Service;
4
5
use GuzzleHttp\Client;
6
use GuzzleHttp\Psr7\Request;
7
use RuntimeException;
8
use SilverStripe\CKANRegistry\Model\Resource;
9
use SilverStripe\Core\Extensible;
10
use SilverStripe\Core\Injector\Injectable;
11
12
class APIClient implements APIClientInterface
13
{
14
    use Extensible;
15
    use Injectable;
16
17
    private static $dependencies = [
18
        'GuzzleClient' => '%$' . Client::class,
19
    ];
20
21
    /**
22
     * @var Client
23
     */
24
    protected $guzzleClient;
25
26
    /**
27
     * Instance cache for repeated calls within the same request
28
     *
29
     * @var array[]
30
     */
31
    protected $cache;
32
33
    public function getPackage(Resource $resource)
34
    {
35
        return $this->getData($resource, 'package_show', 'DataSet');
36
    }
37
38
    public function getSearchData(Resource $resource)
39
    {
40
        return $this->getData($resource, 'datastore_search', 'Identifier');
41
    }
42
43
    public function getData(Resource $resource, $action = 'datastore_search', $id = 'Identifier')
44
    {
45
        $endpoint = sprintf(
46
            '%s/api/%s/action/%s?id=%s',
47
            trim($resource->Endpoint, '/'),
48
            APIClientInterface::API_VERSION,
49
            $action,
50
            $resource->{$id}
51
        );
52
53
        // Check for a cached result
54
        if (isset($this->cache[$endpoint])) {
55
            return $this->cache[$endpoint];
56
        }
57
58
        $request = new Request('GET', $endpoint);
59
        $response = $this->getGuzzleClient()->send($request, $this->getClientOptions());
60
61
        $statusCode = $response->getStatusCode();
62
        if ($statusCode < 200 || $statusCode >= 300) {
63
            throw new RuntimeException('CKAN API is not available. Error code ' . $statusCode);
64
        }
65
66
        if (!count(preg_grep('#application/json#', $response->getHeader('Content-Type')))) {
67
            throw new RuntimeException('CKAN API returns an invalid response: Content-Type is not JSON');
68
        }
69
70
        $responseBody = json_decode($response->getBody()->getContents(), true);
71
72
        if (!$responseBody || !isset($responseBody['success']) || !$responseBody['success']) {
73
            throw new RuntimeException('CKAN API returns an invalid response: Responded as invalid');
74
        }
75
76
        // Store cached result for subsequent calls within the same request
77
        $this->cache[$endpoint] = $responseBody;
78
79
        return $responseBody;
80
    }
81
82
    /**
83
     * @return \GuzzleHttp\Client
84
     */
85
    protected function getGuzzleClient()
86
    {
87
        return $this->guzzleClient;
88
    }
89
90
    /**
91
     * @param Client $guzzleClient
92
     * @return $this
93
     */
94
    public function setGuzzleClient(Client $guzzleClient)
95
    {
96
        $this->guzzleClient = $guzzleClient;
97
        return $this;
98
    }
99
100
    /**
101
     * Get Guzzle client options
102
     *
103
     * @return array
104
     */
105
    protected function getClientOptions()
106
    {
107
        $options = [
108
            'http_errors' => false,
109
        ];
110
        $this->extend('updateClientOptions', $options);
111
        return $options;
112
    }
113
}
114