Home / 
Blog / 
Events and observers in Magento 2
thumbnail

Events and observers in Magento 2

Events and observers – built-in Magento 2 with publish-subscribe pattern – is a powerful functionality that allows developers to trigger multiple actions on typical store behaviors. From this short tutorial, you will learn how to create new observer classes and attach them to selected events.

The most important thing about pattern publish-subscribe is that publishers send messages and not rely on the answers. In other words – publishers are not dependent on observers. Observers could even not exist and script execution will end with success.

How do events and observers work exactly in Magento 2?

Publishers send several messages to inform about the current state of the processed requests. For example, when the customer is submitting an order, Magento2 is publishing messages that:

  • the application will be trying to save a new order (event: sales_order_save_before)
  • application successfully saved new order (event:  sales_order_save_after)

Ok, so we have events and we can fire some actions on them. But what actions? Let’s say that we would like to check once again if a product selected by a customer is in stock. Does event sales_order_save_before not sound good?

However it could sound correct, but it is not a good idea because event observers should not modify the data (never!). If we would like to once again check stock status then Magento plugins and interceptors will be a much more sufficient and reliable solution.

So maybe we use the event to send additional emails with information about an order? Yes, this the case when using an event observer will be a good idea.

Let’s start with creating a new custom Magento 2 module – let’s name it PandaGroup_EventObserver. We need to create a directory:

mkdir -p app/code/PandaGroup/EventObserver

And also standard configuration files: etc/module.xml:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="PandaGroup_LayoutsAndBlocks"/>
</config>

and registration.php:

<?php

    declare(strict_types=1);

    use Magento\Framework\Component\ComponentRegistrar;

    ComponentRegistrar::register(ComponentRegistrar::MODULE, 'PandaGroup_LayoutsAndBlocks', __DIR__);

The most important file in our case is the observer class. Let’s create a new PHP file under Observer directory:

mkdir Observer && touch NewOrderAdditionalEmailSenderObserver.php

New observer class in Magento2 always should implement \Magento\Framework\Event\ObserverInterface. Let’s say we have already created another service for sending emails  – we inject it through the constructor. What else? Our class must contain an execute method – this is required by the interface. The ready class will look like this:

<?php

    declare(strict_types=1);

    namespace PandaGroup\EventObserver\Observer;

    use Magento\Framework\Event\Observer;
    use EmailService;

    class NewOrderAdditionalEmailSenderObserver implements \Magento\Framework\Event\ObserverInterface
    {
        /**
         * @var EmailService
         */
        private EmailService $emailService;

        public function __construct(EmailService $emailService)
    {
        $this->emailService = $emailService;
    }

        public function execute(Observer $observer): void
    {
        $order = $observer->getEvent()->getOrder();
        // your logic for sending email
    }
    }

Last but not least, we have to attach the observer class to the selected event. To do that, we have to create events.xml file and declare it there:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="sales_order_save_after">
        <observer name="pandagroup_eventobserver_new_order_additional_email_sender"
                  instance="PandaGroup\EventObserver\Observer\NewOrderAdditionalEmailSenderObserver"/>
    </event>
</config>

And that’s all! Run setup:upgrade and clean:cache commands and test it – logic from our event observer should be fired every time when a new order is created.

...