b2bcodext / cms-form-builder
B2Bcodext - CMS Form Builder for OroCommerce to easily create forms via UI
Requires
- oro/commerce: 7.0.*
Requires (Dev)
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^9.5
- squizlabs/php_codesniffer: ^4.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-09-15 13:17:43 UTC
README
Build storefront forms for OroCommerce through the back-office UI — no code, no deployment.
Table of Contents
- Overview
- Requirements
- Installation
- Features
- Extension Points
- Tests
- Known Issues & TODOs
- License
- Resources
Overview
The bundle lets a back-office user assemble a form — its fields, validation, notifications and success behavior — and publish it to the storefront, without a developer writing a form type or a controller. Marketers own the whole lifecycle; developers extend it only where they need something the field-type catalog does not cover.
Five entities carry the model: CmsForm is the form itself, CmsFormField its fields,
CmsFormNotification the per-form email notifications, and CmsFormResponse / CmsFieldResponse
a submission and its individual field values. The runtime flow is
FormBuilder (turns a CmsForm into a Symfony form) → storefront submit → response entities
persisted → notification queued.
Requirements
Requires OroCommerce 6.1 (oro/commerce: 6.1.*).
Installation
-
Require the package:
composer require b2bcodext/cms-form-builder:"^2.5"The package versions on its own
2.xline — release2.5is the OroCommerce 6.1 line. It does not share OroCommerce's version numbers. -
Apply it to the application:
bin/console cache:clear bin/console oro:platform:update --env=prod --force
Forms are then available under Marketing > Cms Forms in the back-office menu. See how to create your first form.
Features
Backend
- Form management UI under Marketing > Cms Forms, routed under the
/cms-formprefix (Controller/FormController.php), with AJAX field editing, reordering and field preview under/cms-form/ajax(Controller/AjaxFormController.php). - A field-type catalog with per-type options and validation — see field types.
- Per-form email notifications (
CmsFormNotification), each able to use its own email template; sending goes throughNotification\SendEmailNotification. - Responses exported to CSV through the Oro import/export batch job
(
ImportExport/), scoped per form. - Responses are regular entities, so the Oro reports engine can build reports over them.
Frontend
- Storefront form rendering and submission over the layout stack
(
Controller/Frontend/FormController.php,Controller/Frontend/AjaxFormController.php,Resources/views/layouts), with per-field validation errors returned to the page and an optional redirect URL on success. - Forms can be embedded in landing pages and other CMS content; the bundle registers its Twig
functions with the CMS and email Twig sandboxes via
DependencyInjection/Compiler/TwigSandboxConfigurationPass.php.
Access Control
Declared in Resources/config/oro/acls.yml:
- Entity permissions on
CmsForm(VIEW / CREATE / EDIT / DELETE) and onCmsFormField(CREATE / EDIT / DELETE), governing the back-office UI. - An action ACL
b2b_code_cms_frontend_form_respondin thecommercegroup, granted to theBUYER,ADMINISTRATORandANONYMOUSfrontend roles by the data migrationMigrations/Data/ORM/data/frontend_roles.yml, and enforced on the storefront submit endpoint (Controller/Frontend/AjaxFormController::respondAction()). Revoking it stops submission: an authenticated customer user then gets 403, an anonymous visitor 401. The default grant toANONYMOUSkeeps storefront forms open to unauthenticated visitors out of the box.
Extension Points
| Contract | Purpose |
|---|---|
B2bCode\Bundle\CmsFormBundle\Provider\FieldTypeProviderInterface |
Contribute field types. Register with the b2b_code_cms_form.field_type_provider service tag. |
B2bCode\Bundle\CmsFormBundle\Validator\ConstraintProviderInterface |
Supply the validation constraints for a form (getConstraintsForForm(CmsForm)). |
B2bCode\Bundle\CmsFormBundle\Notification\NotificationInterface |
Replace or add to how a submission is notified. |
B2bCode\Bundle\CmsFormBundle\Builder\FormBuilderInterface |
Replace how a CmsForm becomes a Symfony form. |
Validation rules can also be declared in YAML or contributed from an event listener — see the developer documentation and how to add a new field type.
Tests
Both suites live in src/B2bCode/Bundle/CmsFormBundle/Tests and ship with the package. Run them from
the application the package is installed into. The two suites use different configurations, and
the difference matters: the unit suite runs against the package's own phpunit.xml.dist with the
application's autoloader passed explicitly (the package has no vendor directory of its own), while the
functional suite must run against the application's phpunit.xml.dist, which supplies the Oro test
bootstrap. Do not "correct" one to match the other.
Unit Tests
bin/phpunit -c vendor/b2bcodext/cms-form-builder/phpunit.xml.dist --testsuite=unit \
--bootstrap ./vendor/autoload.php
Functional Tests
Require an installed test environment (bin/console oro:install --env=test):
bin/phpunit -c phpunit.xml.dist \
vendor/b2bcodext/cms-form-builder/src/B2bCode/Bundle/CmsFormBundle/Tests/Functional
Static Analysis & Code Style
bin/phpcs --standard=vendor/b2bcodext/cms-form-builder/phpcs.xml.dist \
vendor/b2bcodext/cms-form-builder/src
phpcs ships with the Oro application. PHPStan does not — install it (the package declares
phpstan/phpstan: ^2.1 in require-dev) and run:
phpstan analyse -c vendor/b2bcodext/cms-form-builder/phpstan.neon
phpstan.neon runs at level 6 and excludes Tests.
CI
Omitted — the package ships no CI workflow. The hosting GitHub space does not support GitHub Actions, so the checks above are run locally and are not re-run automatically on push or pull request.
Known Issues & TODOs
ImportExport/Reader/FormResponseReader::createSourceEntityQueryBuilder()accepts an$idsargument but does not apply it, so a batched async export re-reads the whole form's responses instead of the requested slice. Current behavior is pinned by a unit test; changing it is a maintainer decision.- Sixteen
@todooccurrences remain in non-test source (one of them inside a string literal). The largest clusters areForm/Extension/ChoiceFieldExtension.php(3 — two asking for the choice-field handling to be reworked into data transformers or data mappers, which the bundle does not currently use) andController/Frontend/AjaxFormController.php(3, in the submit endpoint discussed under Access Control); the rest sit in the Twig extension, validation collection, field-type registry, response repository, notification sending and the schema installer. TheGeneric.Commenting.Todosniff is excluded inphpcs.xml.distso they are kept verbatim rather than deleted to satisfy a linter.
License
OSL-3.0 — Copyright (c) 2019 Daniel Nahrebecki