Form Vinculado a uma Entidade

Form Vinculado a uma Entidade
Para um sistema que faz uso do paradigma de orientação a objetos, o uso de entidades é fundamental. Um formulário mais simples possível reune em si os papéis de adicionar campos (add(field)), adicionar quais campos serão validados (ValidationGroup) e como serão validados (InputFilter). Mas e como ficaria a entidade nesse contexto?
Se quiséssemos usar uma entidade nesse contexto teríamos que pegar os dados do formulário e passá-los a ela manualmente, e perderíamos a produtividade. Além disso, é interessante que o tipo da validação de cada campo esteja na entidade, já que cada campo representaria um atributo, e cada atributo tem suas restrições de valor. Podemos melhorar essa situação.
Para prosseguirmos com detalhes da vinculação entre um formulário e uma entidade, devemos ter antes em mente um formulário de exemplo. Abaixo segue o exemplo de formulário simples, sem fieldsets e vínculo com entidades.  
namespace Application\Form;
use Zend\Form;
class MyForm extends Form {
     function __contruct() {
         $this->setAttribute(‘method’, ‘post’);
         $this->setAttribute(‘id’, ‘my-form’);
         $this->add(
          array(
              ‘name’ => ‘sex’,
              ‘type’ => ‘Zend\Form\Element\Select’,
              ‘options’ => array(
                  ‘label’ => ‘Sex:’,
                  “value_options” => array(
                                                “” => “- Choose your sex -“,
                                                “0” => “Male”,
                                                “1” => “Female”,
                                           ),
              ),
              ‘attributes’ => array(
                  ‘style’ => ‘width: 350px’
              )
          )
      );
      $this->add(
          array(
              ‘name’ => ‘name’,
              ‘options’ => array(
                  ‘label’ => ‘Name:’
              ),
              ‘attributes’ => array(
                  ‘class’ => ‘biggest’,
              )
          )
      );
      $this->add(
          array(
              ‘name’ => ‘btnsubmit’,
              ‘options’ => array(
                  ‘label’ => ‘Submit’
              ),
              ‘attributes’ => array(
                  ‘class’ => ‘btn’,
                  ‘type’ => ‘submit’
              )
          )
      );
      $this->add(
          array(
              ‘name’ => ‘btnsubmit’,
              ‘options’ => array(
                  ‘label’ => ‘Submit’
              ),
              ‘attributes’ => array(
                  ‘class’ => ‘btn’,
                  ‘type’ => ‘submit’
              )
          )
      );
         $this->setInputFilter(
             new Factory()->createInputFilter(
                 array(
                      ‘sex’ => array (
                           ‘required’ => true
                      ),
                      ‘name’ => array (
                           ‘allow_empty’ => false
                      ),
                 )
             )
         );
         $this->setValidationGroup(
             array(
                 ‘security’,
                 ‘sex’,
                 ‘name’,
             )
         );
    }
}
Entidade
Antes tinhamos o InputFilter sendo criado dentro na classe do formulário, mas agora quem passa a possuir esse papel. Então, a mudança principal será com a nossa classe entidade que será criada e que passa a implementar a interface Zend\InputFilter\InputFilterAwareInterface e possuir um atributo que referenciará ao InputFilter, diferente do formulário que herda de Form, pois a classe pai já implementa e utiliza esse detalhes.
Como a entidade representa uma tabela do banco de dados, então é interessante que as restrições de cada coluna estejam representadas nela. Sendo assim, a nossa entidade de exemplo fica dessa maneira.
namespace Application\Entity;
use Zend\InputFilter\InputFilterAwareInterface;
public class MyEntity implements InputFilterAwareInterface{
     private $name;
     private $sex;
     private $inputFilter;
     //Getters and Setters..
  /**
   * Retrieve input filter
   *
   * @return InputFilterInterface
   */
  public function getInputFilter()
  {
      $myValidator = new Validator\MyValidator();
      if (null === $this->inputFilter) {
          $this->inputFilter = new Factory()->createInputFilter(
              array(
                     ‘sex’ => array (
                          ‘required’ => true,
                          ‘validators’ => array(
                               $myValidator
                          )
                     ),
                     ‘name’ => array (
                          ‘allow_empty’ => false,
                          ‘validators’ => array(
                               array(‘name’  =>  ‘Application\Validator\Form\MyValidator’)
                          )
                     ),
                )
          );
      }
      return $this->inputFilter;
  }
}
Vínculo com a Entidade
Com essas mudanças, o nosso form deixa de possuir o InputFilter e cria um vínculo com a entidade. O exemplo de como vincular uma entidade à um form segue abaixo.
namespace Application\Form;
use Zend\Form;
class MyForm extends Form {
     function __contruct() {
         $this->setAttribute(‘method’, ‘post’);
         $this->setAttribute(‘id’, ‘my-form’);
         $this->setObject(new Entity\MyEntity());
         //…Add Fields
         $this->setValidationGroup(
             array(
                 ‘security’,
                 ‘sex’,
                 ‘name’,
             )
         );
    }
}
O vínculo então é gerado à partir do método setObject() que espera como parâmetro a nossa Entity contendo o InputFilter.
isValid()
Mas então o método isValid() irá usar o ValidationGroup() do Form para ver quais campos serão validados e pegar o InputFilter da Entidade para dizer como esses campos serão validados? Exato.Quando for feito um isValid() na instância do nosso formulário, o InputFilter será primeiramente procurado dentro da entidade relacionada, se não houver entidade ou se houver mas não há uma instância de InputFilter nela, será procurado no próprio Form, e se mesmo assim não houver, será instânciado e usado um novo InputFilter.
Bind()
class ExampleController extends AbstractActionController
{
public function indexAction() {
   $form = new Form\MyForm
   $request = $this->getRequest();
   if ($request->isPost()) {
          $form->setData($request->getPost());
          if ($form->isValid()) {
                 //Entidade populada com os campos do formulário.
          }
   }
   return array(‘form’ => $form);
}
}
Outro detalhe é que quando nossa entidade possui valores em seus atributos, esse valores são adotados nos respectivos campos do formulário quando fazemos bind. Suponha que uma instância da nossa entidade receba no atributo $name o valor “Tássio” e no atributo $surname o valor “Auad”. Agora imagine que vamos vincular essa entidade ao formulário, e a consequência disso é o form tendo o campo com nome “name” preenchido pelo valor “Tássio” e o campo com nome “surname” preenchido com o valor “Auad”.

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s