2
2
3
3
namespace ClarityTech \Shopify ;
4
4
5
- use GuzzleHttp \Client ;
6
5
use Illuminate \Support \Facades \Config ;
6
+ use Illuminate \Support \Facades \Http ;
7
7
use ClarityTech \Shopify \Exceptions \ShopifyApiException ;
8
8
use ClarityTech \Shopify \Exceptions \ShopifyApiResourceNotFoundException ;
9
+ use Psr \Http \Message \ResponseInterface ;
9
10
10
11
class Shopify
11
12
{
12
- protected Client $ client ;
13
-
14
13
protected static ?string $ key = null ;
15
14
protected static ?string $ secret = null ;
16
15
protected static ?string $ shopDomain = null ;
17
16
protected static ?string $ accessToken = null ;
18
17
19
18
public const VERSION = '2020-01 ' ;
20
19
public const PREFIX = 'admin/api/ ' ;
20
+
21
+ public bool $ debug = false ;
21
22
22
23
protected array $ requestHeaders = [];
23
24
protected array $ responseHeaders = [];
24
25
protected $ responseStatusCode ;
25
26
protected $ reasonPhrase ;
26
27
27
- public function __construct (Client $ client )
28
+ // public function __construct(Client $client)
29
+ // {
30
+ // $this->client = $client;
31
+ // self::$key = Config::get('shopify.key');
32
+ // self::$secret = Config::get('shopify.secret');
33
+ // }
34
+ public function __construct ()
28
35
{
29
- $ this ->client = $ client ;
30
36
self ::$ key = Config::get ('shopify.key ' );
31
37
self ::$ secret = Config::get ('shopify.secret ' );
32
38
}
33
39
40
+ //use Illuminate\Support\Facades\Http;
41
+
34
42
public function api ()
35
43
{
36
44
return $ this ;
@@ -133,9 +141,13 @@ public function getAccessToken(string $code)
133
141
134
142
$ response = $ this ->makeRequest ('POST ' , $ uri , $ payload );
135
143
136
- $ this ->setAccessToken ($ response );
144
+ $ response = $ response ->json ();
145
+
146
+ $ accessToken = $ response ['access_token ' ] ?? null ;
147
+
148
+ $ this ->setAccessToken ($ accessToken );
137
149
138
- return $ response ?? '' ;
150
+ return $ accessToken ?? '' ;
139
151
}
140
152
141
153
public function setAccessToken ($ accessToken )
@@ -152,7 +164,12 @@ public function setShop(string $domain, string $accessToken)
152
164
return $ this ;
153
165
}
154
166
155
- protected function getXShopifyAccessToken () : array
167
+ public function isTokenSet () : bool
168
+ {
169
+ return !is_null (self ::$ accessToken );
170
+ }
171
+
172
+ protected function getXShopifyAccessTokenHeader () : array
156
173
{
157
174
return ['X-Shopify-Access-Token ' => self ::$ accessToken ];
158
175
}
@@ -171,78 +188,94 @@ public function removeHeaders() : self
171
188
return $ this ;
172
189
}
173
190
191
+ public function setDebug (bool $ status = true )
192
+ {
193
+ $ this ->debug = $ status ;
194
+
195
+ return $ this ;
196
+ }
197
+
174
198
/*
175
199
* $args[0] is for route uri and $args[1] is either request body or query strings
176
200
*/
177
201
public function __call ($ method , $ args )
178
202
{
179
- list ($ uri , $ params ) = [ltrim ($ args [0 ], "/ " ), $ args [1 ] ?? []];
180
- $ response = $ this ->makeRequest ($ method , $ uri , $ params , $ this ->getXShopifyAccessToken ());
203
+ list ($ uri , $ params ) = [ltrim ($ args [0 ], '/ ' ), $ args [1 ] ?? []];
204
+ $ response = $ this ->makeRequest ($ method , $ uri , $ params );
205
+
206
+ if (is_array ($ array = $ response ->json ()) && count ($ array ) == 1 ) {
207
+ return array_shift ($ array );
208
+ }
181
209
182
- //return (is_array($response)) ? $this->convertResponseToCollection($response) : $response;
183
210
return $ response ;
184
211
}
185
212
186
- public function makeRequest ( string $ method , string $ path , array $ params = [], array $ headers = [])
213
+ public function getHeadersForSend () : array
187
214
{
188
- $ query = in_array ( $ method , [ ' get ' , ' delete ' ]) ? ' query ' : ' json ' ;
215
+ $ headers = [] ;
189
216
190
- $ rateLimit = explode ('/ ' , $ this ->getHeader ('X-Shopify-Shop-Api-Call-Limit ' ));
191
-
192
- if ($ rateLimit [0 ] >= 38 ) {
193
- sleep (15 );
217
+ if ($ this ->isTokenSet ()) {
218
+ $ headers = $ this ->getXShopifyAccessTokenHeader ();
194
219
}
220
+ return array_merge ($ headers , $ this ->requestHeaders );
221
+ }
222
+
223
+ public function makeRequest (string $ method , string $ path , array $ params = [])
224
+ {
225
+ //TODO apply ratelimit or handle it outside from caller function
226
+ // aso that we can have more control when we can retry etc
195
227
196
228
$ url = self ::getBaseUrl () . $ path ;
197
229
198
- $ response = $ this ->client
199
- ->request (strtoupper ($ method ), $ url , [
200
- 'headers ' => array_merge ($ headers , $ this ->requestHeaders ),
201
- $ query => $ params ,
202
- 'timeout ' => 120.0 ,
203
- 'connect_timeout ' => 120.0 ,
204
- 'http_errors ' => false ,
205
- "verify " => false
206
- ]);
207
-
208
- $ this ->parseResponse ($ response );
209
- $ responseBody = $ this ->responseBody ($ response );
210
-
211
- logger ('shopify request ENDPOINT ' . $ url );
212
- logger ('shopify request params ' , (array ) $ params );
213
- logger ('shopify request requestHeaders ' , (array ) array_merge ($ headers , $ this ->requestHeaders ));
214
-
215
- if (isset ($ responseBody ['errors ' ]) || $ response ->getStatusCode () >= 400 ) {
216
- logger ('shopify error responseheaders ' , (array ) $ this ->responseHeaders );
217
- logger ('shopify error response ' , (array ) $ responseBody );
218
-
219
- if (! is_null ($ responseBody )) {
220
- $ errors = is_array ($ responseBody ['errors ' ])
221
- ? json_encode ($ responseBody ['errors ' ])
222
- : $ responseBody ['errors ' ];
223
-
224
- if ($ response ->getStatusCode () == 404 ) {
225
- throw new ShopifyApiResourceNotFoundException (
226
- $ errors ?? $ response ->getReasonPhrase (),
227
- $ response ->getStatusCode ()
228
- );
229
- }
230
- }
230
+ $ method = strtolower ($ method );
231
231
232
- throw new ShopifyApiException (
233
- $ errors ?? $ response ->getReasonPhrase (),
234
- $ response ->getStatusCode ()
235
- );
232
+ $ response = Http::withOptions (['debug ' => $ this ->debug ,])
233
+ ->withHeaders ($ this ->getHeadersForSend ())
234
+ ->$ method ($ url , $ params );
235
+
236
+ $ this ->parseResponse ($ response ->toPsrResponse ());
237
+
238
+ if ($ response ->successful ()) {
239
+ return $ response ;
236
240
}
237
241
238
- return (is_array ($ responseBody ) && (count ($ responseBody ) > 0 )) ? array_shift ($ responseBody ) : $ responseBody ;
242
+ return $ this ->throwErrors ($ response );
243
+ }
244
+
245
+ protected function parseResponse (ResponseInterface $ response )
246
+ {
247
+ $ this
248
+ ->setResponseHeaders ($ response ->getHeaders ())
249
+ ->setStatusCode ($ response ->getStatusCode ())
250
+ ->setReasonPhrase ($ response ->getReasonPhrase ());
239
251
}
240
252
241
- private function parseResponse ( $ response )
253
+ protected function throwErrors ( $ httpResponse )
242
254
{
243
- $ this ->parseHeaders ($ response ->getHeaders ());
244
- $ this ->setStatusCode ($ response ->getStatusCode ());
245
- $ this ->setReasonPhrase ($ response ->getReasonPhrase ());
255
+ $ response = $ httpResponse ->json ();
256
+ $ psrResponse = $ httpResponse ->toPsrResponse ();
257
+
258
+ $ statusCode = $ psrResponse ->getStatusCode ();
259
+
260
+ if (isset ($ response ['errors ' ]) || $ statusCode >= 400 ) {
261
+ $ errorString = null ;
262
+
263
+ if (!is_null ($ response )) {
264
+ $ errorString = is_array ($ response ['errors ' ]) ? json_encode ($ response ['errors ' ]) : $ response ['errors ' ];
265
+ }
266
+
267
+ if ($ statusCode == 404 ) {
268
+ throw new ShopifyApiResourceNotFoundException (
269
+ $ errorString ?? $ psrResponse ->getReasonPhrase (),
270
+ $ statusCode
271
+ );
272
+ }
273
+
274
+ throw new ShopifyApiException (
275
+ $ errorString ?? $ psrResponse ->getReasonPhrase (),
276
+ $ statusCode
277
+ );
278
+ }
246
279
}
247
280
248
281
public function verifyRequest ($ queryParams )
@@ -287,6 +320,7 @@ public function verifyWebHook($data, $hmacHeader) : bool
287
320
private function setStatusCode ($ code )
288
321
{
289
322
$ this ->responseStatusCode = $ code ;
323
+ return $ this ;
290
324
}
291
325
292
326
public function getStatusCode ()
@@ -304,11 +338,10 @@ public function getReasonPhrase()
304
338
return $ this ->reasonPhrase ;
305
339
}
306
340
307
- private function parseHeaders ($ headers )
341
+ private function setResponseHeaders ($ headers )
308
342
{
309
- foreach ($ headers as $ name => $ values ) {
310
- $ this ->responseHeaders = array_merge ($ this ->responseHeaders , [$ name => implode (', ' , $ values )]);
311
- }
343
+ $ this ->responseHeaders = $ headers ;
344
+ return $ this ;
312
345
}
313
346
314
347
public function getHeaders ()
@@ -325,9 +358,4 @@ public function hasHeader($header)
325
358
{
326
359
return array_key_exists ($ header , $ this ->responseHeaders );
327
360
}
328
-
329
- private function responseBody ($ response )
330
- {
331
- return json_decode ($ response ->getBody (), true );
332
- }
333
361
}
0 commit comments