Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ UNIFI_ACCESS_SSL_VERIFY=false
use Carbon\Carbon;
use GuzzleHttp\Client as GuzzleHttpClient;
use Uxicodev\UnifiAccessApi\API\Enums\VisitReason;
use Uxicodev\UnifiAccessApi\API\Requests\Visitor\VisitorRequest;
use Uxicodev\UnifiAccessApi\API\Requests\Visitor\UpsertVisitorRequest;
use Uxicodev\UnifiAccessApi\UnifiAccessApiFacade;

$unifiClient = UnifiAccessApiFacade::getClient();
$visitorRequest = new VisitorRequest('Jimmy', 'McGill', Carbon::now(), Carbon::now()->addHour(), VisitReason::Others);
$visitorRequest = new UpsertVisitorRequest('Jimmy', 'McGill', Carbon::now(), Carbon::now()->addHour(), VisitReason::Others);
$visitorResponse = $unifiClient->visitor()->create($visitorRequest);
$unifiClient->visitor()->assignQrCode($visitorResponse->data->id);
$tmpFile = $unifiClient->credential()->downloadQrCode($visitorResponse->data->id);
Expand All @@ -58,7 +58,7 @@ $tmpFile = $unifiClient->credential()->downloadQrCode($visitorResponse->data->id
```php
use Carbon\Carbon;
use Uxicodev\UnifiAccessApi\API\Enums\VisitReason;
use Uxicodev\UnifiAccessApi\API\Requests\Visitor\VisitorRequest;
use Uxicodev\UnifiAccessApi\API\Requests\Visitor\UpsertVisitorRequest;
use Uxicodev\UnifiAccessApi\Client\Client as UnifiClient;
use GuzzleHttp\Client as GuzzleHttpClient;

Expand All @@ -75,7 +75,7 @@ $guzzleClient = new GuzzleHttpClient([
]);

$unifiClient = new UnifiClient($guzzleClient);
$visitorRequest = new VisitorRequest('Jimmy', 'McGill', Carbon::now(), Carbon::now()->addHour(), VisitReason::Others);
$visitorRequest = new UpsertVisitorRequest('Jimmy', 'McGill', Carbon::now(), Carbon::now()->addHour(), VisitReason::Others);
$visitorResponse = $unifiClient->visitor()->create($visitorRequest);
$unifiClient->visitor()->assignQrCode($visitorResponse->data->id);
$tmpFile = $unifiClient->credential()->downloadQrCode($visitorResponse->data->id);
Expand Down
27 changes: 27 additions & 0 deletions src/API/Enums/Expand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

namespace Uxicodev\UnifiAccessApi\API\Enums;

/**
* Enum for expand[] query parameter in VisitorClient::all
*
* UniFi Access Requirement: 1.22.16 or later
*
* - none: No object will be returned
* - access_policy
* - resource
* - schedule
* - nfc_card
* - pin_code
*/
enum Expand: string
{
case NONE = 'none';
case ACCESS_POLICY = 'access_policy';
case RESOURCE = 'resource';
case SCHEDULE = 'schedule';
case NFC_CARD = 'nfc_card';
case PIN_CODE = 'pin_code';
}
44 changes: 44 additions & 0 deletions src/API/Requests/Visitor/AllVisitorRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

declare(strict_types=1);

namespace Uxicodev\UnifiAccessApi\API\Requests\Visitor;

use Uxicodev\UnifiAccessApi\API\Enums\Expand;

readonly class AllVisitorRequest
{
public function __construct(
public ?int $status = null,
public ?string $keyword = null,
public ?int $page_num = null,
public ?int $page_size = null,
/** @var Expand[]|null $expand */
public ?array $expand = null,
) {}

/**
* Returns the query string for the request, using http_build_query and correct expand[] handling.
*/
public function toQueryString(): string
{
$query = [];
if ($this->status !== null) {
$query['status'] = $this->status;
}
if ($this->keyword !== null) {
$query['keyword'] = $this->keyword;
}
if ($this->page_num !== null) {
$query['page_num'] = $this->page_num;
}
if ($this->page_size !== null) {
$query['page_size'] = $this->page_size;
}
if ($this->expand) {
$query['expand'] = array_map(fn (Expand $e) => $e->value, $this->expand);
}

return $query ? '?'.http_build_query($query) : '';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
use Uxicodev\UnifiAccessApi\API\ValueObjects\UuidV4;
use Uxicodev\UnifiAccessApi\Exceptions\ValidationException;

readonly class VisitorRequest
readonly class UpsertVisitorRequest
{
/**
* @param ?Collection<int, ResourceRequest> $resources
Expand Down
16 changes: 11 additions & 5 deletions src/API/VisitorClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@

use GuzzleHttp\Exception\GuzzleException;
use InvalidArgumentException;
use Uxicodev\UnifiAccessApi\API\Requests\Visitor\VisitorRequest;
use Uxicodev\UnifiAccessApi\API\Requests\Visitor\AllVisitorRequest;
use Uxicodev\UnifiAccessApi\API\Requests\Visitor\UpsertVisitorRequest;
use Uxicodev\UnifiAccessApi\API\Responses\UnifiResponse;
use Uxicodev\UnifiAccessApi\API\Responses\Visitor\VisitorResponse;
use Uxicodev\UnifiAccessApi\API\Responses\Visitor\VisitorsResponse;
Expand Down Expand Up @@ -35,9 +36,9 @@ public function find(UuidV4 $visitorId): VisitorResponse
* @throws GuzzleException
* @throws UnifiApiErrorException
*/
public function all(): VisitorsResponse
public function all(?AllVisitorRequest $request = null): VisitorsResponse
{
$response = $this->client->get($this::ENDPOINT);
$response = $this->client->get($this::ENDPOINT. ($request !== null ? $request->toQueryString() : ''));

$data = json_decode($response->getBody()->getContents(), true);

Expand All @@ -49,7 +50,7 @@ public function all(): VisitorsResponse
* @throws GuzzleException
* @throws UnifiApiErrorException
*/
public function create(VisitorRequest $request): VisitorResponse
public function create(UpsertVisitorRequest $request): VisitorResponse
{
$response = $this->client->post($this::ENDPOINT, $request->toArray());

Expand All @@ -58,7 +59,12 @@ public function create(VisitorRequest $request): VisitorResponse
return VisitorResponse::fromArray($data);
}

public function update(VisitorRequest $request): VisitorResponse
/**
* @throws GuzzleException
* @throws InvalidResponseException
* @throws UnifiApiErrorException
*/
public function update(UpsertVisitorRequest $request): VisitorResponse
{
if ($request->id === null) {
throw new InvalidArgumentException('Visitor ID is required for update.');
Expand Down
2 changes: 0 additions & 2 deletions tests/API/Requests/System/SystemLogRequestTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
use PHPUnit\Framework\TestCase;
use Uxicodev\UnifiAccessApi\API\Enums\SystemLogTopic;
use Uxicodev\UnifiAccessApi\API\Requests\System\SystemLogRequest;
use Uxicodev\UnifiAccessApi\API\ValueObjects\UuidV4;
use Uxicodev\UnifiAccessApi\Exceptions\ValidationException;

class SystemLogRequestTest extends TestCase
Expand Down Expand Up @@ -64,4 +63,3 @@ public function test_from_array_until_not_after_since(): void
}
}
}

44 changes: 44 additions & 0 deletions tests/API/Requests/Visitor/AllVisitorRequestTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

declare(strict_types=1);

namespace Uxicodev\UnifiAccessApi\Tests\API\Requests\Visitor;

use PHPUnit\Framework\TestCase;
use Uxicodev\UnifiAccessApi\API\Enums\Expand;
use Uxicodev\UnifiAccessApi\API\Requests\Visitor\AllVisitorRequest;

class AllVisitorRequestTest extends TestCase
{
public function test_default_query_string_is_empty(): void
{
$request = new AllVisitorRequest();
$this->assertSame('', $request->toQueryString());
}

public function test_query_string_with_all_params(): void
{
$request = new AllVisitorRequest(
status: 2,
keyword: 'John',
page_num: 3,
page_size: 25,
expand: [Expand::ACCESS_POLICY, Expand::RESOURCE]
);
$query = $request->toQueryString();
$this->assertStringContainsString('status=2', $query);
$this->assertStringContainsString('keyword=John', $query);
$this->assertStringContainsString('page_num=3', $query);
$this->assertStringContainsString('page_size=25', $query);
$this->assertStringContainsString('expand%5B0%5D=access_policy', $query);
$this->assertStringContainsString('expand%5B1%5D=resource', $query);
$this->assertStringStartsWith('?', $query);
}

public function test_query_string_with_empty_expand(): void
{
$request = new AllVisitorRequest(expand: []);
$this->assertSame('', $request->toQueryString());
}
}

8 changes: 4 additions & 4 deletions tests/API/Requests/Visitor/VisitorRequestTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;
use Uxicodev\UnifiAccessApi\API\Enums\VisitReason;
use Uxicodev\UnifiAccessApi\API\Requests\Visitor\VisitorRequest;
use Uxicodev\UnifiAccessApi\API\Requests\Visitor\UpsertVisitorRequest;
use Uxicodev\UnifiAccessApi\Exceptions\ValidationException;

class VisitorRequestTest extends TestCase
Expand All @@ -14,7 +14,7 @@ class VisitorRequestTest extends TestCase
public function construct_throws_error_when_phone_number_is_not_e164_compliant(): void
{
$this->expectException(ValidationException::class);
new VisitorRequest(
new UpsertVisitorRequest(
'John',
'Doe',
now(),
Expand All @@ -36,9 +36,9 @@ public function can_be_constructed_from_array(): void
'mobile_phone' => '+1234567890',
];

$visitorRequest = VisitorRequest::fromArray($data);
$visitorRequest = UpsertVisitorRequest::fromArray($data);

$this->assertInstanceOf(VisitorRequest::class, $visitorRequest);
$this->assertInstanceOf(UpsertVisitorRequest::class, $visitorRequest);
$this->assertEquals('Jane', $visitorRequest->first_name);
$this->assertEquals('Doe', $visitorRequest->last_name);
$this->assertEquals(VisitReason::Business, $visitorRequest->visit_reason);
Expand Down
14 changes: 7 additions & 7 deletions tests/API/VisitorClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
use Orchestra\Testbench\TestCase;
use PHPUnit\Framework\Attributes\Test;
use Uxicodev\UnifiAccessApi\API\Enums\VisitReason;
use Uxicodev\UnifiAccessApi\API\Requests\Visitor\VisitorRequest;
use Uxicodev\UnifiAccessApi\API\Requests\Visitor\UpsertVisitorRequest;
use Uxicodev\UnifiAccessApi\API\ValueObjects\UuidV4;
use Uxicodev\UnifiAccessApi\Client\Client as UnifiClient;
use Uxicodev\UnifiAccessApi\Entities\Visitor\VisitorEntity;
Expand Down Expand Up @@ -95,7 +95,7 @@ public function create_a_visitor_returns_visitor_response(): void

$unifiClient = new UnifiClient($client);

$response = $unifiClient->visitor()->create(new VisitorRequest(
$response = $unifiClient->visitor()->create(new UpsertVisitorRequest(
'Saul',
'Goodman',
Carbon::now(),
Expand All @@ -122,7 +122,7 @@ public function bad_request_response_throws_exception(): void
$unifiClient = new UnifiClient($client);

$this->expectException(InvalidResponseException::class);
$unifiClient->visitor()->create(new VisitorRequest(
$unifiClient->visitor()->create(new UpsertVisitorRequest(
'Saul',
'Goodman',
Carbon::now(),
Expand All @@ -144,7 +144,7 @@ public function non_success_code_in_response_throws_unifi_api_error_exception():
$unifiClient = new UnifiClient($client);

$this->expectException(UnifiApiErrorException::class);
$unifiClient->visitor()->create(new VisitorRequest(
$unifiClient->visitor()->create(new UpsertVisitorRequest(
'Saul',
'Goodman',
Carbon::now(),
Expand All @@ -164,7 +164,7 @@ public function edit_visitor_without_id_throws_error(): void
$unifiClient = new UnifiClient($client);

$this->expectException(InvalidArgumentException::class);
$unifiClient->visitor()->update(new VisitorRequest(
$unifiClient->visitor()->update(new UpsertVisitorRequest(
'Saul',
'Goodman',
Carbon::now(),
Expand All @@ -185,7 +185,7 @@ public function a_visitor_can_be_edited(): void

$unifiClient = new UnifiClient($client);

$response = $unifiClient->visitor()->update(new VisitorRequest(
$response = $unifiClient->visitor()->update(new UpsertVisitorRequest(
'Saul',
'Goodman',
Carbon::now(),
Expand All @@ -212,7 +212,7 @@ public function a_failed_edit_throws_an_exception(): void

$this->expectException(InvalidResponseException::class);

$response = $unifiClient->visitor()->update(new VisitorRequest(
$response = $unifiClient->visitor()->update(new UpsertVisitorRequest(
'Saul',
'Goodman',
Carbon::now(),
Expand Down