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

Extended Form Type Laravel Package

grossum/extended-form-type

Grossum Extended Form Type is a Laravel/PHP package for extending standard form types, making it easier to build reusable, customized form fields with less boilerplate. It fits into existing form workflows and helps keep field definitions clean and maintainable.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a small, single-purpose Symfony bundle from 2018 with no stars, no dependents, and no release since April 2018. Treat it as legacy-maintenance-only: the right way to "start" with it is to confirm whether you actually need it, or whether you're inheriting it in an existing composer.json.

1. Confirm compatibility before anything else

composer show grossum/extended-form-type --all

Check the require block for the Symfony constraint. A 2018 bundle will typically pin symfony/form, symfony/framework-bundle, and symfony/dependency-injection to ^2.8|^3.0. On Symfony 4.4+/5+/6+ expect friction: Bundle::boot() signatures, getName() being removed from AbstractType, and container-aware services being deprecated. If you're on Symfony 5+, plan on forking rather than installing.

2. Install and register

composer require grossum/extended-form-type

Symfony 3 style (app/AppKernel.php):

$bundles = [
    // ...
    new Grossum\ExtendedFormTypeBundle\GrossumExtendedFormTypeBundle(),
];

Symfony 4+ style (config/bundles.php):

return [
    Grossum\ExtendedFormTypeBundle\GrossumExtendedFormTypeBundle::class => ['all' => true],
];

3. Where to look first

The repo is tiny — read it in this order:

  1. GrossumExtendedFormTypeBundle.php — confirms the bundle alias and whether it registers compiler passes.
  2. DependencyInjection/ — the extension + Configuration.php tell you every config key that exists (likely very few).
  3. Form/Type/ (or Form/) — the actual type classes. This is where the value lives.
  4. Resources/config/services.yml — shows which services are public, tagged form.type, or tagged form.type_extension.

4. First use case

The bundle's premise is that you extend its base type instead of Symfony's AbstractType, and pick up whatever conveniences it layers on (typically shared option handling, default required/placeholder/help behavior, or a helper for translating labels). Start by converting one existing form type to the bundle's base class, render it unchanged, and diff the HTML output and the resolved option array. Do not convert the whole app at once — you need a baseline to compare against.


Implementation Patterns

Pattern: single form type as a canary

Pick the least critical form in the app. Swap the parent class only:

use Grossum\ExtendedFormTypeBundle\Form\AbstractType as ExtendedAbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class ContactType extends ExtendedAbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('email', EmailType::class)
            ->add('message', TextareaType::class);
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Contact::class,
        ]);
    }
}

Render it in Twig exactly as before. Any visible or behavioral change is attributable to the base class — that's your signal.

Pattern: shared defaults via the resolver

The usual payoff for a bundle like this is codifying house conventions. If the base type exposes a hook (e.g. a configureDefaults() or a set of extra options), push your app-wide defaults through it rather than repeating 'required' => false in fifty types:

public function configureOptions(OptionsResolver $resolver)
{
    parent::configureOptions($resolver);

    $resolver->setDefaults([
        'attr' => ['class' => 'form-control'],
        'translation_domain' => 'forms',
    ]);
}

Calling parent::configureOptions() first is important — if the bundle sets defaults, doing it in the other order silently overwrites them.

Pattern: compose instead of inheriting

If you only need a cross-cutting concern (a CSRF tweak, an anti-spam honeypot, a "required field" asterisk), use Symfony's native extension mechanism and keep the bundle out of the type hierarchy:

use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\Extension\Core\Type\FormType;

class FormControlExtension extends AbstractTypeExtension
{
    public static function getExtendedTypes(): iterable
    {
        return [FormType::class];
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefault('attr', ['class' => 'form-control']);
    }
}

This is the safer long-term path: it survives the bundle being dropped, and it doesn't couple every form type in your app to an unmaintained package.

Pattern: service-based types

If the bundle's types take constructor arguments (entity repositories, translators), register them explicitly. On Symfony 4+ autowiring will usually pick them up; on older setups add the tag:

services:
    app.form.type.contact:
        class: AppBundle\Form\ContactType
        arguments: ['@doctrine.orm.entity_manager']
        tags: ['form.type']

Pattern: incremental strangler

In an inherited codebase where the bundle is load-bearing, don't rip it out in one PR. Instead:

  1. Add a native AbstractTypeExtension that reproduces the bundle's behavior.
  2. Flip one type at a time from the bundle base class to native AbstractType.
  3. Once grep -r Grossum returns nothing, remove the dependency.

This keeps composer update unblocked while you migrate, which matters because the pinned Symfony constraints will otherwise hold the whole app back.


Gotchas and Tips

It is effectively abandoned. Last release 2018-04-13, zero stars, zero dependents. There is no community to catch regressions and no security response. Treat every behavior as "vendor code you own." If it's a genuine dependency, fork it into your VCS and maintain it there — don't rely on Packagist availability.

No dependents means no smoke test. Nobody else has run this against your Symfony version. Budget time for a manual pass over every form that uses it, including edge cases: validation failures, POST re-render with errors, and file uploads (if applicable).

Zero stars also means thin docs. The README is likely 10 lines. The DI configuration and the type classes are the documentation. Run:

bin/console config:dump-reference grossum_extended_form_type

If the alias isn't what you guessed, find it in the bundle class (getName() / getContainerExtension()).

Debug the resolved options, not the type class. The single most useful command when a form behaves unexpectedly:

bin/console debug:form AppBundle\Form\ContactType

It prints the full option tree with resolved defaults and marks which extension contributed each one — that's how you find out exactly what the bundle is injecting.

Watch the option-resolver order. If the bundle's base type sets defaults in configureOptions() and you call $resolver->setDefaults() before parent::configureOptions(), your values win — sometimes you want that, usually you don't. Be explicit in every override.

getName() and form type naming. If the bundle's types implement the old static getName() and you're on Symfony 4.3+, you'll get deprecation notices, and on 5.0 the method is gone. If the bundle calls getName() on your types internally, it will break. Grep for it before upgrading.

Service visibility / services.yml in the bundle. Bundles from this era often declare services without public: false or with a services: block that Symfony 4+ will complain about. If the container fails to compile, the bundle's Resources/config/services.yml is almost always the cause — you can patch it in a fork without changing any PHP.

Templates are a likelier breakage point than PHP. Symfony's form theme blocks (form_row, form_widget) changed subtly across 3.x→4.x→5.x. If the bundle ships Twig overrides, verify they're picked up (debug:twig shows template paths) and that they still override what you expect.

Extension points, in order of preference:

  1. Subclass the bundle's base type in your app — cheapest, but deepens the coupling.
  2. Decorate a bundle service (decorates: in services.yml) — good for changing a single behavior without touching vendor code.
  3. FormTypeExtension on FormType::class — best when the behavior is generic; it makes the bundle redundant over time.
  4. Fork — the pragmatic answer here given the maintenance status.

Don't let it pin your Symfony version. The most common real cost of a bundle like this isn't a bug, it's a composer.json conflict that blocks a framework upgrade for the whole project. If you decide to keep it, check its constraints against your target Symfony release before the upgrade sprint, not during it.

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.
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
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