'Symfony 2 - Setting a Flash Message outside of Controller

I have a logout Listener where I'd like to set a flash message showing a logout confirmation message.

namespace Acme\MyBundle\Security\Listeners;

use Symfony\Component\Security\Http\Logout\LogoutSuccessHandlerInterface;
use Symfony\Component\Security\Core\SecurityContext;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;

class LogoutListener implements LogoutSuccessHandlerInterface
{
  private $security;  

  public function __construct(SecurityContext $security)
  {
    $this->security = $security;
  }

  public function onLogoutSuccess(Request $request)
  {
    $request->get('session')->getFlashBag()->add('notice', 'You have been successfully been logged out.');

    $response = new RedirectResponse('login');
    return $response;
  }
}

Here is my services.yml (as it pertains to this):

logout_listener:
   class:  ACME\MyBundle\Security\Listeners\LogoutListener
   arguments: [@security.context]

This is generating an error:

Fatal error: Call to a member function getFlashBag() on a non-object

How do I set a flashBag message in this context?

Also, how do get access to the router so I can generate the url (via $this->router->generate('login')) instead of passing in a hard-coded url?

Resolution Note

To get the flash to work, you must tell your security.yml config not invalidate the session on logout; otherwise, the session will be destroyed and your flash will never appear.

logout:
    path: /logout
        success_handler: logout_listener
        invalidate_session: false


Solution 1:[1]

You can get the Session object (as well as any other service) trough the service container:

$session = $ServiceContainer->get('session');
$session->setFlash('notice', 'Message');

The way you can access to the service container in different ways:

  • From a controller or any container aware class: just use $this->get('session');
  • From a service: you have to inject the service container object as Aldo Said

Solution 2:[2]

The answers are very old on this post. 10 years later (2022), Symfony allows to deal with flashes very easily outside of a controller using the FlashBagInterface:

<?php

namespace App\Service;

use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface;

class MyService
{
    private $flash;

    public function __construct(FlashBagInterface $flash)
    {
        $this->flash = $flash;
    }

    public function myRandomMethod(): string
    {
        // ...
        $this->flash->add('success', 'This is a success!');
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 ButterDog
Solution 2 Edouard