From a24c10ea99c7ad195f4ebfa89b61f950813ca6f1 Mon Sep 17 00:00:00 2001 From: Jens Schulze Date: Wed, 1 Dec 2021 13:21:24 +0100 Subject: [PATCH 1/3] add product variant by sku accessor --- .../Product/ProductVariantSkuAccessor.php | 64 +++++++++++++++++++ test/unit/ProductProjectionsTest.php | 28 ++++---- test/unit/products.json | 36 ++++++++++- 3 files changed, 115 insertions(+), 13 deletions(-) create mode 100644 src/Api/Models/Product/ProductVariantSkuAccessor.php diff --git a/src/Api/Models/Product/ProductVariantSkuAccessor.php b/src/Api/Models/Product/ProductVariantSkuAccessor.php new file mode 100644 index 00000000000..70d72a8c338 --- /dev/null +++ b/src/Api/Models/Product/ProductVariantSkuAccessor.php @@ -0,0 +1,64 @@ + + */ + private $skuIndex = []; + + /** + * @psalm-assert ProductProjection|ProductData $product + * @psalm-param mixed $product + * @param $product + * @throws InvalidArgumentException + */ + private function __construct($product) + { + if (!($product instanceof ProductProjection || $product instanceof ProductData)) { + throw new InvalidArgumentException(""); + } + $variants = $product->getVariants(); + $variants = $variants != null ? $variants->toArray() ?? [] : []; + $masterVariant = $product->getMasterVariant(); + if ($masterVariant != null) { + array_unshift($variants, $masterVariant); + } + + /** + * @var array $variants + */ + $this->variants = new ProductVariantCollection($variants); + + /** + * @var ProductVariant $variant + */ + foreach ($this->variants as $index => $variant) { + $this->skuIndex[(string)$variant->getSku()] = (int)$index; + } + } + + public function getBySku(string $sku): ?ProductVariant { + return $this->variants->at($this->skuIndex[$sku]); + } + + /** + * @psalm-return callable(ProductProjection|ProductData): self + */ + public static function of() + { + return function ($productProjection): ProductVariantSkuAccessor { + return new self($productProjection); + }; + } +} diff --git a/test/unit/ProductProjectionsTest.php b/test/unit/ProductProjectionsTest.php index 2324548cad9..7e41e71be7c 100644 --- a/test/unit/ProductProjectionsTest.php +++ b/test/unit/ProductProjectionsTest.php @@ -2,14 +2,11 @@ namespace Commercetools\UnitTest; -use Commercetools\Api\Client\ApiRequestBuilder; -use Commercetools\Api\Models\Product\Attribute; use Commercetools\Api\Models\Product\AttributeAccessor; use Commercetools\Api\Models\Product\ProductProjection; -use Commercetools\Api\Models\Product\ProductProjectionModel; -use Commercetools\Api\Models\Product\ProductProjectionPagedQueryResponse; use Commercetools\Api\Models\Product\ProductProjectionPagedQueryResponseModel; -use GuzzleHttp\ClientInterface; +use Commercetools\Api\Models\Product\ProductProjectionVariantSkuAccessor; +use Commercetools\Api\Models\Product\ProductVariantSkuAccessor; use PHPUnit\Framework\TestCase; class ProductProjectionsTest extends TestCase @@ -19,12 +16,7 @@ public function testAttributeMapping() $productsJson = json_decode(file_get_contents(__DIR__ . "/products.json")); $products = ProductProjectionPagedQueryResponseModel::fromStdClass($productsJson)->getResults(); -// /** @var ClientInterface $client */ -// $builder = new ApiRequestBuilder($client); -// $productResponse = $builder->withProjectKey("")->productProjections()->get()->execute(); -// $products = $productResponse->getResults(); - -// /** @var ProductProjection $product */ + /** @var ProductProjection $product */ foreach ($products as $product) { foreach ($product->getMasterVariant()->getAttributes() as $attribute) { /** @var AttributeAccessor $attrAccessor */ @@ -39,4 +31,18 @@ public function testAttributeMapping() } } } + + public function testSkuMapping() + { + $productsJson = json_decode(file_get_contents(__DIR__ . "/products.json")); + $products = ProductProjectionPagedQueryResponseModel::fromStdClass($productsJson)->getResults(); + + $variantsAccessor = $products[0]->with(ProductVariantSkuAccessor::of()); + self::assertSame(1, $variantsAccessor->getBySku("prod1-abc")->getId()); + self::assertSame(2, $variantsAccessor->getBySku("prod1-def")->getId()); + + $variantsAccessor = $products[1]->with(ProductVariantSkuAccessor::of()); + self::assertSame(1, $variantsAccessor->getBySku("prod2-abc")->getId()); + self::assertSame(2, $variantsAccessor->getBySku("prod2-def")->getId()); + } } diff --git a/test/unit/products.json b/test/unit/products.json index 6c420e1ae8e..07e0d552e8c 100644 --- a/test/unit/products.json +++ b/test/unit/products.json @@ -20,6 +20,7 @@ }, "masterVariant": { "id": 1, + "sku": "prod1-abc", "prices": [], "images": [], "attributes": [ @@ -33,7 +34,24 @@ } ] }, - "variants": [], + "variants": [ + { + "id": 2, + "sku": "prod1-def", + "prices": [], + "images": [], + "attributes": [ + { + "name": "text1", + "value": { + "it": "italian1", + "de": "german1", + "en": "englisch1" + } + } + ] + } + ], "searchKeywords": {}, "hasStagedChanges": false, "published": true, @@ -62,6 +80,7 @@ "masterVariant": { "id": 1, "prices": [], + "sku": "prod2-abc", "images": [], "attributes": [ { @@ -70,7 +89,20 @@ } ] }, - "variants": [], + "variants": [ + { + "id": 2, + "prices": [], + "sku": "prod2-def", + "images": [], + "attributes": [ + { + "name": "aboolean", + "value": true + } + ] + } + ], "searchKeywords": {}, "hasStagedChanges": true, "published": true, From e0a3dcca815ffbbf187eee8e94d38b431b898b59 Mon Sep 17 00:00:00 2001 From: Jens Schulze Date: Wed, 1 Dec 2021 13:25:54 +0100 Subject: [PATCH 2/3] add null check --- src/Api/Models/Product/ProductVariantSkuAccessor.php | 3 +++ test/unit/ProductProjectionsTest.php | 1 + 2 files changed, 4 insertions(+) diff --git a/src/Api/Models/Product/ProductVariantSkuAccessor.php b/src/Api/Models/Product/ProductVariantSkuAccessor.php index 70d72a8c338..459fdcb55ef 100644 --- a/src/Api/Models/Product/ProductVariantSkuAccessor.php +++ b/src/Api/Models/Product/ProductVariantSkuAccessor.php @@ -49,6 +49,9 @@ private function __construct($product) } public function getBySku(string $sku): ?ProductVariant { + if (!isset($this->skuIndex[$sku])) { + return null; + } return $this->variants->at($this->skuIndex[$sku]); } diff --git a/test/unit/ProductProjectionsTest.php b/test/unit/ProductProjectionsTest.php index 7e41e71be7c..baaec35e6c2 100644 --- a/test/unit/ProductProjectionsTest.php +++ b/test/unit/ProductProjectionsTest.php @@ -39,6 +39,7 @@ public function testSkuMapping() $variantsAccessor = $products[0]->with(ProductVariantSkuAccessor::of()); self::assertSame(1, $variantsAccessor->getBySku("prod1-abc")->getId()); + self::assertNull($variantsAccessor->getBySku("non-existant")); self::assertSame(2, $variantsAccessor->getBySku("prod1-def")->getId()); $variantsAccessor = $products[1]->with(ProductVariantSkuAccessor::of()); From c7acbaca8b0ddcebd932f068fe1ecca90b175419 Mon Sep 17 00:00:00 2001 From: Jens Schulze Date: Wed, 1 Dec 2021 13:29:59 +0100 Subject: [PATCH 3/3] style fix --- src/Api/Models/Product/ProductVariantSkuAccessor.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Api/Models/Product/ProductVariantSkuAccessor.php b/src/Api/Models/Product/ProductVariantSkuAccessor.php index 459fdcb55ef..e5455047f5e 100644 --- a/src/Api/Models/Product/ProductVariantSkuAccessor.php +++ b/src/Api/Models/Product/ProductVariantSkuAccessor.php @@ -48,7 +48,8 @@ private function __construct($product) } } - public function getBySku(string $sku): ?ProductVariant { + public function getBySku(string $sku): ?ProductVariant + { if (!isset($this->skuIndex[$sku])) { return null; }