1 | <?php |
||
23 | class Api |
||
24 | { |
||
25 | /** |
||
26 | * Example: http://www.example.com |
||
27 | * |
||
28 | * @var string |
||
29 | */ |
||
30 | protected $host; |
||
31 | |||
32 | /** |
||
33 | * The API key from your Dandomain admin |
||
34 | * |
||
35 | * @var string |
||
36 | */ |
||
37 | protected $apiKey; |
||
38 | |||
39 | /** |
||
40 | * This is the HTTP client |
||
41 | * |
||
42 | * @var ClientInterface |
||
43 | */ |
||
44 | protected $client; |
||
45 | |||
46 | /** |
||
47 | * This is the last response |
||
48 | * |
||
49 | * @var Response |
||
50 | */ |
||
51 | protected $response; |
||
52 | |||
53 | /** |
||
54 | * These are the options used for the next request |
||
55 | * After that request, these options are reset |
||
56 | * |
||
57 | * @var array |
||
58 | */ |
||
59 | protected $options; |
||
60 | |||
61 | /** |
||
62 | * These are default options used for every request |
||
63 | * |
||
64 | * @var array |
||
65 | */ |
||
66 | protected $defaultOptions; |
||
67 | |||
68 | /** |
||
69 | * These are the resolved options used in the last request |
||
70 | * |
||
71 | * @var array |
||
72 | */ |
||
73 | protected $lastOptions; |
||
74 | |||
75 | /* |
||
76 | * These are endpoints in the Dandomain API |
||
77 | */ |
||
78 | /** |
||
79 | * @var Endpoint\Customer |
||
80 | */ |
||
81 | protected $customer; |
||
82 | |||
83 | /** |
||
84 | * @var Endpoint\Discount |
||
85 | */ |
||
86 | protected $discount; |
||
87 | |||
88 | /** |
||
89 | * @var Endpoint\Order; |
||
90 | */ |
||
91 | protected $order; |
||
92 | |||
93 | /** |
||
94 | * @var Endpoint\Product; |
||
95 | */ |
||
96 | protected $product; |
||
97 | |||
98 | /** |
||
99 | * @var Endpoint\ProductData; |
||
100 | */ |
||
101 | protected $productData; |
||
102 | |||
103 | /** |
||
104 | * @var Endpoint\ProductTag; |
||
105 | */ |
||
106 | protected $productTag; |
||
107 | |||
108 | /** |
||
109 | * @var Endpoint\RelatedData; |
||
110 | */ |
||
111 | protected $relatedData; |
||
112 | |||
113 | /** |
||
114 | * @var Endpoint\Settings; |
||
115 | */ |
||
116 | protected $settings; |
||
117 | |||
118 | 2 | public function __construct(string $host, string $apiKey, array $defaultOptions = []) |
|
130 | |||
131 | /** |
||
132 | * This ensures lazy loading of the endpoint classes |
||
133 | * |
||
134 | * @param string $name |
||
135 | * @return Endpoint\Endpoint |
||
136 | */ |
||
137 | 2 | public function __get($name) |
|
155 | |||
156 | /** |
||
157 | * Will always return a JSON result contrary to Dandomains API |
||
158 | * Errors are formatted as described here: http://jsonapi.org/format/#errors |
||
159 | * |
||
160 | * @param string $method |
||
161 | * @param string $uri |
||
162 | * @param array|\stdClass $body The body is sent as JSON |
||
163 | * @param array $options |
||
164 | * @return mixed |
||
165 | */ |
||
166 | public function doRequest(string $method, string $uri, $body = null, array $options = []) |
||
167 | { |
||
168 | $parsedResponse = []; |
||
169 | |||
170 | try { |
||
171 | // merge all options |
||
172 | // the priority is |
||
173 | // 1. options supplied by the user |
||
174 | // 2. options supplied by the method calling |
||
175 | // 3. the default options |
||
176 | $options = $this->resolveOptions($this->defaultOptions, $options, $this->options); |
||
177 | |||
178 | if (!empty($body)) { |
||
179 | $body = $this->objectToArray($body); |
||
180 | Assert::that($body)->notEmpty('The body of the request cannot be empty'); |
||
181 | |||
182 | // the body will always override any other data sent |
||
183 | $options['json'] = $body; |
||
184 | } |
||
185 | |||
186 | // save the resolved options |
||
187 | $this->lastOptions = $options; |
||
188 | |||
189 | // replace the {KEY} placeholder with the api key |
||
190 | $url = $this->host . str_replace('{KEY}', $this->apiKey, $uri); |
||
191 | |||
192 | // do request |
||
193 | $this->response = $this->client->request($method, $url, $options); |
||
194 | |||
195 | // parse response and create error object if the json decode throws an exception |
||
196 | try { |
||
197 | $parsedResponse = \GuzzleHttp\json_decode((string)$this->response->getBody(), true); |
||
198 | } catch (\InvalidArgumentException $e) { |
||
199 | $parsedResponse['errors'][] = [ |
||
200 | 'status' => $this->response->getStatusCode(), |
||
201 | 'title' => 'JSON parse error', |
||
202 | 'detail' => $e->getMessage() |
||
203 | ]; |
||
204 | } |
||
205 | |||
206 | if ($this->response->getStatusCode() !== 200) { |
||
207 | $parsedResponse['errors'] = []; |
||
208 | $parsedResponse['errors'][] = [ |
||
209 | 'status' => $this->response->getStatusCode(), |
||
210 | 'detail' => 'See Api::$response for details' |
||
211 | ]; |
||
212 | } |
||
213 | } catch (GuzzleException $e) { |
||
214 | $parsedResponse['errors'] = []; |
||
215 | $parsedResponse['errors'][] = [ |
||
216 | 'title' => 'Unexpected error', |
||
217 | 'detail' => $e->getMessage() |
||
218 | ]; |
||
219 | } finally { |
||
220 | // reset request options |
||
221 | $this->options = []; |
||
222 | } |
||
223 | |||
224 | return $parsedResponse; |
||
225 | } |
||
226 | |||
227 | /** |
||
228 | * @return ClientInterface |
||
229 | */ |
||
230 | public function getClient() : ClientInterface |
||
238 | |||
239 | /** |
||
240 | * @param ClientInterface $client |
||
241 | * @return Api |
||
242 | */ |
||
243 | public function setClient(ClientInterface $client) : Api |
||
244 | { |
||
245 | $this->client = $client; |
||
246 | return $this; |
||
247 | } |
||
248 | |||
249 | /** |
||
250 | * Returns the latest response |
||
251 | * |
||
252 | * @return ResponseInterface |
||
253 | */ |
||
254 | public function getResponse() : ResponseInterface |
||
258 | |||
259 | /** |
||
260 | * Sets request options for the next request |
||
261 | * |
||
262 | * @param array $options |
||
263 | * @return Api |
||
264 | */ |
||
265 | public function setOptions(array $options) : Api |
||
270 | |||
271 | /** |
||
272 | * Sets default request options |
||
273 | * |
||
274 | * @param array $defaultOptions |
||
275 | * @return Api |
||
276 | */ |
||
277 | public function setDefaultOptions(array $defaultOptions) : Api |
||
278 | { |
||
279 | $this->defaultOptions = $defaultOptions; |
||
280 | return $this; |
||
281 | } |
||
282 | |||
283 | /** |
||
284 | * @return array |
||
285 | */ |
||
286 | public function getLastOptions(): array |
||
287 | { |
||
288 | return $this->lastOptions; |
||
289 | } |
||
290 | |||
291 | /** |
||
292 | * Helper method to convert a \stdClass into an array |
||
293 | * |
||
294 | * @param $obj |
||
295 | * @return array |
||
296 | */ |
||
297 | protected function objectToArray($obj) : array |
||
305 | |||
306 | protected function configureOptions(OptionsResolver $resolver) : void |
||
307 | { |
||
308 | $refl = new \ReflectionClass(RequestOptions::class); |
||
309 | |||
321 | |||
322 | protected function resolveOptions(array ...$options) : array |
||
336 | } |
||
337 |
It seems like the type of the argument is not accepted by the function/method which you are calling.
In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.
We suggest to add an explicit type cast like in the following example: