Skip to content

Commit

Permalink
Fix problem with not updating product models
Browse files Browse the repository at this point in the history
  • Loading branch information
piotrmus committed Nov 3, 2021
1 parent 7492850 commit 36ade18
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 89 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "piotrmus/akeneo-product-translation",
"type": "symfony-bundle",
"description": "Translation extension for Akeneo",
"version": "0.1.9",
"version": "0.1.10",
"license": "OSL-3.0",
"authors": [
{
Expand Down
119 changes: 35 additions & 84 deletions src/Connector/Processor/MassEdit/TranslateAttributesProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@
namespace Piotrmus\Translator\Connector\Processor\MassEdit;

use Akeneo\Pim\Enrichment\Component\Product\Connector\Processor\MassEdit\AbstractProcessor;
use Akeneo\Pim\Enrichment\Component\Product\EntityWithFamilyVariant\CheckAttributeEditable;
use Akeneo\Pim\Enrichment\Component\Product\Model\ProductInterface;
use Akeneo\Pim\Enrichment\Component\Product\Model\ProductModelInterface;
use Akeneo\Pim\Enrichment\Component\Product\Model\ValueInterface;
use Akeneo\Pim\Enrichment\Component\Product\Updater\Setter\AttributeSetterInterface;
use Akeneo\Pim\Enrichment\Component\Product\Value\ScalarValue;
use Akeneo\Pim\Structure\Component\Model\AttributeInterface;
use Akeneo\Pim\Structure\Component\Repository\AttributeRepositoryInterface;
use Akeneo\Tool\Component\Batch\Item\DataInvalidItem;
use Akeneo\Tool\Component\Batch\Item\InvalidItemException;
use Akeneo\Tool\Component\StorageUtils\Updater\PropertySetterInterface;
use InvalidArgumentException;
use Piotrmus\Translator\Translator\Language;
use Piotrmus\Translator\Translator\TranslatorInterface;
Expand All @@ -26,13 +29,25 @@ class TranslateAttributesProcessor extends AbstractProcessor
* @var AttributeRepositoryInterface
*/
private $attributeRepository;
/**
* @var CheckAttributeEditable
*/
private $checkAttributeEditable;
/**
* @var PropertySetterInterface
*/
private $propertySetter;

public function __construct(
TranslatorInterface $translator,
AttributeRepositoryInterface $attributeRepository
AttributeRepositoryInterface $attributeRepository,
CheckAttributeEditable $checkAttributeEditable,
PropertySetterInterface $propertySetter
) {
$this->attributeRepository = $attributeRepository;
$this->translator = $translator;
$this->checkAttributeEditable = $checkAttributeEditable;
$this->propertySetter = $propertySetter;
}

/**
Expand All @@ -54,6 +69,16 @@ public function process($item)
/**
* @param ProductInterface|ProductModelInterface $product
* @param array<string, string|array<int, string>> $action
* $actions = [
* 'sourceChannel' => 'ecommerce',
* 'targetChannel' => 'ecommerce',
* 'sourceLocale' => 'pl_PL',
* 'targetLocale' => 'en_US',
* 'translatedAttributes' => [
* 'name',
* 'description',
* ]
* ];
* @return ProductInterface|ProductModelInterface
*/
private function translateAttributes($product, array $action)
Expand All @@ -67,23 +92,10 @@ private function translateAttributes($product, array $action)
$attributeCodes = $action['translatedAttributes'];

foreach ($attributeCodes as $attributeCode) {
/** @var AttributeInterface|null $attribute */
$attribute = $this->attributeRepository->findOneByIdentifier($attributeCode);
if (!$this->canEditAttribute($product, $attribute)) {
throw new InvalidItemException(
sprintf(
"You can not edit attribute \"%s\" in this product \"%s\". Most common reason is that attribute is on another level.",
(string)$attributeCode,
$product->getIdentifier()
),
new DataInvalidItem(
[
'identifier' => $product->getIdentifier(),
'source_attribute' => $attributeCode,
'source_language' => $sourceLocale->asString(),
'source_channel' => $sourceScope,
]
)
);
if (!$this->checkAttributeEditable->isEditable($product, $attribute)) {
continue;
}

if (!$attribute->isScopable()) {
Expand All @@ -92,85 +104,24 @@ private function translateAttributes($product, array $action)
}
/** @var ValueInterface|null $attributeValue */
$attributeValue = $product->getValue($attributeCode, $sourceLocaleAkeneo, $sourceScope);

if ($attributeValue === null) {
continue;
}

$sourceText = $attributeValue->getData();

$translatedValue = $this->translator->translate(
$translatedText = $this->translator->translate(
$sourceText,
$sourceLocale,
$targetLocale
);

$this->replaceProductValue($product, $attribute, $targetLocaleAkeneo, $targetScope, $translatedValue);
}
return $product;
}

private function canEditAttribute($product, $attribute): bool
{
if (
(
($product instanceof ProductInterface && $product->isVariant())
|| $product instanceof ProductModelInterface
)
&& $product->getFamilyVariant() !== null
&& $product->getFamilyVariant()->getLevelForAttributeCode(
$attribute->getCode()
) !== $product->getVariationLevel()
) {
return false;
}
if (
$product instanceof ProductInterface
&& !$product->hasAttributeInFamily($attribute)
) {
return false;
}
return true;
}

/**
* @param ProductInterface $product
* @param AttributeInterface $attribute
* @param string $targetLocale
* @param string|null $targetScope
* @param string $newValue
*/
private function replaceProductValue(
ProductInterface $product,
AttributeInterface $attribute,
string $targetLocale,
?string $targetScope,
string $newValue
): void {
$targetAttributeValue = $product->getValue($attribute->getCode(), $targetLocale, $targetScope);

$isScopable = $attribute->isScopable();
$isLocalizable = $attribute->isLocalizable();

if ($isScopable && $isLocalizable) {
$value = ScalarValue::scopableLocalizableValue(
$attribute->getCode(),
$newValue,
$targetScope,
$targetLocale
);
} elseif ($isScopable) {
$value = ScalarValue::scopableValue($attribute->getCode(), $newValue, $targetScope);
} elseif ($isLocalizable) {
$value = ScalarValue::localizableValue($attribute->getCode(), $newValue, $targetLocale);
} else {
$value = ScalarValue::value($attribute->getCode(), $newValue);
}

if ($targetAttributeValue !== null) {
$product->removeValue($targetAttributeValue);
$this->propertySetter->setData($product, $attribute->getCode(), $translatedText, [
'locale' => $targetLocaleAkeneo,
'scope' => $targetScope,
]);
}

$product->addValue($value);
return $product;
}
}
11 changes: 7 additions & 4 deletions src/Resources/config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ services:
arguments:
- '@Piotrmus\Translator\Translator\GoogleTranslator'
- '@pim_catalog.repository.attribute'
- '@pim_catalog.entity_with_family_variant.check_attribute_editable'
- '@pim_catalog.updater.entity_with_values_property_setter_without_permission'

Google\Cloud\Translate\V2\TranslateClient:
arguments:
Expand Down Expand Up @@ -37,12 +39,13 @@ services:
- { name: akeneo_batch.job.job_parameters.constraint_collection_provider }

piotrmus.step.update_product_translations.mass_edit:
class: Akeneo\Tool\Component\Batch\Step\ItemStep
class: '%pim_connector.step.item_step.class%'
arguments:
- 'perform'
- '@event_dispatcher'
- '@akeneo_batch.job_repository'
- '@pim_enrich.reader.database.products_and_variant_products_of_product_models'
- '@pim_enrich.reader.database.product_and_product_model'
- '@Piotrmus\Translator\Connector\Processor\MassEdit\TranslateAttributesProcessor'
- '@pim_connector.writer.database.product'
- 10
- '@pim_enrich.writer.database.product_and_product_model_writer'
- '%pim_job_product_batch_size%'
- '@akeneo_batch.job.job_stopper'

0 comments on commit 36ade18

Please sign in to comment.