我使用Translatable behaviour of Atlantic18/DoctrineExtensions来翻译我的实体的某些字段。
有没有办法在yml中使用nelmo/alice创建数据夹具并在我的实体中设置多个翻译?
例如,我有:
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Gedmo\Translatable\Translatable;
/**
* Lang
*
* @ORM\Table()
* @ORM\Entity
*/
class Lang implements Translatable
{
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=255)
* @Gedmo\Translatable
*/
private $name;
/...
}
在我的数据夹具中:
use Doctrine\Common\DataFixtures\FixtureInterface;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\Persistence\ObjectManager;
use AppBundle\Entity\Lang;
class LangData extends AbstractFixture implements FixtureInterface
{
/**
* {@inheritDoc}
*/
public function load(ObjectManager $manager)
{
$langs = array(
array('French', 'Français'),
array('English', 'Anglais')
);
$repo = $manager->getRepository('GedmoTranslatable:Translation');
foreach ($langs as $aLang) {
$oLang = new Lang();
$oLang->setName($aLang[0]);
$repo->translate($oLang, 'name', 'fr', $aLang[1]);
$manager->persist($oLang);
}
$manager->flush();
}
}
我想做类似的事情:
AppBundle\Entity\Lang:
fr:
name: French
name_fr: Français
en:
name: English
name_fr: Anglais
或者可能在多个文件中。
由于
答案 0 :(得分:0)
您可以创建一个TranslatableProcessor服务,该服务实现Nelmio \ Alice \ ProcessorInterface并转换对象属性。
https://gist.github.com/istvankis/0010cf0e318258146d4f203007aaf1e2
对于语言翻译,我建议使用Symfony Intl组件
http://symfony.com/doc/current/components/intl.html#language-and-script-names
答案 1 :(得分:0)
最后,我找到了一个真正简单的解决方案:
# src/DataFixtures/ORM/fixtures.yaml
App\Entity\Gender:
gender:
locale: 'en'
name: 'Female'
如果您的实体具有locale
属性,则此方法有效(更多详细信息在Gedmo文档中)。您所要做的就是为此属性添加一个setter:
# src/Entity/Gender.php
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Gedmo\Translatable\Translatable;
/**
* @ORM\Entity(repositoryClass="App\Repository\GenderRepository")
*/
class Gender implements Translatable
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @Gedmo\Translatable
* @ORM\Column(type="string", length=255)
*/
private $name;
/**
* @Gedmo\Locale
* Used locale to override Translation listener`s locale
* this is not a mapped field of entity metadata, just a simple property
*/
private $locale;
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
//
// This one is to satisfy Gedmo :)
//
public function setTranslatableLocale($locale): self
{
$this->locale = $locale;
return $this;
}
//
// This one is to satisfy Alice :)
//
public function setLocale(string $name): self
{
$this->locale = $name;
return $this;
}
}
答案 2 :(得分:0)
灯具配置:
App\Entity\Product:
t_shirt:
translatable_locale: 'en|de'
name: 'My cool T-shirt|Mein cooles T-Shirt'
src/DataFixtures/TranslationsProcessor.php
中的处理器:
<?php
namespace App\DataFixtures;
use Doctrine\Common\Annotations\Reader;
use Doctrine\ORM\EntityManagerInterface;
use Fidry\AliceDataFixtures\ProcessorInterface;
use Gedmo\Mapping\Annotation\Translatable;
class TranslationsProcessor implements ProcessorInterface
{
private $reader;
private $em;
public function __construct(EntityManagerInterface $em, Reader $reader)
{
$this->reader = $reader;
$this->em = $em;
}
public function preProcess(string $id, $object): void
{
}
public function postProcess(string $id, $object): void
{
$class = new \ReflectionClass(get_class($object));
if (null === $locales = $this->getLocales($class, $object)) {
return;
}
foreach ($class->getProperties() as $property) {
foreach ($this->reader->getPropertyAnnotations($property) as $annotation) {
if ($annotation instanceof Translatable) {
$property->setAccessible(true);
$translations = explode('|', $property->getValue($object));
if (count($locales) !== count($translations)) {
throw new \Exception(sprintf('The number of translations in property "%s" of "%s" does not match the number of translatable_locale.', $property->getName(), $class->getName()));
}
foreach ($locales as $i => $locale) {
$property->setValue($object, $translations[$i]);
$object->setTranslatableLocale($locale);
$this->em->persist($object);
$this->em->flush();
}
}
}
}
}
private function getLocales(\ReflectionClass $class, $object): ?array
{
try {
$property = $class->getProperty('locale');
} catch (\ReflectionException $e) {
return null;
}
$property->setAccessible(true);
$locales = $property->getValue($object);
return explode('|', $locales);
}
}