Skip to content

Dispatch CoreBundle events by class name (Mautic 8) - #633

Draft
promptless-for-oss wants to merge 2 commits into
mautic:7.2from
Promptless:promptless/pr-17157-event-class-dispatch
Draft

Dispatch CoreBundle events by class name (Mautic 8)#633
promptless-for-oss wants to merge 2 commits into
mautic:7.2from
Promptless:promptless/pr-17157-event-class-dispatch

Conversation

@promptless-for-oss

@promptless-for-oss promptless-for-oss commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Open in Promptless

Mautic 8 dispatches CoreBundle events by the event object alone (Symfony 4.3 class-name style), so the event class is now the event name and the Mautic\CoreBundle\CoreEvents::* string constants are no longer used for dispatch (though they remain in the codebase for backward compatibility). This updates the developer documentation so plugin authors key CoreBundle event subscribers on the event class instead of the old constant.

The event-subscriber code examples and prose on the UI extension, maintenance, config/routing, and tracking-script pages now use the EventClass::class form (CustomButtonEvent, MaintenanceEvent, RouteEvent, BuildJsEvent) and drop the now-unused CoreEvents import. The "Available events" section gains a note explaining that a subscriber still keyed on a CoreEvents::* constant (or the raw string, such as mautic.build_menu) will silently stop firing under Mautic 8, and each affected page cross-references that note.

The "Available events" section also now carries a complete migration reference table mapping all 13 CoreBundle events from their old event name and CoreEvents::* constant to their new event class, so plugin authors can migrate any CoreBundle subscriber rather than only the events named in the page examples. This mirrors the full mapping table the maintainers added to UPGRADE-8.0.md when PR #17157 merged.

The change is scoped to the CoreBundle CoreEvents family only — other event families such as LeadEvents and PageEvents still use their string constants and are left unchanged.

Trigger Events

Update developer-doc event-subscriber examples and prose to key CoreBundle
event subscribers on the event class (Symfony 4.3 class-name dispatch) instead
of the Mautic\CoreBundle\CoreEvents::* string constants, matching mautic/mautic
PR #17157. Add a BC note in the Available events section warning that a
subscriber still keyed on the old constant or string will silently stop firing
in Mautic 8, and cross-reference it from the affected pages. Scoped to CoreEvents
only; LeadEvents/PageEvents and other families still use constants.
.. vale on

Mautic dispatches the Event ``\Mautic\CoreBundle\CoreEvents::VIEW_INJECT_CUSTOM_BUTTONS`` for Plugins to register their Buttons. Listeners receive a ``Mautic\CoreBundle\Event\CustomButtonEvent`` object. Register the Event using the ``addButton`` method as described below.
Mautic dispatches the ``Mautic\CoreBundle\Event\CustomButtonEvent`` for Plugins to register their Buttons. Listeners key on this event class and receive the ``CustomButtonEvent`` object. Register the event using the ``addButton`` method as described below.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mautic dispatches CustomButtonEvent by object alone ($this->dispatcher->dispatch(new CustomButtonEvent(...))) with no event-name argument, since PR mautic/mautic#17157. Confirms the doc's claim that listeners key on CustomButtonEvent::class rather than CoreEvents::VIEW_INJECT_CUSTOM_BUTTONS.

Source: https://github.com/mautic/mautic/blob/154e64a61abc719946f3290a02cca0d78a7d5957/app/bundles/CoreBundle/Twig/Helper/ButtonHelper.php#L317

.. vale on

To hook into the ``mautic:maintenance:cleanup`` command, create a listener for the ``\Mautic\CoreBundle\CoreEvents::MAINTENANCE_CLEANUP_DATA`` event.
To hook into the ``mautic:maintenance:cleanup`` command, create a listener for the ``Mautic\CoreBundle\Event\MaintenanceEvent`` event.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CleanupMaintenanceCommand dispatches MaintenanceEvent by object alone ($this->dispatcher->dispatch($event) with no CoreEvents::MAINTENANCE_CLEANUP_DATA argument), confirming listeners must key on MaintenanceEvent::class.

Source: https://github.com/mautic/mautic/blob/154e64a61abc719946f3290a02cca0d78a7d5957/app/bundles/CoreBundle/Command/CleanupMaintenanceCommand.php#L123-L124

Comment thread docs/plugins/config.rst
@@ -205,7 +205,7 @@ Mautic defaults the following route definitions if not declared otherwise by the
Advanced routing
================

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RouteLoader dispatches RouteEvent by object alone ($this->dispatcher->dispatch($event), no CoreEvents::BUILD_ROUTE argument) for each firewall, confirming listeners must key on RouteEvent::class.

Source: https://github.com/mautic/mautic/blob/154e64a61abc719946f3290a02cca0d78a7d5957/app/bundles/CoreBundle/Loader/RouteLoader.php#L29-L30

{
return [
CoreEvents::BUILD_MAUTIC_JS => ['onBuildJs', 0],
BuildJsEvent::class => ['onBuildJs', 0],

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JsController constructs BuildJsEvent and the CoreBundle dispatches it by object alone (single-argument dispatch), confirming listeners must key on BuildJsEvent::class rather than CoreEvents::BUILD_MAUTIC_JS.

Source: https://github.com/mautic/mautic/blob/154e64a61abc719946f3290a02cca0d78a7d5957/app/bundles/CoreBundle/Controller/JsController.php#L45

There are many events available throughout Mautic. Depending on what you're trying to implement, look at the ``*Event.php`` for the core bundle, located in the root of the bundle. For example, the ``app\bundles\LeadBundle\LeadEvents.php`` file defines and describes events relating to Contacts. The final classes provide the names of the events to listen to. Always use the event constants to ensure future changes to event names won't break the Plugin.
There are many events available throughout Mautic. Depending on what you're trying to implement, look at the ``*Event.php`` for the core bundle, located in the root of the bundle. For example, the ``app\bundles\LeadBundle\LeadEvents.php`` file defines and describes events relating to Contacts. The final classes provide the names of the events to listen to. For event families that still use string constants, such as ``LeadEvents`` and ``PageEvents``, always use the event constant to ensure future changes to event names won't break the Plugin.

.. note::

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CoreEvents::BUILD_MENU constant is defined as the literal string 'mautic.build_menu'; the class is retained for BC but (per UPGRADE-8.0.md) is no longer used to dispatch the event, since MenuBuilder now dispatches MenuEvent by object alone.

Source: https://github.com/mautic/mautic/blob/154e64a61abc719946f3290a02cca0d78a7d5957/app/bundles/CoreBundle/CoreEvents.php#L14-L15

There are many events available throughout Mautic. Depending on what you're trying to implement, look at the ``*Event.php`` for the core bundle, located in the root of the bundle. For example, the ``app\bundles\LeadBundle\LeadEvents.php`` file defines and describes events relating to Contacts. The final classes provide the names of the events to listen to. Always use the event constants to ensure future changes to event names won't break the Plugin.
There are many events available throughout Mautic. Depending on what you're trying to implement, look at the ``*Event.php`` for the core bundle, located in the root of the bundle. For example, the ``app\bundles\LeadBundle\LeadEvents.php`` file defines and describes events relating to Contacts. The final classes provide the names of the events to listen to. For event families that still use string constants, such as ``LeadEvents`` and ``PageEvents``, always use the event constant to ensure future changes to event names won't break the Plugin.

.. note::

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maintainer's BC note for PR 17157: CoreBundle events are now dispatched by the event object alone (event name is the event class, Symfony 4.3+ style); CoreEvents constants are kept for BC but no longer used internally; subscribers must key on the event class (e.g. MenuEvent::class) instead of CoreEvents::* or the raw string.

Source: https://github.com/mautic/mautic/blob/154e64a61abc719946f3290a02cca0d78a7d5957/UPGRADE-8.0.md#L176-L188

Since Mautic 8, Mautic dispatches CoreBundle events, the ``Mautic\CoreBundle\CoreEvents`` family, by the event object alone, so the event class is the event name. This matches the Symfony 4.3 dispatch style.

* Key ``getSubscribedEvents()`` on the event class, for example ``MenuEvent::class``, not on the ``CoreEvents::*`` constant or the raw string name such as ``mautic.build_menu``.
* The ``CoreEvents`` constants remain in the codebase but are no longer used for dispatch, so a subscriber still keyed on the constant or string won't fire. It fails silently: it throws no exception and logs nothing, and simply never runs.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Symfony EventDispatcher::dispatch() (v7.4.15, the version locked in mautic/mautic's composer.lock) looks up listeners via $this->listeners[$eventName] ?? []/getListeners(); if none are registered for the given event name it skips callListeners() entirely and just returns the event unchanged - no exception is thrown and nothing is logged. Confirms the doc's claim that a subscriber still keyed on a CoreEvents::* constant/string simply never runs, with no error and no log entry, once CoreBundle dispatches by the event class name instead.

Source: https://github.com/symfony/event-dispatcher/blob/336e7f3b9e95aba04f93ea9143920c2186abfbb9/EventDispatcher.php#L45-L60

@promptless-for-oss

Copy link
Copy Markdown
Contributor Author

I noticed that some CI checks failed for this PR. I'm investigating whether the failures are caused by this suggestion. If they're unrelated or pre-existing, I'll leave this suggestion unchanged and create a separate suggestion if a standalone docs fix is needed.

…ration

The merged head of mautic/mautic#17157 added a full old-name -> CoreEvents
constant -> event-class mapping for all 13 CoreBundle events to UPGRADE-8.0.md.
Mirror that complete mapping into the Available events note in
plugins/event_listeners.rst so plugin authors can migrate any CoreBundle
subscriber to the Symfony 4.3 class-name dispatch style.
* The ``CoreEvents`` constants remain in the codebase but are no longer used for dispatch, so a subscriber still keyed on the constant or string won't fire. It fails silently: it throws no exception and logs nothing, and simply never runs.
* Other event families, such as ``LeadEvents`` and ``PageEvents``, still use their constants. Keep keying on those.

The following table is the complete migration reference for CoreBundle event subscribers, mapping each old event name and ``CoreEvents`` constant to its new event class, all of which live in the ``Mautic\CoreBundle\Event`` namespace.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Merged UPGRADE-8.0.md's full CoreBundle event mapping table ("Full mapping of old event name to new event class (all in the Mautic\CoreBundle\Event namespace)") lists all 13 old-event-string / CoreEvents constant / new-event-class rows verbatim, including the two non-mirroring rows (mautic.on_fetch_icons -> CoreEvents::FETCH_ICONS -> IconEvent; mautic.build_embeddable_js -> CoreEvents::BUILD_MAUTIC_JS -> BuildJsEvent). Confirms the doc's 13-row table and its claim that all listed classes live in the Mautic\CoreBundle\Event namespace. Each class file (MenuEvent.php, RouteEvent.php, GlobalSearchEvent.php, StatsEvent.php, CommandListEvent.php, IconEvent.php, BuildJsEvent.php, MaintenanceEvent.php, CustomButtonEvent.php, CustomContentEvent.php, CustomTemplateEvent.php, CustomAssetsEvent.php, GeneratedColumnsEvent.php) is confirmed present under app/bundles/CoreBundle/Event/ with namespace Mautic\CoreBundle\Event at the same commit.

Source: https://github.com/mautic/mautic/blob/0c4889777d72448ad0e5d2b156eef379702a16b3/UPGRADE-8.0.md#L214-L230

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant