Partage
  • Partager sur Facebook
  • Partager sur Twitter

[SYMFONY] récupérer variable dropzone

Fichiers uploadés par Dropzone pas pris en compte dans formulaire

15 octobre 2020 à 9:13:03

Hello,

Je me forge petit à petit à Symfony, et je bute sur un problème qui doit sans doute être simple à résoudre.

J'ai l'entity news et l'entity document joint par manytomany

Dans mon formulaire, sans dropzone, tout marche bien pour l'upload. Dans la base, la table de jointure news-document s'enregistre bien quand je valide le formulaire

Avec Dropzone, Les fichiers  sont bien directement uploadé via la méthode "fileUploadHandler", mais ils ne sont pas pris en compte par mon controller "ajout" quand je valide le formulaire (la table de jointure news-document n'enregistre rien) .

Il me faut donc arriver à récupérer les fichiers uploadés par Dropzone (filename ou id), afin que lorsque je valide le formulaire, le controller ajout (ou le controller modifier) puisse récupérer les fichiers uploadés pour que doctrine crée bien un enregistrement sur la table de jointure news-document.

J'ai essayé de résoudre avec OneupUploaderBundle, mais là c'est pire car rien n'esy uploadé.

En espérant qu'un initié à Symfony veuille bien me guider...

Mes fichiers :

Controller "

fileUploadHandler" (qui upload les documents(appelé quand je dépose une document par Dropzone)
/**
  * @Route("/gestionupload", name="gestionupload", methods={"GET", "POST"})
  */
  public function fileUploadHandler(Request $request): Response
   {

    $output = array('uploaded' => false);

   
    $file = $request->files->get('documents');


                // On génère un nouveau nom de fichier
            $extens = $file->guessExtension();

            $fichier = $extens. '/' .md5(uniqid()) . '.' .$file->guessExtension();


        // On copie les fichiers dans le dossier correspondant
        $file->move(
            $this->getParameter('images_directory'). '/' .$extens,
            $fichier
        );

        // On stocke le nom de l'image dans la base de données
            $documen = new Document();
            $documen->setAdressFile($fichier);
            $documen->setExtension($extens);
            $documen->setEnabled($active);
           $documen->setTitle('Document lié à un formulaire non validé');         
                
 $documen->addUser($this->getUser());

           
            $em = $this->getDoctrine()->getManager();
            $em->persist($documen);
            $em->flush();
          
 
       $output['uploaded'] = true;
       $output['fileName'] = $fichier;
    

    return new JsonResponse($output);  
            return $this->redirectToRoute('utilisateur_actu_ajout');
 // 
      
}

Controller "Ajout" (qui enregistre la news lorque je valide le formulaire)

public function modifNews(Request $request, News $actu): Response
    {
        
        $form = $this->createForm(NewsType::class, $actu);

        $form->handleRequest($request);
        if($form->isSubmitted() && $form->isValid()) {

                // On récupère les documents chargés
                $docs = $form->get('documents')->getData();
                $titre = $form->get('title')->getData();
                $active = false;
                // On boucle sur les documents
                foreach($docs as $docu) {
 
    
            // On copie les fichiers dans le dossier correspondant
            $docu->move(
                $this->getParameter('images_directory'). '/' .$extens,
                $fichier
            );
    
            // On stocke le nom de l'image dans la base de données
                $documen = new Document();
                $documen->setAdressFile($fichier);
                $documen->setExtension($extens);
                $documen->setEnabled($active);
                $documen->setTitle($titre);
                
                $actu->addDocument($documen);
    
        }

            $em = $this->getDoctrine()->getManager();
            $em->persist($actu);
            $em->flush();
           

                    return $this->redirectToRoute('utilisateur_actu_home');
    
                

        }


        return $this->render('utilisateur/actu/ajout.html.twig', [
            'actu' => $actu,
            'form' => $form->createView()
        ]);
    }

Mon fichier Twig (extrait) du formulaire + JS Dropzone

div class="row">
    <div class="col">
        {{ form_start(form) }}
    <div class="my-custom-class-for-errors">
        {{ form_errors(form) }}
    </div>

    <div class="row">
        <div class="col">
            {{ form_row(form.title) }}
        </div>
        </div>
  <div action="" class="dropzone">
       <div class="fallback">
               {{ form_row(form.documents) }}
       </div>
</div>
{% if form.enabled is defined %}
  {{ form_row(form.enabled)}}
{% endif %}
                              
          
{{ form_end(form) }}

 {% block javascripts %}

<script src="{{ asset('js/documents.js') }}"></script>
 <script>
Dropzone.autoDiscover = false;

                $(function() {
                    //Dropzone class
                    var myDropzone = new Dropzone(".dropzone", {
                        url: "{{ path('utilisateur_actu_gestionupload')}}",
                        paramName: "documents",
                        maxFilesize: 5,
                        maxFiles: 10,
                        acceptedFiles: "image/*,application/pdf"
                    });

                    $('#startUpload').click(function(){           
                        myDropzone.processQueue();
                    });
                });
                </script> 
{% endblock %}

Merci par avance




  • Partager sur Facebook
  • Partager sur Twitter
15 octobre 2020 à 9:32:50

Salut, j'étais dans ce cas la pour un ancien projet.

Voici ce que j'ai fais : 

vu que les fichiers du dropzone sont enregistrés sur le serveur avant la validation du formulaire, alors lors du traitement du formulaire (méthode add et edit), tu n'a plus cas parcourir le dossier dans lequel tes fichiers sont sauvegardés et pour chacun d'eux tu les sauvegarde en base.

Pour ce faire j'ai créé une entité Dropzone spécialement conçu pour stocker le chemin des fichiers que j'ai lié à mon entité principal.

Ainsi voici un exemple du code que j'utilise :

            $files = glob($this->getParameter('uploads_directory').'cas/'.$upload_rep_id.'/etapes/'.$upload_rep_etape_id.'/ecrans/'.$i.'/active/*.{jpg,JPG,jpeg,JPEG,png,PNG}', GLOB_BRACE);

            usort(
                $files, 
                function($a,$b){
                  return basename($a) <=> basename($b);
                }
            );

            foreach($files as $filename) {
                $dropzone = new Dropzone();
                $dropzone->setEcran($i);
                $dropzone->setPhase('active');
                $dropzone->setNom(basename($filename));
                $etape->addDropzone($dropzone);
                $em->persist($etape);
            }


Glob me récupère tous mes fichiers du dropzone dans le dossier que je veux, ensuite je les tri, et pour chacun d'eux je save

  • Partager sur Facebook
  • Partager sur Twitter
15 octobre 2020 à 10:39:16

Merci beaucoup pour ton message

Pour résumer si j'ai bien compris, tu crée un un dossier spécifique aux documents uploadés d'une news, puis lors de la validation, tu parcours ce fichier pour en récupérer les fichiers afin de les enregistrer dans la base. Est-ce cela?

Par contre je ne comprends pas :"Pour ce faire j'ai créé une entité Dropzone spécialement conçu pour stocker le chemin des fichiers que j'ai lié à mon entité principal."

J'imagine que cette entity Dropzone est crée quand tu upload un document, mais qu'entends tu par "que j'ai lié à mon entité principal" ?

En fait, le problème est de savoir comment récupérer l'entité Dropzone dans mon controller Ajout.

  • Partager sur Facebook
  • Partager sur Twitter
15 octobre 2020 à 11:00:25

Tu as ton entité principale News.

Tu as une entité Dropzone.

Tu créé une relation ManyToOne entre les deux (une News peut avoir plusieurs fichier, mais un fichier n'appartient qu'a une seule News)

Tu dois avoir une bonne architecture pour stocker tes fichiers, un repertoire par News.

En gros voici l'architecture :

- public

    - uploads

       - news

          - 594545

          - 989855

          - etc

Ensuite dans ta fonction upload, tu upload tes fichiers dans le répertoire de la News. Rien de plus

Ensuite dans ta méthode d'ajout, tu parcours le répertoire avec  "glob", pour chaque fichier tu fais un new Dropzone et tu le lie ta relation avec ta new News(), tu persist et tu flush

  • Partager sur Facebook
  • Partager sur Twitter
15 octobre 2020 à 11:35:02

Finalement, cela n'est pas réalisable, dans la mesure où si un utilisateur upload par dropzone un document, quitte le formulaire sans valider, puis remplit un nouveau formulaire sans rapport avec le précédent, il charge tout de même le document du 1er formulaire non validé.

C'est dommage ! En fait, le problème est : comment récupérer le filename du dropzone dans Filetype lors de la validation du formulaire.

-
Edité par AlexandreBERTRAND5 15 octobre 2020 à 14:22:29

  • Partager sur Facebook
  • Partager sur Twitter
16 octobre 2020 à 17:22:12

Un petit up ! Personne n'a utilisé dropzone dans symfony ?

  • Partager sur Facebook
  • Partager sur Twitter
17 octobre 2020 à 10:45:58

Salut

Pour ma part, j'avais mis en place un système d'upload en AJAX avec dropzone sur un projet Symfony. Mais même sans AJAX, tu devrais pouvoir jouer avec les différents événements JavaScript déclenchés sur les zones de dépose, notamment 'drop', cf. ce fichier.

  • Partager sur Facebook
  • Partager sur Twitter
19 octobre 2020 à 10:10:30

AlexandreBERTRAND5 a écrit:

Finalement, cela n'est pas réalisable, dans la mesure où si un utilisateur upload par dropzone un document, quitte le formulaire sans valider, puis remplit un nouveau formulaire sans rapport avec le précédent, il charge tout de même le document du 1er formulaire non validé.

C'est dommage ! En fait, le problème est : comment récupérer le filename du dropzone dans Filetype lors de la validation du formulaire.

-
Edité par AlexandreBERTRAND5 15 octobre 2020 à 14:22:29


Oui mais la on peut pas savoir ce que va faire l'utilisateur, c'est le même cas pour n'importe qu'elle dropzone, vu que c'est le principe du dropzone même, il stocke les fichiers sur le serveur avant la validation du formulaire.

Tu peux te débrouiller pour capturer la fermeture de la fenêtre, ou alors tu crée un cron pour nettoyer tes dossiers qui contiennent des images mais qui n'ont aucune entré dans la table Dropzone.

  • Partager sur Facebook
  • Partager sur Twitter
19 octobre 2020 à 18:21:19

Je pensais que c'était plus simple la dropzone dans symphony! Mes connaissance sont encore trop limitées. Pourtant il suffit de récupérer dans le controller d'ajout de news le nom des fichiers uploadės pour qu'il asscocie à l'entité  news. Possible en json?
  • Partager sur Facebook
  • Partager sur Twitter
20 octobre 2020 à 11:26:19

Merci Ymox je vais essayer de me dépatouiller avec tout ça... Ou alors je retente avec OneupUploaderBundle
  • Partager sur Facebook
  • Partager sur Twitter