2015-12-16 23 views
13

Attualmente sono presenti tabelle di articoli e tag. Sto cercando di popolare automaticamente l'elemento del modulo "Tag" come una casella di selezione nel modulo dell'articolo. Qual è il modo migliore per impostare le opzioni di valore dei tag per selezionare una casella da una tabella di database e poi fare in modo che l'articolo leghi automaticamente i dati del tag durante la chiamata al metodo "bind"?Compilazione dei dati delle relazioni in Zend Framework 2 Form tramite Annotation Builder

Article.php

<?php 
// Article class 
class Article { 
    /** 
    * 
    * @var \Doctrine\Common\Collections\Collection|Tag[] 
    * 
    * @ORM\ManyToMany(targetEntity="Tag", inversedBy="articles") 
    * @Orm\JoinTable(name="rel_article_tag", joinColumns={@ORM\JoinColumn(name="article_id", referencedColumnName="article_id")}, inverseJoinColumns={@ORM\JoinColumn(name="tag_id", referencedColumnName="tag_id")}) 
    * 
    * @Form\Required(false) 
    * @Form\Type("Zend\Form\Element\Select") 
    * @Form\Options({"label":"Tags: ") 
    * @Form\Attributes({"id":"tags", "data-placeholder":"Choose tags...", "multiple" : "multiple", "class" : "chosen-select"}) 
    */ 
    private $tags; 

    public function __construct() 
    { 
     $this->tags = new ArrayCollection(); 
    } 

    public function getTags() 
    { 
     return $this->tags; 
    } 

    public function addTags($tags) 
    { 
     $this->tags = $tags; 
    } 

    public function removeTags() 
    { 
     $this->tags = new ArrayCollection(); 
    } 
} 

ArticleController.php

class ArticleController{ 
    public function editAction() 
    { 
     $builder = new AnnotationBuilder(); 
     $form = $builder->createForm(new TblArticle()); 

     $id = 1; 
     $article = $em->find('Admin\Entity\TblArticle', $id); 
     $form->bind($article); 
    } 
} 

quello che ho fatto

All'interno ArticleController::editAction(), ho dinamicamente le opzioni di valore aggiunto ai tag elemento sul modulo.

class ArticleController 
{ 
    public function editAction() 
    { 
     $builder = new AnnotationBuilder(); 
     $form = $builder->createForm(new TblArticle()); 

     // add tag options to form 
     $sm = $this->getServiceLocator(); 
     $em = $sm->get('Doctrine\ORM\EntityManager'); 
     $tags = $em->getRepository('Admin\Entity\LuTag')->findAll(); 
     $tagOptions = [null => '']; 
     foreach ($tags as $tag) { 
      $tagOptions[$tag->getTagId()] = $tag->getName(); 
     } 
     $form->get('tags')->setValueOptions($tagOptions); 
     // end add tag options to form 


     $id = 1; 
     $article = $em->find('Admin\Entity\TblArticle', $id); 
     $form->bind($article); 

     if ($article->getTags()) { 
      $tagIds = array(); 
      foreach ($article->getTags() as $tag) { 
       $tagIds[] = $tag->getTagId(); 
      } 
      $form->get('tags')->setValue($tagIds); 
     } 
    } 
} 

Questo mi sembra una quantità eccessiva di codice nel mio controllo, io so che non è giusto, ma non sono sicuro di come fare meglio questo. Forse usando un FormBuilder che imposta le opzioni di valore per gli elementi Tag?

Grazie.

+0

Non credo sia possibile. –

risposta

2

Dai un'occhiata a questo tutorial: https://samsonasik.wordpress.com/2014/05/22/zend-framework-2-using-doctrinemoduleformelementobjectselect-and-custom-repository/

Fondamentalmente è necessario specificare una classe repository nel tag-Entities entità di annotazione in questo modo:

@ORM\Entity(repositoryClass="Admin\Entity\LuTag") 

Quindi è possibile utilizzare Dottrine DoctrineModule \ forma \ elemento \ Tipo ObjectSelect che sarà in grado di fornire la funzionalità richiesta:

Articolo.php (Annotare @Form \ Type Annotation e l'ulteriore @Form \ Options voci)

... 
/** 
* 
* @var \Doctrine\Common\Collections\Collection|Tag[] 
* 
* @ORM\ManyToMany(targetEntity="Tag", inversedBy="articles") 
* @Orm\JoinTable(name="rel_article_tag", joinColumns={@ORM\JoinColumn(name="article_id", referencedColumnName="article_id")}, inverseJoinColumns={@ORM\JoinColumn(name="tag_id", referencedColumnName="tag_id")}) 
* 
* @Form\Required(false) 
* @Form\Type("DoctrineModule\Form\Element\ObjectSelect")* 
* @Form\Options({"label":"Tags: ", "target_class": "Admin\Entity\LuTag", "property": "name"}) 
* @Form\Attributes({"id":"tags", "data-placeholder":"Choose tags...", "multiple" : "multiple", "class" : "chosen-select"}) 
*/ 
private $tags; 

Anche consultare il https://github.com/doctrine/DoctrineModule/blob/master/docs/form-element.md per ulteriori informazioni su ObjectSelect

Finalmente è necessario per costruire il tuo modulo utilizzando

DoctrineORMModule\Form\Annotation\AnnotationBuilder 

invece di Zends AnnotationBuilder al fine di risolvere l'object_manager dipendenze.

/* using the service manager like this within a controller method is 
bad practice. Inject the EntityManager using a Controller Factory! */ 
$sm = $this->getServiceLocator(); 
$em = $sm->get('Doctrine\ORM\EntityManager'); 

$builder = new DoctrineORMModule\Form\Annotation\AnnotationBuilder($em); 
$form = $builder->createForm(TblArticle::class); 

Questo dovrebbe fare il trucco.

+0

Grazie mille! Questo ha funzionato come un fascino. –