从 zend 框架 3 中的 select 表单元素获取 Doctrine\Collection

Getting Doctrine\Collection from select form element in zend framework 3

我正在尝试在我的模块中实现 https://github.com/ZF-Commons/zfc-rbac。目前我被卡住了,因为我遇到以下异常:

Argument 1 passed to User\Entity\User::setRoles() must implement interface Doctrine\Common\Collections\Collection, array given ...

行,导致 UserManager class 中的错误:$user->setRoles($data['role']);

所以很明显,实体中的 setter 是错误的,或者 select 类型的元素 return 是 $data['role'] 元素。

setter代码:

public function setRoles(Collection $roles)
{
    $this->roles->clear();
    foreach ($roles as $role) {
        $this->roles[] = $role;
    }
}

UserForm 中 select 元素的代码:

$this->add([            
        'type'  => 'DoctrineModule\Form\Element\ObjectSelect',
        'name' => 'role',
        'attributes' => [
            'multiple' => true,
        ],
        'options' => [
            'object_manager' => $this->entityManager,
            'target_class' => 'User\Entity\Role',
            'label' => 'Role',
            'value_options' => $roles,
            'disable_inarray_validator' => true, //TODO: create validator
            'required' => true,
        ],
    ]);

那我怎么制作select元素returnDoctrine\Common\Collections\Collection?

我尝试使用 Doctrine 命名空间中的 ArrayCollection,但没有成功。我是否必须单独制作实现 Collection 接口的 class 并将其与 select 元素一起使用?或者也许有一些更方便的方法来实现这一点?

我也尝试删除实体中的@var、@param 注释和类型,但在这种情况下,我收到以下消息:

Expected value of type "Doctrine\Common\Collections\Collection|array" for association field "User\Entity\User#$roles", got "string" instead.

我找到了解决问题的方法。用户实体中的 setter 是正确的我只需要制作一个小的辅助函数,它将数组从 select 输入转换为角色对象数组:

private function getRolesFromArray($array){
    $roles = $this->entityManager->getRepository(Role::class)
            ->findBy(['id'=> $array]);
    return new ArrayCollection($roles);
}

所以 ArrayCollection 有效! 在 Form 对象中也有正确制作的 select 字段:

$this->add([            
        'type'  => 'DoctrineModule\Form\Element\ObjectSelect',
        'name' => 'role',
        'attributes' => [
            'multiple' => true,
        ],
        'options' => [
            'object_manager' => $this->entityManager,
            'target_class' => 'User\Entity\Role',
            'label' => 'Role',
            'required' => true,
        ],
    ]);