У меня есть объект Address.Этот адрес имеет страну.К этой стране прикреплено многоязычное поле.
GET /address/{id}
возвращает стремительное расширение страны как часть ее продукции.Я бы хотел, чтобы потребитель REST API мог передавать Accept-Locale: fr_FR
(или аналогичный) и получать правильный перевод для страны.
У меня есть существующая настройка перевода на основе Gedmo / Transurable пакет.Он отлично работает для отдельных лиц.Я передаю информацию о локали:1012 *
Пользовательский сериализатор, который назначает языковой стандарт контексту с помощью шаблона декоратора:
// Extracted from overall class "TranslatableContextBuilder"
/**
* {@inheritDoc}
*
* Adds the 'locale' to $context, which will be the 2-character
* preferred language string ('en', 'fr', 'es', 'pt') that the user
* wishes for the requested content.
*/
public function createFromRequest(
Request $request,
bool $normalization,
?array $extractedAttributes = null
): array {
$context = $this->decorated->createFromRequest(
$request,
$normalization,
$extractedAttributes
);
// Add locale info to every context.
$context['locale'] = $this->localeListener->getPreferredLanguage(
$request
);
return $context;
}
Поставщик данных элемента, который расширяет
\ApiPlatform\Core\Bridge\Doctrine\Orm\ItemDataProvider
.Это используется для установки локали для результата, полученного из
ItemDataProvider
, чтобы он возвращал результат, соответствующий языку:
/**
* {@inheritdoc}
*
* Assigns the locale to the result obtained from
* ApiPlatform\Core\Bridge\Doctrine\Orm\ItemDataProvider.
*
* @see \App\EventListener\LocaleListener::onKernelRequest
* @see \App\Serializer\TranslatableContextBuilder::createFromRequest
* Involved in the translation process.
*
*/
public function getItem(
string $resourceClass,
$id,
string $operationName = null,
array $context = []
) {
$result = parent::getItem(
$resourceClass,
$id,
$operationName,
$context
);
if (!is_subclass_of($resourceClass, TranslatableInterface::class)) {
return $result;
}
if ( ! isset($context['locale'])) {
throw new LogicException(
'This request requires a locale, but none was passed. You should pass the locale as an "Accept-Language" header. See https://www.w3.org/TR/ltli/ for the format of the value.'
);
}
// Normalize the locale.
// @TODO: duplicative with \App\EventListener\LocaleListener::onKernelRequest; DRY this out.
$accept_language = Locale::getPrimaryLanguage($context['locale']);
/* @var TranslatableInterface $result */
if (null !== $result) {
$result->setAcceptLanguage($accept_language);
}
return $result;
}
В приведенном выше примере Country
будет реализовывать TranslatableInterface
потому что у него есть переводимое поле.Address
не будет.
Проблема, с которой я сталкиваюсь, заключается в том, что я думал, что \ApiPlatform\Core\Bridge\Doctrine\Orm\ItemDataProvider::getItem
вызывается рекурсивно, например, сначала getItem
будет вызываться для Address
, а затем getItem
будет вызыватьсядля Country
, чтобы я мог изменить результаты конкретного объекта.Похоже, что это не так.
Я ищу любые предложения, которые люди могут дать о том, что делать здесь.Должен ли я пытаться подключиться к другому событию или услуге?Должен ли я стремиться к расширению доктрины 1037 *?
Буду признателен за любые предложения.Заранее спасибо.