Skip to content

Commit 0bb7c81

Browse files
committed
Refactored Call Collection / Resource and added Sub-Resources:
- Yes, this should not have been a single commit. - Changed `Calls` namespace to `Call` to match the rest of the library. - Should read better "Call Collection, Call Stream, etc". - But perhaps namespace should match client signature (still `$nexmo->calls[$id]->stream();`) - Flattened `Nexmo\Call` namespace. - Added support for steame / talk / dtmf. - Refactored the concept of client / entity to collection / resource. - Now `Nexmo\Call\Collection` - Should perhaps change `Nexmo\Call\Call` to `Nexmo\Call\Resource` - Changed some interfaces / forced changes to `Nexmo\Applicaion\*` - Fixed case of `jsonUnserialize`
1 parent 1b37053 commit 0bb7c81

Some content is hidden

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

45 files changed

+1704
-486
lines changed

README.md

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -249,10 +249,10 @@ $client->calls()->create([
249249
]);
250250
```
251251

252-
Or you can create a `Nexmo\Calls\Call` object, and use that:
252+
Or you can create a `Nexmo\Call\Call` object, and use that:
253253

254254
```php
255-
use Nexmo\Calls\Call;
255+
use Nexmo\Call\Call;
256256
$call = new Call();
257257
$call->setTo('14843331234')
258258
->setFrom('14843335555')
@@ -264,17 +264,40 @@ $client->calls()->create($call);
264264

265265
### Fetching A Call
266266

267-
You can fetch a call using a `Nexmo\Calls\Call` object, or the call's UUID as a string:
267+
You can fetch a call using a `Nexmo\Call\Call` object, or the call's UUID as a string:
268268

269269
```php
270270
$call = $client->calls()->get('3fd4d839-493e-4485-b2a5-ace527aacff3');
271271

272-
$call = new Nexmo\Calls\Call('3fd4d839-493e-4485-b2a5-ace527aacff3');
272+
$call = new Nexmo\Call\Call('3fd4d839-493e-4485-b2a5-ace527aacff3');
273273
$client->calls()->get($call);
274274

275275
echo $call->getDirection();
276276
```
277277

278+
The call collection can also be treated as an array:
279+
280+
```php
281+
echo $client->calls['3fd4d839-493e-4485-b2a5-ace527aacff3']->getDirection();
282+
```
283+
284+
And iterated over:
285+
286+
```php
287+
foreach($client->calls as $call){
288+
echo $call->getDirection();
289+
}
290+
```
291+
292+
With an optional filter:
293+
294+
```php
295+
$filter = new \Nexmo\Call\Filter()->setStatus('completed');
296+
foreach($client->calls($filter) as $call){
297+
echo $call->getDirection();
298+
}
299+
```
300+
278301
### Creating An Application
279302

280303
Application are configuration containers, and you can create one using a simple array structure:
@@ -377,7 +400,7 @@ API Coverage
377400
* [ ] Sending Alerts
378401
* [ ] Campaign Subscription Management
379402
* Voice
380-
* [X] Outbound Calls
403+
* [X] Outbound Call
381404
* [ ] Inbound Call
382405
* [ ] Text-To-Speech Call
383406
* [ ] Text-To-Speech Prompt

src/Application/Client.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,14 @@ class Client implements ClientAwareInterface, CollectionInterface
2121
use ClientAwareTrait;
2222
use CollectionTrait;
2323

24-
public function getCollectionName()
24+
public static function getCollectionName()
2525
{
2626
return 'applications';
2727
}
2828

29-
public function getCollectionPath()
29+
public static function getCollectionPath()
3030
{
31-
return '/v1/' . $this->getCollectionName();
31+
return '/v1/' . self::getCollectionName();
3232
}
3333

3434
public function hydrateEntity($data, $id)
Lines changed: 111 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,28 +6,37 @@
66
* @license https://github.com/Nexmo/nexmo-php/blob/master/LICENSE.txt MIT License
77
*/
88

9-
namespace Nexmo\Calls;
9+
namespace Nexmo\Call;
1010

11+
use Nexmo\Client\ClientAwareInterface;
12+
use Nexmo\Client\ClientAwareTrait;
1113
use Nexmo\Conversations\Conversation;
12-
use Nexmo\Entity\CollectionAwareInterface;
13-
use Nexmo\Entity\CollectionAwareTrait;
1414
use Nexmo\Entity\EntityInterface;
1515
use Nexmo\Entity\JsonResponseTrait;
1616
use Nexmo\Entity\JsonSerializableTrait;
1717
use Nexmo\Entity\JsonUnserializableInterface;
1818
use Nexmo\Entity\NoRequestResponseTrait;
19-
use Nexmo\Entity\Psr7Trait;
19+
use Psr\Http\Message\ResponseInterface;
20+
use Nexmo\Client\Exception;
21+
use Zend\Diactoros\Request;
2022

2123
/**
2224
* Class Call
23-
* @method Collection getCollection()
25+
*
26+
* @property \Nexmo\Call\Stream $stream
27+
* @property \Nexmo\Call\Talk $talk
28+
* @property \Nexmo\Call\Dtmf $dtmf
29+
*
30+
* @method \Nexmo\Call\Stream stream()
31+
* @method \Nexmo\Call\Talk talk()
32+
* @method \Nexmo\Call\Dtmf dtmf()
2433
*/
25-
class Call implements EntityInterface, \JsonSerializable, JsonUnserializableInterface, CollectionAwareInterface
34+
class Call implements EntityInterface, \JsonSerializable, JsonUnserializableInterface, ClientAwareInterface
2635
{
2736
use NoRequestResponseTrait;
2837
use JsonSerializableTrait;
2938
use JsonResponseTrait;
30-
use CollectionAwareTrait;
39+
use ClientAwareTrait;
3140

3241
const WEBHOOK_ANSWER = 'answer';
3342
const WEBHOOK_EVENT = 'event';
@@ -50,19 +59,65 @@ class Call implements EntityInterface, \JsonSerializable, JsonUnserializableInte
5059

5160
protected $data = [];
5261

62+
protected $subresources = [];
63+
5364
public function __construct($id = null)
5465
{
5566
$this->id = $id;
5667
}
5768

5869
public function get()
5970
{
60-
return $this->getCollection()->get($this);
71+
$request = new Request(
72+
\Nexmo\Client::BASE_API . Collection::getCollectionPath() . '/' . $this->getId()
73+
,'GET'
74+
);
75+
76+
$response = $this->getClient()->send($request);
77+
78+
if($response->getStatusCode() != '200'){
79+
throw $this->getException($response);
80+
}
81+
82+
$data = json_decode($response->getBody()->getContents(), true);
83+
$this->jsonUnserialize($data);
84+
85+
return $this;
86+
}
87+
88+
protected function getException(ResponseInterface $response)
89+
{
90+
$body = json_decode($response->getBody()->getContents(), true);
91+
$status = $response->getStatusCode();
92+
93+
if($status >= 400 AND $status < 500) {
94+
$e = new Exception\Request($body['error_title'], $status);
95+
} elseif($status >= 500 AND $status < 600) {
96+
$e = new Exception\Server($body['error_title'], $status);
97+
} else {
98+
$e = new Exception\Exception('Unexpected HTTP Status Code');
99+
}
100+
101+
return $e;
61102
}
62103

63104
public function put($payload)
64105
{
65-
return $this->getCollection()->put($payload, $this);
106+
$request = new Request(
107+
\Nexmo\Client::BASE_API . Collection::getCollectionPath() . '/' . $this->getId()
108+
,'PUT',
109+
'php://temp',
110+
['content-type' => 'application/json']
111+
);
112+
113+
$request->getBody()->write(json_encode($payload));
114+
$response = $this->client->send($request);
115+
116+
if($response->getStatusCode() != '200'){
117+
throw $this->getException($response);
118+
}
119+
120+
return $this;
66121
}
67122

68123
public function getId()
@@ -122,7 +177,7 @@ public function setWebhook($type, $url = null, $method = null)
122177
}
123178

124179
if(is_null($url)){
125-
throw new \InvalidArgumentException('must provide `Nexmo\Calls\Webhook` object, or a type and url: missing url' );
180+
throw new \InvalidArgumentException('must provide `Nexmo\Call\Webhook` object, or a type and url: missing url' );
126181
}
127182

128183
$this->webhooks[$type] = new Webhook($type, $url, $method);
@@ -160,20 +215,64 @@ public function getConversation()
160215
}
161216
}
162217

218+
/**
219+
* Returns true if the resource data is loaded.
220+
*
221+
* Will attempt to load the data if it's not already.
222+
*
223+
* @return bool
224+
*/
163225
protected function lazyLoad()
164226
{
165227
if(!empty($this->data)){
166228
return true;
167229
}
168230

169231
if(isset($this->id)){
170-
$this->getCollection()->get($this);
232+
$this->get($this);
171233
return true;
172234
}
173235

174236
return false;
175237
}
176238

239+
public function __get($name)
240+
{
241+
switch($name){
242+
case 'stream':
243+
case 'talk':
244+
case 'dtmf':
245+
return $this->lazySubresource(ucfirst($name));
246+
default:
247+
throw new \RuntimeException('property does not exist: ' . $name);
248+
}
249+
}
250+
251+
public function __call($name, $arguments)
252+
{
253+
switch($name){
254+
case 'stream':
255+
case 'talk':
256+
case 'dtmf':
257+
$entity = $this->lazySubresource(ucfirst($name));
258+
return call_user_func_array($entity, $arguments);
259+
default:
260+
throw new \RuntimeException('method does not exist: ' . $name);
261+
}
262+
}
263+
264+
protected function lazySubresource($type)
265+
{
266+
if(!isset($this->subresources[$type])){
267+
$class = 'Nexmo\Call\\' . $type;
268+
$instance = new $class($this->getId());
269+
$instance->setClient($this->getClient());
270+
$this->subresources[$type] = $instance;
271+
}
272+
273+
return $this->subresources[$type];
274+
}
275+
177276
public function jsonSerialize()
178277
{
179278
$data = $this->data;
@@ -193,7 +292,7 @@ public function jsonSerialize()
193292
return $data;
194293
}
195294

196-
public function JsonUnserialize(array $json)
295+
public function jsonUnserialize(array $json)
197296
{
198297
$this->data = $json;
199298
$this->id = $json['uuid'];

0 commit comments

Comments
 (0)