Problème de renommage au moment de l'import de fichier - Composant elearning Shika

Réduire
X
  • Filtrer
  • Heure
  • Afficher
Tout effacer
nouveaux messages

  • Problème de renommage au moment de l'import de fichier - Composant elearning Shika

    Bonjour,

    Je rencontre un problème avec un composant d’elearning Shika.

    Avec ce composant, il est possible de créer des leçons, et pour chaque leçon d’associer un ou plusieurs fichiers (par exemple des fichiers PDF ou PPTX).
    Le problème est que les fichiers sont randomisés au moment de l’import sur le site.
    L’import se fait via le composant.
    Si mon fichier se nomme : « fichier.pdf », quand je vais sur l’interface utilisateur frontend (en tant qu'étudiant), je vois bien dans la section des fichiers à télécharger le nom correct de mon fichier, mais quand je le télécharge, il est intitulé par exemple « 2247054353.pdf ».

    Sur le FTP, le fichier se retrouve dans le répertoire / media / com_tjlms / lessons

    Je pense qu’il faudrait modifier le fichier qui traite de l’import pour agir sur ce point, car c’est au moment de l’import que le fichier est renommé. Mais je ne vois pas où chercher…

    Voici par exemple une partie du fichier fileupload.json.php qui se trouve dans les controllers du composant :

    public function addTableEntries()
    {
    $input = JFactory::getApplication()->input;
    $post = $input->post;
    $uploadPathData = $mediaData = [];

    $testData = $post->get('test', array(), 'ARRAY');
    $lessonData = $post->get('lesson', array(), 'ARRAY');
    $format = $uploadPathData['mediaformat'] = $post->get('mediaformat', '', 'STRING');
    $subformat = $uploadPathData['subformat'] = $post->get('subformat', '', 'STRING');
    $file = $post->get('fileToUpload', '', 'Array');

    JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_tjlms/models');
    $mediaModel = JModelLegacy::getInstance('Media', 'TjlmsModel');

    if (!empty($file))
    {
    $mediaData['source'] = JFile::makeSafe($file['source']);
    $mediaData['org_filename'] = JFile::makeSafe($file['name']);
    $mediaData['format'] = $format;
    $mediaData['sub_format'] = $subformat;

    // $mediaData['path'] = $this->getuploadFolder($uploadPathData);
    $mediaData['created_by'] = JFactory::getUser()->id;
    $path = $this->getuploadFolder($uploadPathData);

    if (JFile::exists($path . $mediaData['source']))
    {
    $mediaModel->save($mediaData);
    $mediaId = $mediaModel->getState($mediaModel->getName() . '.id');

    if (!empty($format))
    {
    if ($format == 'test' && $subformat == 'answer.upload')
    {
    $mediaData['path'] = JRoute::_('index.php?option=com_tjlms&task=lesson. downloadMedia&mid=' . $mediaId);

    JTable::addIncludePath(JPATH_ROOT . '/administrator/components/com_tmt/tables');
    $testAnswersTable = JTable::getInstance('testanswers', 'TmtTable', array('dbo', JFactory::getDbo()));

    $test = $post->get('test', array(), "Array");
    $olUserId = JFactory::getUser()->id;
    $testAnswersTable->load(
    array("question_id" => $test['answer']['qid'],
    "user_id" => $olUserId, "test_id" => $test['answer']['testid'],
    "invite_id" => $test['answer']['ltid']
    )
    );
    $mediaData['answer_id'] = $testAnswersTable->id;
    $mediaData['qid'] = $testData['answer']['qid'];
    }
    elseif ($format == 'associate')
    {
    $db = JFactory::getDbo();
    $fileData = new stdClass;
    $fileData->id = '';
    $fileData->lesson_id = $lessonData['associate']['lessonId'];
    $fileData->media_id = $mediaId;
    $db->insertObject('#__tjlms_associated_files', $fileData, 'id');
    }
    }

    $mediaData['media_id'] = $mediaId;
    $msg = JText::_("COM_TJLMS_FILE_TABLE_ENTRIES_ADDED");
    echo new JResponseJson($mediaData, $msg);
    }
    else
    {
    echo new JResponseJson(0, JText::_("COM_TJLMS_ERROR_FILENOTSAFE_TO_UPLOAD"), true);
    }
    }
    else
    {
    echo new JResponseJson(0, JText::_("COM_TJLMS_ERROR_FILENOTSAFE_TO_UPLOAD"), true);
    }
    }
    }

    Voyez-vous dans ce fichier la commande qui indique de changer le nom du fichier ?
    [Précision : dans la base de données, la table pour les fichier uploadé comporte les champs suivants : "org_filename" (qui affiche le nom d’origine) et "source" (qui affiche le nom avec la suite de 10 chiffres)

    Merci à l'avance pour votre aide.

  • #2
    Bonjour,

    Ce composant étant commercial, cher et étant très rarement cité ici, tu devrais poser la question à son auteur.
    Il y a peut-être une raison (et éventuellement un paramétrage) pour que ce champ "source" soit un nombre remplaçant le nom réel. Mais je n'ai pas bien compris sous quel nom il est stocké dans "lessons", sous son nom "numérique" ? Si oui, c'est peut-être un moyen d'empêcher un téléchargement direct d'un fichier précis faute de connaître son nom exact.

    A vue de nez, dans le code que tu cites, j'aurais tendance à penser que c'est là que ce qui te gêne se passe :
    $mediaData['source'] = JFile::makeSafe($file['source']);
    $mediaData['org_filename'] = JFile::makeSafe($file['name']);
    "Patience et longueur de temps font plus que force ni que rage..." (La Fontaine : Le Lion et le Rat) - "Il n'y a pas de problèmes; il n'y a que des solutions" (André Gide). MoovJla et LazyDbBackup sur www.joomxtensions.com - FaQ sur www.fontanil.info hébergés chez PHPNET - +sites gérés chez 1and1 et OVH - Site pro : www.robertg-conseil.fr

    Commentaire


    • #3
      Bonjour,

      Merci pour ta réponse. C’est cool de voir quelqu’un qui s’intéresse un tant soit peu à ce problème, car j’ai bien compris qu’il s’agit d’un composant peu répandu. Il est payant mais il offre beaucoup de services. Moodle aussi devient payant dès lors qu’on veut certains services. Et par rapport à d’autres composant d’elearning pour Joomla, il m’a semblé vraiment le plus abouti, notamment au niveau des statistiques qui offrent plusieurs rapports pour suivre l’activité des étudiants.

      Je me suis tournée vers l’équipe de développement, on m’a répondu que cette demandé était mise sur la file d’attente et qu’elle serait honorée dans les versions futures. C’est un peu vague comme réponse et je voulais voir si j’arrivais à m’en dépatouiller.

      Pour répondre à tes questions, je mets en copie d’écran commet se présente la leçon en FO quand on clique sur le bouton des fichiers associés : on voit le nom d’origine du fichier avec l’extension pdf.
      Mais quand on télécharge le fichier, le nom est remplacé par une suite de 10 chiffres suivie de ".pdf" (la « source »). Sur le FTP, on a bien le fichier avec le nom encodé en chiffres.

      Dans la 2e copie d’écran, voilà comment ça se présente dans la base de données :
      le fichier « bonjour_pdf.pdf » (colonne « org_filename ») et le nom encodé (colonne « source »).

      Dans le fichier fileupload.json.php il y a l’extension JSON qui est utilisée. Elle permet d’encoder une chaîne de caractères.
      Je mets ici le fichier en entier.


      // No direct access
      defined('_JEXEC') or die;

      jimport('joomla.application.component.controllerfo rm');
      jimport('joomla.filesystem.folder');
      jimport('joomla.filesystem.file');

      /**
      * File upload controller class.
      *
      * since 1.0.0
      */
      class TjlmsControllerFileupload extends JControllerForm
      {
      /**
      * The main function triggered to upload file off question
      *
      * @return object of result and message
      *
      * since 1.0.0
      * */

      public function validateAndUpload()
      {
      $app = JFactory::getApplication();
      $input = JFactory::getApplication()->input;
      $tjlmsparams = JComponentHelper::getParams('com_tjlms');

      $return = $input->post->getArray();
      $return['fileToUpload'] = $input->files->get('FileInput', null, 'raw');

      // Validate the uploaded file
      $validate_result = $this->validateupload($return['fileToUpload']);
      $return['fileToUpload']['valid'] = 1;

      if ($validate_result['res'] != 1)
      {
      echo new JResponseJson(0, $validate_result['msg'], true);
      $app->close();
      }

      $res = $this->moveToCorrectFolder($return);

      if (!$res)
      {
      $fileName = $return['fileToUpload']['name'];
      echo new JResponseJson(0, JText::sprintf("COM_TJLMS_ERROR_UPLOADINGFILE", $fileName), true);
      }
      else
      {
      $return['fileToUpload']['source'] = $res;
      echo new JResponseJson($return, JText::sprintf("COM_TJLMS_UPLOAD_SUCCESS"));
      }
      }

      /**
      * The main function triggered to upload file off question
      *
      * @param Array $data Array of data for fileupload
      *
      * @return object of result and message
      *
      * since 1.0.0
      * */
      private function getuploadFolder($data)
      {
      $folder = '';

      if (!empty($data['mediaformat']))
      {
      if ($data['mediaformat'] == 'test' && $data['subformat'] == 'answer.upload')
      {
      $folder = 'media/com_tmt/test/';
      }
      else
      {
      $folder = 'media/com_tjlms/lessons/';
      }
      }

      return $folder;
      }

      /**
      * The main function triggered to upload file off question
      *
      * @param Array $data Array of data for fileupload
      *
      * @return mixed
      *
      * since 1.0.0
      * */

      private function moveToCorrectFolder($data)
      {
      $src = $data['fileToUpload']['tmp_name'];

      // Make the filename safe
      $fileName = JFile::makeSafe($data['fileToUpload']['name']);

      $ext = JFile::getExt($fileName);

      $filepath = $this->getuploadFolder($data);

      if (!$filepath)
      {
      echo new JResponseJson('', JText::sprintf("COM_TJLMS_NO_FOLDER_FOUND_AS_PER_F ORMAT"), true);
      }
      else
      {
      // New file name
      $newfilename = rand(0, 9999999999) . '.' . $ext;

      $PathWithName = $filepath . $newfilename;

      $destination = JPATH_SITE . '/' . $PathWithName;

      $options = array('fobidden_ext_in_content' => false);

      /*3rd param is to stream and 4is set to true to ask to upload unsafe file*/
      if (!JFile::upload($src, $destination, false, false, $options))
      {
      return false;
      }

      return $newfilename;
      }
      }

      /**
      * The function to validate the uploaded format file
      *
      * @param MIXED $fileToUpload file object
      *
      * @return object of result and message
      *
      * since 1.0.0
      * */
      private function validateupload($fileToUpload)
      {
      $tjlmsparams = JComponentHelper::getParams('com_tjlms');
      $mediaParams = JComponentHelper::getParams('com_media');
      $validExtensions = array_map('trim', explode(',', $mediaParams->get('upload_extensions')));
      $ext = JFile::getExt(JFile::makeSafe($fileToUpload['name']));

      $return = 1;
      $msg = '';

      if (!in_array($ext, $validExtensions))
      {
      $return = 0;
      $msg = JText::_("COM_TJLMS_ERROR_UNABLE_TO_UPLOAD_FILE");
      }
      elseif ($fileToUpload["error"] == UPLOAD_ERR_OK)
      {
      // Total length of post back data in bytes.
      $contentLength = (int) $_SERVER['CONTENT_LENGTH'];

      // Instantiate the media helper
      $mediaHelper = new JHelperMedia;

      // Maximum allowed size of post back data in MB.
      $postMaxSize = $mediaHelper->toBytes(ini_get('post_max_size'));

      // Maximum allowed size of script execution in MB.
      $memoryLimit = $mediaHelper->toBytes(ini_get('memory_limit'));

      // Maximum allowed size of script execution in MB.
      $uploadMaxFileSize = $mediaHelper->toBytes(ini_get('upload_max_filesize'));

      /* check if file size in within the uploading limit of site*/

      // Check for the total size of post back data.
      if ($contentLength > ($tjlmsparams->get('lesson_upload_size', 10) * 1024 * 1024)
      || ($postMaxSize > 0 && $contentLength > $postMaxSize)
      || ($uploadMaxFileSize > 0 && $contentLength > $uploadMaxFileSize)
      || ($memoryLimit != -1 && $contentLength > $memoryLimit))
      {
      $return = 0;
      $msg = JText::sprintf('COM_TMT_UPLOAD_SIZE_ERROR', $tjlmsparams->get('lesson_upload_size', 10, 'INT') . ' MB');
      }
      }
      else
      {
      $return = 0;
      $msg = JText::_("COM_TJLMS_ERROR_UPLOADINGFILE", $fileToUpload['name']);
      }

      $output['res'] = $return;
      $output['msg'] = $msg;

      return $output;
      }

      /**
      * Triggered from ajax
      *
      * @return json encoded id of the row of related table
      *
      * since 1.3
      * */
      public function onAfterUpload()
      {
      $input = JFactory::getApplication()->input;
      $return = $input->post->getArray();
      $msg = JText::_("COM_TJLMS_FILE_MOVED_TO_CORRECT_LOCATION ");
      echo new JResponseJson($return, $msg);
      }

      /**
      * Triggered from ajax
      * Add entry in tjlms_media
      *
      * @return json encoded id of the row of related table
      *
      * since 1.3
      * */
      public function addTableEntries()
      {
      $input = JFactory::getApplication()->input;
      $post = $input->post;
      $uploadPathData = $mediaData = [];

      $testData = $post->get('test', array(), 'ARRAY');
      $lessonData = $post->get('lesson', array(), 'ARRAY');
      $format = $uploadPathData['mediaformat'] = $post->get('mediaformat', '', 'STRING');
      $subformat = $uploadPathData['subformat'] = $post->get('subformat', '', 'STRING');
      $file = $post->get('fileToUpload', '', 'Array');

      JModelLegacy::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_tjlms/models');
      $mediaModel = JModelLegacy::getInstance('Media', 'TjlmsModel');

      if (!empty($file))
      {
      $mediaData['source'] = JFile::makeSafe($file['source']);
      $mediaData['org_filename'] = JFile::makeSafe($file['name']);
      $mediaData['format'] = $format;
      $mediaData['sub_format'] = $subformat;

      // $mediaData['path'] = $this->getuploadFolder($uploadPathData);
      $mediaData['created_by'] = JFactory::getUser()->id;
      $path = $this->getuploadFolder($uploadPathData);

      if (JFile::exists($path . $mediaData['source']))
      {
      $mediaModel->save($mediaData);
      $mediaId = $mediaModel->getState($mediaModel->getName() . '.id');

      if (!empty($format))
      {
      if ($format == 'test' && $subformat == 'answer.upload')
      {
      $mediaData['path'] = JRoute::_('index.php?option=com_tjlms&task=lesson. downloadMedia&mid=' . $mediaId);

      JTable::addIncludePath(JPATH_ROOT . '/administrator/components/com_tmt/tables');
      $testAnswersTable = JTable::getInstance('testanswers', 'TmtTable', array('dbo', JFactory::getDbo()));

      $test = $post->get('test', array(), "Array");
      $olUserId = JFactory::getUser()->id;
      $testAnswersTable->load(
      array("question_id" => $test['answer']['qid'],
      "user_id" => $olUserId, "test_id" => $test['answer']['testid'],
      "invite_id" => $test['answer']['ltid']
      )
      );
      $mediaData['answer_id'] = $testAnswersTable->id;
      $mediaData['qid'] = $testData['answer']['qid'];
      }
      elseif ($format == 'associate')
      {
      $db = JFactory::getDbo();
      $fileData = new stdClass;
      $fileData->id = '';
      $fileData->lesson_id = $lessonData['associate']['lessonId'];
      $fileData->media_id = $mediaId;
      $db->insertObject('#__tjlms_associated_files', $fileData, 'id');
      }
      }

      $mediaData['media_id'] = $mediaId;
      $msg = JText::_("COM_TJLMS_FILE_TABLE_ENTRIES_ADDED");
      echo new JResponseJson($mediaData, $msg);
      }
      else
      {
      echo new JResponseJson(0, JText::_("COM_TJLMS_ERROR_FILENOTSAFE_TO_UPLOAD"), true);
      }
      }
      else
      {
      echo new JResponseJson(0, JText::_("COM_TJLMS_ERROR_FILENOTSAFE_TO_UPLOAD"), true);
      }
      }
      }

      Je vois le premier appel JSON en ligne 50 :
      echo new JResponseJson(0, $validate_result['msg'], true);
      Est-ce que c’est cette ligne qui encode le nom du fichier avant téléchargement ?
      Par quoi dois-je la remplacer pour que ce remplacement n’ait pas lieu ?

      Merci à l'avance pour votre aide.

      Commentaire


      • #4
        Bonjour,
        Sans connaitre l'extension, je pense plutôt que c'est cette ligne qui modifie le nom du fichier :
        Code:
        / New file name
        $newfilename = rand(0, 9999999999) . '.' . $ext;
        Ceci dit, tu dois prendre en compte le fait que si le fichier a son nom modifié, c'est peut être pour une raison particulière...
        - Protection contre les accès non autorisé ?
        - limite du nom de fichier dans la base pour le normaliser ?
        - est-ce que d'autres vérifications ou traitements sont réalisés par la suite sur ce nom ou c'est juste pour "masquer" le nom du fichier ?

        Dans tous les cas, si tu modifies cette ligne (en la commentant par exemple ou en modifiant en "$newfilename = $fileName.'.'.$ext;"), tu dois alors vérifier intégralement le fonctionnement (est-ce que le fichier reste accessible ? Est-ce qu'il est accessible directement ? Etc..) et en plus garder en tête que si tu fais une mise à jour ultérieure, tu risques d'avoir un gros problème de fonctionnement par la suite (si les personnes développant le composant modifie le code et que tes fichiers deviennent alors inaccessibles...).


        Cordialement,
        Chabi01 - http://www.xlformation.com

        Commentaire


        • #5
          Bonjour,

          En fait, si je comprends bien, le nom est codé à l'enregistrement, et le choix du fichier que doit récupérer l'élève semble le transférer tel qu'il est stocké, sans aucune "traduction".
          Donc à mon avis, deux solutions : empêcher le renommage lors de l'envoi sur le serveur, ou ajouter du code pour remplacer le "source" par son "name".
          Pour ça, il faudrait faire des tests sur une copie du site ou sur un site vierge, en sachant que ce sera à recommencer à chaque mise à jour si les auteurs n'ont pas intégré eux-mêmes la modification.
          "Patience et longueur de temps font plus que force ni que rage..." (La Fontaine : Le Lion et le Rat) - "Il n'y a pas de problèmes; il n'y a que des solutions" (André Gide). MoovJla et LazyDbBackup sur www.joomxtensions.com - FaQ sur www.fontanil.info hébergés chez PHPNET - +sites gérés chez 1and1 et OVH - Site pro : www.robertg-conseil.fr

          Commentaire


          • #6
            Merci pour votre rapidité et pour votre intérêt.

            Oui, RobertG, le nom est bien codé au moment du transfert. J’avais essayé d’intervertir les « org_filename » et « source » dans le fichier tmpl, mais ça donnait une erreur.

            Donc ta solution est bonne, Chabi01. C’est bien là qu’il fallait agir, merci super !

            Le code exact est :

            $newfilename = $fileName;
            tout simplement (sinon, il y avait doublement du point + extension).
            J’ai vérifié, le fonctionnement semble ok.

            Pour les mises à jour ultérieures, pensez-vous que le fait d’avoir modifié des fichiers php puisse empêcher une mise à jour ?
            Est-ce que ça peut être le cas aussi pour des fichiers css ?
            Merci pour vos éclaircissements.

            Commentaire


            • #7
              Bonjour,
              Content d'avoir pu aider
              Sinon, à partir du moment où c'est le code du composant que tu as modifié, à la prochaine mise à jour, tes modifications seront perdues puisque le fichier complet sera remplacé par la mise à jour.

              La solution est alors de noter précieusement toutes modifications que tu pourrais avoir besoin de remettre en place pour pouvoir les remettre à la prochaine mise à jour du composant (si les développeurs n'ont pas complètement changé le code ici

              Cordialement,
              Chabi01 - http://www.xlformation.com

              Commentaire

              Annonce

              Réduire
              1 sur 2 < >

              C'est [Réglé] et on n'en parle plus ?

              A quoi ça sert ?
              La mention [Réglé] permet aux visiteurs d'identifier rapidement les messages qui ont trouvé une solution.

              Merci donc d'utiliser cette fonctionnalité afin de faciliter la navigation et la recherche d'informations de tous sur le forum.

              Si vous deviez oublier de porter cette mention, nous nous permettrons de le faire à votre place... mais seulement une fois
              Comment ajouter la mention [Réglé] à votre discussion ?
              1 - Aller sur votre discussion et éditer votre premier message :


              2 - Cliquer sur la liste déroulante Préfixe.

              3 - Choisir le préfixe [Réglé].


              4 - Et voilà… votre discussion est désormais identifiée comme réglée.

              2 sur 2 < >

              Assistance au forum - Outil de publication d'infos de votre site

              Compatibilité: PHP 4.1,PHP4, 5, 6DEV MySQL 3.2 - 5.5 MySQLi from 4.1 ( @ >=PHP 4.4.9)

              Support Version de Joomla! : | J!3.0 | J!2.5.xx | J!1.7.xx | J!1.6.xx | J1.5.xx | J!1.0.xx |

              Version française (FR) D'autres versions sont disponibles depuis la version originale de FPA

              UTILISER À VOS PROPRES RISQUES :
              L'exactitude et l'exhaustivité de ce script ainsi que la documentation ne sont pas garanties et aucune responsabilité ne sera acceptée pour tout dommage, questions ou confusion provoquée par l'utilisation de ce script.

              Problèmes connus :
              FPA n'est actuellement pas compatible avec des sites Joomla qui ont eu leur fichier configuration.php déplacé en dehors du répertoire public_html.

              Installation :

              1. Téléchargez l'archive souhaitée : http://afuj.github.io/FPA/

              Archive zip : https://github.com/AFUJ/FPA/zipball/master

              2. Décompressez le fichier de package téléchargé sur votre propre ordinateur (à l'aide de WinZip ou d'un outil de décompression natif).

              3. Lisez le fichier LISEZMOI inclus pour toutes les notes de versions spécifiques.

              4. LIRE le fichier de documentation inclus pour obtenir des instructions d'utilisation détaillées.

              5. Téléchargez le script fpa-fr.php à la racine de votre site Joomla!. C'est l'endroit que vous avez installé Joomla et ce n'est pas la racine principale de votre serveur. Voir les exemples ci-dessous.

              6. Exécutez le script via votre navigateur en tapant: http:// www. votresite .com/ fpa-fr.php
              et remplacer www. votresite .com par votre nom de domaine


              Exemples:
              Joomla! est installé dans votre répertoire web et vous avez installé la version française du fichier FPA:
              Télécharger le script fpa-fr.php dans: /public_html/
              Pour executer le script: http://www..com/fpa-fr.php

              Joomla! est installé dans un sous-répertoire nommé "cms" et vous avez installé la version française du fichier FPA:
              Télécharger le script fpa-fr.php dans: /public_html/cms/
              Pour executer le script: http://www..com/cms/fpa-fr.php

              En raison de la nature très sensible de l'information affichée par le script FPA, il doit être retiré immédiatement du serveur après son utilisation.

              Pour supprimer le script de votre site, utilisez le lien de script de suppression fourni en haut de la page du script. Si le lien de suppression échoue pour supprimer le script, utilisez votre programme FTP pour le supprimer manuellement ou changer le nom une fois que le script a généré les données du site et le message publié sur le forum. Si le script est toujours présent sur le site, il peut être utilisé pour recueillir suffisamment d'informations pour pirater votre site. Le retrait du script empêche des étrangers de l'utiliser pour jeter un oeil à la façon dont votre site est structuré et de détecter les défauts qui peuvent être utilisé à vos dépends.
              Voir plus
              Voir moins

              Partenaire de l'association

              Réduire

              Hébergeur Web PlanetHoster
              Travaille ...
              X