Events

← Events

Ashterix

feat(seo): og:image size for front matter images; short titles and explicit descriptions for From Magento to Symfony

en/articles/magento-to-symfony/core/events.md +2 −1

Events

Magento observers become event listeners in Symfony: a typed event class instead of a string name and a data array, with priorities and stopping propagation.

Magento · events.xml + Observer

<event name="sales_order_place_after">
    <observer name="vendor_send_confirmation"
              instance="Vendor\Sales\Observer\SendConfirmation"/>
</event>
class SendConfirmation implements ObserverInterface
{
    public function execute(Observer $observer): void
    {
        $order = $observer->getEvent()->getData('order');
        // ...
    }
}

$this->eventManager->dispatch(
    'sales_order_place_after',
    ['order' => $order]
);

Symfony · event class + listener

final class OrderPlaced
{
    public function __construct(
        public readonly int $orderId,
    ) {}
}

#[AsEventListener(event: OrderPlaced::class)]
final class SendOrderConfirmation
{
    public function __invoke(OrderPlaced $event): void
    {
        // ...
    }
}

$this->dispatcher->dispatch(new OrderPlaced($order->getId()));
  • An event is a typed class, and the event name is its FQCN. No string keys in an array.
  • There is a priority: #[AsEventListener(priority: 10)], higher runs earlier. In Magento the order of observers is not guaranteed.
  • $event->stopPropagation() stops the remaining listeners (the event has to extend Symfony\Contracts\EventDispatcher\Event).
  • Doctrine events (prePersist, postUpdate, onFlush) go through a separate dispatcher: #[AsDoctrineListener], #[AsEntityListener].
  • If the reaction is slow (an email, an ERP call), the listener puts a message into Messenger instead of doing the work itself.

Symfony · kernel listener, the equivalent of controller_action_predispatch

#[AsEventListener(event: KernelEvents::REQUEST, priority: 20)]
final class MaintenanceListener
{
    public function __construct(
        #[Autowire(env: 'bool:MAINTENANCE')]
        private bool $maintenance,
    ) {}

    public function __invoke(RequestEvent $event): void
    {
        if (!$this->maintenance || !$event->isMainRequest()) {
            return;
        }
        $event->setResponse(new Response('Maintenance', 503));
    }
}