Partage
  • Partager sur Facebook
  • Partager sur Twitter

[symfony2]pas de fichier lors de la modification

Sujet résolu
    24 août 2012 à 15:35:46

    Bonjour,

    J'ai suivi la doc officielle sur l'upload des fichier : http://symfony.com/doc/current/cookboo [...] _uploads.html

    Tout fonctionne très bien je crée et supprime des images et des videos.

    Mais lorsque je veux modifier modifier dans le formulaire tous les données apparaissent comme le titre le type (image ou video) ... mais pas le fichier dans le champ Image/Video y a pas le fichier déjà enregistré

    <?php
    public function buildForm(FormBuilder $builder, array $options)
        {
    $builder
                ->add('title', 'text',array('label'=>'Titre :', ))
                ->add('type', 'choice', array( 'choices' => array ('i' => 'Image', 'v' => 'Video'),
                 'label'=>'Type :'))
    
                ->add('file', 'file', array('label'=>'Image/Video :', 'required' => false,))
                 ;
    
        }


    quand je modifier sans sélectionner un fichier dans la bdd je trouve que le champ est NULL c'est évident.

    Quelqu'un peut m'aider ?

    Merci.
    • Partager sur Facebook
    • Partager sur Twitter
      24 août 2012 à 16:58:46

      Alors c'est tout à fait logique puisque ton champ est à null si tu ne mets rien.

      Une solution serait de vérifier que le champ file n'est pas nul lors du traitement de l'update.

      Si il est nul tu mets le nom déjà présent en base.

      Quelque chose dans ce genre là (bien sur ce n'est qu'une piste hein, à adapter ;) ):
      <?php
      $lastFile = $entity->getFile()
      //Tu récupères les données du formulaire 
      
      //là si le champ file est a nul tu lui remets l'ancienne valeur que tu as mis dans une variable avant la récupération des données du formulaire
      if($form['file']->getData() == null){
             $entity->setFile($lastFile);
      }
      
      • Partager sur Facebook
      • Partager sur Twitter
        24 août 2012 à 17:36:57

        Merci !! j'ai repris ton idée et par la suite j'essayé :


        public function editFileAction($id)
            {
                        $em = $this->getDoctrine()->getEntityManager();
                        $file = $em->getRepository('AppMyBundle:Media')->findByFile($id);
                        
        
                $editForm = $this->createForm(new MediaFileType(), $entity);
                        
                $entity->setFile($file);
             }


        le champ est tjrs vide !! et j'ai met les lignes code dans updateFileAction($id) pour la mise a jour et en fait y a pas le fichier valeur null.

        • Partager sur Facebook
        • Partager sur Twitter
          3 septembre 2012 à 11:40:14

          svp personne peut m'aider !!
          • Partager sur Facebook
          • Partager sur Twitter
            3 septembre 2012 à 13:23:34

            Salut !

            Citation : aiafree

            Mais lorsque je veux modifier modifier dans le formulaire tous les données apparaissent comme le titre le type (image ou video) ... mais pas le fichier dans le champ Image/Video y a pas le fichier déjà enregistré

            C'est normal. Si tu fais attention, quand tu mets un fichier dans un <input type="file" />, tu as le chemin absolu du fichier qui s'inscrit dans le champ. Or, par logique, on devrait afficher le chemin absolu du fichier sur le serveur quand on fait référence à un fichier qui y existe. Mais cela représenterait une grosse faille de sécurité. C'est pourquoi l'attribut value d'un <input type="file" /> n'est pas pris en compte par les navigateurs. De plus, ce chemin absolu serveur ne rimerait plus à rien chez le client, et le chemin absolu client ne servirait à rien au serveur.

            En complément de ce sujet, le code ci-dessous n'y figure pas, mais pourrait t'intéresser tout autant. En plus d'un champ <input type="file" />, il affiche l'image, quand tu édites. Malheureusement, je n'ai pas de truc pour faire apparaître une image extraite d'une vidéo.
            {% block ysoft_picture_widget %}
            {% spaceless %}
            	<div class="box blue picture" id="{{ form.parent.get('label') ~ '_' ~ form.get('name') }}">
            	{% if (form.file_name.vars.value != '') %}
            		{{ html_image(
            				form.file_path.vars.value|default(constant('YSoft\\MediaBundle\\Entity\\Picture::UPLOAD_DIR') ~ '/') ~ form.file_name.vars.value,
            				{'title': form.picture_title.vars.value, 'alt': form.alt.vars.value|default('ysoft_media.default.common'|trans), 'type': 'thumbnail'}
            		)|raw }}
            		{% set prototype = form_widget(form.file) %}
            	{% else %}
            		{% if auth_key is defined and template_id is defined %}
            		<input type="hidden" name="params" value="{&quot;auth&quot;:{&quot;key&quot;:&quot;{{ auth_key }}&quot;},&quot;template_id&quot;:&quot;{{ template_id }}&quot;,&quot;redirect_url&quot;:&quot;{{ path('_welcome') }}&quot;}" />
            		{% endif %}
            		{% set prototype = form_widget(form.file) %}
            		{{ prototype|raw }}
            	{% endif %}
            		{{ form_rest(form) }}
            	{% if in_collection is defined  %}
            		<div class="{{ form.parent.get('name') }} remover"></div>
            	{% else %}
            		<div class="{{ form.parent.get('name') }} resetter"{% if auth_key is defined and template_id is defined %} data-prototype-empty="&lt;input type=&quot;hidden&quot; name=&quot;params&quot; value=&quot;{&amp;quot;auth&amp;quot;:{&amp;quot;key&amp;quot;:&amp;quot;{{ auth_key }}&amp;quot;},&amp;quot;template_id&amp;quot;:&amp;quot;{{ template_id }}&amp;quot;,&amp;quot;redirect_url&amp;quot;:&amp;quot;{{ url('_welcome') }}&amp;quot;}&quot; /&gt;{{ prototype|escape }}" data-prototype-chosen=""{% endif %}></div>
            	{% endif %}
            	</div>
            {% endspaceless %}
            {% endblock %}
            

            -
            Edité par Ymox 1 avril 2013 à 15:34:11

            • Partager sur Facebook
            • Partager sur Twitter
              3 septembre 2012 à 16:19:13

              voila mes 2 fonctions actions du contrôleur :


              <?php
                      
                      
                      public function editFileAction($id)
                  {
              
                      $em = $this->getDoctrine()->getEntityManager();
                      $entity = $em->getRepository('AppRiverBundle:Media')->find($id);
                              
                      if (!$entity) {
                          throw $this->createNotFoundException('Unable to find Media entity.');
                      }
                    
                      $editForm = $this->createForm(new MediaFileType(), $entity);
                              
                    
                      return $this->render('AppRiverBundle:Media:editfile.html.twig', array(
                          'entity'      => $entity,
                          'edit_form'   => $editForm->createView(),
                      ));
                  }
                      
                
                
                  public function updateFileAction($id)
                  {
                      $em = $this->getDoctrine()->getEntityManager();
              
                      $entity = $em->getRepository('AppRiverBundle:Media')->find($id);
                              
                      
                              
              
                      if (!$entity) {
                          throw $this->createNotFoundException('Unable to find Media entity.');
                      }
              
                      $editForm   = $this->createForm(new MediaFileType(), $entity);
                      $deleteForm = $this->createDeleteForm($id);
              
                      $request = $this->getRequest();
              
                      $editForm->bindRequest($request);
                      if ($editForm->isValid()) {
                                  $entity->uploadFile();
                          $em->persist($entity);
                          $em->flush();
              
                          return $this->redirect($this->generateUrl('app_show', array('id' => $id)));
                      }
              
                      return $this->render('AppRiverBundle:Media:editfile.html.twig', array(
                          'entity'      => $entity,
                          'edit_form'   => $editForm->createView(),
                          'delete_form' => $deleteForm->createView(),
                      ));
                      }
              • Partager sur Facebook
              • Partager sur Twitter
                3 septembre 2012 à 16:46:50

                Serai-il possible d'avoir aussi l'entité Media ?
                • Partager sur Facebook
                • Partager sur Twitter
                  3 septembre 2012 à 16:52:59

                  <?php
                  
                  
                  namespace App\RiverBundle\Entity;
                  
                  use Doctrine\ORM\Mapping as ORM;
                  use Symfony\Component\Validator\Constraints as Assert;
                  
                  use Symfony\Component\HttpFoundation\File\File;
                  
                  umask(0000);
                  /**
                   * App\RiverBundle\Entity\Media
                   * @ORM\HasLifecycleCallbacks
                   * @ORM\Table(name="media")
                   */
                  class Media
                  {
                      /**
                       * @var integer $id
                       *
                       * @ORM\Column(name="id", type="integer", nullable=false)
                       * @ORM\Id
                       * @ORM\GeneratedValue(strategy="SEQUENCE")
                       * @ORM\SequenceGenerator(sequenceName="media_id_seq", allocationSize="1", initialValue="1")
                       */
                      private $id;
                  
                      /**
                       * @var text $title
                       *
                       * @ORM\Column(name="title", type="text", nullable=true)
                       */
                      private $title;
                  
                      /**
                       * @var text $type
                       *
                       * @ORM\Column(name="type", type="text", nullable=true)
                       */
                      private $type;
                  
                       /**
                           * @ORM\Column(type="string", length=255, nullable=true)
                       * @Assert\File( 
                           * maxSize="10000000",
                       * mimeTypes = {"image/jpeg", "image/png", "image/gif", "image/jpg", "video/ogg"},
                           * mimeTypesMessage = "le fichier chosit doit etre unr image ou une video"
                           * )
                       */
                          private $file;
                  
                      /**
                       * @var text $comment
                       * @ORM\Column(name="comment", type="text", nullable=true)
                       */
                      private $comment;
                  
                      /**
                       * @var integer $partie
                       *
                       * @ORM\Column(name="partie", type="integer", nullable=true)
                       */
                      private $partie;
                  
                  
                  
                  
                      /**
                       * Get id
                       *
                       * @return integer 
                       */
                      public function getId()
                      {
                          return $this->id;
                      }
                  
                      /**
                       * Set title
                       *
                       * @param text $title
                       */
                      public function setTitle($title)
                      {
                          $this->title = $title;
                      }
                  
                      /**
                       * Get title
                       *
                       * @return text 
                       */
                      public function getTitle()
                      {
                          return $this->title;
                      }
                  
                      /**
                       * Set type
                       *
                       * @param text $type
                       */
                      public function setType($type)
                      {
                          $this->type = $type;
                      }
                  
                      /**
                       * Get type
                       *
                       * @return text 
                       */
                      public function getType()
                      {
                          return $this->type;
                      }
                  
                      /**
                       * Set file
                       *
                       * @param text $file
                       */
                      public function setFile($file)
                      {
                          $this->file = $file;
                      }
                  
                      /**
                       * Get file
                       *
                       * @return text 
                       */
                      public function getFile()
                      {
                          return $this->file;
                      }
                  
                      /**
                       * Set comment
                       *
                       * @param text $comment
                       */
                      public function setComment($comment)
                      {
                          $this->comment = $comment;
                      }
                  
                      /**
                       * Get comment
                       *
                       * @return text 
                       */
                      public function getComment()
                      {
                          return $this->comment;
                      }
                  
                      /**
                       * Set partie
                       *
                       * @param integer $partie
                       */
                      public function setPartie($partie)
                      {
                          $this->partie = $partie;
                      }
                  
                      /**
                       * Get partie
                       *
                       * @return integer 
                       */
                      public function getPartie()
                      {
                          return $this->partie;
                      }
                  
                      
                  
                  
                  //upload le fichier
                  
                  
                  
                      
                      public function getWebPath()
                      {
                          return null === $this->file ? null : $this->getUploadDir().'/'.$this->file;
                      }
                          
                     
                      protected function getUploadRootDir()
                      {
                          
                           return __DIR__.'/../../../../web/'.$this->getUploadDir();
                      }
                  
                      public function getUploadDir()
                      {
                         
                             return 'Test/';
                      }
                      
                      public function uploadFile()
                      {
                          
                          if (null === $this->file) {
                           return;
                          } 
                  
                          
                          $this->file->move($this->getUploadRootDir(), $this->file->getClientOriginalName());
                  
                     
                           $this->file = $this->file->getClientOriginalName();
                        
                      }
                  
                      public function removeFile()
                      {
                          if ($file = $this->getWebPath()) {
                              unlink($file);
                      }
                          
                  }
                  }
                  

                  • Partager sur Facebook
                  • Partager sur Twitter
                    3 septembre 2012 à 16:58:50

                    D'accord. Mais avec les getters et setters de $file, et avec la coloration syntaxique, ce serait parfait. Edite ton précédent message plutôt que d'en créer un autre.
                    • Partager sur Facebook
                    • Partager sur Twitter
                      3 septembre 2012 à 17:05:51

                      Citation : Ymox

                      D'accord. Mais avec les getters et setters de $file, et avec la coloration syntaxique, ce serait parfait. Edite ton précédent message plutôt que d'en créer un autre.




                      C'est bon j'ai modifier le code. Merci
                      • Partager sur Facebook
                      • Partager sur Twitter
                        3 septembre 2012 à 17:08:10

                        <?php
                            /**
                             * @ORM\Column(type="string", length=255, nullable=true)
                             * @Assert\File( 
                             *     maxSize="10000000",
                             *     mimeTypes={"image/jpeg", "image/png", "image/gif", "image/jpg", "video/ogg"},
                             *     mimeTypesMessage="le fichier chosi doit etre une image ou une vidéo"
                             * )
                             */
                            private $file;
                        
                        Il n'y a pas quelque chose qui te choque, là ?
                        Tu veux persister ton fichier en base de données !? Comme une chaîne de 255 caractères, en plus !!?
                        • Partager sur Facebook
                        • Partager sur Twitter
                          3 septembre 2012 à 17:44:15

                          Oui le type est "file" j'ai enlever cette colonne

                          dans l'actionUptadeFile($id)
                          <?php
                          $lastFile = $entity->getFile();		 
                          $entity->setFile($lastFile);
                          


                          rien ne change le champ file n'a aucun fichier :/
                          • Partager sur Facebook
                          • Partager sur Twitter
                            3 septembre 2012 à 17:50:44

                            Regarde mon getFile dans le sujet où je t'ai fourni le code de mon MediaBundle, il n'est pas aussi simple que le tien.
                            • Partager sur Facebook
                            • Partager sur Twitter
                              4 septembre 2012 à 10:20:51

                              Merci j'ai essayé mais ça ne marche pas, ça existe des bundles tiers pour gérer mes uploads ainsi que les images (visualisation ....) ?
                              • Partager sur Facebook
                              • Partager sur Twitter
                                4 septembre 2012 à 11:03:15

                                Je peux regarder pour te fournir mon MediaBundle, il y a aussi SonataMediaBundle et VichUploadBundle, à toi de voir.

                                Au passage, tu peux me montrer ton nouveau getFile ?

                                Autre question : tu dis que ça ne marche pas, qu'as-tu comme erreur ? Aucune, mais toujours le même problème ?
                                Montre aussi ton MediaType, s'il te plaît.
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  4 septembre 2012 à 11:28:23

                                  Merci, ca marche pas lorsque je modifie sans sectionner une image le champ file reste nul !!

                                  mon getFile est le suivant :
                                  /**
                                       * Get file
                                       *
                                       * @return object 
                                       */
                                      public function getFile()
                                      {
                                          return $this->file;
                                      }
                                  

                                  ton entité et la mienne sans différente j'ai les propriétés : id ,title, file, comment, partie et type mes méthodes aussi qui permettent d'uploader un fichier !!

                                  class MediaFileType extends AbstractType
                                  {
                                  
                                  
                                       public function buildForm(FormBuilder $builder, array $options)
                                      {
                                          
                                         $builder
                                              ->add('title', 'text',array('label'=>'Titre :', ))
                                              ->add('type', 'choice', array( 'choices' => array ('i' => 'Image', 'v' => 'Video'),
                                               'label'=>'Type :'))
                                  
                                              ->add('file', 'file', array('label'=>'Image/Video :', 'required' => false, "attr" => array(
                                                  "multiple" => "multiple",
                                                  "name" => "files[]")))
                                              
                                              ->add('partie', 'integer', array('label'=>'Partie :', ))
                                  
                                                
                                         
                                       
                                  
                                          ;
                                  
                                      } 
                                  
                                      public function getName()
                                      {
                                          return 'app_riverbundle_mediatype';
                                      }
                                      public function getDefaultOptions(array $options)
                                      {
                                      return array(
                                          'validation_groups' => array('registration'),
                                          'data_class' => 'App\RiverBundle\Entity\Media',
                                      );
                                      }
                                  

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    4 septembre 2012 à 11:39:59

                                    Tu n'as pas adapté le getFile, il est encore comme avant. Ce ne sont pas les annotations qui feront effet, là.

                                    Citation : Ymox

                                    Montre aussi ton MediaType, s'il te plaît.

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      4 septembre 2012 à 11:52:43

                                      Dans ton exemple tu as fais ceci :

                                      public function getFile()
                                          {
                                              /* Note that the file is taken relatively to the web root. The initial
                                               * slash for the path of the picture is to be removed, else the server
                                               * will return a 500 error */
                                              return (($this->file_path == NULL) && ($this->file_name != NULL)
                                                      ? new UploadedFile(
                                                              $this->getUploadRootDir() . '/' . $this->file_name,
                                                              $this->file_name)
                                                      : NULL);
                                          }


                                      je n'ai pas file_name, file-path dans mon entité du coup j'improvise ... et je ne sais pas quoi mettre !!
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        4 septembre 2012 à 11:58:34

                                        Un peu de lecture à propos de l'attribut HTML multiple pour les <input type="file" />

                                        Si tu n'enregistres pas le nom de ta photo/vidéo, comment la récupères-tu pour l'afficher !? o_O

                                        -
                                        Edité par Ymox 16 avril 2013 à 8:10:20

                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          4 septembre 2012 à 12:21:51

                                          mes images et les videos prennent le nom du fichier uploadé, du :

                                          $this->file->getClientOriginalName()


                                          et je les affiche sous Twig :

                                          <img src="{{ asset(entity.file.getWebPath()) }}"/>
                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            4 septembre 2012 à 12:34:23

                                            D'accord. Mais du coup, comment reconstruis-tu le fichier ? Il te faut bien son nom (et éventuellement son chemin), non ? Et il est/était enregistré où dans la base de données ?
                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              4 septembre 2012 à 12:44:01

                                              oui il enregistrer dans la base de données si le fichier s'appelle toto.jpg dans le disque dur il pend le même nom dans le champ file de la table (toto.jpg). son chemin (path) c'est : getWebPath(). voila quoi tout va bien sauf l'action editFile et UpdateFile qui ne prend pas en compte la valeur du champ (aucun fichier sélectionner)!!

                                              remarque la méthode getFile() récupère le nom du fichier : toto.jpg !!
                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                                4 septembre 2012 à 12:51:28

                                                On va faire un essai : modifie la méthode getFile comme suit :
                                                <?php
                                                public function getFile()
                                                {
                                                    var_dump($this->file);
                                                    throw new \Exception('Stopped on dev request');
                                                    return $this->file;
                                                }
                                                
                                                Et tu me dis ce qui s'affiche en haut à gauche de l'écran, soit le résultat du var_dump, quand tu accèdes au formulaire d'édition de ton media.

                                                Citation : aiafree

                                                remarque la méthode getFile() récupère le nom du fichier : toto.jpg !!

                                                Et non un objet UploadedFile comme reçu après soumission du formulaire. Normal. C'est pour ça que je ne persiste pas le fichier directement (même comme une chaîne de caractères), mais son nom et son chemin, et que mon getFile est plus conséquent que le tien.

                                                Edit

                                                <?php
                                                    public function uploadFile()
                                                    {
                                                        
                                                        if (null === $this->file) {
                                                         return;
                                                        } 
                                                
                                                        
                                                        $this->file->move($this->getUploadRootDir(), $this->file->getClientOriginalName());
                                                
                                                   
                                                         $this->file = $this->file->getClientOriginalName();
                                                      
                                                    }
                                                
                                                Ça ne te choque pas, toi, de changer ce qu'il y a dans $file, soit un objet, et d'y mettre une chaîne de caractères ? Je sais que PHP n'est pas fortement typé, mais avec Symfony et Doctrine, il te faut tout de même faire attention à ce genre de choses. Je pense que tu as pris l'exemple du cookbook de Symfony, mais que tu l'as modifié à ta sauce ? J'espère que tu savais ce que tu faisais…
                                                • Partager sur Facebook
                                                • Partager sur Twitter
                                                  4 septembre 2012 à 14:09:40

                                                  En effet, le tableau m'affiche : string(10) "toto.jpg", j'ai repris l'exemple du CookBook de sf2 !! le type du champ file dans /Resources/config/doctrine/metadata/orm/ est "text" mais avec les asset je peux afficher l'image uploadé !!
                                                  • Partager sur Facebook
                                                  • Partager sur Twitter
                                                    4 septembre 2012 à 14:27:49

                                                    Sincèrement, je te conseille d'enregistrer le nom du fichier dans une autre propriété que $file, sans quoi tu auras des soucis à n'en plus finir. $file doit contenir un objet de type UploadedFile, ou être nul, mais il ne doit jamais contenir une chaîne de caractères, c'est déjà asssez étrange que Symfony ne te crie pas dessus quand il remplit ton formulaire d'édition.

                                                    Tu as repris le code du cookbook, mais tu y as ajouté cette ligne 215 qui est une aberration. Ta propriété $file n'est plus l'objet représentant ton fichier, mais simplement son nom, après cette ligne. Alors oui, ça peut fonctionner en bricolant comme tu l'as fait, mais c'est pas propre.

                                                    Ne persiste pas la propriété $file
                                                    Mets le nom du fichier dans une autre propriété que tu persistes, celle-là
                                                    Et reconstruit la propriété $file (new UploadedFile) à partir de son nom et de son chemin.

                                                    Je t'ai donné un code peut-être compliqué, certainement pas très commenté, mais fonctionnel, dans l'autre sujet. Tout comme le code du cookbook – à un petit détail près qu'il ne joue pas dans tous les cas, mais dans le tien, ça ne devrait pas être un problème.

                                                    Fais ces modifications, teste, et reviens si tu as encore un souci, avec le nouveau code englobé dans une balise <secret></secret>

                                                    Edit (08/09/2012)

                                                    Souci apparemment réglé (par MP), mais comme je ne peux pas mettre moi le sujet en résolu…

                                                    Edit (12.11.2012)

                                                    Peut-être que cette entrée dans la FAQ vous sera utile

                                                    -
                                                    Edité par Ymox 16 avril 2013 à 8:51:17

                                                    • Partager sur Facebook
                                                    • Partager sur Twitter

                                                    [symfony2]pas de fichier lors de la modification

                                                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                                    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                                    • Editeur
                                                    • Markdown