用Symfony和树枝重定向 详细信息

问题描述

在我的Symfony项目中,我有两种看法。特定实体的“详细信息”视图和一个按钮,可将我带到带有日期参数的其他数据的新视图。

我的代码存在问题,是从第二种方法返回第一种方法生成“返回上一页页面按钮。

代码

/**
 * @Route("/details/{id}",name="first_method")
 */
public function firstMethod(Detail $id)
{
    $workspace = $this->entityManager
        ->getRepository(Detail::class)
        ->find($id);

    $build['detail'] = $detail;

$form = $this->createFormBuilder()
        ->add('date',DateTimeType::class,[
            'data' => new \DateTime(),'widget' => 'single_text'
        ])
        ->add(
            'save',SubmitType::class,[
                'attr' => ['class' => 'btn-submit']
            ]
        )
        ->getForm();

    $form->handleRequest($request);

    if ($form->isSubmitted() && $form->isValid()) {
        $data = $form->getData();
        $date = $data['date']

        return $this->redirectToRoute('second_method',[
            'date' => $date
        ]);
    }

    return $this->render('first-method.html.twig',[
          'detail' => $detail,]);
}

还有“第二种”方法

 /**
 * @Route("/second-method/{date}",name="second_method")
 */
public function secondMethod($date)
{
    return $this->render('second-method.html.twig',[
        'someData' => $someData,'date' => $date,]);
}

second_method树枝视图上有一个按钮,需要将我返回到method_one页面

如何完成此操作,因为第二种方法可能需要参数$ id,但是找不到提供它的方法。也许还有其他方法?有人可以帮忙吗?

我认为,第一种方式应该像这样:

{{ path('first_method',{'detailId':detail.id}) }}

解决方法

如@msg所示,您应该在第二页上提供第二个参数。然后,您需要@Entity批注进行Detail转换,并需要@ParamConverter批注进行日期转换:

/**
 * @Route("/second_method/{id_detail}/{date}",name="second_method")
 * @Entity("detail",expr="repository.find(id_detail)")
 * @ParamConverter("date",options={"format": "!Y-m-d"})
 */
public function (Detail $detail,\DateTime $date)
// ...

参数转换将执行第一次完整性检查,如果该实体不存在,则返回404。 您还可以在控制器中签入$detail与URL中的date一致。请记住:永远不要信任用户输入(包括URL)。

当您重定向到第二个控制器时,您可以提供此新参数:

return $this->redirectToRoute("second_method",[
    "date" => $date,"id_detail" => $workspace->getId() // You can also pass the whole object and fetch the ID in the template
]);

然后在您的模板中:

{{ path('first_method',{'id': id_detail}) }}

详细信息

对于ParamConverters,您可以在这里找到更多详细信息:https://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/converters.html

我个人更喜欢使用@Entity注释来进行Entity的转换,因为您确定转换是如何完成的:我发现,当项目增长且实体具有越来越多的参数时,它会更好。即使@ParamConverter适用于您的情况。

,

替代方法,无需更改second_method路由参数,而仅依赖于引荐来源网址。

将辅助方法添加到控制器:

/**
 * Returns the referer url to redirect back if the request came from first_method
 * Otherwise returns FALSE.
 */
private function getBackUrl(Request $request,UrlMatcherInterface $matcher)
{
    $referer = $request->headers->get('referer');
    if (null === $referer) {
        return false;
    }

    $url = parse_url($referer);
    if ($url['host'] != $request->getHost()) {
        return false;
    }

    // Remove the baseurl if we're in a subdir or there's no Rewrite
    $path = str_replace($request->getBaseUrl(),'',$url['path']);
    try {
        $route = $matcher->match($path);
    } catch (ResourceNotFoundException $e) {
        // Doesn't match any known local route
        return false;
    }

    // A route has been determined,check if it matches the requirement
    if ('first_method' == $route['_route']) {
        return $referer;
    }

    return false;
}

将方法更改为(Route批注不会更改,只是方法签名):

public function secondMethod($date,Request $request,UrlMatcherInterface $matcher)
{
    return $this->render('second-method.html.twig',[
        'someData' => $someData,'date' => $date,'back_url' => $this->getBackUrl($request,$matcher),]);
}

在您的模板中:

{# Show the button only if the request came from first_method (otherwise will be false) #}
{% if back_url %}
     <a class="btn" href="{{ back_url }}">Return</a>
{% endif %}