Symfony’s Forms
system separates the construction, rendering, and processing of forms. This involves multiple key concepts, including form creation, data provision, validation, data persistence from submitted forms, and form rendering.
Controllers
- Handles all logic for the Form
FormBuilder
- Builds the Form
, and provide data to the Form
FormDataProvider
- Provides data to the Form
Form
- Defines the Form
and its contentForm Theme
- Allows to customise the style of the Form
Form Templates
- Allows to render the Form
with Twig
FormHandler
- Handles the submited Form
, provides data to the FormDataHandler
, and handles FormHandlerResult
FormDataHandler
- Persists the data to Database
Controllers
in the back office receive HTTP requests. When handling requests for creating or editing an entity, they instantiate and utilize several concepts.
In most scenarios, the Controller initially instantiates the FormBuilder. This component constructs the necessary Form, incorporating all Form Types. It also retrieves data from the FormDataProvider, ensuring that the form is populated with the appropriate data.
The FormBuilder
will build the required Form
with all Form Types
, and retrieve data from the FormDataProvider
.
The FormDataProvider is responsible for retrieving data from the Database. This data is used to populate the form when editing an existing entity. Additionally, it provides default values for the form fields, both when creating a new entity and when editing an existing one.
Learn more about CRUD forms and FormDataProviders.
Developers have access to a wide range of field types (see Symfony types) that come from the Symfony framework. Additionally, PrestaShop enhances this selection with its own reusable field types.
A complete reference of PrestaShop form types can be found here.
The FormHandler
is responsible of:
actionBeforeCreate<FormName>FormHandler
, actionBeforeUpdate<FormName>FormHandler
, actionAfterCreate<FormName>FormHandler
and actionAfterUpdate<FormName>FormHandler
hooksFormDataHandler
FormHandlerResult
The FormDataHandler
is tasked with persisting data to the Database. It accomplishes this by dispatching a CQRS command to the command bus, ensuring efficient and effective data handling.
This page focuses on migrated Forms utilizing Symfony and the CQRS pattern.
It’s important to note that data can be persisted in several ways, including: Doctrine entities, using ObjectModel entities, or using CQRS concepts.
To render forms in a clean and user-friendly way, PrestaShop extended Symfony’s Bootstrap 4 Form Theme to create PrestaShop UI Kit Form theme. Learn more on Symfony Form theme for PrestaShop
FormModifier
: This component is used to modify the Form, primarily for module integration.FormModifier
hook_: Connects the FormModifier to the form, enabling modifications.FormDataProviderData
hook: Facilitates the provision of specific data to the form.FormDataProviderDefaultData
hook: Used for supplying default data to the form.FormHandler hook
: Allows the module to handle the form and its data effectively.A FormModifier
(also known as FormBuilderModifier
) allows you to alter the contents of a Form. It is particularly useful within modules, allowing developers to add, modify, or remove elements from the form as required.
It’s been implemented in an example module: DemoProductForm2.
namespace PrestaShop\Module\DemoProductForm\Form\Modifier;
[...]
final class ProductFormModifier
{
public function __construct(
private readonly TranslatorInterface $translator,
private readonly FormBuilderModifier $formBuilderModifier
) {
}
public function modify(
?ProductId $productId,
FormBuilderInterface $productFormBuilder
): void {
[...]
}
services:
PrestaShop\Module\DemoProductForm\Form\Modifier\ProductFormModifier:
autowire: true
public: true
arguments:
$formBuilderModifier: '@form.form_builder_modifier'
A FormModifier
by itself will not affect a Form
unless it is properly hooked. To ensure functionality, the FormModifier
must be linked by implementing the action.
In the module, register the hook and implement the method, for example, for the Product
entity:
public function install()
{
$this->registerHook('actionProductFormBuilderModifier');
}
public function hookActionProductFormBuilderModifier(array $params): void
{
/** @var ProductFormModifier $productFormModifier */
$productFormModifier = $this->get(ProductFormModifier::class);
$productId = isset($params['id']) ? new ProductId((int) $params['id']) : null;
$productFormModifier->modify($productId, $params['form_builder']);
}
The Action<FormName>FormDataProviderDefaultData
hook allows your module to provide or modify the default values sent to forms.
public function install()
{
$this->registerHook('actionProductFormDataProviderDefaultData');
}
public function hookActionProductFormDataProviderDefaultData(array $params): void
{
// define default values for fields in $params["data"]
}
This hook has been implemented as an example in our example-modules repository.
The Action<FormName>FormDataProviderData
hook allows your module to provide or modify the values sent to forms.
public function install()
{
$this->registerHook('actionProductFormDataProviderData');
}
public function hookActionProductFormDataProviderData(array $params): void
{
// change value of fields in $params["data"]
}
This hook has been implemented as an example in our example-modules repository - demoformdataproviders.
The FormHandler
hook is designed to intercept Form
data, enabling the execution of various operations with this data. Its primary function is to facilitate the persistence of form data, ensuring that the data captured by the form can be effectively processed and stored later.
There are 4 hooks available to work with the Form
data:
Hook | Description |
---|---|
actionBeforeCreate<FormName>FormHandler |
Triggered on creation of an IdentifiableObject, before persisting it to Database |
actionBeforeUpdate<FormName>FormHandler |
Triggered on update of an IdentifiableObject, before persisting it to Database |
actionAfterCreate<FormName>FormHandler |
Triggered on creation of an IdentifiableObject, after persisting it to Database |
actionAfterUpdate<FormName>FormHandler |
Triggered on update of an IdentifiableObject, after persisting it to Database |
It as been implemented in an example module: DemoProductForm.
public function hookActionAfterUpdateCombinationFormFormHandler(array $params): void
{
$combinationId = $params['form_data']['id'];
[...]
}
You can find some examples of how to use forms in your modules to extend PrestaShop capabilities:
Subject | Link |
---|---|
Extend a Symfony form in a module with an upload field for image | Tutorial |
How to extend the new product page form | Tutorial |
How to modify Customers grid | Tutorial |