Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Sulu Bulk Actions Bundle Laravel Package

manuxi/sulu-bulk-actions-bundle

A Sulu CMS bundle that adds bulk actions to admin list views, letting editors select multiple records and run actions such as delete, publish, or custom operations at once. Extensible action registration supports tailored editorial workflows.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Sulu CMS bundle built on Symfony, not a native Laravel package. The mental model maps cleanly enough: bundle registration replaces package discovery, bundle config replaces config/*.php, and Symfony service autowiring replaces Laravel’s container bindings.

Minimal setup:

composer require <vendor>/<package>

Register the bundle in config/bundles.php (or the Sulu bundle set), then confirm the config key:

# config/packages/sulu_bulk_actions.yaml
sulu_bulk_actions:
    delete_enabled: true

As of v1.2.0, delete_enabled defaults to true. You no longer need to opt in to expose the delete bulk action.

Look first at:

  • Resources/config/services.yaml — services moved from XML to YAML in v1.2.0.
  • ContentEntityBulkActionHandler — the core handler for content entity bulk operations.
  • docs/delete.en.md / docs/delete.de.md — new delete documentation.

First practical use case: enable bulk delete for articles, snippets, testimonials, or events, then verify a role with the “Delete” permission in the “Bulk actions” context and the list context can see and use the action. Test in the Sulu admin list view, not only via container inspection.

Implementation Patterns

Use permission-gated delete, not config-gated delete, as your primary control. delete_enabled: true only exposes the action; Sulu still checks the role’s “Delete” permission in the “Bulk actions” context and in the list context. Configure roles rather than disabling the feature globally unless you want to remove it for everyone.

Expect trash-aware deletion. ContentEntityBulkActionHandler now deletes like the Testimonials and Events controllers: it stores the entity in trash if the trash bundle is available, removes it, and collects the removed domain event. Treat the domain event as the integration point for search indexing and activity logging rather than manually reindexing after a bulk delete.

Use locale copy as a draft-copy primitive. ContentEntityBulkActionHandler implements LocaleCopyHandlerInterface and the new copy_locale bulk action copies the draft via the content manager for testimonials and events. It does not publish. A common workflow is: bulk copy locale → review drafts → bulk publish.

Rely on publish/unpublish domain events. In v1.2.0, publish and unpublish for testimonials and events collect published and unpublished domain events. Previously the activity log and search index were not updated for these bundles. If you have custom listeners or indexers, verify they react to these events rather than assuming the handler updates indexes directly.

Customize through the handler service. If you need different delete semantics, decorate or extend ContentEntityBulkActionHandler. Its constructor now takes:

  1. content manager
  2. domain event collector
  3. trash manager
  4. domain event classes

The last three are optional, but the order matters. In a normal Sulu application these are autowired; in a custom container or test setup, wire them explicitly.

Testing pattern. Assert three things for bulk delete: the entity is in trash when the trash bundle is present, the entity is removed from the content manager, and the removed domain event was collected. For locale copy, assert a draft was created in the target locale and that no publish event was fired.

Laravel comparison for day-to-day work: think of the domain event collector as an event dispatcher, the trash manager as a soft-delete/trash service, and services.yaml as your package’s service provider bindings.

Gotchas and Tips

The delete default changed. sulu_bulk_actions.delete_enabled is now true. If your application previously relied on delete being absent by default, set it to false. This is a visible admin UI change, though permission checks still apply.

services.xml is gone. v1.2.0 defines services in Resources/config/services.yaml, and symfony/yaml is now a requirement. If you override, copy, or merge the old XML service definitions, update them. A missing symfony/yaml dependency will fail at container build time, not at runtime.

Constructor compatibility. If you instantiate ContentEntityBulkActionHandler manually or override its service definition, update the arguments. The new signature is content manager, domain event collector, trash manager, domain event classes. The optional arguments are optional only if you do not need domain events or trash behavior.

Omitting optional services has consequences. If the domain event collector is not wired, activity log and search index updates that depend on removed, published, and unpublished events will not happen. If the trash manager is not wired, delete may permanently remove content instead of trashing it.

Locale copy is draft-only. Do not assume copy_locale publishes the copied content. Combine it with the publish action and verify permissions for both actions.

Permission debugging. If delete does not appear, check both the “Bulk actions” context and the list context for the role’s Delete permission before changing delete_enabled. Setting delete_enabled: false removes the action for everybody, including administrators.

Debugging commands. Use bin/console debug:container ContentEntityBulkActionHandler to inspect wiring, bin/console debug:config sulu_bulk_actions to confirm config, and clear the cache after YAML changes.

Extension points. The stable extension points are the bulk action handler service, LocaleCopyHandlerInterface for locale-copy behavior, the optional domain event classes, and the trash manager. Prefer listening to the collected domain events over duplicating handler logic.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib