Skip to content

Commit

Permalink
Skip locales not used in any product channels (#137)
Browse files Browse the repository at this point in the history
  • Loading branch information
lruozzi9 committed Jul 13, 2022
1 parent 257fc6c commit 2995d0a
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 14 deletions.
51 changes: 37 additions & 14 deletions spec/ValueHandler/TranslatablePropertyValueHandlerSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@
use Prophecy\Argument;
use RuntimeException;
use stdClass;
use Sylius\Component\Core\Model\Channel;
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Core\Model\ProductInterface;
use Sylius\Component\Core\Model\ProductTranslationInterface;
use Sylius\Component\Core\Model\ProductVariantInterface;
use Sylius\Component\Locale\Model\LocaleInterface;
use Sylius\Component\Locale\Provider\LocaleProviderInterface;
use Sylius\Component\Product\Model\ProductVariantTranslationInterface;
use Sylius\Component\Resource\Factory\FactoryInterface;
use Sylius\Component\Resource\Translation\Provider\TranslationLocaleProviderInterface;
Expand All @@ -36,35 +38,41 @@ public function let(
ProductVariantTranslationInterface $italianProductVariantTranslation,
ProductInterface $product,
ProductTranslationInterface $englishProductTranslation,
ProductTranslationInterface $italianProductTranslation
ProductTranslationInterface $italianProductTranslation,
LocaleInterface $italianLocale,
LocaleInterface $englishLocale,
ChannelInterface $commerceChannel,
ChannelInterface $supportChannel
): void {
$propertyAccessor->isWritable($englishProductVariantTranslation, self::TRANSLATION_PROPERTY_PATH)->willReturn(true);
$propertyAccessor->isWritable($italianProductVariantTranslation, self::TRANSLATION_PROPERTY_PATH)->willReturn(true);
$propertyAccessor->isWritable($englishProductTranslation, self::TRANSLATION_PROPERTY_PATH)->willReturn(true);
$propertyAccessor->isWritable($italianProductTranslation, self::TRANSLATION_PROPERTY_PATH)->willReturn(true);

$localeProvider->getDefinedLocalesCodes()->willReturn(['en_US', 'it_IT']);
$italianLocale->getCode()->willReturn('it_IT');
$englishLocale->getCode()->willReturn('en_US');

$productVariant->getProduct()->willReturn($product);
$commerceChannel = new Channel();
$commerceChannel->setCode('ecommerce');
$supportChannel = new Channel();
$supportChannel->setCode('support');
$product->getChannels()->willReturn(new ArrayCollection([$commerceChannel, $supportChannel]));
$localeProvider->getDefinedLocalesCodes()->willReturn(['en_US', 'it_IT']);
$commerceChannel->getCode()->willReturn('ecommerce');
$commerceChannel->getLocales()->willReturn(new ArrayCollection([$italianLocale->getWrappedObject(), $englishLocale->getWrappedObject()]));
$supportChannel->getCode()->willReturn('support');
$supportChannel->getLocales()->willReturn(new ArrayCollection([$italianLocale->getWrappedObject(), $englishLocale->getWrappedObject()]));

$productVariant->getProduct()->willReturn($product);
$englishProductVariantTranslation->getLocale()->willReturn('en_US');
$italianProductVariantTranslation->getLocale()->willReturn('it_IT');
$englishProductVariantTranslation->getTranslatable()->willReturn($productVariant);
$italianProductVariantTranslation->getTranslatable()->willReturn($productVariant);
$productVariant->getTranslation('en_US')->willReturn($englishProductVariantTranslation);
$productVariant->getTranslation('it_IT')->willReturn($italianProductVariantTranslation);
$englishProductTranslation->getLocale()->willReturn('en_US');
$italianProductTranslation->getLocale()->willReturn('it_IT');

$product->getChannels()->willReturn(new ArrayCollection([$commerceChannel->getWrappedObject(), $supportChannel->getWrappedObject()]));
$product->getTranslation('en_US')->willReturn($englishProductTranslation);
$product->getTranslation('it_IT')->willReturn($italianProductTranslation);

$productVariant->getProduct()->willReturn($product);
$productVariant->getTranslation('en_US')->willReturn($englishProductVariantTranslation);
$productVariant->getTranslation('it_IT')->willReturn($italianProductVariantTranslation);

$this->beConstructedWith(
$propertyAccessor,
$productTranslationFactory,
Expand Down Expand Up @@ -182,6 +190,21 @@ public function it_skips_locales_not_specified_in_sylius(
$propertyAccessor->setValue($productTranslation, self::TRANSLATION_PROPERTY_PATH, 'New value')->shouldNotHaveBeenCalled();
}

public function it_skips_locales_not_used_in_any_product_channels(
ProductVariantInterface $productVariant,
ProductVariantTranslationInterface $productVariantTranslation,
ProductTranslationInterface $productTranslation,
PropertyAccessorInterface $propertyAccessor,
LocaleProviderInterface $localeProvider
): void {
$localeProvider->getDefinedLocalesCodes()->willReturn(['en_US', 'it_IT', 'es_ES']);

$this->handle($productVariant, self::AKENEO_ATTRIBUTE_CODE, [['locale' => 'es_ES', 'scope' => null, 'data' => 'New value']]);

$propertyAccessor->setValue($productVariantTranslation, self::TRANSLATION_PROPERTY_PATH, 'New value')->shouldNotHaveBeenCalled();
$propertyAccessor->setValue($productTranslation, self::TRANSLATION_PROPERTY_PATH, 'New value')->shouldNotHaveBeenCalled();
}

public function it_sets_value_on_all_product_translations_when_locale_not_specified(
ProductVariantInterface $productVariant,
ProductVariantTranslationInterface $englishProductVariantTranslation,
Expand Down Expand Up @@ -321,14 +344,14 @@ public function it_skips_values_related_to_channels_that_are_not_associated_to_t
public function it_throws_when_data_is_not_an_array(ProductVariantInterface $productVariant): void
{
$this
->shouldThrow(new \InvalidArgumentException('Invalid Akeneo value data: expected an array, "NULL" given.',))
->shouldThrow(new InvalidArgumentException('Invalid Akeneo value data: expected an array, "NULL" given.',))
->during('handle', [$productVariant, self::AKENEO_ATTRIBUTE_CODE, [null]]);
}

public function it_throws_when_data_doesnt_contain_scope_info(ProductVariantInterface $productVariant): void
{
$this
->shouldThrow(new \InvalidArgumentException('Invalid Akeneo value data: required "scope" information was not found.',))
->shouldThrow(new InvalidArgumentException('Invalid Akeneo value data: required "scope" information was not found.',))
->during(
'handle',
[
Expand Down
17 changes: 17 additions & 0 deletions src/ValueHandler/TranslatablePropertyValueHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ public function handle($subject, string $attribute, array $value): void
if (!in_array($localeCode, $availableLocalesCodes, true)) {
continue;
}
if (!$this->isLocaleUsedInAtLeastOneChannelForTheProduct($product, $localeCode)) {
continue;
}

$this->setValueOnProductVariantAndProductTranslation($subject, $localeCode, $valueData['data']);
}
Expand Down Expand Up @@ -217,4 +220,18 @@ private function setNullOnExistingProductVariantAndProductTranslation(
}
}
}

private function isLocaleUsedInAtLeastOneChannelForTheProduct(ProductInterface $product, string $localeCode): bool
{
foreach ($product->getChannels() as $channel) {
Assert::isInstanceOf($channel, \Sylius\Component\Core\Model\ChannelInterface::class);
foreach ($channel->getLocales() as $locale) {
if ($locale->getCode() === $localeCode) {
return true;
}
}
}

return false;
}
}

0 comments on commit 2995d0a

Please sign in to comment.