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

Step Bundle Laravel Package

idci/step-bundle

IDCI StepBundle is a Symfony bundle for modeling and running sequential steps in PHP applications. It helps structure multi-step processes such as wizards and workflows with reusable step definitions, navigation, and lifecycle hooks.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install and register

    composer require idci/step-bundle
    
    // config/bundles.php
    return [
        // ...
        IDCI\Bundle\StepBundle\IDCIStepBundle::class => ['all' => true],
    ];
    
  2. Look here first, in this order

    • README.md — usually the only prose docs; skim it before anything else.
    • DependencyInjection/Configuration.php — the config tree is the real documentation for workflow/step keys. It is more authoritative than the README.
    • Step/, Workflow/, Process/ namespaces — the abstractions you will actually extend.
    • Tests/ — for a bundle this size, the test suite is the best usage example you'll get.
  3. First use case: a two-step linear workflow

    Register a step as a service, describe the graph in YAML, and drive a Process (the per-run state object) through it from a controller.

    # config/packages/idci_step.yaml
    # Shape only — confirm exact keys against DependencyInjection/Configuration.php
    idci_step:
        workflows:
            onboarding:
                initial_step: collect_email
                steps:
                    collect_email:
                        type: my_app_collect_email
                    confirm:
                        type: my_app_confirm
                        next_step: ~   # terminal
    

    The moment you have one workflow running end-to-end behind a controller, you understand 80% of the bundle. Don't try to model your whole domain first.

Implementation Patterns

Treat a step as a unit of work, not a controller. Each step should do one thing, take what it needs from the process context, and return a result describing where to go next. Keep HTTP concerns (Request/Response, redirects) out of steps so they can run from a console command too.

Use step factories for anything parameterizable. This is the bundle's main scaling lever: rather than writing SendWelcomeEmailStep, SendReminderStep, SendInvoiceStep, write one SendEmailStep and expose it through a factory that accepts template, recipient_source, etc., in YAML. The step graph then becomes configuration rather than code — which is the whole point of a "highly customisable workflow".

Keep the graph in config, keep the logic in services. Workflow topology (order, branching, terminal steps) belongs in YAML so it can change without a deploy of new classes. Anything with a conditional business rule belongs in a step. Resist the urge to encode rules in step names.

Single-entry controller pattern. One route, one action: load the Process from the session or a persisted entity, ask the workflow which step is current, execute it, store the result, redirect to the same route (or render the step's view). This keeps the step graph fully dynamic and lets you add steps without adding routes.

public function run(Request $request): Response
{
    $process = $this->processStore->load($request->getSession()); // your persistence
    $result  = $this->workflowRunner->execute($process, $request);

    if ($result->isComplete()) {
        return $this->redirectToRoute('done');
    }

    $this->processStore->save($request->getSession(), $process);

    return $this->render($result->getTemplate(), $result->getViewData());
}

Persist the process, not the objects inside it. Store scalars and IDs in the process data. Step instances, entities, and closures do not survive serialization into a session or a JSON column.

Use a console command for batch/import flows. Because steps are plain services, the same graph can be walked by a command. This is where the bundle earns its keep: an import pipeline that a developer can also re-run and step through manually.

Cross-cutting concerns via subscribers, not base classes. Logging, audit trails, and metrics are better attached as event listeners/subscribers on step execution than pushed into a shared AbstractStep parent — otherwise every new step inherits behaviour it doesn't need.

Test the graph, not just the steps. Unit-test individual steps in isolation with a plain context object; then write one integration test that walks the full workflow and asserts the sequence of steps and the final state. The graph is where regressions hide.

Gotchas and Tips

  • You are effectively the maintainer. 6 stars and 0 dependents means no Stack Overflow answers, no third-party blog posts. Pin an exact version in composer.json, commit composer.lock, and be prepared to read source when something is unclear. Budget time for that on day one; it pays back.

  • Check the actual tags. The release metadata is inconsistent (the latest version is dated in the future), so don't trust the "last release" listing — run composer show idci/step-bundle --all and read the tag list before choosing a constraint.

  • Config caching will bite you. After editing workflow YAML, bin/console cache:clear in dev. After adding a new tagged step service, the container needs a rebuild — cache:clear again, or debug:container --tag=<step-tag> to confirm the tag actually picked it up.

  • Private services and runtime lookup. If steps are resolved from the container at runtime by ID, a private service will explode only when that branch of the workflow executes — which may be weeks after you wrote it. Prefer factory injection or a service locator, and add a smoke test that instantiates every configured step at boot.

  • Step names are array keys. Avoid dots, colons, and anything YAML-sensitive. Namespace them (onboarding.collect_email) if you have many workflows, and treat renames as breaking changes — persisted processes may reference the old name.

  • Don't assume monotonic progression. If your UI exposes a back button, a browser refresh, or a resumed session, steps can execute more than once. Make side effects (emails, payments, record creation) idempotent or guarded by a "already done" flag on the process.

  • Version your workflow definitions. Once processes are persisted, changing the graph can strand in-flight runs on a step that no longer exists. Either migrate open processes on deploy or version workflows by name (onboarding_v2).

  • Debugging: debug:container for registered steps and factories, debug:event-dispatcher for step events, and a temporary dump() inside your runner around the current-step resolution — most "stuck workflow" bugs are a step returning a next_step name that doesn't exist in the graph. Validate the graph at container compile time if the bundle doesn't already.

  • Extension points worth knowing: a custom step factory (parameterized behaviour), a custom step type (new kind of work), a decorator around the workflow/process factory (instrumentation, tenancy), and event subscribers (audit, logging). Start with factories and subscribers; only extend the core abstractions if you genuinely need new semantics.

  • It is not symfony/workflow. This bundle is its own abstraction with its own process model. Don't mix the two in one flow expecting shared state — pick one per feature and be explicit about it in your codebase conventions.

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.
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource