Files
2026-09-15 10:35:56 +08:00

83 lines
2.4 KiB
PHP

<?php
declare(strict_types=1);
namespace Esun\Translation\Model\Product;
use Esun\Translation\Model\Html\HtmlTranslationValidator;
use Magento\Catalog\Api\ProductRepositoryInterface;
class TranslationApplier
{
public function __construct(
private readonly ProductRepositoryInterface $productRepository,
private readonly TranslatableFieldProvider $fieldProvider,
private readonly HtmlTranslationValidator $htmlValidator
) {
}
/**
* @param int[] $storeIds
* @param array<string, string> $fields
*/
public function apply(int $productId, array $storeIds, array $fields): int
{
$fields = $this->filterAndValidateFields($fields);
if ($fields === []) {
throw new \RuntimeException('No translatable fields were provided.');
}
$updated = 0;
foreach (array_unique(array_map('intval', $storeIds)) as $storeId) {
if ($storeId <= 0) {
continue;
}
$product = $this->productRepository->getById($productId, false, $storeId);
$product->setStoreId($storeId);
foreach ($fields as $code => $value) {
$product->setData($code, $value);
}
$this->productRepository->save($product);
$updated++;
}
if ($updated === 0) {
throw new \RuntimeException('No valid target store views were provided.');
}
return $updated;
}
/**
* @param array<string, mixed> $fields
* @return array<string, string>
*/
private function filterAndValidateFields(array $fields): array
{
$result = [];
foreach ($fields as $code => $value) {
$code = (string)$code;
if (!$this->fieldProvider->isAttributeAllowed($code)) {
continue;
}
$value = (string)$value;
if ($this->fieldProvider->isHtmlAttributeCode($code)) {
$errors = $this->htmlValidator->validate($value);
if ($errors !== []) {
throw new \RuntimeException(sprintf(
'HTML for "%s" is invalid: %s',
$code,
implode('; ', $errors)
));
}
}
$result[$code] = $value;
}
return $result;
}
}