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

Form Bundle Laravel Package

netvlies/form-bundle

Netvlies FormBundle extends Symfony's form component with reusable form types, extensions and helpers, making it easier to build, customize and render complex forms in PHP applications.

View on GitHub
Deep Wiki
Context7

Getting Started

This bundle targets Symfony 2.x with Sonata Admin. Before writing any code, confirm it will actually install in your project — on a modern Laravel app (or Symfony 5/6/7), there is no adapter path; treat it as a reference implementation for a forms module. Use it only in a legacy Symfony 2 maintenance app, or plan to fork and own it.

  1. Confirm the constraint match. Read the bundle's composer.json require block first. It pins Sonata Admin, Doctrine, and SwiftMailer versions — those dictate whether it can coexist with the rest of your stack. If Composer cannot resolve, stop here; do not "fix" it by loosening constraints.

  2. Install with Composer against the Symfony 2 constraint your app already uses:

    composer require netvlies/form-bundle
    
  3. Register the bundle in app/AppKernel.php, along with its dependencies (SonataAdminBundle, SonataDoctrineORMAdminBundle, DoctrineBundle, SwiftmailerBundle).

  4. Create the schema from the shipped Doctrine entities (forms, fields, stored results). Generate a migration — never use schema:update in production:

    php app/console doctrine:migrations:diff
    php app/console doctrine:migrations:migrate
    
  5. Configure in app/config/config.yml: mailer from/to addresses, storage, export settings. Verify the exact config keys against the README for the version you installed — they are not stable across tags.

  6. Where to look first:

    • README.md — config keys and the intended workflow.
    • Admin/ — FormAdmin and field admin classes show how a form is modeled and edited.
    • Entity/ — understand the form → field → result relationships before writing any query against submissions.
    • The controller/service that compiles stored field definitions into a Symfony\Component\Form\Form at runtime.
  7. First use case: create a form in Sonata Admin, add a few fields (text, email, textarea, select), set a recipient, embed the rendered form in a Twig template, submit it, and verify both outcomes — the result row is persisted and the notification email is delivered. That single loop exercises every moving part in the bundle.

Implementation Patterns

Admin-driven form definition. Forms are Doctrine entities managed through Sonata Admin. Each field carries a type, label, required flag, and position. The admin is the source of truth: developers do not hardcode front-end fields — the bundle compiles the stored definitions into a Symfony Form at runtime. When you need a new field type, you add it to the field-type registry (and typically a Twig block for rendering) rather than touching each consumer.

Runtime rendering. The typical integration is a controller route that loads the form entity, builds the Symfony Form, handles the request, persists the result, and sends mail. Embed it from a page template:

{{ render(controller('NetvliesFormBundle:Form:show', { id: form.id })) }}

Use render(controller(...)) (a sub-request) rather than render('...:show.html.twig') directly, because the controller is what attaches the CSRF token, form state, and validation errors.

Storage and reporting. Submissions are persisted as Doctrine entities linked back to the form and its field definitions. Query through the entity repositories, not raw SQL — the relationship graph (form ↔ field ↔ value) is the contract. For export, drive it off the same repository query and stream the file; do not hydrate everything into memory if volumes are non-trivial.

Notification on submit. Mail is sent as part of the submit handler. Treat email as a notification, not the source of truth: the submission row is durable, the mail is best-effort. If you need retries or delivery visibility, wrap the send in your own service, log outcomes, and consider a queue (in a legacy Symfony 2 app, that typically means a lightweight messenger or a cron-driven outbox — SwiftMailer's spool can work if you configure it).

Reusable form types. Prefer composing shared Symfony form types (address block, contact block, choice sets) and referencing them from stored field definitions, rather than repeating field configs across forms. This is where the bundle's "clean reusable layer" value shows up in day-to-day work.

Extending workflows. The integration points, in order of usefulness:

  • a custom admin class extending FormAdmin for per-form behavior;
  • an event/subscriber around submit if the bundle exposes one (check the controller — hooks here are usually thin);
  • overriding the Twig templates (forms render blocks) for layout and styling;
  • a small service that transforms a stored field.type into a Symfony field type, which is the natural seam for adding new types without touching core code.

Gotchas and Tips

Framework mismatch is total. On Laravel there is no integration path — no service provider, no Eloquent mapping, no Blade equivalent of its Twig wiring. If you landed here from a Laravel roadmap, read it as a spec (form-definition schema, submission table, templated notification, CSV export) and rebuild on Laravel with Filament/Nova, Mail + queues, and maatwebsite/excel. Do not attempt an adapter.

EOL stack. Symfony 2.8 reached end-of-life in 2018, and Sonata Admin + Doctrine + SwiftMailer from that era are similarly abandoned. Direct use is defensible only inside an already-legacy Symfony 2 service with a bounded lifespan and a named owner for patches. Assume no upstream fixes are coming.

Config keys drift between versions. The README is version-specific and thin. Before wiring config, read the bundle's DependencyInjection/Configuration.php — that file, not the README, is the authoritative list of options (and their defaults).

Schema drift. Because forms and fields are rows, changing a field definition affects future renders but not historical submissions. Decide up front whether to snapshot the field definition on each submission (recommended) — otherwise editing a form silently changes how past results are interpreted in exports.

Mail failures are silent. SwiftMailer send can fail (transport down, bad recipient) without surfacing to the user. Log sends and failures explicitly, and test with a failover/spool transport before going live. Public forms also attract spam — the bundle's flat model has no built-in captcha/rate limiting; add a Symfony form extension or a middleware-like guard yourself.

Export is memory- and timeout-sensitive. Batch/stream exports and cap the result set, or a large form will exhaust memory. Test with realistic volumes, not three rows.

Sonata Admin is the security surface. Admin-defined forms mean non-developers can create public-facing input surfaces. Restrict who can publish forms, disable raw HTML/file-upload field types unless explicitly needed, and review the admin ACLs — a misconfigured admin is an injection and spam vector, not just a UX issue.

CSRF and validation. Embed via the controller sub-request so CSRF and validation errors render correctly. If you bypass the controller (e.g., constructing the form in your own service), you take on token generation, error display, and redirect-after-post yourself.

Testing. Assume minimal test coverage in the bundle. Add your own functional tests around the submit path (persist + mail) and the export endpoint; those are the two places a regression is most expensive and least obvious.

Extension points worth knowing. The rendering Twig blocks, the field-type-to-form-type mapping service, and a subclass of FormAdmin are the three seams most day-to-day changes flow through. Keep customizations in your app's overrides, not edits to the vendored package, so upgrades (or a fork) stay tractable.

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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource