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

Seed Batch Bundle Laravel Package

libre-informatique/seed-batch-bundle

A Symfony/Sylius bundle that adds configurable batch actions to admin grids, letting editors select multiple resources and run bulk operations directly from the grid. It provides reusable batch action services and UI controls to streamline repetitive admin workflows.

View on GitHub
Deep Wiki
Context7

Getting Started

Reality check first. libre-informatique/seed-batch-bundle is a Symfony bundle, and it is marked [DEPRECATED]. There is no ServiceProvider, no auto-discovery, no php artisan vendor:publish path, and the composer.json will constrain symfony/* packages you do not have. Do not attempt composer require inside a Laravel app — resolve the dependency tree in a throwaway Symfony skeleton if you must install it at all, or simply clone the repo and read it.

Also read the name correctly: "Seed" is the host application (Libre Informatique's admin/ERP line), and "Batch" means batch processing — a framework for mass actions over entity collections, not a seed-lot/agriculture data model. The other evaluations in this repo got that backwards. What you are mining here is a pluggable batch-action architecture, not agritech schema.

Read in this order:

  1. composer.json — confirm the abandoned flag, PHP floor, and symfony/* / Doctrine constraints.
  2. *Bundle.php and DependencyInjection/ — see how actions are registered and tagged. This is the core idea worth stealing.
  3. The action interface/base class — what contract does a batch action implement? Does it get one entity or a chunk? Does it return a result object or a boolean?
  4. Resources/config/ — the service tag name and how the registry collects tagged services.
  5. Controller/ and any admin/grid glue — last, and only to see how the UI invokes a batch.

First use case: you have an admin grid (Filament, Nova, Livewire, Backpack) where an operator selects 500–50,000 rows and clicks "Export", "Reassign", or "Recalculate". You want that logic out of the controller, out of the Livewire component, and off the web request. That is the exact problem this bundle solves in Symfony — and the exact shape of Bus::batch() + chunked jobs in Laravel. Read this repo to validate your design, then build it natively.

Implementation Patterns

Translate the tagged-service registry to a Laravel registry. Symfony's tagged services exist so that adding a batch action is one class plus one tag, with no edits to a central switch statement. In Laravel, put that class list in a config key and resolve it through a small registry:

// config/batch.php
return ['actions' => [
    'export'         => App\Batch\Actions\ExportEntities::class,
    'recalculate'    => App\Batch\Actions\RecalculateTotals::class,
]];
final class BatchActionRegistry
{
    public function __construct(private array $actions) {}

    public function resolve(string $key): BatchAction
    {
        return app($this->actions[$key] ?? throw new InvalidArgumentException("Unknown batch action [$key]"));
    }

    public function all(): array { /* ->map(fn($c) => app($c)) for the UI dropdown */ }
}

The UI reads all() to build the action list; the controller takes a key and a query/selection, then hands off. New action = one class + one config line.

Keep the contract chunk-shaped, not row-shaped. The Symfony version almost certainly passes entities one at a time because it runs inline. In Laravel you want queue safety, so define:

interface BatchAction
{
    public function key(): string;
    public function label(): string;
    /** @param Collection<int, Model> $models */
    public function handle(Collection $models, BatchActionContext $ctx): void;
}

Then one job per chunk, dispatched through Bus::batch() so you get then / catch / finally callbacks and per-chunk failure tolerance (allowFailures()) for free:

$ids = $query->pluck('id');                    // snapshot the selection up front
$jobs = $ids->chunk(500)->map(
    fn ($chunk) => new RunBatchActionJob($actionKey, $chunk->all(), $contextId)
);

Bus::batch($jobs)
    ->allowFailures()
    ->onQueue('batch')
    ->name("{$actionKey}:{$contextId}")
    ->dispatch();

Snapshot the selection. The bundle operates on the ids the grid submitted. Do the same — never re-run the user's where clause inside the worker, or the set mutates under you mid-run.

Persist per-run state. A batch_runs table (id, action, total, processed, failed, payload, started_at, finished_at) plus a batch_run_failures table gives operators a progress bar and gives you a debugging trail. The bundle relies on the host app for this; you will not.

Where to put the code. app/Batch/{Actions,Jobs,BatchActionRegistry.php} with a bound BatchActionContext carrying actor id, run id, and action options. Controllers/Livewire components shrink to: authorize, validate, resolve action, create batch_runs row, dispatch, redirect with a run id.

Gotchas and Tips

  • NOASSERTION license. The repo's license file does not map to an SPDX identifier. Do not copy code, mapping files, or class bodies into your app until someone clears it. Read it as documentation; write your own implementation from the pattern.
  • Deprecation means "this is a design memo." No patches, no Symfony compatibility fixes, no security response. Treat any line you do reuse as code you now own forever.
  • Do not bridge Symfony into Laravel. A Doctrine bridge or bundle-emulation shim to run this inside a Laravel app costs strictly more than a two-day native reimplementation and leaves you with both frameworks' failure modes.
  • Beware the misleading name in tickets. If someone logs "evaluate seed batch package for seed-lot tracking," correct it: this is generic mass-action plumbing. The agricultural lot/genealogy model is a separate conversation, and this repo is not a useful source for it.
  • Chunk by id, not offset. chunk() with skip/take degrades and shifts rows when the action mutates the filtered column. Use chunkById() or lazyById().
  • Transaction scope. Commit per chunk, never around the whole run. A 50k-row transaction will hold locks for minutes and roll everything back on one bad row.
  • Idempotency and retries. Queue visibility timeouts cause silent re-runs. Guard mutating actions with a whereNull('batched_at') predicate or a unique job — a partial re-run is worse than a clean failure.
  • allowFailures() cuts both ways. It keeps one bad row from killing the batch, but you must record the failure yourself in catch; otherwise the operator sees "done" with silent losses.
  • Log the actor and the action options on every run. When someone asks "who exported the customer list and with which filters," the run row is the only answer you will have.
  • The one thing to keep from the bundle is the extension point: a registry keyed by string so a new mass action is additive. If you find yourself editing a match statement in a controller to add an action, the abstraction has already failed.
  • Debugging a stuck run: check the queue (Horizon/failed_jobs) first, then batch_runs.processed vs. total. A mismatch with no failed jobs almost always means a job timeout, not a logic bug.
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.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core