Как узнать, является ли поле формы переводимым

Есть ли ярлык, чтобы узнать, имеет ли поле entity значение свойства @Gedmo \ Translatable , скажем, при визуализации формы или отображения значений сущности?

Например, имея это поле:

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

Показывая объект, я хотел бы знать, может ли поле быть переводимым, сделав что-то вроде этого (идея псевдокода того, что она может быть или выглядит в шаблонах twig )

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

Примечание. Настоящая идея заключается в том, чтобы автоматически отображать маркер в поле для переводимой формы.

1
nl ja de

3 ответы

Вы можете создать расширение 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 %}
2
добавлено

В репозитории вашей организации, предполагая, что вы расширяете 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;
     }
}

Затем загрузите результаты в свой шаблон и используйте аналогичное предложение «в», как вы упомянули выше.

$translatableFields = $this->getDoctrine()->getRepository('MyBundle:MyTranslatableEntity')->getTranslatableFieldsByClass(get_class($myTranslatableEntity));
1
добавлено
Аккуратно, но в случае, если у меня много переводимых объектов (10+), это, похоже, является такой повторяющейся задачей. Я также забыл упомянуть, что у меня есть сущность для каждого перевода, возможно, таким образом я мог бы избежать получения полей по классам? Как вы думаете ? Я пробую это сегодня. Спасибо за помощь.
добавлено автор rayfranco, источник
Хорошая идея ! Спасибо, что нашли время Майка, полезный ответ.
добавлено автор rayfranco, источник
У меня не так много опыта с расширением перевода, так как я создал свой ответ, посмотрев на источник пакета. Я думаю, что ваш ответ будет заключаться в создании расширения ветки, которое выполняет вышеупомянутый запрос, но сущность-агностик. Вы должны иметь возможность получить метаданные перевода на основе имени класса объекта, прошедшего через расширение ветки.
добавлено автор Mike, источник

У меня такое же требование, но принятый ответ не будет работать для меня, поскольку он полагается на уже переведенные поля. Поскольку я хочу его, даже если 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__);

РЕДАКТИРОВАТЬ:

0
добавлено
После написания этого, понял, что ответ Криса - это в основном одно и то же решение. Тем не менее решил сохранить это, в случае, если кому-то это понадобится :)
добавлено автор Maciej Jaśniaczyk, источник
symfony
symfony
1 045 участник(ов)

Сообщество Symfony, Symfony Components, Symfony Framework. Вакансии: https://t.me/symfony_careers Официальный slack: https://symfony.com/slack-invite

symfony
symfony
354 участник(ов)