PC SOFT

FORUMS PROFESSIONNELS
WINDEVWEBDEV et WINDEV Mobile

Accueil → WEBDEV 2025 → UPLOAD DOSSIER WEBDEV SESSION PHP ??
UPLOAD DOSSIER WEBDEV SESSION PHP ??
Débuté par mickael.nesty, 18 fév. 2022 03:40 - 8 réponses
Posté le 18 février 2022 - 03:40
Bonjour,

Je viens de créer pour un client un site webdev en mode session, pour que les client puissent uploader des fichiers.
Un we transfert en gros
.
Tout fonctionne très bien.

En utilisant la solution d'upload de webdev je ne peux upload que des fichiers.
Mon client me demande la possibilité d'envoyer des dossiers complet avec leur arborescence.
J'ai essayer de voir si il etait possible de recuperer le chemin des fichiers avant l'upload je n'ai rien trouvé.


J'ai donc commencer a chercher des solutions en Javascript, php etc.

je suis tomber sur ce code php qui marche parfaitement :
<?php

if(! empty($_FILES['folder']))
{
$i = 0;

foreach($_FILES['folder']['name'] as $name)
{
if(getimagesize($_FILES['folder']['tmp_name'][$i])){
$full_path = $_FILES['folder']['full_path'][$i];

$directory = substr($full_path, 0, strrpos($full_path, '/'));

@mkdir('uploads/'.$directory, 0755, True);

move_uploaded_file($_FILES['folder']['tmp_name'][$i], 'uploads/'.$full_path);
}

$i++;
}

$errors = array_unique($_FILES['folder']['error']);

if(count($errors) == 1 && $errors[0] == 0){
$success = 'Upload terminé!';
}
}

?>

<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Upload Directory</title>

<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css" integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l" crossorigin="anonymous">

<style>
#container{margin-top: 75px;}
</style>
</head>
<body>

<div class="container" id="container">

<?php if(! empty($success)):?>
<div class="alert alert-success"><?=$success;?></div>
<?php endif;?>

<form action="index.php" method="post" enctype="multipart/form-data">
<div class="form-group">
<label for="folder">Upload un dossier</label>
<input type="file" name="folder[]" class="form-control-file" webkitdirectory multiple>
</div>

<div class="form-group">
<button type="submit" class="btn btn-primary">Upload</button>
</div>
</form>
</div>

</body>
</html>


mon soucis c'est comment l'adapter. j'ai dupliquer mon projet , j'ai changer le type de sessions => PHP, sauf que je ne sais pas ou saisir mon code php. , comment recuperer les valeur de $_FILES.

J'ai essayé de créer un composant web en HTML / CSS / Javascript, il arrive toujours un moment ou il faut un formulaire PHP pour l'upload.
si vous avez des pistes ce serai top.

Merci d'avance pour votre aide.
Membre enregistré
43 messages
Posté le 23 février 2022 - 00:57
petit up , je suis vraiment bloqué, je suis a deux doigts de tout refaire en html / css/ php

merci d'avance pour votre aide

--
--=Ils ne savaient pas que c'était impossible, alors ils l'ont fait=--
Membre enregistré
499 messages
Posté le 23 février 2022 - 11:10
Bonjour,

Il est possible d'utiliser jQuery pour ajouter l'attribut "webkitDirectory" sur le champ Upload multiple de WebDev, de cette façon :
// à mettre dans l'init navigateur de la page (onload)
jQuery(SAI_UPLOAD).parent().find("input[type=file]").attr("webkitDirectory",1);


Attention cependant, d'après le MDN : https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/webkitdirectory cet attribut ne fait que rajouter une propriété "webkitRelativePath" à l'objet File côté Javascript, mais celui-ci n'est aucunement envoyé au serveur. Cela signifie que dans tous les cas (y compris votre code en PHP) la notion de hiérarchie n'est pas envoyée au serveur : les fichiers sont envoyés "à plat".

Si votre dossier ressemble à ceci :
dossier sélectionné
 - test.txt
 - test2.txt
 - sous-dossier
    - test.txt


Côté serveur vous allez recevoir deux fichiers test.txt, sans savoir lequel doit aller où.

A partir de là, deux possibilités :
- demander aux utilisateurs de n'uploader que des dossier sans sous-dossier, ou les prévenir que la hiérarchie sera cassée (dans ce cas-là autant ne pas rajouter l'attribut)
- oublier le champ upload et passer par du javascript pour faire des uploads en mode Ajax avec l'envoi des données du fichiers, son nom et son webkitRelatifPath vers une page AWP ou un webservice REST qui traiterait tout ça correctement.
Membre enregistré
324 messages
Posté le 23 février 2022 - 14:26
Bonjour,

J'ai essayer de voir si il etait possible de recuperer le chemin des fichiers avant l'upload je n'ai rien trouvé.


Oui c'est normal, le navigateur et donc par conséquent votre site web ne sont pas censé avoir au contenu de votre machine, c'est la base de la sécurité sur internet depuis qu'internet existe.

Tout le reste ne sera que des solutions bancales qui finiront par ne plus fonctionner un jour ou l'autre. Surtout que tous les navigateurs ne sont pas forcément baser sur webKit, ni la même version !

Le champ upload n'est pas fait pour ce genre de manip. Ca doit rester juste des fichiers.

Je verrais 3 options :
- Un client FTP, là y'a plus de soucis
- Lancer un JAR via la page web, c'est tjs possible et c'est le seul moyen d'avoir accès au contenu de la machine
- Un programme en windev à installer à la première connexion au site web par exemple et qui se chargera lui de faire les envois par FTP sur votre serveur web et là pas de soucis de répertoires.
Membre enregistré
43 messages
Posté le 28 février 2022 - 05:49
Bonjour ,

Je viens de voir que vous m'aviez repondut. deja merci beaucoup d'avoir pris le temps pour moi.
- Un client FTP, là y'a plus de soucis => Impossible 
- Lancer un JAR via la page web, c'est tjs possible et c'est le seul moyen d'avoir accès au contenu de la machine => Impossible 
- Un programme en windev à installer à la première connexion au site web par exemple et qui se chargera lui de faire les envois par FTP sur votre serveur web et là pas de soucis de répertoires. => Impossible


Je ne peux utiliser aucune de vos proposition malheureusement.

oublier le champ upload et passer par du javascript pour faire des uploads en mode Ajax avec l'envoi des données du fichiers, son nom et son webkitRelatifPath vers une page AWP ou un webservice REST qui traiterait tout ça correctement.


Je suis vraiment preneur de votre solution AWP / JS etc, comment voyez vous la chose ?
Merci d'avance pour votre aide

--
--=Ils ne savaient pas que c'était impossible, alors ils l'ont fait=--
Membre enregistré
499 messages
Posté le 28 février 2022 - 15:09
Bonjour,

Je n'ai pas fiabilisé le code, mais cela ressemblerait à ça.

<Input type="file" id="upload" multiple webkitDirectory />
<script>
function onReceiveFiles(Event) {
const promises = [];
for (let i = 0, l = Event.target.files.length; i < l; i += 1) {
promises.push(new Promise((resolve, reject) => {
const file = Event.target.files[i];
const fr = new FileReader(file);
fr.addEventListener('load', () => {
resolve({
filename: file.name,
path: file.webkitRelativePath,
content: fr.result,
});
});
fr.readAsDataURL(file);
}));
}

Promise.allSettled(promises).then((results) => {
const body = [];
results.forEach((result) => {
body.push(result.value);
});

// body sera un tableau ressemblant à cela:
// [
// {
// "filename": "test.txt",
// "path": "upload/test.txt",
// "content": "data:text/plain;base64,dGVzdA=="
// },
// {
// "filename": "test2.txt",
// "path": "upload/test2.txt",
// "content": "data:text/plain;base64,dGVzdA=="
// },
// {
// "filename": "test.txt",
// "path": "upload/dossier/test.txt",
// "content": "data:text/plain;base64,dGVzdDM="
// },
// {
// "filename": "test2.txt",
// "path": "upload/dossier/test2.txt",
// "content": "data:text/plain;base64,dGVzdDQ="
// }
// ]

// Ce contenu peut être stocké dans une variable globale navigateur, utilisée plus tard lors de l'envoi du formulaire.

// En page AWP il faut faire un pageParamètre(paramBuffer) pour récupérer le contenu envoyé dans le body du POST
// Puis un JSONVersVariant et traiter chaque élément un par un
);
});
}
</script>


Une démo ici : https://stackblitz.com/edit/web-platform-oz3h2x…

Plusieurs remarques:
- Ca demande une expérience assez approfondie en javascript et programmation asynchrone
- Il n'est pas obligé de faire un upload groupé, on peut faire l'upload par fichier en faisant un appel post au résultat du FileReader
- le readDataAsURL va charger en mémoire la totalité de chaque fichier pour l'encoder en base 64 : attention sur les gros fichiers, surtout en sélection multiple.
- à cause du point précédent, le temps de traitement général est plus long, le navigateur va prendre le temps de lire le contenu, l'encoder, puis ensuite faire l'upload, là où de base il ne lit que pour faire l'upload.
- les appels en POST ne sont plus considérés comme des uploads, donc ne sont pas plus limités par la configuration spécifique des uploads (taille limite, restrictions, etc)

Toutes ces remarques ont des solutions, comme par ex. lire le document par "morceaux" et envoyer chaque morceau indépendamment. Mais cela peut demander beaucoup de temps.
Membre enregistré
43 messages
Posté le 02 mars 2022 - 16:40
Bonjour,

Merci BEAUCOUP !! "bchanudet".

Je viens de voir votre réponse, je n'ai jamais utiliser awp,
Comment j'intègre votre code dans une page AWP ?

avec un composant web ou il y a une autre solution ?

J'ai du mal a comprendre , comment j'enregistre les fichiers a uploader avec votre solution. je suis vraiment désolés de vous poser autant de question , mais comme je ne maitrise pas du tout WEBDEV avec AWP c'est plutôt compliqué. autant en WinDev je me débrouille sans aucun soucis mais la je patauge complètement.

Je vais faire des essais avec tout se que vous m'avez fournis.
Je vous tiens au courant.

Merci encore!!

--
--=Ils ne savaient pas que c'était impossible, alors ils l'ont fait=--
Membre enregistré
499 messages
Posté le 02 mars 2022 - 18:55
Bonjour,

Le script devrait se trouver dans un champ HTML sur une page webdev classique. Et la page AWP serait une page supplémentaire à activer en mode AWP (dans la description de la page).

Par ailleurs le code présenté ici n'est qu'une "piste", il ne se suffit pas à lui-même pour fonctionner. En l'état il ne fait que lire les fichiers sur le poste utilisateur et les intégrer dans une structure mémoire côté navigateur, mais il faut faire toute la partie "récupération de cette structure" + "soumission du formulaire" + "traitement des données côté serveur" + "traitement du retour du serveur". J'ai bien peur que si vous n'avez qu'une connaissance récente de WebDev, et très peu en JavaScript et API Web comme les Promise, FileReader, vous allez avoir beaucoup de mal à intégrer ce système, et encore plus à le maintenir à l'avenir.

De mon point de vue, en l'état il serait plus simple de demander à l'utilisateur de faire un zip du dossier souhaité et d'utiliser les fonctions classiques d'upload de WebDev pour rester dans des schémas connus. Le monde du web et WebDev en particulier ont déjà beaucoup de nuances à digérer lorsqu'on vient du côté "client lourd" et WinDev. Se rajouter tout de suite l'apprentissage des API avancées Promise/FileReader/etc serait avoir les yeux plus gros que le ventre. Et en général ce genre de choses en dev ne pardonnent pas (bug, crash, failles de sécurité et j'en passe).

Si vous avez quelqu'un autour de vous avec des connaissances du Web et/ou de WebDev, allez-y. Sinon, j'aurais tendance à faire le calcul. Vous pourriez vous retrouver à investir beaucoup de temps dans une fonctionnalité qui, suivant votre audience, ne sera pas forcément très utilisée ou peut être comblée différemment.

Bon courage :)
Membre enregistré
43 messages
Posté le 02 mars 2022 - 19:40
Bonjour,

Tout d'abord merci de prendre le temps de me répondre, effectivement il me manque des bases, mais je ne désespère pas.

Petit point de situation.

J'ai mis le code que vous m'avez donné dans un composant web. Je récupère dans une structure les informations du fichier JSON.
Jusque là pas de soucis.
J'ai créé une page AWP, qui prend en paramètre les 3 informations ( filename / path / content).
Le rôle de la page est de créer l'arborescence des dossiers puis d'enregistrer le fichier encode en base64

j'utilise ensuite un httprequete pour lancer ma page et lui passer les paramètres

Au moment où je vous écris ces lignes, j'ai une erreur qui me dit que mon lien est trop long, je suis en train de voir comment faire la config de IIS et de webdev pour autoriser des liens plus longs, "Longueur maximale d'URL en octets" et la "Longueur maximale des chaines de requêtes". mais on dirait que les paramètres ne sont pas pris en compte pour le moment

si cette solution ne marche pas comme je le souhaite, je pense que je vais faire un web service qui fera la récupération du fichier en base64

J'aimerais vraiment avoir votre avis pour savoir si je suis le bon chemin.

Merci encore

--
--=Ils ne savaient pas que c'était impossible, alors ils l'ont fait=--