Installation
composer require bic/form-validation
Register the bundle in config/bundles.php:
return [
// ...
Bic\FormValidationBundle\BicFormValidationBundle::class => ['all' => true],
];
First Use Case: Basic Form Validation Extraction Inject the service into a controller or command:
use Bic\FormValidationBundle\Service\FormValidation;
public function __construct(private FormValidation $formValidation) {}
public function index(Request $request)
{
$form = $this->createFormBuilder()->getForm()->handleRequest($request);
$validation = $this->formValidation->extract($form);
return $this->json($validation->toArray());
}
Key Files to Review
src/Service/FormValidation.php (core logic)src/Model/FormValidation.php (data structure)src/Validator/Constraints/ (custom constraints)Form Creation
Use Symfony’s FormBuilder as usual, but ensure fields are properly typed (e.g., custom DocumentType).
$form = $this->createFormBuilder($data)
->add('document', DocumentType::class)
->getForm();
Validation Extraction Pass the handled form to the service:
$validation = $this->formValidation->extract($form);
FormValidation object with:
Register + Document).JavaScript Integration Convert the validation to JS-friendly format:
$jsValidation = $this->formValidation->toJs($validation);
// Outputs: { "phone": { "required": true }, "document": { "type": "DocumentType" } }
API/CLI Validation Reuse the same logic for API responses or CLI tools:
$apiSchema = $this->formValidation->toOpenApi($validation);
FormBuilder and FormType classes.AbstractType and annotate constraints (e.g., @Assert\NotBlank()).FormBuilder methods like add() dynamically based on user roles/data.$validation->toArray() to templates for client-side validation hints.Constraint Mismatch
@Assert\Custom) may not serialize correctly.ConstraintInterface and are registered in the validator service.Nested Forms
User[Address[City]]) may not serialize as expected.FormBuilder::createNamedBuilder() for explicit nesting control.Circular References
User ↔ Profile) can cause infinite loops in toArray().JsonSerializable or SerializerComponent for safe conversion.Type Hints
/** @var */ casts.dump($this->formValidation->extract($form)->toArray());
$this->formValidation->toJs($validation, true); // Pretty-print
# config/packages/validator.yaml
services:
_defaults:
autowire: true
autoconfigure: true
Symfony\Component\Validator\Validator\ValidatorInterface: '@validator'
Custom Serializers
Implement Bic\FormValidationBundle\Serializer\FormValidationSerializerInterface to add new output formats (e.g., YAML, GraphQL).
Constraint Adapters
Extend Bic\FormValidationBundle\Validator\ConstraintAdapter to support non-Symfony constraints (e.g., Laravel’s Rule objects).
Event Listeners
Subscribe to form_validation.extract events to modify validation data pre-serialization:
$eventDispatcher->addListener(
'form_validation.extract',
fn($event) => $event->setData(array_merge($event->getData(), ['custom' => true]))
);
Configuration
Override default behavior via config/packages/bic_form_validation.yaml:
bic_form_validation:
include_constraints: ['NotBlank', 'Length'] # Whitelist constraints
js_format: 'angular' # 'angular', 'jquery', or 'custom'
How can I help you explore Laravel packages today?