Skip to content

Commit df1cd77

Browse files
Merge pull request #192 from Nexmo/v2-alpha
SDK v2 Release
2 parents a27c3ad + 291748a commit df1cd77

File tree

169 files changed

+1988
-863
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

169 files changed

+1988
-863
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
composer.lock
33
vendor
44
logs
5+
.php_cs.cache

.travis.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
language: php
22
php:
3-
- '5.6'
4-
- '7.0'
53
- '7.1'
64
- '7.2'
75
- '7.3'

README.md

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Client Library for PHP
55
[![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE.txt)
66
[![codecov](https://codecov.io/gh/Nexmo/nexmo-php/branch/master/graph/badge.svg)](https://codecov.io/gh/Nexmo/nexmo-php)
77

8-
*This library requires a minimum PHP version of 5.6*
8+
*This library requires a minimum PHP version of 7.1*
99

1010
This is the PHP client library for use Nexmo's API. To use this, you'll need a Nexmo account. Sign up [for free at
1111
nexmo.com][signup].
@@ -655,6 +655,43 @@ $response = $client->account()->updateConfig([
655655
print_r($response->data);
656656
```
657657

658+
### Get Information About a Number
659+
660+
The [Number Insights API](https://developer.nexmo.com/api/number-insight) allows a user to check that a number is valid and to find out more about how to use it.
661+
662+
#### Basic and Standard Usage
663+
664+
You can use either the `basic()` or `standard()` methods (an `advanced()` method is available, but it is recommended to use the async option to get advanced info), like this:
665+
666+
```php
667+
668+
try {
669+
$insights = $client->insights()->basic(PHONE_NUMBER);
670+
671+
echo $insights['national_format_number'];
672+
} catch (Exception $e) {
673+
// for the Nexmo-specific exceptions, try the `getEntity()` method for more diagnostic information
674+
}
675+
```
676+
677+
The data is returned in the `$insights` variable in the example above.
678+
679+
#### Advanced Usage
680+
681+
To get advanced insights, use the async feature and supply a URL for the webhook to be sent to:
682+
683+
```php
684+
try {
685+
$client->insights()->advancedAsync(PHONE_NUMBER, 'http://example.com/webhooks/number-insights');
686+
} catch (Exception $e) {
687+
// for the Nexmo-specific exceptions, try the `getEntity()` method for more diagnostic information
688+
}
689+
```
690+
691+
Check out the [documentation](https://developer.nexmo.com/number-insight/code-snippets/number-insight-advanced-async-callback) for what to expect in the incoming webhook containing the data you requested.
692+
693+
694+
658695
## Troubleshooting
659696

660697

@@ -679,7 +716,7 @@ curl.cainfo = "/etc/pki/tls/cacert.pem"
679716
curl.cainfo = "C:\php\extras\ssl\cacert.pem"
680717
```
681718

682-
### Pass custom Guzzle client
719+
### Pass custom HTTP client
683720

684721
We allow use of any HTTPlug adapter, so you can create a client with alternative configuration if you need it, for example to take account of a local proxy, or deal with something else specific to your setup.
685722

@@ -690,6 +727,15 @@ $adapter_client = new Http\Adapter\Guzzle6\Client(new GuzzleHttp\Client(['timeou
690727
$nexmo_client = new Nexmo\Client(new Nexmo\Client\Credentials\Basic($api_key, $api_secret), [], $adapter_client);
691728
```
692729

730+
### Accessing Response Data
731+
732+
When things go wrong, you'll receive an `Exception`. The Nexmo exception classes `Nexmo\Client\Exception\Request` and `Nexmo\Client\Exception\Server` support an additional `getEntity()` method which you can use in addition to `getCode()` and `getMessage()` to find out more about what went wrong. The entity returned will typically be an object related to the operation, or the response object from the API call.
733+
734+
### Composer installation fails due to Guzzle Adapter
735+
736+
If you have a conflicting package installation that cannot co-exist with our recommended `php-http/guzzle6-adapter` package, then you may install the package `nexmo/client-core` along with any package that satisfies the `php-http/client-implementation` requirement.
737+
738+
See the [Packagist page for client-implementation](https://packagist.org/providers/php-http/client-implementation) for options.
693739

694740
Contributing
695741
------------

composer.json

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"name": "nexmo/client",
2+
"name": "nexmo/client-core",
33
"description": "PHP Client for using Nexmo's API.",
44
"license": "MIT",
55
"type": "library",
@@ -9,23 +9,39 @@
99
"email": "tim@nexmo.com",
1010
"role": "Developer",
1111
"homepage": "http://twitter.com/tjlytle"
12+
},
13+
{
14+
"name": "Michael Heap",
15+
"email": "michael.heap@vonage.com",
16+
"role": "Developer"
17+
},
18+
{
19+
"name": "Lorna Mitchell",
20+
"email": "lorna.mitchell@vonage.com",
21+
"role": "Developer"
22+
},
23+
{
24+
"name": "Chris Tankersley",
25+
"email": "chris.tankersley@vonage.com",
26+
"role": "Developer"
1227
}
1328
],
1429
"support": {
1530
"email": "devrel@nexmo.com"
1631
},
1732
"require": {
18-
"php": ">=5.6",
33+
"php": ">=7.1",
1934
"php-http/client-implementation": "^1.0",
2035
"zendframework/zend-diactoros": "^1.8.4 || ^2.0",
21-
"php-http/guzzle6-adapter": "^1.0",
22-
"lcobucci/jwt": "^3.2"
36+
"lcobucci/jwt": "^3.2",
37+
"ocramius/package-versions": "^1.4"
2338
},
2439
"require-dev": {
25-
"phpunit/phpunit": "^5.7",
40+
"phpunit/phpunit": "^7.4",
2641
"php-http/mock-client": "^0.3.0",
27-
"estahn/phpunit-json-assertions": "^1.0.0",
28-
"squizlabs/php_codesniffer": "^3.1"
42+
"estahn/phpunit-json-assertions": "^3.0.0",
43+
"squizlabs/php_codesniffer": "^3.1",
44+
"php-http/guzzle6-adapter": "^1.0"
2945
},
3046
"autoload": {
3147
"psr-4": {
@@ -37,5 +53,8 @@
3753
"Nexmo\\": "test/",
3854
"NexmoTest\\": "test/"
3955
}
56+
},
57+
"replace": {
58+
"nexmo/client": "^2.0"
4059
}
4160
}

src/Account/Balance.php

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,19 @@
77
use Nexmo\Entity\JsonSerializableInterface;
88
use Nexmo\Entity\JsonUnserializableInterface;
99

10-
class Balance implements JsonSerializableInterface, JsonUnserializableInterface, ArrayAccess {
10+
/**
11+
* @todo Have the JSON unserialize/serialize keys match with $this->data keys
12+
*/
13+
class Balance implements JsonSerializableInterface, JsonUnserializableInterface, ArrayAccess
14+
{
15+
/**
16+
* @var array
17+
*/
18+
public $data;
19+
20+
/**
21+
* @todo Have these take null values, since we offer an unserialize option to populate
22+
*/
1123
public function __construct($balance, $autoReload)
1224
{
1325
$this->data['balance'] = $balance;
@@ -32,7 +44,7 @@ public function jsonUnserialize(array $json)
3244
];
3345
}
3446

35-
function jsonSerialize()
47+
public function jsonSerialize()
3648
{
3749
return $this->data;
3850
}
@@ -56,4 +68,4 @@ public function offsetUnset($offset)
5668
{
5769
throw new Exception('Balance is read only');
5870
}
59-
}
71+
}

src/Account/Client.php

Lines changed: 57 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
use Zend\Diactoros\Request;
1111
use Nexmo\Client\Exception;
1212

13-
13+
/**
14+
* @todo Unify the exception handling to avoid duplicated code and logic (ie: getPrefixPricing())
15+
*/
1416
class Client implements ClientAwareInterface
1517
{
1618
use ClientAwareTrait;
@@ -36,7 +38,7 @@ public function getPrefixPricing($prefix)
3638
if ($codeCategory != 2) {
3739
if ($codeCategory == 4) {
3840
throw new Exception\Request($body['error-code-label']);
39-
}else if ($codeCategory == 5) {
41+
} elseif ($codeCategory == 5) {
4042
throw new Exception\Server($body['error-code-label']);
4143
}
4244
}
@@ -72,6 +74,9 @@ public function getVoicePrice($country)
7274
return $voicePrice;
7375
}
7476

77+
/**
78+
* @todo This should return an empty result instead of throwing an Exception on no results
79+
*/
7580
protected function makePricingRequest($country, $pricingType)
7681
{
7782
$queryString = http_build_query([
@@ -94,9 +99,11 @@ protected function makePricingRequest($country, $pricingType)
9499
return json_decode($rawBody, true);
95100
}
96101

102+
/**
103+
* @todo This needs further investigated to see if '' can even be returned from this endpoint
104+
*/
97105
public function getBalance()
98106
{
99-
100107
$request = new Request(
101108
$this->getClient()->getRestUrl() . '/account/get-balance',
102109
'GET',
@@ -123,23 +130,22 @@ public function topUp($trx)
123130
];
124131

125132
$request = new Request(
126-
$this->getClient()->getRestUrl() . '/account/top-up'
127-
,'POST'
128-
, 'php://temp'
129-
, ['content-type' => 'application/x-www-form-urlencoded']
133+
$this->getClient()->getRestUrl() . '/account/top-up',
134+
'POST',
135+
'php://temp',
136+
['content-type' => 'application/x-www-form-urlencoded']
130137
);
131138

132139
$request->getBody()->write(http_build_query($body));
133140
$response = $this->client->send($request);
134141

135-
if($response->getStatusCode() != '200'){
142+
if ($response->getStatusCode() != '200') {
136143
throw $this->getException($response);
137144
}
138145
}
139146

140147
public function getConfig()
141148
{
142-
143149
$request = new Request(
144150
$this->getClient()->getRestUrl() . '/account/settings',
145151
'POST',
@@ -169,11 +175,11 @@ public function updateConfig($options)
169175
{
170176
// supported options are SMS Callback and DR Callback
171177
$params = [];
172-
if(isset($options['sms_callback_url'])) {
178+
if (isset($options['sms_callback_url'])) {
173179
$params['moCallBackUrl'] = $options['sms_callback_url'];
174180
}
175181

176-
if(isset($options['dr_callback_url'])) {
182+
if (isset($options['dr_callback_url'])) {
177183
$params['drCallBackUrl'] = $options['dr_callback_url'];
178184
}
179185

@@ -187,7 +193,7 @@ public function updateConfig($options)
187193
$request->getBody()->write(http_build_query($params));
188194
$response = $this->client->send($request);
189195

190-
if($response->getStatusCode() != '200'){
196+
if ($response->getStatusCode() != '200') {
191197
throw $this->getException($response);
192198
}
193199

@@ -211,13 +217,13 @@ public function updateConfig($options)
211217

212218
public function listSecrets($apiKey)
213219
{
214-
$body = $this->get( $this->getClient()->getApiUrl() . '/accounts/'.$apiKey.'/secrets');
220+
$body = $this->get($this->getClient()->getApiUrl() . '/accounts/'.$apiKey.'/secrets');
215221
return SecretCollection::fromApi($body);
216222
}
217223

218224
public function getSecret($apiKey, $secretId)
219225
{
220-
$body = $this->get( $this->getClient()->getApiUrl() . '/accounts/'.$apiKey.'/secrets/'. $secretId);
226+
$body = $this->get($this->getClient()->getApiUrl() . '/accounts/'.$apiKey.'/secrets/'. $secretId);
221227
return Secret::fromApi($body);
222228
}
223229

@@ -228,10 +234,10 @@ public function createSecret($apiKey, $newSecret)
228234
];
229235

230236
$request = new Request(
231-
$this->getClient()->getApiUrl() . '/accounts/'.$apiKey.'/secrets'
232-
,'POST'
233-
, 'php://temp'
234-
, ['content-type' => 'application/json']
237+
$this->getClient()->getApiUrl() . '/accounts/'.$apiKey.'/secrets',
238+
'POST',
239+
'php://temp',
240+
['content-type' => 'application/json']
235241
);
236242

237243
$request->getBody()->write(json_encode($body));
@@ -247,10 +253,10 @@ public function createSecret($apiKey, $newSecret)
247253
public function deleteSecret($apiKey, $secretId)
248254
{
249255
$request = new Request(
250-
$this->getClient()->getApiUrl() . '/accounts/'.$apiKey.'/secrets/'. $secretId
251-
,'DELETE'
252-
, 'php://temp'
253-
, ['content-type' => 'application/json']
256+
$this->getClient()->getApiUrl() . '/accounts/'.$apiKey.'/secrets/'. $secretId,
257+
'DELETE',
258+
'php://temp',
259+
['content-type' => 'application/json']
254260
);
255261

256262
$response = $this->client->send($request);
@@ -263,12 +269,13 @@ public function deleteSecret($apiKey, $secretId)
263269
// This returns a 204, so no response body
264270
}
265271

266-
protected function get($url) {
267-
$request = new Request(
268-
$url
269-
,'GET'
270-
, 'php://temp'
271-
, ['content-type' => 'application/json']
272+
protected function get($url)
273+
{
274+
$request = new Request(
275+
$url,
276+
'GET',
277+
'php://temp',
278+
['content-type' => 'application/json']
272279
);
273280

274281
$response = $this->client->send($request);
@@ -281,20 +288,35 @@ protected function get($url) {
281288
return $body;
282289
}
283290

291+
/**
292+
* Generates an appropriate Exception message and object based on HTTP response
293+
* This has a bit of logic to it since different error messages have a different
294+
* reponse format.
295+
*
296+
* @return Exception
297+
*/
284298
protected function getException(ResponseInterface $response, $application = null)
285299
{
286300
$body = json_decode($response->getBody()->getContents(), true);
287301
$status = $response->getStatusCode();
288302

289-
if($status >= 400 AND $status < 500) {
290-
$e = new Exception\Request($body['error_title'], $status);
291-
} elseif($status >= 500 AND $status < 600) {
292-
$e = new Exception\Server($body['error_title'], $status);
293-
} else {
294-
$e = new Exception\Exception('Unexpected HTTP Status Code');
303+
$errorMessage = "Unexpected HTTP Status Code";
304+
if (array_key_exists('error_title', $body)) {
305+
$errorMessage = $body['error_title'];
306+
} elseif (array_key_exists('error-code-label', $body)) {
307+
$errorMessage = $body['error-code-label'];
295308
}
296309

310+
$e = new Exception\Exception($errorMessage);
311+
if ($status >= 400 && $status < 500) {
312+
$e = new Exception\Request($errorMessage, $status);
313+
} elseif ($status >= 500 && $status < 600) {
314+
$e = new Exception\Server($errorMessage, $status);
315+
}
316+
317+
$response->getBody()->rewind();
318+
$e->setEntity($response);
319+
297320
return $e;
298321
}
299-
300322
}

0 commit comments

Comments
 (0)