как загрузить и сохранить данные поля формы для флажка из другого объекта в symfony2

Проект: Symfony 2.4, FOSUserBundle, SonataUserBundle.

Задача

У меня есть User объект и форма профиля для него. Я хочу добавить флажок для подписки напоминания. Это сохраняется в другом объекте «Настройка» (с односторонним отношением «Настройка» -> «Пользователь»). Если в «Настройках» есть строка для пользователя, следует поставить галочку, если строки нет - снять галочку. Итак, мне нужно:

  1. рендерить флажок
  2. загрузить данные
  3. сохранить данные

Реализация

1. Флажок «Визуализировать»

Я знаю, что это зависит от типа поля (потому что я думаю, что мог бы использовать тип entity), но теперь у меня есть этот код:

class ProfileFormType extends ProfileType
{
    $builder
    ->add("subscribeReminder", "checkbox",
        array(
            "mapped" => false,
            'required'  => false,
        )
    );
}

2. Загрузите данные

Я думаю, что это можно сделать, используя 'class' и 'query_builder' в параметрах поля, но мне это не удалось. Необходимо установить флажок в значение true, если настройка существует.

3. Сохраните данные

Я думаю, что могу сохранить данные в FormHandler->onSuccess() (передавая репозиторий конструктору). Нужно удалить строку или создать новую.

По дороге

Я полностью потерялся в документации. Можно реализовать EventListeners, EventSubscribers. Пробовал разные подходы безуспешно. Я думаю (надеюсь) есть что-то проще.


person Aurelijus Rozenas    schedule 07.05.2014    source источник


Ответы (1)


Если вы можете создать свойство или метод в классе User, который будет возвращать true, если пользователь подписан, вы можете добавить что-то вроде этого в конце вашего метода buildForm():

$user = $builder->getData();
if($user instanceof User && $user->isSubscribed())
{
    $builder->remove('subscribeReminder');
}

Если вы не можете создать такой метод или свойство, используйте массив параметров. Получите логическое значение в контроллере, например, если ваш пользователь подписан, и передайте значение в качестве опции в свою форму, например:

$form = $formFactory->create($formType, $entity, array('isSubscribed' => true));

Я передал true для простоты, но вы должны передать правильное логическое значение.

Затем в вашем типе формы добавьте этот метод:

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'isSubscribed' => false
    ));
}

Для дополнительной безопасности вы также можете проверить переданный параметр с помощью $resolver->setAllowedTypes()...

И в вашем buildForm() добавьте это в конце:

if($options['isSubscribed'])
{
    $builder->remove('subscribeReminder');
}

Извините за опечатки и удачи! :)

И последняя часть вашего вопроса: вы можете добавить события формы, но я думаю, что в этом сценарии лучше не усложнять.

Вы можете добавить обработчики событий в форму внутри buildForm():

$builder->addEventListener(FormEvents::SUBMIT, function(FormEvent $event) use ($something)
{
    ...
}
person tomazahlin    schedule 07.05.2014