Communauté Elgg francophone

Créer un compteAide  
Connexion
  • Accueil
  • Blogs
  • abFab
  • Problème des types mimes - contournement par modif du plugin "file"

Problème des types mimes - contournement par modif du plugin "file"

Bonjour,

 

En fait actuellement je suis en train d'installer un Elgg autour de la miouzique (voir ici)... et la gestion des type mime par Elgg est carrément problématique.

Ainsi, sans que je comprenne pourquoi, des utilisateurs qui uploadaient des ".mp3" ont vu leurs fichiers associé tantôt à du "audio/x-mp3" tantôt à du "applications/octet-stream".

En fait si je m'en réfère au fichier mod/fil/actions/upload.php, l'affectation se fait par:

$file->setMimeType($_FILES['upload']['type']);

 

Autrement dit, elle affecte au champ "mime", la valeur retrournée par le navigateur de l'utilisateur. J'ai opu le vérifier moi-même avec des fichiers de type "flv".  Au départ Elgg le reconnaissait comme un "applications/octet-stream" (autrement dit "inconnu au bataillon"). Comme j'utilise Seamonkey, j'ai pu forcer le type mime à "video/x-flv" dans les préférences. Et effectivement, l'affectation qui suivait le téléchargement était désormais correcte.

De base ce n'est pas très ergonomique, mais cela peut faire l'objet d'un "trouble shooting".

Seulement voilà, il semble que FireFox ne permette pas ce genre de manip. Plusieurs fils de discussion (comme ici) montrent que cette possibilité n'existe plus dans ce navigateur.

On est donc tout simplement coincé.

J'ai donc implémenté le contournement suivant. C'est "sauvage", mais les fonctions php qui sont sensées retourner les types mimes sont soient "deprecated" soit inopérantes en local sous easyphp.

Ca se passe dans le fichier "mod/file/actions/upload.php".

1ere étape: ajout de ce code :

    // Affectation du type mime en fonction de l'extension. La récupération par $_FILE est ingérable surtout que
    // FireFox semble ne plus permettre d'affecter correctement les types   
   
    $fichier=$_FILES['upload']['name'];
    $typemime=$_FILES['upload']['type'];
   
    $flag = ereg("^(.+)\.(.+)$", $fichier, $ext);
    if ($flag) {
    $extension=$ext[2] ;
   
    switch($extension)
            {
                case "mp3":
                    $typemime="audio/mp3";
                break;
                case "flv": 
                    $typemime="video/x-flv";
                  break;

            }
   
   
    } // fin affectation

 

2ème étape : Modification des affectations pré-existantes :

     // modif relative au type mime
     // $file->setMimeType($_FILES['upload']['type']);
    $file->setMimeType($typemime);

[...]

    // Modif relative au type mime   
    //$file->simpletype = get_general_file_type($_FILES['upload']['type']);
    $file->simpletype = get_general_file_type($typemime);

 

Si vous avez plus clean, évidemment je suis preneur... mais cela semble bien fonctionner.

Commentaires

  • Fabrice Collette le 8 janvier 2010

    Salut,

    Merci de l'astuce. Elgg se fie aux infos passées par les navigateurs pour détecter les types de fichier (c'est la méthode classique) mais c'est intéressant ce voir que quelquefois les infos ne sont pas fiables (d'autant plus que je bosse en ce moment sur un projet "musique" avec mes copains du blues ;) )

    Quelques idées pour gérer les choses de manière plus clean :

    - pour éviter de modifier l'action de base du plugin file, tu peux overrider l'action en la déclarant dans un autre plugin dans lequel tu pets ton actions modifiée - ça évite de faire écraser tes modifs à chaque nouvelle version de file. Pour que ça marche il suffit que ton plugin soit en dessous du plugin file dans la liste pour que l'acion prise en compte soit la tienne

    - tu peux aussi t'accrocher à l'événement "create" d'un objet "file" et à chaque fois qu'un fichier est crée, tester si le type correspond. Le mérite c'est que tu profites de tous les nouveaux ajout du code du plugin, tu te contente de passer le balais derrière pour voir si tout est conforme

    a+

    Fabrice

  • abFab le 10 janvier 2010

    Bonjour,

    "tu peux overrider l'action en la déclarant dans un autre plugin dans lequel tu pets ton actions modifiée".

    Bon alors j'ai essayé... mais j'y arrive po. et je comprends pas trop..

    Si je crée le plugin "file_pxrz", et que je mets le fichier "upload.php" modifié dans :


    mod/file_pxrz/actions/upload.php

    il ne se passe rien.

    C'est logique parce que cette fonction n'est jamais appelée.

    En fait quand j'arrive sur la page du formulaire de téléchargement et que je valide, si je ne me trompe pas, il fait appel à la fonction

    mod/file/views/default/file/upload.php

    et celle-ci, ensuite, va appeler la véritable fonction d'upload par l'intermédiaire du formulaire :

    <form action="<?php echo $vars['url']; ?>action/<?php echo $action; ?>" enctype="multipart/form-data" method="post">
    <?php

        if ($action == "file/upload") {

    ?>

    Donc il faut d'abord surcharger cette fonction, pour faire appel à la bonne fonction.

    Donc j'ai modifié le fichier upload.php dans le nouveau plugins, ici

    mod/file_pxrz/views/default/file/upload.php

    Et effectivement, cette fonction est bien appelée lors de la creation du formulaire.
    Mais maintenant il faut que je la modifie pour qu'elle appelle celle-ci :

    mod/file_pxrz/actions/upload

    Donc j'ai fait :

    [...]

    $action = "file_pxrz/upload";

    [...]

    <form action="<?php echo $vars['url']; ?>action/<?php echo $action; ?>" enctype="multipart/form-data" method="post">
    <?php

        if ($action == "file_pxrz/upload") {

    ?>

    [...]

     

    Et là ça plante, avec le message : "file_pxrz/upload" n'est pas définie par le système...

    Autrement dit.. si je laisse $action = "file/upload" il fait appel à la mauvaise fonction upload (celle du plugin "file") et si je mets $action = "file_pxrz/upload", il me dit que l'url n'existe pas (!?!)

    Il doit y avoir un truc tout simple, mais je cale...

  • Fabrice Collette le 11 janvier 2010

    Il faut que dans le start.php de ton plugin file_pxrz tu déclare ta l'action avec register_action

    par exemple, si l'action à overrider s'appelle file/upload, dans ton start.php tu dois avoir

    register_action('file/upload', false, $CONFIG->wwwroot.'mod/file_pxrz/actions/upload.php)

    cela permettra à elgg d'actualiser ses tables et de pointer vers ton script perso pour l'action en question

    Ton plugin doit êtreplacé en dessous de 'file' car elgg charge les chemin des actions dans l'ordre des plugins et donc c'est le chemin vers ton script qui viendra remplacer celui vers le script standard pour le nom d'action 'file/upload'

    Le nom de l'action à appelr dans les forms reste toujours le même

    Amuse toi bien :)

    Fabrice

  • abFab le 16 janvier 2010

    Ah ouais là ça devient sérieux... mais je commence à mieux cerner le fonctionnement... merci