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

Wizard Bundle Laravel Package

ruwork/wizard-bundle

ruwork/wizard-bundle is a Symfony bundle for building multi-step wizard flows, helping organize forms and sequential user input into structured, manageable steps with navigation support.

View on GitHub
Deep Wiki
Context7

Getting Started

Note upfront: this is a Symfony bundle, not a Laravel package. A Laravel developer will either (a) use it inside a Symfony sub-service/hybrid app, or (b) read it as a reference implementation for a wizard pattern and port ~200 lines into a Laravel service. Given it's archived with 1 star and no dependents, treat it as a design reference, not a dependency you install into a new Laravel app.

If you do install it (Symfony context):

  1. composer require ruwork/wizard-bundle — expect to pin an old Symfony version; check composer.json constraints before committing.
  2. Register Ruwork\WizardBundle\RuworkWizardBundle in config/bundles.php.
  3. Look first at these classes (in the repo, src/):
    • Wizard / WizardInterface — orchestrates the step sequence.
    • StepInterface / AbstractStep — one form per step.
    • SessionWizardStorage (or equivalent storage) — persists step state across requests.
    • Event classes (e.g. StepEvent, WizardEvent) — hook points for branching/validation.
  4. First use case: a 3–5 step signup or checkout where each step is its own Symfony form type and the user must not lose data between requests.

For Laravel, the minimal port: a Wizard service resolving the current step from a session key, each Step implementing FormRequest + handle(), plus a controller that advances/rewinds the pointer.

Implementation Patterns

One step = one form type + one handler. The common shape is:

class AddressStep extends AbstractStep
{
    public function getForm(array $data): FormInterface { /* build form */ }
    public function handleForm(array $data): void { /* persist to storage */ }
    public function isApplicable(array $data): bool { /* conditional skip */ }
}

Session-backed linear flow with explicit navigation. The controller pattern is almost always a redirect, not a render-through:

  • GET /wizard/step/{name} → render.
  • POST /wizard/step/{name} → validate, handleForm, advance pointer, redirect() to the next step URL.
  • Redirecting on POST avoids double-submission and back-button re-posting — the classic wizard pitfall.

Compose steps, don't inherit. Register each step as a tagged service; let the wizard receive an iterable of steps. This lets you reorder the flow in config or reorder via priority without editing classes.

Conditional branching via isApplicable(). Steps opt themselves out (e.g. "company details" only if user chose "business"). Keep the branch logic inside the step, not in the controller — otherwise the controller becomes a switch monster.

Event hooks for cross-cutting concerns. Use the step/wizard events to do things like: recompute totals, send partial-completion analytics, or invalidate downstream step data when an earlier step changes. In Laravel the equivalent is Event::dispatch(new StepCompleted(...)) inside the wizard service.

Storage abstraction. Keep WizardStorageInterface (or your own contract) in front of session data. Swap SessionWizardStorage for a database- or cache-backed implementation when a wizard must survive session expiry (e.g. long checkout abandonments).

Resume-on-return. On wizard entry, if storage has state, jump to the first incomplete step rather than step 1. This is the single biggest UX win and is nearly free once storage exists.

Gotchas and Tips

  • Archived — no upstream fixes. Pin the exact version, and vendor the code if you depend on it. Security-relevant issues (session unserialization, form tampering) will not be patched.
  • Symfony/Laravel impedance mismatch. Do not try to composer require this into a Laravel app and expect it to boot — bundles need Symfony's kernel. Port the pattern instead.
  • Session serialization of steps/forms is fragile. Never put a live FormInterface or entity manager object into session storage. Store plain arrays/IDs; rebuild forms on request.
  • Back/forward navigation. Users will use the browser back button. Decide explicitly whether revisiting a step re-validates downstream data or leaves it stale. The safe default is: re-validate everything from the current step onward when an earlier step changes.
  • Double POST / refresh. Always redirect after successful step submission (Post/Redirect/Get). Missing this is the #1 wizard bug.
  • Validation at final submit. The wizard must re-run handleForm for all applicable steps at the end (or at least re-check isApplicable) — data may have been mutated or steps added since.
  • isApplicable() must be cheap and side-effect-free. It's called on every step transition; doing DB writes there causes subtle bugs.
  • Config quirks: bundle-level config usually only has the storage service and step tags. Check src/DependencyInjection/Configuration.php for the exact keys — don't guess.
  • Extension points worth using: the storage interface (swap for DB/Redis), the step interface (add isApplicable(), label() for a progress bar), and events (analytics, totals).
  • Testing tip: drive the wizard from the controller layer with functional tests that walk the full flow (POST each step, assert redirect target and final persisted state). Unit-testing the Wizard service alone will miss session and form-boundary bugs.
  • Progress UI: expose a getSteps()/getProgress() on the wizard so your Blade/Twig template can render step indicators; don't hardcode step lists in the view.
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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
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
cgv/localized-resource