Skip to content

Commit 173010e

Browse files
authored
Begin refactor of anystack related code (#155)
* begin refactor of anystack related code * remove unused Anystack::getLicense()
1 parent e6de85e commit 173010e

File tree

12 files changed

+232
-119
lines changed

12 files changed

+232
-119
lines changed

app/Actions/Licenses/DeleteLicense.php

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,15 @@
77

88
class DeleteLicense
99
{
10-
public function __construct(
11-
protected Anystack $anystack
12-
) {}
13-
1410
/**
1511
* Handle the deletion of a license.
1612
*/
1713
public function handle(License $license, bool $deleteFromAnystack = true): bool
1814
{
1915
if ($deleteFromAnystack) {
20-
$this->anystack->deleteLicense($license->anystack_product_id, $license->anystack_id);
16+
Anystack::api()
17+
->license($license->anystack_id, $license->anystack_product_id)
18+
->delete();
2119
}
2220

2321
return $license->delete();

app/Actions/Licenses/SuspendLicense.php

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,14 @@
77

88
class SuspendLicense
99
{
10-
public function __construct(
11-
protected Anystack $anystack
12-
) {}
13-
1410
/**
1511
* Handle the suspension of a license.
1612
*/
1713
public function handle(License $license): License
1814
{
19-
$this->anystack->suspendLicense($license->anystack_product_id, $license->anystack_id);
15+
Anystack::api()
16+
->license($license->anystack_id, $license->anystack_product_id)
17+
->suspend();
2018

2119
$license->update([
2220
'is_suspended' => true,

app/Filament/Resources/LicenseResource/Pages/EditLicense.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,10 @@ protected function getHeaderActions(): array
3535
->visible(fn () => filled($this->record->anystack_id))
3636
->action(function () {
3737
try {
38-
$response = app(Anystack::class)->getLicense($this->record->anystack_product_id, $this->record->anystack_id);
38+
$response = Anystack::api()
39+
->license($this->record->anystack_id, $this->record->anystack_product_id)
40+
->retrieve();
41+
3942
dispatch_sync(new UpsertLicenseFromAnystackLicense($response->json('data')));
4043

4144
Notification::make()

app/Filament/Resources/LicenseResource/Pages/ListLicenses.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,10 @@ protected function getHeaderActions(): array
4141
])
4242
->action(function (array $data) {
4343
try {
44-
$productId = Subscription::Mini->anystackProductId();
45-
$response = app(Anystack::class)->getLicense($productId, $data['anystack_id']);
44+
$response = Anystack::api()
45+
->license($data['anystack_id'], Subscription::Mini->anystackProductId()) // any plan's product id will work
46+
->retrieve();
47+
4648
$licenseData = $response->json('data');
4749

4850
dispatch_sync(new UpsertLicenseFromAnystackLicense($licenseData));

app/Filament/Resources/SubscriptionItemResource/Pages/ViewSubscriptionItem.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,10 @@ protected function getHeaderActions(): array
4242
])
4343
->action(function (array $data) {
4444
try {
45-
$productId = Subscription::Mini->anystackProductId();
46-
$response = app(Anystack::class)->getLicense($productId, $data['anystack_id']);
45+
$response = Anystack::api()
46+
->license($data['anystack_id'], Subscription::Mini->anystackProductId()) // any plan's product id will work
47+
->retrieve();
48+
4749
$licenseData = $response->json('data');
4850

4951
dispatch_sync(new UpsertLicenseFromAnystackLicense($licenseData));

app/Services/Anystack/Anystack.php

Lines changed: 16 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2,69 +2,34 @@
22

33
namespace App\Services\Anystack;
44

5-
use Illuminate\Http\Client\PendingRequest;
6-
use Illuminate\Http\Client\Response;
7-
use Illuminate\Support\Facades\Http;
5+
use App\Models\User;
6+
use Illuminate\Http\Client\HttpClientException;
87

9-
class Anystack
8+
final class Anystack
109
{
1110
/**
1211
* Create a new Anystack API client.
1312
*/
14-
public function client(): PendingRequest
13+
public static function api(?string $apiKey = null): AnystackClient
1514
{
16-
return Http::withToken(config('services.anystack.key'))
17-
->acceptJson()
18-
->asJson();
19-
}
15+
if (! ($apiKey ??= config('services.anystack.key'))) {
16+
throw new HttpClientException('Anystack API key is not configured.');
17+
}
2018

21-
/**
22-
* Suspend a license on AnyStack.
23-
*
24-
* @param string $productId The AnyStack product ID
25-
* @param string $licenseId The AnyStack license ID
26-
* @return Response The API response
27-
*
28-
* @throws \Illuminate\Http\Client\RequestException If the request fails
29-
*/
30-
public function suspendLicense(string $productId, string $licenseId): Response
31-
{
32-
return $this->client()
33-
->patch("https://api.anystack.sh/v1/products/{$productId}/licenses/{$licenseId}", [
34-
'suspended' => true,
35-
])
36-
->throw();
19+
return app(AnystackClient::class, ['apiKey' => $apiKey]);
3720
}
3821

39-
/**
40-
* Delete a license on AnyStack.
41-
*
42-
* @param string $productId The AnyStack product ID
43-
* @param string $licenseId The AnyStack license ID
44-
* @return Response The API response
45-
*
46-
* @throws \Illuminate\Http\Client\RequestException If the request fails
47-
*/
48-
public function deleteLicense(string $productId, string $licenseId): Response
22+
public static function findContact(string $contactUuid): ?User
4923
{
50-
return $this->client()
51-
->delete("https://api.anystack.sh/v1/products/{$productId}/licenses/{$licenseId}")
52-
->throw();
24+
return User::query()
25+
->where('anystack_contact_id', $contactUuid)
26+
->first();
5327
}
5428

55-
/**
56-
* Retrieve a license from AnyStack.
57-
*
58-
* @param string $productId The AnyStack product ID
59-
* @param string $licenseId The AnyStack license ID
60-
* @return Response The API response
61-
*
62-
* @throws \Illuminate\Http\Client\RequestException If the request fails
63-
*/
64-
public function getLicense(string $productId, string $licenseId): Response
29+
public static function findContactOrFail(string $contactUuid): User
6530
{
66-
return $this->client()
67-
->get("https://api.anystack.sh/v1/products/{$productId}/licenses/{$licenseId}")
68-
->throw();
31+
return User::query()
32+
->where('anystack_contact_id', $contactUuid)
33+
->firstOrFail();
6934
}
7035
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
namespace App\Services\Anystack;
4+
5+
use App\Enums\Subscription;
6+
use App\Services\Anystack\Resources\License;
7+
use App\Services\Anystack\Resources\Licenses;
8+
use App\Services\Anystack\Resources\Products;
9+
use Illuminate\Http\Client\PendingRequest;
10+
use Illuminate\Support\Facades\Http;
11+
12+
final class AnystackClient
13+
{
14+
public function __construct(
15+
public readonly string $apiKey,
16+
) {}
17+
18+
public function products(): Products
19+
{
20+
return new Products($this->prepareRequest());
21+
}
22+
23+
/**
24+
* Get the licenses resource for a product on Anystack.
25+
*/
26+
public function licenses(?string $productId = null): Licenses
27+
{
28+
$productId ??= Subscription::Mini->anystackProductId();
29+
30+
return new Licenses($this->prepareRequest(), $productId);
31+
}
32+
33+
public function license(string $id, ?string $productId = null): License
34+
{
35+
return $this->licenses($productId)->id($id);
36+
}
37+
38+
/**
39+
* Create a new Anystack API client.
40+
*/
41+
public function prepareRequest(): PendingRequest
42+
{
43+
return Http::withToken($this->apiKey)
44+
->baseUrl('https://api.anystack.sh/v1/')
45+
->acceptJson()
46+
->asJson()
47+
->throw();
48+
}
49+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
namespace App\Services\Anystack\Resources;
4+
5+
use Illuminate\Http\Client\PendingRequest;
6+
use Illuminate\Http\Client\Response;
7+
8+
final class License
9+
{
10+
public function __construct(
11+
private readonly PendingRequest $client,
12+
private readonly string $productId,
13+
private readonly string $licenseId,
14+
) {}
15+
16+
public function retrieve(): Response
17+
{
18+
return $this->client->get($this->baseUrl());
19+
}
20+
21+
public function update(array $data): Response
22+
{
23+
return $this->client->patch($this->baseUrl(), $data);
24+
}
25+
26+
public function suspend(bool $suspend = true): Response
27+
{
28+
return $this->client->patch($this->baseUrl(), [
29+
'suspended' => $suspend,
30+
]);
31+
}
32+
33+
public function renew(): Response
34+
{
35+
return $this->client->patch("{$this->baseUrl()}/renew");
36+
}
37+
38+
public function delete(): Response
39+
{
40+
return $this->client->delete($this->baseUrl());
41+
}
42+
43+
private function baseUrl(): string
44+
{
45+
return "products/{$this->productId}/licenses/{$this->licenseId}";
46+
}
47+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
namespace App\Services\Anystack\Resources;
4+
5+
use Illuminate\Http\Client\PendingRequest;
6+
use Illuminate\Http\Client\Response;
7+
8+
final class Licenses
9+
{
10+
public function __construct(
11+
private readonly PendingRequest $client,
12+
private readonly string $productId,
13+
) {}
14+
15+
public function all(?int $page = 1): Response
16+
{
17+
return $this->client->get($this->url(), [
18+
'page' => $page,
19+
]);
20+
}
21+
22+
public function create(array $data): Response
23+
{
24+
return $this->client->post($this->url(), $data);
25+
}
26+
27+
public function id(string $licenseId): License
28+
{
29+
return new License(
30+
$this->client,
31+
$this->productId,
32+
$licenseId,
33+
);
34+
}
35+
36+
private function url(): string
37+
{
38+
return "products/{$this->productId}/licenses";
39+
}
40+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
namespace App\Services\Anystack\Resources;
4+
5+
use Illuminate\Http\Client\PendingRequest;
6+
use Illuminate\Http\Client\Response;
7+
8+
final class Product
9+
{
10+
public function __construct(
11+
private readonly PendingRequest $client,
12+
private readonly string $productId,
13+
) {}
14+
15+
public function licenses(): Licenses
16+
{
17+
return new Licenses($this->client, $this->productId);
18+
}
19+
20+
public function retrieve(): Response
21+
{
22+
return $this->client->get($this->baseUrl());
23+
}
24+
25+
private function baseUrl(): string
26+
{
27+
return "products/{$this->productId}";
28+
}
29+
}

0 commit comments

Comments
 (0)