如何知道表单字段是否可翻译

时间:2013-01-09 18:08:56

标签: symfony doctrine-orm translation symfony-2.1

是否有快捷方式可以知道实体字段是否设置了@Gedmo\Translatable属性,比如渲染表单或显示实体值?

例如,有这个字段:

/**
 * @var string
 *
 * @ORM\Column(name="name", type="string", length=255)
 * @Gedmo\Translatable
 */
private $name;

在显示实体的同时,我想知道一个字段是否可以翻译,通过做这样的事情(伪代码想法它可能是什么或在 twig 模板中看起来像)< / p>

{% entity.title in entity.translatable.fields %}

注意:这背后的真正想法是在可翻译的表单字段上自动显示标记。

3 个答案:

答案 0 :(得分:2)

您可以创建一个Twig扩展名:

class TranslatableTypeExtension extends AbstractTypeExtension
{
/**
 * @var ObjectManager
 */
private $om;

/**
 * @var TranslatableListener
 */
private $listener;

/**
 * @param ObjectManager $om
 */
public function __construct(ObjectManager $om, TranslatableListener $listener )
{
    $this->om = $om;
    $this->listener = $listener;
}

private function isTranslatableField($object, $name)
{
    $config = $this->listener->getConfiguration($this->om, get_class($object));

    if (isset($config['fields']) && in_array($name, $config['fields']) ) 
        return true;
    return false;
}

public function buildView(FormView $view, FormInterface $form, array $options)
{
    if ( $form->getParent() == null )
        return;

    if ( is_object($form->getParent()->getData())) {
        if ( $this->isTranslatableField($form->getParent()->getData(),    $form->getName()) )
            $view->vars['field_translatable'] = true;
    }
}

/**
 * Returns the name of the type being extended.
 *
 * @return string The name of the type being extended
 */
public function getExtendedType()
{
    return 'field';
}
}

按如下方式加载此扩展程序:

my_extension.translatable_type_extension:
    class: Acme\DemoBundle\Form\Extension\TranslatableTypeExtension
    arguments: ["@doctrine.orm.entity_manager", "@gedmo.listener.translatable"]
    tags:
        - { name: form.type_extension, alias: field }

在您的树枝模板中,您可以使用以下内容:

{% if field_translatable is defined and field_translatable %} Translatable field {% endif %}

答案 1 :(得分:1)

在您的实体存储库中,假设您扩展了TranslationRepository,您可以创建一个自定义函数来检索具有翻译的字段。您可以按照

的行在存储库中创建自定义方法
use use Doctrine\ORM\Query;
use Gedmo\Translatable\Entity\Repository\TranslationRepository;

class MyEntityRepository extends TranslationRepository 
{

     public function getTranslatableFieldsByClass($className)
     {
            $translationMeta = $this->getClassMetadata();

            $qb = $this->_em->createQueryBuilder();
            $qb->select('trans.field')
                ->from($translationMeta->rootEntityName, 'trans')
                ->where('trans.objectClass = :entityClass')
                ->groupBy('trans.field');

            $q = $qb->getQuery();

            $data = $q->execute(
                array('entityClass' => $className),
                Query::HYDRATE_ARRAY
            );

            return (array) $data;
     }
}

然后将结果加载到模板中,并使用与上面提到的类似的“in”子句。

$translatableFields = $this->getDoctrine()->getRepository('MyBundle:MyTranslatableEntity')->getTranslatableFieldsByClass(get_class($myTranslatableEntity));

答案 2 :(得分:0)

我有相同的要求尽管接受的答案对我有用,因为它依赖于已翻译的字段。因为我想要它,即使db是空的,我想出了基于Gedmo ExtensionMetadataFactory的解决方案。 (解决方案是在SF 2.8和PHP 7.1上编写的)

 [...]

use Doctrine\ORM\EntityManager;
use Gedmo\Translatable\TranslatableListener;

/**
 * Helper Class TranslatableFieldsHelper - allow to get array of translatable fields for given entity class.
 *
 * @package [...]
 * @author [...]
 */
class TranslatableFieldsHelper
{
    /**
     * @var TranslatableListener
     */
    protected $listener;
    /**
     * @var EntityManager
     */
    protected $em;

    /**
     * TranslatableFieldsHelper constructor.
     * @param TranslatableListener $listener
     * @param EntityManager $em
     */
    public function __construct(TranslatableListener $listener, EntityManager $em)
    {
        $this->listener = $listener;
        $this->em = $em;
    }

    /**
     * Get translatable fields list of given class
     *
     * @param string $class
     * @return array
     */
    public function getTranslatableFields(string $class): array
    {
        $config = $this->listener->getConfiguration($this->em, $class);

        return $config && isset($config['fields']) && is_array($config['fields']) ? $config['fields'] : [];
    }
}

实现此类后,只需将其注册为服务:

_alias_:
    class: _class_
    arguments: ['@stof_doctrine_extensions.listener.translatable', '@doctrine.orm.default_entity_manager']

并使用它:

$this->container->get(__alias__)->getTranslatableFields(__your_entity_class__);

编辑: