我使用Atlantic18/DoctrineExtensions的可翻译行为来翻译我的实体的一些字段。
有没有一种方法可以在yml中使用nelmo/alice创建数据固定装置,并在我的实体中设置多个翻译?
例如,我有:
use DoctrineORMMapping as ORM;
use GedmoMappingAnnotation as Gedmo;
use GedmoTranslatableTranslatable;
/**
* Lang
*
* @ORMTable()
* @ORMEntity
*/
class Lang implements Translatable
{
/**
* @var string
*
* @ORMColumn(name="name", type="string", length=255)
* @GedmoTranslatable
*/
private $name;
/...
}
在我的数据固定装置中:
use DoctrineCommonDataFixturesFixtureInterface;
use DoctrineCommonDataFixturesAbstractFixture;
use DoctrineCommonPersistenceObjectManager;
use AppBundleEntityLang;
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();
}
}
我想做一些类似的事情:
AppBundleEntityLang:
fr:
name: French
name_fr: Français
en:
name: English
name_fr: Anglais
或者可能在多个文件中。
感谢
您可以创建一个TranslatableProcessor服务,该服务实现Nelmio\Alice\ProcessorInterface并转换对象属性。
https://gist.github.com/istvankis/0010cf0e318258146d4f203007aaf1e2
对于语言翻译,我可以建议使用Symfony Intl组件
http://symfony.com/doc/current/components/intl.html#language-和脚本名称
夹具配置:
AppEntityProduct:
t_shirt:
translatable_locale: 'en|de'
name: 'My cool T-shirt|Mein cooles T-Shirt'
src/DataFixtures/TranslationsProcessor.php
:中的一个处理器
<?php
namespace AppDataFixtures;
use DoctrineCommonAnnotationsReader;
use DoctrineORMEntityManagerInterface;
use FidryAliceDataFixturesProcessorInterface;
use GedmoMappingAnnotationTranslatable;
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);
}
}
最后我找到了一个非常简单的解决方案,但只适用于一种语言。关于更多语言,请参阅我的另一个答案。
# src/DataFixtures/ORM/fixtures.yaml
AppEntityGender:
gender:
translatable_locale: 'en'
name: 'Female'
实体:
# src/Entity/Gender.php
<?php
namespace AppEntity;
use DoctrineORMMapping as ORM;
use GedmoMappingAnnotation as Gedmo;
use GedmoTranslatableTranslatable;
/**
* @ORMEntity(repositoryClass="AppRepositoryGenderRepository")
*/
class Gender implements Translatable
{
/**
* @ORMId()
* @ORMGeneratedValue()
* @ORMColumn(type="integer")
*/
private $id;
/**
* @GedmoTranslatable
* @ORMColumn(type="string", length=255)
*/
private $name;
/**
* @GedmoLocale
* 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 getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
public function setTranslatableLocale(string $locale): self
{
$this->locale = $locale;
return $this;
}
}