ecohead/symfony-form-generator-bundle
Installation:
composer require ecohead/symfony-form-generator-bundle
For non-Flex projects, also enable the bundle in config/bundles.php.
First Use Case: Replace a traditional Symfony form builder array with a fluent API. Example:
use Ecohead\FormGeneratorBundle\Form\Generator;
$form = $this->createFormBuilder()
->add('name', Generator::text('Name')->required())
->add('email', Generator::email('Email')->required()->unique())
->getForm();
Key Files to Review:
src/Form/Generator.php (core fluent methods)src/DependencyInjection/ (configurable options)tests/ (real-world usage examples)Fluent Form Building:
Chain methods for field configuration (e.g., Generator::text()->required()->unique()).
$builder->add('username', Generator::text('Username')
->label('Your Username')
->attr(['placeholder' => 'Enter username'])
->constraints([new NotBlank(), new Length(['max' => 50])])
);
Dynamic Field Generation:
Use Generator::choice() with dynamic options:
$roles = ['admin', 'editor', 'user'];
$builder->add('role', Generator::choice('Role', $roles)
->multiple()
->expanded()
);
Reusable Field Types:
Create a custom generator class (e.g., CustomGenerator) extending Generator for project-specific defaults:
class CustomGenerator extends Generator {
public static function password(string $name): self {
return self::text($name)
->attr(['autocomplete' => 'new-password'])
->constraints([new NotBlank(), new Length(['min' => 8])]);
}
}
Form Events Integration: Attach event listeners after fluent generation:
$form = $builder->getForm();
$form->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
$data = $event->getData();
// Modify form based on data
});
Symfony UX Integration: Combine with Symfony UX for enhanced interactivity:
$builder->add('search', Generator::text('Search')
->attr(['symfony_ux_autocomplete' => true])
);
form_row() with custom classes from fluent attributes:
{{ form_row(form.username, {'attr': {'class': 'form-control'}}) }}
Generator::text('Field')->validationGroup('registration');
csrf_token() is added to the form after fluent generation.Method Chaining Order:
Generator::text()->constraints()).attr()) override defaults but can be reset with attr(['key' => null]).Symfony Version Mismatch:
The bundle targets Symfony 5.4+. Test with symfony/form ^5.4 in composer.json.
Dynamic Options Caching:
For Generator::choice() with database-driven options, cache the query result to avoid N+1 issues:
$options = $this->entityManager->getRepository(Role::class)->findAll();
$builder->add('role', Generator::choice('Role', $options)->byReference());
Form Theming Conflicts:
Fluent attributes may clash with Twig themes. Use attr(['class' => 'custom-class']) explicitly.
$form->getErrors(true); // Returns all errors (including nested)
Generator::text() instead of Generator::string() (Symfony 5.4+ uses text for strings).Custom Generators:
Extend Ecohead\FormGeneratorBundle\Form\Generator to add project-specific methods:
class AppGenerator extends Generator {
public static function phone(string $name): self {
return self::text($name)
->attr(['type' => 'tel'])
->constraints([new Assert\Regex('/^\+?[\d\s\-\(\)]{10,}$/')]);
}
}
Override Defaults:
Configure global defaults in config/packages/ecohead_form_generator.yaml:
ecohead_form_generator:
defaults:
text:
attr:
class: "form-control"
Event Listeners:
Subscribe to FormGeneratorEvents (if available) to intercept fluent generation:
// config/services.yaml
services:
App\EventListener\FormGeneratorListener:
tags:
- { name: kernel.event_listener, event: ecohead.form_generator.build, method: onBuild }
How can I help you explore Laravel packages today?