Bonjour,
J'aimerais avoir votre avis et vos eventuelles corrections à propos d'un formulaire qui ne fonctionne pas totalement.
C'est un formulaire classique pour ajouter un article à un blog. Il y a un champ titre, image, contenu et tags.
Voici le type pour l'article :
Celui pour les tags :
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 namespace App\BlogBundle\Form; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilder; use Doctrine\Common\Persistence\ObjectManager; use App\BlogBundle\Form\MediaType; class ArticleType extends AbstractType { public function buildForm(FormBuilder $builder, array $options) { $builder->add('titre', 'text') ->add('data', 'file', array('label' => 'Image', 'required' => false)) ->add('contenu', 'textarea', array('required' => false, 'attr' => array( 'class' => 'tinymce', 'data-theme' => 'advanced' ))) ->add('vedette', 'checkbox', array('label' => 'En vedette', 'required' => false)) ->add('tags', 'tags'); } public function getName() { return 'article'; } }
Un data transformer pour les tags qui ne fonctionne que dans un sens (le paramètre de la fonction transform est toujours égal à null) :
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
37
38
39
40
41 namespace App\BlogBundle\Form; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilder; use App\BlogBundle\Form\StringToTagsTransformer; use Doctrine\Common\Persistence\ObjectManager; class TagsType extends AbstractType { private $om; public function __construct(ObjectManager $om) { $this->om = $om; } public function buildForm(FormBuilder $builder, array $options) { $transformer = new StringToTagsTransformer($this->om); $builder->appendClientTransformer($transformer); } public function getDefaultOptions(array $options) { return array( 'invalid_message' => 'The selected tags does not exist', ); } public function getParent(array $options) { return 'text'; } public function getName() { return 'tags'; } }
[S]Ensuite le handler :
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
37
38
39
40
41
42
43 namespace App\BlogBundle\Form; use Symfony\Component\Form\DataTransformerInterface; use Symfony\Component\Form\Exception\TransformationFailedException; use Doctrine\Common\Persistence\ObjectManager; use Doctrine\Common\Collections\ArrayCollection; use App\MetaBundle\Entity\Tag; class StringToTagsTransformer implements DataTransformerInterface { private $om; public function __construct(ObjectManager $om) { $this->om = $om; } public function reverseTransform($ftags) { $tags = new ArrayCollection(); $tag = strtok($ftags, ","); while($tag !== false) { $itag = new Tag(); $itag->setLibelle($tag); if(!$tags->contains($itag)) $tags[] = $itag; $tag = strtok(","); } return $tags; } public function transform($tags) { $ftags = ""; /*foreach($tags as $tag) $ftags = $ftags.','.$tag->getLibelle();*/ return $ftags; } }
Le controleur :
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71 namespace App\BlogBundle\Form; use Symfony\Component\Form\Form; use Symfony\Component\HttpFoundation\Request; use Doctrine\ORM\EntityManager; use App\BlogBundle\Entity\Article; use App\MetaBundle\Entity\Media; class ArticleHandler { protected $form; protected $request; protected $em; protected $user; public function __construct(Form $form, Request $request, EntityManager $em, \App\UserBundle\Entity\User $user) { $this->form = $form; $this->request = $request; $this->em = $em; $this->user = $user; } public function process() { if( $this->request->getMethod() == 'POST' ) { $this->form->bindRequest($this->request); if( $this->form->isValid() ) { $this->onSuccess($this->form->getData()); return true; } } return false; } public function onSuccess(Article $article) { $data = $article->data; $image = new Media(); $image->setNom($data->getClientOriginalName()); $image->setTaille($data->getClientSize()); $image->setType("image"); $image->setMembre($this->user); $name = md5(uniqid('H', 5)); $image->setUrl("images/".$name.strrchr($data->getClientOriginalName(),'.')); $data->move(__DIR__.'/../../../../web/uploads/images/', $name.strrchr($data->getClientOriginalName(),'.')); $article->setMembre($this->user); $article->setImage($image); $article->setContenu(stripslashes($article->getContenu())); $this->em->persist($article); $this->em->persist($image); foreach($article->getTags() as $tag) { $this->em->persist($tag); } $this->em->flush(); } }
Puis enfin les entités :
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73 class BlogController extends Controller { public function showAction($id) { $em = $this->getDoctrine()->getEntityManager(); $article = $em->getRepository('AppBlogBundle:Article')->find($id); if (!$article) { throw $this->createNotFoundException('Impossible de trouver l\'article'); } $tags = $em->getRepository('AppMetaBundle:Tag') ->getLatestTags(); return $this->render('AppBlogBundle:Blog:show.html.twig', array( 'form' => $article, 'tags' => $tags, )); } /** * @Secure(roles="ROLE_SUPER_ADMIN") */ public function addAction() { $article = new Article(); $form = $this->createForm(new ArticleType(), $article); $user = $this->container->get('security.context')->getToken()->getUser(); $formHandler = new ArticleHandler($form, $this->get('request'), $this->getDoctrine()->getEntityManager(), $user); if($formHandler->process()) { $this->get('session')->setFlash('app-notice', 'Article enregistré!'); return $this->redirect($this->generateUrl('AppBlogBundle_blog_show', array('id' => $article->getId()))); } return $this->render('AppBlogBundle:Blog:blog.html.twig', array( 'form' => $form->createView(), 'article' => $article )); } /** * @Secure(roles="ROLE_SUPER_ADMIN") */ public function editAction($id) { $em = $this->getDoctrine()->getEntityManager(); if(!$article = $em->getRepository('App\BlogBundle\Entity\Article')->find($id)) { throw $this->createNotFoundException('Article[id='.$id.'] inexistant'); } $form = $this->createForm(new ArticleType(), $article); $user = $this->container->get('security.context')->getToken()->getUser(); $formHandler = new ArticleHandler($form, $this->get('request'), $this->getDoctrine()->getEntityManager(), $user); if($formHandler->process()) { $this->get('session')->setFlash('app-notice', 'Article modifié!'); return $this->redirect($this->generateUrl('AppBlogBundle_blog_show', array('id' => $article->getId()))); } return $this->render('AppBlogBundle:Blog:blog.html.twig', array( 'form' => $form->createView(),'article' => $article )); } }
Article
Tag
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257 namespace App\BlogBundle\Entity; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Validator\Mapping\ClassMetadata; use Symfony\Component\Validator\Constraints\NotBlank; use Symfony\Component\Validator\Constraints\Image; use Doctrine\Common\Collections\ArrayCollection; /** * @ORM\Table(name="article") * @ORM\Entity(repositoryClass="app\BlogBundle\Repository\ArticleRepository") * @ORM\HasLifecycleCallbacks() */ class Article { public function __construct() { $this->setdateCreation(new \DateTime()); $this->setdateMAJ(new \DateTime()); $this->tags = new ArrayCollection(); } public static function loadValidatorMetadata(ClassMetadata $metadata) { $metadata->addPropertyConstraint('titre', new NotBlank()); $metadata->addPropertyConstraint('tags', new NotBlank()); $metadata->addPropertyConstraint('image', new Image()); $metadata->addPropertyConstraint('contenu', new NotBlank()); } /** * @ORM\preUpdate */ public function setdateMAJValue() { $this->setdateMAJ(new \DateTime()); } /** * @ORM\Id * @ORM\Column(type="integer") * @ORM\GeneratedValue(strategy="AUTO") */ protected $id; /** * @ORM\Column(type="string") */ protected $titre; /** * @ORM\ManyToOne(targetEntity="App\UserBundle\Entity\User") */ protected $membre; /** * @ORM\Column(type="text") */ protected $contenu; /** * @ORM\OneToOne(targetEntity="App\MetaBundle\Entity\Media") */ protected $image; public $data; /** * @ORM\ManyToMany(targetEntity="App\MetaBundle\Entity\Tag", inversedBy="articles") * @ORM\JoinTable(name="tag_article", * joinColumns={@ORM\JoinColumn(name="idArticle", referencedColumnName="id")}, * inverseJoinColumns={@ORM\JoinColumn(name="idTag", referencedColumnName="id")}) */ protected $tags; /** * @ORM\Column(type="datetime") */ protected $dateCreation; /** * @ORM\Column(type="datetime") */ protected $dateMAJ; /** * @ORM\Column(type="boolean") */ protected $vedette; /** * Get id * * @return integer */ public function getId() { return $this->id; } /** * Set titre * * @param string $titre */ public function setTitre($titre) { $this->titre = $titre; } /** * Get titre * * @return string */ public function getTitre() { return $this->titre; } public function setTags($tags) { $this->tags = $tags; } public function getTags() { return $this->tags; } /** * Set idMembre */ public function setMembre(\App\UserBundle\Entity\User $membre) { $this->membre = $membre; } /** * Get idMembre */ public function getMembre() { return $this->membre; } /** * Set contenu * * @param text $contenu */ public function setContenu($contenu) { $this->contenu = $contenu; } /** * Get contenu * * @return text */ public function getContenu($length = null) { if (false === is_null($length) && $length > 0) return substr($this->contenu, 0, $length); else return $this->contenu; } /** * Set idImage */ public function setImage(\App\MetaBundle\Entity\Media $image) { $this->image = $image; } /** * Get idImage */ public function getImage() { return $this->image; } /** * Set dateCreation * * @param datetime $dateCreation */ public function setDateCreation($dateCreation) { $this->dateCreation = $dateCreation; } /** * Get dateCreation * * @return datetime */ public function getDateCreation() { return $this->dateCreation; } /** * Set dateMAJ * * @param datetime $dateMAJ */ public function setDateMAJ($dateMAJ) { $this->dateMAJ = $dateMAJ; } /** * Get dateMAJ * * @return datetime */ public function getDateMAJ() { return $this->dateMAJ; } /** * Set vedette * * @param boolean $vedette */ public function setVedette($vedette) { $this->vedette = $vedette; } /** * Get vedette * * @return boolean */ public function getVedette() { return $this->vedette; } /** * Add tags * * @param App\MetaBundle\Entity\Tag $tags */ public function addTag(\App\MetaBundle\Entity\Tag $tags) { $this->tags[] = $tags; } }
Media (pour l'image de l'article)
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80 namespace App\MetaBundle\Entity; use Doctrine\ORM\Mapping as ORM; /** * App\MetaBundle\Entity\Tag * * @ORM\Table(name="tag") * @ORM\Entity(repositoryClass="App\MetaBundle\Repository\TagRepository") */ class Tag { public function __construct() { $this->articles = new \Doctrine\Common\Collections\ArrayCollection(); } /** * @ORM\ManyToMany(targetEntity="App\BlogBundle\Entity\Article", mappedBy="tags") */ private $articles; /** * @var integer $id * * @ORM\Column(name="id", type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") */ private $id; /** * @var string $libelle * * @ORM\Column(type="string", length=30) */ private $libelle; /** * Get id * * @return integer */ public function getId() { return $this->id; } /** * Set libelle * * @param string $libelle */ public function setLibelle($libelle) { $this->libelle = $libelle; } /** * Get libelle * * @return string */ public function getLibelle() { return $this->libelle; } public function addArticle($article) { $this->articles[] = $article; } public function getArticles() { return $this->articles; } }
Je suis ouvert à toutes remarques qui me permettraient de m'améliorer et en particulier de faire fonctionner correctement ce formulaire qui ne marche pas en modification. Merci.
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184 namespace App\MetaBundle\Entity; use Doctrine\ORM\Mapping as ORM; /** * App\MetaBundle\Entity\Media * * @ORM\Table(name="media") * @ORM\Entity(repositoryClass="App\MetaBundle\Repository\MediaRepository") */ class Media { public function __construct() { $this->setdateAjout(new \DateTime()); } /** * @ORM\Id * @ORM\Column(type="integer") * @ORM\GeneratedValue(strategy="AUTO") */ protected $id; /** * @ORM\Column(type="string", length=30) */ protected $nom; /** * @ORM\Column(type="string", length=255) */ protected $url; /** * @ORM\Column(type="float") */ protected $taille; /** * @ORM\Column(type="datetime") */ protected $dateAjout; /** * @ORM\Column(type="string", length=30) */ protected $type; /** * @ORM\ManyToOne(targetEntity="App\UserBundle\Entity\User") */ protected $membre; /** * Get id * * @return integer */ public function getId() { return $this->id; } /** * Set nom * * @param string $nom */ public function setNom($nom) { $this->nom = $nom; } /** * Get nom * * @return string */ public function getNom() { return $this->nom; } /** * Set url * * @param string $url */ public function setUrl($url) { $this->url = $url; } /** * Get url * * @return string */ public function getUrl() { return $this->url; } /** * Set taille * * @param float $taille */ public function setTaille($taille) { $this->taille = $taille; } /** * Get taille * * @return float */ public function getTaille() { return $this->taille; } /** * Set dateAjout * * @param datetime $dateAjout */ public function setDateAjout($dateAjout) { $this->dateAjout = $dateAjout; } /** * Get dateAjout * * @return datetime */ public function getDateAjout() { return $this->dateAjout; } /** * Set type * * @param string $type */ public function setType($type) { $this->type = $type; } /** * Get type * * @return string */ public function getType() { return $this->type; } /** * Set membre */ public function setMembre(\App\UserBundle\Entity\User $membre) { $this->membre = $membre; } /** * Get membre */ public function getMembre() { return $this->membre; } }
Partager