Question

I would like to add other items by edit of a profile in FOSUserBundle.
I was trying to solve by using a form collection.

Entity/Information.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;

    // ....
}

Entity/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;
}

Controller/ProfileController

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);

    // ...

Form/Type/InformationType

// ...

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',
    ));
}

// ...

Form/Type/ProfileFormType

// ...

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(),
        ))
    ;
}

// ...

View/Profile/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) }}

// ...

enter image description here

Error occurs when I sent this.

Warning: spl_object_hash() expects parameter 1 to be object, array given in /path/to/symfony/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php line 1375

error point: FOSUserBundle/Form/Handler/ProfileFormHandler.php

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

Is the right method to use data transfer like an invitation system?
Is it possible with a collection form?

Was it helpful?

Solution

SOLVED.

I seem to should not have use the collection form.
And I seem to should use to "->add('profile', new ProfileType())".

hope this helps


Entity/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;

    // ....
}

Entity/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;
}

Controller/ProfileController

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);

    // ...

Form/Type/ProfileType

// ...

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',
    ));
}

// ...

Form/Type/ProfileFormType

// ...

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

// ...

View/Profile/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) }}

// ...

OTHER TIPS

Looks like that user you edited doesnt have information filled so form cant display anything. Read How to Embed a Collection of Forms article. Possible that you must init this field with some value.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top