2017-09-01 5 views
1

Je commence tout juste avec Doctrine et je réécrivais du code pour utiliser des entités Doctrine dans certains formulaires.Comment bien hydrater et extraire les entités Doctrine de Zend Forms

J'ai une Entity Business qui a des relations 1: n avec des adresses, des employés, des emails, etc. L'installation est vraiment basique et fonctionne très bien.

Pour ajouter de nouvelles entreprises, j'ai créé un BusinessForm et des Fieldsets pour chacune de mes entités. Ici, le constructeur de la forme:

public function __construct($scenario='create', $entityManager = null) { 
    parent::__construct('business_form'); 
    $this->scenario = $scenario; 
    $this->entityManager = $entityManager; 
    $this->setAttribute('method', 'post'); 

    $businessFieldset = new BusinessFieldset($this->entityManager); 
    $businessFieldset->setUseAsBaseFieldset(true); 
    $this->add($businessFieldset); 

    $hydrator = new DoctrineHydrator($this->entityManager, new Business()); 
    $this->setHydrator($hydrator); 
    $this->addElements(); 
    $this->addInputFilter(); 
} 

addElements ajoute simplement une entrée Submit et CSRF.

Et ici l'action du contrôleur:

public function addAction(){ 
    $form = new BusinessForm('create', $this->entityManager); 
    if ($this->getRequest()->isPost()) { 
     $data = $this->params()->fromPost();     
     $form->setData($data); 
     if($form->isValid()) { 
      // save Object 
      return $this->redirect()->toRoute('subcontractor', ['action'=>'index']);     
     }  
    } 
    return new ViewModel([ 
     'form' => $form 
    ]); 
} 

Le formulaire valide et je peux obtenir les données du formulaire avec $form->getData(). Mais je n'arrive pas à comprendre comment obtenir un objet peuplé à partir du formulaire en utilisant l'hydrateur du formulaire. Lorsque j'utilise setObject(new Business()) au début du contrôleur je reçois une erreur en $form->isValid() est en cours d'exécution:

Zend\Hydrator\ArraySerializable::extract expects the provided object to implement getArrayCopy() 

Isnt que le mauvais hydrator appelé?

Si je ne setObject() mais à la place utiliser $form->bind(new Business()) après la validation je reçois un objet vide de $form->getObject(). Si j'obtiens les données et hydrate un nouvel objet avec l'hydrateur du formulaire comme ceci: $form->getHydrator()->hydrate($data['business], new Business()) j'obtiens l'objet peuplé que j'attendais. Donc, ma question est, comment puis-je obtenir le résultat du dernier appel à partir de $form->getObject() après la validation?

[EDIT]

Le problème semble être avec les collections de fieldsets utilisées comme sous-fieldsets dans le businessfieldset. Si je valide le formulaire sans utiliser les collections que je reçois l'objet d'affaires attendu de $form->getData()

Voici un exemple comment j'ajouter la collection (dans le fieldset d'affaires):

$this->add([ 
     'name' => 'emails', 
     'type' => 'Zend\Form\Element\Collection', 
     'attributes' => [ 
      'id' => 'business_emails', 
     ], 
     'options' => [ 
      'label' => 'Emails', 
      'count' => 1, 
      'should_create_template' => true, 
      'template_placeholder' => '__index__', 
      'allow_add' => true, 
      'target_element' => [ 
       'type' => 'LwsSubcontractor\Form\EmailFieldset', 
      ], 
      'target_class' => 'LwsSubcontractor\Entity\Email' 
     ], 
    ]); 

et voici le EmailFieldset:

public function __construct() { 
    parent::__construct('email'); 
    $this->setObject(new Email()); 
    $this->addElements();   
} 

protected function addElements() { 
    $this->add([ 
     'name' => 'email', 
     'type' => 'Zend\Form\Element\Email', 
     'attributes' => [ 
      'placeholder' => 'E-Mail (z.B. [email protected])', 
      'class' => 'form-control', 
      'required' => true, 
      'size' => 50, 
     ], 
     'options' => [ 
      'label' => 'Email', 
     ], 
    ]);   

}

}

Si vous utilisez les collections, le message d'erreur ci-dessus s'affiche. Donc, après avoir ajouté un hydrateur à chaque Fieldset, ça allait.

Bien que j'avais l'impression que le réglage de l'hydrateur pour la forme entraînerait l'héritage de cet hydrateur. Ou était-ce parce que les fieldsets étaient utilisés comme collections et non directement?

Répondre

0

Vous devez ajouter l'hydrateur à tous vos champs, personnellement j'utilise DoctrineModule\Stdlib\Hydrator\DoctrineObject pour les entités de doctrine.

Je voudrais également utiliser la méthode init() pour initialiser vos formulaires et ajouter des éléments puis enregistrer et récupérer votre formulaire et fieldsets à travers le FormElementManager, $serviceLocator->get('FormElementManager')->get(yourFieldsetorForm::class). Le formulaire peut être injecté dans votre contrôleur.

J'espère que cela aide.