Process localized content as described in the api spec

This commit is contained in:
2025-01-15 13:19:58 +01:00
parent 172e5f36f1
commit dece03dc3f
+78 -7
View File
@@ -9,8 +9,9 @@ use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProcessorInterface;
use App\Entity\Interface\LocalizedContentInterface;
use App\Service\LocalizationService;
use Doctrine\ORM\EntityManagerInterface;
use Gedmo\Translatable\Entity\Translation;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\HttpFoundation\Request;
class EntityStateProcessor implements ProcessorInterface
{
@@ -20,6 +21,7 @@ class EntityStateProcessor implements ProcessorInterface
#[Autowire(service: PersistProcessor::class)]
private ProcessorInterface $persistProcessor,
private LocalizationService $localizationService,
private EntityManagerInterface $entityManager,
) {}
/**
@@ -28,12 +30,7 @@ class EntityStateProcessor implements ProcessorInterface
public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = [])
{
if ($data instanceof LocalizedContentInterface) {
/** @var Request */
$request = $context['request'];
$data->setTranslatableLocale($this->localizationService->getLanguage(
$request->headers->get('Content-Language'),
));
return $this->processLocalizedContent($data, $operation, $uriVariables, $context);
}
if ($operation instanceof DeleteOperationInterface) {
@@ -42,4 +39,78 @@ class EntityStateProcessor implements ProcessorInterface
return $this->persistProcessor->process($data, $operation, $uriVariables, $context);
}
private function processLocalizedContent(
LocalizedContentInterface $data,
Operation $operation,
array $uriVariables = [],
array $context = [],
): mixed {
$languages = $this->getContextLanguages($context);
if ($operation instanceof DeleteOperationInterface) {
if ($languages === null) {
return $this->deleteProcessor->process($data, $operation, $uriVariables, $context);
}
return $this->deleteLocalizedContent($data, $operation, $uriVariables, $context, $languages);
}
$language = $languages ? $languages[0] : $this->localizationService->getDefaultLanguage();
$data->setTranslatableLocale($language);
return $this->persistProcessor->process($data, $operation, $uriVariables, $context);
}
private function getContextLanguages(array $context): ?array
{
$tags = $context['request']->headers->get('Content-Language', '');
if (empty($tags)) {
return null;
}
return $this->localizationService->getLanguages($tags);
}
private function deleteLocalizedContent(
LocalizedContentInterface $data,
Operation $operation,
array $uriVariables = [],
array $context = [],
array $languages = []
) {
$translationRepository = $this->entityManager->getRepository(Translation::class);
if (!\array_diff($data->getLocales(), $languages)) {
throw new \Exception("Cannot leave empty resource. Must have at least one available localization.");
}
$nonLocalizedLanguages = \array_diff($languages, $data->getLocales());
if (!empty($nonLocalizedLanguages)) {
throw new \Exception(\sprintf(
"Could not find requested localizations '%s' of the resource.",
\join(', ', $nonLocalizedLanguages)
));
}
foreach ($languages as $language) {
$translations = $translationRepository->findBy([
'locale' => $language,
'objectClass' => $data::class,
'foreignKey' => $data->getId()
]);
foreach ($translations as $translation) {
$this->entityManager->remove($translation);
}
$data->removeLocale($language);
}
$this->entityManager->flush();
return $this->persistProcessor->process($data, $operation, $uriVariables, $context);
}
}