Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony 2: Save referer for form and redirect to it referer on submit

I have a entity list with any filters (created at, posted at, published, etc)... All this filters send with GET query. As example: /list?createdAt=...&published=yes. This is a pagination list, and on page has pager items. Each item has a edit button, and on click, open new page with editing form. After submit this form, i must redirect user to last page (via filters, last page, etc...). How i can redirect user to last page (before editing)?

I see 2 solution:

  1. Save URL with GET query to session storage. This solution have a problem: the storage data has been rewrite, if i edit many (larger than 2) entities simultaneously.

  2. Save URL in hidden (virtual) field for this form, and in submit, i have a referer value.

Can has a any solution (Components, Bundles)?

like image 454
ZhukV Avatar asked Jan 25 '26 04:01

ZhukV


1 Answers

I went to the same question. Best is to create a form extension and dynamically add a hidden field.

<?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;
    }
}

The event subscriber:

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

The service definition

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

Now, when you create your form, you just have to set the option redirect_to_enabled to true and the field __redirect_to will be available.

$redirectUri = $form->has('__redirect_to') ? $form->get('__redirect_to')->getData() : DEFAULT_REDIRECT_URI_GOES_HERE;
like image 168
Spomky-Labs Avatar answered Jan 27 '26 17:01

Spomky-Labs



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!