Skip to content

Commit d4f2151

Browse files
Add Users Client (#420)
* Hacks for APIcollection (again), logic for 5 endpoints * Move Users into its own namespace * PR review changes, pt 1 * PR review changes, pt 2 * Pass in hydrator * reset verify, make User full DTO * Correct auth, add more tests * Update src/Users/Client.php Co-authored-by: Chris Tankersley <chris@ctankersley.com> * Update src/Users/Client.php Co-authored-by: Chris Tankersley <chris@ctankersley.com> * Update src/Users/ClientFactory.php Co-authored-by: Chris Tankersley <chris@ctankersley.com> * Update src/Users/Client.php Co-authored-by: Chris Tankersley <chris@ctankersley.com> * Update src/Users/ClientFactory.php Co-authored-by: Chris Tankersley <chris@ctankersley.com> * Update src/Users/Client.php Co-authored-by: Chris Tankersley <chris@ctankersley.com> * pass in standard array hydrator --------- Co-authored-by: Chris Tankersley <chris@ctankersley.com>
1 parent b88a1fe commit d4f2151

File tree

14 files changed

+1041
-8
lines changed

14 files changed

+1041
-8
lines changed

phpunit.xml.dist

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@
4141
<testsuite name="meetings">
4242
<directory>test/Meetings</directory>
4343
</testsuite>
44+
<testsuite name="application">
45+
<directory>test/Application</directory>
46+
</testsuite>
47+
<testsuite name="users">
48+
<directory>test/Users</directory>
49+
</testsuite>
4450
</testsuites>
4551
<php>
4652
<ini name='error_reporting' value='E_ALL' />

src/Client.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
use Vonage\SMS\ClientFactory as SMSClientFactory;
5454
use Vonage\Subaccount\ClientFactory as SubaccountClientFactory;
5555
use Vonage\Messages\ClientFactory as MessagesClientFactory;
56+
use Vonage\Users\ClientFactory as UsersClientFactory;
5657
use Vonage\Verify\ClientFactory as VerifyClientFactory;
5758
use Vonage\Verify2\ClientFactory as Verify2ClientFactory;
5859
use Vonage\Verify\Verification;
@@ -85,6 +86,7 @@
8586
* @method Secrets\Client secrets()
8687
* @method SMS\Client sms()
8788
* @method Subaccount\Client subaccount()
89+
* @method Users\Client users()
8890
* @method Verify\Client verify()
8991
* @method Verify2\Client verify2()
9092
* @method Voice\Client voice()
@@ -224,6 +226,7 @@ public function __construct(
224226
'secrets' => SecretsClientFactory::class,
225227
'sms' => SMSClientFactory::class,
226228
'subaccount' => SubaccountClientFactory::class,
229+
'users' => UsersClientFactory::class,
227230
'verify' => VerifyClientFactory::class,
228231
'verify2' => Verify2ClientFactory::class,
229232
'voice' => VoiceClientFactory::class,

src/Entity/IterableAPICollection.php

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ class IterableAPICollection implements ClientAwareInterface, Iterator, Countable
111111
protected bool $noQueryParameters = false;
112112

113113
/**
114-
* User set pgge sixe.
114+
* User set pgge size.
115115
*/
116116
protected ?int $size = null;
117117

@@ -123,6 +123,12 @@ class IterableAPICollection implements ClientAwareInterface, Iterator, Countable
123123

124124
protected $hydrator;
125125

126+
/**
127+
* Used to override pagination to remove it from the URL page query
128+
* but differs from noQueryParameters when you want to use other filters
129+
*/
130+
protected bool $hasPagination = true;
131+
126132
public function getPageIndexKey(): string
127133
{
128134
return $this->pageIndexKey;
@@ -496,7 +502,7 @@ protected function fetchPage($absoluteUri): void
496502
$query[$this->pageSizeKey] = $this->size;
497503
}
498504

499-
if (isset($this->index)) {
505+
if (isset($this->index) && $this->hasPagination()) {
500506
$query[$this->pageIndexKey] = $this->index;
501507
}
502508

@@ -625,4 +631,19 @@ public function setIndex(?int $index): IterableAPICollection
625631

626632
return $this;
627633
}
634+
635+
/**
636+
* @return bool
637+
*/
638+
public function hasPagination(): bool
639+
{
640+
return $this->hasPagination;
641+
}
642+
643+
public function setHasPagination(bool $hasPagination): static
644+
{
645+
$this->hasPagination = $hasPagination;
646+
647+
return $this;
648+
}
628649
}

src/Users/Client.php

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Vonage\Users;
6+
7+
use Vonage\Client\APIClient;
8+
use Vonage\Client\APIResource;
9+
use Vonage\Client\ClientAwareInterface;
10+
use Vonage\Client\ClientAwareTrait;
11+
use Vonage\Client\Exception\Exception as ClientException;
12+
use Vonage\Entity\Filter\EmptyFilter;
13+
use Vonage\Entity\Hydrator\HydratorInterface;
14+
use Vonage\Entity\IterableAPICollection;
15+
use Vonage\Entity\Filter\FilterInterface;
16+
17+
use Vonage\Users\Filter\UserFilter;
18+
use function is_null;
19+
20+
class Client implements ClientAwareInterface, APIClient
21+
{
22+
use ClientAwareTrait;
23+
24+
public function __construct(protected APIResource $api, protected ?HydratorInterface $hydrator = null)
25+
{
26+
}
27+
28+
public function getApiResource(): APIResource
29+
{
30+
return $this->api;
31+
}
32+
33+
public function listUsers(FilterInterface $filter = null): IterableAPICollection
34+
{
35+
if (is_null($filter)) {
36+
$filter = new EmptyFilter();
37+
}
38+
39+
$response = $this->api->search($filter);
40+
$response->setHydrator($this->hydrator);
41+
$response->setPageSizeKey('page_size');
42+
$response->setHasPagination(false);
43+
44+
return $response;
45+
}
46+
47+
public function createUser(User $user): User
48+
{
49+
$response = $this->api->create($user->toArray());
50+
51+
return $this->hydrator->hydrate($response);
52+
}
53+
54+
public function getUser(string $id): User
55+
{
56+
$response = $this->api->get($id);
57+
return $this->hydrator->hydrate($response);
58+
59+
return $returnUser;
60+
}
61+
62+
public function updateUser(User $user): User
63+
{
64+
if (is_null($user->getId())) {
65+
throw new \InvalidArgumentException('User must have an ID set');
66+
}
67+
68+
$response = $this->api->partiallyUpdate($user->getId(), $user->toArray());
69+
70+
return $this->hydrator->hydrate($response);
71+
}
72+
73+
public function deleteUser(string $id): bool
74+
{
75+
try {
76+
$this->api->delete($id);
77+
return true;
78+
} catch (ClientException $exception) {
79+
return false;
80+
}
81+
}
82+
}

src/Users/ClientFactory.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Vonage\Users;
6+
7+
use Psr\Container\ContainerInterface;
8+
use Vonage\Client\APIResource;
9+
use Vonage\Client\Credentials\Handler\KeypairHandler;
10+
use Vonage\Entity\Hydrator\ArrayHydrator;
11+
12+
class ClientFactory
13+
{
14+
public function __invoke(ContainerInterface $container): Client
15+
{
16+
$api = $container->make(APIResource::class);
17+
$api
18+
->setBaseUri('/v1/users')
19+
->setCollectionName('users')
20+
->setAuthHandler(new KeypairHandler());
21+
22+
$hydrator = new ArrayHydrator();
23+
$hydrator->setPrototype(new User());
24+
25+
return new Client($api, $hydrator);
26+
}
27+
}

src/Users/Filter/UserFilter.php

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Vonage\Users\Filter;
6+
7+
use InvalidArgumentException;
8+
use Vonage\Entity\Filter\FilterInterface;
9+
10+
class UserFilter implements FilterInterface
11+
{
12+
public const ORDER_ASC = 'asc';
13+
public const ORDER_DESC = 'desc';
14+
15+
protected ?int $pageSize = null;
16+
17+
protected ?string $order = null;
18+
protected ?string $cursor = null;
19+
20+
public function getQuery(): array
21+
{
22+
$query = [];
23+
24+
if ($this->pageSize !== null) {
25+
$query['page_size'] = $this->getPageSize();
26+
}
27+
28+
if ($this->order !== null) {
29+
$query['order'] = $this->getOrder();
30+
}
31+
32+
if ($this->cursor !== null) {
33+
$query['cursor'] = $this->getCursor();
34+
}
35+
36+
return $query;
37+
}
38+
39+
public function getPageSize(): int
40+
{
41+
return $this->pageSize;
42+
}
43+
44+
public function setPageSize(int $pageSize): static
45+
{
46+
$this->pageSize = $pageSize;
47+
48+
return $this;
49+
}
50+
51+
public function getOrder(): string
52+
{
53+
return $this->order;
54+
}
55+
56+
public function setOrder(string $order): static
57+
{
58+
if ($order !== self::ORDER_ASC && $order !== self::ORDER_DESC) {
59+
throw new InvalidArgumentException('Order must be `asc` or `desc`');
60+
}
61+
62+
$this->order = $order;
63+
64+
return $this;
65+
}
66+
67+
public function getCursor(): ?string
68+
{
69+
return $this->cursor;
70+
}
71+
72+
public function setCursor(?string $cursor): static
73+
{
74+
$this->cursor = $cursor;
75+
76+
return $this;
77+
}
78+
}

0 commit comments

Comments
 (0)