1

I've read about sessions here:

https://symfony.com/doc/current/components/http_foundation/sessions.html

If I use the code directly, Symfony logins using Guard don't work on the first attempt (first time always fails, second time succeeds). So I'm guessing that I have to use the session at $this->container->get('session'). But adding bags to that baffles me.

I've tried this:

/**
 * @Route("/", name="homepage")
 */
public function indexAction(Request $request) {
    $session=$this->container->get('session');
    $cart=new AttributeBag('ShoppingCartItems');
    $session->registerBag($cart);
    $session->start();

...but it tells me

Cannot register a bag when the session is already started.

I've tried this:

...in the bundle:

    public function build(ContainerBuilder $container) {
        parent::build($container);
        $container->addCompilerPass(new \Website\DependencyInjection\Compiler\InjectShoppingCart());
    }

...and then this for InjectShoppingCart

namespace Website\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;

class InjectShoppingCart implements CompilerPassInterface {
    public function process(ContainerBuilder $container) {
        $bagDefinition = new Definition();
        $bagDefinition->setClass(AttributeBag::class);
        $bagDefinition->addArgument("ShoppingCartItems");
        $bagDefinition->addMethodCall("setName", ["ShoppingCartItems"]);
        $container->setDefinition("ShoppingCartItemsService",$bagDefinition);

        $container->getDefinition("session")->addMethodCall("registerBag",[new Reference("ShoppingCartItemsService")]);
    }
}

...which I tried to use, Cargo Cult style, from question 44723613. Whatever it does, it does not result in the registration of an attribute bag.

No matter what I've tried so far, either Guard authentication breaks, or else the bag doesn't get registered. I want to do both, though, hopefully without installing Megs and Megs of external libraries.

It can't be this hard. What have I missed?

gp_sflover
  • 3,460
  • 5
  • 38
  • 48
Alan Schmidt
  • 113
  • 7

1 Answers1

1

Okay, I figured it out.

In the end, it was just one line from the example I was using that was making it fail for me:

$bagDefinition->addArgument("ShoppingCartItems");

...has to be deleted.

What this all amounts to is that in the compiler pass, instead of making it do this:

$bag = new AttributeBag('ShoppingCartItems');
$bag->setName('ShoppingCartItems');
$session->registerBag($bag);

I needed to make it do this:

$bag = new AttributeBag();
$bag->setName('ShoppingCartItems');
$session->registerBag($bag);

So InjectShoppingCart ends up looking like this:

namespace Website\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;

class InjectShoppingCart implements CompilerPassInterface {
    public function process(ContainerBuilder $container) {
        $bagDefinition = new Definition();
        $bagDefinition->setClass(AttributeBag::class);
        $bagDefinition->addMethodCall("setName", ["ShoppingCartItems"]);
        $container->setDefinition("ShoppingCartItemsService",$bagDefinition);

        $container->getDefinition("session")->addMethodCall("registerBag",[new Reference("ShoppingCartItemsService")]);
    }
}
Alan Schmidt
  • 113
  • 7