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

Formtype Bundle Laravel Package

integrated/formtype-bundle

Symfony bundle for defining and managing reusable form types with clean configuration and integration-friendly defaults, helping you build consistent forms faster across your applications.

View on GitHub
Deep Wiki
Context7

Getting Started

Start by accepting what this is. integrated/formtype-bundle is a Symfony bundle — the -bundle suffix, Kernel::registerBundles(), an Extension class, and Twig form themes are all Symfony vocabulary. There is no extra.laravel block, no package discovery, no config publish tag. You cannot composer require this into a Laravel app and get working form fields out of the box. The realistic day-to-day leverage for a Laravel developer is source material: you read it, quantify what's reusable, and port the domain logic into FormRequest classes and Blade components.

Minimal steps (day one, read-only).

git clone [email protected]:eactive/integrated-formtype-bundle.git /tmp/formtype-bundle
cd /tmp/formtype-bundle
git log -1 --format='%ci %s'          # recency — often the whole answer
cat composer.json                      # PHP + symfony/* constraint ranges
cat LICENSE 2>/dev/null                # can we legally vendor a fork?
find src -name '*Type.php' -o -name '*Extension.php'

Read in this order:

  1. src/IntegratedFormTypeBundle.php — confirms the FQCN and reveals whether it registers compiler passes or just loads a service file.
  2. src/Form/Type/ — these are the actual field definitions. This is where any reusable value lives.
  3. src/Form/Extension/ — if FormTypeExtensions are registered globally, the bundle silently changes every form in the app. That's either the main value or the main hazard; know which before you port anything.
  4. Resources/config/services.xml (or .yaml) and DependencyInjection/ — tells you which tags are wired and with what options.

First use case. Pick the single most repetitive field in your Laravel codebase — typically money, a date range, or an entity/select picker — and port only that one from the bundle's Type class into a Blade component plus a FormRequest rule set. Do not attempt a wholesale port on day one. One ported field proves whether the bundle's semantics are worth adopting or whether you already do it better.

Verify the stack assumption before spending more than an hour. If composer.json declares Symfony 2/3 constraints and PHP 7.x, stop — the code will not run on PHP 8.2+ without patching, and the port becomes an archaeology exercise.

Implementation Patterns

Pattern 1 — Port the field semantics (default recommendation). Map each Symfony construct to its Laravel equivalent and reimplement natively. Keep the bundle open as a spec.

Symfony construct Laravel equivalent
AbstractType::buildForm() Blade component <x-form.money /> + a FormRequest
configureOptions() defaults rules(), attributes(), messages() on the FormRequest
DataTransformer Eloquent cast, accessor/mutator, or a custom Casts\ class
FormTypeExtension (global) Default props on the Blade component; a shared FormRequest trait
Constraints (validator) Validation rules, or a Rule:: object for anything non-trivial
FormEvents / DataMapper prepareForValidation(), or Livewire updated* hooks
Twig form theme Blade component template + @error partial
CSRF (CsrfTokenManagerInterface) @csrf — already handled, do not double up

Keep the ported field's validation contract identical, then lock it with a test that feeds the original's expected inputs through the new FormRequest:

it('matches the original money type contract', function () {
    $this->post('/orders', ['total' => '1,234.50'])
        ->assertSessionHasErrors('total');        // locale-formatted input rejected
    $this->post('/orders', ['total' => '1234.50'])
        ->assertSessionHasNoErrors();
});

Pattern 2 — Standalone symfony/form behind an adapter (only if a requirement demands it). If the bundle's value is genuinely in Symfony Form's dynamic behaviour — conditional field trees, cross-field data mapping — you can run symfony/form as a standalone component. It needs a ValidatorInterface, a CsrfTokenManagerInterface, and a renderer (Twig, or a hand-written FormRendererInterface implementation). Do not use the bundle wrapper for this; the bundle almost certainly assumes FrameworkBundle.

Isolate it to a single namespace with one interface and a documented removal path:

interface DynamicFormBuilder
{
    /** @return array<string, mixed> validated payload */
    public function buildAndValidate(object $definition, array $input): array;
}

If the adapter leaks into more than one service, you've taken on a dual-framework form layer and the maintenance cost is permanent.

Pattern 3 — Centralize conventions, not classes. The bundle's real product decision is "one place where field behaviour and validation live." Reproduce that intent in Laravel without the dependency:

  • A BaseFormRequest with shared attributes() and messages() so error copy is uniform.
  • A HasMoneyField / HasDateRangeField trait that supplies rules and prepareForValidation() normalisation.
  • Blade components under resources/views/components/form/ that own markup, wire:model conventions, old() repopulation, and @error rendering.

This gives you the bundle's stated benefit — reducing duplicated form code — with zero cross-framework surface.

Workflow for the port itself. Work field-by-field, not bundle-by-bundle. For each type: read the Symfony class → write a failing feature test that encodes its behaviour → implement the Blade component and rules → commit. Five fields is roughly a day; if the spike shows the types are thin glue over symfony/form (common for internal bundles), a day is enough to conclude "write our own" and close it out.

Integration tips if you ever do take a dependency. Add a Composer VCS repository, pin a commit SHA, mirror the repo locally, and wrap it behind a service so composer remove is a one-file change. Never let it appear in more than one namespace.

Gotchas and Tips

It will not install cleanly into Laravel. No auto-discovery, no extra.laravel, and the service definitions reference Symfony DI tags (form.type, form.type_extension) that Laravel's container ignores. A successful composer require produces a registered bundle class that nothing instantiates — the classic silent failure where you conclude the package is broken when in fact it was never wired.

Two validation layers is the highest-severity risk. Symfony constraints alongside Laravel's Validator produce silent divergence: input accepted by one and rejected by the other, or accepted by both and invalid in the domain. If you go the adapter route, contract-test every field against both layers. The failure surfaces as bad data in the database, not as an exception.

Bitbucket access is a hard blocker. The repo may be private or credentialed. Confirm clone access and license terms before any review time is spent; if the repo is private, vendor a mirror the day you start — internal Bitbucket repos get deleted, and a build that depends on a dead host breaks irrecoverably.

Zero stars and zero dependents means you are the maintainer. There is no issue history to search, no Packagist metadata, no community security review. Budget for a permanent line item: your own CI, your own composer audit coverage, your own PHP-major-upgrade patches. If you can't name an owner for that fork, don't adopt it.

Watch for globally-registered FormTypeExtensions. They mutate every form in the app with no trace in the form class you're reading — the single hardest thing to debug in a Symfony form codebase and exactly the kind of magic you don't want to replicate. If you port extensions, make the behaviour explicit: props on the Blade component, or named traits, never a global default applied invisibly.

Option resolver defaults don't translate. Symfony's OptionsResolver distinguishes "not set" from "set to null"; Laravel's $request->input() and nullable rules do not. Field defaults that look identical can behave differently (empty string vs. null reaching the database). Assert the coerced value in a test, not just the validation outcome.

Data mapping is a different model. Symfony forms bind request data by field name directly onto an object; Laravel goes request → validated() array → fill()/create(). Ports that mechanically copy a Symfony type can end up with an Eloquent model being mutated before validation runs. Always $request->validated().

Formatting and timezone edge cases are where these types earn their keep. Money (decimal cast, locale input 1.234,50 vs 1,234.50), date ranges (inclusive/exclusive end, timezone on storage vs display), and file uploads (temp path vs stored path) are the fields most likely to hide the bundle's actual domain knowledge. Read those classes carefully before deciding they're trivial.

Debugging tools differ. You won't have bin/console debug:form. Use php artisan route:list, dd($request->all(), $request->rules()), and php artisan about for the runtime picture. If you keep the Symfony side as a spike, debug:form on a minimal Symfony app is the fastest way to see what the extension actually injects.

Exit plan, written down. However you adopt it — port or adapter — record the removal path in the PR: which files reference it, what replaces them, and what test proves parity. A dependency with no downstream users and no maintainer deserves an exit plan before it deserves a composer require.

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