2013-03-19 4 views
2

이들은 SF2에 대한 첫 번째 단계입니다. 다른 엔티티가 포함 된 엔티티에 대해 다중 단계 양식을 설정하려고합니다.Symfony2가 하나의 결과로 다중 단계 형식을 병합합니다.

내가 (단축) 양식 유형

class ApplicationFormType extends AbstractType 
{ 
    protected $_step = 1; 

    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     if ($this->_step == 1) { 
      $builder 
       ->add('patient', new Type\PersonType()) 
       ->add('insurance', 'entity', array(
        'class' => 'Acme\MainBundle\Entity\Insurance', 
       )); 
     } elseif ($this->_step == 2) { 
      $nurse = new Type\PersonType(); 
      $nurse->requireBareData(); 
      $builder 
       ->add('nurse', $nurse) 
       ->add('nurse_type', 'entity', array(
        'class' => 'Acme\MainBundle\Entity\NurseType', 
        'expanded' => true, 
        'multiple' => false, 
       )) 
       ->add('nursing_support', 'checkbox', array(
        'required' => false, 
       )); 
     } 
    } 

    public function setStep($step) 
    { 
     $this->_step = $step; 
    } 

내 컨트롤러의 모양을했습니다

public function assistAction() { 
    $request = $this->getRequest(); 

    $step = $this->getSession()->get('assist_step', 1); 
    if ($request->getMethod() != 'POST') { 
     $step = 1; 
     $this->getSession()->set('assist_data', NULL); 
    } 
    $this->getSession()->set('assist_step', $step); 
    $application = new Application(); 
    $type = new ApplicationFormType(); 
    $type->setStep($step); 

    $form = $this->createForm($type, $application, array(
     'validation_groups' => array($step == 1 ? 'FormStepOne' : 'FormStepTwo'), 
    )); 
    if ($request->getMethod() == 'POST') { 
     $form->bindRequest($request); 
     if ($form->isValid()) { 
      if ($step == 1) { 

       $data = $form->getData(); 
       $this->getSession()->set('assist_data', serialize($data)); 
       $this->getSession()->set('assist_step', ++$step); 
       $type = new ApplicationFormType(); 
       $type->setStep($step); 
       $form = $this->createForm($type, $application, array(
        'validation_groups' => array('FormStepTwo'), 
       )); 

      } else { 

       $step_1 = unserialize($this->getSession()->get('assist_data', '')); 
       $data = $form->getData(); 
=>    $data->setPatient($step_1->getPatient()); 
=>    $data->setInsurance($step_1->getInsurance()); 
       $this->getSession()->set('assist_data', NULL); 
       $this->getSession()->set('assist_step', 1); 

      } 
     } 
    } 

    return $this->render('Acme:Default:onlineassist.html.twig', array(
     'form' => $form->createView(), 
     'step' => $step, 
    )); 
} 

같은 내 질문입니다, 내가 별도로 첫 번째 양식 단계를 "복사"속성이 있다면, 같은

$data->setPatient($step_1->getPatient()); 
$data->setInsurance($step_1->getInsurance()); 

또는 I 번째 형태 인트으로부터 데이터 세션의 데이터를 직렬화를 병합 피? 아니면 완전히 다른 접근 방식이 있습니까?

+0

다중 단계 양식의 궁극적 인 목적은 무엇입니까? 프로세스 전반에 걸쳐 제출 된 데이터 (유효하다면)를 유지하고 클라이언트가 데이터를 검토 한 다음 DB에 삽입하면 정확합니까? –

+0

@ThomasPotaire : 정확하지 않습니다. 클라이언트는 데이터를 검토하지 않습니다. FormType에서 볼 수 있듯이 두 번째 단계는 사용자가 채울 다른 엔터티 필드를 제공합니다. (그리고 세 번째 단계가 있습니다.) 사용자가 모든 단계를 완료하면 (btw : 두 번째 옵션은 곧 선택 될 것입니다.) 모든 관련 엔티티가있는 'Application'엔티티를 DB에 유지해야합니다. – rabudde

답변

0

좋아,

$pre_step = unserialize($this->getSession()->get('assist_data', '')); 
$data->setPatient($pre_step->getPatient()); 
$data->setInsurance($pre_step->getInsurance()); 
$data->setInsuranceNumber($pre_step->getInsuranceNumber()); 
$data->setInsuranceLevel($pre_step->getInsuranceLevel()); 

그리고 그런 식으로, 별도로 사전 단계 필드를 설정하는 것보다 다른 방법이 있어요 발견 나는 이미 지금까지 무슨 짓을했는지 : 여기

내가 그것을 구상하는 방법입니다 .

1

엔터티는 stackoverflow에 대한 응답에 따라 세션에 직렬화하여 입력 할 수 있습니다.

각 양식이 다른 유형 인 경우 여러 유형으로 유형을 구분할 것을 권장합니다.

public function submitAction($step = 1) 
{ 
    switch ($step) { 
     case 1: 
      $entity = new EntityOne(); 
      $form = $this->createForm(new EntityOneType(), $entity); 
      $template = "template_one.html.twig"; 
      $redirect = $urlToStepTwo; // which redirects to this controller action with $step = 2 
      break; 
     case 2: 
      $entity = new EntityTwo(); 
      $form = $this->createForm(new EntityTwoType(), $entity); 
      $template = "template_two.html.twig"; 
      $redirect = $urlToStepThree; // which redirects to this controller action with $step = 3 
      break; 
     case 3: 
      $entity = new EntityThird(); 
      $form = $this->createForm(new EntityThreeType(), $entity); 
      $template = "template_three.html.twig"; 
      $redirect = $urlToConfirmPage; // which redirects to another controller action that unserialize all entities and save them in the DB 
      break; 
     default: 
      throw $this->createNotFoundException(); 
      break; 
    } 

    $request = $this->get('request'); 
    $session = $this->get('session'); 

    if ($request->isMethod('post') === true) { 

     $form->bind($request); 

     if ($form->isValid() === true) { 
      $session->set('entity_'. $step, serialize($entity)); 

      return $this->redirect($redirect); 
     } 
    } 

    $params = array(
     'form' => $form->createView(), 
     'entity' => $entity 
    ); 

    return $this->render($template, $params); 
} 
+0

귀하의 솔루션은 별도의 엔티티에 적합합니다. 그러나 나는 세 가지 단계 중 두 단계에 대해 큰 개체를 사용합니다. 'ApplicationFormType'은'Application' 엔티티를 나타냅니다. (BTW : 당신의 코드는 SF2.2에 부합하지 않는다. 즉,'bindRequest'와'bind'와'getMethod()'vs'isMethod ('post')') – rabudde

+0

데이터 집합을 나타내는 두 가지 형식을 만들 수있다. 'Application'을 호출하고 이후에 그들을 융합시킵니다 (deprecated 호출에 대한 감사). –

+0

그건 정확히 내가하고있는 일이다. 그리고 그것은 정확하게 나의 질문입니다. 이 두 단계를 병합하는 방법. 그것은 PHP에서 하나의 문장으로 할 수 있을까요? 아니면 제가 수동으로 두 번째 단계에서 첫 번째 단계의 모든 속성을 설정할 수 있습니까? – rabudde