DEV Community

Cover image for Component Form Symfony
Roberto Manchado
Roberto Manchado

Posted on

Component Form Symfony

Trabajar con formularios en nuestros proyectos PHP puede ser
extraordinariamente complicado sino tenemos debidamente organizado
nuestro código.

Symfony dispone de uno de los componentes más sofisticados para
la recuperación y envio de datos en el servidor.

El componente The Form Component o el componente para formularios.

Este componente es ideal para tratar, si trabajamos con Symfony , nuestras
entidades ya que permite mapear de un modo directo en nuestra vista
los datos perfectamente sincronizados con los de nuestras entidades.

Para poder utilizarlo tan solo debemos ejecutar el siguiente comando :

composer require symfony/form
Enter fullscreen mode Exit fullscreen mode

Si queremos utilizar en nuestro proyecto symfony, disponemos de las clases Type, que permiten escoger o construir cada una de las partes que compondrá el renderizado del formulario.

Además, podemos interceptar, la request de envio , justo antes del procesamiento en el lado del servidor, gracias a los eventos de formulario.

Aunque, este componente se acopla como un guante a nuestros proyectos de Symfony, también podemos utilizarlos en nuestros proyectos sin un framework por debajo.

Sin embargo, si no tenemos un sistema de plantillas, tipo Smarty o Twig deberemos renderizar nosotros mismos el formulario en lo que a la vista se refiere.

Una primera aproximación, sería pasar como dependencia en el método que pintará el control del formulario, un objeto de la clase FormView.


class UtilsForm
{
    // método que instancia un formulario con nuestro FormType por defecto
    public static function createForm(): FormBuilderInterface
    {
        // creates a Session object from the HttpFoundation component
        $session = new Session();
        $csrfGenerator = new UriSafeTokenGenerator();
        $csrfStorage = new SessionTokenStorage($session);
        $csrfManager = new CsrfTokenManager($csrfGenerator, $csrfStorage);

        $formFactory = Forms::createFormFactoryBuilder()
            ->addExtension(new CsrfExtension($csrfManager))
            ->getFormFactory();

        return $formFactory->createBuilder(FormType::class, null, ['csrf_protection' => true]);
    }

    /**
     *  por cada control de formulario podemos recuperar su tipo y pasárselo 
     *  como argumento a un método que renderize el control
     */
    public static function generateViewForm() : string
    {
        $form = self::createForm();

        $htmlForm = '';
        foreach ($form->getForm()->createView()->getIterator() as $field) {
            $htmlForm .= self::generateInputControl('textarea', $field);
        }

        return $htmlForm;
    }


    /**
     *  genera un control específico según nuestro FormType
     */
    public static function generateInputControl(string $type, FormView $formView) : string
    {
        switch ($type) {
            case 'textarea': return self::generateTextarea($formView);

            default: throw new Exception('this InputControl is not developed yet');
        }
    }


    /**
     *  genera un control de tipo TextArea para este tipo de controles.
     *  Obsérvese que se ha creado una clase TextAreaInput específico
     *  para este tipo de controles
     */
    public static function generateTextarea(FormView $formView) : string
    {
        $htmlFormView = (new TextAreaInput($formView))
            ->generateOutPut()
            ->getHtml();

        return $htmlFormView;
    }
Enter fullscreen mode Exit fullscreen mode

Y nuestra clase para el dibujado de controles bien podria quedar asi:


namespace AppBundle\Inputs;

use Symfony\Component\Form\FormView;

class TextAreaInput
{
    private $id ;

    private $name = '';

    private $cols ;

    private $rows ;

    private $value = '';

    private $required;

    private $disabled;

    private $formView;

    protected $html = '';


    public function __construct(FormView $formView)
    {
        $this->formView = $formView;
    }


    protected function getTemplate()
    {
         return '{ textarea [] }{ /textarea }';
    }


    public function generateOutPut() : self
    {
        $parameters = [
            'id' => $this->formView->vars['id'],
            'name' => $this->formView->vars['full_name'],
            'cols' => 30,
            'rows' => 10,
            'value' => $this->formView->vars['value']
        ];

        if ($this->formView->vars['required']) {
            $parameters['required'] = 'true';
        }

        if ($this->formView->vars['disabled']) {
            $parameters['disabled'] = 'true';
        }

        $stringParameters = '' ;
        foreach ($parameters as $key => $parameter) {
            $stringParameters .= $key . '=' . $parameter .' ' ;
        }

        $this->html = html_entity_decode(str_replace('[]', $stringParameters, $this->getTemplate())) ;

        return $this;
    }
Enter fullscreen mode Exit fullscreen mode

De esta manera podemos aprovechar en nuestros proyectos PHP esta fabulosa herramienta (de las que tiene)
Symfony .

Discussion (0)