Search code examples
symfonysonata-adminsymfony-sonata

Sonata Admin sonata_type_collection


I have an issue with Sonata admin form...

I would like to insert music in a album with position...

My issue is when I create an album... I can add many as I want AlbumHasMusic... But when I submit my form... Each AlbumHasMusic have a null album whereas music and positions are ok.

How could I put album id to each AlbumHasMusic ?

These are my Entities :

Album:

/**
 * Album
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="AppBundle\Entity\AlbumRepository")
 * @ORM\HasLifecycleCallbacks()
 */
class Album
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="titre", type="string", length=255)
     */
    private $titre;

    /**
     * @var UploadedFile
     */
    private $cover;

    /**
     * @var String
     *
     * @ORM\Column(name="filename", type="string", length=255, nullable=true)
     */
    private $covername;

    /**
     *
     * @var Array<AlbumHasMusiques>
     * @ORM\OneToMany(targetEntity="AppBundle\Entity\AlbumHasMusiques", mappedBy="album", cascade={"persist"})
     */
    private $albumHasMusiques;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="updated", type="time", nullable=true)
     */
    private $updated;
}

AlbumHasMusic:

/**
 * AlbumHasMusiques
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="AppBundle\Entity\AlbumHasMusiquesRepository")
 */
class AlbumHasMusiques
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var Album
     *
     * @ORM\ManyToOne(targetEntity="Album")
     * @ORM\JoinColumn(name="album_id", referencedColumnName="id")
     */
    private $album;

    /**
     * @var Musique
     *
     * @ORM\ManyToOne(targetEntity="Musique")
     * @ORM\JoinColumn(name="musique_id", referencedColumnName="id")
     */
    private $musique;

    /**
     * @var integer
     *
     * @ORM\Column(name="position", type="integer")
     */
    private $position;

}

Music:

/**
 * Musique
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="AppBundle\Entity\MusiqueRepository")
 * @ORM\HasLifecycleCallbacks()
 */
class Musique
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="duree", type="time", nullable=true)
     */
    private $duree;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="updated", type="time", nullable=true)
     */
    private $updated;

    /**
     * @var string
     */
    private $file;

    /**
     * @var String
     *
     * @ORM\Column(name="filename", type="string", length=255, nullable=true)
     */
    private $filename;

    /**
     * @var string
     *
     * @ORM\Column(name="titre", type="string", length=255, nullable=true)
     */
    private $titre;

    /**
     * @var Genre
     *
     * @ORM\ManyToOne(targetEntity="Genre", inversedBy="musiques")
     * @ORM\JoinColumn(name="genre_id", referencedColumnName="id", nullable=false)
     */
    private $genre;

    /**
     * @ORM\ManyToMany(targetEntity="MotClef", inversedBy="musiques")
     */
    private $motsClef;
}

I would like to do something like Galeries and media of Sonata Media Bundle.

And this is my AlbumAdmin:

class AlbumAdmin extends Admin
{
    /**
     * @param FormMapper $formMapper
     */
    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
            ->add('titre')
            ->add('covername')
            ->add('updated')
            ->add('albumHasMusiques', 'sonata_type_collection', array(
                'cascade_validation' => true,
                'by_reference'       => false,
            ), array(
                    'edit'              => 'inline',
                    'inline'            => 'table',
                    'sortable'          => 'position',
                    'link_parameters'   => array('context' => 'default'),
                    'admin_code'        => 'app.admin.album_has_musiques',
                )
            )
        ;
    }

    /**
     * {@inheritdoc}
     */
    public function prePersist($album)
    {
        $album->setAlbumHasMusiques($album->getAlbumHasMusiques());
    }

    /**
     * {@inheritdoc}
     */
    public function preUpdate($album)
    {
        $album->setAlbumHasMusiques($album->getAlbumHasMusiques());
    }
}

And AlbumHasMusicAdmin :

class AlbumHasMusiquesAdmin extends Admin
{
    /**
     * @param FormMapper $formMapper
     */
    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
            ->add('musique', 'sonata_type_model_list', array('required' => true), array(
                 'link_parameters' => ['context' => 'default'],
            ))
            ->add('position', 'hidden')
        ;
    }
}

Do you have any idea ?


Solution

  • I think that you missed something in the addAlbumHasMusiques() function in your album entity : make sure that you wrote it like that :

     public function addAlbumHasMusiques(\AppBundle\Entity\AlbumHasMusiques $albumHasMusiques) {
        $albumHasMusiques->setAlbum($this);  // The important line !!!!  
        $this->albumHasMusiques[] = $albumHasMusiques;
    
        return $this;
     }