Symfony 2 Action最初只能从另一个Action访问吗?

时间:2016-07-10 23:20:59

标签: symfony symfony-forms

我努力在问题的标题中表达我的意思!我会尽力在这里更有意义......

Symfony 2.7

我有一个表格,在提交并成功验证时,我想提供第二个独立表格,以便进一步开展用户活动。我希望第二种形式的初始值由第一种形式提供,但第二种形式则是独立的,例如它可以通过自己独立的提交/验证步骤。

我不想要:

  • 用户可以直接进入第二种形式
  • 必须将第二个表单的值作为查询字符串参数传递
  • 使用Javascript实现此目的
  • 以第一种形式将数据保存到数据库,然后在第二种形式中将数据提取到

从概念上讲,我希望能够验证第一个表单,然后在Controller中将收到的数据传递给另一个Action,这将向用户显示新表单。然后,新动作将处理进一步的用户提交。我觉得这应该是可能的,我只是不确定如何实现它!在某种程度上,我希望第二个Action是私有的,但它确实需要公开,以便可以提交第二个表单。我希望能够使用对象直接将数据传递给第二个Action,但我不想将该入口点公开为标准Route。

提前致谢。

2 个答案:

答案 0 :(得分:0)

Sorry for any lack of clarity in the question. Here's how I solved it (I'd still be interested in any different/better solutions):

I created a separate FormType (ReportConfirmType) and Action (ConfirmAction) for the second step. ReportConfirmType has the type of Data Class, and essentially all the same fields as the original FormType (ReportType), but with them all marked readonly. The route is very similar. I also created a private method to act as the "glue" between the first and second steps.

When I'm finished with my first step, I then call the private method, passing it the validated data from the first step (which can be used unchanged). This method sets up the second form and returns the second view. The action of the form needs to be changed to that of the second route.

All subsequent submissions will go to the new route, and when the second form validates I can carry out the final activities of the process.

Here's some example code to illustrate further:

ReportType

class ReportType extends AbstractType{

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('name', 'text')
        ->add('completedBy', 'text')
        ->add('comments', 'textarea', ['required' => false])
        ->add('format', 'choice', ['choices' => ['pdf' => 'PDF', 'word' => 'MS Word'] ])
        ->add('save', 'submit', ['label' => 'Submit', 'attr' => ['class' => 'btn btn-primary']])
        ->getForm();
}

...

ReportConfirmType

class ReportConfirmType extends AbstractType{

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('name', 'text', ['attr' => ['readonly' => 'readonly']])
        ->add('completedBy', 'text', ['attr' => ['readonly' => 'readonly']])
        ->add('comments', 'textarea', ['required' => false, 'attr' => ['readonly' => 'readonly']])
        ->add('format', 'choice', ['choices' => ['pdf' => 'PDF', 'word' => 'MS Word'], 'attr' => ['readonly' => 'readonly'] ])
        ->add('agree', 'checkbox', ['mapped' => false, 'label' => 'I agree', 'constraints' => [new IsTrue()]])
        ->add('save', 'submit', ['label' => 'Submit', 'attr' => ['class' => 'btn btn-primary']])
        ->getForm();
}

...

ReportController

class ReportController extends Controller
{

public function indexAction(Request $request, $id)
{
    $form = $this->createForm(new ReportType(), new ReportDetails() );

    $form->handleRequest($request);

    if ($form->isValid()) {
        return $this->confirmPseudoAction($id, $form);
    }

    return $this->render('Bundle:Report:index.html.twig', ['form'=> $form->createView()]);
}

private function confirmPseudoAction($id, \Symfony\Component\Form\Form $form)
{
    $action = $this->generateUrl('form_confirm_report', ['id' => $id]);
    $confirmForm = $this->createForm(new ReportConfirmType(), $form->getData(), ['action' => $action]);

    return $this->render('Bundle:Report:confirm.html.twig', ['form'=> $confirmForm->createView()]);
}

public function confirmAction(Request $request, $id)
{
    $form = $this->createForm(new ReportConfirmType(), new ReportDetails() );

    $form->handleRequest($request);

    if ($form->isValid()) {
        return $this->generateReport($id, $form->getData());
    }

    return $this->render('Bundle:Report:confirm.html.twig', ['form'=> $form->createView()]);
}

...

routing.yml

form_report:
    path: /form/{id}/report
    defaults: { _controller: Bundle:Report:index }
    requirements:
        id:  \d+

form_confirm_report:
    path: /form/{id}/reportConfirm
    defaults: { _controller: Bundle:Report:confirm }
    requirements:
        id:  \d+

And this does what I want! There may be an easier way, but I've done it now...

答案 1 :(得分:0)

我相信您可以为提交的表单使用动态生成。 It allows you to customize the form specific to the data that was submitted by the user