nowo-tech / contact-form-bundle
Symfony bundle for configurable multilingual contact forms with GDPR compliance, customizable fields, client association, and admin CRUD.
Package info
github.com/nowo-tech/ContactFormBundle
Type:symfony-bundle
pkg:composer/nowo-tech/contact-form-bundle
Fund package maintenance!
Requires
- php: >=8.2 <8.6
- doctrine/doctrine-bundle: ^2.13 || ^3.0
- doctrine/orm: ^3.7
- nowo-tech/form-kit-bundle: ^2.13.3
- nowo-tech/ui-kit-bundle: ^2.15.3
- psr/clock: ^1.0
- psr/log: ^1.1 || ^2.0 || ^3.0
- symfony/clock: ^7.4 || ^8.0
- symfony/config: ^7.4 || ^8.0
- symfony/console: ^7.4 || ^8.0
- symfony/dependency-injection: ^7.4 || ^8.0
- symfony/event-dispatcher: ^7.4 || ^8.0
- symfony/form: ^7.4 || ^8.0
- symfony/framework-bundle: ^7.4 || ^8.0
- symfony/http-foundation: ^7.4 || ^8.0
- symfony/http-kernel: ^7.4 || ^8.0
- symfony/property-access: ^7.4 || ^8.0
- symfony/routing: ^7.4 || ^8.0
- symfony/security-csrf: ^7.4 || ^8.0
- symfony/translation: ^7.4 || ^8.0
- symfony/twig-bundle: ^7.4 || ^8.0
- symfony/validator: ^7.4 || ^8.0
- twig/extra-bundle: ^3.12
- twig/string-extra: ^3.12
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.0
- igor-php/igor-php: ^0.10.0
- nowo-tech/phpstan-frankenphp: ^1.0
- phpstan/extension-installer: ^1.0
- phpstan/phpstan: ^2.0
- phpstan/phpstan-phpunit: ^2.0
- phpstan/phpstan-symfony: ^2.0
- phpunit/phpunit: ^11.0
- rector/rector: ^2.0
- symfony/browser-kit: ^7.4 || ^8.0
- symfony/css-selector: ^7.4 || ^8.0
- symfony/dom-crawler: ^7.4 || ^8.0
- symfony/mailer: ^7.4 || ^8.0
- symfony/rate-limiter: ^7.4 || ^8.0
- symfony/security-bundle: ^7.4 || ^8.0
- symfony/security-core: ^7.4 || ^8.0
- symfony/var-exporter: ^7.4 || ^8.0
- symfony/yaml: ^7.4 || ^8.0
- vincentlanglet/twig-cs-fixer: ^4.0
Suggests
- nowo-tech/phone-input-bundle: Rich phone fields with country flags and search in the prefix selector
- symfony/form: ^8.1 required for the admin field wizard (FormFlow)
- symfony/mailer: Send submission notifications via email
- symfony/rate-limiter: Atomic public submission rate limiting (public_submission_rate_limit.limiter)
- symfony/security-bundle: Link submissions to authenticated clients automatically
Provides
None
Conflicts
None
Replaces
None
- dev-master
- v1.6.4
- v1.6.3
- v1.6.2
- v1.6.1
- v1.6.0
- v1.5.1
- v1.5.0
- v1.4.1
- v1.4.0
- v1.3.2
- v1.3.1
- v1.3.0
- v1.2.0
- v1.1.3
- v1.1.2
- v1.1.1
- v1.1.0
- v1.0.23
- v1.0.22
- v1.0.21
- v1.0.20
- v1.0.19
- v1.0.18
- v1.0.17
- v1.0.16
- v1.0.15
- v1.0.14
- v1.0.13
- v1.0.12
- v1.0.11
- v1.0.10
- v1.0.9
- v1.0.8
- v1.0.7
- v1.0.6
- v1.0.5
- v1.0.4
- v1.0.3
- v1.0.2
- v1.0.1
- v1.0.0
- dev-feat/arch-bar-w1
- dev-fix/client-label-and-id
- dev-chore/symfony-security-2026-11-04
This package is auto-updated.
Last update: 2026-11-11 03:19:59 UTC
README
⭐ Found this useful? Install from Packagist · Give it a star on GitHub so more developers can find it.
Contact Form Bundle — configurable multilingual contact forms with GDPR consent, customizable fields (email, phone, text, textarea, select), optional client association, anonymous submissions, and admin CRUD. For Symfony 7.4+ and 8 · PHP 8.2+.
This bundle is FrankenPHP worker mode friendly, including when the kernel is not reset between requests (reset_kernel / services resetter off). Audit: docs/FRANKENPHP-WORKER-AUDIT.md.
Public form — phone prefix, topic select, GDPR consent |
Admin inbox — submissions per form (UiKit list) |
Submission detail — consent date and submitted values |
Features
- ✅ Admin CRUD for form definitions, customizable fields, and submissions
- ✅ Multilingual copy via translation entities (title, labels, GDPR text, success message)
- ✅ Customizable fields: text, email, phone, textarea, select (options per field)
- ✅ GDPR: required consent checkbox, privacy policy link, IP anonymization, retention days
- ✅ Client association: optional link to an existing host client entity or anonymous submissions
- ✅ Public form at
/{_locale}/contact/{slug}with PRG flow and flash success message - ✅ UiKit page contract (REQ-UI-003): admin pages on UiKit list / form / wizard / show scaffolds, public form on the guest layout — your layout and CSS stack once in
nowo_ui_kit, no template copies; deletes through the UiKit confirm dialog - ✅ Override Twig templates (per page via
web_ui.templates) and translations from your application - ✅ Pluggable notifications (custom notifier, Symfony Mailer, or
ContactSubmissionCreatedEvent) - ✅ GDPR retention cleanup via
nowo:contact-form:cleanup-submissions
Installation
composer require nowo-tech/contact-form-bundle
Register in config/bundles.php if Flex recipe is not applied:
Nowo\ContactFormBundle\NowoContactFormBundle::class => ['all' => true],
Import routes in config/routes.yaml:
nowo_contact_form: resource: '@NowoContactFormBundle/Resources/config/routes.yaml'
Run Doctrine migrations after mapping entities (bundle registers ORM mappings automatically).
Requirements
- PHP 8.2+
- Symfony 7.4+ or 8.0+
- Doctrine ORM 2.17+ or 3.x
- UiKitBundle ^2.15.3 and FormKitBundle ^2.13.3 (pulled transitively); set
nowo_ui_kit.layoutsto your layout (Configuration) twig/extra-bundle+twig/string-extra(pulled transitively)
Demo
make -C demo/symfony8 up
Default URL: http://localhost:8021 (see demo .env.example for PORT). The demo seeds three forms and a small
submissions inbox (app:seed-contact-demo) and renders every page through its UiKit host layouts
(templates/layouts/).
Playwright e2e and the README screenshots (REQ-DEMO-013): make test-e2e, make demo-screenshots (see
CONTRIBUTING).
FrankenPHP worker mode: default is FRANKENPHP_MODE=worker (see .env.example). Set classic for per-request PHP / easier hot-reload, then recreate the container (docker compose up -d). Details: docs/DEMO-FRANKENPHP.md.
Development
make up
make test
make qa
make release-check
Documentation
- Installation
- Configuration
- Usage
- Contributing
- Code of Conduct
- Changelog
- Upgrading
- Release
- Security
- Engram
- Spec-driven development
- GitHub Spec Kit
Additional documentation
- GitHub Actions CI requirements
- PSR evaluation (REQ-CS-007)
- Coverage policy
- Demo FrankenPHP (when using the FrankenPHP demo)
- FrankenPHP worker audit (no kernel reset)
Tests and coverage
| Language | Coverage |
|---|---|
| PHP | 100% line coverage of src/ (no exclusions; make test-coverage / CI fail below 100%). See docs/COVERAGE.md. |
| TS/JS | N/A |
| Python | N/A |
License & author
MIT · Nowo.tech · Héctor Franco Aceituno



