From 58514668410cb902dab613221a8e7f963cc36317 Mon Sep 17 00:00:00 2001 From: polo Date: Sun, 26 Jul 2026 19:29:53 +0200 Subject: versioning fichiers CSS et JS --- .gitignore | 1 + controller/media.php | 4 +- index.php | 1 + public/file_upload.js | 101 ------------------------------------------- public/inversion.js | 16 ------- public/js/file_upload.js | 101 +++++++++++++++++++++++++++++++++++++++++++ public/js/index.php | 3 ++ public/js/inversion.js | 16 +++++++ public/js/main.js | 92 +++++++++++++++++++++++++++++++++++++++ public/main.js | 92 --------------------------------------- view/Versioning.php | 24 ++++++++++ view/accueil.php | 4 +- view/album.php | 23 +++------- view/backup.php | 6 +-- view/discographie.php | 24 +++------- view/pageArticlesSimples.php | 32 +++----------- view/password.php | 6 +-- view/template.php | 4 +- 18 files changed, 267 insertions(+), 283 deletions(-) create mode 100644 .gitignore delete mode 100644 public/file_upload.js delete mode 100644 public/inversion.js create mode 100644 public/js/file_upload.js create mode 100644 public/js/index.php create mode 100644 public/js/inversion.js create mode 100644 public/js/main.js delete mode 100644 public/main.js create mode 100644 view/Versioning.php diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8fce603 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +data/ diff --git a/controller/media.php b/controller/media.php index b6774e0..71eddf9 100644 --- a/controller/media.php +++ b/controller/media.php @@ -3,7 +3,7 @@ // traitement avant enregistrement dans le fichier submit.php // cette fonction extrait les liens pointant vers des medias embarqués // (liste de sites) et les restituent nus, sans les balises -function mediaSubmit($chaine) +function mediaSubmit(string $chaine) { // liste de sites concernés par les fonctions de ce fichiers $listeMedia = "youtube.com|vimeo.com|dailymotion.com|spotify.com|soundcloud.com|instagram.com|twitter.com|flickr.com|facebook.com|fb.watch|deezer.com|openstreetmap.org|goo.gl/maps|google.com/maps|itunes.apple.com|wordpress.com"; @@ -191,7 +191,7 @@ function mediaSubmit($chaine) // embarquement !! -function mediaEmbed($chaine) +function mediaEmbed(string $chaine) { //require("../Embera/src/Autoloader.php"); //$embera = new Embera\Embera(); diff --git a/index.php b/index.php index 182f931..7d805f2 100644 --- a/index.php +++ b/index.php @@ -57,6 +57,7 @@ if(isset($_GET['page'])) // utile? // contrôleurs // mode visiteur (sans l'éditeur) +require 'view/Versioning.php'; require('controller/visitor.php'); // contrôleur des pages en mode admin diff --git a/public/file_upload.js b/public/file_upload.js deleted file mode 100644 index c24b798..0000000 --- a/public/file_upload.js +++ /dev/null @@ -1,101 +0,0 @@ -// public/file_upload.js -// -// envoie d'un gros fichier ZIP en contournant la limite du php.ini -// ce fichier est "caché", il n'est envoyé qu'à un utilisateur connecté et sur la page "restauration" - -// -> input file onchange -function sendFileSize() -{ - var tagId = 'archiveUpload'; - var fileInfos = getFileInfo(tagId); - //var fileSize = document.getElementById(tagId).files[0].size; - - const xhr = new XMLHttpRequest(); - url = 'index.php?action=restauration&file_name='+fileInfos.name+'&file_size='+fileInfos.size; - xhr.open("GET", url); - xhr.send(); -} - -// -> input submit onclick -function uploadDespiteServerMaxWeightLimit(maxPHPiniWeight, archiveFormat) -{ - // dans - var tagId = 'archiveUpload'; - //var fileInfos = getFileInfo(tagId); - var file = document.getElementById(tagId).files[0]; - - // si le fichier est assez léger, javascript s'arrête ici - if(file.size > maxPHPiniWeight) - { - // découpage - // envoyer et recevoir des pointeurs pour les perfs - // chunksArray est un tableau de "blob" - var nbChunks = Math.ceil(file.size / maxPHPiniWeight); - var chunksArray = sliceFile(file, nbChunks); - - // requêtes AJAX - chunkIndex = 0; // une variable globale - uploadChunksAJAX(chunksArray, tagId); - - // annule l'envoi normal par POST - event.preventDefault(); - - // vider le formulaire et recharger - // reload() est un F5 et non un Ctrl + F5 - //document.getElementById(tagId).value = ''; - //location.reload(); - - location.href = "index.php?from=menu&action=restauration"; - } -} - -function getFileInfo(tagId) -{ - var infos = - { - name: document.getElementById(tagId).files[0].name, - size: document.getElementById(tagId).files[0].size, - type: document.getElementById(tagId).files[0].type, - } - - return(infos); -} - -function sliceFile(file, nbChunks) -{ - var byteIndex = 0; // octet du début - var chunks = []; // données - - for (var i = 0; i < nbChunks; i += 1) - { - // octet de fin - var byteEnd = Math.ceil((file.size / nbChunks) * (i + 1)); - - // un morceau du fichier va dans une case du tableau - chunks.push(file.slice(byteIndex, byteEnd)); - - // nouvel octet du début - byteIndex += (byteEnd - byteIndex); - } - - return chunks; -} - -function uploadChunksAJAX(chunksArray, tagId) -{ - var fileName = document.getElementById(tagId).files[0].name; - var formData = new FormData(); - const xhr = new XMLHttpRequest(); - - for(var i = 0; i < chunksArray.length; i++) - { - formData.append('blob', chunksArray[i]); - - url = 'index.php?from=menu&action=restauration&chunk_name='+fileName+'_'+i; - // false => synchrone, déprécié parce que fige le navigateur, mais ici on s'en fout - xhr.open("POST", url, false); - xhr.send(formData); - - formData.delete('blob'); - } -} diff --git a/public/inversion.js b/public/inversion.js deleted file mode 100644 index 20a6871..0000000 --- a/public/inversion.js +++ /dev/null @@ -1,16 +0,0 @@ -// public/inversion.js - -// inverser la position de deux "articles" ou albums d'une page -function inversion() -{ - var page = ''; - var action = ''; // monter ou descendre - var fileCode = ''; // fileList[$i]['fileCode'] ?> - var position = ''; // fileList[$i]['position'] ?> - - const xhr = new XMLHttpRequest(); - url = 'index.php?page='+page+'&action='+action+'&file_code='+fileCode+'&position='+position+'#'+fileCode; - url = 'index.php?action=restauration&file_name='+fileInfos.name+'&file_size='+fileInfos.size; - xhr.open("GET", url); - xhr.send(); -} \ No newline at end of file diff --git a/public/js/file_upload.js b/public/js/file_upload.js new file mode 100644 index 0000000..737ca5f --- /dev/null +++ b/public/js/file_upload.js @@ -0,0 +1,101 @@ +// public/js/file_upload.js +// +// envoie d'un gros fichier ZIP en contournant la limite du php.ini +// ce fichier est "caché", il n'est envoyé qu'à un utilisateur connecté et sur la page "restauration" + +// -> input file onchange +function sendFileSize() +{ + var tagId = 'archiveUpload'; + var fileInfos = getFileInfo(tagId); + //var fileSize = document.getElementById(tagId).files[0].size; + + const xhr = new XMLHttpRequest(); + url = 'index.php?action=restauration&file_name='+fileInfos.name+'&file_size='+fileInfos.size; + xhr.open("GET", url); + xhr.send(); +} + +// -> input submit onclick +function uploadDespiteServerMaxWeightLimit(maxPHPiniWeight, archiveFormat) +{ + // dans + var tagId = 'archiveUpload'; + //var fileInfos = getFileInfo(tagId); + var file = document.getElementById(tagId).files[0]; + + // si le fichier est assez léger, javascript s'arrête ici + if(file.size > maxPHPiniWeight) + { + // découpage + // envoyer et recevoir des pointeurs pour les perfs + // chunksArray est un tableau de "blob" + var nbChunks = Math.ceil(file.size / maxPHPiniWeight); + var chunksArray = sliceFile(file, nbChunks); + + // requêtes AJAX + chunkIndex = 0; // une variable globale + uploadChunksAJAX(chunksArray, tagId); + + // annule l'envoi normal par POST + event.preventDefault(); + + // vider le formulaire et recharger + // reload() est un F5 et non un Ctrl + F5 + //document.getElementById(tagId).value = ''; + //location.reload(); + + location.href = "index.php?from=menu&action=restauration"; + } +} + +function getFileInfo(tagId) +{ + var infos = + { + name: document.getElementById(tagId).files[0].name, + size: document.getElementById(tagId).files[0].size, + type: document.getElementById(tagId).files[0].type, + } + + return(infos); +} + +function sliceFile(file, nbChunks) +{ + var byteIndex = 0; // octet du début + var chunks = []; // données + + for (var i = 0; i < nbChunks; i += 1) + { + // octet de fin + var byteEnd = Math.ceil((file.size / nbChunks) * (i + 1)); + + // un morceau du fichier va dans une case du tableau + chunks.push(file.slice(byteIndex, byteEnd)); + + // nouvel octet du début + byteIndex += (byteEnd - byteIndex); + } + + return chunks; +} + +function uploadChunksAJAX(chunksArray, tagId) +{ + var fileName = document.getElementById(tagId).files[0].name; + var formData = new FormData(); + const xhr = new XMLHttpRequest(); + + for(var i = 0; i < chunksArray.length; i++) + { + formData.append('blob', chunksArray[i]); + + url = 'index.php?from=menu&action=restauration&chunk_name='+fileName+'_'+i; + // false => synchrone, déprécié parce que fige le navigateur, mais ici on s'en fout + xhr.open("POST", url, false); + xhr.send(formData); + + formData.delete('blob'); + } +} diff --git a/public/js/index.php b/public/js/index.php new file mode 100644 index 0000000..f67f1d7 --- /dev/null +++ b/public/js/index.php @@ -0,0 +1,3 @@ +fileList[$i]['fileCode'] ?> + var position = ''; // fileList[$i]['position'] ?> + + const xhr = new XMLHttpRequest(); + url = 'index.php?page='+page+'&action='+action+'&file_code='+fileCode+'&position='+position+'#'+fileCode; + url = 'index.php?action=restauration&file_name='+fileInfos.name+'&file_size='+fileInfos.size; + xhr.open("GET", url); + xhr.send(); +} \ No newline at end of file diff --git a/public/js/main.js b/public/js/main.js new file mode 100644 index 0000000..f5f602b --- /dev/null +++ b/public/js/main.js @@ -0,0 +1,92 @@ +// public/js/main.js + +function versMenu() +{ + // ergonomique + window.setTimeout(function(){ + location.href = "index.php?page=menu"; + }, 10000); +} + +function deconnexionAutomatique() +{ + // minuterie réinitialisée après une action de l'utilisateur + // 600000 ms = 10 min + //window.setTimeout("location=('index.php?action=deconnexion');", 600000); + + // sauvegarde de la rédaction en cours avec le plugin "autosave" de l'éditeur +} + +function confirmerSuppression() // appel 'onCLick' +{ + // avec JS, on ne suit le lien qu'avec un "oui" + // sans JS, le lien fonctionne + var oui = confirm('Confirmer la suppression de cet article.'); + if(!oui) + { + event.preventDefault(); + } +} + +// code exécuté à la validation du formulaire +function envoiDonnees() +{} + +// bouton "mailto", le visiteur ne quitte pas la page +function clientCourriel() +{ + var adresse = "melaine.favennec@wanadoo.fr"; + var objet = "?subject=visite%20du%20site"; + var link = "mailto:" + adresse + objet; + document.location.href = link; +} + +// pour "cacher" l'adresse du HTML +// inutile -> nécessite une requête AJAX +function copierCourriel() +{ + var adresse = "melaine.favennec@wanadoo.fr"; + copierDansPressePapier(adresse); +} + +function copierDansPressePapier(chaine) +{ + // une balise avec des attributs + var element = document.createElement("input"); + element.setAttribute("id", "copyMe"); + element.setAttribute("value", chaine); + + // placement dans la page (= le "document") + document.body.appendChild(element); + var cible = document.getElementById('copyMe'); + + // selection comme on le ferait à la souris + cible.select(); + // copie (= Ctrl + C) + document.execCommand("copy"); + + // nettoyage + element.parentNode.removeChild(element); + + // test optionnel + // essayer un document.execCommand("paste"); dans une variable + // mais depuis une deuxième fonction + + alert('Cette adresse a été copiée dans le presse-papier:\n\n' + chaine); +} + +// cacher le lien #nouvelArticle quand le ckeditor est appelé +// hum pourquoi faire déjà? +// function cacherLienArticle() +// { +// var cible = document.getElementById('nouvelArticle'); +// cible.setAttribute("style", "display: none;"); +// } + +function nouveauMotdepasse(page) +{ + alert('Le mot de passe a été modifié.'); + window.setTimeout(function(){ + location.href = "index.php?page=" + page + "&message=nouveau_mdp"; + }, 0); +} diff --git a/public/main.js b/public/main.js deleted file mode 100644 index 19a09bb..0000000 --- a/public/main.js +++ /dev/null @@ -1,92 +0,0 @@ -// public/main.js - -function versMenu() -{ - // ergonomique - window.setTimeout(function(){ - location.href = "index.php?page=menu"; - }, 10000); -} - -function deconnexionAutomatique() -{ - // minuterie réinitialisée après une action de l'utilisateur - // 600000 ms = 10 min - //window.setTimeout("location=('index.php?action=deconnexion');", 600000); - - // sauvegarde de la rédaction en cours avec le plugin "autosave" de l'éditeur -} - -function confirmerSuppression() // appel 'onCLick' -{ - // avec JS, on ne suit le lien qu'avec un "oui" - // sans JS, le lien fonctionne - var oui = confirm('Confirmer la suppression de cet article.'); - if(!oui) - { - event.preventDefault(); - } -} - -// code exécuté à la validation du formulaire -function envoiDonnees() -{} - -// bouton "mailto", le visiteur ne quitte pas la page -function clientCourriel() -{ - var adresse = "melaine.favennec@wanadoo.fr"; - var objet = "?subject=visite%20du%20site"; - var link = "mailto:" + adresse + objet; - document.location.href = link; -} - -// pour "cacher" l'adresse du HTML -// inutile -> nécessite une requête AJAX -function copierCourriel() -{ - var adresse = "melaine.favennec@wanadoo.fr"; - copierDansPressePapier(adresse); -} - -function copierDansPressePapier(chaine) -{ - // une balise avec des attributs - var element = document.createElement("input"); - element.setAttribute("id", "copyMe"); - element.setAttribute("value", chaine); - - // placement dans la page (= le "document") - document.body.appendChild(element); - var cible = document.getElementById('copyMe'); - - // selection comme on le ferait à la souris - cible.select(); - // copie (= Ctrl + C) - document.execCommand("copy"); - - // nettoyage - element.parentNode.removeChild(element); - - // test optionnel - // essayer un document.execCommand("paste"); dans une variable - // mais depuis une deuxième fonction - - alert('Cette adresse a été copiée dans le presse-papier:\n\n' + chaine); -} - -// cacher le lien #nouvelArticle quand le ckeditor est appelé -// hum pourquoi faire déjà? -// function cacherLienArticle() -// { -// var cible = document.getElementById('nouvelArticle'); -// cible.setAttribute("style", "display: none;"); -// } - -function nouveauMotdepasse(page) -{ - alert('Le mot de passe a été modifié.'); - window.setTimeout(function(){ - location.href = "index.php?page=" + page + "&message=nouveau_mdp"; - }, 0); -} diff --git a/view/Versioning.php b/view/Versioning.php new file mode 100644 index 0000000..f75afe1 --- /dev/null +++ b/view/Versioning.php @@ -0,0 +1,24 @@ +' . "\n"; + } + static function insertJS(string $name, bool $module = false): string + { + return '' . "\n"; + } + + static function versionedFileURL(string $type, string $filename, ?string $custom_path = null): string + { + $path = $custom_path ?? 'public/' . $type . '/' . $filename . '.' . $type; // si custom_path, $type et $filename ne servent à rien + + if(file_exists(getcwd() . '/' . $path)){ + $version = substr(md5_file($path), 0, 8); + return $path . '?v=' . $version; + } + return $path; // sécurité fichier absent + } +} diff --git a/view/accueil.php b/view/accueil.php index 1e8db56..d7297e4 100644 --- a/view/accueil.php +++ b/view/accueil.php @@ -2,12 +2,12 @@ // view/accueil.php // variable $js +$js = Versioning::insertJS('main'); ob_start(); ?> - - - - - - - - -'; } -$js = ob_get_clean(); // variable $header ob_start(); diff --git a/view/backup.php b/view/backup.php index 78e2d04..c56661f 100644 --- a/view/backup.php +++ b/view/backup.php @@ -77,12 +77,12 @@ elseif(isset($_GET['action']) && $_GET['action'] == 'restauration') <?= $title ?> - - + + '); + echo Versioning::insertJS('file_upload'); } ?> diff --git a/view/discographie.php b/view/discographie.php index 84358db..96026bf 100644 --- a/view/discographie.php +++ b/view/discographie.php @@ -2,30 +2,18 @@ // view/discographie.php // variable $css -ob_start(); -?> - - - - - - - -'; } -$js = ob_get_clean(); - // variable $header ob_start(); diff --git a/view/pageArticlesSimples.php b/view/pageArticlesSimples.php index d282964..fcb453a 100644 --- a/view/pageArticlesSimples.php +++ b/view/pageArticlesSimples.php @@ -2,39 +2,17 @@ // view/pageArticleSimple.php // variable $css -ob_start(); -if($page == 'menu') -{ -?> - - - - - - - - - -'; } -$js = ob_get_clean(); - // message lecteur multimedia if($page == 'archives') diff --git a/view/password.php b/view/password.php index ae153b5..62f53ec 100644 --- a/view/password.php +++ b/view/password.php @@ -75,9 +75,9 @@ ob_start(); - - - + + + diff --git a/view/template.php b/view/template.php index dfe68bd..3facc13 100644 --- a/view/template.php +++ b/view/template.php @@ -10,9 +10,9 @@ - -