Я ищу решение для автоматического перевода объектов моего приложения Symfony. Я застрял с устаревшей базой данных, где переводы хранятся в той же таблице, что и дополнительные поля:
id | name | name_de | name_fr
1 | cat | Katze | chat
2 | dog | Hund | chien
Моя сущность отображается в соответствии с:
class Animal
{
/**
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*
* @var integer
*/
private $id;
/**
* @ORM\Column(name="name", type="string", length=64, nullable=false)
*
* @var string
*/
private $name;
/**
* @ORM\Column(name="name_de", type="string", length=64, nullable=false)
*
* @var string
*/
private $nameDe;
/**
* @ORM\Column(name="name_fr", type="string", length=64, nullable=false)
*
* @var string
*/
private $nameFr;
/* Followed by getters and setters */
}
Я уже изучаю расширение Translatable, но это не соответствует моей схеме базы данных. Я также начал с пользовательской привязки к событию postLoad
, но затем меня остановила простая проблема, с которой postLoad
может запускаться в прокси-состоянии объекта.
Затем я просмотрю пользовательский хост-запрос (в основном, модифицированный подход к расширению Translatable), но я надеюсь, что там будет менее сложное решение.
Приветствия Матиаса
Здесь есть немало решений, и я думаю, что я не смотрел на половину из них.
Во всяком случае, наименее сложное и, по крайней мере, немного чистое решение, к которому я придумал, использует статический класс для перевода. Это может выглядеть примерно так:
class Translation
{
/**
* @var string
*/
private static $language;
/**
* tries to get a translated property by prepending the
* configured language to the given entities getter
*
* @param object $entity
* @param string $getter
* @return mixed
*/
public static function getTranslated($entity, $getter) {
$language = self::getLanguage();
$translatedGetter = $getter.$language;
if(method_exists($entity, $translatedGetter)) {
return $entity->$translatedGetter();
} else {
return $entity->$getter;
}
}
/**
* @return string
*/
public static function getLanguage()
{
return self::$language;
}
/**
* @param string $language
*/
public static function setLanguage($language)
{
self::$language = ucfirst(strtolower($language));
}
}
Затем вы устанавливаете язык всякий раз, когда запускается ваше приложение, и реализуйте переводы либо в своих сущностях:
/**
* @return string
*/
public function getName()
{
return Translation::getTranslated($this, __FUNCTION__);
}
или вызвать его извне:
Translation::getTranslated($animal, "getName");
Итак, с первым методом этот код:
Translation::setLanguage("DE");
// far more code
/** @var Animal[] $animals */
$animals = $entityManager->getRepository(Animal::class)->findAll();
foreach ($animals as $animal) {
echo $animal->getName()."<br >";
}
потушит:
Katze
Hund
Это, конечно, один из способов сделать это со статическим классом.