Я пытаюсь создать динамический Survey / Form Bundle для моего приложения в Symfony 3.2.4 и PHP 5.6.28
У меня есть 3 объекта: опрос / вопрос / ответ
Первый шаг — создать опрос для каждого пользователя.
Вопросы должны быть отображены перед соответствующими полями ответов.
При отправке они будут храниться в БД, классика.
Вопросы уже хранятся в БД Question.table.
Я хочу, чтобы форма работала. Показать все вопросы, хранящиеся в БД и представить ответы (связанные с вопросами). Также все ответы должны быть связаны с опросом, чтобы я мог отобразить конкретный результат опроса (после того, как пользователь завершил его)
Не могли бы вы помочь мне заставить это работать?
Я могу отображать только один ответ на последний вопрос, я что-то не так сделал в логике контроллера или в моем FormType?
Answer.entity
<?php
namespace SurveyBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Answer
*
* @ORM\Table(name="answer")
* @ORM\Entity(repositoryClass="SurveyBundle\Repository\AnswerRepository")
*/
class Answer
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="text", type="string", length=255)
*/
private $text;
/**
* Id from Company Entity
*
* @var int
*
* @ORM\ManyToOne(targetEntity="SurveyBundle\Entity\Survey", inversedBy="answer", cascade={"persist"})
*
*/
private $survey;
/**
* Id from Question Entity
*
* @ORM\OneToOne(targetEntity="SurveyBundle\Entity\Question", mappedBy="answer")
*/
private $question;/**
* Get id
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Set text
*
* @param string $text
*
* @return Answer
*/
public function setText($text)
{
$this->text = $text;
return $this;
}
/**
* Get text
*
* @return string
*/
public function getText()
{
return $this->text;
}
/**
* @return int
*/
public function getSurvey()
{
return $this->survey;
}
/**
* @param int $survey
*/
public function setSurvey($survey)
{
$this->survey = $survey;
}
/**
* @return mixed
*/
public function getQuestion()
{
return $this->question;
}
/**
* @param mixed $question
*/
public function setQuestion($question)
{
$this->question = $question;
}
}
Question.entity
<?php
namespace SurveyBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* Question
*
* @ORM\Table(name="question")
* @ORM\Entity(repositoryClass="SurveyBundle\Repository\QuestionRepository")
*/
class Question
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="text", type="string", length=255)
*/
private $text;public function __toString()
{
return (string) $this->text;
}
/**
* Get id
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Set text
*
* @param string $text
*
* @return Question
*/
public function setText($text)
{
$this->text = $text;
return $this;
}
/**
* Get text
*
* @return string
*/
public function getText()
{
return $this->text;
}}
Survey.entity
<?php
namespace SurveyBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* Survey
*
* @ORM\Table(name="survey")
* @ORM\Entity(repositoryClass="SurveyBundle\Repository\SurveyRepository")
*/
class Survey
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Id from Question Entity
*
* @ORM\OneToMany(targetEntity="SurveyBundle\Entity\Question", mappedBy="survey")
*/
private $question;function __construct()
{
$this->question = new ArrayCollection();
}
public function getQuestion()
{
return $this->question;
}
/**
* Id from Answer Entity
*
* @ORM\OneToMany(targetEntity="SurveyBundle\Entity\Answer", mappedBy="survey")
*/
private $answer;
public function setAnswer($answer)
{
$this->answer = $answer;
return $this;
}
/**
* @return mixed
*/
public function getAnswer()
{
return $this->answer;
}
/**
* @param Question $question
*/
public function addQuestion(Question $question)
{
$this->question[] = $question;
}}
Survey.controller
<?php
namespace SurveyBundle\Controller;
use SurveyBundle\Entity\Survey;
use SurveyBundle\Form\SurveyType;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Request;
class DefaultController extends Controller
{
/**
* @Route("/survey", name="survey")
*/
public function indexAction(Request $request)
{
$em = $this->getDoctrine()->getEntityManager();
$questions = $em->getRepository('SurveyBundle:Question')->findAll();
$survey = new Survey();
//$ListProduits->setProduits($produits);
foreach ($questions as $question)
$survey->addQuestion($question);
$form = $this->createForm(SurveyType::class, $survey);
$form->handleRequest($request);
if ($request->getMethod() === 'POST') {
if ($form->isSubmitted() && $form->isValid()) {
$em->persist($survey);
$em->flush();
$data = $form->getData();
var_dump($data);
echo 'OK2';
}else {
//ERROR
trigger_error('Error - Survey hasn\'t been completed - Contact a Wizard');
}
}return $this->render('SurveyBundle:Default:index.html.twig', array('form' => $form->createView()));
}
}
Survey.FormType
<?php
namespace SurveyBundle\Form;
use Doctrine\ORM\EntityRepository;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class SurveyType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
//->add('name','text')
->add('question', EntityType::class,
'class' => 'SurveyBundle:Question',
'mapped' => false,
"multiple" => true,
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('q')
->orderBy('q.text', 'ASC');
},
))
->add(
'answer',
AnswerType::class
)
;
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'SurveyBundle\Entity\Survey'
));
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'referencebundle_survey';
}}
У меня есть только одно поле ответа, только для вопроса 2. Мне нужно одно для каждого вопроса.
Также, когда я пытаюсь представить, я получил эту ошибку:
Исправляемая фатальная ошибка: аргумент 1 передан
Doctrine \ Common \ Collections \ ArrayCollection :: __ construct () должны иметь
массив типов, заданный объект, вызванный в
… / vendor / doctrine / orm / lib / Doctrine / ORM / UnitOfWork.php в строке 605
и определил
Вы задаете все вопросы с помощью оператора множественного => true, но это не связывает ответ с каждым вопросом. Тогда ваша форма дает ответ, поэтому вы видите только один ответ.
Я думаю, что вам нужно, это коллекция форм, см. Документы: http://symfony.com/doc/current/form/form_collections.html
Сначала создайте отдельную форму для каждого комбинированного вопроса / ответа, затем визуализируйте коллекцию форм из Survey.FormType.
Хорошо, я нашел решение благодаря @ehymel
В моем конструкторе форм опроса у меня теперь 2 CollectionType : Вопрос & Ответ
Каждый из них имеет свой собственный FormType.
Я сделал foreach в моем контроллере, чтобы связать Q & A с моим Объектом опроса и другим для сохранения моих ответов после отправки.
Я также немного переделал свои отношения с сущностями.
Контроллер:
$questions = $em->getRepository('SurveyBundle:Question')->findAll();
$survey = new Survey();
foreach ($questions as $question) {
$answer = new Answer();
$survey->getQuestion()->add($question);
$answer->setQuestion($question);
$survey->getAnswer()->add($answer);
}
$form = $this->createForm(SurveyType::class, $survey);
$form->handleRequest($request);
if ($request->getMethod() === 'POST') {
if ($form->isSubmitted() && $form->isValid()) {
$survey->setExperience($experience);
$em->persist($survey);
$em->flush();
foreach ($survey->getAnswer() as $answer) {
$answer->setSurvey($survey);
$em->persist($answer);
$em->flush();
}
} else {
//ERROR
trigger_error('Error - Experience hasn\'t been completed - Contact a Wizard');
}
}
SurveyType:
class SurveyType extends AbstractType{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
private $name = 'default_name';
public function getName(){
return $this->name;
}
public function setName($name){
$this->name = $name;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add(
'question',
CollectionType::class,
array(
'entry_type' => QuestionType::class)
)
->add(
'answer',
CollectionType::class,
array(
'entry_type' => AnswerType::class)
);
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'SurveyBundle\Entity\Survey'
));
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'referencebundle_survey';
}
}