New in Symfony 8.2 (in development). To order listeners, all you had was the priority: an integer, chosen by reading everybody else's. You need to know the 32 of RouterListener and the 16 of LocaleListener to write the 20 that fits between them, and the day you have to slip a step between 20 and 10, you renumber. Symfony 8.2 lets you say what the priority only implied: who goes before whom.
before and after
#[AsEventListener(after: AppliquerCodePromoListener::class, before: CalculerTotalListener::class)] class FraisDePortListener
Targets are service ids or classes, alone or in a list. To target only one method of a listener that declares several, write LocaleListener::class.'::onKernelRequest'. A subscriber (EventSubscriberInterface) says the same thing with the before and after keys of getSubscribedEvents().
Everything is resolved when the container is compiled, by a sort that only moves a listener when a constraint forces it to. A missing target (the bundle that provides it isn't installed) is ignored. A cycle, however, is an error, which names the listeners involved.
And the priority?
It stays, but it becomes optional: AsEventListener::$priority now defaults to null, no longer 0.
- Without a priority, the listener is placed by its constraints, and gets the priority its position requires (0 when possible).
- With a priority, the constraints only break ties between listeners of the same priority. If they would need to cross it, the container refuses to compile and tells you which priority would be needed.
Your task
The shop has added shipping costs, free from €30, after the discount. FraisDePortListener must therefore run after the promo and before the total, but it has no room: the promo is at 20, the total at 10, and shipping, with no priority, comes after the total. The /order preview shows it: the log reads stock, promo, total, shipping, confirmation, and the total forgets the €4.90 of shipping.
- Replace all the priorities of the order listeners with
before/after, so that the log becomesstock, promo, shipping, total, confirmation. - Do the same for
LangueDuVisiteurListener, whose 20 is just a roundabout way of saying “after the router, before LocaleListener”. Thelanguage=frcookie must still switch the page to French.