我正在创建一个用户表单,其中通过表单下拉列表选择了角色。我的表单和实体看起来像这样
//entity
private $roles;
public function getRoles()
{
return $this->roles;
}
//form
class RoleType extends AbstractType
{
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'choices' => array(
'ROLE_USER' => 'ROLE_USER',
'ROLE_ADMIN' => 'ROLE_ADMIN',
)
));
}
public function getParent()
{
return 'choice';
}
public function getName()
{
return 'role';
}
class RegistrationType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('username')
->add('password', 'repeated', array(
'type' => 'password',
'invalid_message' => 'The password fields must match.',
'options' => array('attr' => array('class' => 'password-field')),
'required' => true,
'first_options' => array('label' => 'Password'),
'second_options' => array('label' => 'Repeat Password'),
))
//->add('terms', 'checkbox', array(
// 'property_path' => 'termsAccepted',
// ))
->add('firstname')
->add('lastname')
->remove('photo')
->add('email', 'email')
->remove('status')
->remove('createdBy')
->remove('isActive')
->remove('dateCreated')
->remove('updatedBy')
->remove('dateUpdated')
//->remove('roles', 'choice', array(
// 'choices' => array('ROLE_USER' => 'ROLE_USER', 'ROLE_ADMIN' => 'ROLE_ADMIN'),
//))
->add('roles', new RoleType(), array(
'placeholder' => 'Choose Roles',
))
//->add('terms', 'checkbox', array(
// 'property_path' => 'termsAccepted',
// 'attr' => array('class' => 'checkbox'),
// ))
->add('Register', 'submit')
;
}
public function getName()
{
return 'registration';
}
创建一个通过表单下拉列表选择角色的用户时我没有问题。问题是,在登录期间,它会抛出错误,必须在数组中,而不是在字符串中
捕获致命错误:参数4传递给Symfony \ Component \ Security \ Core \ Authentication \ Token \ UsernamePasswordToken :: __ construct()必须是类型数组,字符串给定,在/ var / www /
中调用
我更改了我的用户实体
private $roles = array();
public function setRoles($roles)
{
$this->roles = $roles;
return $this;
}
public function getRoles()
{
return array($this->roles);
}
用户现在可以成功登录,但在以
形式添加其他用户时会引发错误type" array"的值无法转换为有效的数组键。
这只是一个简单的用户包。我不想使用像FOSUsersrBundle这样的另一个第三方软件包。想知道如何解决这个问题吗?
更新
在控制器中,我用它将其存储到数据库中
public function createAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
//$form = $this->createForm(new RegistrationType(), new Registration());
$form = $this->createForm(new RegistrationType(), new Users());
$form->handleRequest($request);
if ($form->isValid()) {
$registration = new Users();
$registration = $form->getData();
$registration->setDateCreated(new \DateTime());
//$registration->setRoles('ROLE_ADMIN');
$registration->setPhoto('http://www.gravatar.com/avatar/'.md5(trim($request->get('email'))));
$pwd=$registration->getPassword();
$encoder=$this->container->get('security.password_encoder');
$pwd=$encoder->encodePassword($registration, $pwd);
$registration->setPassword($pwd);
$em->persist($registration);
$em->flush();
$this->addFlash('danger', 'New User successfully added!');
return $this->redirect($this->generateUrl('voters_list'));
} else {
$this->addFlash('danger', 'Some errors buddy cannot proceed, please check!');
return $this->render('DuterteBundle:Security:register.html.twig',array(
'form' => $form->createView())
);
}
更新
我的基本映射
Project\Bundle\DuterteBundle\Entity\Users:
type: entity
table: users
repositoryClass: Project\Bundle\DuterteBundle\Repository\UsersRepository
#indexes:
#role_id_idx:
#columns:
#- role_id
id:
id:
type: integer
nullable: false
unsigned: false
comment: ''
id: true
generator:
strategy: IDENTITY
fields:
username:
type: string
nullable: false
length: 50
fixed: false
comment: ''
password:
type: string
nullable: false
length: 32
fixed: false
comment: ''
firstname:
type: string
nullable: true
length: 50
fixed: false
comment: ''
lastname:
type: string
nullable: true
length: 50
fixed: false
comment: ''
photo:
type: string
nullable: true
length: 200
fixed: false
comment: ''
email:
type: string
nullable: true
length: 200
fixed: false
comment: ''
status:
type: string
nullable: true
length: 8
fixed: false
comment: ''
roles:
type: string
nullable: true
length: 100
fixed: false
comment: ''
在mysql中,users表包含角色列,其中存储了角色,例如ROLE_USERS'" ROLE_ADMIN'等。从用户实体中更改getRoles函数
public function getRoles()
{
return array('ROLE_USER'_)
}
将成功记录用户,但角色始终设置为' ROLE_USERS'即使在数据库中,用户的角色也相当于' ROLE_ADMIN'
答案 0 :(得分:5)
代码中最大的错误是在getRoles()
函数中返回数组内的数组:
private $roles = array();
public function setRoles($roles)
{
$this->roles = $roles;
return $this;
}
public function getRoles()
{
return array($this->roles);
}
现在,在您的地图信息中,您将角色视为字符串,这意味着您的用户只使用一个角色,这简化了很多事情:
我们要更改字段的名称,因为安全组件需要一个数组并使用函数“getRoles()”,因为它继承自UserInterface或AdvancedUserInterfaceClass,但是如果已经存在数据,则表单检查对象在它上面(您还可以编辑和/或预加载要在表单中显示的数据),必须在数据库和映射信息中进行等效更改。
//entity
private $role;
public function setRole($role){
$this->roles = $role;
return $this;
}
public function getRole(){
return $this->roles;
}
public function getRoles(){
return array($this->role);
}
您不需要将其设置为数组,因为您将其作为字符串保留,安全组件不会注册用户,您可以这样做。为此,我们将改变你的formtypes和你的控制器。
//formtype
//I don't know what version you are using, but you dont need a separate formtype to add a choice and neither need to `remove` fields, you just don't `add` them.
//Remember to change the field in from 'roles' to 'role'
class RegistrationType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('username')
->add('password', 'repeated', array(
'type' => 'password',
'invalid_message' => 'The password fields must match.',
'options' => array('attr' => array('class' => 'password-field')),
'required' => true,
'first_options' => array('label' => 'Password'),
'second_options' => array('label' => 'Repeat Password'),
))
->add('firstname')
->add('lastname')
->add('email', 'email')
->add('role', 'choice', array(
'choices' => array('ROLE_USER' => 'User', 'ROLE_ADMIN' => 'Admin'),
))
->add('Register', 'submit')
;
}
public function configureOptions(OptionsResolver $resolver) {
$resolver->setDefaults(array(
'data_class' => 'Project\Bundle\DuterteBundle\Entity\Users' //this is important
));
}
}
现在你的控制器:
//Controller
//Also if you link a form to a entity you dont need the `getData()`
use Project\Bundle\DuterteBundle\Entity\Users;
public function createAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$user = new Users();
$form = $this->createForm(new RegistrationType(), $user);
$form->handleRequest($request); //here, every form field that has an equivalent in the entity, fills the entity property instead, that's why you only need to set the role as a string ;)
if ($form->isValid()) {
$user->setDateCreated(new \DateTime());
$user->setPhoto('http://www.gravatar.com/avatar/'.md5(trim($request->get('email'))));
$pwd=$user->getPassword();
$encoder=$this->container->get('security.password_encoder');
$pwd=$encoder->encodePassword($user, $user->getPassword());
$user->setPassword($pwd);
$em->persist($user);
$em->flush();
$this->addFlash('danger', 'New User successfully added!');
return $this->redirect($this->generateUrl('voters_list'));
} else {
$this->addFlash('danger', 'Some errors buddy cannot proceed, please check!');
return $this->render('DuterteBundle:Security:register.html.twig',array(
'form' => $form->createView())
);
}
}
你可以看到更简单,更容易和更干净。安全组件使用getRoles
将角色加载到应用程序中,是一个数组,因为用户可以获得多个角色,但为此您需要一个不同的模式。