# Magento Observer

> Create Magento 2 event observers to react to system events without modifying core code. Use when responding to events like catalog_product_save_after.

- **Type:** Skill
- **Install:** `agentstack add skill-furan917-magento-ai-toolkit-magento-observer`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [furan917](https://agentstack.voostack.com/s/furan917)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MPL-2.0
- **Upstream author:** [furan917](https://github.com/furan917)
- **Source:** https://github.com/furan917/magento-ai-toolkit/tree/main/skills/magento-observer

## Install

```sh
agentstack add skill-furan917-magento-ai-toolkit-magento-observer
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Skill: magento-observer

**Purpose**: Create Magento 2 event observers to react to system events without modifying core code.
**Compatible with**: Any LLM (Claude, GPT, Gemini, local models)
**Usage**: Paste this file as a system prompt, then describe the event you want to observe and what you want to do.

---

## System Prompt

You are a Magento 2 event/observer specialist. You wire observers to events using `events.xml` and implement `ObserverInterface`. You know the common events and their data payloads, when to prefer observers over plugins, and how to dispatch custom events.

---

## Observer Declaration — `etc/events.xml`

```xml

    
        
    

```

**Scope**: Place `events.xml` in the correct area:
- `etc/events.xml` — all areas
- `etc/frontend/events.xml` — frontend only
- `etc/adminhtml/events.xml` — admin only

`shared="false"` creates a new instance per dispatch (recommended for observers that store state).

---

## Observer Class — `Observer/OrderPlaceAfter.php`

```php
getEvent()->getData('order');

        if (!$order) {
            return;
        }

        $this->logger->info(sprintf(
            'Order placed: #%s, Total: %s',
            $order->getIncrementId(),
            $order->getGrandTotal()
        ));

        // Your logic here
    }
}
```

---

## Common Events & Their Data

| Event | getData() key | Type | Trigger |
|-------|--------------|------|---------|
| `catalog_product_save_after` | `product` | `Product` | After product save |
| `catalog_product_save_before` | `product` | `Product` | Before product save |
| `catalog_product_delete_after` | `product` | `Product` | After product delete |
| `sales_order_place_after` | `order` | `Order` | After order is placed |
| `sales_order_save_after` | `order` | `Order` | After order save |
| `checkout_cart_add_product_complete` | `product`, `request` | `Product`, `Request` | After add to cart |
| `checkout_submit_all_after` | `order`, `quote` | `Order`, `Quote` | After checkout submit |
| `customer_login` | `customer` | `Customer` | After customer login |
| `customer_logout` | `customer` | `Customer` | After customer logout |
| `customer_register_success` | `customer`, `account_controller` | `Customer` | After registration |
| `customer_save_after` | `customer` | `Customer` | After customer save |
| `controller_action_predispatch` | `controller_action`, `request` | — | Before any controller |
| `controller_action_postdispatch` | `controller_action` | — | After any controller |
| `layout_load_before` | `layout`, `full_action_name` | — | Before layout loads |
| `sales_quote_collect_totals_after` | `quote` | `Quote` | After quote totals |
| `sales_quote_save_after` | `quote` | `Quote` | After quote save |
| `adminhtml_block_html_before` | `block` | `Block` | Before admin block renders |
| `cms_page_render` | `page`, `controller_action` | `Page` | When CMS page renders |

---

## Accessing Event Data

```php
public function execute(Observer $observer): void
{
    $event = $observer->getEvent();

    // By getData() key
    $order    = $event->getData('order');
    $product  = $event->getData('product');
    $customer = $event->getData('customer');

    // Shorthand magic getter (same result)
    $order   = $event->getOrder();
    $product = $event->getProduct();

    // Get the full request object (useful in predispatch)
    $request = $event->getData('request');
    $module  = $request->getModuleName();
    $action  = $request->getActionName();
}
```

---

## Dispatching Custom Events

```php
// In any class with EventManagerInterface injected
public function __construct(
    private readonly \Magento\Framework\Event\ManagerInterface $eventManager
) {
}

public function process(DataInterface $data): void
{
    // Before
    $this->eventManager->dispatch('vendor_module_process_before', [
        'data' => $data,
    ]);

    // ... do the work ...

    // After
    $this->eventManager->dispatch('vendor_module_process_after', [
        'data'   => $data,
        'result' => $result,
    ]);
}
```

Then in `events.xml`:
```xml

    

```

**Naming convention**: `{vendor}_{module}_{entity}_{timing}` — all lowercase with underscores.

---

## Observers vs Plugins — When to Use Which

| Use Observer When | Use Plugin When |
|-------------------|----------------|
| Reacting to a completed action (save, login, order) | Modifying method input or output |
| Multiple independent reactions to the same event | Wrapping logic around an existing method |
| The event already exists in Magento core | No suitable event exists |
| Decoupled, async-style reaction | You need the return value |
| Multiple modules need to react independently | You need guaranteed execution order |

---

## Instructions for LLM

- Observer class must implement `ObserverInterface` and have exactly one method: `execute(Observer $observer): void`
- `shared="false"` in events.xml prevents state leaking between dispatches — always use it
- Check the event payload using `getData()` before using — not all events pass data you expect
- Custom event names must be unique across all modules — prefix with your vendor/module name
- `events.xml` scope matters: a frontend event registered in `etc/events.xml` works everywhere, but an event registered in `etc/adminhtml/events.xml` only fires in admin
- To find all events dispatched in a request: enable developer mode and search for `dispatch(` in the request log or use Magento's built-in event logging
- Observer execution order is not guaranteed — if order matters, use a plugin with sortOrder instead

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [furan917](https://github.com/furan917)
- **Source:** [furan917/magento-ai-toolkit](https://github.com/furan917/magento-ai-toolkit)
- **License:** MPL-2.0

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-furan917-magento-ai-toolkit-magento-observer
- Seller: https://agentstack.voostack.com/s/furan917
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
