Symfony 2 - как передать данные formBuilder?
Я использую список выбора сущности в своей форме. Я хочу использовать только определенные объекты (например: только группы, к которым принадлежит пользователь)
Итак, в контроллере я получаю эти группы и пытаюсь передать их в formBuider
.
Контроллер:
/.../
$groups = $em->getRepository('VendorMyBundle:Group')->getUserGroups($user);
$form = $this->createForm(new Message($groups), $message);
/.../
Итак, что теперь? как использовать его в formBuilder?
как изменить эту строку для использования переданного массива групп?
->add('group','entity',array('class' => 'Vendor\MyBundle\Entity\Group', 'label'=>'Group:'))
или по-другому:
class MessageType
{
/.../
public function buildForm(FormBuilder $builder, array $options)
{
$builder
->add('group','entity',
array(
'class' => 'Vendor\MyBundle\Entity\Group',
'property' => 'name',
'query_builder' => function ($repository) {
$qb = $repository->createQueryBuilder('group');
$qb->add('where', 'group.administrator = :user');
$qb->setParameter('user', $user->getId());
return $qb;
},
'label' => 'Group'
)
)
// Continue adding fields
;
}
/.../
}
так как я могу получить объект $user для использования в построителе форм? ($ user представляет текущего зарегистрированного пользователя)
Ответы
Ответ 1
Вы можете указать объект, который хотите использовать в методе __construct().
Например:
$form = $this
->get('form.factory')
->create(new ApplyStepOneFormType($this->company, $this->ad), $applicant);
В вашем виде формы:
function __construct(\Your\Bundle\Entity\Company $company, \DYB\ConnectBundle\Entity\Ad $ad) {
$this->company = $company;
$this->ad = $ad;
}
И затем в форме формы в методе buildForm:
$company = $this->company;
$builder->add('ad', 'entity', array(
'class' => '\Your\Bundle\Entity\Ad',
'query_builder' => function(\Your\Bundle\Repository\AdRepository $er) use ($company) {
return $er->getActiveAdsQueryBuilder($company);
},
));
Ответ 2
//In controller pass the value which you want to use in builder form in array like
$object = new Question();
$form->create(new QuestionType() , $object , array('sqtname'=>2,'question_type'=>2));
//In Form type class
public function buildForm(FormBuilderInterface $builder , array $options)
{
//for setting data field dynamically
if (array_key_exists('question_type', $options) && $options['question_type'] != '') {
$data = $em->getReference("RecrutOnlineStandardBundle:StdQuestionType",$options['question_type']->getId());
} else {
$data = "";
}
$builder->add('StdQuestionType', 'entity', array(
'class' => 'TestStandardBundle:StdQuestionType',
'property' => 'name',
'empty_value' => 'Sélectionner un question type',
'required' => true,
'data' => $data,
'query_builder' => function(EntityRepository $er ) use ( $options ) {
if (isset($options['sqtname']) && $options['sqtname'] != '') {
return $er->createQueryBuilder('sqt')
->where("sqt.name!= ".$options['sqtname']);
} else{
return $er->createQueryBuilder('sqt');
}
}
));
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Test\QuestionBundle\Entity\Question',
'required' => false,
'sqtname' => '',
'question_type' =>''
));
}
Ответ 3
Бактериальное решение НЕ является хорошим. Например, если вы объявляете свой тип как службу, невозможно передать объект конструктору.
Идеальное решение - это опции - просто передайте данные в качестве опции для создания компоновщика.
Ответ 4
Если вы хотите использовать пользовательский запрос, вы должны установить query_builder
вариант следующим образом:
use Doctrine\ORM\EntityRepository;
...
$message = new Message();
$form = $this->createFormBuilder($message)
->add('group', 'entity', array(
'class' => 'Vendor\MyBundle\Entity\Group',
'label'=>'Group:',
'query_builder' => function(EntityRepository $er) {
return $er->createQueryBuilder('g')
->... // whatever you want to do
}
))
->getForm();
Вы можете найти дополнительную информацию о построителе запросов в Руководство по Doctrine и о параметрах entity
в Руководство по Symfony2.
Ответ 5
Бактериальное решение является хорошим. Просто заметьте, чтобы сохранить головную боль другому человеку, как я:)
В этой части можно указать часть use ($company)
.
Он был спрятан фреймом и, конечно, без него ничего не работает.
$builder->add('ad', 'entity', array(
'class' =>
'\Your\Bundle\Entity\Ad',
'query_builder' =>
function(\Your\Bundle\Repository\AdRepository $er) use ($company) {
return $er->getActiveAdsQueryBuilder($company);
},
)
);
Ответ 6
Лучший способ (мое мнение) - предоставить вашей форме entityManager и выбрать все, что вам нужно. Но не забудьте объявить пустой ключ в setDefaults(), иначе данные не будут переданы вашему строителю.
Что-то вроде этого
public function buildForm(FormBuilderInterface $builder, array $options)
{
$options['em']->getRepository(''); // select all you need
$builder->add('title', 'text')
->add('content', 'textarea');
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Main\BlogBundle\Entity\Post',
'validation_groups' => array('post'),
'required' => false,
'em' => null // this var is for your entityManager
));
}
Применять EM как простой вариант...