Quick Stats
Plugins Overview
The Magento_Customer module implements 19 plugins across different areas to intercept and modify behavior at critical execution points.
Plugin Execution Priority
- -1: TransactionWrapper (must run first to open transaction)
- 1: Data validation plugins
- 10: Standard business logic plugins (default)
- 100+: Cosmetic or non-critical plugins
Global Plugins
These plugins are registered in etc/di.xml and apply across all areas (frontend, admin, API).
| Plugin Name | Intercepts | Sort Order | Purpose |
|---|---|---|---|
| TransactionWrapper | CustomerRepositoryInterface |
-1 | Wraps customer repository operations in database transactions |
| CustomerNotification | Framework\App\ActionInterface |
10 | Displays admin-triggered notifications in frontend |
| CustomerFlushFormKey | PageCache\Observer\FlushFormKey |
10 | Regenerates form_key on login/logout to prevent CSRF |
| SaveCustomerGroupExcludedWebsite | GroupRepositoryInterface::save |
10 | Saves excluded website associations for customer groups |
| DeleteCustomerGroupExcludedWebsite | GroupRepositoryInterface::delete |
10 | Cleanup excluded website records on group deletion |
| GetByIdCustomerGroupExcludedWebsite | GroupRepositoryInterface::getById |
10 | Populates excluded websites when loading group |
| GetListCustomerGroupExcludedWebsite | GroupRepositoryInterface::getList |
10 | Populates excluded websites for all groups in results |
TransactionWrapper Plugin
Critical Business Logic: Ensures atomicity of customer operations
<type name="Magento\Customer\Api\CustomerRepositoryInterface">
<plugin name="transactionWrapper"
type="Magento\Customer\Model\Plugin\CustomerRepository\TransactionWrapper"
sortOrder="-1"/>
</type>
Methods Intercepted:
- → save()
- → delete()
- → deleteById()
Behavior:
- 1. beforeSave: Opens database transaction
- 2. Original Method: Customer save logic executes
- 3. afterSave: Commits transaction (or rolls back on exception)
Result: Customer + addresses + EAV attributes saved atomically. Prevents partial customer saves if address save fails.
Frontend Plugins
These plugins are registered in etc/frontend/di.xml and only apply to storefront requests.
| Plugin Name | Intercepts | Purpose |
|---|---|---|
| DepersonalizePlugin | Framework\View\Layout |
Removes customer-specific data from cached pages (FPC) |
| ContextPlugin | Framework\App\ActionInterface |
Injects customer context for page cache variations |
| Account | Customer\Controller\AccountInterface |
Validates customer access to account pages |
| ConfigPlugin | Checkout\Block\Cart\Sidebar |
Configures minicart behavior by customer group |
| SessionChecker | Framework\Session\SessionManagerInterface |
Validates session before processing customer sections |
| ClearSessionsAfterLogoutPlugin | Customer\Model\Session |
Clears all active sessions on logout (multi-session mgmt) |
DepersonalizePlugin (Critical for Full Page Cache)
Purpose: Removes customer-specific data from cached pages to enable aggressive FPC caching.
What Gets Depersonalized:
- • Customer name
- • Customer email
- • Customer group
- • Cart item count
- • Wishlist item count
- • Recently viewed products
How Personalization is Restored: Customer sections (private content) load personalized data via AJAX:
GET /customer/section/load/sections/cart,customer,wishlist
Admin Plugins
These plugins are registered in etc/adminhtml/di.xml and only apply to admin area.
| Plugin Name | Intercepts | Purpose |
|---|---|---|
| CustomerGridIndexAfterWebsiteDelete | Store\Api\WebsiteRepositoryInterface::delete |
Reindexes customer grid after website deletion |
| DeleteCustomerGroupExcludedWebsite | Store\Api\WebsiteRepositoryInterface::delete |
Cleanup excluded website records when website deleted |
REST API Plugins
These plugins are registered in etc/webapi_rest/di.xml and only apply to REST API requests.
| Plugin Name | Intercepts | Sort Order | Purpose |
|---|---|---|---|
| CustomerAuthorization | CustomerRepositoryInterface |
10 | Validates customer token authorization |
| UpdateCustomer | CustomerRepositoryInterface::save |
10 | Populates customer data from REST request body |
| ValidateCustomerData | Webapi\Controller\Rest |
1 | Validates customer data format before processing |
Observers Overview
The Magento_Customer module implements 16 observers that react to events dispatched during customer operations.
Observer Execution
- → Synchronous: Observers execute immediately when event is dispatched (blocking)
- → Transaction Safety: Observers run inside TransactionWrapper transaction, so exceptions rollback entire operation
Customer Lifecycle Observers
| Observer Name | Event | Purpose | Area |
|---|---|---|---|
| UpgradeOrderCustomerEmailObserver | customer_save_after_data_object |
Synchronizes customer email changes to historical orders | global |
| UpgradeQuoteCustomerEmailObserver | customer_save_after_data_object |
Synchronizes customer email changes to active cart | global |
| UpgradeCustomerPasswordObserver | customer_customer_authenticated |
Upgrades password hash to current algorithm on login | global |
UpgradeOrderCustomerEmailObserver
Critical Business Logic: Synchronizes customer email changes to historical orders
Database Impact:
UPDATE sales_order
SET customer_email = 'new@example.com'
WHERE customer_id = 123
AND customer_email = 'old@example.com'
Why This Exists: Order lookup in admin uses customer_email filter. If email changes, admin can't find customer's orders. This keeps order email in sync with current customer email.
Performance: May update hundreds of orders for long-time customers.
Address Observers
| Observer Name | Event | Purpose |
|---|---|---|
| BeforeAddressSaveObserver | customer_address_save_before |
Validates and processes VAT number before address save |
| AfterAddressSaveObserver | customer_address_save_after |
Changes customer group based on VAT validation result |
AfterAddressSaveObserver - Critical Side Effect
Warning: Saving an address can change customer group!
Based on VAT validation, this observer can move customers between groups (e.g., Regular → Intra-EU), affecting:
- • Product prices (group pricing)
- • Catalog rules
- • Shopping cart prices
- • Tax calculations
Transaction Safety: Customer group change occurs in same transaction as address save. Rollback if fails.
Authentication Observers
| Observer Name | Event | Purpose | Area |
|---|---|---|---|
| LogLastLoginAtObserver | customer_login |
Records customer login timestamp | frontend |
| LogLastLogoutAtObserver | customer_logout |
Records customer logout timestamp | frontend |
| CustomerLoginSuccessObserver | customer_login |
Extensibility point for custom login logic | frontend |
| CustomerGroupAuthenticate | customer_customer_authenticated |
Validates customer group is active and allowed | global |
Visitor Tracking Observers
| Observer Name | Event | Purpose |
|---|---|---|
| InitByRequestObserver | controller_action_predispatch |
Initialize visitor tracking on every page request |
| SaveByRequestObserver | controller_action_postdispatch |
Update visitor last_visit_at timestamp after request |
| BindCustomerLoginObserver | customer_data_object_login |
Link anonymous visitor session to customer account |
| BindQuoteCreateObserver | sales_quote_save_after |
Link quote (cart) to visitor session for analytics |
Integration Observers
AddCustomerGroupExcludedWebsite
Event: catalog_rule_collection_load_after
Purpose: Filters catalog rules to exclude customer groups not allowed on current website
Behavior:
- 1. Get current website ID
- 2. Load excluded customer groups for this website
- 3. Remove rules that apply to excluded groups
B2B Feature: Prevents wholesale pricing from appearing on retail website.
Observer Best Practices
1. Keep Observers Lightweight
Bad: Complex business logic in observers
Good: Delegate to service classes
2. Check for Data Changes
Don't perform expensive operations if data didn't change. Compare original vs current values.
3. Handle Exceptions
Observers run in transactions. Unhandled exceptions rollback entire operation. Catch and log when appropriate.
4. Avoid Circular Dependencies
Use session flags or different events to prevent infinite loops when observer triggers same event.
Performance Monitoring
Slow Observers to Watch
- 1. UpgradeOrderCustomerEmailObserver: May update hundreds of orders
- 2. BeforeAddressSaveObserver: External VAT API call (1-3 seconds)
- 3. AfterAddressSaveObserver: May trigger customer save (cascade)
Profiling
Use Magento profiler to measure observer execution time:
bin/magento dev:profiler:enable html
Then check event dispatch times in profiler output.