Skip to content

Commit b8657d0

Browse files
committed
Enrich product sent to Clerk.io
1 parent 8d69572 commit b8657d0

File tree

5 files changed

+146
-58
lines changed

5 files changed

+146
-58
lines changed

config/services/serializer.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
'$productVariantPricesCalculator' => service('sylius.calculator.product_variant_price'),
5858
'$urlGenerator' => service('router'),
5959
'$cacheManager' => service('liip_imagine.cache.manager'),
60+
'$fallbackLocale' => param('kernel.default_locale'),
6061
])
6162
->tag('serializer.normalizer', ['priority' => 100])
6263
;
@@ -67,6 +68,7 @@
6768
'$productVariantPricesCalculator' => service('sylius.calculator.product_variant_price'),
6869
'$urlGenerator' => service('router'),
6970
'$cacheManager' => service('liip_imagine.cache.manager'),
71+
'$fallbackLocale' => param('kernel.default_locale'),
7072
])
7173
->tag('serializer.normalizer', ['priority' => 100])
7274
;

src/DataSyncInfrastructure/Normalizer/CommonProductNormalizerTrait.php

Lines changed: 94 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,25 @@
55
namespace Webgriffe\SyliusClerkPlugin\DataSyncInfrastructure\Normalizer;
66

77
use Liip\ImagineBundle\Imagine\Cache\CacheManager;
8+
use Sylius\Component\Core\Model\CatalogPromotionInterface;
89
use Sylius\Component\Core\Model\ChannelInterface;
910
use Sylius\Component\Core\Model\ProductImageInterface;
1011
use Sylius\Component\Core\Model\ProductInterface;
1112
use Sylius\Component\Core\Model\ProductTranslationInterface;
1213
use Sylius\Component\Core\Model\ProductVariantInterface;
1314
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
15+
use Webgriffe\SyliusClerkPlugin\DataSyncInfrastructure\Normalizer\Event\ProductVariantNormalizerEvent;
1416
use Webmozart\Assert\Assert;
1517

18+
/**
19+
* @psalm-import-type clerkIoProductData from ProductVariantNormalizerEvent
20+
*/
1621
trait CommonProductNormalizerTrait
1722
{
23+
abstract private function getImageFilterToApply(): string;
24+
25+
abstract private function getFallbackLocale(): string;
26+
1827
abstract private function getUrlGenerator(): UrlGeneratorInterface;
1928

2029
abstract private function getCacheManager(): CacheManager;
@@ -45,7 +54,7 @@ private function getMainImage(ProductInterface $product, ?ProductVariantInterfac
4554
return null;
4655
}
4756

48-
public function getUrlOfImage(ProductImageInterface $productMainImage, ChannelInterface $channel): string
57+
private function getUrlOfImage(ProductImageInterface $productMainImage, ChannelInterface $channel): string
4958
{
5059
$channelRequestContext = $this->getUrlGenerator()->getContext();
5160
$previousHost = $channelRequestContext->getHost();
@@ -58,7 +67,7 @@ public function getUrlOfImage(ProductImageInterface $productMainImage, ChannelIn
5867

5968
$imageUrl = $this->getCacheManager()->getBrowserPath(
6069
$imagePath,
61-
$this->imageFilterToApply,
70+
$this->getImageFilterToApply(),
6271
);
6372

6473
$channelRequestContext->setHost($previousHost);
@@ -104,4 +113,87 @@ private function getCategoryIds(ProductInterface $product): array
104113

105114
return $categoryIds;
106115
}
116+
117+
/**
118+
* @psalm-suppress InvalidReturnType
119+
*
120+
* @param clerkIoProductData $productData
121+
*
122+
* @return clerkIoProductData
123+
*/
124+
private function enrichProductDataFromProduct(array $productData, ProductInterface $product, ChannelInterface $channel, string $localeCode): array
125+
{
126+
foreach ($product->getAttributesByLocale($localeCode, $this->getFallbackLocale()) as $attribute) {
127+
/** @var bool|string|int|float|\DateTimeInterface|array|null $value */
128+
$value = $attribute->getValue();
129+
if ($value instanceof \DateTimeInterface) {
130+
$value = $value->format('Y-m-d H:i:s');
131+
}
132+
$productData['attribute_' . (string) $attribute->getCode()] = $value;
133+
}
134+
/** @var array<string, string[]> $optionWithValues */
135+
$optionWithValues = [];
136+
foreach ($product->getEnabledVariants() as $productVariant) {
137+
foreach ($productVariant->getOptionValues() as $optionValue) {
138+
$productOption = $optionValue->getOption();
139+
if (null === $productOption) {
140+
continue;
141+
}
142+
$optionWithValues[(string) $productOption->getCode()][] = (string) $optionValue->getValue();
143+
}
144+
}
145+
foreach ($optionWithValues as $optionCode => $optionValues) {
146+
$productData['product_option_' . $optionCode] = $optionValues;
147+
}
148+
$productData['product_code'] = $product->getCode();
149+
$productData['is_simple'] = $product->isSimple();
150+
$productData['variant_selection_method'] = $product->getVariantSelectionMethod();
151+
152+
return $productData; //@phpstan-ignore-line
153+
}
154+
155+
/**
156+
* @param clerkIoProductData $productData
157+
*
158+
* @return clerkIoProductData
159+
*/
160+
private function enrichProductDataFromProductTranslation(array $productData, ProductTranslationInterface $productTranslation): array
161+
{
162+
$productData['slug'] = $productTranslation->getSlug();
163+
$productData['short_description'] = $productTranslation->getShortDescription();
164+
$productData['meta_keywords'] = $productTranslation->getMetaKeywords();
165+
$productData['meta_description'] = $productTranslation->getMetaDescription();
166+
167+
return $productData; //@phpstan-ignore-line
168+
}
169+
170+
/**
171+
* @param clerkIoProductData $productData
172+
*
173+
* @return clerkIoProductData
174+
*/
175+
private function enrichProductDataFromProductVariant(array $productData, ProductVariantInterface $productVariant, ChannelInterface $channel): array
176+
{
177+
$productData['variant_code'] = $productVariant->getCode();
178+
$productData['depth'] = $productVariant->getDepth();
179+
$productData['weight'] = $productVariant->getWeight();
180+
$productData['height'] = $productVariant->getHeight();
181+
$productData['width'] = $productVariant->getWidth();
182+
$productData['on_hand'] = $productVariant->getOnHand();
183+
$productData['on_hold'] = $productVariant->getOnHold();
184+
$productData['version'] = $productVariant->getVersion();
185+
foreach ($productVariant->getOptionValues() as $optionValue) {
186+
$productOption = $optionValue->getOption();
187+
if (null === $productOption) {
188+
continue;
189+
}
190+
$productData['variant_option_' . (string) $productOption->getCode()] = $optionValue->getValue();
191+
}
192+
/** @var CatalogPromotionInterface $promotion */
193+
foreach ($productVariant->getAppliedPromotionsForChannel($channel) as $promotion) {
194+
$productData['variant_promotion_' . (string) $promotion->getCode()] = $promotion->getName();
195+
}
196+
197+
return $productData; //@phpstan-ignore-line
198+
}
107199
}

src/DataSyncInfrastructure/Normalizer/Event/ProductVariantNormalizerEvent.php

Lines changed: 16 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,23 @@
88
use Sylius\Component\Core\Model\ProductInterface;
99
use Sylius\Component\Core\Model\ProductVariantInterface;
1010

11+
/**
12+
* @psalm-type clerkIoProductData=array{
13+
* id: string|int,
14+
* name: string,
15+
* description?: string,
16+
* price: float,
17+
* list_price: float,
18+
* image?: string,
19+
* url: string,
20+
* categories: array<int|string>,
21+
* created_at: string,
22+
* }&array<string, bool|string|int|float|array|null>
23+
*/
1124
final class ProductVariantNormalizerEvent
1225
{
1326
/**
14-
* @param array{
15-
* id: string|int,
16-
* name: string,
17-
* description?: string,
18-
* price: float,
19-
* list_price: float,
20-
* image?: string,
21-
* url: string,
22-
* categories: array<int|string>,
23-
* created_at: string,
24-
* }&array<string, string|int|float|array<array-key, string|int|float>> $productData
27+
* @param clerkIoProductData $productData
2528
*/
2629
public function __construct(
2730
private array $productData,
@@ -34,35 +37,15 @@ public function __construct(
3437
}
3538

3639
/**
37-
* @return array{
38-
* id: string|int,
39-
* name: string,
40-
* description?: string,
41-
* price: float,
42-
* list_price: float,
43-
* image?: string,
44-
* url: string,
45-
* categories: array<int|string>,
46-
* created_at: string,
47-
* }&array<string, string|int|float|array<array-key, string|int|float>>
40+
* @return clerkIoProductData
4841
*/
4942
public function getProductData(): array
5043
{
5144
return $this->productData;
5245
}
5346

5447
/**
55-
* @param array{
56-
* id: string|int,
57-
* name: string,
58-
* description?: string,
59-
* price: float,
60-
* list_price: float,
61-
* image?: string,
62-
* url: string,
63-
* categories: array<int|string>,
64-
* created_at: string,
65-
* }&array<string, string|int|float|array<array-key, string|int|float>> $productData
48+
* @param clerkIoProductData $productData
6649
*/
6750
public function setProductData(array $productData): void
6851
{

src/DataSyncInfrastructure/Normalizer/ProductNormalizer.php

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
use Webgriffe\SyliusClerkPlugin\DataSyncInfrastructure\Normalizer\Event\ProductVariantNormalizerEvent;
1717
use Webmozart\Assert\Assert;
1818

19+
/**
20+
* @psalm-import-type clerkIoProductData from ProductVariantNormalizerEvent
21+
*/
1922
final readonly class ProductNormalizer implements NormalizerInterface
2023
{
2124
use CommonProductNormalizerTrait;
@@ -28,23 +31,14 @@ public function __construct(
2831
private CacheManager $cacheManager,
2932
private string $imageType,
3033
private string $imageFilterToApply,
34+
private string $fallbackLocale,
3135
) {
3236
}
3337

3438
/**
3539
* @param ProductInterface|mixed $object
3640
*
37-
* @return array{
38-
* id: string|int,
39-
* name: string,
40-
* description?: string,
41-
* price: float,
42-
* list_price: float,
43-
* image?: string,
44-
* url: string,
45-
* categories: array<int|string>,
46-
* created_at: string,
47-
* }&array<string, mixed>
41+
* @return clerkIoProductData
4842
*/
4943
public function normalize(mixed $object, ?string $format = null, array $context = []): array
5044
{
@@ -100,6 +94,9 @@ public function normalize(mixed $object, ?string $format = null, array $context
10094
if ($productMainImageUrl !== null) {
10195
$productData['image'] = $productMainImageUrl;
10296
}
97+
$productData = $this->enrichProductDataFromProduct($productData, $product, $channel, $localeCode);
98+
$productData = $this->enrichProductDataFromProductTranslation($productData, $productTranslation);
99+
$productData = $this->enrichProductDataFromProductVariant($productData, $productVariant, $channel);
103100

104101
$productNormalizerEvent = new ProductVariantNormalizerEvent(
105102
$productData,
@@ -137,4 +134,14 @@ private function getCacheManager(): CacheManager
137134
{
138135
return $this->cacheManager;
139136
}
137+
138+
public function getImageFilterToApply(): string
139+
{
140+
return $this->imageFilterToApply;
141+
}
142+
143+
public function getFallbackLocale(): string
144+
{
145+
return $this->fallbackLocale;
146+
}
140147
}

src/DataSyncInfrastructure/Normalizer/ProductVariantNormalizer.php

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
use Webmozart\Assert\Assert;
1717

1818
/**
19-
* @method array getSupportedTypes(?string $format)
19+
* @psalm-import-type clerkIoProductData from ProductVariantNormalizerEvent
2020
*/
2121
final readonly class ProductVariantNormalizer implements NormalizerInterface
2222
{
@@ -29,23 +29,14 @@ public function __construct(
2929
private CacheManager $cacheManager,
3030
private string $imageType,
3131
private string $imageFilterToApply,
32+
private string $fallbackLocale,
3233
) {
3334
}
3435

3536
/**
3637
* @param ProductVariantInterface|mixed $object
3738
*
38-
* @return array{
39-
* id: string|int,
40-
* name: string,
41-
* description?: string,
42-
* price: float,
43-
* list_price: float,
44-
* image?: string,
45-
* url: string,
46-
* categories: array<int|string>,
47-
* created_at: string,
48-
* }&array<string, mixed>
39+
* @return clerkIoProductData
4940
*/
5041
public function normalize(mixed $object, ?string $format = null, array $context = []): array
5142
{
@@ -100,6 +91,9 @@ public function normalize(mixed $object, ?string $format = null, array $context
10091
if ($productMainImageUrl !== null) {
10192
$productData['image'] = $productMainImageUrl;
10293
}
94+
$productData = $this->enrichProductDataFromProduct($productData, $product, $channel, $localeCode);
95+
$productData = $this->enrichProductDataFromProductTranslation($productData, $productTranslation);
96+
$productData = $this->enrichProductDataFromProductVariant($productData, $productVariant, $channel);
10397

10498
$productNormalizerEvent = new ProductVariantNormalizerEvent(
10599
$productData,
@@ -137,4 +131,14 @@ private function getCacheManager(): CacheManager
137131
{
138132
return $this->cacheManager;
139133
}
134+
135+
public function getImageFilterToApply(): string
136+
{
137+
return $this->imageFilterToApply;
138+
}
139+
140+
public function getFallbackLocale(): string
141+
{
142+
return $this->fallbackLocale;
143+
}
140144
}

0 commit comments

Comments
 (0)