Application modes
Application modes are frontend-specific operational states that change how the application responds to incoming
requests. Each mode is enforced by a dedicated event subscriber on EventEnum::APP_REQUEST. All modes read their
configuration through Amarant\Framework\Application\Frontend\Config, which in turn reads from ConfigEnum paths.
All four subscribers are listed below in execution order (highest EventPriorityEnum value first):
| Priority case | Value | Subscriber |
|---|---|---|
EventPriorityEnum::DECOUPLED_MODE |
610 | DecoupledModeEventSubscriber |
EventPriorityEnum::FULL_MAINTENANCE |
600 | FullMaintenanceModeEventSubscriber |
EventPriorityEnum::MAINTENANCE |
480 | MaintenanceModeEventSubscriber |
EventPriorityEnum::PRIVATE_MODE |
440 | PrivateModeEventSubscriber |
Note
All modes apply to the frontend area only. They are controlled via the configuration system and can typically be toggled from the admin back office.
Decoupled mode
Subscriber: Amarant\Framework\EventSubscriber\Request\DecoupledModeEventSubscriber
Priority: EventPriorityEnum::DECOUPLED_MODE (610)
Decoupled mode turns the frontend into an API-only application. When enabled and the frontend is set to disabled,
all non-API HTTP requests receive a 404 Not Found response. API requests are always allowed through regardless
of this setting.
Configuration
ConfigEnum path |
Description |
|---|---|
FRONTEND_APPLICATION_DECOUPLED_MODE_ENABLED |
Master switch. Enables decoupled mode. |
FRONTEND_APPLICATION_DECOUPLED_MODE_DISABLE_FRONTEND |
When true, non-API requests are rejected with 404. Decoupled mode can be enabled without this flag to signal headless operation to other parts of the application without blocking regular requests. |
FRONTEND_APPLICATION_DECOUPLED_MODE_ALLOWED_FRONTEND_ROUTES |
A regex pattern. Paths matching this pattern are still served even when the frontend is disabled. Useful for keeping health checks or webhooks alive. |
Behaviour
When isDecoupledModeEnabled() and isDecoupledModeDisabledFrontend() are both true:
- If the request is an API request — pass through, no action.
- If the request path matches
DECOUPLED_MODE_ALLOWED_FRONTEND_ROUTES— pass through, no action. - Otherwise — set a
404 Not Foundresponse and stop the event.
Maintenance mode
Maintenance mode is implemented as a two-phase mechanism split across two subscribers that run at different priorities. This allows specific identities to bypass the maintenance page and see the normal application.
Phase 1 — Full maintenance (EventPriorityEnum::FULL_MAINTENANCE, 600)
Subscriber: Amarant\Framework\EventSubscriber\Request\FullMaintenanceModeEventSubscriber
When enabled, every request is routed to RouteEnum::MAINTENANCE_PAGE_ROUTE_NAME (maintenance_page).
The subscriber does not stop the event — it only replaces the route — so phase 2 still runs afterwards.
Bypasses (route is not replaced when any applies):
- The request path is
DeploymentEnum::HEALTH_CHECK_PATH(/health) — the health check endpoint always responds normally, allowing load balancers and monitoring to detect that the application is running even during maintenance. - The current scope matches one of the values in
MAINTENANCE_MODE_ALLOWED_SCOPES— useful in multi-scope (e.g. multi-store) setups where maintenance applies only to selected scopes. - The request path matches the
MAINTENANCE_MODE_ALLOWED_FRONTEND_ROUTESregex — specific paths (e.g. a status API) can be kept accessible.
Configuration
ConfigEnum path |
Description |
|---|---|
FRONTEND_APPLICATION_MAINTENANCE_MODE_ENABLED |
Master switch. |
FRONTEND_APPLICATION_MAINTENANCE_MODE_ALLOWED_FRONTEND_ROUTES |
Regex of paths that bypass maintenance. |
FRONTEND_APPLICATION_MAINTENANCE_MODE_ALLOWED_SCOPES |
Comma-separated list of scope values that bypass maintenance (e.g. specific store codes). |
FRONTEND_APPLICATION_MAINTENANCE_MODE_SCHEDULED_FROM |
Informational scheduled start timestamp (used by the admin UI; not enforced by the subscriber). |
FRONTEND_APPLICATION_MAINTENANCE_MODE_SCHEDULED_TO |
Informational scheduled end timestamp (used by the admin UI; not enforced by the subscriber). |
Phase 2 — Identity bypass (EventPriorityEnum::MAINTENANCE, 480)
Subscriber: Amarant\Framework\EventSubscriber\Request\MaintenanceModeEventSubscriber
Runs after full maintenance. Only acts when the current route is already RouteEnum::MAINTENANCE_PAGE_ROUTE_NAME.
- If
MAINTENANCE_MODE_ALLOWED_IDENTITIESis non-empty and the current identity's identifier value is in that list, the route is cleared (set tonull) so normal routing continues for that visitor. The event is not stopped, allowing the router to resolve the actual route. - Otherwise the event is stopped, locking the response to the maintenance page.
Configuration
ConfigEnum path |
Description |
|---|---|
FRONTEND_APPLICATION_MAINTENANCE_MODE_ALLOWED_IDENTITIES |
Comma-separated list of identity identifier values (e.g. guest IDs, customer IDs) that can bypass the maintenance page and see the live application. |
Combined flow
Request
│
▼ priority 600
FullMaintenanceModeEventSubscriber
├─ maintenance disabled? → pass through
├─ scope in allowed scopes? → pass through
├─ path in allowed routes? → pass through
├─ path is /health? → pass through
└─ else: setRoute(maintenance_page) [event continues]
│
▼ priority 480
MaintenanceModeEventSubscriber
├─ current route ≠ maintenance_page? → pass through
├─ identity in allowed identities? → clearRoute(), pass through
└─ else: stop event → maintenance page rendered
Private mode
Subscriber: Amarant\Framework\EventSubscriber\Request\PrivateModeEventSubscriber
Priority: EventPriorityEnum::PRIVATE_MODE (440)
Private mode restricts the frontend to authenticated visitors only. Any visitor who is not fully authenticated is redirected to a configured path (typically a login page).
Configuration
ConfigEnum path |
Description |
|---|---|
FRONTEND_APPLICATION_PRIVATE_MODE_ENABLED |
Master switch. |
FRONTEND_APPLICATION_PRIVATE_MODE_REDIRECT_TO |
The path to redirect unauthenticated visitors to (e.g. /login). |
FRONTEND_APPLICATION_PRIVATE_MODE_ALLOWED_FRONTEND_ROUTES |
Regex of paths that are accessible without authentication even in private mode. The redirect target path itself is always implicitly exempt. |
Behaviour
- If the request path is
DeploymentEnum::HEALTH_CHECK_PATH(/health) — pass through. - If the current identity is fully authenticated — pass through.
- If private mode is disabled — pass through.
- If the request path equals
PRIVATE_MODE_REDIRECT_TO— pass through (prevents redirect loops). - If the request path matches
PRIVATE_MODE_ALLOWED_FRONTEND_ROUTES— pass through. - Otherwise — issue a redirect response to
PRIVATE_MODE_REDIRECT_TOand stop the event.
Note
Private mode runs after the firewall (EventPriorityEnum::FIREWALL = 450). Authentication has already
run at priority 500 by the time private mode is checked, so isFullyAuthenticated() reflects the identity
resolved for this request.