2012-10-04 8 views
9

Ich habe 2 Entitäten - Benutzer und Gruppe. Sie haben eine Viele-zu-Viele-Beziehung, und Gruppen werden verwendet, um die Rollen eines Benutzers zu speichern.Symfony 2 Embedded Form Collection Viele zu vielen

Ich versuche, einen Benutzer bearbeiten Form zu machen, indem eine Sammlung hinzufügen, möchte ich in der Lage sein, eine neue Rolle hinzufügen, indem sie aus einem Drop-Down (begrenzt auf, was bereits in der DB) Auswahl

Usertype. php:

class UserType extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
      ->add('username') 
      ->add('email') 
      ->add('forename') 
      ->add('surname') 
      ->add('isActive') 
      ->add('joinDate', 'date', array('input' => 'datetime', 'format' => 'dd-MM-yyyy')) 
      ->add('lastActive', 'date', array('input' => 'datetime', 'format' => 'dd-MM-yyyy')) 
      ->add('groups', 'collection', array(
        'type' => new GroupType(), 
        'allow_add' => true, 
        )) 
     ; 
    } 

    public function setDefaultOptions(OptionsResolverInterface $resolver) 
    { 
     $resolver->setDefaults(array(
      'data_class' => 'Sfox\CoreBundle\Entity\User' 
     )); 
    } 
} 

und GroupType.php:

class GroupType extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
      ->add('name') 
      ->add('role'); 
    } 

    public function setDefaultOptions(OptionsResolverInterface $resolver) 
    { 
     $resolver->setDefaults(array(
       "data_class" => 'Sfox\CoreBundle\Entity\Group' 
       )); 
    } 
} 

Dies zeigt die Rollen in der Form, in grundlegenden Textfelder, aber wenn ich einen Eintrag in das Formular hinzufügen, wird es kaskadieren ein neues ent persistieren Wenn ich einen Eintrag bearbeiten würde, würden sich die zugrunde liegenden Gruppendaten ändern.

Ich versuchte, ein GroupSelectType.php machen:

class GroupSelectType extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
      ->add('role', 'entity', array('class'=>'SfoxCoreBundle:Group', 'property'=>'name')); 
    } 

    public function setDefaultOptions(OptionsResolverInterface $resolver) 
    { 
     $resolver->setDefaults(array(
       "data_class" => 'Sfox\CoreBundle\Entity\Group' 
       )); 
    } 
} 

das Feld als „Einheit“ Typ Hinzufügen dieses zeigt das richtige Auswahlfeld (aber mit den Standardwerten) Ich kann es nicht an die zu binden scheinen UserType-Formular!

Alles, was ich möchte das Formular zu tun ist die zugrunde liegende "Gruppen" ArrayCollection in der Entität Benutzer ändern.

Weiß jemand, wie ich das erreichen kann?

Antwort

14

Nun habe ich eine Lösung für alle aus anderen mit ähnlichen Problemen zu kämpfen ...

ich einen benutzerdefinierten Formulartyp zu schaffen hatte und es als Dienst zu erklären, damit ich in den Entity-Managern übergeben. Ich brauchte dann eine dataTransformer machen zu meiner Gruppe

Benutzerdefinierte GroupSelectType Objekte in eine ganze Zahl ändern für Form:

class GroupSelectType extends AbstractType 

{ 
    /** 
    * @var ObjectManager 
    */ 
    private $om; 

    private $choices; 

    /** 
    * @param ObjectManager $om 
    */ 
    public function __construct(ObjectManager $om) 
    { 
     $this->om = $om; 

     // Build our choices array from the database 
     $groups = $om->getRepository('SfoxCoreBundle:Group')->findAll(); 
     foreach ($groups as $group) 
     { 
      // choices[key] = label 
      $this->choices[$group->getId()] = $group->getName() . " [". $group->getRole() ."]"; 
     } 
    } 

    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $transformer = new GroupToNumberTransformer($this->om); 
     $builder->addModelTransformer($transformer); 
    } 

    public function setDefaultOptions(OptionsResolverInterface $resolver) 
    { 
     $resolver->setDefaults(array(
       "choices" => $this->choices, 
       )); 
    } 

    public function getParent() 
    { 
     return 'choice'; 
    } 

    public function getName() 
    { 
     return 'group_select'; 
    } 
} 

Im Konstruktor ich alle verfügbaren Gruppen bekommen und sie in eine „Auswahl“ setzen Array, das als Option an das Auswahlfeld übergeben wird.

Sie werden auch feststellen, dass ich einen benutzerdefinierten Datentransformator verwende, um die groupId (die beim Rendern des Formulars verwendet wird) zu einer Gruppenentität zu ändern. Ich machte den GroupSelectType einen Dienst als auch und in der [@ doctrine.orm.entity_manager] bestanden

services.yml (Bündel config):

services: 
    sfox_core.type.group_select: 
     class: Sfox\CoreBundle\Form\Type\GroupSelectType 
     arguments: [@doctrine.orm.entity_manager] 
     tags: 
      - { name: form.type, alias: group_select } 

GroupToNumberTranformer.php

class GroupToNumberTransformer implements DataTransformerInterface 
{ 
    /** 
    * @var ObjectManager 
    */ 
    private $om; 

    /** 
    * @param ObjectManager $om 
    */ 
    public function __construct(ObjectManager $om) 
    { 
     $this->om = $om; 
    } 

    /** 
    * Transforms an object (group) to a string (number). 
    * 
    * @param Group|null $group 
    * @return string 
    */ 
    public function transform($group) 
    { 
     if (null === $group) { 
      return ""; 
     } 

     return $group->getId(); 
    } 

    /** 
    * Transforms a string (number) to an object (group). 
    * 
    * @param string $number 
    * @return Group|null 
    * @throws TransformationFailedException if object (group) is not found. 
    */ 
    public function reverseTransform($number) 
    { 
     if (!$number) { 
      return null; 
     } 

     $group = $this->om 
     ->getRepository('SfoxCoreBundle:Group') 
     ->findOneBy(array('id' => $number)) 
     ; 

     if (null === $group) { 
      throw new TransformationFailedException(sprintf(
        'Group with ID "%s" does not exist!', 
        $number 
      )); 
     } 

     return $group; 
    } 
} 

Und meine geänderte UserType.php - Notiz Ich verwende mein benutzerdefiniertes Formulartyp "group_select" jetzt, da es als Dienst ausgeführt wird:

class UserType extends AbstractType 
{ 
    private $entityManager; 

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

    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $transformer = new GroupToNumberTransformer($this->entityManager); 

     $builder 
      ->add('username') 
      ->add('email') 
      ->add('forename') 
      ->add('surname') 
      ->add('isActive') 
      ->add('joinDate', 'date', array('input' => 'datetime', 'format' => 'dd-MM-yyyy')) 
      ->add('lastActive', 'date', array('input' => 'datetime', 'format' => 'dd-MM-yyyy')); 
     $builder 
      ->add(
       $builder->create('groups', 'collection', array(
        'type' => 'group_select', 
        'allow_add' => true, 
        'options' => array(
          'multiple' => false, 
          'expanded' => false, 
          ) 
        )) 
     ); 
    } 

    public function setDefaultOptions(OptionsResolverInterface $resolver) 
    { 
     $resolver->setDefaults(array(
      'data_class' => 'Sfox\CoreBundle\Entity\User' 
     )); 
    } 

    public function getName() 
    { 
     return 'sfox_corebundle_usertype'; 
    } 
} 
+0

Diese Antwort hat mir sehr geholfen! Vielen Dank! – jcbwlkr

+0

Perfekter Dank! –

+0

Sehr hilfreich. Vielen Dank – Rinat