Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add category level attributes api support #3

Merged
merged 12 commits into from
Mar 22, 2024
Merged
Show file tree
Hide file tree
Changes from 8 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
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
php: ['8.0', '8.1', '8.2']
php: ['8.1', '8.2', '8.3']
composer: ['--prefer-lowest', '']
steps:
- name: Setup PHP
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ facade
│ └─ new - Obtain new session token
├─ category/ - Category endpoint
│ ├─ get - Get product listing category
│ └─ getAttributes - Get system-defined attributes based on category ID
│ ├─ getAttributes - Get system-defined attributes based on category ID
│ └─ getLevelAttribute - Get next-level attribute based on category, attribute and value ID (e.g. car_model values)
└─ product/ - Product endpoint
└─ getGroup - Get product group
```
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
}
],
"require": {
"php": "^8",
"php": "^8.1",
"ext-json": "*",
"ext-mbstring": "*",
"symfony/http-client": "^5.4 || ^6"
Expand Down
7 changes: 5 additions & 2 deletions src/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,14 @@ private function throwOnError(array $data): void
$errorResponse = $data['error_response'] ?? null;

if ($errorResponse !== null) {
$subMessage = $errorResponse['sub_msg'] ?? null;
$subCode = $errorResponse['sub_code'] ?? null;

throw new AlibabaException(
$errorResponse['msg'],
(int) $errorResponse['code'],
$errorResponse['sub_msg'],
$errorResponse['sub_code'],
$subMessage,
$subCode,
);
}
}
Expand Down
27 changes: 27 additions & 0 deletions src/Endpoint/CategoryEndpoint.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Kyto\Alibaba\Factory\CategoryFactory;
use Kyto\Alibaba\Model\Category;
use Kyto\Alibaba\Model\CategoryAttribute;
use Kyto\Alibaba\Model\CategoryLevelAttribute;

class CategoryEndpoint
{
Expand Down Expand Up @@ -68,4 +69,30 @@ public function getAttributes(string $categoryId): array

return $result;
}

/**
* Get next-level attribute based on category, attribute and optionally level attribute value ID.
* @link https://developer.alibaba.com/en/doc.htm?spm=a2728.12183079.k2mwm9fd.1.4b3630901WuQWY#?docType=2&docId=48659
*
* @param ?string $valueId provide null to fetch first level
*/
public function getLevelAttribute(
string $categoryId,
string $attributeId,
?string $valueId = null
): CategoryLevelAttribute {
$attributeValueRequest = [
'cat_id' => $categoryId,
'attr_id' => $attributeId,
'value_id' => $valueId ?? '0'
];

$data = $this->client->request([
'method' => 'alibaba.icbu.category.level.attr.get',
'attribute_value_request' => json_encode($attributeValueRequest)
Dominik-Czulak marked this conversation as resolved.
Show resolved Hide resolved
]);

$attribute = $data['alibaba_icbu_category_level_attr_get_response']['result_list'];
return $this->categoryFactory->createLevelAttribute($attribute);
}
}
12 changes: 12 additions & 0 deletions src/Enum/InputType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

namespace Kyto\Alibaba\Enum;

enum InputType: string
{
case INPUT = 'input';
case MULTI_SELECT = 'multi_select';
case SINGLE_SELECT = 'single_select';
}
15 changes: 15 additions & 0 deletions src/Enum/ShowType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

declare(strict_types=1);

namespace Kyto\Alibaba\Enum;

enum ShowType: string
{
case CHECK_BOX = 'check_box'; // multi_select
case GROUP_TABLE = 'group_table'; // single_select
case INPUT = 'input'; // input (string)
case INTERVAL = 'interval'; // input (number)
case LIST_BOX = 'list_box'; // single_select
case MODEL_NUMBERS = 'model_numbers'; // input (string)
}
11 changes: 11 additions & 0 deletions src/Enum/ValueType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

declare(strict_types=1);

namespace Kyto\Alibaba\Enum;

enum ValueType: string
{
case NUMBER = 'number';
case STRING = 'string';
}
13 changes: 8 additions & 5 deletions src/Exception/AlibabaException.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,23 @@ class AlibabaException extends \RuntimeException
public function __construct(
string $message,
int $code,
private string $subMessage,
private string $subCode,
private ?string $subMessage,
private ?string $subCode,
Dominik-Czulak marked this conversation as resolved.
Show resolved Hide resolved
?\Throwable $previous = null
) {
$message = sprintf('%s. Sub-code: "%s". Sub-message: "%s".', $message, $this->subCode, $this->subMessage);
$subCodePart = $this->subCode !== null ? sprintf(' Sub-code: "%s".', $this->subCode) : null;
$subMessagePart = $this->subMessage !== null ? sprintf(' Sub-message: "%s".', $this->subMessage) : null;
$message = sprintf('%s.%s%s', $message, $subCodePart, $subMessagePart);

parent::__construct($message, $code, $previous);
}

public function getSubMessage(): string
public function getSubMessage(): ?string
{
return $this->subMessage;
}

public function getSubCode(): string
public function getSubCode(): ?string
{
return $this->subCode;
}
Expand Down
49 changes: 43 additions & 6 deletions src/Factory/CategoryFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@

namespace Kyto\Alibaba\Factory;

use Kyto\Alibaba\Enum\InputType;
use Kyto\Alibaba\Enum\ShowType;
use Kyto\Alibaba\Enum\ValueType;
use Kyto\Alibaba\Model\CategoryLevelAttribute;
use Kyto\Alibaba\Model\CategoryLevelAttributeValue;
use Kyto\Alibaba\Util\Formatter;
use Kyto\Alibaba\Model\Category;
use Kyto\Alibaba\Model\CategoryAttribute;
Expand All @@ -15,7 +20,7 @@
class CategoryFactory
{
/**
* @param mixed[] $data
* @param array<string, mixed> $data
*/
public function createCategory(array $data): Category
{
Expand All @@ -34,7 +39,7 @@ public function createCategory(array $data): Category
}

/**
* @param mixed[] $data
* @param array<string, mixed> $data
*/
public function createAttribute(array $data): CategoryAttribute
{
Expand All @@ -44,9 +49,9 @@ public function createAttribute(array $data): CategoryAttribute
$model->name = (string) $data['en_name'];
$model->isRequired = (bool) $data['required'];

$model->inputType = (string) $data['input_type'];
$model->showType = (string) $data['show_type'];
$model->valueType = (string) $data['value_type'];
$model->inputType = InputType::from($data['input_type']);
$model->showType = ShowType::from($data['show_type']);
$model->valueType = ValueType::from($data['value_type']);

$model->isSku = (bool) $data['sku_attribute'];
$model->hasCustomizeImage = (bool) $data['customize_image'];
Expand All @@ -64,7 +69,7 @@ public function createAttribute(array $data): CategoryAttribute
}

/**
* @param mixed[] $data
* @param array<string, mixed> $data
*/
public function createAttributeValue(array $data): CategoryAttributeValue
{
Expand All @@ -77,4 +82,36 @@ public function createAttributeValue(array $data): CategoryAttributeValue

return $model;
}

/**
* @param array<string, mixed> $data
*/
public function createLevelAttribute(array $data): CategoryLevelAttribute
Dominik-Czulak marked this conversation as resolved.
Show resolved Hide resolved
{
$model = new CategoryLevelAttribute();

$model->id = (string) $data['property_id'];
$model->name = (string) $data['property_en_name'];

$model->values = [];
$decodedValues = json_decode($data['values'], true);
Dominik-Czulak marked this conversation as resolved.
Show resolved Hide resolved
foreach ($decodedValues as $value) {
$model->values[] = $this->createLevelAttributeValue($value);
}

return $model;
}

/**
* @param array<string, mixed> $data
*/
public function createLevelAttributeValue(array $data): CategoryLevelAttributeValue
Dominik-Czulak marked this conversation as resolved.
Show resolved Hide resolved
{
$model = new CategoryLevelAttributeValue();
$model->name = (string) $data['name'];
$model->id = (string) $data['id'];
$model->isLeaf = isset($data['leaf']);

return $model;
}
}
11 changes: 7 additions & 4 deletions src/Model/CategoryAttribute.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,19 @@

namespace Kyto\Alibaba\Model;

use Kyto\Alibaba\Enum\InputType;
use Kyto\Alibaba\Enum\ShowType;
use Kyto\Alibaba\Enum\ValueType;

class CategoryAttribute
{
public string $id;
public string $name;
public bool $isRequired;

// TODO: change to enums once all values would be known
public string $inputType; // Known values: single_select, multi_select, input
public string $showType; // Known values: list_box (single_select), check_box (multi_select), input (input)
public string $valueType; // Known values: string, number
public InputType $inputType;
public ShowType $showType;
public ValueType $valueType;

public bool $isSku;
public bool $hasCustomizeImage;
Expand Down
14 changes: 14 additions & 0 deletions src/Model/CategoryLevelAttribute.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

declare(strict_types=1);

namespace Kyto\Alibaba\Model;

class CategoryLevelAttribute
{
public string $id;
public string $name;

/** @var CategoryLevelAttributeValue[] */
public array $values;
}
12 changes: 12 additions & 0 deletions src/Model/CategoryLevelAttributeValue.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

namespace Kyto\Alibaba\Model;

class CategoryLevelAttributeValue
{
public string $id;
public string $name;
public bool $isLeaf;
}
27 changes: 27 additions & 0 deletions tests/Endpoint/CategoryEndpointTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Kyto\Alibaba\Factory\CategoryFactory;
use Kyto\Alibaba\Model\Category;
use Kyto\Alibaba\Model\CategoryAttribute;
use Kyto\Alibaba\Model\CategoryLevelAttribute;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;

Expand Down Expand Up @@ -98,4 +99,30 @@ public function testGetAttributes(): void
$actual = $this->categoryEndpoint->getAttributes($id);
self::assertSame($result, $actual);
}

public function testGetLevelAttributes(): void
{
$attributeValueRequestBody = '{"cat_id":"1","attr_id":"1","value_id":"0"}';
$levelAttribute = ['LevelAttribute'];
$data = ['alibaba_icbu_category_level_attr_get_response' => ['result_list' => $levelAttribute]];

$this->client
->expects(self::once())
->method('request')
->with([
'method' => 'alibaba.icbu.category.level.attr.get',
'attribute_value_request' => $attributeValueRequestBody,
])
->willReturn($data);

$result = new CategoryLevelAttribute();

$this->categoryFactory
->expects(self::once())
->method('createLevelAttribute')
->willReturn($result);

$actual = $this->categoryEndpoint->getLevelAttribute('1', '1', null);
self::assertSame($result, $actual);
}
}
Loading
Loading