Skip to content

55 simple bus#433

Merged
jonasdekeukelaere merged 20 commits intomasterfrom
55-simple-bus
Mar 19, 2026
Merged

55 simple bus#433
jonasdekeukelaere merged 20 commits intomasterfrom
55-simple-bus

Conversation

@jonasdekeukelaere
Copy link
Copy Markdown
Member

@jonasdekeukelaere jonasdekeukelaere commented Mar 19, 2026

https://next-app.activecollab.com/108877/projects/62?modal=Task-243505-62

Summary by Sourcery

Replace the legacy SimpleBus command/event bus with Symfony Messenger across the application and adjust related configuration, handlers, and integrations accordingly.

New Features:

  • Register command and subscription handlers as Symfony Messenger message handlers using attributes and autowiring instead of explicit command bus service definitions.

Enhancements:

  • Refactor command handler classes in media library, media galleries, content blocks, form builder, location, and mailmotor modules to use __invoke methods, Doctrine entity manager flushing, and Symfony\Component\Messenger for command dispatching.
  • Simplify service configuration by enabling autowire/autoconfigure defaults, switching handler and form type registrations to FQCN-based service definitions, and aliasing repository services to their concrete classes.
  • Update console commands, AJAX actions, backend actions, event listeners, and page copy logic to dispatch commands via the default Messenger bus rather than the old command_bus service.
  • Adjust DTO-style command objects for locale-related copy operations to use typed properties and cleaner default-from-locale initialization.
  • Use the public logger service alias for frontend mailmotor error logging and expose SpoonDatabase as a service alias for database access.

Build:

  • Remove SimpleBus-related bundles, configuration, and composer dependencies in favor of Symfony Messenger and streamline Doctrine configuration by dropping the doctrine_orm_bridge integration.

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai bot commented Mar 19, 2026

Reviewer's Guide

Replaces the legacy SimpleBus command bus integration with Symfony Messenger for command handling across multiple backend and frontend modules, updates handlers to be Messenger message handlers with explicit flushing, simplifies service wiring via autowiring/autoconfigure, and removes SimpleBus-related bundles and dependencies.

Sequence diagram for creating a content block via Symfony Messenger

sequenceDiagram
    actor Admin
    participant AddAction as BackendContentBlocksAdd
    participant Form as SymfonyForm
    participant MB as MessengerDefaultBus
    participant Cmd as CreateContentBlock
    participant Handler as CreateContentBlockHandler
    participant Repo as ContentBlockRepository
    participant EM as EntityManagerInterface

    Admin->>AddAction: HTTP request to add content block
    AddAction->>Form: build and handleRequest
    Form-->>AddAction: isSubmitted && isValid
    AddAction->>Cmd: new CreateContentBlock(formData)
    AddAction->>Cmd: set userId
    AddAction->>MB: dispatch(Cmd)

    MB-->>Handler: __invoke(CreateContentBlock)
    Handler->>Handler: getNewExtraId()
    Handler->>Repo: getNextIdForLanguage(Cmd.locale)
    Handler->>Repo: add(ContentBlock::fromDataTransferObject(Cmd))
    Handler->>Cmd: setContentBlockEntity(contentBlock)
    Handler->>EM: flush()

    MB-->>AddAction: dispatch returns
    AddAction-->>Admin: redirect to overview with success
Loading

Sequence diagram for deleting a media item via MediaItemManager and Messenger

sequenceDiagram
    actor Admin
    participant Action as BackendMediaItemMassAction
    participant Manager as MediaItemManager
    participant MB as MessengerDefaultBus
    participant Cmd as DeleteMediaItem
    participant Handler as DeleteMediaItemHandler
    participant Repo as MediaItemRepository
    participant EM as EntityManagerInterface

    Admin->>Action: selects media items and confirms delete
    Action->>Manager: delete(MediaItem)
    Manager->>Cmd: new DeleteMediaItem(MediaItem)
    Manager->>MB: dispatch(Cmd)

    MB-->>Handler: __invoke(DeleteMediaItem)
    Handler->>Repo: remove(Cmd.mediaItem)
    Handler->>EM: flush()

    MB-->>Manager: dispatch returns
    Manager-->>Action: DeleteMediaItem (for further use if needed)
    Action-->>Admin: AJAX success response
Loading

Class diagram for updated command handlers and messaging components

classDiagram
    class MessageBusInterface

    class CreateContentBlock {
        +int id
        +int extraId
        +Locale locale
        +int userId
        +ContentBlock contentBlock
        +setContentBlockEntity(ContentBlock contentBlock) void
    }

    class CreateContentBlockHandler {
        -ContentBlockRepository contentBlockRepository
        -EntityManagerInterface entityManager
        +__construct(ContentBlockRepository contentBlockRepository, EntityManagerInterface entityManager)
        +__invoke(CreateContentBlock createContentBlock) void
    }

    class DeleteMediaItem {
        +MediaItem mediaItem
        +__construct(MediaItem mediaItem)
    }

    class DeleteMediaItemHandler {
        -MediaItemRepository mediaItemRepository
        -EntityManagerInterface entityManager
        +__construct(MediaItemRepository mediaItemRepository, EntityManagerInterface entityManager)
        +__invoke(DeleteMediaItem deleteMediaItem) void
    }

    class MediaItemManager {
        -MessageBusInterface messageBus
        +__construct(MessageBusInterface messageBus)
        +delete(MediaItem mediaItem) DeleteMediaItem
    }

    class CopyContentBlocksToOtherLocale {
        +Locale toLocale
        +Locale fromLocale
        +array extraIdMap
        +__construct(Locale toLocale, Locale fromLocale)
    }

    class CopyContentBlocksToOtherLocaleHandler {
        -ContentBlockRepository contentBlockRepository
        -EntityManagerInterface entityManager
        +__construct(ContentBlockRepository contentBlockRepository, EntityManagerInterface entityManager)
        +__invoke(CopyContentBlocksToOtherLocale command) void
    }

    class SaveSettings {
        +string mailEngine
        +bool doubleOptIn
        +bool requireSubscription
        +__construct(ModulesSettings modulesSettings)
    }

    class SaveSettingsHandler {
        -ModulesSettings modulesSettings
        +__construct(ModulesSettings modulesSettings)
        +__invoke(SaveSettings settings) void
    }

    CreateContentBlockHandler ..> CreateContentBlock : handles
    DeleteMediaItemHandler ..> DeleteMediaItem : handles
    CopyContentBlocksToOtherLocaleHandler ..> CopyContentBlocksToOtherLocale : handles
    SaveSettingsHandler ..> SaveSettings : handles

    MediaItemManager --> MessageBusInterface : uses
    MediaItemManager ..> DeleteMediaItem : creates

    CreateContentBlockHandler --> EntityManagerInterface : flushes
    DeleteMediaItemHandler --> EntityManagerInterface : flushes
    CopyContentBlocksToOtherLocaleHandler --> EntityManagerInterface : flushes

    class MediaItem
    class ContentBlock
    class ContentBlockRepository
    class MediaItemRepository
    class ModulesSettings
    class Locale
    class EntityManagerInterface

    CreateContentBlock --> ContentBlock
    CreateContentBlockHandler --> ContentBlockRepository
    DeleteMediaItem --> MediaItem
    DeleteMediaItemHandler --> MediaItemRepository
    SaveSettingsHandler --> ModulesSettings
Loading

File-Level Changes

Change Details Files
Migrate command handlers from SimpleBus to Symfony Messenger message handlers with explicit flushing of Doctrine changes.
  • Annotate command handler classes with AsMessageHandler and change handler methods from handle() to __invoke().
  • Inject EntityManagerInterface into write-side handlers and call flush() after persisting/removing entities.
  • Adjust command classes (Copy*ToOtherLocale, etc.) to support being dispatched via Messenger while maintaining their data contracts.
src/Backend/Modules/MediaLibrary/Domain/MediaFolder/Command/DeleteMediaFolderHandler.php
src/Backend/Modules/MediaLibrary/Domain/MediaItem/Command/CreateMediaItemFromMovieUrlHandler.php
src/Backend/Modules/MediaLibrary/Domain/MediaFolder/Command/CreateMediaFolderHandler.php
src/Backend/Modules/MediaLibrary/Domain/MediaGroup/Command/SaveMediaGroupHandler.php
src/Backend/Modules/MediaLibrary/Domain/MediaItem/Command/CreateMediaItemFromLocalStorageTypeHandler.php
src/Backend/Modules/ContentBlocks/Domain/ContentBlock/Command/DeleteContentBlockHandler.php
src/Backend/Modules/MediaGalleries/Domain/MediaGallery/Command/CreateMediaGalleryHandler.php
src/Backend/Modules/MediaGalleries/Domain/MediaGallery/Command/UpdateMediaGalleryHandler.php
src/Backend/Modules/MediaLibrary/Domain/MediaFolder/Command/UpdateMediaFolderHandler.php
src/Backend/Modules/MediaLibrary/Domain/MediaItem/Command/UpdateMediaItemHandler.php
src/Backend/Modules/ContentBlocks/Domain/ContentBlock/Command/CopyContentBlocksToOtherLocaleHandler.php
src/Backend/Modules/ContentBlocks/Domain/ContentBlock/Command/CreateContentBlockHandler.php
src/Backend/Modules/ContentBlocks/Domain/ContentBlock/Command/UpdateContentBlockHandler.php
src/Backend/Modules/MediaLibrary/Domain/MediaItem/Command/DeleteMediaItemHandler.php
src/Backend/Modules/FormBuilder/Command/CopyFormWidgetsToOtherLocaleHandler.php
src/Backend/Modules/Location/Command/CopyLocationWidgetsToOtherLocaleHandler.php
src/Backend/Modules/Mailmotor/Domain/Settings/Command/SaveSettingsHandler.php
src/Frontend/Modules/Mailmotor/Domain/Subscription/Command/SubscriptionHandler.php
src/Frontend/Modules/Mailmotor/Domain/Subscription/Command/UnsubscriptionHandler.php
Replace command bus usage in actions, AJAX handlers, console commands, listeners, and managers with Symfony Messenger MessageBusInterface, and adjust related wiring.
  • Update all usages of command_bus/MessageBus to use messenger.default_bus and dispatch() instead of handle().
  • Inject MessageBusInterface where needed (e.g. console command, MediaItemManager, form types, AJAX actions, frontend subscription actions).
  • Simplify MediaItemManager to only depend on MessageBusInterface for deletions.
src/Backend/Modules/MediaGalleries/Console/MediaGalleryDeleteAllCommand.php
src/Backend/Modules/MediaLibrary/Actions/MediaItemMassAction.php
src/Backend/Modules/Pages/Engine/Model.php
src/Backend/Modules/MediaLibrary/EventListener/MediaItemDeletedReSequenceMediaGroupMediaItemListener.php
src/Backend/Modules/MediaLibrary/Ajax/MediaItemUpload.php
src/Backend/Modules/MediaLibrary/Manager/MediaItemManager.php
src/Backend/Modules/MediaLibrary/Actions/MediaFolderDelete.php
src/Backend/Modules/MediaLibrary/Ajax/MediaFolderMove.php
src/Backend/Modules/MediaLibrary/Ajax/MediaItemEditTitle.php
src/Frontend/Modules/Mailmotor/Actions/Subscribe.php
src/Backend/Modules/MediaGalleries/Actions/MediaGalleryDelete.php
src/Backend/Modules/MediaLibrary/Ajax/MediaItemAddMovie.php
src/Backend/Modules/MediaLibrary/Domain/MediaGroup/MediaGroupType.php
src/Backend/Core/Ajax/UpdateSequence.php
src/Backend/Modules/ContentBlocks/Actions/Add.php
src/Backend/Modules/ContentBlocks/Actions/Delete.php
src/Backend/Modules/ContentBlocks/Actions/Edit.php
src/Backend/Modules/Mailmotor/Actions/Ping.php
src/Backend/Modules/Mailmotor/Actions/Settings.php
src/Backend/Modules/MediaGalleries/Actions/MediaGalleryAdd.php
src/Backend/Modules/MediaGalleries/Actions/MediaGalleryEdit.php
src/Backend/Modules/MediaLibrary/Actions/MediaItemEdit.php
src/Backend/Modules/MediaLibrary/Ajax/MediaFolderAdd.php
src/Backend/Modules/MediaLibrary/Ajax/MediaFolderEdit.php
src/Backend/Modules/MediaLibrary/Installer/Installer.php
src/Frontend/Modules/Mailmotor/Actions/Unsubscribe.php
src/Backend/Modules/MediaLibrary/EventListener/MediaItemSubscriber.php
Reconfigure service definitions to rely on Symfony autowire/autoconfigure, register repositories as service aliases, and remove legacy command bus wiring.
  • Replace explicit handler service definitions and command_handler tags with type-based service definitions under _defaults autowire/autoconfigure.
  • Register repository classes as aliases to existing repository services for DI-friendly type-hints.
  • Update MediaLibrary, ContentBlocks, Mailmotor, MediaGalleries, FormBuilder, Location, and events config to use Messenger and autowiring.
  • Expose SpoonDatabase via a service alias and remove command_bus.public alias.
src/Backend/Modules/MediaLibrary/Resources/config/commands.yml
src/Backend/Modules/ContentBlocks/Resources/config/commands.yml
src/Backend/Modules/Mailmotor/Resources/config/commands.yml
src/Backend/Modules/MediaGalleries/Resources/config/commands.yml
src/Backend/Modules/MediaLibrary/Resources/config/form.yml
src/Backend/Modules/MediaGalleries/Resources/config/console.yml
src/Backend/Modules/FormBuilder/Resources/config/commands.yml
src/Backend/Modules/Location/Resources/config/commands.yml
src/Backend/Modules/MediaLibrary/Resources/config/events.yml
src/Backend/Modules/MediaLibrary/Resources/config/repositories.yml
src/Backend/Modules/ContentBlocks/Resources/config/repositories.yml
src/Backend/Modules/MediaGalleries/Resources/config/repositories.yml
app/config/config.yml
app/config/doctrine.yml
src/Backend/Modules/MediaLibrary/Resources/config/managers.yml
Remove SimpleBus integration from the application and update core dependencies and kernel bundles accordingly.
  • Drop SimpleBus Symfony and Doctrine bridge bundles from AppKernel registration.
  • Remove doctrine_orm_bridge configuration and command_bus public alias wiring.
  • Remove SimpleBus-related composer dependencies.
  • Minor related cleanups such as adjusting logger usage and Locale::fromString() return type to static for better extensibility.
app/AppKernel.php
app/config/doctrine.yml
app/config/config.yml
composer.json
src/Frontend/Modules/Mailmotor/Actions/Subscribe.php
src/Common/Locale.php

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 2 issues, and left some high level feedback:

  • The media_library.manager.item service definition still passes two arguments (@messenger.bus.default and @event_dispatcher) while MediaItemManager now only accepts a MessageBusInterface, so the extra event_dispatcher argument should be removed to avoid a container wiring error.
  • There is an inconsistency in how the messenger bus is referenced (@messenger.bus.default in service config vs. messenger.default_bus via $this->get(...) in various actions); aligning on a single service ID/alias will make the configuration clearer and reduce the risk of misconfiguration.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The `media_library.manager.item` service definition still passes two arguments (`@messenger.bus.default` and `@event_dispatcher`) while `MediaItemManager` now only accepts a `MessageBusInterface`, so the extra `event_dispatcher` argument should be removed to avoid a container wiring error.
- There is an inconsistency in how the messenger bus is referenced (`@messenger.bus.default` in service config vs. `messenger.default_bus` via `$this->get(...)` in various actions); aligning on a single service ID/alias will make the configuration clearer and reduce the risk of misconfiguration.

## Individual Comments

### Comment 1
<location path="src/Backend/Modules/MediaLibrary/Resources/config/managers.yml" line_range="20-22" />
<code_context>
+        autowire: true
+        autoconfigure: true
         public: true
-        arguments:
-            - "@content_blocks.repository.content_block"
-        tags:
</code_context>
<issue_to_address>
**issue (bug_risk):** Service definition for MediaItemManager no longer matches the constructor signature.

The service definition still passes two arguments (`@messenger.bus.default`, `@event_dispatcher`) while the constructor now only accepts a `MessageBusInterface`. This will break container compilation. Please either reintroduce the second constructor argument or, preferably, rely on autowiring and remove the explicit `arguments:` (at least the extra `@event_dispatcher`).
</issue_to_address>

### Comment 2
<location path="src/Frontend/Modules/Mailmotor/Actions/Subscribe.php" line_range="74" />
<code_context>
             }

-            $this->getContainer()->get('logger')->error('Mailmotor Subcribe Mailchimp error: ' . $reason);
+            $this->getContainer()->get('logger.public')->error('Mailmotor Subcribe Mailchimp error: ' . $reason);

             $this->template->assign('mailmotorSubscribeHasFormError', true);
</code_context>
<issue_to_address>
**suggestion (typo):** Log message contains a typo in the word 'Subscribe'.

Since this line is already being updated, please also correct the log message text to fix the typo in `'Mailmotor Subcribe Mailchimp error: '`, e.g. `'Mailmotor Subscribe Mailchimp error: '`.

```suggestion
            $this->getContainer()->get('logger.public')->error('Mailmotor Subscribe Mailchimp error: ' . $reason);
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@tijsverkoyen
Copy link
Copy Markdown
Member

Op verschillende plaatsen voeg je de EntityManager toe. En doe je $this->entityManager->flush();.
Niet logischer om dat in de repository te doen? Want nu is dat weer een extra dependency overal erbij.

@jonasdekeukelaere
Copy link
Copy Markdown
Member Author

Heb het al in aparte taak gestoken

@tijsverkoyen tijsverkoyen self-requested a review March 19, 2026 10:49
@jonasdekeukelaere jonasdekeukelaere merged commit 5310c6d into master Mar 19, 2026
10 of 12 checks passed
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.

2 participants