kematjaya/hidden-type-bundle
The kematjaya/hidden-type-bundle is a lightweight Symfony bundle that provides a reusable hidden form type, making it easy to embed and manage hidden values in forms. Simple to install and configure, it integrates smoothly into existing PHP applications, letting developers add hidden fields without...
Reality check first: despite the "Laravel developer" framing, kematjaya/hidden-type-bundle is a Symfony bundle, not a Laravel package. It will not install into a Laravel app via composer require in any useful way — no service provider, no facade, no config publishing. If you are working in Laravel, treat this assessment as a design reference (how to model a "hidden value" form type) rather than a dependency you can pull in.
For a Symfony project:
composer require kematjaya/hidden-type-bundle
config/bundles.php. Older Symfony: config/bundles.php does not exist, so register in app/AppKernel.php. There is almost certainly no Flex recipe (2 stars, 0 dependents), so nothing is auto-wired for you.README.md — usually the only documentation that exists for a package this small.src/Form/Type/ — the actual form type class(es). This is the whole package.src/Resources/config/services.yaml (or services.xml) — the service ID and whether the type is autowired/tagged form.type.composer.json — the symfony/* version constraints. This tells you immediately whether it supports your Symfony version (e.g. ^4.4|^5.0 will break the moment you install it on Symfony 6/7).HiddenType when you need the bundle's extra behavior (option handling, data transformation, or view-variable setup).Minimal smoke test before you build anything on it:
$form = $this->createFormBuilder(['id' => 42])
->add('id', \Kematjaya\HiddenTypeBundle\Form\Type\HiddenType::class)
->getForm();
$form->handleRequest($request);
dump($form->getData(), $form->get('id')->getViewData());
If that renders an <input type="hidden"> and round-trips the value, the bundle is doing its job.
Basic field with a default. The most common day-to-day usage is supplying a value at build time rather than binding it from the request:
$builder->add('recordId', HiddenType::class, [
'data' => $entity->getId(),
'mapped' => false,
]);
Use 'mapped' => false when the value is contextual (a redirect target, a CSRF-adjacent token) and should not be written back onto your entity/DTO. Keep it mapped when it genuinely is a form field (e.g. an id on a DTO used to look up the record in a handler).
Edit forms / "carry the identity". The pattern that justifies the package: the user edits everything except the ID, but the ID must survive the POST.
$builder
->add('id', HiddenType::class)
->add('name', TextType::class)
->add('save', SubmitType::class);
Because it is a real form type, it participates in the normal pipeline: handleRequest() → isValid() → $form->getData(). Do not read $_POST directly for this value; let the form component do it and let the validator judge it.
Validation and integrity. A hidden field is just an input — a user can post anything. Pair the type with a constraint so the value is actually checked:
->add('id', HiddenType::class, [
'constraints' => [new Assert\NotBlank(), new Assert\Type('integer')],
])
For values that must not be tampered with (prices, foreign keys, tenant IDs), do not rely on the hidden input at all. Either (a) re-fetch the entity server-side from the ID and ignore any other hidden values, or (b) sign the value and verify the signature on submit. Standard Symfony practice, unchanged by this bundle.
Collections / embedded forms. If you have a CollectionType of rows, each row can carry its own hidden id. This is the classic "bulk edit" workflow:
$builder->add('items', CollectionType::class, [
'entry_type' => ItemType::class, // ItemType has a HiddenType 'id'
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
]);
This is where hidden IDs shine and where they are most dangerous — you must validate that each submitted id belongs to the current user/tenant before persisting.
Twig rendering. Symfony already renders hidden fields without a label or wrapper via form_rest(), but be explicit:
{{ form_start(form) }}
{{ form_widget(form.id) }}
{{ form_row(form.name) }}
{{ form_widget(form.save) }}
{{ form_end(form) }}
If the bundle registers a custom form theme, check src/Resources/views/Form/ and add it to twig.form_themes if it is not auto-registered.
Where the bundle does not fit. If all you need is a hidden input, Symfony's core Symfony\Component\Form\Extension\Core\Type\HiddenType already exists and is battle-tested. Only reach for this package if the README documents a concrete capability the core type lacks (e.g. automatic hydration of an entity by hidden ID, or a hidden variant that survives PRE_SUBMIT). Otherwise you are adding an unmaintained dependency for zero gain.
composer.json constraints are usually stale (^4.4 / ^5.x). On Symfony 6+ the bundle class may not implement the required BundleInterface methods or the service definitions may fail to load. Verify composer require resolves before writing any code against it, and be prepared to fork.src/ end to end — for a "form type for hidden values" it is likely one or two files. Do not guess the option names; open configureOptions().mapped and empty data. A hidden field that is mapped and submitted as an empty string can overwrite a valid entity property with null. Use 'mapped' => false for contextual values, or add NotBlank to catch it loudly.data vs empty_data vs getData(). If the value is not prepopulated, getData() returns null on the initial GET. Debug with dump($form->get('field')->getViewData()) — view data (the HTML value) and model data (your object property) are different, and this is the most common source of confusion with hidden fields generally.bin/console debug:container --tag=form.type and confirm the bundle's type class is listed. If it throws "Could not load type", the service ID in the bundle's services.yaml does not match the FQCN, or autoconfigure is off.autoconfigure: true on their service namespace, so the type is registered but not tagged form.type. If debug:container shows it but the form can't find it by class name, that is the cause — instantiate it by its container service alias or add the tag yourself in your own services.yaml.FormTypeExtension (getExtendedTypes() returning the bundle's type) to add options or view variables, and a form theme override to change markup. That keeps you upgradeable if the package ever ships a release — and cheap to drop if it does not.HiddenType plus a PRE_SUBMIT listener as soon as you hit a compatibility wall. Wrap its usage behind one small custom form type in your own codebase so the swap is a one-file change.How can I help you explore Laravel packages today?