使用nelmio/alice和gedmo/条令扩展创建Fixture Translatable



我使用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;
    }
}

相关内容

  • 没有找到相关文章

最新更新