创建quizz form symfony

时间:2017-06-14 14:02:17

标签: php symfony

我正试图在symfony中进行一项搜索,但我很难完成渲染。

这是我的数据库:

Databse

序列(quizz)可以有很多问题,这些问题有多个答案,用户可以选择一个答案。

但是它的构建方式,我不知道如何创建一个简单的表单,所以当用户选择一个答案时,它将更新该用户。 简单的树枝渲染:

Twig render

这是视图代码(我删除了一些html):

{% for sequence in enquete.sequences %}
{% for questseq in sequence.QuestionsSequence %}

<input id="textinput" name="textinput" type="text" placeholder="{{questseq.Intitule}}" class="form-control input-md">

<!-- Multiple Checkboxes -->
<div class="form-group">
  <label class="col-md-4 control-label" for="checkboxes">Réponses :</label>
   {% for repseq in questseq.ReponsesQuestion %}
  <div class="checkbox">
    <label for="checkboxes-{{repseq.id}}">
      <input type="checkbox" name="checkboxes" id="checkboxes-{{repseq.id}}" value="1">
      {{ repseq.Intitule }}
     {%endfor%}
{% endfor %}
{%endfor%}

我知道这不是这样做的方法,我应该创建一个表格并将其发送到视图中吗?

1 个答案:

答案 0 :(得分:2)

  

我知道这不是这样做的方法,我应该创建一个表格并将其发送到视图中吗?

这在很大程度上取决于你的观点。 Symfony Best Practices建议将表单定义为PHP类,但在这种情况下实现这一点并不容易。

在我过去创建MOOC的一个项目中,我面临着类似的任务:在每个模块的末尾显示一个测验,其中只有一个答案类型的多个问题(单选按钮)。我已经实现了以下实体 - 可以映射到您的实体

  • Quiz(序列)
  • Question(question_sequence)
  • Answer(response_sequence)
  • UserQuizAnswer(response_sequence_utilisateur)
  • UserQuizResult
  • User(utilisateur)

除了我创建的持久性实体未映射UserQuizAnswerEvaluationUserQuizEvaluation,因为我需要检查天气,用户达到了某个阈值(80%)通过测验的正确答案。

我当时的解决方案(最快,不是最好的)是将测验对象从控制器传递到树枝视图,并在没有任何Form Classes的情况下渲染表单:

# src/AppBundle/Controller/QuizController.php
public function showAction($id, Request $request)
{
    $quiz = $this->get('app.quiz.manager')->findQuizById($id);
    if (!$quiz) {
        throw new EntityNotFoundException();
    }

    $viewParams = ['quiz' => $quiz];

    ...

    return $this->render(
      'AppBundle:quiz:show.html.twig',
        $viewParams
    );
}

在视图中,我遍历questions的{​​{1}},显示问题文本,并针对每个Quiz迭代answers,所以几乎相同你在干嘛。

Question

但是,如果我再次构建这样的东西,我会尝试遵循最佳实践并为其定义表单类。我会使用实体# src/AppBundle/Resources/views/quiz/show.html.twig <form action="{{ path('quiz_evaluate', {'id': quiz.id}) }}" method="post"> {% for question in quiz.questions %} <div class="content-element"> <p>{{ loop.index }}. {{ question.text }}</p> {% for answer in question.answers %} {% if evaluation is defined %} {% if (answer.id == evaluation.answers[question.id].answerId) %} {% set checked = 'checked' %} {% else %} {% set checked = '' %} {% endif %} {% endif %} <div class="radio"> <label> <input type="radio" name="answers[{{ question.id }}]" value="{{ answer.id }}" {% if checked is defined %}{{ checked }}{% endif %} > <span class="upper">{{ loop.index|numberToAlphabet }}.</span> {{ answer.text }} </label> </div> {% endfor %} </div> {% if evaluation is defined %} <br> {% if evaluation.answers[question.id].isCorrect %} <div class="alert alert-success"> <h3><i class="fa fa-check"> Success</i></h3> {% else %} <div class="alert alert-danger"> <h3><i class="fa fa-times"></i> Almost, please try again</h3> {% endif %} {{ question.answerDescription }} </div> {% endif %} <div class="divider"></div> {% endfor %} {% if app.user and is_granted('ROLE_PRE_SURVEY_COMPLETED') %} <input type="submit" class="btn btn-enroll btn-block" value="Submit your answers"> </form> UserQuizAnswer实体作为表单类型的基础,并相应地构建表单。

以下是两个实体的摘录,以查看映射定义:

<强> UserQuizAnswer

UserQuizResult

<强> UserQuizResult

# src/AppBundle/Entity/UserQuizAnswer.php
/**
 * UserQuizAnswer
 *
 * @ORM\Table(name="user__quiz__answer")
 * @ORM\Entity
 */
class UserQuizAnswer
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var Question
     *
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Question")
     */
    private $question;

    /**
     * @var Answer
     *
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Answer")
     */
    private $answer;

    /**
     * @var UserQuizResult
     *
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\UserQuizResult", inversedBy="answers")
     */
    private $quizResult;

以下代码是一个未经测试的示例,它只是为了让您了解如何构建表单类型类

创建表单类型# src/AppBundle/Entity/UserQuizResult.php /** * UserQuizResult * * @ORM\Table(name="user__quiz__result") * @ORM\Entity(repositoryClass="AppBundle\Entity\UserQuizResultRepository") */ class UserQuizResult { use ORMBehaviors\Timestampable\Timestampable; /** * @var integer * * @ORM\Column(name="id", type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") */ private $id; /** * @var User * @ORM\ManyToOne(targetEntity="AppBundle\Entity\User", inversedBy="quizResults") */ private $user; /** * @var Quiz * * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Quiz", inversedBy="results") */ private $quiz; /** * @ORM\OneToMany(targetEntity="AppBundle\Entity\UserQuizAnswer", mappedBy="quizResult", cascade={"persist", "remove"}, orphanRemoval=true) */ private $answers; ,引用该问题并呈现该问题的可能答案。

UserQuizAnswerType

要完成这项工作,您需要在创建表单时在传递给表单的数据对象上设置# src/AppBundle/Form/UserQuizAnswerType.php <?php namespace AppBundle\Form; use AppBundle\Entity\Question; use AppBundle\Entity\UserQuizAnswer; use Doctrine\ORM\EntityRepository; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolverInterface; class UserQuizAnswerType extends AbstractType { /** * @param FormBuilderInterface $builder * @param array $options */ public function buildForm(FormBuilderInterface $builder, array $options) { /** @var UserQuizAnswer $userQuizAnswer */ $userQuizAnswer = $builder->getData(); /** @var Question $question */ $question = $userQuizAnswer->getQuestion(); $builder ->add('question') ->add( 'answer', EntityType::class, [ 'class' => 'AppBundle:Answer', 'query_builder' => function (EntityRepository $er) use ( $question ) { return $er->createQueryBuilder('a') ->where('a.question = :question') ->setParameter('question', $question); }, 'choice_label' => 'text', ] ); } /** * @param OptionsResolverInterface $resolver */ public function setDefaultOptions(OptionsResolverInterface $resolver) { $resolver->setDefaults( [ 'data_class' => 'AppBundle\Entity\UserQuizAnswer', ] ); } /** * @return string */ public function getName() { return 'appbundle_userquizanswer'; } } ,因此表单只会显示与该问题相关的答案。

E.g。在你的控制器中:

Question

使用$userQuizAnswer = new UserQuizAnswer(); $userQuizAnswer->setQuestion($question); $this->createForm(new UserQuizAnswer(), $userQuizAnswer); 表单类型的集合创建表单类型UserQuizResultType

UserQuizAnswerType

在您的控制器中,您需要准备以下数据:

use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
// ...

$builder->add('answers', CollectionType::class, array(
    'entry_type'   => UserQuizAnswerType::class,
    'allow_add'  => false
));