2017-06-14 83 views
1

我试图在symfony中做一个quizz,但我很难与渲染。创建quizz窗体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%} 

我知道这是不是这样做的方式,我应该创建一个形成并发送到视图的权利?

+0

“我知道这不是正确的做法”。为什么?从你的角度来看它有什么问题?此外,没有任何代码可以帮助你解决问题。屏幕截图只能说明故事的一小部分内容。 – ADyson

+0

你可以添加更多的信息,你的表单(类)和视图是怎样的? – lordrhodos

+0

@lordrhodos我编辑了一下,你想要我添加一些关于我的表单的信息? – Cesar

回答

1

我知道这不是这样做的,我应该创建一个窗体并将其发送到视图的权利?

这很大程度上取决于您的观点。 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 
    ); 
} 

在我迭代视图通过questionsQuiz,显示问题文本并遍历answers为每个Question,这几乎是相同的,你在做什么。但是,如果我要再次构建这样的东西,我会尝试遵循最佳实践并为其定义表单类。我将使用实体UserQuizAnswerUserQuizResult实体作为表单类型的基础并相应地构建表单。

这里是两个实体的提取物以查看映射定义:

UserQuizAnswer

# 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; 

UserQuizResult

# 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'; 
    } 
} 

为了使这项工作,你需要设置Question创建时,它传递给表单中的数据对象上,这样的形式只会显示有关这个问题的答案。

E.g.在你的控制器:

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 
)); 

在你的控制,你会比需要准备像数据:

/** @var UserQuizResult $userQuizResult */ 
$userQuizResult = new UserQuizResult(); 
$userQuizResult->setUser($this->getUser()); 

/** @var Question $question */ 
foreach ($quiz->getQuestions() as $question) { 
    $userQuizAnswer = new UserQuizAnswer(); 
    $userQuizAnswer->setQuestion($question); 

    // add answer to "collection" 
    $userQuizResult->addAnswer($userQuizAnswer); 
} 

$this->createForm(new UserQuizResult(), $userQuizResult); 

$userQuizAnswer = new UserQuizAnswer(); 
$userQuizAnswer->setQuestion($question); 

$this->createForm(new UserQuizAnswer(), $userQuizAnswer); 

UserQuizAnswerType表单类型的集合创建一个表单类型UserQuizResultType

+0

多好的评论!非常感谢@lordrhodos,我学到了很多! – Cesar

+0

@Cesar欢迎,如果这回答你的问题,你可能会接受答案,否则请提供一些更多的信息如何帮助完全。 – lordrhodos

+1

它工作得很好,我已经接受你的答案。它希望可以帮助很多像我这样的初学者。谢谢 ! – Cesar