diff --git a/src/Attribute/ImageAttributeProcessor.php b/src/Attribute/ImageAttributeProcessor.php
new file mode 100644
index 0000000..1527b55
--- /dev/null
+++ b/src/Attribute/ImageAttributeProcessor.php
@@ -0,0 +1,70 @@
+productImageFactory = $productImageFactory;
+ $this->productImageRepository = $productImageRepository;
+ $this->imageAttribute = $imageAttribute;
+ }
+
+ /** {@inheritdoc} */
+ public function process(ProductInterface $product, Attribute $attribute): void
+ {
+ if (!$this->supports($attribute)) {
+ return;
+ }
+
+ foreach ($product->getImagesByType('akeneo') as $productImage) {
+ $product->removeImage($productImage);
+ }
+
+ if (null === $attribute->data()) {
+ return;
+ }
+
+ /** @var ProductImageInterface|null $image */
+ $productImage = $this->productImageRepository->findOneBy([
+ 'owner' => $product,
+ 'type' => 'akeneo',
+ 'path' => $attribute->data(),
+ ]);
+
+ if (null === $productImage) {
+ /** @var ProductImageInterface $productImage */
+ $productImage = $this->productImageFactory->createNew();
+ $productImage->setType('akeneo');
+ $productImage->setPath($attribute->data());
+ }
+
+ $product->addImage($productImage);
+ }
+
+ private function supports(Attribute $attribute): bool
+ {
+ return $this->imageAttribute === $attribute->attribute() && (null === $attribute->data() || is_string($attribute->data()));
+ }
+}
diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php
index bd201bd..44dfbe9 100644
--- a/src/DependencyInjection/Configuration.php
+++ b/src/DependencyInjection/Configuration.php
@@ -27,6 +27,7 @@ public function getConfigTreeBuilder()
->scalarNode('name_attribute')->defaultValue('name')->end()
->scalarNode('description_attribute')->defaultValue('description')->end()
->scalarNode('price_attribute')->defaultValue('price')->end()
+ ->scalarNode('image_attribute')->defaultValue('images')->end()
->end()
->end()
->end()
diff --git a/src/DependencyInjection/SylakeSyliusConsumerExtension.php b/src/DependencyInjection/SylakeSyliusConsumerExtension.php
index 511dadf..0164c1e 100644
--- a/src/DependencyInjection/SylakeSyliusConsumerExtension.php
+++ b/src/DependencyInjection/SylakeSyliusConsumerExtension.php
@@ -32,6 +32,10 @@ public function load(array $config, ContainerBuilder $container)
'sylake_sylius_consumer.denormalizer.product.price_attribute',
$config['denormalizer']['product']['price_attribute']
);
+ $container->setParameter(
+ 'sylake_sylius_consumer.denormalizer.product.image_attribute',
+ $config['denormalizer']['product']['image_attribute']
+ );
}
/**
diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml
index 187ef03..3e71fcf 100644
--- a/src/Resources/config/services.xml
+++ b/src/Resources/config/services.xml
@@ -49,6 +49,13 @@
%sylake_sylius_consumer.denormalizer.product.price_attribute%
+
+
+
+
+ %sylake_sylius_consumer.denormalizer.product.image_attribute%
+
+
diff --git a/tests/DependencyInjection/ExtensionTest.php b/tests/DependencyInjection/ExtensionTest.php
index 53b7773..dd0c32a 100644
--- a/tests/DependencyInjection/ExtensionTest.php
+++ b/tests/DependencyInjection/ExtensionTest.php
@@ -20,6 +20,7 @@ public function it_adds_product_denormalization_parameters_by_default()
$this->assertContainerBuilderHasParameter('sylake_sylius_consumer.denormalizer.product.name_attribute', 'name');
$this->assertContainerBuilderHasParameter('sylake_sylius_consumer.denormalizer.product.description_attribute', 'description');
$this->assertContainerBuilderHasParameter('sylake_sylius_consumer.denormalizer.product.price_attribute', 'price');
+ $this->assertContainerBuilderHasParameter('sylake_sylius_consumer.denormalizer.product.image_attribute', 'images');
}
/**
diff --git a/tests/Functional/ProductSynchronizationTest.php b/tests/Functional/ProductSynchronizationTest.php
index cb9cfbf..4955efe 100644
--- a/tests/Functional/ProductSynchronizationTest.php
+++ b/tests/Functional/ProductSynchronizationTest.php
@@ -9,6 +9,7 @@
use PHPUnit\Framework\Assert;
use Sylius\Bundle\FixturesBundle\Fixture\FixtureInterface;
use Sylius\Component\Core\Model\ChannelInterface;
+use Sylius\Component\Core\Model\ProductImageInterface;
use Sylius\Component\Core\Model\ProductInterface;
use Sylius\Component\Core\Model\ProductVariantInterface;
use Sylius\Component\Core\Model\TaxonInterface;
@@ -185,6 +186,123 @@ public function it_updates_an_existing_product_with_basic_product_information()
Assert::assertFalse($product->isEnabled());
}
+ /**
+ * @test
+ */
+ public function it_adds_a_new_product_with_images()
+ {
+ $this->consumer->execute(new AMQPMessage('{
+ "type": "akeneo_product_updated",
+ "payload": {
+ "identifier": "AKNTS_BPXS",
+ "family": "tshirts",
+ "groups": [],
+ "variant_group": "akeneo_tshirt",
+ "categories": ["goodies", "tshirts"],
+ "enabled": true,
+ "values": {
+ "sku": [{"locale": null, "scope": null, "data": "AKNTS_BPXS"}],
+ "clothing_size": [{"locale": null, "scope": null, "data": "xs"}],
+ "main_color": [{"locale": null, "scope": null, "data": "black"}],
+ "name": [{"locale": null, "scope": null, "data": "Akeneo T-Shirt black and purple with short sleeve"}],
+ "secondary_color": [{"locale": null, "scope": null, "data": "purple"}],
+ "tshirt_materials": [{"locale": null, "scope": null, "data": "cotton"}],
+ "tshirt_style": [{"locale": null, "scope": null, "data": ["crewneck", "short_sleeve"]}],
+ "price": [{"locale": null, "scope": null, "data": [{"amount": 10, "currency": "EUR"}, {"amount": 14, "currency": "USD"}]}],
+ "description": [{"locale": "en_US", "scope": "mobile", "data": "T-Shirt description"}],
+ "picture": [{"locale": null, "scope": null, "data": null}],
+ "images": [{"locale": null, "scope": null, "data": "8\/7\/5\/3\/8753d08e04e7ecdda77ef77573cd42bbfb029dcb_image.jpg"}]
+ },
+ "created": "2017-04-18T16:12:55+02:00",
+ "updated": "2017-04-18T16:12:55+02:00",
+ "associations": {"SUBSTITUTION": {"groups": [], "products": ["AKNTS_WPXS", "AKNTS_PBXS", "AKNTS_PWXS"]}}
+ },
+ "recordedOn": "2017-05-22 10:13:34"
+ }'));
+
+ /** @var ProductInterface|null $product */
+ $product = $this->productRepository->findOneBy(['code' => 'AKNTS_BPXS']);
+
+ Assert::assertNotNull($product);
+
+ $akeneoProductImages = $product->getImagesByType('akeneo')->toArray();
+ $akeneoProductImage = current($akeneoProductImages);
+
+ Assert::assertNotFalse($akeneoProductImage);
+ Assert::assertSame('8/7/5/3/8753d08e04e7ecdda77ef77573cd42bbfb029dcb_image.jpg', $akeneoProductImage->getPath());
+ Assert::assertSame('akeneo', $akeneoProductImage->getType());
+ }
+
+ /**
+ * @test
+ */
+ public function it_updates_an_existing_product_with_images()
+ {
+ $this->consumer->execute(new AMQPMessage('{
+ "type": "akeneo_product_updated",
+ "payload": {
+ "identifier": "AKNTS_BPXS",
+ "family": "tshirts",
+ "groups": [],
+ "variant_group": "akeneo_tshirt",
+ "categories": ["goodies", "tshirts"],
+ "enabled": true,
+ "values": {
+ "sku": [{"locale": null, "scope": null, "data": "AKNTS_BPXS"}],
+ "clothing_size": [{"locale": null, "scope": null, "data": "xs"}],
+ "main_color": [{"locale": null, "scope": null, "data": "black"}],
+ "name": [{"locale": null, "scope": null, "data": "Akeneo T-Shirt black and purple with short sleeve"}],
+ "secondary_color": [{"locale": null, "scope": null, "data": "purple"}],
+ "tshirt_materials": [{"locale": null, "scope": null, "data": "cotton"}],
+ "tshirt_style": [{"locale": null, "scope": null, "data": ["crewneck", "short_sleeve"]}],
+ "price": [{"locale": null, "scope": null, "data": [{"amount": 10, "currency": "EUR"}, {"amount": 14, "currency": "USD"}]}],
+ "description": [{"locale": "en_US", "scope": "mobile", "data": "T-Shirt description"}],
+ "picture": [{"locale": null, "scope": null, "data": null}],
+ "images": [{"locale": null, "scope": null, "data": "8\/7\/5\/3\/8753d08e04e7ecdda77ef77573cd42bbfb029dcb_image.jpg"}]
+ },
+ "created": "2017-04-18T16:12:55+02:00",
+ "updated": "2017-04-18T16:12:55+02:00",
+ "associations": {"SUBSTITUTION": {"groups": [], "products": ["AKNTS_WPXS", "AKNTS_PBXS", "AKNTS_PWXS"]}}
+ },
+ "recordedOn": "2017-05-22 10:13:34"
+ }'));
+
+ $this->consumer->execute(new AMQPMessage('{
+ "type": "akeneo_product_updated",
+ "payload": {
+ "identifier": "AKNTS_BPXS",
+ "family": "tshirts",
+ "groups": [],
+ "variant_group": "akeneo_tshirt",
+ "categories": ["goodies", "tshirts"],
+ "enabled": false,
+ "values": {
+ "sku": [{"locale": null, "scope": null, "data": "AKNTS_BPXS"}],
+ "clothing_size": [{"locale": null, "scope": null, "data": "xs"}],
+ "main_color": [{"locale": null, "scope": null, "data": "black"}],
+ "name": [{"locale": null, "scope": null, "data": "Akeneo T-Shirt black and purple with short sleeve (updated)"}],
+ "secondary_color": [{"locale": null, "scope": null, "data": "purple"}],
+ "tshirt_materials": [{"locale": null, "scope": null, "data": "cotton"}],
+ "tshirt_style": [{"locale": null, "scope": null, "data": ["crewneck", "short_sleeve"]}],
+ "price": [{"locale": null, "scope": null, "data": [{"amount": 10, "currency": "EUR"}, {"amount": 14, "currency": "USD"}]}],
+ "description": [{"locale": "en_US", "scope": "mobile", "data": "T-Shirt description (updated)"}],
+ "picture": [{"locale": null, "scope": null, "data": null}],
+ "images": [{"locale": null, "scope": null, "data": null}]
+ },
+ "created": "2017-04-18T16:12:58+02:00",
+ "updated": "2017-04-18T16:12:55+02:00",
+ "associations": {"SUBSTITUTION": {"groups": [], "products": ["AKNTS_WPXS", "AKNTS_PBXS", "AKNTS_PWXS"]}}
+ },
+ "recordedOn": "2017-05-22 10:13:34"
+ }'));
+
+ /** @var ProductInterface|null $product */
+ $product = $this->productRepository->findOneBy(['code' => 'AKNTS_BPXS']);
+
+ Assert::assertNotNull($product);
+ Assert::assertSame([], $product->getImagesByType('akeneo')->toArray());
+ }
+
/**
* @test
*/