PHPackages                             vardumper/ibexa-form-builder-bundle - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. vardumper/ibexa-form-builder-bundle

ActiveSymfony-bundle[Utility &amp; Helpers](/categories/utility)

vardumper/ibexa-form-builder-bundle
===================================

Standalone Ibexa DXP bundle for rendering frontend-facing forms managed as Ibexa content.

1.0.9(1mo ago)149[6 PRs](https://github.com/vardumper/IbexaFormBuilderBundle/pulls)MITPHPPHP ^8.3CI passing

Since Mar 26Pushed 2w agoCompare

[ Source](https://github.com/vardumper/IbexaFormBuilderBundle)[ Packagist](https://packagist.org/packages/vardumper/ibexa-form-builder-bundle)[ Docs](https://github.com/vardumper/IbexaFormBuilderBundle)[ Fund](https://www.buymeacoffee.com/vardumper)[ Fund](https://www.patreon.com/vardumper)[ RSS](/packages/vardumper-ibexa-form-builder-bundle/feed)WikiDiscussions main Synced 3w ago

READMEChangelog (10)Dependencies (47)Versions (19)Used By (0)

   [ ![Ibexa Logo](https://camo.githubusercontent.com/eaca7ff6afc475ad5009191851b83057df684df9d40fe1a1ba0a47535a7c29e0/68747470733a2f2f76617264756d7065722e6769746875622e696f2f657874656e6465642d68746d6c646f63756d656e742f6c6f676f2d69626578612e737667) ](https://ibexa.co)  IbexaFormBuilderBundle
======================

[](#ibexaformbuilderbundle)

 [ ![Latest Stable Version](https://camo.githubusercontent.com/38b98ee671a575dce2594ec7d26bd1ef8fd3e7dbf3767b19000ad4d225b331d1/68747470733a2f2f706f7365722e707567782e6f72672f76617264756d7065722f69626578612d666f726d2d6275696c6465722d62756e646c652f762f737461626c65) ](https://packagist.org/packages/vardumper/ibexa-form-builder-bundle) [![Total Downloads](https://camo.githubusercontent.com/232eed59fea00c371b338baa0fd2a47385b4de890c8436f9fbf54d01557cf0d4/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f76617264756d7065722f69626578612d666f726d2d6275696c6465722d62756e646c65)](https://camo.githubusercontent.com/232eed59fea00c371b338baa0fd2a47385b4de890c8436f9fbf54d01557cf0d4/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f76617264756d7065722f69626578612d666f726d2d6275696c6465722d62756e646c65) [![License](https://camo.githubusercontent.com/90e1426799a40ac79f73b9f2de33f8939117f257ab8d18cc638a1ec40fb4e0fe/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d6d69742d726564)](https://camo.githubusercontent.com/90e1426799a40ac79f73b9f2de33f8939117f257ab8d18cc638a1ec40fb4e0fe/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d6d69742d726564) [![](https://camo.githubusercontent.com/0395833017ab75581633c6828b2a15a3e2b8146edfd2fc916b8c4dab59859441/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f756e697425323074657374732d70617373696e672d677265656e3f7374796c653d666c617426636f6c6f723d253233346331)](https://camo.githubusercontent.com/0395833017ab75581633c6828b2a15a3e2b8146edfd2fc916b8c4dab59859441/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f756e697425323074657374732d70617373696e672d677265656e3f7374796c653d666c617426636f6c6f723d253233346331) [![](https://raw.githubusercontent.com/vardumper/IbexaFormBuilderBundle/refs/heads/main/coverage.svg)](https://raw.githubusercontent.com/vardumper/IbexaFormBuilderBundle/refs/heads/main/coverage.svg) [![](https://camo.githubusercontent.com/ecfba9c813ceb3951368949540c8b593af8064d7db01d685ff90c88ad6c3ef28/68747470733a2f2f64747261636b2e6572696b706f65686c65722e75732f6170692f76312f62616467652f76756c6e732f70726f6a6563742f33353338373234372d666331652d343637372d386338392d3762666134633735336362623f6170694b65793d6f64745f6e473833575f454163515a6b6b3662354b716b6e49566f4b386e664e6a537a33384f6d706e6e)](https://camo.githubusercontent.com/ecfba9c813ceb3951368949540c8b593af8064d7db01d685ff90c88ad6c3ef28/68747470733a2f2f64747261636b2e6572696b706f65686c65722e75732f6170692f76312f62616467652f76756c6e732f70726f6a6563742f33353338373234372d666331652d343637372d386338392d3762666134633735336362623f6170694b65793d6f64745f6e473833575f454163515a6b6b3662354b716b6e49566f4b386e664e6a537a33384f6d706e6e)

Standalone Ibexa DXP bundle for rendering frontend-facing forms managed as Ibexa content. Forms are modelled as a content type tree — each field (input, textarea, select, choice, fieldset, horizontal group, button) is a separate content item nested under a form content item. Submissions are stored in a dedicated database table and/or delivered via email.

Requirements
------------

[](#requirements)

- PHP &gt;= 8.3
- Ibexa DXP &gt;= v4.4 or &gt;= v5.0
- Symfony 5.4.x or 7.x
- Doctrine ORM ^2.11 or ^3.0

Features
--------

[](#features)

- Forms are managed as content inside the Ibexa content tree
- Uses Symfony Forms under the hood, including Validation
- Supports horizontal grouping (eg: first name, last name)
- Tag-aware result caching via Symfony Cache (cache invalidated on content publish)
- Form submissions can be stored in a dedicated `form_submission` database table
- Form submissions can trigger an Email notifications (configurable To/CC/BCC/Subject)
- Admin UI for browsing and viewing submissions
- Console commands to install required content types
- Symfony Flex recipe for zero-configuration installation

Installation
------------

[](#installation)

### 1. Install the bundle

[](#1-install-the-bundle)

If your project uses [Symfony Flex](https://symfony.com/doc/current/setup/flex.html) (recommended), add the private recipe endpoint to your project's `composer.json` once:

```
"extra": {
    "symfony": {
        "endpoint": [
            "https://raw.githubusercontent.com/vardumper/IbexaFormBuilderBundle/main/flex/",
            "flex://defaults"
        ]
    }
}
```

Then install:

```
composer require vardumper/ibexa-form-builder-bundle
```

Symfony Flex will automatically:

- Register the bundle in `config/bundles.php`
- Copy the Doctrine ORM mapping config to `config/packages/ibexa_form_builder.yaml`
- Copy the Ibexa admin-ui config to `config/packages/ibexa_form_builder_admin_ui.yaml`
- Copy the route import to `config/routes/ibexa_form_builder.yaml`
- Copy the database migration to `migrations/`

### 2. Run the migration

[](#2-run-the-migration)

The Flex recipe copies a migration to your `migrations/` directory that creates the `form_submission` table. Run it:

```
bin/console doctrine:migrations:migrate
```

### 3. Install the content types

[](#3-install-the-content-types)

```
bin/console ibexa:form-builder:install-content-types
```

---

Manual installation (without Symfony Flex)### Register the bundle in `config/bundles.php`

[](#register-the-bundle-in-configbundlesphp)

```
return [
    // ...
    vardumper\IbexaFormBuilderBundle\IbexaFormBuilderBundle::class => ['all' => true],
];
```

### Register the Doctrine ORM mapping

[](#register-the-doctrine-orm-mapping)

```
# config/packages/ibexa_form_builder.yaml
doctrine:
    orm:
        mappings:
            IbexaFormBuilder:
                is_bundle: false
                type: attribute
                dir: '%kernel.project_dir%/vendor/vardumper/ibexa-form-builder-bundle/src/Entity'
                prefix: 'vardumper\IbexaFormBuilderBundle\Entity'
                alias: IbexaFormBuilder
```

### Register the routes

[](#register-the-routes)

```
# config/routes/ibexa_form_builder.yaml
ibexa_form_builder_routes:
    resource: '@IbexaFormBuilderBundle/config/routes.yaml'
```

### Run the migration

[](#run-the-migration)

Create the `form_submission` table manually or copy the migration from the bundle and run it:

```
CREATE TABLE form_submission (
    id          INT AUTO_INCREMENT NOT NULL,
    content_id  INT NOT NULL,
    submitted_at DATETIME NOT NULL COMMENT '(DC2Type:datetime_immutable)',
    data        JSON NOT NULL,
    ip_address  VARCHAR(45) DEFAULT NULL,
    PRIMARY KEY (id)
) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB;
```

```
bin/console doctrine:migrations:migrate
```

### Install the content types

[](#install-the-content-types)

```
bin/console ibexa:form-builder:install-content-types
```

Configuration
-------------

[](#configuration)

```
# config/packages/ibexa_form_builder.yaml
ibexa_form_builder:
    from_email: 'no-reply@example.com'   # sender address for notification emails
```

Console Commands
----------------

[](#console-commands)

CommandDescription`ibexa:form-builder:install-content-types`Creates or updates the content types required by the bundle (`form`, `input`, `textarea`, `select`, `option`, `fieldset`, `horizontal_group`, `button`, `choice`)`ibexa:form-builder:sync-order`Retroactively syncs the `form_builder_order` field value → location priority so the admin sub-item list reflects the intended field orderRendering a Form
----------------

[](#rendering-a-form)

Use any of the three identifiers to render a form from a controller or template:

```
// by content ID
$this->forward('vardumper\IbexaFormBuilderBundle\Controller\FormController::renderForm', [
    'contentId' => 123,
]);
```

You can render a form by passing its content ID, location ID or Form name:

```
{{ render(controller('vardumper\\IbexaFormBuilderBundle\\Controller\\FormController::renderForm', { contentId: 54 })) }}
{{ render(controller('vardumper\\IbexaFormBuilderBundle\\Controller\\FormController::renderForm', { locationId: 56 })) }}
{{ render(controller('vardumper\\IbexaFormBuilderBundle\\Controller\\FormController::renderForm', { formName: 'Search Form' })) }}
```

Or link directly via the registered route:

```
/form/{identifier}

```

Submission Handling
-------------------

[](#submission-handling)

Set the `submission_action` field on your form content item to one of:

ValueBehaviour`store`Saves the submission to the `form_submission` database table`email`Sends a notification email (requires `notification_email` field to be filled)`both`Stores the submission and sends the emailEmail fields on the form content item:

FieldDescription`notification_email`To address`notification_email_cc`CC address (optional)`notification_email_bcc`BCC address (optional)`email_subject`Email subject line (optional)Extending the Form Theme and Templates
--------------------------------------

[](#extending-the-form-theme-and-templates)

Events
------

[](#events)

The bundle dispatches six events throughout the form submission lifecycle, giving you fine-grained control without needing to override any services. All event names are defined as constants on `FormBuilderEvents`.

ConstantDispatchedCancellable`PRE_VALIDATION`After `handleRequest()`, before `isValid()` is evaluated✔ Cancelling prevents `SubmissionHandler` from running at all`PRE_SUBMIT`After POST data is cleaned, before any storage or email action✔ Cancelling skips both; listeners may also call `setData()` to enrich or sanitize the data`PRE_STORE_SUBMISSION`Before `persist()` + `flush()`✔ Cancelling skips the DB write; the email action still proceeds`POST_STORE_SUBMISSION`After `flush()`; entity carries its auto-generated ID✗`PRE_SEND_EMAIL`After the `Email` object is built, before sending✔ Cancelling suppresses the send; mutate the `Email` object directly to change recipients, subject, or body`POST_SUBMIT`End of `handle()`, regardless of cancellations✗ Always fires; `getSubmission()` returns `null` when the store step was skippedCancellable events expose `cancel()` and `isCancelled()`. Calling `cancel()` does **not** call `stopPropagation()`, so subsequent listeners on the same event still receive it.

### Example: reject submissions that appear to be spam

[](#example-reject-submissions-that-appear-to-be-spam)

```
