diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 570f1d33..28b23ff7 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,3 +1,4 @@ ### New Features -Until BigCommerce decide to be consistent and include a _Get Customer_ endpoint, add `CustomersApi::getById(int $id)`. +Implement the new (Custom Template Associations)[https://developer.bigcommerce.com/api-reference/store-management/custom-template-associations] +API. \ No newline at end of file diff --git a/src/BigCommerce/Api/CustomTemplateAssociations/CustomTemplateAssociationsApi.php b/src/BigCommerce/Api/CustomTemplateAssociations/CustomTemplateAssociationsApi.php new file mode 100644 index 00000000..fa093004 --- /dev/null +++ b/src/BigCommerce/Api/CustomTemplateAssociations/CustomTemplateAssociationsApi.php @@ -0,0 +1,91 @@ +getAllResources($filters, $page, $limit)); + } + + /** + * @param CustomTemplateAssociation[] $templateAssociations + * @return CustomTemplateAssociationsResponse + */ + public function batchUpdate(array $templateAssociations): CustomTemplateAssociationsResponse + { + return CustomTemplateAssociationsResponse::buildFromMultipleResponses( + $this->batchUpdateResource($templateAssociations) + ); + } + + public function multipleResourcesEndpoint(): string + { + return self::TEMPLATES_ENDPOINT; + } + + public function multipleResourceUrl(): string + { + return $this->multipleResourcesEndpoint(); + } + + public function delete(array $query): void + { + $this->getClient()->getRestClient()->delete( + $this->multipleResourceUrl(), + [ + RequestOptions::QUERY => $query + ] + ); + } + + public function deleteByIds(array $ids): void + { + $this->delete([ + self::DELETE_QUERY_ID_IN => $ids + ]); + } + + public function deleteByChannelId(int $channelId): void + { + $this->delete([ + self::DELETE_QUERY_CHANNEL_ID => $channelId + ]); + } + + public function deleteByEntityIds(string $type, array $ids): void + { + $this->delete([ + self::DELETE_QUERY_ENTITY_ID_IN => $ids, + self::DELETE_QUERY_TYPE => $type, + ]); + } +} diff --git a/src/BigCommerce/Api/Generic/BatchUpdateResource.php b/src/BigCommerce/Api/Generic/BatchUpdateResource.php new file mode 100644 index 00000000..f80e2d88 --- /dev/null +++ b/src/BigCommerce/Api/Generic/BatchUpdateResource.php @@ -0,0 +1,40 @@ +maxBatchSize()); + $responses = []; + foreach ($chunks as $chunk) { + $responses[] = $this->getClient()->getRestClient()->put( + $this->multipleResourcesEndpoint(), + [ + RequestOptions::JSON => $chunk, + ] + ); + } + + return $responses; + } +} diff --git a/src/BigCommerce/Api/Generic/ResourceWithBatchUpdateApi.php b/src/BigCommerce/Api/Generic/ResourceWithBatchUpdateApi.php index 4744c877..2b9f49f6 100644 --- a/src/BigCommerce/Api/Generic/ResourceWithBatchUpdateApi.php +++ b/src/BigCommerce/Api/Generic/ResourceWithBatchUpdateApi.php @@ -8,28 +8,5 @@ abstract class ResourceWithBatchUpdateApi extends ResourceApi { - protected const MAX_BATCH_SIZE = 10; - - abstract public function batchUpdate(array $resources): PaginatedResponse; - - /** - * @param array $resources - * @return ResponseInterface[] - * @throws \GuzzleHttp\Exception\GuzzleException - */ - protected function batchUpdateResource(array $resources): array - { - $chunks = array_chunk($resources, self::MAX_BATCH_SIZE); - $responses = []; - foreach ($chunks as $chunk) { - $responses[] = $this->getClient()->getRestClient()->put( - $this->multipleResourcesEndpoint(), - [ - RequestOptions::JSON => $chunk, - ] - ); - } - - return $responses; - } + use BatchUpdateResource; } diff --git a/src/BigCommerce/Client.php b/src/BigCommerce/Client.php index b39aa656..4e3d4659 100644 --- a/src/BigCommerce/Client.php +++ b/src/BigCommerce/Client.php @@ -10,6 +10,7 @@ use BigCommerce\ApiV3\Api\Scripts\ScriptsApi; use BigCommerce\ApiV3\Api\Themes\ThemesApi; use BigCommerce\ApiV3\Api\Widgets\WidgetsApi; +use BigCommerce\ApiV3\Api\CustomTemplateAssociations\CustomTemplateAssociationsApi; use GuzzleHttp\HandlerStack; use GuzzleHttp\Middleware; @@ -159,4 +160,9 @@ public function content(): WidgetsApi { return $this->widgets(); } + + public function customTemplateAssociations(): CustomTemplateAssociationsApi + { + return new CustomTemplateAssociationsApi($this); + } } diff --git a/src/BigCommerce/ResourceModels/CustomTemplateAssociation/CustomTemplateAssociation.php b/src/BigCommerce/ResourceModels/CustomTemplateAssociation/CustomTemplateAssociation.php new file mode 100644 index 00000000..733e0eaf --- /dev/null +++ b/src/BigCommerce/ResourceModels/CustomTemplateAssociation/CustomTemplateAssociation.php @@ -0,0 +1,22 @@ +getData(); + } + + protected function resourceClass(): string + { + return CustomTemplateAssociation::class; + } +} diff --git a/src/BigCommerce/ResponseModels/Customer/SubscribersResponse.php b/src/BigCommerce/ResponseModels/Customer/SubscribersResponse.php index 06bcf3c3..c9922217 100644 --- a/src/BigCommerce/ResponseModels/Customer/SubscribersResponse.php +++ b/src/BigCommerce/ResponseModels/Customer/SubscribersResponse.php @@ -14,6 +14,7 @@ public function getSubscribers(): array { return $this->getData(); } + protected function resourceClass(): string { return Subscriber::class; diff --git a/tests/BigCommerce/Api/CustomTemplateAssociations/CustomTemplateAssociationsApiTest.php b/tests/BigCommerce/Api/CustomTemplateAssociations/CustomTemplateAssociationsApiTest.php new file mode 100644 index 00000000..264ce1f1 --- /dev/null +++ b/tests/BigCommerce/Api/CustomTemplateAssociations/CustomTemplateAssociationsApiTest.php @@ -0,0 +1,58 @@ +setReturnData('templates__get_all.json'); + + $response = $this->getApi()->customTemplateAssociations()->getAll(); + $this->assertEquals(5, $response->getPagination()->count); + $this->assertEquals('custom-product-1.html', $response->getCustomTemplateAssociations()[0]->file_name); + } + + public function testCanDeleteAssociation() + { + $this->setReturnData(self::EMPTY_RESPONSE, 204); + + $customTemplateAssocApi = $this->getApi()->customTemplateAssociations(); + $customTemplateAssocApi->deleteByChannelId(1); + $this->setReturnData(self::EMPTY_RESPONSE, 204); + $customTemplateAssocApi->deleteByIds([1, 2, 3]); + $this->setReturnData(self::EMPTY_RESPONSE, 204); + $customTemplateAssocApi->deleteByEntityIds(CustomTemplateAssociation::TYPE_CATEGORY, [4, 5, 6]); + $this->assertTrue(true); + } + + public function testCanUpsertAssociation() + { + $this->setReturnData('templates__get_all.json'); + $templateAssociationOne = new CustomTemplateAssociation((object)[ + "id" => 1, + "channel_id" => 1, + "entity_type" => "product", + "entity_id" => 123, + "file_name" => "custom-product-1.html", + ]); + + $templateAssociationTwo = new CustomTemplateAssociation((object)[ + "id" => 2, + "channel_id" => 12345, + "entity_type" => "page", + "entity_id" => 123, + "file_name" => "custom-page.html", + ]); + + $this->getApi()->customTemplateAssociations()->batchUpdate([ + $templateAssociationOne, $templateAssociationTwo + ]); + + $this->assertTrue(true); + } +} diff --git a/tests/BigCommerce/responses/templates__get_all.json b/tests/BigCommerce/responses/templates__get_all.json new file mode 100644 index 00000000..558b66cc --- /dev/null +++ b/tests/BigCommerce/responses/templates__get_all.json @@ -0,0 +1,31 @@ +{ + "data": [ + { + "id": 1, + "channel_id": 1, + "entity_type": "product", + "entity_id": 123, + "file_name": "custom-product-1.html" + }, + { + "id": 2, + "channel_id": 12345, + "entity_type": "page", + "entity_id": 123, + "file_name": "custom-page.html" + } + ], + "meta": { + "pagination": { + "total": 246, + "count": 5, + "per_page": 5, + "current_page": 1, + "total_pages": 50, + "links": { + "next": "?limit=5&page=2", + "current": "?limit=5&page=1" + } + } + } +}