2017-02-20 188 views
3

我有两个类User.phpGroup.php,扩展自fosuserbundle中定义的类。实体类型字段的默认选择选项

除此之外,我有他们之间的ManyToMany关系。

该应用程序的想法是当我添加一个新用户,我分配给用户一个或多个组(我正在使用材料设计多选择选项)。当用户没有分配任何组时(例如,当组选项为空时)出现问题。我在控制台中得到这个javascript错误:

name ='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

或直接修改对象在你的控制器(记者@马丁回答)

+0

感谢您的u'r效应初探,我想牛逼说,我在我的控制台中的JavaScript错误: 新:1名无效表单控件= '用户[组] []'不可聚焦。 – ahmedbhs

+0

奇怪的尝试,看看有关的脚本,如果你设法找到错误来自哪里。不应该与你的表单监听器有关。你可能应该问另一个问题。请考虑接受和/或upvoting我的答案,如果你发现它有帮助,以便其他人可以从中受益。 – 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;} 然后,如你所说:$ user-> setGroups($ something)); ?? – ahmedbhs

+0

@safe是的,这应该是你想要的。 '$ user'是当你调用'$ form-> submit()'时刚刚更新的表单的默认值。因此,如果提交的数据不包含任何组,则它将保留默认值。 – martin

+0

我如何初始化一个集合? 我需要更改$ something并设置一个deffault集合对象。 – ahmedbhs