Browse code

removed Telnyx Plivo Twilio Flowroute appinfo/info.xml appinfo/signature.json README.md lib/Controller/AuthorApiController.php

DoubleBastionAdmin authored on 20/08/2022 16:26:33
Showing 1 changed files
1 1
deleted file mode 100644
... ...
@@ -1,464 +0,0 @@
1
-<?php
2
-
3
-namespace Telnyx;
4
-
5
-/**
6
- * Class ApiRequestor
7
- *
8
- * @package Telnyx
9
- */
10
-class ApiRequestor
11
-{
12
-    /**
13
-     * @var string|null
14
-     */
15
-    private $_apiKey;
16
-
17
-    /**
18
-     * @var string
19
-     */
20
-    private $_apiBase;
21
-
22
-    /**
23
-     * @var HttpClient\ClientInterface
24
-     */
25
-    private static $_httpClient;
26
-
27
-    /**
28
-     * @var RequestTelemetry
29
-     */
30
-    private static $requestTelemetry;
31
-
32
-    /**
33
-     * ApiRequestor constructor.
34
-     *
35
-     * @param string|null $apiKey
36
-     * @param string|null $apiBase
37
-     */
38
-    public function __construct($apiKey = null, $apiBase = null)
39
-    {
40
-        $this->_apiKey = $apiKey;
41
-        if (!$apiBase) {
42
-            $apiBase = Telnyx::$apiBase;
43
-        }
44
-        $this->_apiBase = $apiBase;
45
-    }
46
-
47
-    /**
48
-     * Creates a telemetry json blob for use in 'X-Telnyx-Client-Telemetry' headers
49
-     * @static
50
-     *
51
-     * @param RequestTelemetry $requestTelemetry
52
-     * @return string
53
-     */
54
-    private static function _telemetryJson($requestTelemetry)
55
-    {
56
-        $payload = array(
57
-            'last_request_metrics' => array(
58
-                'request_id' => $requestTelemetry->requestId,
59
-                'request_duration_ms' => $requestTelemetry->requestDuration,
60
-        ));
61
-
62
-        $result = json_encode($payload);
63
-        if ($result != false) {
64
-            return $result;
65
-        } else {
66
-            Telnyx::getLogger()->error("Serializing telemetry payload failed!");
67
-            return "{}";
68
-        }
69
-    }
70
-
71
-    /**
72
-     * @static
73
-     *
74
-     * @param ApiResource|bool|array|mixed $d
75
-     *
76
-     * @return ApiResource|array|string|mixed
77
-     */
78
-    private static function _encodeObjects($d)
79
-    {
80
-        if ($d instanceof ApiResource) {
81
-            return Util\Util::utf8($d->id);
82
-        } elseif ($d === true) {
83
-            return 'true';
84
-        } elseif ($d === false) {
85
-            return 'false';
86
-        } elseif (is_array($d)) {
87
-            $res = [];
88
-            foreach ($d as $k => $v) {
89
-                $res[$k] = self::_encodeObjects($v);
90
-            }
91
-            return $res;
92
-        } else {
93
-            return Util\Util::utf8($d);
94
-        }
95
-    }
96
-
97
-    /**
98
-     * @param string     $method
99
-     * @param string     $url
100
-     * @param array|null $params
101
-     * @param array|null $headers
102
-     *
103
-     * @return array An array whose first element is an API response and second
104
-     *    element is the API key used to make the request.
105
-     * @throws Error\Api
106
-     * @throws Error\Authentication
107
-     * @throws Error\Card
108
-     * @throws Error\InvalidRequest
109
-     * @throws Error\Permission
110
-     * @throws Error\RateLimit
111
-     * @throws Error\Idempotency
112
-     * @throws Error\ApiConnection
113
-     */
114
-    public function request($method, $url, $params = null, $headers = null)
115
-    {
116
-        $params = $params ?: [];
117
-        $headers = $headers ?: [];
118
-        list($rbody, $rcode, $rheaders, $myApiKey) =
119
-        $this->_requestRaw($method, $url, $params, $headers);
120
-        $json = $this->_interpretResponse($rbody, $rcode, $rheaders);
121
-        $resp = new ApiResponse($rbody, $rcode, $rheaders, $json);
122
-        return [$resp, $myApiKey];
123
-    }
124
-
125
-    /**
126
-     * @param string $rbody A JSON string.
127
-     * @param int $rcode
128
-     * @param array $rheaders
129
-     * @param array $resp
130
-     *
131
-     * @throws Error\InvalidRequest if the error is caused by the user.
132
-     * @throws Error\Authentication if the error is caused by a lack of
133
-     *    permissions.
134
-     * @throws Error\Permission if the error is caused by insufficient
135
-     *    permissions.
136
-     * @throws Error\Card if the error is the error code is 402 (payment
137
-     *    required)
138
-     * @throws Error\InvalidRequest if the error is caused by the user.
139
-     * @throws Error\Idempotency if the error is caused by an idempotency key.
140
-     * @throws Error\Permission if the error is caused by insufficient
141
-     *    permissions.
142
-     * @throws Error\RateLimit if the error is caused by too many requests
143
-     *    hitting the API.
144
-     * @throws Error\Api otherwise.
145
-     */
146
-    public function handleErrorResponse($rbody, $rcode, $rheaders, $resp)
147
-    {
148
-        if (!is_array($resp) || !isset($resp['error'])) {
149
-            $msg = "Invalid response object from API: $rbody "
150
-              . "(HTTP response code was $rcode)";
151
-            throw new Error\Api($msg, $rcode, $rbody, $resp, $rheaders);
152
-        }
153
-
154
-        $errorData = $resp['error'];
155
-
156
-        #echo $rbody;exit;
157
-
158
-        $error = null;
159
-        if (!$error) {
160
-            $error = self::_specificAPIError($rbody, $rcode, $rheaders, $resp, $errorData);
161
-        }
162
-
163
-        throw $error;
164
-    }
165
-
166
-    /**
167
-     * @static
168
-     *
169
-     * @param string $rbody
170
-     * @param int    $rcode
171
-     * @param array  $rheaders
172
-     * @param array  $resp
173
-     * @param array  $errorData
174
-     *
175
-     * @return Error\RateLimit|Error\Idempotency|Error\InvalidRequest|Error\Authentication|Error\Card|Error\Permission|Error\Api
176
-     */
177
-    private static function _specificAPIError($rbody, $rcode, $rheaders, $resp, $errorData)
178
-    {
179
-        $msg = isset($errorData['message']) ? $errorData['message'] : null;
180
-        $param = isset($errorData['param']) ? $errorData['param'] : null;
181
-        $code = isset($errorData['code']) ? $errorData['code'] : null;
182
-        $type = isset($errorData['type']) ? $errorData['type'] : null;
183
-
184
-        switch ($rcode) {
185
-            case 400:
186
-                // 'rate_limit' code is deprecated, but left here for backwards compatibility
187
-                // for API versions earlier than 2015-09-08
188
-                if ($code == 'rate_limit') {
189
-                    return new Error\RateLimit($msg, $param, $rcode, $rbody, $resp, $rheaders);
190
-                }
191
-                if ($type == 'idempotency_error') {
192
-                    return new Error\Idempotency($msg, $rcode, $rbody, $resp, $rheaders);
193
-                }
194
-
195
-                // intentional fall-through
196
-                // no break
197
-            case 404:
198
-                return new Error\InvalidRequest($msg, $param, $rcode, $rbody, $resp, $rheaders);
199
-            case 401:
200
-                return new Error\Authentication($msg, $rcode, $rbody, $resp, $rheaders);
201
-            case 402:
202
-                return new Error\Card($msg, $param, $code, $rcode, $rbody, $resp, $rheaders);
203
-            case 403:
204
-                return new Error\Permission($msg, $rcode, $rbody, $resp, $rheaders);
205
-            case 429:
206
-                return new Error\RateLimit($msg, $param, $rcode, $rbody, $resp, $rheaders);
207
-            default:
208
-                return new Error\Api($msg, $rcode, $rbody, $resp, $rheaders);
209
-        }
210
-    }
211
-
212
-    /**
213
-     * @static
214
-     *
215
-     * @param null|array $appInfo
216
-     *
217
-     * @return null|string
218
-     */
219
-    private static function _formatAppInfo($appInfo)
220
-    {
221
-        if ($appInfo !== null) {
222
-            $string = $appInfo['name'];
223
-            if ($appInfo['version'] !== null) {
224
-                $string .= '/' . $appInfo['version'];
225
-            }
226
-            if ($appInfo['url'] !== null) {
227
-                $string .= ' (' . $appInfo['url'] . ')';
228
-            }
229
-            return $string;
230
-        } else {
231
-            return null;
232
-        }
233
-    }
234
-
235
-    /**
236
-     * @static
237
-     *
238
-     * @param string $apiKey
239
-     * @param null   $clientInfo
240
-     *
241
-     * @return array
242
-     */
243
-    private static function _defaultHeaders($apiKey, $clientInfo = null)
244
-    {
245
-        $uaString = 'Telnyx/v2 PhpBindings/' . Telnyx::VERSION;
246
-
247
-        $langVersion = phpversion();
248
-        $uname = php_uname();
249
-
250
-        $appInfo = Telnyx::getAppInfo();
251
-        $ua = [
252
-            'bindings_version' => Telnyx::VERSION,
253
-            'lang' => 'php',
254
-            'lang_version' => $langVersion,
255
-            'publisher' => 'telnyx',
256
-            'uname' => $uname,
257
-        ];
258
-        if ($clientInfo) {
259
-            $ua = array_merge($clientInfo, $ua);
260
-        }
261
-        if ($appInfo !== null) {
262
-            $uaString .= ' ' . self::_formatAppInfo($appInfo);
263
-            $ua['application'] = $appInfo;
264
-        }
265
-
266
-        $defaultHeaders = [
267
-            'X-Telnyx-Client-User-Agent' => json_encode($ua),
268
-            'User-Agent' => $uaString,
269
-            'Authorization' => 'Bearer ' . $apiKey,
270
-        ];
271
-        return $defaultHeaders;
272
-    }
273
-
274
-    /**
275
-     * @param string $method
276
-     * @param string $url
277
-     * @param array  $params
278
-     * @param array  $headers
279
-     *
280
-     * @return array
281
-     * @throws Error\Api
282
-     * @throws Error\ApiConnection
283
-     * @throws Error\Authentication
284
-     */
285
-    private function _requestRaw($method, $url, $params, $headers)
286
-    {
287
-        $myApiKey = $this->_apiKey;
288
-        if (!$myApiKey) {
289
-            $myApiKey = Telnyx::$apiKey;
290
-        }
291
-
292
-        if (!$myApiKey) {
293
-            $msg = 'No API key provided.  (HINT: set your API key using '
294
-              . '"Telnyx::setApiKey(<API-KEY>)".  You can generate API keys from '
295
-              . 'the Telnyx web interface.  See https://developers.telnyx.com/docs/v2/development/authentication '
296
-              . 'for details, or email support@telnyx.com if you have any questions.';
297
-            throw new Error\Authentication($msg);
298
-        }
299
-
300
-        // Clients can supply arbitrary additional keys to be included in the
301
-        // X-Telnyx-Client-User-Agent header via the optional getUserAgentInfo()
302
-        // method
303
-        $clientUAInfo = null;
304
-        if (method_exists($this->httpClient(), 'getUserAgentInfo')) {
305
-            $clientUAInfo = $this->httpClient()->getUserAgentInfo();
306
-        }
307
-
308
-        $absUrl = $this->_apiBase.$url;
309
-        $params = self::_encodeObjects($params);
310
-        $defaultHeaders = $this->_defaultHeaders($myApiKey, $clientUAInfo);
311
-        if (Telnyx::$apiVersion) {
312
-            $defaultHeaders['Telnyx-Version'] = Telnyx::$apiVersion;
313
-        }
314
-
315
-        if (Telnyx::$accountId) {
316
-            $defaultHeaders['Telnyx-Account'] = Telnyx::$accountId;
317
-        }
318
-
319
-        if (Telnyx::$enableTelemetry && self::$requestTelemetry != null) {
320
-            $defaultHeaders["X-Telnyx-Client-Telemetry"] = self::_telemetryJson(self::$requestTelemetry);
321
-        }
322
-
323
-        $hasFile = false;
324
-        $hasCurlFile = class_exists('\CURLFile', false);
325
-        foreach ($params as $k => $v) {
326
-            if (is_resource($v)) {
327
-                $hasFile = true;
328
-                $params[$k] = self::_processResourceParam($v, $hasCurlFile);
329
-            } elseif ($hasCurlFile && $v instanceof \CURLFile) {
330
-                $hasFile = true;
331
-            }
332
-        }
333
-
334
-        if ($hasFile) {
335
-            $defaultHeaders['Content-Type'] = 'multipart/form-data';
336
-        } else {
337
-            $defaultHeaders['Content-Type'] = 'application/json';
338
-        }
339
-
340
-        $combinedHeaders = array_merge($defaultHeaders, $headers);
341
-        $rawHeaders = [];
342
-
343
-        foreach ($combinedHeaders as $header => $value) {
344
-            $rawHeaders[] = $header . ': ' . $value;
345
-        }
346
-
347
-        $requestStartMs = Util\Util::currentTimeMillis();
348
-
349
-        list($rbody, $rcode, $rheaders) = $this->httpClient()->request(
350
-            $method,
351
-            $absUrl,
352
-            $rawHeaders,
353
-            $params,
354
-            $hasFile
355
-        );
356
-
357
-//        if (array_key_exists('request-id', $rheaders)) {
358
-        if (property_exists($rheaders, 'request-id') && (null !== $rheaders->request-id)) {
359
-            self::$requestTelemetry = new RequestTelemetry(
360
-                $rheaders['request-id'],
361
-                Util\Util::currentTimeMillis() - $requestStartMs
362
-            );
363
-        }
364
-
365
-        return [$rbody, $rcode, $rheaders, $myApiKey];
366
-    }
367
-
368
-    /**
369
-     * @param resource $resource
370
-     * @param bool     $hasCurlFile
371
-     *
372
-     * @return \CURLFile|string
373
-     * @throws Error\Api
374
-     */
375
-    private function _processResourceParam($resource, $hasCurlFile)
376
-    {
377
-        if (get_resource_type($resource) !== 'stream') {
378
-            throw new Error\Api(
379
-                'Attempted to upload a resource that is not a stream'
380
-            );
381
-        }
382
-
383
-        $metaData = stream_get_meta_data($resource);
384
-        if ($metaData['wrapper_type'] !== 'plainfile') {
385
-            throw new Error\Api(
386
-                'Only plainfile resource streams are supported'
387
-            );
388
-        }
389
-
390
-        if ($hasCurlFile) {
391
-            // We don't have the filename or mimetype, but the API doesn't care
392
-            return new \CURLFile($metaData['uri']);
393
-        } else {
394
-            return '@'.$metaData['uri'];
395
-        }
396
-    }
397
-
398
-    /**
399
-     * @param string $rbody
400
-     * @param int    $rcode
401
-     * @param array  $rheaders
402
-     *
403
-     * @return mixed
404
-     * @throws Error\Api
405
-     * @throws Error\Authentication
406
-     * @throws Error\Card
407
-     * @throws Error\InvalidRequest
408
-     * @throws Error\Permission
409
-     * @throws Error\RateLimit
410
-     * @throws Error\Idempotency
411
-     */
412
-    private function _interpretResponse($rbody, $rcode, $rheaders)
413
-    {
414
-        $resp = json_decode($rbody, true);
415
-
416
-        // Move [data] to the parent node
417
-        if (isset($resp['data'])) {
418
-            $resp = $resp['data'];
419
-        }
420
-
421
-        $jsonError = json_last_error();
422
-        if ($resp === null && $jsonError !== JSON_ERROR_NONE) {
423
-            $msg = "Invalid response body from API: $rbody "
424
-              . "(HTTP response code was $rcode, json_last_error() was $jsonError)";
425
-            throw new Error\Api($msg, $rcode, $rbody);
426
-        }
427
-
428
-        if ($rcode < 200 || $rcode >= 300) {
429
-            $this->handleErrorResponse($rbody, $rcode, $rheaders, $resp);
430
-        }
431
-        return $resp;
432
-    }
433
-
434
-    /**
435
-     * @static
436
-     *
437
-     * @param HttpClient\ClientInterface $client
438
-     */
439
-    public static function setHttpClient($client)
440
-    {
441
-        self::$_httpClient = $client;
442
-    }
443
-
444
-    /**
445
-     * @static
446
-     *
447
-     * Resets any stateful telemetry data
448
-     */
449
-    public static function resetTelemetry()
450
-    {
451
-        self::$requestTelemetry = null;
452
-    }
453
-
454
-    /**
455
-     * @return HttpClient\ClientInterface
456
-     */
457
-    private function httpClient()
458
-    {
459
-        if (!self::$_httpClient) {
460
-            self::$_httpClient = HttpClient\CurlClient::instance();
461
-        }
462
-        return self::$_httpClient;
463
-    }
464
-}
Browse code

added appinfo/signature.json Telnyx Twilio Flowroute

DoubleBastionAdmin authored on 19/08/2022 13:10:24
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,464 @@
1
+<?php
2
+
3
+namespace Telnyx;
4
+
5
+/**
6
+ * Class ApiRequestor
7
+ *
8
+ * @package Telnyx
9
+ */
10
+class ApiRequestor
11
+{
12
+    /**
13
+     * @var string|null
14
+     */
15
+    private $_apiKey;
16
+
17
+    /**
18
+     * @var string
19
+     */
20
+    private $_apiBase;
21
+
22
+    /**
23
+     * @var HttpClient\ClientInterface
24
+     */
25
+    private static $_httpClient;
26
+
27
+    /**
28
+     * @var RequestTelemetry
29
+     */
30
+    private static $requestTelemetry;
31
+
32
+    /**
33
+     * ApiRequestor constructor.
34
+     *
35
+     * @param string|null $apiKey
36
+     * @param string|null $apiBase
37
+     */
38
+    public function __construct($apiKey = null, $apiBase = null)
39
+    {
40
+        $this->_apiKey = $apiKey;
41
+        if (!$apiBase) {
42
+            $apiBase = Telnyx::$apiBase;
43
+        }
44
+        $this->_apiBase = $apiBase;
45
+    }
46
+
47
+    /**
48
+     * Creates a telemetry json blob for use in 'X-Telnyx-Client-Telemetry' headers
49
+     * @static
50
+     *
51
+     * @param RequestTelemetry $requestTelemetry
52
+     * @return string
53
+     */
54
+    private static function _telemetryJson($requestTelemetry)
55
+    {
56
+        $payload = array(
57
+            'last_request_metrics' => array(
58
+                'request_id' => $requestTelemetry->requestId,
59
+                'request_duration_ms' => $requestTelemetry->requestDuration,
60
+        ));
61
+
62
+        $result = json_encode($payload);
63
+        if ($result != false) {
64
+            return $result;
65
+        } else {
66
+            Telnyx::getLogger()->error("Serializing telemetry payload failed!");
67
+            return "{}";
68
+        }
69
+    }
70
+
71
+    /**
72
+     * @static
73
+     *
74
+     * @param ApiResource|bool|array|mixed $d
75
+     *
76
+     * @return ApiResource|array|string|mixed
77
+     */
78
+    private static function _encodeObjects($d)
79
+    {
80
+        if ($d instanceof ApiResource) {
81
+            return Util\Util::utf8($d->id);
82
+        } elseif ($d === true) {
83
+            return 'true';
84
+        } elseif ($d === false) {
85
+            return 'false';
86
+        } elseif (is_array($d)) {
87
+            $res = [];
88
+            foreach ($d as $k => $v) {
89
+                $res[$k] = self::_encodeObjects($v);
90
+            }
91
+            return $res;
92
+        } else {
93
+            return Util\Util::utf8($d);
94
+        }
95
+    }
96
+
97
+    /**
98
+     * @param string     $method
99
+     * @param string     $url
100
+     * @param array|null $params
101
+     * @param array|null $headers
102
+     *
103
+     * @return array An array whose first element is an API response and second
104
+     *    element is the API key used to make the request.
105
+     * @throws Error\Api
106
+     * @throws Error\Authentication
107
+     * @throws Error\Card
108
+     * @throws Error\InvalidRequest
109
+     * @throws Error\Permission
110
+     * @throws Error\RateLimit
111
+     * @throws Error\Idempotency
112
+     * @throws Error\ApiConnection
113
+     */
114
+    public function request($method, $url, $params = null, $headers = null)
115
+    {
116
+        $params = $params ?: [];
117
+        $headers = $headers ?: [];
118
+        list($rbody, $rcode, $rheaders, $myApiKey) =
119
+        $this->_requestRaw($method, $url, $params, $headers);
120
+        $json = $this->_interpretResponse($rbody, $rcode, $rheaders);
121
+        $resp = new ApiResponse($rbody, $rcode, $rheaders, $json);
122
+        return [$resp, $myApiKey];
123
+    }
124
+
125
+    /**
126
+     * @param string $rbody A JSON string.
127
+     * @param int $rcode
128
+     * @param array $rheaders
129
+     * @param array $resp
130
+     *
131
+     * @throws Error\InvalidRequest if the error is caused by the user.
132
+     * @throws Error\Authentication if the error is caused by a lack of
133
+     *    permissions.
134
+     * @throws Error\Permission if the error is caused by insufficient
135
+     *    permissions.
136
+     * @throws Error\Card if the error is the error code is 402 (payment
137
+     *    required)
138
+     * @throws Error\InvalidRequest if the error is caused by the user.
139
+     * @throws Error\Idempotency if the error is caused by an idempotency key.
140
+     * @throws Error\Permission if the error is caused by insufficient
141
+     *    permissions.
142
+     * @throws Error\RateLimit if the error is caused by too many requests
143
+     *    hitting the API.
144
+     * @throws Error\Api otherwise.
145
+     */
146
+    public function handleErrorResponse($rbody, $rcode, $rheaders, $resp)
147
+    {
148
+        if (!is_array($resp) || !isset($resp['error'])) {
149
+            $msg = "Invalid response object from API: $rbody "
150
+              . "(HTTP response code was $rcode)";
151
+            throw new Error\Api($msg, $rcode, $rbody, $resp, $rheaders);
152
+        }
153
+
154
+        $errorData = $resp['error'];
155
+
156
+        #echo $rbody;exit;
157
+
158
+        $error = null;
159
+        if (!$error) {
160
+            $error = self::_specificAPIError($rbody, $rcode, $rheaders, $resp, $errorData);
161
+        }
162
+
163
+        throw $error;
164
+    }
165
+
166
+    /**
167
+     * @static
168
+     *
169
+     * @param string $rbody
170
+     * @param int    $rcode
171
+     * @param array  $rheaders
172
+     * @param array  $resp
173
+     * @param array  $errorData
174
+     *
175
+     * @return Error\RateLimit|Error\Idempotency|Error\InvalidRequest|Error\Authentication|Error\Card|Error\Permission|Error\Api
176
+     */
177
+    private static function _specificAPIError($rbody, $rcode, $rheaders, $resp, $errorData)
178
+    {
179
+        $msg = isset($errorData['message']) ? $errorData['message'] : null;
180
+        $param = isset($errorData['param']) ? $errorData['param'] : null;
181
+        $code = isset($errorData['code']) ? $errorData['code'] : null;
182
+        $type = isset($errorData['type']) ? $errorData['type'] : null;
183
+
184
+        switch ($rcode) {
185
+            case 400:
186
+                // 'rate_limit' code is deprecated, but left here for backwards compatibility
187
+                // for API versions earlier than 2015-09-08
188
+                if ($code == 'rate_limit') {
189
+                    return new Error\RateLimit($msg, $param, $rcode, $rbody, $resp, $rheaders);
190
+                }
191
+                if ($type == 'idempotency_error') {
192
+                    return new Error\Idempotency($msg, $rcode, $rbody, $resp, $rheaders);
193
+                }
194
+
195
+                // intentional fall-through
196
+                // no break
197
+            case 404:
198
+                return new Error\InvalidRequest($msg, $param, $rcode, $rbody, $resp, $rheaders);
199
+            case 401:
200
+                return new Error\Authentication($msg, $rcode, $rbody, $resp, $rheaders);
201
+            case 402:
202
+                return new Error\Card($msg, $param, $code, $rcode, $rbody, $resp, $rheaders);
203
+            case 403:
204
+                return new Error\Permission($msg, $rcode, $rbody, $resp, $rheaders);
205
+            case 429:
206
+                return new Error\RateLimit($msg, $param, $rcode, $rbody, $resp, $rheaders);
207
+            default:
208
+                return new Error\Api($msg, $rcode, $rbody, $resp, $rheaders);
209
+        }
210
+    }
211
+
212
+    /**
213
+     * @static
214
+     *
215
+     * @param null|array $appInfo
216
+     *
217
+     * @return null|string
218
+     */
219
+    private static function _formatAppInfo($appInfo)
220
+    {
221
+        if ($appInfo !== null) {
222
+            $string = $appInfo['name'];
223
+            if ($appInfo['version'] !== null) {
224
+                $string .= '/' . $appInfo['version'];
225
+            }
226
+            if ($appInfo['url'] !== null) {
227
+                $string .= ' (' . $appInfo['url'] . ')';
228
+            }
229
+            return $string;
230
+        } else {
231
+            return null;
232
+        }
233
+    }
234
+
235
+    /**
236
+     * @static
237
+     *
238
+     * @param string $apiKey
239
+     * @param null   $clientInfo
240
+     *
241
+     * @return array
242
+     */
243
+    private static function _defaultHeaders($apiKey, $clientInfo = null)
244
+    {
245
+        $uaString = 'Telnyx/v2 PhpBindings/' . Telnyx::VERSION;
246
+
247
+        $langVersion = phpversion();
248
+        $uname = php_uname();
249
+
250
+        $appInfo = Telnyx::getAppInfo();
251
+        $ua = [
252
+            'bindings_version' => Telnyx::VERSION,
253
+            'lang' => 'php',
254
+            'lang_version' => $langVersion,
255
+            'publisher' => 'telnyx',
256
+            'uname' => $uname,
257
+        ];
258
+        if ($clientInfo) {
259
+            $ua = array_merge($clientInfo, $ua);
260
+        }
261
+        if ($appInfo !== null) {
262
+            $uaString .= ' ' . self::_formatAppInfo($appInfo);
263
+            $ua['application'] = $appInfo;
264
+        }
265
+
266
+        $defaultHeaders = [
267
+            'X-Telnyx-Client-User-Agent' => json_encode($ua),
268
+            'User-Agent' => $uaString,
269
+            'Authorization' => 'Bearer ' . $apiKey,
270
+        ];
271
+        return $defaultHeaders;
272
+    }
273
+
274
+    /**
275
+     * @param string $method
276
+     * @param string $url
277
+     * @param array  $params
278
+     * @param array  $headers
279
+     *
280
+     * @return array
281
+     * @throws Error\Api
282
+     * @throws Error\ApiConnection
283
+     * @throws Error\Authentication
284
+     */
285
+    private function _requestRaw($method, $url, $params, $headers)
286
+    {
287
+        $myApiKey = $this->_apiKey;
288
+        if (!$myApiKey) {
289
+            $myApiKey = Telnyx::$apiKey;
290
+        }
291
+
292
+        if (!$myApiKey) {
293
+            $msg = 'No API key provided.  (HINT: set your API key using '
294
+              . '"Telnyx::setApiKey(<API-KEY>)".  You can generate API keys from '
295
+              . 'the Telnyx web interface.  See https://developers.telnyx.com/docs/v2/development/authentication '
296
+              . 'for details, or email support@telnyx.com if you have any questions.';
297
+            throw new Error\Authentication($msg);
298
+        }
299
+
300
+        // Clients can supply arbitrary additional keys to be included in the
301
+        // X-Telnyx-Client-User-Agent header via the optional getUserAgentInfo()
302
+        // method
303
+        $clientUAInfo = null;
304
+        if (method_exists($this->httpClient(), 'getUserAgentInfo')) {
305
+            $clientUAInfo = $this->httpClient()->getUserAgentInfo();
306
+        }
307
+
308
+        $absUrl = $this->_apiBase.$url;
309
+        $params = self::_encodeObjects($params);
310
+        $defaultHeaders = $this->_defaultHeaders($myApiKey, $clientUAInfo);
311
+        if (Telnyx::$apiVersion) {
312
+            $defaultHeaders['Telnyx-Version'] = Telnyx::$apiVersion;
313
+        }
314
+
315
+        if (Telnyx::$accountId) {
316
+            $defaultHeaders['Telnyx-Account'] = Telnyx::$accountId;
317
+        }
318
+
319
+        if (Telnyx::$enableTelemetry && self::$requestTelemetry != null) {
320
+            $defaultHeaders["X-Telnyx-Client-Telemetry"] = self::_telemetryJson(self::$requestTelemetry);
321
+        }
322
+
323
+        $hasFile = false;
324
+        $hasCurlFile = class_exists('\CURLFile', false);
325
+        foreach ($params as $k => $v) {
326
+            if (is_resource($v)) {
327
+                $hasFile = true;
328
+                $params[$k] = self::_processResourceParam($v, $hasCurlFile);
329
+            } elseif ($hasCurlFile && $v instanceof \CURLFile) {
330
+                $hasFile = true;
331
+            }
332
+        }
333
+
334
+        if ($hasFile) {
335
+            $defaultHeaders['Content-Type'] = 'multipart/form-data';
336
+        } else {
337
+            $defaultHeaders['Content-Type'] = 'application/json';
338
+        }
339
+
340
+        $combinedHeaders = array_merge($defaultHeaders, $headers);
341
+        $rawHeaders = [];
342
+
343
+        foreach ($combinedHeaders as $header => $value) {
344
+            $rawHeaders[] = $header . ': ' . $value;
345
+        }
346
+
347
+        $requestStartMs = Util\Util::currentTimeMillis();
348
+
349
+        list($rbody, $rcode, $rheaders) = $this->httpClient()->request(
350
+            $method,
351
+            $absUrl,
352
+            $rawHeaders,
353
+            $params,
354
+            $hasFile
355
+        );
356
+
357
+//        if (array_key_exists('request-id', $rheaders)) {
358
+        if (property_exists($rheaders, 'request-id') && (null !== $rheaders->request-id)) {
359
+            self::$requestTelemetry = new RequestTelemetry(
360
+                $rheaders['request-id'],
361
+                Util\Util::currentTimeMillis() - $requestStartMs
362
+            );
363
+        }
364
+
365
+        return [$rbody, $rcode, $rheaders, $myApiKey];
366
+    }
367
+
368
+    /**
369
+     * @param resource $resource
370
+     * @param bool     $hasCurlFile
371
+     *
372
+     * @return \CURLFile|string
373
+     * @throws Error\Api
374
+     */
375
+    private function _processResourceParam($resource, $hasCurlFile)
376
+    {
377
+        if (get_resource_type($resource) !== 'stream') {
378
+            throw new Error\Api(
379
+                'Attempted to upload a resource that is not a stream'
380
+            );
381
+        }
382
+
383
+        $metaData = stream_get_meta_data($resource);
384
+        if ($metaData['wrapper_type'] !== 'plainfile') {
385
+            throw new Error\Api(
386
+                'Only plainfile resource streams are supported'
387
+            );
388
+        }
389
+
390
+        if ($hasCurlFile) {
391
+            // We don't have the filename or mimetype, but the API doesn't care
392
+            return new \CURLFile($metaData['uri']);
393
+        } else {
394
+            return '@'.$metaData['uri'];
395
+        }
396
+    }
397
+
398
+    /**
399
+     * @param string $rbody
400
+     * @param int    $rcode
401
+     * @param array  $rheaders
402
+     *
403
+     * @return mixed
404
+     * @throws Error\Api
405
+     * @throws Error\Authentication
406
+     * @throws Error\Card
407
+     * @throws Error\InvalidRequest
408
+     * @throws Error\Permission
409
+     * @throws Error\RateLimit
410
+     * @throws Error\Idempotency
411
+     */
412
+    private function _interpretResponse($rbody, $rcode, $rheaders)
413
+    {
414
+        $resp = json_decode($rbody, true);
415
+
416
+        // Move [data] to the parent node
417
+        if (isset($resp['data'])) {
418
+            $resp = $resp['data'];
419
+        }
420
+
421
+        $jsonError = json_last_error();
422
+        if ($resp === null && $jsonError !== JSON_ERROR_NONE) {
423
+            $msg = "Invalid response body from API: $rbody "
424
+              . "(HTTP response code was $rcode, json_last_error() was $jsonError)";
425
+            throw new Error\Api($msg, $rcode, $rbody);
426
+        }
427
+
428
+        if ($rcode < 200 || $rcode >= 300) {
429
+            $this->handleErrorResponse($rbody, $rcode, $rheaders, $resp);
430
+        }
431
+        return $resp;
432
+    }
433
+
434
+    /**
435
+     * @static
436
+     *
437
+     * @param HttpClient\ClientInterface $client
438
+     */
439
+    public static function setHttpClient($client)
440
+    {
441
+        self::$_httpClient = $client;
442
+    }
443
+
444
+    /**
445
+     * @static
446
+     *
447
+     * Resets any stateful telemetry data
448
+     */
449
+    public static function resetTelemetry()
450
+    {
451
+        self::$requestTelemetry = null;
452
+    }
453
+
454
+    /**
455
+     * @return HttpClient\ClientInterface
456
+     */
457
+    private function httpClient()
458
+    {
459
+        if (!self::$_httpClient) {
460
+            self::$_httpClient = HttpClient\CurlClient::instance();
461
+        }
462
+        return self::$_httpClient;
463
+    }
464
+}
Browse code

removed appinfo/signature.json and Telnyx

DoubleBastionAdmin authored on 19/08/2022 12:45:59
Showing 1 changed files
1 1
deleted file mode 100644
... ...
@@ -1,464 +0,0 @@
1
-<?php
2
-
3
-namespace Telnyx;
4
-
5
-/**
6
- * Class ApiRequestor
7
- *
8
- * @package Telnyx
9
- */
10
-class ApiRequestor
11
-{
12
-    /**
13
-     * @var string|null
14
-     */
15
-    private $_apiKey;
16
-
17
-    /**
18
-     * @var string
19
-     */
20
-    private $_apiBase;
21
-
22
-    /**
23
-     * @var HttpClient\ClientInterface
24
-     */
25
-    private static $_httpClient;
26
-
27
-    /**
28
-     * @var RequestTelemetry
29
-     */
30
-    private static $requestTelemetry;
31
-
32
-    /**
33
-     * ApiRequestor constructor.
34
-     *
35
-     * @param string|null $apiKey
36
-     * @param string|null $apiBase
37
-     */
38
-    public function __construct($apiKey = null, $apiBase = null)
39
-    {
40
-        $this->_apiKey = $apiKey;
41
-        if (!$apiBase) {
42
-            $apiBase = Telnyx::$apiBase;
43
-        }
44
-        $this->_apiBase = $apiBase;
45
-    }
46
-
47
-    /**
48
-     * Creates a telemetry json blob for use in 'X-Telnyx-Client-Telemetry' headers
49
-     * @static
50
-     *
51
-     * @param RequestTelemetry $requestTelemetry
52
-     * @return string
53
-     */
54
-    private static function _telemetryJson($requestTelemetry)
55
-    {
56
-        $payload = array(
57
-            'last_request_metrics' => array(
58
-                'request_id' => $requestTelemetry->requestId,
59
-                'request_duration_ms' => $requestTelemetry->requestDuration,
60
-        ));
61
-
62
-        $result = json_encode($payload);
63
-        if ($result != false) {
64
-            return $result;
65
-        } else {
66
-            Telnyx::getLogger()->error("Serializing telemetry payload failed!");
67
-            return "{}";
68
-        }
69
-    }
70
-
71
-    /**
72
-     * @static
73
-     *
74
-     * @param ApiResource|bool|array|mixed $d
75
-     *
76
-     * @return ApiResource|array|string|mixed
77
-     */
78
-    private static function _encodeObjects($d)
79
-    {
80
-        if ($d instanceof ApiResource) {
81
-            return Util\Util::utf8($d->id);
82
-        } elseif ($d === true) {
83
-            return 'true';
84
-        } elseif ($d === false) {
85
-            return 'false';
86
-        } elseif (is_array($d)) {
87
-            $res = [];
88
-            foreach ($d as $k => $v) {
89
-                $res[$k] = self::_encodeObjects($v);
90
-            }
91
-            return $res;
92
-        } else {
93
-            return Util\Util::utf8($d);
94
-        }
95
-    }
96
-
97
-    /**
98
-     * @param string     $method
99
-     * @param string     $url
100
-     * @param array|null $params
101
-     * @param array|null $headers
102
-     *
103
-     * @return array An array whose first element is an API response and second
104
-     *    element is the API key used to make the request.
105
-     * @throws Error\Api
106
-     * @throws Error\Authentication
107
-     * @throws Error\Card
108
-     * @throws Error\InvalidRequest
109
-     * @throws Error\Permission
110
-     * @throws Error\RateLimit
111
-     * @throws Error\Idempotency
112
-     * @throws Error\ApiConnection
113
-     */
114
-    public function request($method, $url, $params = null, $headers = null)
115
-    {
116
-        $params = $params ?: [];
117
-        $headers = $headers ?: [];
118
-        list($rbody, $rcode, $rheaders, $myApiKey) =
119
-        $this->_requestRaw($method, $url, $params, $headers);
120
-        $json = $this->_interpretResponse($rbody, $rcode, $rheaders);
121
-        $resp = new ApiResponse($rbody, $rcode, $rheaders, $json);
122
-        return [$resp, $myApiKey];
123
-    }
124
-
125
-    /**
126
-     * @param string $rbody A JSON string.
127
-     * @param int $rcode
128
-     * @param array $rheaders
129
-     * @param array $resp
130
-     *
131
-     * @throws Error\InvalidRequest if the error is caused by the user.
132
-     * @throws Error\Authentication if the error is caused by a lack of
133
-     *    permissions.
134
-     * @throws Error\Permission if the error is caused by insufficient
135
-     *    permissions.
136
-     * @throws Error\Card if the error is the error code is 402 (payment
137
-     *    required)
138
-     * @throws Error\InvalidRequest if the error is caused by the user.
139
-     * @throws Error\Idempotency if the error is caused by an idempotency key.
140
-     * @throws Error\Permission if the error is caused by insufficient
141
-     *    permissions.
142
-     * @throws Error\RateLimit if the error is caused by too many requests
143
-     *    hitting the API.
144
-     * @throws Error\Api otherwise.
145
-     */
146
-    public function handleErrorResponse($rbody, $rcode, $rheaders, $resp)
147
-    {
148
-        if (!is_array($resp) || !isset($resp['error'])) {
149
-            $msg = "Invalid response object from API: $rbody "
150
-              . "(HTTP response code was $rcode)";
151
-            throw new Error\Api($msg, $rcode, $rbody, $resp, $rheaders);
152
-        }
153
-
154
-        $errorData = $resp['error'];
155
-
156
-        #echo $rbody;exit;
157
-
158
-        $error = null;
159
-        if (!$error) {
160
-            $error = self::_specificAPIError($rbody, $rcode, $rheaders, $resp, $errorData);
161
-        }
162
-
163
-        throw $error;
164
-    }
165
-
166
-    /**
167
-     * @static
168
-     *
169
-     * @param string $rbody
170
-     * @param int    $rcode
171
-     * @param array  $rheaders
172
-     * @param array  $resp
173
-     * @param array  $errorData
174
-     *
175
-     * @return Error\RateLimit|Error\Idempotency|Error\InvalidRequest|Error\Authentication|Error\Card|Error\Permission|Error\Api
176
-     */
177
-    private static function _specificAPIError($rbody, $rcode, $rheaders, $resp, $errorData)
178
-    {
179
-        $msg = isset($errorData['message']) ? $errorData['message'] : null;
180
-        $param = isset($errorData['param']) ? $errorData['param'] : null;
181
-        $code = isset($errorData['code']) ? $errorData['code'] : null;
182
-        $type = isset($errorData['type']) ? $errorData['type'] : null;
183
-
184
-        switch ($rcode) {
185
-            case 400:
186
-                // 'rate_limit' code is deprecated, but left here for backwards compatibility
187
-                // for API versions earlier than 2015-09-08
188
-                if ($code == 'rate_limit') {
189
-                    return new Error\RateLimit($msg, $param, $rcode, $rbody, $resp, $rheaders);
190
-                }
191
-                if ($type == 'idempotency_error') {
192
-                    return new Error\Idempotency($msg, $rcode, $rbody, $resp, $rheaders);
193
-                }
194
-
195
-                // intentional fall-through
196
-                // no break
197
-            case 404:
198
-                return new Error\InvalidRequest($msg, $param, $rcode, $rbody, $resp, $rheaders);
199
-            case 401:
200
-                return new Error\Authentication($msg, $rcode, $rbody, $resp, $rheaders);
201
-            case 402:
202
-                return new Error\Card($msg, $param, $code, $rcode, $rbody, $resp, $rheaders);
203
-            case 403:
204
-                return new Error\Permission($msg, $rcode, $rbody, $resp, $rheaders);
205
-            case 429:
206
-                return new Error\RateLimit($msg, $param, $rcode, $rbody, $resp, $rheaders);
207
-            default:
208
-                return new Error\Api($msg, $rcode, $rbody, $resp, $rheaders);
209
-        }
210
-    }
211
-
212
-    /**
213
-     * @static
214
-     *
215
-     * @param null|array $appInfo
216
-     *
217
-     * @return null|string
218
-     */
219
-    private static function _formatAppInfo($appInfo)
220
-    {
221
-        if ($appInfo !== null) {
222
-            $string = $appInfo['name'];
223
-            if ($appInfo['version'] !== null) {
224
-                $string .= '/' . $appInfo['version'];
225
-            }
226
-            if ($appInfo['url'] !== null) {
227
-                $string .= ' (' . $appInfo['url'] . ')';
228
-            }
229
-            return $string;
230
-        } else {
231
-            return null;
232
-        }
233
-    }
234
-
235
-    /**
236
-     * @static
237
-     *
238
-     * @param string $apiKey
239
-     * @param null   $clientInfo
240
-     *
241
-     * @return array
242
-     */
243
-    private static function _defaultHeaders($apiKey, $clientInfo = null)
244
-    {
245
-        $uaString = 'Telnyx/v2 PhpBindings/' . Telnyx::VERSION;
246
-
247
-        $langVersion = phpversion();
248
-        $uname = php_uname();
249
-
250
-        $appInfo = Telnyx::getAppInfo();
251
-        $ua = [
252
-            'bindings_version' => Telnyx::VERSION,
253
-            'lang' => 'php',
254
-            'lang_version' => $langVersion,
255
-            'publisher' => 'telnyx',
256
-            'uname' => $uname,
257
-        ];
258
-        if ($clientInfo) {
259
-            $ua = array_merge($clientInfo, $ua);
260
-        }
261
-        if ($appInfo !== null) {
262
-            $uaString .= ' ' . self::_formatAppInfo($appInfo);
263
-            $ua['application'] = $appInfo;
264
-        }
265
-
266
-        $defaultHeaders = [
267
-            'X-Telnyx-Client-User-Agent' => json_encode($ua),
268
-            'User-Agent' => $uaString,
269
-            'Authorization' => 'Bearer ' . $apiKey,
270
-        ];
271
-        return $defaultHeaders;
272
-    }
273
-
274
-    /**
275
-     * @param string $method
276
-     * @param string $url
277
-     * @param array  $params
278
-     * @param array  $headers
279
-     *
280
-     * @return array
281
-     * @throws Error\Api
282
-     * @throws Error\ApiConnection
283
-     * @throws Error\Authentication
284
-     */
285
-    private function _requestRaw($method, $url, $params, $headers)
286
-    {
287
-        $myApiKey = $this->_apiKey;
288
-        if (!$myApiKey) {
289
-            $myApiKey = Telnyx::$apiKey;
290
-        }
291
-
292
-        if (!$myApiKey) {
293
-            $msg = 'No API key provided.  (HINT: set your API key using '
294
-              . '"Telnyx::setApiKey(<API-KEY>)".  You can generate API keys from '
295
-              . 'the Telnyx web interface.  See https://developers.telnyx.com/docs/v2/development/authentication '
296
-              . 'for details, or email support@telnyx.com if you have any questions.';
297
-            throw new Error\Authentication($msg);
298
-        }
299
-
300
-        // Clients can supply arbitrary additional keys to be included in the
301
-        // X-Telnyx-Client-User-Agent header via the optional getUserAgentInfo()
302
-        // method
303
-        $clientUAInfo = null;
304
-        if (method_exists($this->httpClient(), 'getUserAgentInfo')) {
305
-            $clientUAInfo = $this->httpClient()->getUserAgentInfo();
306
-        }
307
-
308
-        $absUrl = $this->_apiBase.$url;
309
-        $params = self::_encodeObjects($params);
310
-        $defaultHeaders = $this->_defaultHeaders($myApiKey, $clientUAInfo);
311
-        if (Telnyx::$apiVersion) {
312
-            $defaultHeaders['Telnyx-Version'] = Telnyx::$apiVersion;
313
-        }
314
-
315
-        if (Telnyx::$accountId) {
316
-            $defaultHeaders['Telnyx-Account'] = Telnyx::$accountId;
317
-        }
318
-
319
-        if (Telnyx::$enableTelemetry && self::$requestTelemetry != null) {
320
-            $defaultHeaders["X-Telnyx-Client-Telemetry"] = self::_telemetryJson(self::$requestTelemetry);
321
-        }
322
-
323
-        $hasFile = false;
324
-        $hasCurlFile = class_exists('\CURLFile', false);
325
-        foreach ($params as $k => $v) {
326
-            if (is_resource($v)) {
327
-                $hasFile = true;
328
-                $params[$k] = self::_processResourceParam($v, $hasCurlFile);
329
-            } elseif ($hasCurlFile && $v instanceof \CURLFile) {
330
-                $hasFile = true;
331
-            }
332
-        }
333
-
334
-        if ($hasFile) {
335
-            $defaultHeaders['Content-Type'] = 'multipart/form-data';
336
-        } else {
337
-            $defaultHeaders['Content-Type'] = 'application/json';
338
-        }
339
-
340
-        $combinedHeaders = array_merge($defaultHeaders, $headers);
341
-        $rawHeaders = [];
342
-
343
-        foreach ($combinedHeaders as $header => $value) {
344
-            $rawHeaders[] = $header . ': ' . $value;
345
-        }
346
-
347
-        $requestStartMs = Util\Util::currentTimeMillis();
348
-
349
-        list($rbody, $rcode, $rheaders) = $this->httpClient()->request(
350
-            $method,
351
-            $absUrl,
352
-            $rawHeaders,
353
-            $params,
354
-            $hasFile
355
-        );
356
-
357
-//        if (array_key_exists('request-id', $rheaders)) {
358
-        if (property_exists($rheaders, 'request-id') && (null !== $rheaders->request-id)) {
359
-            self::$requestTelemetry = new RequestTelemetry(
360
-                $rheaders['request-id'],
361
-                Util\Util::currentTimeMillis() - $requestStartMs
362
-            );
363
-        }
364
-
365
-        return [$rbody, $rcode, $rheaders, $myApiKey];
366
-    }
367
-
368
-    /**
369
-     * @param resource $resource
370
-     * @param bool     $hasCurlFile
371
-     *
372
-     * @return \CURLFile|string
373
-     * @throws Error\Api
374
-     */
375
-    private function _processResourceParam($resource, $hasCurlFile)
376
-    {
377
-        if (get_resource_type($resource) !== 'stream') {
378
-            throw new Error\Api(
379
-                'Attempted to upload a resource that is not a stream'
380
-            );
381
-        }
382
-
383
-        $metaData = stream_get_meta_data($resource);
384
-        if ($metaData['wrapper_type'] !== 'plainfile') {
385
-            throw new Error\Api(
386
-                'Only plainfile resource streams are supported'
387
-            );
388
-        }
389
-
390
-        if ($hasCurlFile) {
391
-            // We don't have the filename or mimetype, but the API doesn't care
392
-            return new \CURLFile($metaData['uri']);
393
-        } else {
394
-            return '@'.$metaData['uri'];
395
-        }
396
-    }
397
-
398
-    /**
399
-     * @param string $rbody
400
-     * @param int    $rcode
401
-     * @param array  $rheaders
402
-     *
403
-     * @return mixed
404
-     * @throws Error\Api
405
-     * @throws Error\Authentication
406
-     * @throws Error\Card
407
-     * @throws Error\InvalidRequest
408
-     * @throws Error\Permission
409
-     * @throws Error\RateLimit
410
-     * @throws Error\Idempotency
411
-     */
412
-    private function _interpretResponse($rbody, $rcode, $rheaders)
413
-    {
414
-        $resp = json_decode($rbody, true);
415
-
416
-        // Move [data] to the parent node
417
-        if (isset($resp['data'])) {
418
-            $resp = $resp['data'];
419
-        }
420
-
421
-        $jsonError = json_last_error();
422
-        if ($resp === null && $jsonError !== JSON_ERROR_NONE) {
423
-            $msg = "Invalid response body from API: $rbody "
424
-              . "(HTTP response code was $rcode, json_last_error() was $jsonError)";
425
-            throw new Error\Api($msg, $rcode, $rbody);
426
-        }
427
-
428
-        if ($rcode < 200 || $rcode >= 300) {
429
-            $this->handleErrorResponse($rbody, $rcode, $rheaders, $resp);
430
-        }
431
-        return $resp;
432
-    }
433
-
434
-    /**
435
-     * @static
436
-     *
437
-     * @param HttpClient\ClientInterface $client
438
-     */
439
-    public static function setHttpClient($client)
440
-    {
441
-        self::$_httpClient = $client;
442
-    }
443
-
444
-    /**
445
-     * @static
446
-     *
447
-     * Resets any stateful telemetry data
448
-     */
449
-    public static function resetTelemetry()
450
-    {
451
-        self::$requestTelemetry = null;
452
-    }
453
-
454
-    /**
455
-     * @return HttpClient\ClientInterface
456
-     */
457
-    private function httpClient()
458
-    {
459
-        if (!self::$_httpClient) {
460
-            self::$_httpClient = HttpClient\CurlClient::instance();
461
-        }
462
-        return self::$_httpClient;
463
-    }
464
-}
Browse code

added appinfo/signature.json and Telnyx directory

DoubleBastionAdmin authored on 19/08/2022 11:38:54
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,464 @@
1
+<?php
2
+
3
+namespace Telnyx;
4
+
5
+/**
6
+ * Class ApiRequestor
7
+ *
8
+ * @package Telnyx
9
+ */
10
+class ApiRequestor
11
+{
12
+    /**
13
+     * @var string|null
14
+     */
15
+    private $_apiKey;
16
+
17
+    /**
18
+     * @var string
19
+     */
20
+    private $_apiBase;
21
+
22
+    /**
23
+     * @var HttpClient\ClientInterface
24
+     */
25
+    private static $_httpClient;
26
+
27
+    /**
28
+     * @var RequestTelemetry
29
+     */
30
+    private static $requestTelemetry;
31
+
32
+    /**
33
+     * ApiRequestor constructor.
34
+     *
35
+     * @param string|null $apiKey
36
+     * @param string|null $apiBase
37
+     */
38
+    public function __construct($apiKey = null, $apiBase = null)
39
+    {
40
+        $this->_apiKey = $apiKey;
41
+        if (!$apiBase) {
42
+            $apiBase = Telnyx::$apiBase;
43
+        }
44
+        $this->_apiBase = $apiBase;
45
+    }
46
+
47
+    /**
48
+     * Creates a telemetry json blob for use in 'X-Telnyx-Client-Telemetry' headers
49
+     * @static
50
+     *
51
+     * @param RequestTelemetry $requestTelemetry
52
+     * @return string
53
+     */
54
+    private static function _telemetryJson($requestTelemetry)
55
+    {
56
+        $payload = array(
57
+            'last_request_metrics' => array(
58
+                'request_id' => $requestTelemetry->requestId,
59
+                'request_duration_ms' => $requestTelemetry->requestDuration,
60
+        ));
61
+
62
+        $result = json_encode($payload);
63
+        if ($result != false) {
64
+            return $result;
65
+        } else {
66
+            Telnyx::getLogger()->error("Serializing telemetry payload failed!");
67
+            return "{}";
68
+        }
69
+    }
70
+
71
+    /**
72
+     * @static
73
+     *
74
+     * @param ApiResource|bool|array|mixed $d
75
+     *
76
+     * @return ApiResource|array|string|mixed
77
+     */
78
+    private static function _encodeObjects($d)
79
+    {
80
+        if ($d instanceof ApiResource) {
81
+            return Util\Util::utf8($d->id);
82
+        } elseif ($d === true) {
83
+            return 'true';
84
+        } elseif ($d === false) {
85
+            return 'false';
86
+        } elseif (is_array($d)) {
87
+            $res = [];
88
+            foreach ($d as $k => $v) {
89
+                $res[$k] = self::_encodeObjects($v);
90
+            }
91
+            return $res;
92
+        } else {
93
+            return Util\Util::utf8($d);
94
+        }
95
+    }
96
+
97
+    /**
98
+     * @param string     $method
99
+     * @param string     $url
100
+     * @param array|null $params
101
+     * @param array|null $headers
102
+     *
103
+     * @return array An array whose first element is an API response and second
104
+     *    element is the API key used to make the request.
105
+     * @throws Error\Api
106
+     * @throws Error\Authentication
107
+     * @throws Error\Card
108
+     * @throws Error\InvalidRequest
109
+     * @throws Error\Permission
110
+     * @throws Error\RateLimit
111
+     * @throws Error\Idempotency
112
+     * @throws Error\ApiConnection
113
+     */
114
+    public function request($method, $url, $params = null, $headers = null)
115
+    {
116
+        $params = $params ?: [];
117
+        $headers = $headers ?: [];
118
+        list($rbody, $rcode, $rheaders, $myApiKey) =
119
+        $this->_requestRaw($method, $url, $params, $headers);
120
+        $json = $this->_interpretResponse($rbody, $rcode, $rheaders);
121
+        $resp = new ApiResponse($rbody, $rcode, $rheaders, $json);
122
+        return [$resp, $myApiKey];
123
+    }
124
+
125
+    /**
126
+     * @param string $rbody A JSON string.
127
+     * @param int $rcode
128
+     * @param array $rheaders
129
+     * @param array $resp
130
+     *
131
+     * @throws Error\InvalidRequest if the error is caused by the user.
132
+     * @throws Error\Authentication if the error is caused by a lack of
133
+     *    permissions.
134
+     * @throws Error\Permission if the error is caused by insufficient
135
+     *    permissions.
136
+     * @throws Error\Card if the error is the error code is 402 (payment
137
+     *    required)
138
+     * @throws Error\InvalidRequest if the error is caused by the user.
139
+     * @throws Error\Idempotency if the error is caused by an idempotency key.
140
+     * @throws Error\Permission if the error is caused by insufficient
141
+     *    permissions.
142
+     * @throws Error\RateLimit if the error is caused by too many requests
143
+     *    hitting the API.
144
+     * @throws Error\Api otherwise.
145
+     */
146
+    public function handleErrorResponse($rbody, $rcode, $rheaders, $resp)
147
+    {
148
+        if (!is_array($resp) || !isset($resp['error'])) {
149
+            $msg = "Invalid response object from API: $rbody "
150
+              . "(HTTP response code was $rcode)";
151
+            throw new Error\Api($msg, $rcode, $rbody, $resp, $rheaders);
152
+        }
153
+
154
+        $errorData = $resp['error'];
155
+
156
+        #echo $rbody;exit;
157
+
158
+        $error = null;
159
+        if (!$error) {
160
+            $error = self::_specificAPIError($rbody, $rcode, $rheaders, $resp, $errorData);
161
+        }
162
+
163
+        throw $error;
164
+    }
165
+
166
+    /**
167
+     * @static
168
+     *
169
+     * @param string $rbody
170
+     * @param int    $rcode
171
+     * @param array  $rheaders
172
+     * @param array  $resp
173
+     * @param array  $errorData
174
+     *
175
+     * @return Error\RateLimit|Error\Idempotency|Error\InvalidRequest|Error\Authentication|Error\Card|Error\Permission|Error\Api
176
+     */
177
+    private static function _specificAPIError($rbody, $rcode, $rheaders, $resp, $errorData)
178
+    {
179
+        $msg = isset($errorData['message']) ? $errorData['message'] : null;
180
+        $param = isset($errorData['param']) ? $errorData['param'] : null;
181
+        $code = isset($errorData['code']) ? $errorData['code'] : null;
182
+        $type = isset($errorData['type']) ? $errorData['type'] : null;
183
+
184
+        switch ($rcode) {
185
+            case 400:
186
+                // 'rate_limit' code is deprecated, but left here for backwards compatibility
187
+                // for API versions earlier than 2015-09-08
188
+                if ($code == 'rate_limit') {
189
+                    return new Error\RateLimit($msg, $param, $rcode, $rbody, $resp, $rheaders);
190
+                }
191
+                if ($type == 'idempotency_error') {
192
+                    return new Error\Idempotency($msg, $rcode, $rbody, $resp, $rheaders);
193
+                }
194
+
195
+                // intentional fall-through
196
+                // no break
197
+            case 404:
198
+                return new Error\InvalidRequest($msg, $param, $rcode, $rbody, $resp, $rheaders);
199
+            case 401:
200
+                return new Error\Authentication($msg, $rcode, $rbody, $resp, $rheaders);
201
+            case 402:
202
+                return new Error\Card($msg, $param, $code, $rcode, $rbody, $resp, $rheaders);
203
+            case 403:
204
+                return new Error\Permission($msg, $rcode, $rbody, $resp, $rheaders);
205
+            case 429:
206
+                return new Error\RateLimit($msg, $param, $rcode, $rbody, $resp, $rheaders);
207
+            default:
208
+                return new Error\Api($msg, $rcode, $rbody, $resp, $rheaders);
209
+        }
210
+    }
211
+
212
+    /**
213
+     * @static
214
+     *
215
+     * @param null|array $appInfo
216
+     *
217
+     * @return null|string
218
+     */
219
+    private static function _formatAppInfo($appInfo)
220
+    {
221
+        if ($appInfo !== null) {
222
+            $string = $appInfo['name'];
223
+            if ($appInfo['version'] !== null) {
224
+                $string .= '/' . $appInfo['version'];
225
+            }
226
+            if ($appInfo['url'] !== null) {
227
+                $string .= ' (' . $appInfo['url'] . ')';
228
+            }
229
+            return $string;
230
+        } else {
231
+            return null;
232
+        }
233
+    }
234
+
235
+    /**
236
+     * @static
237
+     *
238
+     * @param string $apiKey
239
+     * @param null   $clientInfo
240
+     *
241
+     * @return array
242
+     */
243
+    private static function _defaultHeaders($apiKey, $clientInfo = null)
244
+    {
245
+        $uaString = 'Telnyx/v2 PhpBindings/' . Telnyx::VERSION;
246
+
247
+        $langVersion = phpversion();
248
+        $uname = php_uname();
249
+
250
+        $appInfo = Telnyx::getAppInfo();
251
+        $ua = [
252
+            'bindings_version' => Telnyx::VERSION,
253
+            'lang' => 'php',
254
+            'lang_version' => $langVersion,
255
+            'publisher' => 'telnyx',
256
+            'uname' => $uname,
257
+        ];
258
+        if ($clientInfo) {
259
+            $ua = array_merge($clientInfo, $ua);
260
+        }
261
+        if ($appInfo !== null) {
262
+            $uaString .= ' ' . self::_formatAppInfo($appInfo);
263
+            $ua['application'] = $appInfo;
264
+        }
265
+
266
+        $defaultHeaders = [
267
+            'X-Telnyx-Client-User-Agent' => json_encode($ua),
268
+            'User-Agent' => $uaString,
269
+            'Authorization' => 'Bearer ' . $apiKey,
270
+        ];
271
+        return $defaultHeaders;
272
+    }
273
+
274
+    /**
275
+     * @param string $method
276
+     * @param string $url
277
+     * @param array  $params
278
+     * @param array  $headers
279
+     *
280
+     * @return array
281
+     * @throws Error\Api
282
+     * @throws Error\ApiConnection
283
+     * @throws Error\Authentication
284
+     */
285
+    private function _requestRaw($method, $url, $params, $headers)
286
+    {
287
+        $myApiKey = $this->_apiKey;
288
+        if (!$myApiKey) {
289
+            $myApiKey = Telnyx::$apiKey;
290
+        }
291
+
292
+        if (!$myApiKey) {
293
+            $msg = 'No API key provided.  (HINT: set your API key using '
294
+              . '"Telnyx::setApiKey(<API-KEY>)".  You can generate API keys from '
295
+              . 'the Telnyx web interface.  See https://developers.telnyx.com/docs/v2/development/authentication '
296
+              . 'for details, or email support@telnyx.com if you have any questions.';
297
+            throw new Error\Authentication($msg);
298
+        }
299
+
300
+        // Clients can supply arbitrary additional keys to be included in the
301
+        // X-Telnyx-Client-User-Agent header via the optional getUserAgentInfo()
302
+        // method
303
+        $clientUAInfo = null;
304
+        if (method_exists($this->httpClient(), 'getUserAgentInfo')) {
305
+            $clientUAInfo = $this->httpClient()->getUserAgentInfo();
306
+        }
307
+
308
+        $absUrl = $this->_apiBase.$url;
309
+        $params = self::_encodeObjects($params);
310
+        $defaultHeaders = $this->_defaultHeaders($myApiKey, $clientUAInfo);
311
+        if (Telnyx::$apiVersion) {
312
+            $defaultHeaders['Telnyx-Version'] = Telnyx::$apiVersion;
313
+        }
314
+
315
+        if (Telnyx::$accountId) {
316
+            $defaultHeaders['Telnyx-Account'] = Telnyx::$accountId;
317
+        }
318
+
319
+        if (Telnyx::$enableTelemetry && self::$requestTelemetry != null) {
320
+            $defaultHeaders["X-Telnyx-Client-Telemetry"] = self::_telemetryJson(self::$requestTelemetry);
321
+        }
322
+
323
+        $hasFile = false;
324
+        $hasCurlFile = class_exists('\CURLFile', false);
325
+        foreach ($params as $k => $v) {
326
+            if (is_resource($v)) {
327
+                $hasFile = true;
328
+                $params[$k] = self::_processResourceParam($v, $hasCurlFile);
329
+            } elseif ($hasCurlFile && $v instanceof \CURLFile) {
330
+                $hasFile = true;
331
+            }
332
+        }
333
+
334
+        if ($hasFile) {
335
+            $defaultHeaders['Content-Type'] = 'multipart/form-data';
336
+        } else {
337
+            $defaultHeaders['Content-Type'] = 'application/json';
338
+        }
339
+
340
+        $combinedHeaders = array_merge($defaultHeaders, $headers);
341
+        $rawHeaders = [];
342
+
343
+        foreach ($combinedHeaders as $header => $value) {
344
+            $rawHeaders[] = $header . ': ' . $value;
345
+        }
346
+
347
+        $requestStartMs = Util\Util::currentTimeMillis();
348
+
349
+        list($rbody, $rcode, $rheaders) = $this->httpClient()->request(
350
+            $method,
351
+            $absUrl,
352
+            $rawHeaders,
353
+            $params,
354
+            $hasFile
355
+        );
356
+
357
+//        if (array_key_exists('request-id', $rheaders)) {
358
+        if (property_exists($rheaders, 'request-id') && (null !== $rheaders->request-id)) {
359
+            self::$requestTelemetry = new RequestTelemetry(
360
+                $rheaders['request-id'],
361
+                Util\Util::currentTimeMillis() - $requestStartMs
362
+            );
363
+        }
364
+
365
+        return [$rbody, $rcode, $rheaders, $myApiKey];
366
+    }
367
+
368
+    /**
369
+     * @param resource $resource
370
+     * @param bool     $hasCurlFile
371
+     *
372
+     * @return \CURLFile|string
373
+     * @throws Error\Api
374
+     */
375
+    private function _processResourceParam($resource, $hasCurlFile)
376
+    {
377
+        if (get_resource_type($resource) !== 'stream') {
378
+            throw new Error\Api(
379
+                'Attempted to upload a resource that is not a stream'
380
+            );
381
+        }
382
+
383
+        $metaData = stream_get_meta_data($resource);
384
+        if ($metaData['wrapper_type'] !== 'plainfile') {
385
+            throw new Error\Api(
386
+                'Only plainfile resource streams are supported'
387
+            );
388
+        }
389
+
390
+        if ($hasCurlFile) {
391
+            // We don't have the filename or mimetype, but the API doesn't care
392
+            return new \CURLFile($metaData['uri']);
393
+        } else {
394
+            return '@'.$metaData['uri'];
395
+        }
396
+    }
397
+
398
+    /**
399
+     * @param string $rbody
400
+     * @param int    $rcode
401
+     * @param array  $rheaders
402
+     *
403
+     * @return mixed
404
+     * @throws Error\Api
405
+     * @throws Error\Authentication
406
+     * @throws Error\Card
407
+     * @throws Error\InvalidRequest
408
+     * @throws Error\Permission
409
+     * @throws Error\RateLimit
410
+     * @throws Error\Idempotency
411
+     */
412
+    private function _interpretResponse($rbody, $rcode, $rheaders)
413
+    {
414
+        $resp = json_decode($rbody, true);
415
+
416
+        // Move [data] to the parent node
417
+        if (isset($resp['data'])) {
418
+            $resp = $resp['data'];
419
+        }
420
+
421
+        $jsonError = json_last_error();
422
+        if ($resp === null && $jsonError !== JSON_ERROR_NONE) {
423
+            $msg = "Invalid response body from API: $rbody "
424
+              . "(HTTP response code was $rcode, json_last_error() was $jsonError)";
425
+            throw new Error\Api($msg, $rcode, $rbody);
426
+        }
427
+
428
+        if ($rcode < 200 || $rcode >= 300) {
429
+            $this->handleErrorResponse($rbody, $rcode, $rheaders, $resp);
430
+        }
431
+        return $resp;
432
+    }
433
+
434
+    /**
435
+     * @static
436
+     *
437
+     * @param HttpClient\ClientInterface $client
438
+     */
439
+    public static function setHttpClient($client)
440
+    {
441
+        self::$_httpClient = $client;
442
+    }
443
+
444
+    /**
445
+     * @static
446
+     *
447
+     * Resets any stateful telemetry data
448
+     */
449
+    public static function resetTelemetry()
450
+    {
451
+        self::$requestTelemetry = null;
452
+    }
453
+
454
+    /**
455
+     * @return HttpClient\ClientInterface
456
+     */
457
+    private function httpClient()
458
+    {
459
+        if (!self::$_httpClient) {
460
+            self::$_httpClient = HttpClient\CurlClient::instance();
461
+        }
462
+        return self::$_httpClient;
463
+    }
464
+}
Browse code

removed Telnyx directory

DoubleBastionAdmin authored on 19/08/2022 11:12:03
Showing 1 changed files
1 1
deleted file mode 100644
... ...
@@ -1,464 +0,0 @@
1
-<?php
2
-
3
-namespace Telnyx;
4
-
5
-/**
6
- * Class ApiRequestor
7
- *
8
- * @package Telnyx
9
- */
10
-class ApiRequestor
11
-{
12
-    /**
13
-     * @var string|null
14
-     */
15
-    private $_apiKey;
16
-
17
-    /**
18
-     * @var string
19
-     */
20
-    private $_apiBase;
21
-
22
-    /**
23
-     * @var HttpClient\ClientInterface
24
-     */
25
-    private static $_httpClient;
26
-
27
-    /**
28
-     * @var RequestTelemetry
29
-     */
30
-    private static $requestTelemetry;
31
-
32
-    /**
33
-     * ApiRequestor constructor.
34
-     *
35
-     * @param string|null $apiKey
36
-     * @param string|null $apiBase
37
-     */
38
-    public function __construct($apiKey = null, $apiBase = null)
39
-    {
40
-        $this->_apiKey = $apiKey;
41
-        if (!$apiBase) {
42
-            $apiBase = Telnyx::$apiBase;
43
-        }
44
-        $this->_apiBase = $apiBase;
45
-    }
46
-
47
-    /**
48
-     * Creates a telemetry json blob for use in 'X-Telnyx-Client-Telemetry' headers
49
-     * @static
50
-     *
51
-     * @param RequestTelemetry $requestTelemetry
52
-     * @return string
53
-     */
54
-    private static function _telemetryJson($requestTelemetry)
55
-    {
56
-        $payload = array(
57
-            'last_request_metrics' => array(
58
-                'request_id' => $requestTelemetry->requestId,
59
-                'request_duration_ms' => $requestTelemetry->requestDuration,
60
-        ));
61
-
62
-        $result = json_encode($payload);
63
-        if ($result != false) {
64
-            return $result;
65
-        } else {
66
-            Telnyx::getLogger()->error("Serializing telemetry payload failed!");
67
-            return "{}";
68
-        }
69
-    }
70
-
71
-    /**
72
-     * @static
73
-     *
74
-     * @param ApiResource|bool|array|mixed $d
75
-     *
76
-     * @return ApiResource|array|string|mixed
77
-     */
78
-    private static function _encodeObjects($d)
79
-    {
80
-        if ($d instanceof ApiResource) {
81
-            return Util\Util::utf8($d->id);
82
-        } elseif ($d === true) {
83
-            return 'true';
84
-        } elseif ($d === false) {
85
-            return 'false';
86
-        } elseif (is_array($d)) {
87
-            $res = [];
88
-            foreach ($d as $k => $v) {
89
-                $res[$k] = self::_encodeObjects($v);
90
-            }
91
-            return $res;
92
-        } else {
93
-            return Util\Util::utf8($d);
94
-        }
95
-    }
96
-
97
-    /**
98
-     * @param string     $method
99
-     * @param string     $url
100
-     * @param array|null $params
101
-     * @param array|null $headers
102
-     *
103
-     * @return array An array whose first element is an API response and second
104
-     *    element is the API key used to make the request.
105
-     * @throws Error\Api
106
-     * @throws Error\Authentication
107
-     * @throws Error\Card
108
-     * @throws Error\InvalidRequest
109
-     * @throws Error\Permission
110
-     * @throws Error\RateLimit
111
-     * @throws Error\Idempotency
112
-     * @throws Error\ApiConnection
113
-     */
114
-    public function request($method, $url, $params = null, $headers = null)
115
-    {
116
-        $params = $params ?: [];
117
-        $headers = $headers ?: [];
118
-        list($rbody, $rcode, $rheaders, $myApiKey) =
119
-        $this->_requestRaw($method, $url, $params, $headers);
120
-        $json = $this->_interpretResponse($rbody, $rcode, $rheaders);
121
-        $resp = new ApiResponse($rbody, $rcode, $rheaders, $json);
122
-        return [$resp, $myApiKey];
123
-    }
124
-
125
-    /**
126
-     * @param string $rbody A JSON string.
127
-     * @param int $rcode
128
-     * @param array $rheaders
129
-     * @param array $resp
130
-     *
131
-     * @throws Error\InvalidRequest if the error is caused by the user.
132
-     * @throws Error\Authentication if the error is caused by a lack of
133
-     *    permissions.
134
-     * @throws Error\Permission if the error is caused by insufficient
135
-     *    permissions.
136
-     * @throws Error\Card if the error is the error code is 402 (payment
137
-     *    required)
138
-     * @throws Error\InvalidRequest if the error is caused by the user.
139
-     * @throws Error\Idempotency if the error is caused by an idempotency key.
140
-     * @throws Error\Permission if the error is caused by insufficient
141
-     *    permissions.
142
-     * @throws Error\RateLimit if the error is caused by too many requests
143
-     *    hitting the API.
144
-     * @throws Error\Api otherwise.
145
-     */
146
-    public function handleErrorResponse($rbody, $rcode, $rheaders, $resp)
147
-    {
148
-        if (!is_array($resp) || !isset($resp['error'])) {
149
-            $msg = "Invalid response object from API: $rbody "
150
-              . "(HTTP response code was $rcode)";
151
-            throw new Error\Api($msg, $rcode, $rbody, $resp, $rheaders);
152
-        }
153
-
154
-        $errorData = $resp['error'];
155
-
156
-        #echo $rbody;exit;
157
-
158
-        $error = null;
159
-        if (!$error) {
160
-            $error = self::_specificAPIError($rbody, $rcode, $rheaders, $resp, $errorData);
161
-        }
162
-
163
-        throw $error;
164
-    }
165
-
166
-    /**
167
-     * @static
168
-     *
169
-     * @param string $rbody
170
-     * @param int    $rcode
171
-     * @param array  $rheaders
172
-     * @param array  $resp
173
-     * @param array  $errorData
174
-     *
175
-     * @return Error\RateLimit|Error\Idempotency|Error\InvalidRequest|Error\Authentication|Error\Card|Error\Permission|Error\Api
176
-     */
177
-    private static function _specificAPIError($rbody, $rcode, $rheaders, $resp, $errorData)
178
-    {
179
-        $msg = isset($errorData['message']) ? $errorData['message'] : null;
180
-        $param = isset($errorData['param']) ? $errorData['param'] : null;
181
-        $code = isset($errorData['code']) ? $errorData['code'] : null;
182
-        $type = isset($errorData['type']) ? $errorData['type'] : null;
183
-
184
-        switch ($rcode) {
185
-            case 400:
186
-                // 'rate_limit' code is deprecated, but left here for backwards compatibility
187
-                // for API versions earlier than 2015-09-08
188
-                if ($code == 'rate_limit') {
189
-                    return new Error\RateLimit($msg, $param, $rcode, $rbody, $resp, $rheaders);
190
-                }
191
-                if ($type == 'idempotency_error') {
192
-                    return new Error\Idempotency($msg, $rcode, $rbody, $resp, $rheaders);
193
-                }
194
-
195
-                // intentional fall-through
196
-                // no break
197
-            case 404:
198
-                return new Error\InvalidRequest($msg, $param, $rcode, $rbody, $resp, $rheaders);
199
-            case 401:
200
-                return new Error\Authentication($msg, $rcode, $rbody, $resp, $rheaders);
201
-            case 402:
202
-                return new Error\Card($msg, $param, $code, $rcode, $rbody, $resp, $rheaders);
203
-            case 403:
204
-                return new Error\Permission($msg, $rcode, $rbody, $resp, $rheaders);
205
-            case 429:
206
-                return new Error\RateLimit($msg, $param, $rcode, $rbody, $resp, $rheaders);
207
-            default:
208
-                return new Error\Api($msg, $rcode, $rbody, $resp, $rheaders);
209
-        }
210
-    }
211
-
212
-    /**
213
-     * @static
214
-     *
215
-     * @param null|array $appInfo
216
-     *
217
-     * @return null|string
218
-     */
219
-    private static function _formatAppInfo($appInfo)
220
-    {
221
-        if ($appInfo !== null) {
222
-            $string = $appInfo['name'];
223
-            if ($appInfo['version'] !== null) {
224
-                $string .= '/' . $appInfo['version'];
225
-            }
226
-            if ($appInfo['url'] !== null) {
227
-                $string .= ' (' . $appInfo['url'] . ')';
228
-            }
229
-            return $string;
230
-        } else {
231
-            return null;
232
-        }
233
-    }
234
-
235
-    /**
236
-     * @static
237
-     *
238
-     * @param string $apiKey
239
-     * @param null   $clientInfo
240
-     *
241
-     * @return array
242
-     */
243
-    private static function _defaultHeaders($apiKey, $clientInfo = null)
244
-    {
245
-        $uaString = 'Telnyx/v2 PhpBindings/' . Telnyx::VERSION;
246
-
247
-        $langVersion = phpversion();
248
-        $uname = php_uname();
249
-
250
-        $appInfo = Telnyx::getAppInfo();
251
-        $ua = [
252
-            'bindings_version' => Telnyx::VERSION,
253
-            'lang' => 'php',
254
-            'lang_version' => $langVersion,
255
-            'publisher' => 'telnyx',
256
-            'uname' => $uname,
257
-        ];
258
-        if ($clientInfo) {
259
-            $ua = array_merge($clientInfo, $ua);
260
-        }
261
-        if ($appInfo !== null) {
262
-            $uaString .= ' ' . self::_formatAppInfo($appInfo);
263
-            $ua['application'] = $appInfo;
264
-        }
265
-
266
-        $defaultHeaders = [
267
-            'X-Telnyx-Client-User-Agent' => json_encode($ua),
268
-            'User-Agent' => $uaString,
269
-            'Authorization' => 'Bearer ' . $apiKey,
270
-        ];
271
-        return $defaultHeaders;
272
-    }
273
-
274
-    /**
275
-     * @param string $method
276
-     * @param string $url
277
-     * @param array  $params
278
-     * @param array  $headers
279
-     *
280
-     * @return array
281
-     * @throws Error\Api
282
-     * @throws Error\ApiConnection
283
-     * @throws Error\Authentication
284
-     */
285
-    private function _requestRaw($method, $url, $params, $headers)
286
-    {
287
-        $myApiKey = $this->_apiKey;
288
-        if (!$myApiKey) {
289
-            $myApiKey = Telnyx::$apiKey;
290
-        }
291
-
292
-        if (!$myApiKey) {
293
-            $msg = 'No API key provided.  (HINT: set your API key using '
294
-              . '"Telnyx::setApiKey(<API-KEY>)".  You can generate API keys from '
295
-              . 'the Telnyx web interface.  See https://developers.telnyx.com/docs/v2/development/authentication '
296
-              . 'for details, or email support@telnyx.com if you have any questions.';
297
-            throw new Error\Authentication($msg);
298
-        }
299
-
300
-        // Clients can supply arbitrary additional keys to be included in the
301
-        // X-Telnyx-Client-User-Agent header via the optional getUserAgentInfo()
302
-        // method
303
-        $clientUAInfo = null;
304
-        if (method_exists($this->httpClient(), 'getUserAgentInfo')) {
305
-            $clientUAInfo = $this->httpClient()->getUserAgentInfo();
306
-        }
307
-
308
-        $absUrl = $this->_apiBase.$url;
309
-        $params = self::_encodeObjects($params);
310
-        $defaultHeaders = $this->_defaultHeaders($myApiKey, $clientUAInfo);
311
-        if (Telnyx::$apiVersion) {
312
-            $defaultHeaders['Telnyx-Version'] = Telnyx::$apiVersion;
313
-        }
314
-
315
-        if (Telnyx::$accountId) {
316
-            $defaultHeaders['Telnyx-Account'] = Telnyx::$accountId;
317
-        }
318
-
319
-        if (Telnyx::$enableTelemetry && self::$requestTelemetry != null) {
320
-            $defaultHeaders["X-Telnyx-Client-Telemetry"] = self::_telemetryJson(self::$requestTelemetry);
321
-        }
322
-
323
-        $hasFile = false;
324
-        $hasCurlFile = class_exists('\CURLFile', false);
325
-        foreach ($params as $k => $v) {
326
-            if (is_resource($v)) {
327
-                $hasFile = true;
328
-                $params[$k] = self::_processResourceParam($v, $hasCurlFile);
329
-            } elseif ($hasCurlFile && $v instanceof \CURLFile) {
330
-                $hasFile = true;
331
-            }
332
-        }
333
-
334
-        if ($hasFile) {
335
-            $defaultHeaders['Content-Type'] = 'multipart/form-data';
336
-        } else {
337
-            $defaultHeaders['Content-Type'] = 'application/json';
338
-        }
339
-
340
-        $combinedHeaders = array_merge($defaultHeaders, $headers);
341
-        $rawHeaders = [];
342
-
343
-        foreach ($combinedHeaders as $header => $value) {
344
-            $rawHeaders[] = $header . ': ' . $value;
345
-        }
346
-
347
-        $requestStartMs = Util\Util::currentTimeMillis();
348
-
349
-        list($rbody, $rcode, $rheaders) = $this->httpClient()->request(
350
-            $method,
351
-            $absUrl,
352
-            $rawHeaders,
353
-            $params,
354
-            $hasFile
355
-        );
356
-
357
-//        if (array_key_exists('request-id', $rheaders)) {
358
-        if (property_exists($rheaders, 'request-id') && (null !== $rheaders->request-id)) {
359
-            self::$requestTelemetry = new RequestTelemetry(
360
-                $rheaders['request-id'],
361
-                Util\Util::currentTimeMillis() - $requestStartMs
362
-            );
363
-        }
364
-
365
-        return [$rbody, $rcode, $rheaders, $myApiKey];
366
-    }
367
-
368
-    /**
369
-     * @param resource $resource
370
-     * @param bool     $hasCurlFile
371
-     *
372
-     * @return \CURLFile|string
373
-     * @throws Error\Api
374
-     */
375
-    private function _processResourceParam($resource, $hasCurlFile)
376
-    {
377
-        if (get_resource_type($resource) !== 'stream') {
378
-            throw new Error\Api(
379
-                'Attempted to upload a resource that is not a stream'
380
-            );
381
-        }
382
-
383
-        $metaData = stream_get_meta_data($resource);
384
-        if ($metaData['wrapper_type'] !== 'plainfile') {
385
-            throw new Error\Api(
386
-                'Only plainfile resource streams are supported'
387
-            );
388
-        }
389
-
390
-        if ($hasCurlFile) {
391
-            // We don't have the filename or mimetype, but the API doesn't care
392
-            return new \CURLFile($metaData['uri']);
393
-        } else {
394
-            return '@'.$metaData['uri'];
395
-        }
396
-    }
397
-
398
-    /**
399
-     * @param string $rbody
400
-     * @param int    $rcode
401
-     * @param array  $rheaders
402
-     *
403
-     * @return mixed
404
-     * @throws Error\Api
405
-     * @throws Error\Authentication
406
-     * @throws Error\Card
407
-     * @throws Error\InvalidRequest
408
-     * @throws Error\Permission
409
-     * @throws Error\RateLimit
410
-     * @throws Error\Idempotency
411
-     */
412
-    private function _interpretResponse($rbody, $rcode, $rheaders)
413
-    {
414
-        $resp = json_decode($rbody, true);
415
-
416
-        // Move [data] to the parent node
417
-        if (isset($resp['data'])) {
418
-            $resp = $resp['data'];
419
-        }
420
-
421
-        $jsonError = json_last_error();
422
-        if ($resp === null && $jsonError !== JSON_ERROR_NONE) {
423
-            $msg = "Invalid response body from API: $rbody "
424
-              . "(HTTP response code was $rcode, json_last_error() was $jsonError)";
425
-            throw new Error\Api($msg, $rcode, $rbody);
426
-        }
427
-
428
-        if ($rcode < 200 || $rcode >= 300) {
429
-            $this->handleErrorResponse($rbody, $rcode, $rheaders, $resp);
430
-        }
431
-        return $resp;
432
-    }
433
-
434
-    /**
435
-     * @static
436
-     *
437
-     * @param HttpClient\ClientInterface $client
438
-     */
439
-    public static function setHttpClient($client)
440
-    {
441
-        self::$_httpClient = $client;
442
-    }
443
-
444
-    /**
445
-     * @static
446
-     *
447
-     * Resets any stateful telemetry data
448
-     */
449
-    public static function resetTelemetry()
450
-    {
451
-        self::$requestTelemetry = null;
452
-    }
453
-
454
-    /**
455
-     * @return HttpClient\ClientInterface
456
-     */
457
-    private function httpClient()
458
-    {
459
-        if (!self::$_httpClient) {
460
-            self::$_httpClient = HttpClient\CurlClient::instance();
461
-        }
462
-        return self::$_httpClient;
463
-    }
464
-}
Browse code

added CHANGELOG.txt Contributors.txt README.md Telnyx/lib/ApiRequestor.php appinfo/info.xml appinfo/signature.json lib/Migration/Version104Date20220507234521.php

DoubleBastionAdmin authored on 07/05/2022 23:50:17
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,464 @@
1
+<?php
2
+
3
+namespace Telnyx;
4
+
5
+/**
6
+ * Class ApiRequestor
7
+ *
8
+ * @package Telnyx
9
+ */
10
+class ApiRequestor
11
+{
12
+    /**
13
+     * @var string|null
14
+     */
15
+    private $_apiKey;
16
+
17
+    /**
18
+     * @var string
19
+     */
20
+    private $_apiBase;
21
+
22
+    /**
23
+     * @var HttpClient\ClientInterface
24
+     */
25
+    private static $_httpClient;
26
+
27
+    /**
28
+     * @var RequestTelemetry
29
+     */
30
+    private static $requestTelemetry;
31
+
32
+    /**
33
+     * ApiRequestor constructor.
34
+     *
35
+     * @param string|null $apiKey
36
+     * @param string|null $apiBase
37
+     */
38
+    public function __construct($apiKey = null, $apiBase = null)
39
+    {
40
+        $this->_apiKey = $apiKey;
41
+        if (!$apiBase) {
42
+            $apiBase = Telnyx::$apiBase;
43
+        }
44
+        $this->_apiBase = $apiBase;
45
+    }
46
+
47
+    /**
48
+     * Creates a telemetry json blob for use in 'X-Telnyx-Client-Telemetry' headers
49
+     * @static
50
+     *
51
+     * @param RequestTelemetry $requestTelemetry
52
+     * @return string
53
+     */
54
+    private static function _telemetryJson($requestTelemetry)
55
+    {
56
+        $payload = array(
57
+            'last_request_metrics' => array(
58
+                'request_id' => $requestTelemetry->requestId,
59
+                'request_duration_ms' => $requestTelemetry->requestDuration,
60
+        ));
61
+
62
+        $result = json_encode($payload);
63
+        if ($result != false) {
64
+            return $result;
65
+        } else {
66
+            Telnyx::getLogger()->error("Serializing telemetry payload failed!");
67
+            return "{}";
68
+        }
69
+    }
70
+
71
+    /**
72
+     * @static
73
+     *
74
+     * @param ApiResource|bool|array|mixed $d
75
+     *
76
+     * @return ApiResource|array|string|mixed
77
+     */
78
+    private static function _encodeObjects($d)
79
+    {
80
+        if ($d instanceof ApiResource) {
81
+            return Util\Util::utf8($d->id);
82
+        } elseif ($d === true) {
83
+            return 'true';
84
+        } elseif ($d === false) {
85
+            return 'false';
86
+        } elseif (is_array($d)) {
87
+            $res = [];
88
+            foreach ($d as $k => $v) {
89
+                $res[$k] = self::_encodeObjects($v);
90
+            }
91
+            return $res;
92
+        } else {
93
+            return Util\Util::utf8($d);
94
+        }
95
+    }
96
+
97
+    /**
98
+     * @param string     $method
99
+     * @param string     $url
100
+     * @param array|null $params
101
+     * @param array|null $headers
102
+     *
103
+     * @return array An array whose first element is an API response and second
104
+     *    element is the API key used to make the request.
105
+     * @throws Error\Api
106
+     * @throws Error\Authentication
107
+     * @throws Error\Card
108
+     * @throws Error\InvalidRequest
109
+     * @throws Error\Permission
110
+     * @throws Error\RateLimit
111
+     * @throws Error\Idempotency
112
+     * @throws Error\ApiConnection
113
+     */
114
+    public function request($method, $url, $params = null, $headers = null)
115
+    {
116
+        $params = $params ?: [];
117
+        $headers = $headers ?: [];
118
+        list($rbody, $rcode, $rheaders, $myApiKey) =
119
+        $this->_requestRaw($method, $url, $params, $headers);
120
+        $json = $this->_interpretResponse($rbody, $rcode, $rheaders);
121
+        $resp = new ApiResponse($rbody, $rcode, $rheaders, $json);
122
+        return [$resp, $myApiKey];
123
+    }
124
+
125
+    /**
126
+     * @param string $rbody A JSON string.
127
+     * @param int $rcode
128
+     * @param array $rheaders
129
+     * @param array $resp
130
+     *
131
+     * @throws Error\InvalidRequest if the error is caused by the user.
132
+     * @throws Error\Authentication if the error is caused by a lack of
133
+     *    permissions.
134
+     * @throws Error\Permission if the error is caused by insufficient
135
+     *    permissions.
136
+     * @throws Error\Card if the error is the error code is 402 (payment
137
+     *    required)
138
+     * @throws Error\InvalidRequest if the error is caused by the user.
139
+     * @throws Error\Idempotency if the error is caused by an idempotency key.
140
+     * @throws Error\Permission if the error is caused by insufficient
141
+     *    permissions.
142
+     * @throws Error\RateLimit if the error is caused by too many requests
143
+     *    hitting the API.
144
+     * @throws Error\Api otherwise.
145
+     */
146
+    public function handleErrorResponse($rbody, $rcode, $rheaders, $resp)
147
+    {
148
+        if (!is_array($resp) || !isset($resp['error'])) {
149
+            $msg = "Invalid response object from API: $rbody "
150
+              . "(HTTP response code was $rcode)";
151
+            throw new Error\Api($msg, $rcode, $rbody, $resp, $rheaders);
152
+        }
153
+
154
+        $errorData = $resp['error'];
155
+
156
+        #echo $rbody;exit;
157
+
158
+        $error = null;
159
+        if (!$error) {
160
+            $error = self::_specificAPIError($rbody, $rcode, $rheaders, $resp, $errorData);
161
+        }
162
+
163
+        throw $error;
164
+    }
165
+
166
+    /**
167
+     * @static
168
+     *
169
+     * @param string $rbody
170
+     * @param int    $rcode
171
+     * @param array  $rheaders
172
+     * @param array  $resp
173
+     * @param array  $errorData
174
+     *
175
+     * @return Error\RateLimit|Error\Idempotency|Error\InvalidRequest|Error\Authentication|Error\Card|Error\Permission|Error\Api
176
+     */
177
+    private static function _specificAPIError($rbody, $rcode, $rheaders, $resp, $errorData)
178
+    {
179
+        $msg = isset($errorData['message']) ? $errorData['message'] : null;
180
+        $param = isset($errorData['param']) ? $errorData['param'] : null;
181
+        $code = isset($errorData['code']) ? $errorData['code'] : null;
182
+        $type = isset($errorData['type']) ? $errorData['type'] : null;
183
+
184
+        switch ($rcode) {
185
+            case 400:
186
+                // 'rate_limit' code is deprecated, but left here for backwards compatibility
187
+                // for API versions earlier than 2015-09-08
188
+                if ($code == 'rate_limit') {
189
+                    return new Error\RateLimit($msg, $param, $rcode, $rbody, $resp, $rheaders);
190
+                }
191
+                if ($type == 'idempotency_error') {
192
+                    return new Error\Idempotency($msg, $rcode, $rbody, $resp, $rheaders);
193
+                }
194
+
195
+                // intentional fall-through
196
+                // no break
197
+            case 404:
198
+                return new Error\InvalidRequest($msg, $param, $rcode, $rbody, $resp, $rheaders);
199
+            case 401:
200
+                return new Error\Authentication($msg, $rcode, $rbody, $resp, $rheaders);
201
+            case 402:
202
+                return new Error\Card($msg, $param, $code, $rcode, $rbody, $resp, $rheaders);
203
+            case 403:
204
+                return new Error\Permission($msg, $rcode, $rbody, $resp, $rheaders);
205
+            case 429:
206
+                return new Error\RateLimit($msg, $param, $rcode, $rbody, $resp, $rheaders);
207
+            default:
208
+                return new Error\Api($msg, $rcode, $rbody, $resp, $rheaders);
209
+        }
210
+    }
211
+
212
+    /**
213
+     * @static
214
+     *
215
+     * @param null|array $appInfo
216
+     *
217
+     * @return null|string
218
+     */
219
+    private static function _formatAppInfo($appInfo)
220
+    {
221
+        if ($appInfo !== null) {
222
+            $string = $appInfo['name'];
223
+            if ($appInfo['version'] !== null) {
224
+                $string .= '/' . $appInfo['version'];
225
+            }
226
+            if ($appInfo['url'] !== null) {
227
+                $string .= ' (' . $appInfo['url'] . ')';
228
+            }
229
+            return $string;
230
+        } else {
231
+            return null;
232
+        }
233
+    }
234
+
235
+    /**
236
+     * @static
237
+     *
238
+     * @param string $apiKey
239
+     * @param null   $clientInfo
240
+     *
241
+     * @return array
242
+     */
243
+    private static function _defaultHeaders($apiKey, $clientInfo = null)
244
+    {
245
+        $uaString = 'Telnyx/v2 PhpBindings/' . Telnyx::VERSION;
246
+
247
+        $langVersion = phpversion();
248
+        $uname = php_uname();
249
+
250
+        $appInfo = Telnyx::getAppInfo();
251
+        $ua = [
252
+            'bindings_version' => Telnyx::VERSION,
253
+            'lang' => 'php',
254
+            'lang_version' => $langVersion,
255
+            'publisher' => 'telnyx',
256
+            'uname' => $uname,
257
+        ];
258
+        if ($clientInfo) {
259
+            $ua = array_merge($clientInfo, $ua);
260
+        }
261
+        if ($appInfo !== null) {
262
+            $uaString .= ' ' . self::_formatAppInfo($appInfo);
263
+            $ua['application'] = $appInfo;
264
+        }
265
+
266
+        $defaultHeaders = [
267
+            'X-Telnyx-Client-User-Agent' => json_encode($ua),
268
+            'User-Agent' => $uaString,
269
+            'Authorization' => 'Bearer ' . $apiKey,
270
+        ];
271
+        return $defaultHeaders;
272
+    }
273
+
274
+    /**
275
+     * @param string $method
276
+     * @param string $url
277
+     * @param array  $params
278
+     * @param array  $headers
279
+     *
280
+     * @return array
281
+     * @throws Error\Api
282
+     * @throws Error\ApiConnection
283
+     * @throws Error\Authentication
284
+     */
285
+    private function _requestRaw($method, $url, $params, $headers)
286
+    {
287
+        $myApiKey = $this->_apiKey;
288
+        if (!$myApiKey) {
289
+            $myApiKey = Telnyx::$apiKey;
290
+        }
291
+
292
+        if (!$myApiKey) {
293
+            $msg = 'No API key provided.  (HINT: set your API key using '
294
+              . '"Telnyx::setApiKey(<API-KEY>)".  You can generate API keys from '
295
+              . 'the Telnyx web interface.  See https://developers.telnyx.com/docs/v2/development/authentication '
296
+              . 'for details, or email support@telnyx.com if you have any questions.';
297
+            throw new Error\Authentication($msg);
298
+        }
299
+
300
+        // Clients can supply arbitrary additional keys to be included in the
301
+        // X-Telnyx-Client-User-Agent header via the optional getUserAgentInfo()
302
+        // method
303
+        $clientUAInfo = null;
304
+        if (method_exists($this->httpClient(), 'getUserAgentInfo')) {
305
+            $clientUAInfo = $this->httpClient()->getUserAgentInfo();
306
+        }
307
+
308
+        $absUrl = $this->_apiBase.$url;
309
+        $params = self::_encodeObjects($params);
310
+        $defaultHeaders = $this->_defaultHeaders($myApiKey, $clientUAInfo);
311
+        if (Telnyx::$apiVersion) {
312
+            $defaultHeaders['Telnyx-Version'] = Telnyx::$apiVersion;
313
+        }
314
+
315
+        if (Telnyx::$accountId) {
316
+            $defaultHeaders['Telnyx-Account'] = Telnyx::$accountId;
317
+        }
318
+
319
+        if (Telnyx::$enableTelemetry && self::$requestTelemetry != null) {
320
+            $defaultHeaders["X-Telnyx-Client-Telemetry"] = self::_telemetryJson(self::$requestTelemetry);
321
+        }
322
+
323
+        $hasFile = false;
324
+        $hasCurlFile = class_exists('\CURLFile', false);
325
+        foreach ($params as $k => $v) {
326
+            if (is_resource($v)) {
327
+                $hasFile = true;
328
+                $params[$k] = self::_processResourceParam($v, $hasCurlFile);
329
+            } elseif ($hasCurlFile && $v instanceof \CURLFile) {
330
+                $hasFile = true;
331
+            }
332
+        }
333
+
334
+        if ($hasFile) {
335
+            $defaultHeaders['Content-Type'] = 'multipart/form-data';
336
+        } else {
337
+            $defaultHeaders['Content-Type'] = 'application/json';
338
+        }
339
+
340
+        $combinedHeaders = array_merge($defaultHeaders, $headers);
341
+        $rawHeaders = [];
342
+
343
+        foreach ($combinedHeaders as $header => $value) {
344
+            $rawHeaders[] = $header . ': ' . $value;
345
+        }
346
+
347
+        $requestStartMs = Util\Util::currentTimeMillis();
348
+
349
+        list($rbody, $rcode, $rheaders) = $this->httpClient()->request(
350
+            $method,
351
+            $absUrl,
352
+            $rawHeaders,
353
+            $params,
354
+            $hasFile
355
+        );
356
+
357
+//        if (array_key_exists('request-id', $rheaders)) {
358
+        if (property_exists($rheaders, 'request-id') && (null !== $rheaders->request-id)) {
359
+            self::$requestTelemetry = new RequestTelemetry(
360
+                $rheaders['request-id'],
361
+                Util\Util::currentTimeMillis() - $requestStartMs
362
+            );
363
+        }
364
+
365
+        return [$rbody, $rcode, $rheaders, $myApiKey];
366
+    }
367
+
368
+    /**
369
+     * @param resource $resource
370
+     * @param bool     $hasCurlFile
371
+     *
372
+     * @return \CURLFile|string
373
+     * @throws Error\Api
374
+     */
375
+    private function _processResourceParam($resource, $hasCurlFile)
376
+    {
377
+        if (get_resource_type($resource) !== 'stream') {
378
+            throw new Error\Api(
379
+                'Attempted to upload a resource that is not a stream'
380
+            );
381
+        }
382
+
383
+        $metaData = stream_get_meta_data($resource);
384
+        if ($metaData['wrapper_type'] !== 'plainfile') {
385
+            throw new Error\Api(
386
+                'Only plainfile resource streams are supported'
387
+            );
388
+        }
389
+
390
+        if ($hasCurlFile) {
391
+            // We don't have the filename or mimetype, but the API doesn't care
392
+            return new \CURLFile($metaData['uri']);
393
+        } else {
394
+            return '@'.$metaData['uri'];
395
+        }
396
+    }
397
+
398
+    /**
399
+     * @param string $rbody
400
+     * @param int    $rcode
401
+     * @param array  $rheaders
402
+     *
403
+     * @return mixed
404
+     * @throws Error\Api
405
+     * @throws Error\Authentication
406
+     * @throws Error\Card
407
+     * @throws Error\InvalidRequest
408
+     * @throws Error\Permission
409
+     * @throws Error\RateLimit
410
+     * @throws Error\Idempotency
411
+     */
412
+    private function _interpretResponse($rbody, $rcode, $rheaders)
413
+    {
414
+        $resp = json_decode($rbody, true);
415
+
416
+        // Move [data] to the parent node
417
+        if (isset($resp['data'])) {
418
+            $resp = $resp['data'];
419
+        }
420
+
421
+        $jsonError = json_last_error();
422
+        if ($resp === null && $jsonError !== JSON_ERROR_NONE) {
423
+            $msg = "Invalid response body from API: $rbody "
424
+              . "(HTTP response code was $rcode, json_last_error() was $jsonError)";
425
+            throw new Error\Api($msg, $rcode, $rbody);
426
+        }
427
+
428
+        if ($rcode < 200 || $rcode >= 300) {
429
+            $this->handleErrorResponse($rbody, $rcode, $rheaders, $resp);
430
+        }
431
+        return $resp;
432
+    }
433
+
434
+    /**
435
+     * @static
436
+     *
437
+     * @param HttpClient\ClientInterface $client
438
+     */
439
+    public static function setHttpClient($client)
440
+    {
441
+        self::$_httpClient = $client;
442
+    }
443
+
444
+    /**
445
+     * @static
446
+     *
447
+     * Resets any stateful telemetry data
448
+     */
449
+    public static function resetTelemetry()
450
+    {
451
+        self::$requestTelemetry = null;
452
+    }
453
+
454
+    /**
455
+     * @return HttpClient\ClientInterface
456
+     */
457
+    private function httpClient()
458
+    {
459
+        if (!self::$_httpClient) {
460
+            self::$_httpClient = HttpClient\CurlClient::instance();
461
+        }
462
+        return self::$_httpClient;
463
+    }
464
+}
Browse code

removed CHANGELOG.txt Contributors.txt README.md Telnyx/lib/ApiRequestor.php appinfo/info.xml appinfo/signature.json

DoubleBastionAdmin authored on 07/05/2022 23:46:07
Showing 1 changed files
1 1
deleted file mode 100644
... ...
@@ -1,463 +0,0 @@
1
-<?php
2
-
3
-namespace Telnyx;
4
-
5
-/**
6
- * Class ApiRequestor
7
- *
8
- * @package Telnyx
9
- */
10
-class ApiRequestor
11
-{
12
-    /**
13
-     * @var string|null
14
-     */
15
-    private $_apiKey;
16
-
17
-    /**
18
-     * @var string
19
-     */
20
-    private $_apiBase;
21
-
22
-    /**
23
-     * @var HttpClient\ClientInterface
24
-     */
25
-    private static $_httpClient;
26
-
27
-    /**
28
-     * @var RequestTelemetry
29
-     */
30
-    private static $requestTelemetry;
31
-
32
-    /**
33
-     * ApiRequestor constructor.
34
-     *
35
-     * @param string|null $apiKey
36
-     * @param string|null $apiBase
37
-     */
38
-    public function __construct($apiKey = null, $apiBase = null)
39
-    {
40
-        $this->_apiKey = $apiKey;
41
-        if (!$apiBase) {
42
-            $apiBase = Telnyx::$apiBase;
43
-        }
44
-        $this->_apiBase = $apiBase;
45
-    }
46
-
47
-    /**
48
-     * Creates a telemetry json blob for use in 'X-Telnyx-Client-Telemetry' headers
49
-     * @static
50
-     *
51
-     * @param RequestTelemetry $requestTelemetry
52
-     * @return string
53
-     */
54
-    private static function _telemetryJson($requestTelemetry)
55
-    {
56
-        $payload = array(
57
-            'last_request_metrics' => array(
58
-                'request_id' => $requestTelemetry->requestId,
59
-                'request_duration_ms' => $requestTelemetry->requestDuration,
60
-        ));
61
-
62
-        $result = json_encode($payload);
63
-        if ($result != false) {
64
-            return $result;
65
-        } else {
66
-            Telnyx::getLogger()->error("Serializing telemetry payload failed!");
67
-            return "{}";
68
-        }
69
-    }
70
-
71
-    /**
72
-     * @static
73
-     *
74
-     * @param ApiResource|bool|array|mixed $d
75
-     *
76
-     * @return ApiResource|array|string|mixed
77
-     */
78
-    private static function _encodeObjects($d)
79
-    {
80
-        if ($d instanceof ApiResource) {
81
-            return Util\Util::utf8($d->id);
82
-        } elseif ($d === true) {
83
-            return 'true';
84
-        } elseif ($d === false) {
85
-            return 'false';
86
-        } elseif (is_array($d)) {
87
-            $res = [];
88
-            foreach ($d as $k => $v) {
89
-                $res[$k] = self::_encodeObjects($v);
90
-            }
91
-            return $res;
92
-        } else {
93
-            return Util\Util::utf8($d);
94
-        }
95
-    }
96
-
97
-    /**
98
-     * @param string     $method
99
-     * @param string     $url
100
-     * @param array|null $params
101
-     * @param array|null $headers
102
-     *
103
-     * @return array An array whose first element is an API response and second
104
-     *    element is the API key used to make the request.
105
-     * @throws Error\Api
106
-     * @throws Error\Authentication
107
-     * @throws Error\Card
108
-     * @throws Error\InvalidRequest
109
-     * @throws Error\Permission
110
-     * @throws Error\RateLimit
111
-     * @throws Error\Idempotency
112
-     * @throws Error\ApiConnection
113
-     */
114
-    public function request($method, $url, $params = null, $headers = null)
115
-    {
116
-        $params = $params ?: [];
117
-        $headers = $headers ?: [];
118
-        list($rbody, $rcode, $rheaders, $myApiKey) =
119
-        $this->_requestRaw($method, $url, $params, $headers);
120
-        $json = $this->_interpretResponse($rbody, $rcode, $rheaders);
121
-        $resp = new ApiResponse($rbody, $rcode, $rheaders, $json);
122
-        return [$resp, $myApiKey];
123
-    }
124
-
125
-    /**
126
-     * @param string $rbody A JSON string.
127
-     * @param int $rcode
128
-     * @param array $rheaders
129
-     * @param array $resp
130
-     *
131
-     * @throws Error\InvalidRequest if the error is caused by the user.
132
-     * @throws Error\Authentication if the error is caused by a lack of
133
-     *    permissions.
134
-     * @throws Error\Permission if the error is caused by insufficient
135
-     *    permissions.
136
-     * @throws Error\Card if the error is the error code is 402 (payment
137
-     *    required)
138
-     * @throws Error\InvalidRequest if the error is caused by the user.
139
-     * @throws Error\Idempotency if the error is caused by an idempotency key.
140
-     * @throws Error\Permission if the error is caused by insufficient
141
-     *    permissions.
142
-     * @throws Error\RateLimit if the error is caused by too many requests
143
-     *    hitting the API.
144
-     * @throws Error\Api otherwise.
145
-     */
146
-    public function handleErrorResponse($rbody, $rcode, $rheaders, $resp)
147
-    {
148
-        if (!is_array($resp) || !isset($resp['error'])) {
149
-            $msg = "Invalid response object from API: $rbody "
150
-              . "(HTTP response code was $rcode)";
151
-            throw new Error\Api($msg, $rcode, $rbody, $resp, $rheaders);
152
-        }
153
-
154
-        $errorData = $resp['error'];
155
-
156
-        #echo $rbody;exit;
157
-
158
-        $error = null;
159
-        if (!$error) {
160
-            $error = self::_specificAPIError($rbody, $rcode, $rheaders, $resp, $errorData);
161
-        }
162
-
163
-        throw $error;
164
-    }
165
-
166
-    /**
167
-     * @static
168
-     *
169
-     * @param string $rbody
170
-     * @param int    $rcode
171
-     * @param array  $rheaders
172
-     * @param array  $resp
173
-     * @param array  $errorData
174
-     *
175
-     * @return Error\RateLimit|Error\Idempotency|Error\InvalidRequest|Error\Authentication|Error\Card|Error\Permission|Error\Api
176
-     */
177
-    private static function _specificAPIError($rbody, $rcode, $rheaders, $resp, $errorData)
178
-    {
179
-        $msg = isset($errorData['message']) ? $errorData['message'] : null;
180
-        $param = isset($errorData['param']) ? $errorData['param'] : null;
181
-        $code = isset($errorData['code']) ? $errorData['code'] : null;
182
-        $type = isset($errorData['type']) ? $errorData['type'] : null;
183
-
184
-        switch ($rcode) {
185
-            case 400:
186
-                // 'rate_limit' code is deprecated, but left here for backwards compatibility
187
-                // for API versions earlier than 2015-09-08
188
-                if ($code == 'rate_limit') {
189
-                    return new Error\RateLimit($msg, $param, $rcode, $rbody, $resp, $rheaders);
190
-                }
191
-                if ($type == 'idempotency_error') {
192
-                    return new Error\Idempotency($msg, $rcode, $rbody, $resp, $rheaders);
193
-                }
194
-
195
-                // intentional fall-through
196
-                // no break
197
-            case 404:
198
-                return new Error\InvalidRequest($msg, $param, $rcode, $rbody, $resp, $rheaders);
199
-            case 401:
200
-                return new Error\Authentication($msg, $rcode, $rbody, $resp, $rheaders);
201
-            case 402:
202
-                return new Error\Card($msg, $param, $code, $rcode, $rbody, $resp, $rheaders);
203
-            case 403:
204
-                return new Error\Permission($msg, $rcode, $rbody, $resp, $rheaders);
205
-            case 429:
206
-                return new Error\RateLimit($msg, $param, $rcode, $rbody, $resp, $rheaders);
207
-            default:
208
-                return new Error\Api($msg, $rcode, $rbody, $resp, $rheaders);
209
-        }
210
-    }
211
-
212
-    /**
213
-     * @static
214
-     *
215
-     * @param null|array $appInfo
216
-     *
217
-     * @return null|string
218
-     */
219
-    private static function _formatAppInfo($appInfo)
220
-    {
221
-        if ($appInfo !== null) {
222
-            $string = $appInfo['name'];
223
-            if ($appInfo['version'] !== null) {
224
-                $string .= '/' . $appInfo['version'];
225
-            }
226
-            if ($appInfo['url'] !== null) {
227
-                $string .= ' (' . $appInfo['url'] . ')';
228
-            }
229
-            return $string;
230
-        } else {
231
-            return null;
232
-        }
233
-    }
234
-
235
-    /**
236
-     * @static
237
-     *
238
-     * @param string $apiKey
239
-     * @param null   $clientInfo
240
-     *
241
-     * @return array
242
-     */
243
-    private static function _defaultHeaders($apiKey, $clientInfo = null)
244
-    {
245
-        $uaString = 'Telnyx/v2 PhpBindings/' . Telnyx::VERSION;
246
-
247
-        $langVersion = phpversion();
248
-        $uname = php_uname();
249
-
250
-        $appInfo = Telnyx::getAppInfo();
251
-        $ua = [
252
-            'bindings_version' => Telnyx::VERSION,
253
-            'lang' => 'php',
254
-            'lang_version' => $langVersion,
255
-            'publisher' => 'telnyx',
256
-            'uname' => $uname,
257
-        ];
258
-        if ($clientInfo) {
259
-            $ua = array_merge($clientInfo, $ua);
260
-        }
261
-        if ($appInfo !== null) {
262
-            $uaString .= ' ' . self::_formatAppInfo($appInfo);
263
-            $ua['application'] = $appInfo;
264
-        }
265
-
266
-        $defaultHeaders = [
267
-            'X-Telnyx-Client-User-Agent' => json_encode($ua),
268
-            'User-Agent' => $uaString,
269
-            'Authorization' => 'Bearer ' . $apiKey,
270
-        ];
271
-        return $defaultHeaders;
272
-    }
273
-
274
-    /**
275
-     * @param string $method
276
-     * @param string $url
277
-     * @param array  $params
278
-     * @param array  $headers
279
-     *
280
-     * @return array
281
-     * @throws Error\Api
282
-     * @throws Error\ApiConnection
283
-     * @throws Error\Authentication
284
-     */
285
-    private function _requestRaw($method, $url, $params, $headers)
286
-    {
287
-        $myApiKey = $this->_apiKey;
288
-        if (!$myApiKey) {
289
-            $myApiKey = Telnyx::$apiKey;
290
-        }
291
-
292
-        if (!$myApiKey) {
293
-            $msg = 'No API key provided.  (HINT: set your API key using '
294
-              . '"Telnyx::setApiKey(<API-KEY>)".  You can generate API keys from '
295
-              . 'the Telnyx web interface.  See https://developers.telnyx.com/docs/v2/development/authentication '
296
-              . 'for details, or email support@telnyx.com if you have any questions.';
297
-            throw new Error\Authentication($msg);
298
-        }
299
-
300
-        // Clients can supply arbitrary additional keys to be included in the
301
-        // X-Telnyx-Client-User-Agent header via the optional getUserAgentInfo()
302
-        // method
303
-        $clientUAInfo = null;
304
-        if (method_exists($this->httpClient(), 'getUserAgentInfo')) {
305
-            $clientUAInfo = $this->httpClient()->getUserAgentInfo();
306
-        }
307
-
308
-        $absUrl = $this->_apiBase.$url;
309
-        $params = self::_encodeObjects($params);
310
-        $defaultHeaders = $this->_defaultHeaders($myApiKey, $clientUAInfo);
311
-        if (Telnyx::$apiVersion) {
312
-            $defaultHeaders['Telnyx-Version'] = Telnyx::$apiVersion;
313
-        }
314
-
315
-        if (Telnyx::$accountId) {
316
-            $defaultHeaders['Telnyx-Account'] = Telnyx::$accountId;
317
-        }
318
-
319
-        if (Telnyx::$enableTelemetry && self::$requestTelemetry != null) {
320
-            $defaultHeaders["X-Telnyx-Client-Telemetry"] = self::_telemetryJson(self::$requestTelemetry);
321
-        }
322
-
323
-        $hasFile = false;
324
-        $hasCurlFile = class_exists('\CURLFile', false);
325
-        foreach ($params as $k => $v) {
326
-            if (is_resource($v)) {
327
-                $hasFile = true;
328
-                $params[$k] = self::_processResourceParam($v, $hasCurlFile);
329
-            } elseif ($hasCurlFile && $v instanceof \CURLFile) {
330
-                $hasFile = true;
331
-            }
332
-        }
333
-
334
-        if ($hasFile) {
335
-            $defaultHeaders['Content-Type'] = 'multipart/form-data';
336
-        } else {
337
-            $defaultHeaders['Content-Type'] = 'application/json';
338
-        }
339
-
340
-        $combinedHeaders = array_merge($defaultHeaders, $headers);
341
-        $rawHeaders = [];
342
-
343
-        foreach ($combinedHeaders as $header => $value) {
344
-            $rawHeaders[] = $header . ': ' . $value;
345
-        }
346
-
347
-        $requestStartMs = Util\Util::currentTimeMillis();
348
-
349
-        list($rbody, $rcode, $rheaders) = $this->httpClient()->request(
350
-            $method,
351
-            $absUrl,
352
-            $rawHeaders,
353
-            $params,
354
-            $hasFile
355
-        );
356
-
357
-        if (array_key_exists('request-id', $rheaders)) {
358
-            self::$requestTelemetry = new RequestTelemetry(
359
-                $rheaders['request-id'],
360
-                Util\Util::currentTimeMillis() - $requestStartMs
361
-            );
362
-        }
363
-
364
-        return [$rbody, $rcode, $rheaders, $myApiKey];
365
-    }
366
-
367
-    /**
368
-     * @param resource $resource
369
-     * @param bool     $hasCurlFile
370
-     *
371
-     * @return \CURLFile|string
372
-     * @throws Error\Api
373
-     */
374
-    private function _processResourceParam($resource, $hasCurlFile)
375
-    {
376
-        if (get_resource_type($resource) !== 'stream') {
377
-            throw new Error\Api(
378
-                'Attempted to upload a resource that is not a stream'
379
-            );
380
-        }
381
-
382
-        $metaData = stream_get_meta_data($resource);
383
-        if ($metaData['wrapper_type'] !== 'plainfile') {
384
-            throw new Error\Api(
385
-                'Only plainfile resource streams are supported'
386
-            );
387
-        }
388
-
389
-        if ($hasCurlFile) {
390
-            // We don't have the filename or mimetype, but the API doesn't care
391
-            return new \CURLFile($metaData['uri']);
392
-        } else {
393
-            return '@'.$metaData['uri'];
394
-        }
395
-    }
396
-
397
-    /**
398
-     * @param string $rbody
399
-     * @param int    $rcode
400
-     * @param array  $rheaders
401
-     *
402
-     * @return mixed
403
-     * @throws Error\Api
404
-     * @throws Error\Authentication
405
-     * @throws Error\Card
406
-     * @throws Error\InvalidRequest
407
-     * @throws Error\Permission
408
-     * @throws Error\RateLimit
409
-     * @throws Error\Idempotency
410
-     */
411
-    private function _interpretResponse($rbody, $rcode, $rheaders)
412
-    {
413
-        $resp = json_decode($rbody, true);
414
-
415
-        // Move [data] to the parent node
416
-        if (isset($resp['data'])) {
417
-            $resp = $resp['data'];
418
-        }
419
-
420
-        $jsonError = json_last_error();
421
-        if ($resp === null && $jsonError !== JSON_ERROR_NONE) {
422
-            $msg = "Invalid response body from API: $rbody "
423
-              . "(HTTP response code was $rcode, json_last_error() was $jsonError)";
424
-            throw new Error\Api($msg, $rcode, $rbody);
425
-        }
426
-
427
-        if ($rcode < 200 || $rcode >= 300) {
428
-            $this->handleErrorResponse($rbody, $rcode, $rheaders, $resp);
429
-        }
430
-        return $resp;
431
-    }
432
-
433
-    /**
434
-     * @static
435
-     *
436
-     * @param HttpClient\ClientInterface $client
437
-     */
438
-    public static function setHttpClient($client)
439
-    {
440
-        self::$_httpClient = $client;
441
-    }
442
-
443
-    /**
444
-     * @static
445
-     *
446
-     * Resets any stateful telemetry data
447
-     */
448
-    public static function resetTelemetry()
449
-    {
450
-        self::$requestTelemetry = null;
451
-    }
452
-
453
-    /**
454
-     * @return HttpClient\ClientInterface
455
-     */
456
-    private function httpClient()
457
-    {
458
-        if (!self::$_httpClient) {
459
-            self::$_httpClient = HttpClient\CurlClient::instance();
460
-        }
461
-        return self::$_httpClient;
462
-    }
463
-}
Browse code

Created repository.

DoubleBastionAdmin authored on 01/03/2022 23:47:00
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,463 @@
1
+<?php
2
+
3
+namespace Telnyx;
4
+
5
+/**
6
+ * Class ApiRequestor
7
+ *
8
+ * @package Telnyx
9
+ */
10
+class ApiRequestor
11
+{
12
+    /**
13
+     * @var string|null
14
+     */
15
+    private $_apiKey;
16
+
17
+    /**
18
+     * @var string
19
+     */
20
+    private $_apiBase;
21
+
22
+    /**
23
+     * @var HttpClient\ClientInterface
24
+     */
25
+    private static $_httpClient;
26
+
27
+    /**
28
+     * @var RequestTelemetry
29
+     */
30
+    private static $requestTelemetry;
31
+
32
+    /**
33
+     * ApiRequestor constructor.
34
+     *
35
+     * @param string|null $apiKey
36
+     * @param string|null $apiBase
37
+     */
38
+    public function __construct($apiKey = null, $apiBase = null)
39
+    {
40
+        $this->_apiKey = $apiKey;
41
+        if (!$apiBase) {
42
+            $apiBase = Telnyx::$apiBase;
43
+        }
44
+        $this->_apiBase = $apiBase;
45
+    }
46
+
47
+    /**
48
+     * Creates a telemetry json blob for use in 'X-Telnyx-Client-Telemetry' headers
49
+     * @static
50
+     *
51
+     * @param RequestTelemetry $requestTelemetry
52
+     * @return string
53
+     */
54
+    private static function _telemetryJson($requestTelemetry)
55
+    {
56
+        $payload = array(
57
+            'last_request_metrics' => array(
58
+                'request_id' => $requestTelemetry->requestId,
59
+                'request_duration_ms' => $requestTelemetry->requestDuration,
60
+        ));
61
+
62
+        $result = json_encode($payload);
63
+        if ($result != false) {
64
+            return $result;
65
+        } else {
66
+            Telnyx::getLogger()->error("Serializing telemetry payload failed!");
67
+            return "{}";
68
+        }
69
+    }
70
+
71
+    /**
72
+     * @static
73
+     *
74
+     * @param ApiResource|bool|array|mixed $d
75
+     *
76
+     * @return ApiResource|array|string|mixed
77
+     */
78
+    private static function _encodeObjects($d)
79
+    {
80
+        if ($d instanceof ApiResource) {
81
+            return Util\Util::utf8($d->id);
82
+        } elseif ($d === true) {
83
+            return 'true';
84
+        } elseif ($d === false) {
85
+            return 'false';
86
+        } elseif (is_array($d)) {
87
+            $res = [];
88
+            foreach ($d as $k => $v) {
89
+                $res[$k] = self::_encodeObjects($v);
90
+            }
91
+            return $res;
92
+        } else {
93
+            return Util\Util::utf8($d);
94
+        }
95
+    }
96
+
97
+    /**
98
+     * @param string     $method
99
+     * @param string     $url
100
+     * @param array|null $params
101
+     * @param array|null $headers
102
+     *
103
+     * @return array An array whose first element is an API response and second
104
+     *    element is the API key used to make the request.
105
+     * @throws Error\Api
106
+     * @throws Error\Authentication
107
+     * @throws Error\Card
108
+     * @throws Error\InvalidRequest
109
+     * @throws Error\Permission
110
+     * @throws Error\RateLimit
111
+     * @throws Error\Idempotency
112
+     * @throws Error\ApiConnection
113
+     */
114
+    public function request($method, $url, $params = null, $headers = null)
115
+    {
116
+        $params = $params ?: [];
117
+        $headers = $headers ?: [];
118
+        list($rbody, $rcode, $rheaders, $myApiKey) =
119
+        $this->_requestRaw($method, $url, $params, $headers);
120
+        $json = $this->_interpretResponse($rbody, $rcode, $rheaders);
121
+        $resp = new ApiResponse($rbody, $rcode, $rheaders, $json);
122
+        return [$resp, $myApiKey];
123
+    }
124
+
125
+    /**
126
+     * @param string $rbody A JSON string.
127
+     * @param int $rcode
128
+     * @param array $rheaders
129
+     * @param array $resp
130
+     *
131
+     * @throws Error\InvalidRequest if the error is caused by the user.
132
+     * @throws Error\Authentication if the error is caused by a lack of
133
+     *    permissions.
134
+     * @throws Error\Permission if the error is caused by insufficient
135
+     *    permissions.
136
+     * @throws Error\Card if the error is the error code is 402 (payment
137
+     *    required)
138
+     * @throws Error\InvalidRequest if the error is caused by the user.
139
+     * @throws Error\Idempotency if the error is caused by an idempotency key.
140
+     * @throws Error\Permission if the error is caused by insufficient
141
+     *    permissions.
142
+     * @throws Error\RateLimit if the error is caused by too many requests
143
+     *    hitting the API.
144
+     * @throws Error\Api otherwise.
145
+     */
146
+    public function handleErrorResponse($rbody, $rcode, $rheaders, $resp)
147
+    {
148
+        if (!is_array($resp) || !isset($resp['error'])) {
149
+            $msg = "Invalid response object from API: $rbody "
150
+              . "(HTTP response code was $rcode)";
151
+            throw new Error\Api($msg, $rcode, $rbody, $resp, $rheaders);
152
+        }
153
+
154
+        $errorData = $resp['error'];
155
+
156
+        #echo $rbody;exit;
157
+
158
+        $error = null;
159
+        if (!$error) {
160
+            $error = self::_specificAPIError($rbody, $rcode, $rheaders, $resp, $errorData);
161
+        }
162
+
163
+        throw $error;
164
+    }
165
+
166
+    /**
167
+     * @static
168
+     *
169
+     * @param string $rbody
170
+     * @param int    $rcode
171
+     * @param array  $rheaders
172
+     * @param array  $resp
173
+     * @param array  $errorData
174
+     *
175
+     * @return Error\RateLimit|Error\Idempotency|Error\InvalidRequest|Error\Authentication|Error\Card|Error\Permission|Error\Api
176
+     */
177
+    private static function _specificAPIError($rbody, $rcode, $rheaders, $resp, $errorData)
178
+    {
179
+        $msg = isset($errorData['message']) ? $errorData['message'] : null;
180
+        $param = isset($errorData['param']) ? $errorData['param'] : null;
181
+        $code = isset($errorData['code']) ? $errorData['code'] : null;
182
+        $type = isset($errorData['type']) ? $errorData['type'] : null;
183
+
184
+        switch ($rcode) {
185
+            case 400:
186
+                // 'rate_limit' code is deprecated, but left here for backwards compatibility
187
+                // for API versions earlier than 2015-09-08
188
+                if ($code == 'rate_limit') {
189
+                    return new Error\RateLimit($msg, $param, $rcode, $rbody, $resp, $rheaders);
190
+                }
191
+                if ($type == 'idempotency_error') {
192
+                    return new Error\Idempotency($msg, $rcode, $rbody, $resp, $rheaders);
193
+                }
194
+
195
+                // intentional fall-through
196
+                // no break
197
+            case 404:
198
+                return new Error\InvalidRequest($msg, $param, $rcode, $rbody, $resp, $rheaders);
199
+            case 401:
200
+                return new Error\Authentication($msg, $rcode, $rbody, $resp, $rheaders);
201
+            case 402:
202
+                return new Error\Card($msg, $param, $code, $rcode, $rbody, $resp, $rheaders);
203
+            case 403:
204
+                return new Error\Permission($msg, $rcode, $rbody, $resp, $rheaders);
205
+            case 429:
206
+                return new Error\RateLimit($msg, $param, $rcode, $rbody, $resp, $rheaders);
207
+            default:
208
+                return new Error\Api($msg, $rcode, $rbody, $resp, $rheaders);
209
+        }
210
+    }
211
+
212
+    /**
213
+     * @static
214
+     *
215
+     * @param null|array $appInfo
216
+     *
217
+     * @return null|string
218
+     */
219
+    private static function _formatAppInfo($appInfo)
220
+    {
221
+        if ($appInfo !== null) {
222
+            $string = $appInfo['name'];
223
+            if ($appInfo['version'] !== null) {
224
+                $string .= '/' . $appInfo['version'];
225
+            }
226
+            if ($appInfo['url'] !== null) {
227
+                $string .= ' (' . $appInfo['url'] . ')';
228
+            }
229
+            return $string;
230
+        } else {
231
+            return null;
232
+        }
233
+    }
234
+
235
+    /**
236
+     * @static
237
+     *
238
+     * @param string $apiKey
239
+     * @param null   $clientInfo
240
+     *
241
+     * @return array
242
+     */
243
+    private static function _defaultHeaders($apiKey, $clientInfo = null)
244
+    {
245
+        $uaString = 'Telnyx/v2 PhpBindings/' . Telnyx::VERSION;
246
+
247
+        $langVersion = phpversion();
248
+        $uname = php_uname();
249
+
250
+        $appInfo = Telnyx::getAppInfo();
251
+        $ua = [
252
+            'bindings_version' => Telnyx::VERSION,
253
+            'lang' => 'php',
254
+            'lang_version' => $langVersion,
255
+            'publisher' => 'telnyx',
256
+            'uname' => $uname,
257
+        ];
258
+        if ($clientInfo) {
259
+            $ua = array_merge($clientInfo, $ua);
260
+        }
261
+        if ($appInfo !== null) {
262
+            $uaString .= ' ' . self::_formatAppInfo($appInfo);
263
+            $ua['application'] = $appInfo;
264
+        }
265
+
266
+        $defaultHeaders = [
267
+            'X-Telnyx-Client-User-Agent' => json_encode($ua),
268
+            'User-Agent' => $uaString,
269
+            'Authorization' => 'Bearer ' . $apiKey,
270
+        ];
271
+        return $defaultHeaders;
272
+    }
273
+
274
+    /**
275
+     * @param string $method
276
+     * @param string $url
277
+     * @param array  $params
278
+     * @param array  $headers
279
+     *
280
+     * @return array
281
+     * @throws Error\Api
282
+     * @throws Error\ApiConnection
283
+     * @throws Error\Authentication
284
+     */
285
+    private function _requestRaw($method, $url, $params, $headers)
286
+    {
287
+        $myApiKey = $this->_apiKey;
288
+        if (!$myApiKey) {
289
+            $myApiKey = Telnyx::$apiKey;
290
+        }
291
+
292
+        if (!$myApiKey) {
293
+            $msg = 'No API key provided.  (HINT: set your API key using '
294
+              . '"Telnyx::setApiKey(<API-KEY>)".  You can generate API keys from '
295
+              . 'the Telnyx web interface.  See https://developers.telnyx.com/docs/v2/development/authentication '
296
+              . 'for details, or email support@telnyx.com if you have any questions.';
297
+            throw new Error\Authentication($msg);
298
+        }
299
+
300
+        // Clients can supply arbitrary additional keys to be included in the
301
+        // X-Telnyx-Client-User-Agent header via the optional getUserAgentInfo()
302
+        // method
303
+        $clientUAInfo = null;
304
+        if (method_exists($this->httpClient(), 'getUserAgentInfo')) {
305
+            $clientUAInfo = $this->httpClient()->getUserAgentInfo();
306
+        }
307
+
308
+        $absUrl = $this->_apiBase.$url;
309
+        $params = self::_encodeObjects($params);
310
+        $defaultHeaders = $this->_defaultHeaders($myApiKey, $clientUAInfo);
311
+        if (Telnyx::$apiVersion) {
312
+            $defaultHeaders['Telnyx-Version'] = Telnyx::$apiVersion;
313
+        }
314
+
315
+        if (Telnyx::$accountId) {
316
+            $defaultHeaders['Telnyx-Account'] = Telnyx::$accountId;
317
+        }
318
+
319
+        if (Telnyx::$enableTelemetry && self::$requestTelemetry != null) {
320
+            $defaultHeaders["X-Telnyx-Client-Telemetry"] = self::_telemetryJson(self::$requestTelemetry);
321
+        }
322
+
323
+        $hasFile = false;
324
+        $hasCurlFile = class_exists('\CURLFile', false);
325
+        foreach ($params as $k => $v) {
326
+            if (is_resource($v)) {
327
+                $hasFile = true;
328
+                $params[$k] = self::_processResourceParam($v, $hasCurlFile);
329
+            } elseif ($hasCurlFile && $v instanceof \CURLFile) {
330
+                $hasFile = true;
331
+            }
332
+        }
333
+
334
+        if ($hasFile) {
335
+            $defaultHeaders['Content-Type'] = 'multipart/form-data';
336
+        } else {
337
+            $defaultHeaders['Content-Type'] = 'application/json';
338
+        }
339
+
340
+        $combinedHeaders = array_merge($defaultHeaders, $headers);
341
+        $rawHeaders = [];
342
+
343
+        foreach ($combinedHeaders as $header => $value) {
344
+            $rawHeaders[] = $header . ': ' . $value;
345
+        }
346
+
347
+        $requestStartMs = Util\Util::currentTimeMillis();
348
+
349
+        list($rbody, $rcode, $rheaders) = $this->httpClient()->request(
350
+            $method,
351
+            $absUrl,
352
+            $rawHeaders,
353
+            $params,
354
+            $hasFile
355
+        );
356
+
357
+        if (array_key_exists('request-id', $rheaders)) {
358
+            self::$requestTelemetry = new RequestTelemetry(
359
+                $rheaders['request-id'],
360
+                Util\Util::currentTimeMillis() - $requestStartMs
361
+            );
362
+        }
363
+
364
+        return [$rbody, $rcode, $rheaders, $myApiKey];
365
+    }
366
+
367
+    /**
368
+     * @param resource $resource
369
+     * @param bool     $hasCurlFile
370
+     *
371
+     * @return \CURLFile|string
372
+     * @throws Error\Api
373
+     */
374
+    private function _processResourceParam($resource, $hasCurlFile)
375
+    {
376
+        if (get_resource_type($resource) !== 'stream') {
377
+            throw new Error\Api(
378
+                'Attempted to upload a resource that is not a stream'
379
+            );
380
+        }
381
+
382
+        $metaData = stream_get_meta_data($resource);
383
+        if ($metaData['wrapper_type'] !== 'plainfile') {
384
+            throw new Error\Api(
385
+                'Only plainfile resource streams are supported'
386
+            );
387
+        }
388
+
389
+        if ($hasCurlFile) {
390
+            // We don't have the filename or mimetype, but the API doesn't care
391
+            return new \CURLFile($metaData['uri']);
392
+        } else {
393
+            return '@'.$metaData['uri'];
394
+        }
395
+    }
396
+
397
+    /**
398
+     * @param string $rbody
399
+     * @param int    $rcode
400
+     * @param array  $rheaders
401
+     *
402
+     * @return mixed
403
+     * @throws Error\Api
404
+     * @throws Error\Authentication
405
+     * @throws Error\Card
406
+     * @throws Error\InvalidRequest
407
+     * @throws Error\Permission
408
+     * @throws Error\RateLimit
409
+     * @throws Error\Idempotency
410
+     */
411
+    private function _interpretResponse($rbody, $rcode, $rheaders)
412
+    {
413
+        $resp = json_decode($rbody, true);
414
+
415
+        // Move [data] to the parent node
416
+        if (isset($resp['data'])) {
417
+            $resp = $resp['data'];
418
+        }
419
+
420
+        $jsonError = json_last_error();
421
+        if ($resp === null && $jsonError !== JSON_ERROR_NONE) {
422
+            $msg = "Invalid response body from API: $rbody "
423
+              . "(HTTP response code was $rcode, json_last_error() was $jsonError)";
424
+            throw new Error\Api($msg, $rcode, $rbody);
425
+        }
426
+
427
+        if ($rcode < 200 || $rcode >= 300) {
428
+            $this->handleErrorResponse($rbody, $rcode, $rheaders, $resp);
429
+        }
430
+        return $resp;
431
+    }
432
+
433
+    /**
434
+     * @static
435
+     *
436
+     * @param HttpClient\ClientInterface $client
437
+     */
438
+    public static function setHttpClient($client)
439
+    {
440
+        self::$_httpClient = $client;
441
+    }
442
+
443
+    /**
444
+     * @static
445
+     *
446
+     * Resets any stateful telemetry data
447
+     */
448
+    public static function resetTelemetry()
449
+    {
450
+        self::$requestTelemetry = null;
451
+    }
452
+
453
+    /**
454
+     * @return HttpClient\ClientInterface
455
+     */
456
+    private function httpClient()
457
+    {
458
+        if (!self::$_httpClient) {
459
+            self::$_httpClient = HttpClient\CurlClient::instance();
460
+        }
461
+        return self::$_httpClient;
462
+    }
463
+}