This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace Inktale\Api; |
||
4 | |||
5 | use Inktale\Api\Exceptions\InktaleApiAuthException; |
||
6 | use Inktale\Api\Exceptions\InktaleApiException; |
||
7 | use Inktale\Api\Structures\ApiErrorItem; |
||
8 | |||
9 | class InktaleApiClient |
||
10 | { |
||
11 | const USER_AGENT = 'Inktale PHP wrapper (https://github.com/inktale/php-api-sdk)'; |
||
12 | |||
13 | /** |
||
14 | * @var string |
||
15 | */ |
||
16 | public $url = 'https://inktale.com/api/v1/'; |
||
17 | |||
18 | /** |
||
19 | * Last JSON encoded response |
||
20 | * |
||
21 | * @var string |
||
22 | */ |
||
23 | private $lastResponseRaw; |
||
24 | |||
25 | /** |
||
26 | * Last parsed response (json decoded) |
||
27 | * |
||
28 | * @var array |
||
29 | */ |
||
30 | private $lastResponse; |
||
31 | |||
32 | /** |
||
33 | * Authorization token |
||
34 | * |
||
35 | * @var string |
||
36 | */ |
||
37 | private $apiKey; |
||
38 | |||
39 | /** |
||
40 | * Your API key |
||
41 | * |
||
42 | * @param string|null $apiKey |
||
43 | */ |
||
44 | public function __construct($apiKey = null) |
||
45 | { |
||
46 | $this->setApiKey($apiKey); |
||
47 | } |
||
48 | |||
49 | /** |
||
50 | * Set authorization header key |
||
51 | * @param string $apiKey |
||
52 | */ |
||
53 | public function setApiKey($apiKey) |
||
54 | { |
||
55 | $this->apiKey = $apiKey; |
||
56 | } |
||
57 | |||
58 | /** |
||
59 | * Perform a GET request to the API |
||
60 | * |
||
61 | * @param string $path Request path |
||
62 | * @param array $params Additional GET parameters as an associative array |
||
63 | * @return mixed |
||
64 | */ |
||
65 | public function get($path, $params = []) |
||
66 | { |
||
67 | return $this->request('GET', $path, $params); |
||
68 | } |
||
69 | |||
70 | /** |
||
71 | * Perform a DELETE request to the API |
||
72 | * |
||
73 | * @param string $path Request path |
||
74 | * @param array $params Additional GET parameters as an associative array |
||
75 | * @return mixed |
||
76 | */ |
||
77 | public function delete($path, $params = []) |
||
78 | { |
||
79 | return $this->request('DELETE', $path, $params); |
||
80 | } |
||
81 | |||
82 | /** |
||
83 | * Perform a POST request to the API |
||
84 | * |
||
85 | * @param string $path Request path |
||
86 | * @param array $data Request body data as an associative array |
||
87 | * @param array $params Additional GET parameters as an associative array |
||
88 | * @return mixed |
||
89 | */ |
||
90 | public function post($path, $data = [], $params = []) |
||
91 | { |
||
92 | return $this->request('POST', $path, $params, $data); |
||
93 | } |
||
94 | |||
95 | /** |
||
96 | * Perform a PUT request to the API |
||
97 | * |
||
98 | * @param string $path Request path |
||
99 | * @param array $data Request body data as an associative array |
||
100 | * @param array $params Additional GET parameters as an associative array |
||
101 | * @return mixed |
||
102 | */ |
||
103 | public function put($path, $data = [], $params = []) |
||
104 | { |
||
105 | return $this->request('PUT', $path, $params, $data); |
||
106 | } |
||
107 | |||
108 | /** |
||
109 | * Return raw response data from the last request |
||
110 | * |
||
111 | * @return string|null Response data |
||
112 | */ |
||
113 | public function getLastResponseRaw() |
||
114 | { |
||
115 | return $this->lastResponseRaw; |
||
116 | } |
||
117 | |||
118 | /** |
||
119 | * Return decoded response data from the last request |
||
120 | * |
||
121 | * @return array|null Response data |
||
122 | */ |
||
123 | public function getLastResponse() |
||
124 | { |
||
125 | return $this->lastResponse; |
||
126 | } |
||
127 | |||
128 | /** |
||
129 | * Internal request implementation |
||
130 | * @param string $method POST, GET, etc. |
||
131 | * @param string $path API endpoint path |
||
132 | * @param array $query Query parameters |
||
133 | * @param array|mixed $data Post data |
||
134 | * @return mixed |
||
135 | * @throws InktaleApiException |
||
136 | */ |
||
137 | protected function request($method, $path, array $query = [], $data = null) |
||
138 | { |
||
139 | $curl = $this->initCurl($method, $path, $query); |
||
140 | |||
141 | $bodyLength = 0; |
||
142 | if ($data !== null) { |
||
143 | $bodyEncoded = json_encode($data); |
||
144 | $bodyLength = strlen($bodyEncoded); |
||
145 | curl_setopt($curl, CURLOPT_POSTFIELDS, $bodyEncoded); |
||
146 | } |
||
147 | |||
148 | $headers = $this->getCurlHeaders($bodyLength, 'application/json'); |
||
149 | |||
150 | curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); |
||
151 | |||
152 | return $this->execute($curl); |
||
153 | } |
||
154 | |||
155 | /** |
||
156 | * @param string $method |
||
157 | * @param string $path |
||
158 | * @param array $query Query parameters |
||
159 | * @return resource cURL handler |
||
160 | */ |
||
161 | protected function initCurl($method, $path, array $query) |
||
162 | { |
||
163 | $curl = curl_init($this->getUrl($path, $query)); |
||
164 | |||
165 | curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method); |
||
166 | curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); |
||
167 | curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); |
||
168 | curl_setopt($curl, CURLOPT_MAXREDIRS, 3); |
||
169 | |||
170 | curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 20); |
||
171 | curl_setopt($curl, CURLOPT_TIMEOUT, 10); |
||
172 | |||
173 | curl_setopt($curl, CURLOPT_USERAGENT, self::USER_AGENT); |
||
174 | |||
175 | return $curl; |
||
176 | } |
||
177 | |||
178 | /** |
||
179 | * @param string $path |
||
180 | * @param array $query |
||
181 | * @return string |
||
182 | */ |
||
183 | private function getUrl($path, array $query) |
||
184 | { |
||
185 | $url = $this->url . ltrim($path, '/'); |
||
186 | if ($query) { |
||
0 ignored issues
–
show
|
|||
187 | $url .= '?' . http_build_query($query); |
||
188 | } |
||
189 | return $url; |
||
190 | } |
||
191 | |||
192 | /** |
||
193 | * Execute cURL handler and return response |
||
194 | * @param resource $curl |
||
195 | * @return mixed |
||
196 | * @throws InktaleApiException |
||
197 | */ |
||
198 | private function execute($curl) |
||
199 | { |
||
200 | $this->lastResponseRaw = null; |
||
201 | $this->lastResponse = null; |
||
0 ignored issues
–
show
It seems like
null of type null is incompatible with the declared type array of property $lastResponse .
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. ![]() |
|||
202 | |||
203 | $responseRaw = curl_exec($curl); |
||
204 | |||
205 | $responseCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); |
||
206 | |||
207 | $errorNumber = curl_errno($curl); |
||
208 | $error = curl_error($curl); |
||
209 | curl_close($curl); |
||
210 | |||
211 | if ($errorNumber) { |
||
212 | throw new InktaleApiException('Inktale API CURL error: ' . $error, $errorNumber); |
||
213 | } |
||
214 | |||
215 | $response = json_decode($responseRaw, true); |
||
216 | |||
217 | if ($responseCode >= 400 || !empty($response['error'])) { |
||
218 | $errorItem = ApiErrorItem::fromArray($response['error']); |
||
219 | $exceptionMessage = $errorItem->title . ': ' . $errorItem->details; |
||
220 | |||
221 | if ($responseCode == 401) { |
||
222 | $exception = new InktaleApiAuthException($exceptionMessage, $errorItem->code); |
||
223 | } else { |
||
224 | $exception = new InktaleApiException($exceptionMessage, $errorItem->code); |
||
225 | } |
||
226 | |||
227 | $exception->setRawResponse($responseRaw) |
||
228 | ->setErrorDetails($errorItem->details) |
||
229 | ->setErrorTitle($errorItem->title); |
||
230 | |||
231 | throw $exception; |
||
232 | } |
||
233 | |||
234 | $this->lastResponse = $response; |
||
235 | $this->lastResponseRaw = $responseRaw; |
||
236 | |||
237 | return $response; |
||
238 | } |
||
239 | |||
240 | /** |
||
241 | * @param int $contentLength |
||
242 | * @param string $contentType |
||
243 | * @return string[] |
||
244 | */ |
||
245 | private function getCurlHeaders($contentLength, $contentType) |
||
246 | { |
||
247 | $headers = [ |
||
248 | 'Content-Type: ' . $contentType, |
||
249 | 'Content-Length: ' . $contentLength, |
||
250 | ]; |
||
251 | |||
252 | if ($this->apiKey) { |
||
253 | $headers[] = 'Authorization:' . $this->apiKey; |
||
254 | } |
||
255 | |||
256 | return $headers; |
||
257 | } |
||
258 | } |
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.