Bonjour,

Avant tout, je sais, ce sujet existe déjà sur un autre site, mais je préfère ouvrir plusieurs discussions sur plusieurs forums pour avoir plusieurs sons de cloche...

Ce sujet a peut-être déjà été traité, mais je préfère en créer un autre pour mon problème.

J'ai mis en place un système d'échange de fichiers entre mon entreprise et nos clients.

J'ai donc un formulaire d'ajout d'un document avec un champ file en relation OneToOne.

Mon problème est le suivant, lorsque j'ajoute un nouveau document, le fichier n'est pas uploadé, et donc persisté en base, je suis obligé de le modifier et de rajouter le fichier à uploader pour qu'il soit persisté, ce qui, vous en conviendrez est assez fastidieux et peu intuitif pour nos clients...

J'ai suivi à la lettre un tuto sur l'upload avec les événements Doctrine, et ça ne marche pas.

Voici mon entité Document (représentant le fichier à uploader) :

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
 
<?php
 
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
 
namespace Asmolding\Bundle\Entity;
 
/**
 * Description of Image
 *
 * @author SGOURMELON
 */
 
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Validator\Constraints as Assert;
 
/**
 * @ORM\Entity
 * @ORM\HasLifecycleCallbacks
 */
class Document
{
  /**
   * @ORM\Column(name="id", type="integer")
   * @ORM\Id
   * @ORM\GeneratedValue(strategy="AUTO")
   */
  private $id;
 
  /**
   * @ORM\Column(name="extension", type="string", length=255)
   */
  private $extension;
 
  /**
   * @ORM\Column(name="alt", type="string", length=255)
   */
  private $alt;
 
 /**
  *
  * @var type 
  */
  private $file;
 
   // On ajoute cet attribut pour y stocker le nom du fichier temporairement
  private $tempFilename;
 
  // On modifie le setter de File, pour prendre en compte l'upload d'un fichier lorsqu'il en existe déjà un autre
  public function setFile(UploadedFile $file)
  {
    $this->file = $file;
 
    // On vérifie si on avait déjà un fichier pour cette entité
    if (null !== $this->extension) {
      // On sauvegarde l'extension du fichier pour le supprimer plus tard
      $this->tempFilename = $this->extension;
 
      // On réinitialise les valeurs des attributs url et alt
      $this->extension = null;
      $this->alt = null;
    }
  }
 
  /**
   * @ORM\PrePersist()
   * @ORM\PreUpdate()
   */
  public function preUpload()
  {
    // Si jamais il n'y a pas de fichier (champ facultatif)
    if (null === $this->file) {
      return;
    }
 
    // Le nom du fichier est son id, on doit juste stocker également son extension
    // Pour faire propre, on devrait renommer cet attribut en « extension », plutôt que « url »
    $this->extension = $this->getFile()->guessExtension();
 
    // Et on génère l'attribut alt de la balise <img>, à la valeur du nom du fichier sur le PC de l'internaute
    $this->alt = $this->getFile()->getClientOriginalName();
  }
 
  /**
   * @ORM\PostPersist()
   * @ORM\PostUpdate()
   */
  public function upload()
  {
    // Si jamais il n'y a pas de fichier (champ facultatif)
    if (null === $this->file) {
      return;
    }
 
    // Si on avait un ancien fichier, on le supprime
    if (null !== $this->tempFilename) {
      $oldFile = $this->getUploadRootDir().'/'.$this->id.'.'.$this->tempFilename;
      if (file_exists($oldFile)) {
        unlink($oldFile);
      }
    }
 
    // On déplace le fichier envoyé dans le répertoire de notre choix
    $this->file->move(
      $this->getUploadRootDir(), // Le répertoire de destination
      $this->alt   // Le nom du fichier à créer, ici « id.extension »
    );
  }
 
  /**
   * @ORM\PreRemove()
   */
  public function preRemoveUpload()
  {
    // On sauvegarde temporairement le nom du fichier, car il dépend de l'id
    $this->tempFilename = $this->getUploadRootDir().'/'.$this->id.'.'.$this->extension;
  }
 
  /**
   * @ORM\PostRemove()
   */
  public function removeUpload()
  {
    // En PostRemove, on n'a pas accès à l'id, on utilise notre nom sauvegardé
    if (file_exists($this->tempFilename)) {
      // On supprime le fichier
      unlink($this->tempFilename);
    }
  }
 
  public function getUploadDir()
  {
    // On retourne le chemin relatif vers l'image pour un navigateur
    return 'uploads/docs';
  }
 
  protected function getUploadRootDir()
  {
    // On retourne le chemin relatif vers l'image pour notre code PHP
    return __DIR__.'/../../../../web/'.$this->getUploadDir();
  }
 
  // On récupère le chemin pour afficher l'image
  public function getWebPath()
  {
    return $this->getUploadDir().'/'.$this->getAlt();
  }
 
  // Getters et setters
  function getId() {
      return $this->id;
  }
 
  function getExtension() {
      return $this->extension;
  }
 
  function getAlt() {
      return $this->alt;
  }
 
  public function getFile()
  {
    return $this->file;
  }
 
  function setId($id) {
      $this->id = $id;
  }
 
  function setExtension($extension) {
      $this->extension = $extension;
      return $this;
  }
 
  function setAlt($alt) {
      $this->alt = $alt;
  }
}
Mon formulaire :

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
 
<?php
 
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
 
namespace Asmolding\Bundle\Form\Type;
 
use Asmolding\Bundle\Entity\CompanyRepository;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
 
/**
 * Description of FormFtp
 *
 * @author SGOURMELON
 */
class FormFtpType extends AbstractType {
 
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('fileType', 'choice', array('choices' => array(
                        'Commande' => 'COMMANDE',
                        'AR Commande' => 'AR COMMANDE', 
                        'Planning Général' => 'PLANNING GENERAL', 
                        'CAO' => 'CAO',
                        'Facture' => 'FACTURE', 
                        'Cahier des Charges' => 'CAHIER DES CHARGES',
                        'Photos' => 'PHOTOS',
                        'Vidéos' => 'VIDEOS',
                        'Autres' => 'AUTRES'
                    )))
                ->add('comment', 'textarea')
                ->add('document', new FormDocumentType(), array('required' => false));
    }
 
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
      $resolver->setDefaults(array(
        'data_class' => 'Asmolding\Bundle\Entity\TransferHistory',  
      ));
    }
 
    public function getName() {
       return 'form_ftp'; 
    }
 
 
 
}
Et mon controller

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
 
/*
* Cette méthode est appelée par une autre méthode de gestion, peu importante ici.
*/
public function addFTPAction($form){
 
        $em = $this->getDoctrine()->getManager();
 
        $from = $this->getUser();
        $companyFrom = $from->getCompany();
        $senderName = $from->getNameFirstname();
        $project = $form->get('project')->getData();
        $projectName = $project->getName();
        $mold = $form->get('mold')->getData();
        $moldName = $mold->getName();
 
        $ftp = new TransferHistory();
 
        $ftp->setCompanyFrom($companyFrom);
        $ftp->setFrom($from);
        $ftp->setSenderName($senderName);
        $ftp->setCompanyTo($form->get('companyTo')->getData());
        $ftp->setTo($form->get('to')->getData());
        $ftp->setProject($project);
        $ftp->setProjectName($projectName);
        $ftp->setMold($mold);
        $ftp->setMoldName($moldName);
        $ftp->setFileType($form->get('fileType')->getData());
        $ftp->setComment($form->get('comment')->getData());
        $ftp->setDate(new DateTime);
 
        $em->persist($ftp);
        $em->flush();
    }
Si quelqu'un a une idée...

Je précise également que je rencontre le même problème avec l'upload d'images pour mes projets, ce qui est normal puisque c'est le même tuto que j'ai suivi.

Merci,

SG