Bonjour,

Voila je rencontre un petit problème avec mon code.

Ce que je fais

J'ai un formulaire video avec un bouton qui ouvre une modal pour sélectionner une video qui se trouve dans un dossier. J'utilise Finder component de Symfony. Je suis sur Symfony 4.3.
Mon dossier est à la racine de mon projet (nom dossier = tmpfiles). Ce dossier va contenir plusieurs vidéos, qui seront transferées dans un autre dossier (j'en suis pas encore là).
Le problème c'est quand je test, j'ai une erreur "Variable "finder" does not exist."
Je vous partage ma fonction de mon controller et ma vue ainsi que le chemin qui mène au dossier dans service.yaml.

ma fonction dans VideoController (ps: j'ai le reste du formulaire dans ce controller)

public function finder ()
    {
        //methode 1
        $uploadsDir = $this->getParameter('uploads_directory');

        $finder = false === file_exists($uploadsDir)
            ? []
            : (new Finder())->files()->in($uploadsDir)
        ;

        return $this->render('video/video.html.twig', [
            'finder' => $finder,
        ]);

    }

ma vue

{% block body %}
    <div class="container">
        <div class="row">
            <div class="col text-center">
                <div class="col-xs-12">
                    <h1>Créer une vidéo</h1>

                    {{ form_start(form) }}
                    {{ form_row(form.titre, {'label': 'Titre : ', 'attr' :{'placeholder': 'titre ...' }}) }}

                    {{ form_row(form.date) }}
                    {{ form_row(form.descriptif, {'label': 'Description : ', 'attr' :{'placeholder': 'description ...' }}) }}
                    {{ form_row(form.duree, {'label': 'Durée : ' }) }}
                    {{ form_row(form.Projet, {'label': 'Projets : ' }) }}
                    {{ form_row(form.Hashtag, {'label': 'Hashtags : ' }) }}
                    {{ form_row(form.file) }}

                    <!-- The Modal -->
                    <aside class="modal" id="myModal">
                        <div class="modal-dialog">
                            <div class="modal-content">
                                <!-- Modal Header -->
                                <div class="modal-header">
                                    <h4 class="modal-title">Parcours des dossiers</h4>
                                    <button type="button" class="close" data-dismiss="modal">&times;</button>
                                </div>
                                <!-- Modal body -->
                                <div class="modal-body">
                                    <div class="row">
                                        <div class="col">
                                            <h2>Open file</h2>
                                            <hr>
                                        </div>
                                    </div>
                                    {# Contenu de la modal  #}

                                    {% for file in finder %}
                                        <li> {{ dump() }}
                                            <a href="/tmpfiles/{{ file.relativePathName }}">
                                                {{ file.relativePathName }}
                                            </a>
                                        </li>
                                        {% endfor %}
                                    {# fin du contenu modal#}
                                    <div class="row" style="display: none" id="alert-box">
                                        <div class="col">
                                            <div class="alert alert-danger">File does not longer exists.</div>
                                        </div>
                                    </div>
                                    <div class="browser"></div>

                                </div>
                                <!-- Modal footer -->
                                <div class="modal-footer">
                                    <button type="button" class="btn btn-primary">Valider</button>
                                    <button type="button" class="btn btn-danger" data-dismiss="modal">Close</button>
                                </div>
                            </div>
                        </div>
                    </aside>

                    {#bouton parcourir les fichiers #}
                    <button type="button" class="inline" data-toggle="modal" data-target="#myModal" id="suivant" >
                        Choisir un fichier vidéo
                    </button>
                    <!-- Button to Open the Modal -->
                    <button type="submit" class="btn btn-success">Enregister </button>
                    {{ form_end(form) }}
                </div>
            </div>
        </div>
    </div>
    <!-- Include our script files -->
    <script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
    <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js" type="text/javascript"></script>
    <script type="text/javascript" src="https://code.jquery.com/jquery-1.12.0.min.js"></script>

    {% block javascripts %}

    {% endblock %}
{% endblock %}

service.yaml

parameters:
    uploads_directory: '%kernel.project_dir%/tmpfiles'

6 réponses


Bonjour.
Essaies tout simplement de remplacer :

$finder = false === file_exists($uploadsDir)
            ? []
            : (new Finder())->files()->in($uploadsDir)
        ;

Par :

$finder = !file_exists($uploadsDir) ? [] : (new Finder())->files()->in($uploadsDir);

Ta première erreur est de définir la variable à false dès le début avant le test.
Ta secondaire erreur est d'avoir inversé ta condition, tu dis :
Si le fichier existe renvois un tableau vide sinon renvois la liste des fichiers.
De plus que tu fais une autre erreur, tu devrais plutôt utiliser la fonction is_dir au lieu de file_exists pour vérifier que le dossier existe, ce que permet la fonction is_dir contrairement à la fonction file_exists qui ne permet que de vérifier l'existence d'un fichier.

Lucie A
Auteur

Bonjour,
Tout d'abord merci pour ta réponse. J'ai effectué les modifications indiquées ( + j'ai employé is_dir du coup).
Malheureusement j'ai toujours la même erreur "Variable "finder" does not exist."
J'ai tenté de dump la variable finder dans ma boucle for de ma vue (je sais pas si c'est une bonne solution) mais la page d'erreur reste telle quelle.
Je loupe quelque chose mais je ne vois pas...

Montres le code modifié du controller.
Autre chose, si tu veux que les fichiers Javascripts soient inclues dans le block javascripts dde ton layout, tu devrais placer les scripts à l'intérieur des balises d'inclusions et non avant, soit :

    {% block javascripts %}
        <script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
        <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"></script>
        <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js" type="text/javascript"></script>
        <script type="text/javascript" src="https://code.jquery.com/jquery-1.12.0.min.js"></script>
    {% endblock %}

Au lieu de :

<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
    <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js" type="text/javascript"></script>
    <script type="text/javascript" src="https://code.jquery.com/jquery-1.12.0.min.js"></script>

    {% block javascripts %}

    {% endblock %}

Par contre, pourquoi tu inclues plusieurs fois jQuery à la suite au lieu d'une seule fois ?
Car là tu charges la librairie 4 fois, tu devrais donc plutôt avoir :

    {% block javascripts %}
        <script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
        <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js" type="text/javascript"></script>
    {% endblock %}
Lucie A
Auteur

Pour le js j'ai fait un truc à l'arrache shamed...
Je fais plus simple, voici l'intégral du controller :

<?php

namespace App\Controller;

use App\Entity\Video;
use App\Form\VideoType;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Finder\Finder;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class VideoController extends AbstractController
{
    /**
     * @Route("/admin/video", name="video_video")
     * @param Request $request
     * @return RedirectResponse|Response
     */
    public function register(Request $request)
    {
        $video = new Video();
        $form = $this->createForm(VideoType::class, $video);

        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {
          // On enregistre la video dans la base
            $em = $this->getDoctrine()->getManager();
            $em->persist($video);
            $em->flush();

            return $this->redirectToRoute('video_video');
        }
        return $this->render(
          'video/video.html.twig',
            array('form' => $form->createView())
        );

    }

    public function finder ()
    {
        $uploadsDir = $this->getParameter('uploads_directory');

        $finder = !is_dir($uploadsDir) ? [] : (new Finder())->files()->in($uploadsDir);

        return $this->render('video/video.html.twig', [
            'finder' => $finder,
        ]);
    }
}

En fait, ton problème me parait normal ou alors c'est que j'ai mal compris.
Au moment ou tu charges la vue que tu montres, la variable ne peux pas exister si tu y fais appel via de l'ajax non ?
Car d'après ce que je vois dans ton controller, tu as la méthode register qui renvoie la variable form et la méthode finder qui renvoit la variable finder, et ce pour la même vue concernant les deux méthodes, sauf que tu ne peux pas faire appel aux deux méthodes du même controller en même temps.
Donc comme je disais au moment ou tu charges ta page, tu as la variable form qui est renvoyée via la méthode register, mais la variable finder ne peux pas être définie à ce moment là.

Lucie A
Auteur

Je vois ce que tu veux dire.
Mon objectif est d'insérer la liste du dossier dans une modale, pour qu'a la selection d'un des fichiers, la modale se ferme et on voit le nom du fichier dans un champ du form. Il m'a parut logique que je passe dans le même controller et vue.
Ducoup pour que ça soit correct : peut-on séparer tout ça ?