---
title: Formularios Symfony en modulos PrestaShop 8/9
section: trucos
slug: symfony-form
description: Como crear formularios de configuracion modernos en PrestaShop 8/9 usando Symfony Form, DataConfiguration, DataProvider y FormHandler con servicios DI.
keywords: prestashop symfony form formulario configuracion modulo DataConfiguration DataProvider FormHandler services.yml
last_updated: 2024-12-01
source_url: "https://ayudaprestashop.es/trucos/symfony-form"
---

# Formularios Symfony en modulos PrestaShop 8/9

> Como crear formularios de configuracion modernos en PrestaShop 8/9 usando Symfony Form, DataConfiguration, DataProvider y FormHandler con servicios DI.

PrestaShop 8+ utiliza el componente Symfony Form para las paginas de configuracion del Back Office. El patron recomendado usa tres clases: el **Form Type** (estructura de campos), el **DataConfiguration** (mapeo a la tabla Configuration) y el **FormHandler** (orquesta carga, guardado y hooks).

## El patron triple: Type + DataConfiguration + DataProvider

| Clase | Responsabilidad | Ubicacion |
| --- | --- | --- |
| MyCustomType | Define los campos del formulario | src/Form/MyCustomType.php |
| MyDataConfiguration | Mapea campos a claves de Configuration | src/Form/MyDataConfiguration.php |
| ConfigurableFormDataProvider | Carga y guarda datos del form | Clase del core — instanciar en services.yml |
| FormHandler | Orquesta form factory, hooks y data provider | Clase del core — instanciar en services.yml |

## Form Type

*src/Form/MyCustomType.php*

```php
<?php

declare(strict_types=1);

namespace MyModule\Form;

use PrestaShopBundle\Form\Admin\Type\TranslatorAwareType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\FormBuilderInterface;

final class MyCustomType extends TranslatorAwareType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add('my_setting', TextType::class, [
                'label'    => $this->trans('Nombre del ajuste', 'Modules.Mymodule.Admin'),
                'required' => false,
            ])
            ->add('my_flag', CheckboxType::class, [
                'label'    => $this->trans('Activar funcionalidad', 'Modules.Mymodule.Admin'),
                'required' => false,
            ]);
    }
}
```

## Data Configuration

*src/Form/MyDataConfiguration.php — mapeo a ps_configuration*

```php
<?php

declare(strict_types=1);

namespace MyModule\Form;

use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface;
use PrestaShop\PrestaShop\Adapter\Configuration;

final class MyDataConfiguration implements DataConfigurationInterface
{
    private Configuration $configuration;

    public function __construct(Configuration $configuration)
    {
        $this->configuration = $configuration;
    }

    /**
     * Devuelve los valores actuales para pre-rellenar el formulario.
     */
    public function getConfiguration(): array
    {
        return [
            'my_setting' => $this->configuration->get('MY_MODULE_SETTING', ''),
            'my_flag'    => (bool) $this->configuration->get('MY_MODULE_FLAG', false),
        ];
    }

    /**
     * Guarda los valores enviados por el formulario.
     * Devuelve array de errores (vacio = exito).
     */
    public function updateConfiguration(array $config): array
    {
        $this->configuration->set('MY_MODULE_SETTING', $config['my_setting']);
        $this->configuration->set('MY_MODULE_FLAG', (int) $config['my_flag']);

        return []; // sin errores
    }

    /**
     * Validacion previa (opcional — dejar en true si usas Form Validation).
     */
    public function validateConfiguration(array $configuration): bool
    {
        return true;
    }
}
```

## Registro en services.yml

*config/services.yml — declaracion de todos los servicios del formulario*

```yaml
services:
  _defaults:
    autowire: true
    autoconfigure: true
    public: true

  # 1. Form Type
  my_module.form.type:
    class: MyModule\Form\MyCustomType
    parent: 'form.type.translatable.aware'
    tags:
      - { name: form.type }

  # 2. Data Configuration (mapea campos <-> Configuration)
  my_module.form.data_configuration:
    class: MyModule\Form\MyDataConfiguration
    arguments: ['@prestashop.adapter.legacy.configuration']

  # 3. Data Provider (usa la clase del core)
  my_module.form.data_provider:
    class: PrestaShop\PrestaShop\Core\Form\ConfigurableFormDataProvider
    arguments:
      - '@my_module.form.data_configuration'
      - '@prestashop.core.localization.locale.context'

  # 4. Form Handler (orquesta todo)
  my_module.form.handler:
    class: PrestaShop\PrestaShop\Core\Form\FormHandler
    arguments:
      - '@form.factory'
      - '@prestashop.core.hook.dispatcher'
      - '@my_module.form.data_provider'
      - 'MyModule\Form\MyCustomType'
      - 'MyModuleForm'   # sufijo para los hooks: actionMyModuleFormSave, etc.
```

## Renderizar en el Controller

*src/Controller/Admin/ConfigurationController.php*

```php
<?php

declare(strict_types=1);

namespace MyModule\Controller\Admin;

use PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class ConfigurationController extends FrameworkBundleAdminController
{
    public function indexAction(Request $request): Response
    {
        $formHandler = $this->get('my_module.form.handler');
        $form = $formHandler->getForm();
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $errors = $formHandler->save($form->getData());

            if (empty($errors)) {
                $this->addFlash(
                    'success',
                    $this->trans('Configuracion guardada correctamente.', 'Admin.Notifications.Success')
                );
            } else {
                foreach ($errors as $error) {
                    $this->addFlash('error', $error);
                }
            }
        }

        return $this->render(
            '@Modules/my_module/views/templates/admin/configure.html.twig',
            ['form' => $form->createView()]
        );
    }
}
```

## Tipos especiales de PrestaShop

*Tipos de campo disponibles en PrestaShopBundle*

```php
<?php

// Switch on/off (toggle)
use PrestaShopBundle\Form\Admin\Type\SwitchType;

// Campo de texto multilingual
use PrestaShopBundle\Form\Admin\Type\TranslatableType;

// Selector de categorias
use PrestaShopBundle\Form\Admin\Type\CategoryChoiceTreeType;

// Selector de impuestos
use PrestaShopBundle\Form\Admin\Type\TaxChoiceType;

// Selector de moneda
use PrestaShopBundle\Form\Admin\Type\CurrencyChoiceType;

// Textarea con TinyMCE (editor rico)
use PrestaShopBundle\Form\Admin\Type\FormattedTextareaType;

// Ejemplo con SwitchType
$builder->add('active', SwitchType::class, [
    'label'    => $this->trans('Activo', 'Admin.Global'),
    'required' => false,
]);

// Ejemplo con TranslatableType (campo multilingual)
$builder->add('description', TranslatableType::class, [
    'label'   => $this->trans('Descripcion', 'Admin.Global'),
    'type'    => FormattedTextareaType::class,
    'options' => ['required' => false],
]);
```

> **[TIP] CSRF incluido automaticamente**
>
> Al usar FormHandler del core, la proteccion CSRF de Symfony se aplica automaticamente. No es necesario añadir nada extra.


---

*Fuente: [https://ayudaprestashop.es/trucos/symfony-form](https://ayudaprestashop.es/trucos/symfony-form). Version Markdown generada automaticamente para consumo por LLMs.*
