Skip to content

Commit 6ee01e6

Browse files
authored
Merge pull request #37 from aligent/feature/implemement-custom-templates-api
Implemement custom templates api
2 parents eb2c359 + 90c5256 commit 6ee01e6

File tree

10 files changed

+274
-25
lines changed

10 files changed

+274
-25
lines changed

RELEASE_NOTES.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
### New Features
22

3-
Until BigCommerce decide to be consistent and include a _Get Customer_ endpoint, add `CustomersApi::getById(int $id)`.
3+
Implement the new (Custom Template Associations)[https://developer.bigcommerce.com/api-reference/store-management/custom-template-associations]
4+
API.
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<?php
2+
3+
namespace BigCommerce\ApiV3\Api\CustomTemplateAssociations;
4+
5+
use BigCommerce\ApiV3\Api\Generic\BatchUpdateResource;
6+
use BigCommerce\ApiV3\Api\Generic\GetAllResources;
7+
use BigCommerce\ApiV3\Api\Generic\V3ApiBase;
8+
use BigCommerce\ApiV3\ResourceModels\CustomTemplateAssociation\CustomTemplateAssociation;
9+
use BigCommerce\ApiV3\ResponseModels\CustomTemplateAssociation\CustomTemplateAssociationsResponse;
10+
use GuzzleHttp\RequestOptions;
11+
12+
class CustomTemplateAssociationsApi extends V3ApiBase
13+
{
14+
use GetAllResources;
15+
use BatchUpdateResource;
16+
17+
private const TEMPLATES_ENDPOINT = '/storefront/custom-template-associations';
18+
19+
public const FILTER_CHANNEL_ID = 'channel_id';
20+
public const FILTER_ENTITY_ID_IN = 'entity_id:in';
21+
public const FILTER_TYPE = 'type';
22+
public const FILTER_IS_VALID = 'is_valid';
23+
24+
public const DELETE_QUERY_ID_IN = 'id:in';
25+
public const DELETE_QUERY_ENTITY_ID_IN = 'entity_id:in';
26+
public const DELETE_QUERY_CHANNEL_ID = 'channel_id';
27+
public const DELETE_QUERY_TYPE = 'type';
28+
29+
protected function maxBatchSize(): int
30+
{
31+
return 100;
32+
}
33+
34+
public function getAll(array $filters = [], int $page = 1, int $limit = 250): CustomTemplateAssociationsResponse
35+
{
36+
return new CustomTemplateAssociationsResponse($this->getAllResources($filters, $page, $limit));
37+
}
38+
39+
/**
40+
* @param CustomTemplateAssociation[] $templateAssociations
41+
* @return CustomTemplateAssociationsResponse
42+
*/
43+
public function batchUpdate(array $templateAssociations): CustomTemplateAssociationsResponse
44+
{
45+
return CustomTemplateAssociationsResponse::buildFromMultipleResponses(
46+
$this->batchUpdateResource($templateAssociations)
47+
);
48+
}
49+
50+
public function multipleResourcesEndpoint(): string
51+
{
52+
return self::TEMPLATES_ENDPOINT;
53+
}
54+
55+
public function multipleResourceUrl(): string
56+
{
57+
return $this->multipleResourcesEndpoint();
58+
}
59+
60+
public function delete(array $query): void
61+
{
62+
$this->getClient()->getRestClient()->delete(
63+
$this->multipleResourceUrl(),
64+
[
65+
RequestOptions::QUERY => $query
66+
]
67+
);
68+
}
69+
70+
public function deleteByIds(array $ids): void
71+
{
72+
$this->delete([
73+
self::DELETE_QUERY_ID_IN => $ids
74+
]);
75+
}
76+
77+
public function deleteByChannelId(int $channelId): void
78+
{
79+
$this->delete([
80+
self::DELETE_QUERY_CHANNEL_ID => $channelId
81+
]);
82+
}
83+
84+
public function deleteByEntityIds(string $type, array $ids): void
85+
{
86+
$this->delete([
87+
self::DELETE_QUERY_ENTITY_ID_IN => $ids,
88+
self::DELETE_QUERY_TYPE => $type,
89+
]);
90+
}
91+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
namespace BigCommerce\ApiV3\Api\Generic;
4+
5+
use BigCommerce\ApiV3\Client;
6+
use BigCommerce\ApiV3\ResponseModels\PaginatedResponse;
7+
use GuzzleHttp\RequestOptions;
8+
use Psr\Http\Message\ResponseInterface;
9+
10+
trait BatchUpdateResource
11+
{
12+
abstract public function batchUpdate(array $resources): PaginatedResponse;
13+
abstract public function multipleResourcesEndpoint(): string;
14+
abstract public function getClient(): Client;
15+
16+
protected function maxBatchSize(): int
17+
{
18+
return 10;
19+
}
20+
21+
/**
22+
* @param array $resources
23+
* @return ResponseInterface[]
24+
*/
25+
protected function batchUpdateResource(array $resources): array
26+
{
27+
$chunks = array_chunk($resources, $this->maxBatchSize());
28+
$responses = [];
29+
foreach ($chunks as $chunk) {
30+
$responses[] = $this->getClient()->getRestClient()->put(
31+
$this->multipleResourcesEndpoint(),
32+
[
33+
RequestOptions::JSON => $chunk,
34+
]
35+
);
36+
}
37+
38+
return $responses;
39+
}
40+
}

src/BigCommerce/Api/Generic/ResourceWithBatchUpdateApi.php

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,5 @@
88

99
abstract class ResourceWithBatchUpdateApi extends ResourceApi
1010
{
11-
protected const MAX_BATCH_SIZE = 10;
12-
13-
abstract public function batchUpdate(array $resources): PaginatedResponse;
14-
15-
/**
16-
* @param array $resources
17-
* @return ResponseInterface[]
18-
* @throws \GuzzleHttp\Exception\GuzzleException
19-
*/
20-
protected function batchUpdateResource(array $resources): array
21-
{
22-
$chunks = array_chunk($resources, self::MAX_BATCH_SIZE);
23-
$responses = [];
24-
foreach ($chunks as $chunk) {
25-
$responses[] = $this->getClient()->getRestClient()->put(
26-
$this->multipleResourcesEndpoint(),
27-
[
28-
RequestOptions::JSON => $chunk,
29-
]
30-
);
31-
}
32-
33-
return $responses;
34-
}
11+
use BatchUpdateResource;
3512
}

src/BigCommerce/Client.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use BigCommerce\ApiV3\Api\Scripts\ScriptsApi;
1111
use BigCommerce\ApiV3\Api\Themes\ThemesApi;
1212
use BigCommerce\ApiV3\Api\Widgets\WidgetsApi;
13+
use BigCommerce\ApiV3\Api\CustomTemplateAssociations\CustomTemplateAssociationsApi;
1314
use GuzzleHttp\HandlerStack;
1415
use GuzzleHttp\Middleware;
1516

@@ -159,4 +160,9 @@ public function content(): WidgetsApi
159160
{
160161
return $this->widgets();
161162
}
163+
164+
public function customTemplateAssociations(): CustomTemplateAssociationsApi
165+
{
166+
return new CustomTemplateAssociationsApi($this);
167+
}
162168
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
namespace BigCommerce\ApiV3\ResourceModels\CustomTemplateAssociation;
4+
5+
use BigCommerce\ApiV3\ResourceModels\ResourceModel;
6+
7+
class CustomTemplateAssociation extends ResourceModel
8+
{
9+
public const TYPE_PRODUCT = 'product';
10+
public const TYPE_CATEGORY = 'category';
11+
public const TYPE_BRAND = 'brand';
12+
public const TYPE_PAGE = 'page';
13+
14+
public int $id;
15+
public int $channel_id;
16+
public string $entity_type;
17+
public int $entity_id;
18+
public string $file_name;
19+
public ?bool $is_valid;
20+
public string $date_created;
21+
public string $date_modified;
22+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
namespace BigCommerce\ApiV3\ResponseModels\CustomTemplateAssociation;
4+
5+
use BigCommerce\ApiV3\ResponseModels\PaginatedBatchableResponse;
6+
use BigCommerce\ApiV3\ResourceModels\CustomTemplateAssociation\CustomTemplateAssociation;
7+
8+
class CustomTemplateAssociationsResponse extends PaginatedBatchableResponse
9+
{
10+
/**
11+
* @return CustomTemplateAssociation[]
12+
*/
13+
public function getCustomTemplateAssociations(): array
14+
{
15+
return $this->getData();
16+
}
17+
18+
protected function resourceClass(): string
19+
{
20+
return CustomTemplateAssociation::class;
21+
}
22+
}

src/BigCommerce/ResponseModels/Customer/SubscribersResponse.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ public function getSubscribers(): array
1414
{
1515
return $this->getData();
1616
}
17+
1718
protected function resourceClass(): string
1819
{
1920
return Subscriber::class;
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
3+
namespace BigCommerce\Tests\Api\CustomTemplateAssociation;
4+
5+
use BigCommerce\ApiV3\Api\CustomTemplateAssociations\CustomTemplateAssociationsApi;
6+
use BigCommerce\ApiV3\ResourceModels\CustomTemplateAssociation\CustomTemplateAssociation;
7+
use BigCommerce\Tests\BigCommerceApiTest;
8+
9+
class CustomTemplateAssociationsApiTest extends BigCommerceApiTest
10+
{
11+
public function testCanGetAssociations()
12+
{
13+
$this->setReturnData('templates__get_all.json');
14+
15+
$response = $this->getApi()->customTemplateAssociations()->getAll();
16+
$this->assertEquals(5, $response->getPagination()->count);
17+
$this->assertEquals('custom-product-1.html', $response->getCustomTemplateAssociations()[0]->file_name);
18+
}
19+
20+
public function testCanDeleteAssociation()
21+
{
22+
$this->setReturnData(self::EMPTY_RESPONSE, 204);
23+
24+
$customTemplateAssocApi = $this->getApi()->customTemplateAssociations();
25+
$customTemplateAssocApi->deleteByChannelId(1);
26+
$this->setReturnData(self::EMPTY_RESPONSE, 204);
27+
$customTemplateAssocApi->deleteByIds([1, 2, 3]);
28+
$this->setReturnData(self::EMPTY_RESPONSE, 204);
29+
$customTemplateAssocApi->deleteByEntityIds(CustomTemplateAssociation::TYPE_CATEGORY, [4, 5, 6]);
30+
$this->assertTrue(true);
31+
}
32+
33+
public function testCanUpsertAssociation()
34+
{
35+
$this->setReturnData('templates__get_all.json');
36+
$templateAssociationOne = new CustomTemplateAssociation((object)[
37+
"id" => 1,
38+
"channel_id" => 1,
39+
"entity_type" => "product",
40+
"entity_id" => 123,
41+
"file_name" => "custom-product-1.html",
42+
]);
43+
44+
$templateAssociationTwo = new CustomTemplateAssociation((object)[
45+
"id" => 2,
46+
"channel_id" => 12345,
47+
"entity_type" => "page",
48+
"entity_id" => 123,
49+
"file_name" => "custom-page.html",
50+
]);
51+
52+
$this->getApi()->customTemplateAssociations()->batchUpdate([
53+
$templateAssociationOne, $templateAssociationTwo
54+
]);
55+
56+
$this->assertTrue(true);
57+
}
58+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"data": [
3+
{
4+
"id": 1,
5+
"channel_id": 1,
6+
"entity_type": "product",
7+
"entity_id": 123,
8+
"file_name": "custom-product-1.html"
9+
},
10+
{
11+
"id": 2,
12+
"channel_id": 12345,
13+
"entity_type": "page",
14+
"entity_id": 123,
15+
"file_name": "custom-page.html"
16+
}
17+
],
18+
"meta": {
19+
"pagination": {
20+
"total": 246,
21+
"count": 5,
22+
"per_page": 5,
23+
"current_page": 1,
24+
"total_pages": 50,
25+
"links": {
26+
"next": "?limit=5&page=2",
27+
"current": "?limit=5&page=1"
28+
}
29+
}
30+
}
31+
}

0 commit comments

Comments
 (0)