Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

337
Vistas
Registrar AttributeBag personalizado a través de CompilerPass

Estoy tratando de ordenar mis variables de sesión integrando AttributBags personalizados en la sesión. En Symfony < 6.0, podía inyectar un AttributBag personalizado en el servicio de sesión.

Ver preguntas relacionadas

  • Cómo agregar una bolsa adicional a la sesión de Symfony
  • Uso de Symfony AttributeBags en un controlador

Sin embargo, este enfoque ya no funciona en Symfony >= 6.0. Este artículo de blog explica que el servicio de sesión está en desuso y ahora se debe acceder a él a través del servicio request_stack. Para los controladores esto funciona bien.

Mi enfoque actual (que no funciona) se ve así: Definir una clase AttributBag personalizada.

 class ShoppingCartBag extends AttributeBag { public function __construct(string $storageKey = 'shoppingCart') { parent::__construct($storageKey); } }

Agrega un CompilerPass personalizado en la clase Kernel para que Symfony se encargue de todos los cambios mientras crea el contenedor.

 class Kernel extends BaseKernel { use MicroKernelTrait; protected function build(ContainerBuilder $container): void { $container->addCompilerPass(new AddShoppingCartBagToSessionService()); } }

El CompilerPass personalizado se ve así.

 class AddShoppingCartBagToSessionService implements CompilerPassInterface { public function process(ContainerBuilder $container) { $container->getDefinition('request_stack') //<- Works, but how to access the session? ->addMethodCall('getSession') // How to bridge the gap? This thought does not work. I assume it is because the session is not yet instantiated when the container is build. ->addMethodCall('registerBag', [new Reference('App\Session\CustomBag\ShoppingCartBag')]); } }
over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

Como supuso correctamente, la sesión aún no existe al hacer esto a través del pase del compilador.

Symfony usa una llamada SessionFactory para crear la sesión. Entonces, lo que puede hacer en su lugar es decorar el servicio session.factory existente con su propia implementación de SessionFactoryInterface y agregar su bolsa de atributos allí:

Una implementación de esta fábrica de sesiones decorada podría verse así:

 namespace App; use Symfony\Component\HttpFoundation\Session\SessionFactoryInterface; use Symfony\Component\HttpFoundation\Session\SessionInterface; class SessionFactoryWithAttributeBag implements SessionFactoryInterface { public function __construct(private SessionFactoryInterface $delegate) { } public function createSession(): SessionInterface { $session = $this->delegate->createSession(); $session->registerBag(new ShoppingCartBag()); return $session; } }

Y luego puedes decorar session.factory a través de services.yaml :

 services: App\SessionFactoryWithAttributeBag: decorates: session.factory arguments: ['@.inner']

Ahora, cada vez que se crea una sesión, tu bolsa personalizada también queda registrada

over 4 years ago · Santiago Trujillo Denunciar

0

Esa fue una pista importante, ¡gracias @Spea!

Adopté su idea y creé un nuevo decorador para el servicio de sesión. Después de algunas pruebas y errores, encontré una respuesta a mi problema. La solución se ve así. Observe que la sintaxis real es ligeramente diferente de la respuesta dada por Spea.

Cree un AttributBag personalizado extendiendo la clase con el mismo nombre. Tenga cuidado de establecer el nombre de la bolsa de atributos, no la clave de almacenamiento en el constructor. De lo contrario, Symfony arrojará un error cuando intentes acceder a ShoppingCartBag.

 namepsace App\Session; use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag; class ShoppingCartBag extends AttributeBag { public function __construct() { parent::__construct(); $this->setName('shoppingCart'); } }

Cree un decorador para cambiar el comportamiento del servicio de sesión para obtener el resultado deseado (incluya ShoppingCartBag en cada sesión).

 namespace App\Decorator; use App\Session\ShoppingCartBag; use Symfony\Component\HttpFoundation\Session\SessionFactoryInterface; use Symfony\Component\HttpFoundation\Session\SessionInterface; class SessionFactoryShoppingCartBag implements SessionFactoryInterface { public function __construct(private SessionFactoryInterface $delegate) {} public function createSession(): SessionInterface { $session = $this->delegate->createSession(); $session->registerBag(new ShoppingCartBag()); return $session; } }

A continuación, decore el servicio de sesión en services.yml agregando el siguiente fragmento de código.

 services: App\Decorator\SessionFactoryShoppingCartBag: decorates: session.factory arguments: ['@.inner']
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda