Passed
Pull Request — master (#74)
by Adam
08:58
created

Client::getVersion()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 4
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 6
rs 10
1
<?php
2
3
namespace AcquiaCloudApi\Connector;
4
5
use Psr\Http\Message\ResponseInterface;
6
use GuzzleHttp\Exception\BadResponseException;
7
use AcquiaCloudApi\Exception\ApiErrorException;
8
use Psr\Http\Message\StreamInterface;
9
10
/**
11
 * Class Client
12
 *
13
 * @package AcquiaCloudApi\CloudApi
14
 */
15
class Client implements ClientInterface
16
{
17
    /**
18
     * @var ConnectorInterface The API connector.
19
     */
20
    protected $connector;
21
22
    /**
23
     * @var array Query strings to be applied to the request.
24
     */
25
    protected $query = [];
26
27
    /**
28
     * @var array Guzzle options to be applied to the request.
29
     */
30
    protected $options = [];
31
32
    /**
33
     * Client constructor.
34
     *
35
     * @param ConnectorInterface $connector
36
     */
37
    public function __construct(ConnectorInterface $connector)
38
    {
39
        $this->connector = $connector;
40
    }
41
42
    /**
43
     * Client factory method for instantiating.
44
     *
45
     * @param ConnectorInterface $connector
46
     *
47
     * @return static
48
     */
49
    public static function factory(ConnectorInterface $connector)
50
    {
51
        $client = new static(
52
            $connector
53
        );
54
55
        return $client;
56
    }
57
58
    /**
59
     * Returns the current version of the library.
60
     *
61
     * @return string
62
     * @throws \Exception
63
     */
64
    public function getVersion()
65
    {
66
        if ($file = @file_get_contents(dirname(dirname(__DIR__)) . '/VERSION')) {
67
            return trim($file);
68
        } else {
69
            throw new \Exception('No VERSION file');
70
        }
71
    }
72
73
    /**
74
     * @inheritdoc
75
     */
76
    public function request(string $verb, string $path, array $options = [])
77
    {
78
        // @TODO follow this up by removing $options from the parameters able
79
        // to be passed into this function and instead solely relying on the
80
        // addOption() method as this can then be tested.
81
        $this->addOption('headers', [
82
            'User-Agent' => sprintf(
83
                "%s/%s (https://github.com/typhonius/acquia-php-sdk-v2)",
84
                'acquia-php-sdk-v2',
85
                $this->getVersion()
86
            )
87
        ]);
88
89
        // Combine options set globally e.g. headers with options set by individual API calls e.g. form_params.
90
        $options = $this->options + $options;
91
        $options['query'] = $this->query;
92
93
        // This library can be standalone or as a dependency. Dependent libraries may also set their own user agent
94
        // which will make $options['headers']['User-Agent'] an array.
95
        // We need to reverse the array of User-Agent headers to order this library's header first in log files.
96
        // As Guzzle joins arrays with a comma, we must implode with a space here to pass Guzzle a string.
97
        if (is_array($options['headers']['User-Agent'])) {
98
            $options['headers']['User-Agent'] = implode(' ', array_reverse($options['headers']['User-Agent']));
99
        }
100
101
        if (!empty($options['query']['filter']) && is_array($options['query']['filter'])) {
102
            // Default to an AND filter.
103
            $options['query']['filter'] = implode(',', $options['query']['filter']);
104
        }
105
        $response = $this->makeRequest($verb, $path, $options);
106
107
        return $this->processResponse($response);
108
    }
109
110
    /**
111
     * @inheritdoc
112
     */
113
    public function makeRequest(string $verb, string $path, array $options = [])
114
    {
115
        try {
116
            $response = $this->connector->sendRequest($verb, $path, $options);
117
        } catch (BadResponseException $e) {
118
            $response = $e->getResponse();
119
        }
120
121
        return $response;
122
    }
123
124
    /**
125
     * @inheritdoc
126
     */
127
    public function processResponse(ResponseInterface $response)
128
    {
129
130
        $body = $response->getBody();
131
132
        $object = json_decode($body);
133
        if (json_last_error() !== JSON_ERROR_NONE) {
134
            return $body;
135
        }
136
137
        if (property_exists($object, '_embedded') && property_exists($object->_embedded, 'items')) {
138
            return $object->_embedded->items;
139
        }
140
141
        if (property_exists($object, 'error') && property_exists($object, 'message')) {
142
            throw new ApiErrorException($object);
143
        }
144
145
        return $object;
146
    }
147
148
    /**
149
     * @inheritdoc
150
     */
151
    public function getQuery()
152
    {
153
        return $this->query;
154
    }
155
156
    /**
157
     * @inheritdoc
158
     */
159
    public function clearQuery()
160
    {
161
        $this->query = [];
162
    }
163
164
    /**
165
     * @inheritdoc
166
     */
167
    public function addQuery($name, $value)
168
    {
169
        $this->query = array_merge_recursive($this->query, [$name => $value]);
170
    }
171
172
    /**
173
     * @inheritdoc
174
     */
175
    public function getOptions()
176
    {
177
        return $this->options;
178
    }
179
180
    /**
181
     * @inheritdoc
182
     */
183
    public function clearOptions()
184
    {
185
        $this->options = [];
186
    }
187
188
    /**
189
     * @inheritdoc
190
     */
191
    public function addOption($name, $value)
192
    {
193
        $this->options = array_merge_recursive($this->options, [$name => $value]);
194
    }
195
}
196