Події

← Події

Ashterix

docs(articles): SEO titles, intros and a section preview image for From Magento to Symfony

uk/articles/magento-to-symfony/core/events.md +6 −0

Події

Спостерігачі Magento в Symfony стають слухачами подій: типізований клас події замість рядкового імені й масиву даних, з пріоритетами та зупинкою поширення.

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 · клас події + слухач

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()));
  • Подія — типізований клас, ім'я події — його FQCN. Жодних рядкових ключів у масиві.
  • Є пріоритет: #[AsEventListener(priority: 10)], вищий спрацьовує раніше. В Magento порядок спостерігачів не гарантований.
  • $event->stopPropagation() зупиняє решту слухачів (подія має наслідувати Symfony\Contracts\EventDispatcher\Event).
  • Події Doctrine (prePersist, postUpdate, onFlush) йдуть окремим диспетчером: #[AsDoctrineListener], #[AsEntityListener].
  • Якщо реакція повільна (лист, ERP), слухач кладе повідомлення в Messenger, а не робить роботу сам.

Symfony · слухач ядра, аналог 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));
    }
}