EntityType внутри CollectionType: Получить текущий объект внутри query_builder

#php #symfony #symfony-forms

#php #symfony #symfony-forms

Вопрос:

При использовании EntityType внутри CollectionType a возможно ли получить доступ к текущему объекту коллекции внутри query_builder функции EntityType?

Основная форма:

 class UsersType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('users', CollectionType::class, array('entry_type' => UserType::class));
    }
}
  

Вспомогательная форма:

 class UserType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('mainPost', EntityType::class, array(
                'class' => Post::class,
                'query_builder' => function (PostRepository $postRepository) {
                    return $postRepository->findPostsOfUser(); // <= Here I'd like to pass the *current* user to the repository
                },
            ))
        ;
    }
}
  

Причина: я не хочу видеть все сообщения у каждого пользователя, а только сообщения этого пользователя.

В документах EntityType говорится, что это невозможно:

При использовании вызываемого объекта вам будет передан EntityRepository объекта в качестве единственного аргумента…

Может быть, есть обходной путь? Есть идеи?

Ответ №1:

Вы могли бы сделать обходной путь с FormEvents . В PRE_SET_DATA случае задаются данные для единственной пользовательской сущности. Вы можете перезаписать его следующим образом:

 use SymfonyComponentFormFormEvent;
use SymfonyComponentFormFormEvents;

class UserType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('mainPost', EntityType::class, array(
                'class' => Post::class,
            ))
        ;

        $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
            $user = $event->getData();
            $form = $event->getForm();

            $field = $form->get('mainPost');
            $options = $field->getConfig()->getOptions();
            $options['query_builder'] = function (PostRepository $postRepository) use ($user) {
                return $postRepository->findPostsOfUser($user);
            };

            $form->add($field->getName(), EntityType::class, $options);
        });

    }
}
  

Комментарии:

1. Это работает только тогда, когда я удаляю строку $options = $field->getConfig()->getOptions(); . Мое решение: не добавляйте поле перед средством прослушивания событий, а только внутри него.