Bonjour à tous,

Je démarre avec Sonata Admin et SF2.
J'ai un souci avec une relation many-to-many entre deux entités.


Je souhaite que quand l'admin crée ou modifie un article il puisse, saisir tous les mots-clés de l'article séparés par des virgules dans un champ du formulaire.
Quand il valide, je veux récupérer les mots-clés de ce champ pour les associer à l'article (dans le même ordre, utilisation de l’attribut 'position' de l'entité ArticleKeyword).
Si le mot-clé existe je récupère son ID, si il n'existe pas je le crée et récupère son ID avec l'aide du repository de l'entité Keyword.

Je ne comprends pas à quel endroit je peux intercepter l'évènement prepersist() pour mettre à jour les mots-clés et l'entité d'association ArticleKeyword.

J'ai une entité Article
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
 
/**
 * Article
 *
 * @ORM\Table(name="article")
 * @ORM\Entity(repositoryClass="App\MyBundle\Entity\ArticleRepository")
 */
class Article
{
...
}
une entité Keyword

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
 
/**
 * Keyword
 *
 * @ORM\Table(name="keyword")
 * @ORM\Entity(repositoryClass="App\MyBundle\Entity\KeywordRepository")
 */
class Keyword
{
...
}
une entité ArticleKeyword qui correspond à la table d'association

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/**
 * ArticleKeyword
 *
 * @ORM\Table(name="article_keyword")
 * @ORM\Entity(repositoryClass="App\MyBundle\Entity\ArticleKeywordRepository")
 */
class ArticleKeyword
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;
 
    /**
     * @ORM\ManyToOne(targetEntity="App\MyBundle\Entity\Article")
     * @ORM\JoinColumn(nullable=false)
     */
    private $article;
 
    /**
     * @ORM\ManyToOne(targetEntity="App\MyBundle\Entity\Keyword")
     * @ORM\JoinColumn(nullable=false)
     */
    private $keyword;
 
    /**
     * @var integer
     *
     * @ORM\Column(name="position", type="integer")
     */
    private $position;
}
J'ai une classe ArticleAdmin

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
 
class ArticleAdmin extends Admin
{
    // Fields to be shown on create/edit forms
    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
            ->add('name', 'text', array('label' => 'Libellé'))
            ->add('keywords', 'text', array('label' => 'Mots-clés'))
            ->setHelps(array(
                'keywords' => 'Mots-clés séparés par des virgules, exemple : tennis,foot,natation'
            ))
        ;
    }
	public function prePersist($object) {
 
		// Impossible d'appeler le repository depuis cette classe
        $repository = $this->getDoctrine()->getRepository('AppMyBundle:Keyword');
 
        $keywords = explode(',', $object->keywords);
 
        foreach($keywords as $pos=>$keyword) {
            $keyword = $repository->findByName($keyword);
 
			// On crée la valeur d'association
			$articleKeyword = new ArticleKeyword();
			$articleKeyword->article 	= $object;
			$articleKeyword->keyword 	= $keyword;
			$articleKeyword->position 	= $pos;
			$articleKeyword->persist();
        }
 
        return $object;
    }