сохранение нового пользователя в БД

0

Я знаю о доступности FOSuserbundle, но для того, чтобы помочь узнать symfony2, я решил попытаться создать все с нуля, используя книгу/поваренную книгу.

После выполнения учебников по кулинарной книге для обеспечения безопасности у меня возникли проблемы с разработкой того, как сохранить нового пользователя в базе данных. У меня все работает нормально, логины, домены безопасности брандмауэра, шифрование паролей и т.д.

Когда я пытаюсь добавить пользователя, я получаю следующую ошибку:

Ни свойства "роли", ни один из методов "addRol()"/"removeRol()", "addRole()"/"removeRole()", "setRoles()", "role()", "__set ( ) "или" __call() "существуют и имеют открытый доступ в классе" Ampisoft\Bundle\etrackBundle\Entity\users "

Я заметил, что класс users() не имеет метода setRoles, но я не уверен, как его добавить, поскольку он должен использовать объект массива (?). другое, что меня addRole() заключается в том, что ошибка не addRoles метод 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() есть метод addUser но Im unsure о том, как его использовать. Я был бы очень благодарен, если бы кто-то мог указать мне в правильном направлении.

** обновление 1 **

Я попытался вставить предложенный метод setRoles() выше, и теперь Im получает следующую 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

** update 2 ** исправлена эта проблема: поняли, что у меня было многосотовое/многоголовое отношение между моими пользователями/ролями. Изменено для ManyToOne/OneToMany, и все хорошо.

Теги:
doctrine

1 ответ

2
Лучший ответ

У ваших class users отсутствует его конструктор, который инициализирует свойство $roles ArrayCollection экземпляром ArrayCollection. Я бы также посоветовал вам использовать $this->users[], чтобы рассматривать эти свойства как то, что они на самом деле:

$this->users->add($user);

Что касается ошибки, которую вы получаете, то до того, как Doctrine загружает свои сущности. Ошибка показывает, что доктрина ищет в классе сущностей, для того, чтобы установить свойство: либо roles собственность должна быть публичной, или вам нужен метод с именем, которое выглядит как set<ucfirst-name-of-table-field>, или интерфейс медленной магии приемника/сеттера.

Что касается методов setRoles и setUsers, то это просто:

public function setRoles($roles)
{
    $this->roles = $roles;
    return $this;
}

С возможностью добавления типа-подсказки:

public function setRoles( ArrayCollection $roles)
{
    $this->roles = $roles;
    return $this;
}

Некоторые другие вопросы, которые я хотел бы упомянуть:

Стандарты кодирования важны, ознакомьтесь с наиболее распространенными стандартами здесь. Doctrine, Symfony2, ZendFW2,... все основные игроки подписываются на эти стандарты, и вам тоже. Имя класса, например, начинается с символа верхнего регистра, поэтому class users должны стать class Users т.д....
Я также рекомендую не применять интерфейс Serializable для объектов доктрины, особенно если вы делаете users Serializable, которые могут содержать экземпляры Roles, которые не реализуют Serializable.

  • 0
    большое спасибо за ответ. У меня есть __construct() , я просто не показывал его, когда пытался сократить содержание страницы. Я внес изменения в имена классов, как это было предложено. Это было кое-что, что я узнал после того, как начал и был слишком ленив, чтобы исправить !! сделано сейчас. Я попытаюсь решить проблему, а затем доложу

Ещё вопросы

Сообщество Overcoder
Наверх
Меню