Symfony2: Redirecting to last route and flash a message?

symfony redirecttoroute
symfony path with parameters
symfony/routing
symfony set referer
symfony annotationroute not working
symfony route optional parameter
php symfony routing
symfony notfoundhttpexception

I'm having a small problem when trying to flash a message and redirect the user back to the previous page in Symfony 2.

I have a very simple CRUD. When new, or edit, i want to flash a message if something goes wrong in the respective create/update methods:

  1. User --GET--> new
  2. new --POST--> create (fails)
  3. --REDIRECT--> new (with flash message)

I'm doing the following:

  $this->container->get('session')->setFlash('error', 'myerror');
  $referer = $this->getRequest()->headers->get('referer');   
  return new RedirectResponse($referer);

However, it's not redirecting to the correct referrer! Even though the value of referrer is correct (eg.: http://localhost/demo/2/edit/) It redirects to the index. Why?

This is an alternative version of Naitsirch and Santi their code. I realized a trait would be perfect for this functionality. Also optimized the code somewhat. I preferred to give back all the parameters including the slugs, because you might need those when generating the route.

This code runs on PHP 5.4.0 and up. You can use the trait for multiple controllers of course. If you put the trait in a seperate file make sure you name it the same as the trait, following PSR-0.

<?php
trait Referer {
    private function getRefererParams() {
        $request = $this->getRequest();
        $referer = $request->headers->get('referer');
        $baseUrl = $request->getBaseUrl();
        $lastPath = substr($referer, strpos($referer, $baseUrl) + strlen($baseUrl));
        return $this->get('router')->getMatcher()->match($lastPath);
    }
}

class MyController extends Controller {
    use Referer;

    public function MyAction() {
        $params = $this->getRefererParams();

        return $this->redirect($this->generateUrl(
            $params['_route'],
            [
                'slug' => $params['slug']
            ]
        ));
    }
}

Symfony2: Redirecting to last route and flash a message?, I'm having a small problem when trying to flash a message and redirect the user back to the previous page in Symfony 2. I have a very simple CRUD. When new  Symfony2: Redirecting to last route and flash a message? (6) For symfony 3.0,flash message with redirection back to previous page,this can be done in controller.

For symfony 3.0,flash message with redirection back to previous page,this can be done in controller.

           $request->getSession()
                ->getFlashBag()
                ->add('notice', 'success');
            $referer = $request->headers->get('referer');
            return $this->redirect($referer);

Symfony2: Redirecting to last route and flash a message?, symfony routing php symfony routing. I'm having a small problem when trying to flash a message and redirect the user back to the previous page in Symfony 2. Symfony Flash tutorial shows how to create flash messages in Symfony. Flash messages are temporary messages used for user notifications. They are stored in a session and vanish as soon as they are retrieved.

The message from Naitsirch presented in the next url: https://github.com/symfony/symfony/issues/2951

Seems a good solution for that you need:

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

    //look for the referer route
    $referer = $request->headers->get('referer');
    $lastPath = substr($referer, strpos($referer, $request->getBaseUrl()));
    $lastPath = str_replace($request->getBaseUrl(), '', $lastPath);

    $matcher = $this->get('router')->getMatcher();
    $parameters = $matcher->match($lastPath);
    $route = $parameters['_route'];

    return $route;
}

Then with a redirect:

public function yourFunctionAction()
{
    $ruta = $this->getRefererRoute();

    $locale = $request->get('_locale');
    $url = $this->get('router')->generate($ruta, array('_locale' => $locale));

    $this->getRequest()->getSession()->setFlash('notice', "your_message");   

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

‍ Symfony2: Redirect to last route and flash message?, This is an alternate version of Nitzirch and Santi of their code. I realized that the trait would be perfect for this functionality. The code is also slightly optimized. After processing the request, the controller sets a flash message in the session and then redirects. The message key (notice in this example) can be anything: you'll use this key to retrieve the message.

This works for me:

$this->redirect($request->server->get('HTTP_REFERER'));

Symfony2: Redirecting to last route and flash a message , I'm having a small problem when trying to flash a message and redirect the user back to the previous page in Symfony 2. I have a very simple  Hmm. To make this look right, we don't want to render that mb-5 class when there is a flash message. How can we do that? Back in base.html.twig, scroll up a bit to find the navbar. Ok: we could count the number of success flash messages, and if there are more than 0, do not print the mb-5 class. That's pretty simple, except for one huge problem!

I have similar functionality on my site. It is multilingual. Articles exists only in a single locale. When the user will try to switch to other locale, it should redirect back to previous page and flash message that that page/article doesn't exist on the requested locale.

/en/article/3 -> /fr/article/3 (404) -> Redirect(/en/article/3)

Here is my version of the script that works well on dev and prod environments:

$referer = $request->headers->get('referer')

// 'https://your-domain.com' or 'https://your-domain.com/app_dev.php'
$base = $request->getSchemeAndHttpHost() . $request->getBaseUrl();

// '/en/article/3'
$path = preg_replace('/^'. preg_quote($base, '/') .'/', '', $referer);

if ($path === $referer) {
    // nothing was replaced. referer is an external site
} elseif ($path === $request->getPathInfo()) {
    // current page and referer are the same (prevent redirect loop)
} else {
    try {
        // if this will throw an exception then the route doesn't exist
        $this->container->get('router')->match(
            // '/en/hello?foo=bar' -> '/en/hello'
            preg_replace('/\?.*$/', '', $path)
        );

        // '/app_dev.php' . '/en/article/3'
        $redirectUrl = $request->getBaseUrl() . $path;

        return new RedirectResponse($redirectUrl);
    } catch (\Symfony\Component\Routing\Exception\ResourceNotFoundException $e) {}
}

Save, Redirect, setFlash (and Dance) > Symfony 3 Forms: Build , Hmm, generate a URL to the admin_genus_list route - that's the main admin page Because then, you can set a flash message, redirect to any other page, and  I am having the same issue and I don't have an APPLICATION_ROOT in my project. After flashing a message, if I return redirect('/ ') the message doesn't appear on the redirected page but if I comment out the redirect and use return render_template("index.html") the message does display.

Controller (Symfony Docs), Generating URLs; Redirecting; Rendering Templates; Fetching Services Final Thoughts; Keep Going! This was done above with the @Route("/lucky/number/{​max}") route annotation. To see templates/base.html.twig #} {# read and display just one flash message type #} {% for message in app.flashes('notice') %} <div  PHP's session management requires the use of the $_SESSION super-global, however, this interferes somewhat with code testability and encapsulation in an OOP paradigm. To help overcome this, Symfony uses session bags linked to the session to encapsulate a specific dataset of attributes or flash messages.

Controller (Symfony 2.3 Book), After processing the request, the controller sets a flash message in the session and then redirects. The message key ( notice in this example) can be anything: you'  Redirecting to a new URL and flashing data to the session are usually done at the same time. Typically, this is done after successfully performing an action when you flash a success message to the session. For convenience, you may create a RedirectResponse instance and flash data to the session in a single, fluent method chain:

Get previous route and redirect after action (submitting form etc , I have no clue 'I cheated and used flash messages to store the referrer in my example app' what is going on over there. :expressionless: I think  Using the form_login Authentication Provider {last_username}} not a Symfony route name. Defining the redirect URL via GET using a query string parameter: 1.

Comments
  • For me, I replaced $request->getBaseUrl() by $this->get('request')->getSchemeAndHttpHost() because, "getBaseUrl()" returns an empty string. I'm using symfony 2.5
  • Not even 2.5 but 2.3 got the same problem too.
  • Not that cool as this trait will only work in Controller. Better way is to create service which has request.stack dependency. You can then get master request from it and return referrer in any context.
  • $request->headers->get('referer') does not return the correct $_SERVER[''HTTP_REFERER''] for me
  • @codemagician $_SERVER is directly passed into the ServerBag class. "HTTP_" is then stripped from the key github.com/symfony/symfony/blob/… the resulting array is passed into HeaderBag. The HeaderBag uses set to construct it's values, and you use get to get the value. Both force headers to lowercase github.com/symfony/symfony/blob/… Double check if the error is not on your end.
  • be careful with urls with additional GET parameters. f.e. url: /test will match the route but /test?extra will not (ofc it depends on definition of your routes)
  • Thanks @gondo for your comment. I will test it again
  • This gave me an error: Warning: strpos(): Empty needle and I realized my referring route was the index page /.
  • This is not working in my app (SF 2.5.9) $request->getBaseUrl() seems always empty
  • HTTP_REFERER can be altered by the web server, proxy or web browser.
  • Have the same with $this->redirect($request->headers->get('referer'));
  • This opens a breach to open redirect attacks. owasp.org/index.php/…
  • That might be better in some use cases. "Better" is very questionable though. Consider the the downsides: Dealing with the request object is the responsibility of the controller primarily. Class is heavier than a single trait. Service container get's larger. More configuration. Creation of service object even when you don't need it. Service needs DIC and thus creates dependencies.
  • I both agree and disagree. In pure MVC yes, controller would be best place. In Symfony what controller really does is just a really small part of getresponse event flow. There's also a reason that we have request.stack and DIC - why not use them to make reusable code with loose coupling? I would not mind about performance, as until you use route matching, whole logic is quite light. So I introduced request matching only as an option, marked by comment in code snippet.