Magento 2 Experten — Hyvä Theme, Tailwind CSS & SEO aus einer Hand ›

Understanding the Observer/Event System in Magento

Understanding the Observer/Event System in Magento

~6 Min. Lesezeit Zuletzt aktualisiert am August 9, 2026

Block 3 created nothing but state: attributes, a backend model, a resolver service - but not a single line so far actually reacts to a real business event like "a customer just completed an order". PointsCalculator (chapter 5) has been waiting to be called since chapter 5. Block 4 closes exactly that gap - and this chapter lays the groundwork before chapter 30 writes this series' first real observer.

What is an event?

Magento has a central event manager (\Magento\Framework\Event\ManagerInterface) that gets called via dispatch() at countless points throughout the core - and in any custom module - whenever something noteworthy happened: an order was placed, a product was saved, a credit memo was created. The dispatching code knows none of its listeners - classic publish/subscribe, fully decoupled.

// Somewhere in Magento core, roughly:
$this->eventManager->dispatch(
    'sales_order_place_after',
    ['order' => $order]
);

Registering an observer: events.xml

A custom module "subscribes" to an event via etc/events.xml - either globally (etc/events.xml, applies in every area) or scoped to one area (etc/frontend/events.xml, etc/adminhtml/events.xml, etc/webapi_rest/events.xml, and so on - the same area principle as di.xml). The name attribute of the <observer> node is the merge key across modules, exactly like block and layout XML.

<!-- Schema sketch, not a real file from this module -->
<config>
    <event name="event_name_here">
        <observer name="unique_observer_name"
                  instance="Vendor\Module\Observer\MyObserver"/>
    </event>
</config>

ObserverInterface: the contract side

Every observer class implements \Magento\Framework\Event\ObserverInterface with exactly one method: execute(\Magento\Framework\Event\Observer $observer): void. The Observer passed in wraps the data given to dispatch() - accessed via getEvent()->getData('order') or, when Magento defines a matching magic getter, directly getEvent()->getOrder().

declare(strict_types=1);

namespace Vendor\Module\Observer;

use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;

class MyObserver implements ObserverInterface
{
    public function execute(Observer $observer): void
    {
        $order = $observer->getEvent()->getData('order');
        // ...
    }
}

Observers run synchronously and block

Achtung: An events.xml observer runs synchronously, in the same PHP process as the code that triggered it - unlike a real message queue (Magento has its own, entirely separate publish/consumer system in Magento_MessageQueue/Magento_AsynchronousOperations, deliberately out of scope for this series). A slow observer, or one that throws an exception, on a checkout-critical event directly delays or breaks that exact request. Chapter 30 shows the concrete consequence for AwardPointsOnOrderPlaced.

Which events even exist?

  • Naming convention: <entity>_<action>_<timing>, usually _before/_after.
  • Every AbstractModel entity with an $_eventPrefix set automatically fires <prefix>_save_before, <prefix>_save_after, <prefix>_load_after, <prefix>_delete_after, and more - with no dispatch() call needed in your own code at all.
  • What data a specific event carries lives exclusively in the actual dispatch() call in the core source code - not reliably in documentation, which can go stale.

Tipp: Instead of memorizing event names and payloads: look them up directly in the vendor directory. bin/cli grep -rn "eventManager->dispatch" vendor/magento/module-sales/Model/Order.php shows exactly which events \Magento\Sales\Model\Order fires and with what data - more reliable than any third-party list.

With this groundwork in place, chapter 30 registers this series' first real observer - AwardPointsOnOrderPlaced - on sales_order_place_after, and for the first time actually wires together PointsCalculator (chapter 5), CategoryBonusResolver (chapter 27), and the loyalty_points_earned sales attribute (chapter 23).