2013-03-25 35 views
0

我有一個角色像爲實體和許多像這麼多的關係的自定義處理程序:Symfony的角色:以實體的形式發佈

<?php 

namespace Digital\UserBundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 
use Symfony\Component\Security\Core\Role\RoleInterface; 


    /** 
    * Role Entity 
    * 
    * @ORM\Entity 
    * @ORM\Table(name="app_roles") 
    */ 
    class Role implements RoleInterface 
    { 

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

     /** 
     * @ORM\Column(type="string", name="name", unique=true, length=100) 
     */ 
     private $role; 

     /** 
     * @var Role 
     * @ORM\ManyToOne(targetEntity="Role") 
     * @ORM\JoinColumn(name="parent_id", referencedColumnName="id") 
     **/ 
     private $parent; 


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


     /** 
     * @return string 
     */ 
     public function __toString() 
     { 
      return $this->role; 
     } 


     /** 
     * @param $role 
     */ 
     public function setRole($role) 
     { 
      $this->role = $role; 
     } 


     /** 
     * @return string 
     */ 
     public function getRole() 
     { 
      return $this->role; 
     } 


     /** 
     * @param Role $parent 
     * 
     * @return $this 
     */ 
     public function setParent(Role $parent) 
     { 
      $this->parent = $parent; 
      return $this; 
     } 


     /** 
     * @return Role 
     */ 
     public function getParent() 
     { 
      return $this->parent; 
     } 


     /** 
     * @return bool 
     */ 
     public function hasParent() 
     { 
      return null !== $this->parent; 
     } 

    } 

然後,我有我的用戶對象配置如下:

<?php 
// src/Acme/UserBundle/Entity/User.php 

namespace Digital\UserBundle\Entity; 

use FOS\UserBundle\Entity\User as BaseUserOld; 
use FOS\UserBundle\Model\User as BaseUser; 
use Doctrine\ORM\Mapping as ORM; 
use Doctrine\Common\Collections\Collection; 
use Doctrine\Common\Collections\ArrayCollection; 
use FOS\MessageBundle\Model\ParticipantInterface; 
use Symfony\Component\HttpFoundation\File\File; 

use Symfony\Component\Validator\Constraints as Assert; 
use Symfony\Component\Validator\Constraints\Email; 
use Symfony\Component\Validator\Constraints\NotBlank; 

/** 
* @ORM\Entity 
* @ORM\Table(name="app_users") 
* @ORM\Entity(repositoryClass="Digital\UserBundle\EntityRepository\UserRepository") 
*/ 
class User extends BaseUser implements ParticipantInterface 
{ 
    // properties... 


    /** 
    * @ORM\ManyToMany(targetEntity="Role", indexBy="name") 
    * @ORM\JoinTable(name="app_users_roles") 
    */ 
    protected $roles; 

    /** 
    * Construct. 
    */ 
    public function __construct() 
    { 
     parent::__construct(); 

     $this->roles  = new ArrayCollection; 
    } 


    /** 
    * @return Role[] 
    */ 
    public function getRoles() 
    { 
     $roles = $this->getRolesCollection()->toArray(); 
     $roles[] = $this->getDefaultRole(); 
     return $roles; 
    } 


    /** 
    * @param $role 
    * 
    * @return bool 
    */ 
    public function hasRole($role) 
    { 
     if ($role instanceof Role) { 
      $role = $role->getRole(); 
     } 

     foreach ($this->getRoles() as $roleEntity) { 
      if ($roleEntity->getRole() === $role) { 
       return true; 
      } 
     } 

     return false; 
    } 


    /** 
    * @param $role 
    * 
    * @return self 
    * @throws \InvalidArgumentException 
    */ 
    public function addRole($role) 
    { 
     $this->normaliseRole($role); 

     if ($this->hasRole($role)) { 
      throw new \InvalidArgumentException("Role $role is already applied to this " . get_class($this)); 
     } 

     $this->getRolesCollection()->add($role); 

     return $this; 
    } 


    /** 
    * @param Role|string $role 
    * 
    * @return self 
    */ 
    public function removeRole($role) 
    { 
     $this->normaliseRole($role); 
     $this->getRolesCollection()->removeElement($role); 
     return $this; 
    } 


    /** 
    * @param Role[]|string[] $roles 
    * 
    * @return self 
    */ 
    public function setRoles(array $roles) 
    { 
     $this->getRolesCollection()->clear(); 

     foreach ($roles as $role) { 
      $this->addRole($role); 
     } 

     return $this; 
    } 


    /** 
    * {@inheritdoc} 
    */ 
    protected function getRolesCollection() 
    { 
     return $this->roles; 
    } 


    /** 
    * {@inheritdoc} 
    */ 
    protected function getDefaultRole() 
    { 
     return new Role(parent::ROLE_DEFAULT); 
    } 


    /** 
    * @param $role 
    * 
    * @throws \InvalidArgumentException 
    */ 
    protected function normaliseRole(&$role) 
    { 
     if (is_string($role)) { 
      $role = new Role($role); 
     } 

     if (!$role instanceof Role) { 
      throw new \InvalidArgumentException('Role must be either a Role Entity or a string.'); 
     } 
    } 
} 

現在我的問題是我如何配置我的表單接受按照接口的對象數組?

我是否使用收集/實體/選擇?一切都似乎沒有...

$builder->add('roles', 'entity', array(
     'class' => 'Digital\UserBundle\Entity\Role', 
     'by_reference' => true,) 
    ); 

Catchable Fatal Error: Argument 1 passed to Digital\UserBundle\Entity\User::setRoles() must be of the type array, object given

任何提示將非常讚賞...

這不起作用或者:

$builder->add('roles', 'collection', array(
     'type' => new RoleType(), 
     'allow_add' => true, 
     'allow_delete' => true, 
     'by_reference' => false, 
    )); 

或:

$builder->add('roles', 'collection', 
     array('options' => array(
      'data_class' => 'Digital\UserBundle\Entity\Role'), 
      'allow_add' => true, 
      'allow_delete' => true, 
      'by_reference' => false)); 

我能得到這個工作的壁櫥是th是:

public function addRole($role) 
    { 
     $this->normaliseRole($role); 

//  if (!$this->roles->contains($role)) { 
     if (!$this->hasRole($role)) { 
      $this->getRolesCollection()->add($role); 
     } 

     return $this; 
    } 

     $builder->add('roles', 'collection', array('options' => array('data_class' => 'Digital\UserBundle\Entity\Role'), 
      'allow_add' => true, 'allow_delete' => true, 'by_reference' => false)); 

這樣我能夠沒有誤差修改提交表單,但是任何更改都將失敗,因爲我不得不添加級聯持續,這個角色已經在角色表和學說正試圖重新插入。 ...;(

回答

1

的回答是:

$builder->add('rolesCollection', 'entity', array(
     'multiple'  => true, 
     'expanded'  => true, 
     'by_reference' => false, 
     'label' => 'Roles', 
     'class'  => 'Digital\UserBundle\Entity\Role', 
    )); 

而與 'rolesCollection' 而不是 '角色' 玩。

/** 
* @param Collection $collection 
*/ 
public function setRolesCollection($collection) 
{ 
    $this->setRoles($collection->toArray()); 

    return $this; 
} 
0

您是否嘗試過使用collection類型? entity類型暗示一個相關對象。

http://symfony.com/doc/current/cookbook/form/form_collections.html

+0

是的,其實我嘗試這樣做:'$ builder->添加( '角色', '收藏',陣列( '型'=>新的角色類型(), 'allow_add'=>真實, 'allow_delete'=> true, 'by_reference'=> false, ));'但是這給了我在每個角色的輸入文本在一個分離的字段...並要求我級聯堅持試圖插入角色到我的app_roles表格提交的表格不應該是這種情況.. – rat4m3n 2013-03-25 22:23:54