1: | <?php |
2: | namespace Hyperwallet\Util; |
3: | use GuzzleHttp\Client; |
4: | use GuzzleHttp\Exception\BadResponseException; |
5: | use GuzzleHttp\Exception\ConnectException; |
6: | use Hyperwallet\Exception\HyperwalletApiException; |
7: | use Hyperwallet\Exception\HyperwalletException; |
8: | use Hyperwallet\Model\BaseModel; |
9: | use Hyperwallet\Response\ErrorResponse; |
10: | use Psr\Http\Message\ResponseInterface; |
11: | |
12: | |
13: | |
14: | |
15: | |
16: | |
17: | class ApiClient { |
18: | |
19: | |
20: | |
21: | |
22: | |
23: | |
24: | const VERSION = '2.2.3'; |
25: | |
26: | |
27: | |
28: | |
29: | |
30: | |
31: | private $client; |
32: | |
33: | |
34: | |
35: | |
36: | |
37: | |
38: | private $encryption; |
39: | |
40: | |
41: | |
42: | |
43: | |
44: | |
45: | private $uuid; |
46: | |
47: | |
48: | |
49: | |
50: | |
51: | |
52: | private $isEncrypted = false; |
53: | |
54: | |
55: | |
56: | |
57: | |
58: | |
59: | |
60: | |
61: | |
62: | |
63: | public function __construct($username, $password, $server, $clientOptions = array(), $encryptionData = array()) { |
64: | $this->uuid = HyperwalletUUID::v4(); |
65: | |
66: | $this->client = new Client(array_merge_recursive(array( |
67: | 'base_uri' => $server, |
68: | 'auth' => array($username, $password), |
69: | 'headers' => array( |
70: | 'User-Agent' => 'Hyperwallet PHP SDK v' . self::VERSION, |
71: | 'Accept' => 'application/json', |
72: | 'x-sdk-version' => self::VERSION, |
73: | 'x-sdk-type' => 'PHP', |
74: | 'x-sdk-contextId' => $this->uuid) |
75: | ), $clientOptions)); |
76: | if (!empty($encryptionData) && isset($encryptionData['clientPrivateKeySetLocation']) && |
77: | isset($encryptionData['hyperwalletKeySetLocation'])) { |
78: | $this->isEncrypted = true; |
79: | $this->encryption = new HyperwalletEncryption($encryptionData['clientPrivateKeySetLocation'], $encryptionData['hyperwalletKeySetLocation']); |
80: | } |
81: | } |
82: | |
83: | |
84: | |
85: | |
86: | |
87: | |
88: | |
89: | |
90: | |
91: | |
92: | |
93: | |
94: | |
95: | public function doPost($partialUrl, array $uriParams, BaseModel $data = null, array $query = array(), array $headers = array()) { |
96: | return $this->doRequest('POST', $partialUrl, $uriParams, array( |
97: | 'query' => $query, |
98: | 'body' => $data ? \GuzzleHttp\json_encode($data->getPropertiesForCreate(), JSON_FORCE_OBJECT) : '{}', |
99: | 'headers' => array_merge($headers, array( |
100: | 'Content-Type' => 'application/json' |
101: | )) |
102: | )); |
103: | } |
104: | |
105: | |
106: | |
107: | |
108: | |
109: | |
110: | |
111: | |
112: | |
113: | |
114: | |
115: | |
116: | public function doPut($partialUrl, array $uriParams, BaseModel $data, array $query) { |
117: | return $this->doRequest('PUT', $partialUrl, $uriParams, array( |
118: | 'query' => $query, |
119: | 'body' => \GuzzleHttp\json_encode($data->getPropertiesForUpdate(), JSON_FORCE_OBJECT), |
120: | 'headers' => array( |
121: | 'Content-Type' => 'application/json' |
122: | ) |
123: | )); |
124: | } |
125: | |
126: | |
127: | |
128: | |
129: | |
130: | |
131: | |
132: | |
133: | |
134: | |
135: | |
136: | public function doGet($partialUrl, array $uriParams, array $query) { |
137: | return $this->doRequest('GET', $partialUrl, $uriParams, array( |
138: | 'query' => $query |
139: | )); |
140: | } |
141: | |
142: | |
143: | |
144: | |
145: | |
146: | |
147: | |
148: | |
149: | |
150: | |
151: | |
152: | |
153: | private function doRequest($method, $url, array $urlParams, array $options) { |
154: | try { |
155: | $uri = new HyperwalletUriTemplate(); |
156: | if (!isset($options['headers'])) { |
157: | $options[] = array('headers' => array()); |
158: | } |
159: | $options['headers']['Accept'] = 'application/json'; |
160: | if ($this->isEncrypted) { |
161: | $options['headers']['Accept'] = 'application/jose+json'; |
162: | $options['headers']['Content-Type'] = 'application/jose+json'; |
163: | if (isset($options['body'])) { |
164: | $options['body'] = $this->encryption->encrypt(json_decode($options['body'], true)); |
165: | } |
166: | } |
167: | $response = $this->client->request($method, $uri->expand($url, $urlParams), $options); |
168: | if ($response->getStatusCode() === 204) { |
169: | return array(); |
170: | } |
171: | $this->checkResponseHeaderContentType($response); |
172: | $body = $this->isEncrypted ? \GuzzleHttp\json_decode(\GuzzleHttp\json_encode($this->encryption->decrypt($response->getBody())), true) : |
173: | \GuzzleHttp\json_decode($response->getBody(), true); |
174: | |
175: | return $body; |
176: | } catch (ConnectException $e) { |
177: | $errorResponse = new ErrorResponse(0, array('errors' => array( |
178: | array( |
179: | 'message' => 'Could not communicate with ' . $this->client->getConfig('base_uri'), |
180: | 'code' => 'COMMUNICATION_ERROR' |
181: | ) |
182: | ))); |
183: | throw new HyperwalletApiException($errorResponse, $e); |
184: | } catch (BadResponseException $e) { |
185: | $body = \GuzzleHttp\json_decode($e->getResponse()->getBody(), true); |
186: | if (is_null($body) || !isset($body['errors']) || empty($body['errors'])) { |
187: | $body = array('errors' => array( |
188: | array( |
189: | 'message' => 'Failed to get any error message from response', |
190: | 'code' => 'BAD_REQUEST' |
191: | ) |
192: | )); |
193: | } |
194: | $errorResponse = new ErrorResponse($e->getResponse()->getStatusCode(), $body); |
195: | throw new HyperwalletApiException($errorResponse, $e); |
196: | } |
197: | } |
198: | |
199: | |
200: | |
201: | |
202: | |
203: | |
204: | |
205: | |
206: | private function checkResponseHeaderContentType($response) { |
207: | $contentType = implode('', $response->getHeader('Content-Type')); |
208: | $expectedContentType = $this->isEncrypted ? 'application/jose+json' : 'application/json'; |
209: | $invalidContentType = $response->getStatusCode() !== 204 && !empty($contentType) && strpos($contentType, $expectedContentType) === false; |
210: | if ($invalidContentType) { |
211: | throw new HyperwalletException('Invalid Content-Type specified in Response Header'); |
212: | } |
213: | } |
214: | |
215: | |
216: | |
217: | |
218: | |
219: | |
220: | |
221: | |
222: | |
223: | |
224: | |
225: | public function putMultipartData($partialUrl, array $uriParams, array $options) { |
226: | return $this->doRequest('PUT', $partialUrl, $uriParams, $options); |
227: | } |
228: | } |
229: | |