我知道FOSuserbundle的可用性,但是为了帮助学习symfony2,我决定尝试使用book / cookbook从头开始创建所有内容。
在遵循cookbooks安全性教程后,我无法确定如何将新用户持久保存到数据库中。我还有其他一切正常,登录,防火墙安全域,密码加密等
当我尝试添加用户时,我收到以下错误:
属性"角色"也没有其中一种方法" addRol()" /" removeRol()"," addRole()" /" removeRole()&# 34;," setRoles()"," roles()"," __ set()"或" __ call()"在课堂上存在并拥有公共访问权限" Ampisoft \ Bundle \ etrackBundle \ Entity \ users"
我注意到users()
类没有setRoles方法,但我不确定如何添加一个,因为它需要使用数组对象(?)。令我困惑的另一件事是错误突出显示没有addRole()
(而不是addRoles
方法,即使该成员是roles
。
我的代码如下:
用户实体类(它非常有用,所以这些只是我认为重要的部分
class users implements AdvancedUserInterface, \Serializable
{
// ......
/**
* @ORM\ManyToMany(targetEntity="roles", inversedBy="users")
*
*/
private $roles;
/**
* @inheritDoc
*/
public function getRoles()
{
return $this->roles->toArray();
}
/**
* Add roles
*
* @param \Ampisoft\Bundle\etrackBundle\Entity\roles $roles
* @return users
*/
public function addRoles(roles $roles)
{
$this->roles[] = $roles;
return $this;
}
// ......
}
角色实体类(同样,相关部分)
class roles implements RoleInterface
{
// .........
/**
* @ORM\ManyToMany(targetEntity="users", mappedBy="roles")
*/
private $users;
public function __construct()
{
$this->users = new ArrayCollection();
}
/**
* Add users
*
* @param \Ampisoft\Bundle\etrackBundle\Entity\users $user
* @return roles
*/
public function addUser(users $user)
{
$this->users[] = $user;
return $this;
}
// .........
}
控制器
public function admin_new_userAction()
{
$user = new users();
$form = $this->createForm(new usersType(), $user);
$request = $this->getRequest();
// if form is posted
if ($request->getMethod() === 'POST') {
$form->bind($request);
$user->setSalt(md5(time()));
$encoder = $this->container->get('security.encoder_factory')->getEncoder($user); //get encoder for hashing pwd later
$tempPassword = $encoder->encodePassword($user->getPassword(), $user->getSalt());
$user->setPassword($tempPassword);
// flush to db
$em = $this->getDoctrine()->getEntityManager();
$em->persist($user);
$em->flush();
return $this->redirect($this->generateUrl('admin_users'));
}
// BUILD FORM
return $this->render('etBundle:Admin:new_user.html.twig', array(
'form' => $form->createView(),
));
}
usersType类(我打算用它来编辑用户以及监听器)
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
$user = $event->getData();
$form = $event->getForm();
// check if the User object is "new"
if (!$user || null === $user->getId()) {
$form->add('username', 'text');
$form->add('firstname', 'text');
$form->add('lastname', 'text');
$form->add('password', 'repeated', array(
'type' => 'password',
'invalid_message' => 'The password fields must match.',
'options' => array('attr' => array('class' => 'password-field')),
'required' => false,
'first_options' => array('label' => 'Password'),
'second_options' => array('label' => 'Repeat Password'),
));
$form->add('email', 'repeated', array(
'type' => 'email',
'invalid_message' => 'The email address fields must match.',
'options' => array('attr' => array('class' => 'email-field')),
'required' => true,
'first_options' => array('label' => 'Email'),
'second_options' => array('label' => 'Repeat Email'),
));
$form->add('email', 'repeated', array(
'type' => 'email',
'invalid_message' => 'The email address fields must match.',
'options' => array('attr' => array('class' => 'email-field')),
'required' => true,
'first_options' => array('label' => 'Email'),
'second_options' => array('label' => 'Repeat Email'),
));
$form->add('lastLogged', 'hidden');
$form->add('roles', 'entity', array(
'class' => 'etBundle:roles',
'property' => 'name',
));
} else {
$form->add('id', 'hidden');
$form->add('username', 'text');
$form->add('firstname', 'text');
$form->add('lastname', 'text');
$form->add('password', 'repeated', array(
'type' => 'password',
'invalid_message' => 'The password fields must match.',
'options' => array('attr' => array('class' => 'password-field')),
'required' => false,
'first_options' => array('label' => 'Password'),
'second_options' => array('label' => 'Repeat Password'),
));
$form->add('email', 'repeated', array(
'type' => 'email',
'invalid_message' => 'The email address fields must match.',
'options' => array('attr' => array('class' => 'email-field')),
'required' => true,
'first_options' => array('label' => 'Email'),
'second_options' => array('label' => 'Repeat Email'),
));
}
});
我发现addUser
类中有一个roles()
方法,但我不确定如何使用它。如果有人能指出我正确的方向,我将非常感激。
** 更新 1 **
我尝试在上面插入建议的setRoles()方法,现在我收到以下内容
error: Catchable Fatal Error: Argument 1 passed to Doctrine\Common\Collections\ArrayCollection::__construct() must be of the type array, object given, called in C:\Dropbox\xampp\htdocs\etrack3\vendor\doctrine\orm\lib\Doctrine\ORM\UnitOfWork.php on line 555 and defined
** 更新 2 ** 解决了这个问题:意识到我的用户/角色实体之间有很多关系/多关系。改为manyToOne / OneToMany,一切都很好。
答案 0 :(得分:2)
您的class users
缺少其构造函数,该构造函数将$roles
属性初始化为ArrayCollection
实例。我还建议不要使用$this->users[]
表示法,而是将这些属性视为真正的属性:
$this->users->add($user);
至于你得到的错误,这取决于Doctrine如何加载它的实体。该错误显示了实体类中的doctrine查找内容,以便设置属性:roles
属性应该是公共的,或者您需要一个名称类似于set<ucfirst-name-of-table-field>
的方法,或者慢魔法getter / setter界面。
就setRoles
和setUsers
方法而言,这是一件简单的事情:
public function setRoles($roles)
{
$this->roles = $roles;
return $this;
}
可以选择添加类型提示:
public function setRoles( ArrayCollection $roles)
{
$this->roles = $roles;
return $this;
}
我想提及的其他一些问题:
编码标准很重要,请检查最常用的标准here。 Doctrine,Symfony2,ZendFW2,...所有主要参与者都赞同这些标准,你也应该这样做。类名称例如以大写字母开头,因此class users
应该变为class Users
等...
我还建议不要在doctrine实体上实现Serializable
接口,特别是如果你使users
Serializable,它可能包含Roles
个实例,而不实现Serializable
。< / p>