我正在尝试创建用于测验的 Symfony 表单,其中每个问题都有问题和选择(请参阅实体代码)。我有
RequestQuestion
实体,其中包含 description, isActive, choices
。选择是另一个实体,包含 name, correct
和 relation
来提问。最后 Request
包含 ManyToMany 选择(表示用户勾选了此选项)。
但现在我有问题,我需要以某种方式通过问题对选择进行分组(使用具有多个和扩展 true 的 EntityType)。不 - EntityType 的 group_by 不适用于 multiple = Expanded = true。这仅适用于选择框。
后来我添加了
Request
与Question
的关系。这解决了一半的问题 - 我现在可以在 FormType 中将 CollectionType 添加到问题中(这是另一个 FormType RequestQuestionType
)。 isActive
或添加新问题及时更改) 。但现在的问题是在 RequestQuestionType
我无法添加答案,因为问题没有这种关系(只有 Request
或 QuestionChoice
)。
问题是我怎样才能将答案填入这个表格中?我无法使用父项(
RequestFormType
),因为我无法按问题对选择进行分组,并且在问题中(RequestQuestionType
)我无法添加关系。下面我发送代码的当前状态。
请求
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="uuid")
*/
private $uuid;
/**
* @ORM\ManyToOne(targetEntity=User::class, inversedBy="requests")
* @ORM\JoinColumn(nullable=false)
*/
private $User;
/**
* @ORM\Column(type="datetime")
*/
private $created;
/**
* @ORM\Column(type="datetime", nullable=true)
*/
private $resolved;
/**
* @ORM\ManyToOne(targetEntity=User::class)
*/
private $resolvedBy;
/**
* @ORM\Column(type="string", length=32)
*/
private $state;
/**
* @ORM\Column(type="string", length=255)
*/
private $address;
/**
* @ORM\ManyToMany(targetEntity=RequestQuestion::class, inversedBy="requests")
*/
private $questions;
/**
* @ORM\ManyToMany(targetEntity=RequestQuestionChoice::class, inversedBy="scholarRequestsAnswers")
*/
private $answers;
请求问题
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="text")
*/
private $description;
/**
* @ORM\Column(type="boolean")
*/
private $isActive;
/**
* @ORM\OneToMany(targetEntity=RequestQuestionChoice::class, mappedBy="Question", orphanRemoval=true)
*/
private $choices;
/**
* @ORM\ManyToMany(targetEntity=Request::class, mappedBy="questions")
*/
private $requests;
请求问题选择
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
*/
private $name;
/**
* @ORM\Column(type="boolean")
*/
private $correct;
/**
* @ORM\ManyToOne(targetEntity=RequestQuestion::class, inversedBy="choices")
* @ORM\JoinColumn(nullable=false)
*/
private $Question;
请求表单类型
class RequestFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('address', TextType::class, [
'constraints' => [
new NotBlank([
'message' => "Zadejte adresu"
])
]
])
->add('questions', CollectionType::class, [
'entry_type' => RequestQuestionType::class,
'entry_options' => [
'questions' => $builder->getData()->getQuestions()
]
])
->add('tos', CheckboxType::class, [
'mapped' => false,
'value' => false,
'constraints' => [
new IsTrue([
'message' => "Musíte souhlasit s našimi podmínkami použití"
])
]
])
->add('Submit', SubmitType::class)
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Request::class
]);
}
}
请求问题类型
class RequestQuestionType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$index = str_replace(["[", "]"], "", $builder->getPropertyPath());
$builder
->add('???', EntityType::class, [
'class' => RequestQuestionChoice::class,
'choice_label' => 'name',
'choices' => $options["questions"][$index]->getChoices(),
'expanded' => true,
'multiple' => true
]);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'questions' => []
]);
}
}
注意:由于某种原因,来自
RequestFormType
的问题不会作为数据传递(data = null),所以这就是我将它们作为 Entry_options 传递的原因。但在RequestQuestionType
中,它调用它的次数与问题数一样多,所以这有点奇怪,但我设法通过entry_otpions解决它并使用propertyPath中的索引。
注意:请求是使用虚拟数据 - 问题预先构建的,并传递到此表单。
注意:我之前也尝试过在用户勾选或不勾选选项时将 Request - RequestChoice 中的多对多关系分解为带有 bool 的 RequestAnwer 并预先生成 QuestionChoices 的所有答案。但是按问题对选择进行分组的问题也存在,所以我也无法让它发挥作用。
解决了。
我添加了
RequestQuestionAnswers
,它具有 OneToMany 到 RequestQuestion
(RequestQuestionAnswers
有一个问题),答案为 ManyToMany 到 RequestQuestionChoice
。这样,这个新实体就与问题 1:1 绑定,对于每个问题,我可以单独为每个问题生成 EntityType 并生成问题的选择。
如果有人遇到类似的问题,我将在此处粘贴最终代码。这个问题也非常有帮助:Create quizz form symfony
注意:遗憾的是我不能将其用于多个 false,因为
RequestQuestion.requestAnswers
是 Collection,因此它会抛出错误:Entity of type "Doctrine\Common\Collections\ArrayCollection" passed to the choice field must be managed. Maybe you forget to persist it in the entity manager?
请求表单类型
class RequestFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('address', TextType::class, [
'constraints' => [
new NotBlank([
'message' => "Zadejte adresu"
])
],
])
->add('requestAnswers', CollectionType::class, [
'entry_type' => RequestQuestionType::class,
'entry_options' => [
'request' => $builder->getData(),
'label_attr' => [
'class' => 'd-none'
]
],
'label' => 'Dotazník'
])
->add('tos', CheckboxType::class, [
'mapped' => false,
'value' => false,
'constraints' => [
new IsTrue([
'message' => "Musíte souhlasit s našimi podmínkami použití"
])
],
'label' => 'Souhlasím s podmínkami použití'
])
->add('Submit', SubmitType::class, [
'label' => 'Odeslat'
])
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Request::class
]);
}
}
请求问题类型
class RequestQuestionType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$index = str_replace(["[", "]"], "", $builder->getPropertyPath());
/** @var RequestAnswers $answers */
$answers = $options["request"]->getRequestAnswers()[$index];
$builder
->add('selectedChoices', EntityType::class, [
'class' => RequestQuestionChoice::class,
'choices' => $answers->getQuestion()->getChoices(),
'choice_label' => 'name',
'label' => $answers->getQuestion()->getDescription(),
'expanded' => true,
'multiple' => true
]);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => RequestAnswers::class,
'request' => null
]);
}
}