FOSUserBundle: я хотел бы добавить другие элементы, отредактировав профиль

Я хотел бы добавить другие элементы, отредактировав профиль в FOSUserBundle.
Я пытался решить эту проблему с помощью коллекции форм.

Сущность/Информация.php

namespace My\UserBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="My\UserBundle\Repository\UserRepository")
 */
class Information
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column @ORM\Column(type="string", length=255, nullable=true)
     */
    protected $website;

    // .... and other information

    /**
     * @ORM\OneToOne(targetEntity="User", mappedBy="information", cascade={"persist", "merge"})
     */
    protected $user;

    // ....
}

Сущность/User.php

// ...

public function __construct()
{
    parent::__construct();
    $this->information = new \Doctrine\Common\Collections\ArrayCollection();
}

// ...

/**
 * @ORM\OneToOne(targetEntity="Information", inversedBy="user")
 * @ORM\JoinColumn(referencedColumnName="id")
 */
protected $information;

/**
 * Add information
 *
 * @param My\UserBundle\Entity\Information $information
 * @return User
 */
public function addInformation(Information $information)
{
    $this->information[] = $information;

    return $this;
}

/**
 * Remove information
 *
 * @param My\UserBundle\Entity\Information $information
 */
public function removeInformation(\My\UserBundle\Entity\Information $information)
{
    $this->information->removeElement($information);
}

/**
 * Get information
 *
 * @return Doctrine\Common\Collections\Collection 
 */
public function getInformation()
{
    return $this->information;
}

Контроллер/профилеконтроллер

public function editAction()
{
    $em   = $this->container->get('doctrine')->getManager();
    $own  = $this->container->get('security.context')->getToken()->getUser();
    $user = $em->getRepository('MyUserBundle:User')->find_one_with_info($own);  //=> Left join information table

    if (!is_object($user) || !$user instanceof UserInterface) {
        throw new AccessDeniedException('This user does not have access to this section.');
    }

    if (count($user->getInformation()) == 0)
        $user->addInformation(new Information());

    $form = $this->container->get('fos_user.profile.form');
    $formHandler = $this->container->get('fos_user.profile.form.handler');

    $process = $formHandler->process($user);

    // ...

Форма/Тип/Тип Информации

// ...

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('website', 'text', array('required' => false))
        // ... and other information
    ;
}

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'My\UserBundle\Entity\Information',
    ));
}

// ...

Форма/Тип/ПрофильФормаТип

// ...

protected function buildUserForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('username', null, array('label' => 'form.username', 'translation_domain' => 'FOSUserBundle'))
        ->add('information', 'collection', array(
            'type' => new InformationType(),
        ))
    ;
}

// ...

Вид/Профиль/edit_content.html.twig

// ...

{% for info in form.information %}
    <div class="_errors">
        {{ form_errors(info.website) }}
    </div>
    <div class="_form_bar">
        {{ form_widget(info.website) }}
    </div>

    // ... and other information

{% endfor %}

<div class="_errors">
    {{ form_errors(form.current_password) }}
</div>
<div class="_form_bar">
    {{ form_widget(form.current_password) }}
    {{ form_label(form.current_password) }}
</div>

{{ form_widget(form) }}

// ...

введите здесь описание изображения

Ошибка возникает, когда я отправил это.

Предупреждение: spl_object_hash() ожидает, что параметр 1 будет объектом, массивом, указанным в /path/to/symfony/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php, строка 1375.

точка ошибки: FOSUserBundle/Form/Handler/ProfileFormHandler.php

protected function onSuccess(UserInterface $user)
{
    $this->userManager->updateUser($user);    //=> error point
}

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


person R.Atim    schedule 25.07.2013    source источник


Ответы (2)


РЕШЕНО.

Кажется, мне не нужно было использовать форму для сбора.
И я, кажется, должен был использовать для "->add('profile', new ProfileType())".

надеюсь это поможет


Сущность/Profile.php

namespace My\UserBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="My\UserBundle\Repository\UserRepository")
 */
class Profile
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    protected $website;

    // .... and other profile

    /**
     * @ORM\OneToOne(targetEntity="User", mappedBy="profile", cascade={"persist", "merge", "remove"})
     */
    protected $user;

    // ....
}

Сущность/User.php

// ...

/**
 * @ORM\OneToOne(targetEntity="Profile", inversedBy="user", cascade={"persist", "merge", "remove"})
 * @ORM\JoinColumn(referencedColumnName="id")
 */
protected $profile;

public function setProfile(Profile $profile)
{
    $this->profile = $profile;
}

public function getProfile()
{
    return $this->profile;
}

Контроллер/профилеконтроллер

public function editAction()
{
    $em   = $this->container->get('doctrine')->getManager();
    $own  = $this->container->get('security.context')->getToken()->getUser();
    $user = $em->getRepository('MyUserBundle:User')->find_one_with_info($own);  //=> Left join profile table

    if (!is_object($user) || !$user instanceof UserInterface) {
        throw new AccessDeniedException('This user does not have access to this section.');
    }

    if (! $user->getProfile())
        $user->setProfile(new Profile());

    $form = $this->container->get('fos_user.profile.form');
    $formHandler = $this->container->get('fos_user.profile.form.handler');

    $process = $formHandler->process($user);

    // ...

Форма/Тип/Тип Профиля

// ...

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('website', 'text', array('required' => false))
        // ... and other profile
    ;
}

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'My\UserBundle\Entity\Profile',
    ));
}

// ...

Форма/Тип/ПрофильФормаТип

// ...

protected function buildUserForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('username', null, array('label' => 'form.username', 'translation_domain' => 'FOSUserBundle'))
        ->add('profile', new ProfileType())
    ;
}

// ...

Вид/Профиль/edit_content.html.twig

// ...

<div>
    {{ form_errors(form.profile.website) }}
</div>
<div>
    <label>Website:</label>
    {{ form_widget(form.profile.website) }}
</div>

// ... and other profile

<div>
    {{ form_errors(form.current_password) }}
</div>
<div>
    {{ form_label(form.current_password) }}
    {{ form_widget(form.current_password) }}
</div>

{{ form_widget(form) }}

// ...
person R.Atim    schedule 28.07.2013

Похоже, у того пользователя, которого вы редактировали, не заполнено information, поэтому форма ничего не отображает. Прочтите статью Как встроить коллекцию форм. Возможно, вы должны указать в этом поле какое-то значение.

person Alexey B.    schedule 25.07.2013
comment
1: Информационное свойство User Entity будет в коллекции массивов. 2: Пользователь добавляет новый информационный объект, если у пользователя нет информации. Это правильный способ добавления других элементов путем редактирования профиля? Было странное ощущение, что это к массиву отношение oneToOne. (Разве это не помогло бы, если бы я использовал форму сбора?) - person R.Atim; 25.07.2013
comment
примечание: $this->userManager->updateUser($user); Предупреждение: spl_object_hash() ожидает, что параметр 1 будет объектом, заданным массивом - person R.Atim; 25.07.2013
comment
в отношении oneToOne используйте тип формы entity - person Alexey B.; 25.07.2013
comment
Я, кажется, должен использовать ->add('information', new InformationType()). Спасибо за совет. - person R.Atim; 28.07.2013