Symfony 2:保存表单的referer并在提交时重定向到它referer

时间:2014-08-28 11:33:35

标签: php forms symfony symfony-forms

我有一个包含任何过滤器的实体列表(创建于,发布,发布等)...所有这些过滤器都使用GET查询发送。例如:/list?createdAt=...&published=yes。这是一个分页列表,页面上有寻呼机项目。每个项目都有一个编辑按钮,点击后,打开包含编辑表单的新页面。提交此表单后,我必须将用户重定向到最后一页(通过过滤器,最后一页等)。如何将用户重定向到最后一页(编辑前)?

我看到2个解决方案:

  1. 使用GET查询将URL保存到会话存储。该解决方案存在一个问题:如果我同时编辑多个(大于2个)实体,则存储数据已被重写。

  2. 在此窗体的隐藏(虚拟)字段中保存网址,在提交中,我有一个参考值。

  3. 可以有任何解决方案(组件,套件)吗?

1 个答案:

答案 0 :(得分:0)

我问了同样的问题。 最好是创建一个表单扩展名并动态添加一个隐藏字段。

<?php
// scr/Form/Extension/RedirectToRefererType.php

declare(strict_types=1);

namespace App\Form\Extension;

use App\Form\Listener\RedirectToRefererValidationListener;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\OptionsResolver\OptionsResolver;

class RedirectToRefererType extends AbstractTypeExtension
{
    private $requestStack;

    public function __construct(RequestStack $requestStack)
    {
        $this->requestStack = $requestStack;
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        // If the feature is not enabled, we quit
        if (!$options['redirect_to_enabled']) {
            return;
        }

        // We add a hidden field named "__redirect_to"
        $builder->add('__redirect_to', HiddenType::class, [
            'mapped' => false,
        ]);
        // We will dynamically set the redirect uri
        $builder->get('__redirect_to')->addEventSubscriber(new RedirectToRefererSubscriber($this->requestStack));
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        // We allow this feature to be disabled
        $resolver->setDefault('redirect_to_enabled', false);
        $resolver->setAllowedTypes('redirect_to_enabled', 'bool');
    }

    /**
     * {@inheritdoc}
     */
    public function getExtendedType()
    {
        // We extend all types of forms
        return FormType::class;
    }
}

事件订阅者:

<?php
// src/Form/Subscriber/RedirectToRefererSubscriber.php

declare(strict_types=1);

namespace App\Form\Listener;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\HttpFoundation\RequestStack;

class RedirectToRefererSubscriber implements EventSubscriberInterface
{
    private $requestStack;

    public function __construct(RequestStack $requestStack)
    {
        $this->requestStack = $requestStack;
    }

    public static function getSubscribedEvents()
    {
        return [
            FormEvents::PRE_SET_DATA => 'preSetData',
        ];
    }

    public function preSetData(FormEvent $event)
    {
        $form = $event->getForm();
        // We set the data if the form is not submitted (first view)
        if ($form->isSubmitted()) {
            return;
        }

        // If a referer is not available, we let the default value
        $request = $this->requestStack->getMasterRequest();
        if (!$request) {
            return;
        }
        $referer = $request->headers->get('referer');
        if (!$referer) {
            return;
        }

        // We set the data
        $event->setData($referer);
    }
}

服务定义

services:
    App\Form\Extension\RedirectToRefererType:
        tags:
            - {name: 'form.type_extension', extended_type: 'Symfony\Component\Form\Extension\Core\Type\FormType'}

现在,当您创建表单时,只需将选项redirect_to_enabled设置为true,字段__redirect_to将可用。

$redirectUri = $form->has('__redirect_to') ? $form->get('__redirect_to')->getData() : DEFAULT_REDIRECT_URI_GOES_HERE;