Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create ZF 2 Forms from Doctrine Entities

What I want to know is the best way to create a form which matches an entity.

  • Manually Create the form either in code or using the form annotations?
  • Using Annotations from the entity?

I've see a few different examples, some using @Annotation and others using @Form? Could somebody please explain the difference?

In the case of entities having related/nested entities do I need to provide a custom hydrator for every entity? I'm presuming Doctrine may already have one that implements the hydrator interfaces?

To Summarise: - Best way to create a form from an Entity. - Difference between @Form and @Annotation - Does Doctrine have a Hydrator for it's Entities?

like image 813
Ben Avatar asked Nov 20 '12 14:11

Ben


1 Answers

First off: Annotations are a Speed-Killer. If you want to use the annotation builder, please ALWAYS Cache the created objects. But annotations are also the easiest way to get a form running ;)

Second: The Hydrator. When using ZF2 Forms in conjunction with Doctrine 2 you most likely want to use the DoctrineEntity Hydrator located inside. Consider the following code:

$form = new ReferenzwertForm();
$form->setHydrator(new DoctrineEntity($serviceLocator->get('Doctrine\ORM\EntityManager')))
     ->setObject(new Referenzwert())
     ->setInputFilter(new ReferenzwertFilter())
     ->setAttribute('method', 'post');
return $form;
  • ReferenzwertForm() is of type Zend\Form\Form Object
  • DoctrineEntity() is of type DoctrineORMModule\Stdlib\Hydrator\DoctrineEntity
    • DoctrineEntity needs the EntityManager provided. You should be familiar with this when using Doctrine 2 in ZF2
  • Referenzwert() is a Entity-Object

When not using annotations and you're referencing another Entity, then make sure you use the appropriate form element (in most cases this would be a select-element (like selecting a CategoryEntity for a BlogEntity or something)

$this->add(array(
    'name' => 'type',
    'type' => 'DoctrineORMModule\Form\Element\DoctrineEntity',
    'options' => array(
          'label' => 'Choose a MyEntity',
          'object_manager' => $this->getEntityManager(),
          'target_class' => 'Namespace\Entity\MyEntity',
          'property' => 'name'
    ),
    'attributes' => array(
        'required' => true
    )
));

As you can see, the Form element needs to know about the entityManager, too. This is why ideally you'd want to extend the first Code-Example with another setter to inject the entityManager into your form object.

$form->setEntityManager($serviceLocator->get('Doctrine\ORM\EntityManager'))
     ->set()//all the other stuff

What's the best approach in general? I'd say there is none. For speed purposes, annotations solely are a killer. Using cached versions should help out, though i have no personal experience with caching in ZF2 just yet. I like to create my forms from hand outside of annotations, simply because my IDE supports a lot of stuff, but certainly not form annotations :D

Hope this could help you a bit and i didn't write too much out of context :P

like image 169
Sam Avatar answered Oct 31 '22 12:10

Sam