2017-02-20 22 views
3

У меня есть два класса User.php и Group.php, расширенные от классов, определенных в fosuserbundle.Значение по умолчанию для EntityType Поле

Кроме того, у меня есть отношение ManyToMany между ними.

Идея приложения заключается в том, что когда я добавляю нового пользователя, я назначаю одну или несколько групп пользователю (я использую вариант выбора multi-дизайна материала). Проблема возникает, когда у пользователя нет назначенных групп (например, когда опция группы пуста). Я получаю эту ошибку javascript в консоли:

Недопустимое управление формой с именем = 'user [groups] []' не является сфокусированным.

Чтобы решить эту проблему, мне нужно указать значение по умолчанию для поля группы. Как установить группу пользователей по умолчанию, если группа не выбрана? Мои классы определяются следующим образом.

UserType.php

public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
      ->add(
       'username', 
       null, 
       array(
       'attr' => array(
        'placeholder' => 'username' 
       ), 
      )) 
      ->add(
       'email', 
       null, 
       array(
       'attr' => array(
        'placeholder' => 'email' 
       ), 
      )) 
      /*->add('groups', EntityType::class, array(
       'class' => 'AppBundle\Entity\Group', 
       'choice_label' => 'name', 
       'expanded' => false, 
       'multiple' => false 
      )) */ 
      ->add('groups', EntityType::class, array(
       'class' => 'AppBundle\Entity\Group', 
       'choice_label' => 'name', 
       'attr'=>array(
        'class' => 'mdb-select' 
       ), 
       'multiple' => true, 
      )) 
      ->add('plainPassword', RepeatedType::class, array(
       'invalid_message' => 'Les mots de passe doivent être identiques.', 
       'first_options' => array('label' => 'Mot de passe'), 
       'second_options' => array('label' => 'Répétez le mot de passe'), 
      )) 
      //<input id="input-id" type="file" class="file" multiple data-show-upload="false" data-show-caption="true"> 
      ->add('enabled', null, array(
       'required' => false, 
      )) 
      ->add('imageFile',VichFileType::class, [ 
       'required' => false, 
       'download_link' => true, 
       'attr'=>array(
       'type' => 'file', 
       'onchange' => 'loadFile(event)'), // not mandatory, default is true 
      ]) 
     ; 
    } 

GroupEntity.php

public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
      ->add('name') 
      ->add('roles', CollectionType::class, array(
       'entry_type' => ChoiceType::class, 
       'entry_options' => array(
        'attr' => array(
         'class'=>'mdb-select colorful-select dropdown-default' 
        ), 
        'choices' => array(
         'Admin' => 'ROLE_ADMIN', 
         'USER'  => 'ROLE_USER', 
        ), 
       ) 
      )) 
     ; 
    } 

User.php

<?php 


    namespace AppBundle\Entity; 

    use FOS\UserBundle\Model\User as BaseUser; 
    use Doctrine\ORM\Mapping as ORM; 
    use Doctrine\Common\Collections\ArrayCollection; 
    use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; 
    use Symfony\Component\HttpFoundation\File\File; 
    use Vich\UploaderBundle\Mapping\Annotation as Vich; 

    /** 
    * @Vich\Uploadable 
    * @ORM\Entity 
    * @ORM\Table(name="fos_user") 
    * @UniqueEntity(fields="usernameCanonical", errorPath="username", message="fos_user.username.already_used", groups={"Default", "Registration", "Profile"}) 
    * @UniqueEntity(fields="emailCanonical", errorPath="email", message="fos_user.email.already_used", groups={"Default", "Registration", "Profile"}) 
    */ 
    class User extends BaseUser { 

     /** 
     * @ORM\Id 
     * @ORM\Column(type="integer") 
     * @ORM\GeneratedValue(strategy="AUTO") 
     * 
     */ 
     protected $id; 

     /** 
     * 
     * @ORM\ManyToMany(targetEntity="AppBundle\Entity\Group", inversedBy="users", cascade={"remove"}) 
     * @ORM\JoinTable(name="fos_user_user_group", 
     *  joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")}, 
     *  inverseJoinColumns={@ORM\JoinColumn(name="group_id", referencedColumnName="id")} 
     *) 
     */ 
     protected $groups; 

     /** 
     * @ORM\Column(type="integer", length=6, options={"default":0}) 
     */ 
     protected $loginCount = 0; 

     /** 
     * @var \DateTime 
     * 
     * @ORM\Column(type="datetime", nullable=true) 
     */ 
     protected $firstLogin; 
     /** 
     * NOTE: This is not a mapped field of entity metadata, just a simple property. 
     * 
     * @Vich\UploadableField(mapping="user_image", fileNameProperty="imageName") 
     * 
     * @var File 
     */ 
     private $imageFile; 

     /** 
     * @ORM\Column(type="string", length=255,nullable=true) 
     * 
     * @var string 
     */ 
     private $imageName; 

     /** 
     * @ORM\Column(type="datetime",nullable=true) 
     * 
     * @var \DateTime 
     */ 
     private $updatedAt; 


     public function __construct() { 
      parent::__construct(); 
      $this->enabled = true; 
      $this->groups = new ArrayCollection(); 
     } 
    } 

Group.php

namespace AppBundle\Entity; 

use FOS\UserBundle\Model\Group as BaseGroup; 
use Doctrine\ORM\Mapping as ORM; 

/** 
* @ORM\Entity 
* @ORM\Table(name="fos_group") 
*/ 
class Group extends BaseGroup 
{ 
    /** 
    * @ORM\Id 
    * @ORM\Column(type="integer") 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    protected $id; 

    /** 
     * @ORM\ManyToMany(targetEntity="AppBundle\Entity\User", mappedBy="groups") 
     * 
     * 
     */ 
    protected $users; 

    /** 
    * @var string 
    */ 
    protected $name; 

    /** 
    * @var array 
    */ 
    protected $roles; 

    /** 
    * Group constructor. 
    * 
    * @param string $name 
    * @param array $roles 
    */ 
    public function __construct($name, $roles = array()) 
    { 
     $this->name = $name; 
     $this->roles = $roles; 
    } 

} 

ответ

1

Вы можете достичь этого путем добавления «POST_SET_DATA» или «» PRE_SUBMIT форма события, чтобы назначить группу для пользователя, если нет каких-либо групп в форме данных.

$builder->addEventListener(FormEvents::POS_SET_DATA, function (FormEvent $event) { 
     $user = $event->getData(); 
     $form = $event->getForm(); 


     if (!$user->getGroups->count() > 0) { 
      //... 
     } 
    }); 

http://symfony.com/doc/current/form/dynamic_form_modification.html https://symfony.com/doc/current/form/events.html

вы также можете использовать жизненный цикл обратного вызова для объекта пользователя

http://symfony.com/doc/current/doctrine/lifecycle_callbacks.html

или непосредственно изменять объект в контроллере (ответ @martin «S)

+0

Спасибо ваше для u'r réponse, я хочу сказать, что т я есть яваскрипта ошибка в моей консоли: новое: 1 недопустимое контроль формы с именем = 'user [groups] []' не настраивается. – ahmedbhs

+0

Странная попытка и посмотреть в соответствующем скрипте, если вам удастся найти, откуда исходит ошибка. Нельзя связать с вашим слушателем формы. Вероятно, вы должны задать другой вопрос. Пожалуйста, подумайте о принятии и/или продолжении моего ответа, если вы сочтете это полезным, чтобы другие могли извлечь из этого выгоду. – Mawcel

+0

Совершено, и спасибо, что я очень благодарен за вашу помощь. – ahmedbhs

2

Вам необходимо передать данные по умолчанию при создании формы , Например, в вашем контроллере вы будете иметь:

$user = new User(); 
// Add default groups to the $user 
// ... 
$form = $this->createForm(UserType::class, $user); 
$form->handleRequest($request); 

if ($form->isValid()) { 
    $data = $form->getData(); 
    // ... 
} 
+0

Спасибо за ответ, поэтому мне нужна функция setGroups в моем классе пользователя: setGroups (Collection $ groups = null) { if ($ groups! == null) $ this-> groups = $ groups;} Затем, as u say: $ user-> setGroups ($ something)); ?? – ahmedbhs

+0

@safe Да, это должно быть то, что вы хотите. «$ User» является значением по умолчанию для формы, которая просто обновляется при вызове '$ form-> submit()'. Поэтому, если представленные данные не содержат каких-либо групп, они останутся со значением по умолчанию. – martin

+0

Как я могу инициализировать коллекцию? Мне нужно что-то изменить и установить объект коллекции дефолтов. – ahmedbhs