diff options
| author | polo <ordipolo@gmx.fr> | 2022-03-28 03:45:38 +0200 |
|---|---|---|
| committer | polo <ordipolo@gmx.fr> | 2022-03-28 03:45:38 +0200 |
| commit | 4873117ec6aeb86ef169cbf8750123ca24041cdf (patch) | |
| tree | 7f8ec95171e74d03d9cd9a6edc12108ecbd59785 | |
| parent | 92a4565f303f5b9f273a8d1eb74d52ac541e89bc (diff) | |
| download | melaine-4873117ec6aeb86ef169cbf8750123ca24041cdf.tar.gz melaine-4873117ec6aeb86ef169cbf8750123ca24041cdf.tar.bz2 melaine-4873117ec6aeb86ef169cbf8750123ca24041cdf.zip | |
upload gros zip AJAX
| -rw-r--r-- | controller/backup.php | 145 | ||||
| -rw-r--r-- | controller/installation.php | 12 | ||||
| -rw-r--r-- | dependances.php | 6 | ||||
| -rw-r--r-- | index.php | 40 | ||||
| -rw-r--r-- | model/Article.php | 2 | ||||
| -rw-r--r-- | model/Image.php | 8 | ||||
| -rw-r--r-- | public/css/accueil.css | 58 | ||||
| -rw-r--r-- | public/file_upload.js | 103 | ||||
| -rw-r--r-- | public/main.js | 46 | ||||
| -rw-r--r-- | view/backup.php | 10 | ||||
| -rw-r--r-- | view/template.php | 4 |
11 files changed, 283 insertions, 151 deletions
diff --git a/controller/backup.php b/controller/backup.php index 31974d0..b1a2491 100644 --- a/controller/backup.php +++ b/controller/backup.php | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | // controller/backup.php | 2 | // controller/backup.php |
| 3 | 3 | ||
| 4 | // note: faire que cette fonction soit exécutée automatiquement de temps en temps | 4 | // note: faire que cette fonction soit exécutée automatiquement de temps en temps |
| 5 | function sauvegarder($from) | 5 | function pageSauvegarde($from) |
| 6 | { | 6 | { |
| 7 | $title = 'extraction des données'; | 7 | $title = 'extraction des données'; |
| 8 | 8 | ||
| @@ -21,7 +21,7 @@ function sauvegarder($from) | |||
| 21 | require('view/backup.php'); | 21 | require('view/backup.php'); |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | function creerMelainePHP() | 24 | function createZipMelainePHP() |
| 25 | { | 25 | { |
| 26 | $cheminDestination = 'data/'; | 26 | $cheminDestination = 'data/'; |
| 27 | $nomFichier = "melainePHP"; | 27 | $nomFichier = "melainePHP"; |
| @@ -99,75 +99,124 @@ function createZip($destinationPath, $zipFileName, array $targetDirectories, arr | |||
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | 101 | ||
| 102 | function restaurer($from) | 102 | function restoreData($path) |
| 103 | { | 103 | { |
| 104 | $title = 'Restauration des données'; | ||
| 105 | $message = ''; | ||
| 106 | global $archiveFormat; | 104 | global $archiveFormat; |
| 105 | $message = ''; | ||
| 107 | 106 | ||
| 108 | // recharger la même page en écrivant les données | 107 | // détecter le format (zip ou autre) |
| 109 | if(isset($_FILES['archive']) && $_FILES['archive']['error'] == 0) | 108 | if($archiveFormat == 'zip') |
| 110 | { | 109 | { |
| 111 | // détecter le format (zip ou autre) | 110 | // extraction |
| 112 | if($archiveFormat == 'zip') | 111 | try |
| 113 | { | 112 | { |
| 114 | // une copie du zip est conservée dans data/ au cas où | 113 | $Zip = new ZipArchive(); |
| 115 | move_uploaded_file($_FILES['archive']['tmp_name'], 'data/' . $_FILES['archive']['name']); | 114 | } |
| 116 | chmod('data/' . $_FILES['archive']['name'], 0666); | 115 | catch (Throwable $e) // l'extension zip n'est pas activée |
| 117 | 116 | { | |
| 118 | $nomFichier = 'data/' . $_FILES['archive']['name']; | 117 | echo($e); |
| 119 | 118 | die(); | |
| 120 | // extraction | 119 | } |
| 121 | try | 120 | if($Zip->open($path, ZipArchive::RDONLY) === TRUE) |
| 122 | { | 121 | { |
| 123 | $Zip = new ZipArchive(); | 122 | $j = 0; |
| 124 | } | 123 | for($i = 0; $i < $Zip->numFiles; $i++) |
| 125 | catch (Throwable $e) // l'extension zip n'est pas activée | ||
| 126 | { | ||
| 127 | echo($e); | ||
| 128 | die(); | ||
| 129 | } | ||
| 130 | if($Zip->open($nomFichier, ZipArchive::RDONLY) === TRUE) | ||
| 131 | { | 124 | { |
| 132 | $j = 0; | 125 | $nomEntree = $Zip->getNameIndex($i); |
| 133 | for($i = 0; $i < $Zip->numFiles; $i++) | 126 | if($Zip->extractTo('.', $nomEntree) === TRUE) |
| 134 | { | 127 | { |
| 135 | $nomEntree = $Zip->getNameIndex($i); | 128 | $j++; |
| 136 | if($Zip->extractTo('.', $nomEntree) === TRUE) | ||
| 137 | { | ||
| 138 | $j++; | ||
| 139 | } | ||
| 140 | else | ||
| 141 | { | ||
| 142 | $message = '<p style="color: red;" >Erreur: extraction du zip impossible.</p>'; | ||
| 143 | } | ||
| 144 | chmod($nomEntree, 0666); | ||
| 145 | } | 129 | } |
| 146 | 130 | else | |
| 147 | if($j == $Zip->numFiles) | ||
| 148 | { | 131 | { |
| 149 | $message = '<p style="color: red;" >Restauration réussie !!</p>'; | 132 | $message = '<p style="color: red;" >Erreur: extraction du zip impossible.</p>'; |
| 150 | } | 133 | } |
| 151 | $Zip->close(); | 134 | chmod($nomEntree, 0666); |
| 152 | } | 135 | } |
| 153 | else | 136 | |
| 137 | if($j == $Zip->numFiles) | ||
| 154 | { | 138 | { |
| 155 | // mauvais fichier | 139 | $message = '<p style="color: red;" >Restauration réussie !!</p>'; |
| 156 | $message = '<p style="color: red;" >Erreur: Impossible d\'ouvrir l\'archive Zip."</p>'; | ||
| 157 | } | 140 | } |
| 141 | $Zip->close(); | ||
| 158 | } | 142 | } |
| 159 | else | 143 | else |
| 160 | { | 144 | { |
| 161 | // pas de module zip | 145 | // mauvais fichier |
| 162 | $message = '<p style="color: red" >Erreur: Veuillez activer l\'extension zip dans le php.ini pour pouvoir gérer les sauvegardes.</p>'; | 146 | $message = '<p style="color: red;" >Erreur: Impossible d\'ouvrir l\'archive Zip."</p>'; |
| 163 | } | 147 | } |
| 164 | } | 148 | } |
| 149 | else | ||
| 150 | { | ||
| 151 | // pas de module zip | ||
| 152 | $message = '<p style="color: red" >Erreur: Veuillez activer l\'extension zip dans le php.ini pour pouvoir gérer les sauvegardes.</p>'; | ||
| 153 | } | ||
| 154 | |||
| 155 | return($message); | ||
| 156 | } | ||
| 157 | |||
| 158 | function pageRestauration($from) | ||
| 159 | { | ||
| 160 | $title = 'Restauration des données'; | ||
| 161 | $message = ''; | ||
| 162 | global $maxWeight; | ||
| 163 | |||
| 164 | // recharger la même page en écrivant les données | ||
| 165 | if(isset($_SESSION['fileName']) && isset($_SESSION['fileSize']) && $_SESSION['fileSize'] > $maxWeight) | ||
| 166 | { | ||
| 167 | // une copie du zip est conservée dans data/ au cas où | ||
| 168 | $path = 'data/' . $_SESSION['fileName']; | ||
| 169 | rename('data/tmp/' . $_SESSION['fileName'], $path); | ||
| 170 | chmod($path, 0666); | ||
| 171 | |||
| 172 | // enregistrement | ||
| 173 | $message = restoreData($path); | ||
| 174 | } | ||
| 175 | |||
| 176 | // variables obtenues en AJAX | ||
| 177 | if(isset($_SESSION['fileName'])) | ||
| 178 | { | ||
| 179 | unset($_SESSION['fileName']); | ||
| 180 | } | ||
| 181 | if(isset($_SESSION['fileSize'])) | ||
| 182 | { | ||
| 183 | unset($_SESSION['fileSize']); | ||
| 184 | } | ||
| 185 | |||
| 186 | if(isset($_FILES['archive']) && $_FILES['archive']['error'] == 0) | ||
| 187 | { | ||
| 188 | // une copie du zip est conservée dans data/ au cas où | ||
| 189 | $path = 'data/' . $_FILES['archive']['name']; | ||
| 190 | move_uploaded_file($_FILES['archive']['tmp_name'], $path); | ||
| 191 | chmod($path, 0666); | ||
| 192 | |||
| 193 | // enregistrement | ||
| 194 | $message = restoreData($path); | ||
| 195 | } | ||
| 165 | elseif(isset($_FILES['archive']) && $_FILES['archive']['error'] != 0) | 196 | elseif(isset($_FILES['archive']) && $_FILES['archive']['error'] != 0) |
| 166 | { | 197 | { |
| 167 | $message = '<p style="color: red;" >Erreur: Le fichier n\'a pas pu être téléchargé correctement.<br/> | 198 | $message = '<p style="color: red;" >Erreur: Le fichier n\'a pas pu être téléchargé correctement.<br/> |
| 168 | Au fait, "upload_max_filesize" dans le php.ini vaut ' . ini_get('upload_max_filesize') . '.</p>'; | 199 | Au fait, "upload_max_filesize" dans le php.ini vaut ' . ini_get('upload_max_filesize') . '.</p>'; |
| 169 | } | 200 | } |
| 170 | 201 | ||
| 171 | require('view/backup.php'); | 202 | require('view/backup.php'); |
| 172 | } | 203 | } |
| 173 | 204 | ||
| 205 | // upload AJAX d'un zip dans file_upload.js | ||
| 206 | function uploadChunkAndMerge() | ||
| 207 | { | ||
| 208 | // $_GET['chunk_name'] n'est pas utilisé pour l'instant | ||
| 209 | |||
| 210 | if(isset($_SESSION['fileName'])) | ||
| 211 | { | ||
| 212 | $zipName = 'data/tmp/' . $_SESSION['fileName']; | ||
| 213 | $srcFile = fopen($_FILES['blob']['tmp_name'], 'r'); | ||
| 214 | $destFile = fopen($zipName, 'a'); // 'a' crée ou écrit à la fin | ||
| 215 | |||
| 216 | // copie de données brutes | ||
| 217 | stream_copy_to_stream($srcFile, $destFile); | ||
| 218 | |||
| 219 | fclose($srcFile); | ||
| 220 | fclose($destFile); | ||
| 221 | } | ||
| 222 | } \ No newline at end of file | ||
diff --git a/controller/installation.php b/controller/installation.php index 4966611..3b940c8 100644 --- a/controller/installation.php +++ b/controller/installation.php | |||
| @@ -138,13 +138,23 @@ function installation() | |||
| 138 | { | 138 | { |
| 139 | createIndexPHP('data/discographie/images-mini/index.php', $droitsFichiers); | 139 | createIndexPHP('data/discographie/images-mini/index.php', $droitsFichiers); |
| 140 | } | 140 | } |
| 141 | // fichiers temporaires pour upload des grosses archives | ||
| 142 | if(!file_exists('data/tmp')) | ||
| 143 | { | ||
| 144 | mkdir('data/tmp'); | ||
| 145 | chmod('data/tmp', $droitsDossiers); | ||
| 146 | } | ||
| 147 | if(!file_exists('data/tmp/index.php')) | ||
| 148 | { | ||
| 149 | createIndexPHP('data/tmp/index.php', $droitsFichiers); | ||
| 150 | } | ||
| 141 | // le modèle donnera les droits 0666 (octal) aux nouveaux fichiers à l'intérieur des dossiers | 151 | // le modèle donnera les droits 0666 (octal) aux nouveaux fichiers à l'intérieur des dossiers |
| 142 | 152 | ||
| 143 | // créer le melainePHP.zip | 153 | // créer le melainePHP.zip |
| 144 | if(!file_exists("data/melainePHP.zip")) | 154 | if(!file_exists("data/melainePHP.zip")) |
| 145 | { | 155 | { |
| 146 | require('controller/backup.php'); | 156 | require('controller/backup.php'); |
| 147 | creerMelainePHP(); | 157 | createZipMelainePHP(); |
| 148 | } | 158 | } |
| 149 | 159 | ||
| 150 | // création d'un mot de passe si password.txt est vide | 160 | // création d'un mot de passe si password.txt est vide |
diff --git a/dependances.php b/dependances.php index cd42e3f..216b639 100644 --- a/dependances.php +++ b/dependances.php | |||
| @@ -54,7 +54,7 @@ $maxWeight = ini_get('upload_max_filesize'); | |||
| 54 | // les fichiers un par un quand un zip est trop grand | 54 | // les fichiers un par un quand un zip est trop grand |
| 55 | 55 | ||
| 56 | // conversion des mégas en octets | 56 | // conversion des mégas en octets |
| 57 | /*function return_bytes ($size_str) | 57 | function return_bytes ($size_str) |
| 58 | { | 58 | { |
| 59 | switch (substr ($size_str, -1)) | 59 | switch (substr ($size_str, -1)) |
| 60 | { | 60 | { |
| @@ -63,5 +63,5 @@ $maxWeight = ini_get('upload_max_filesize'); | |||
| 63 | case 'G': case 'g': return (int)$size_str * 1073741824; | 63 | case 'G': case 'g': return (int)$size_str * 1073741824; |
| 64 | default: return $size_str; | 64 | default: return $size_str; |
| 65 | } | 65 | } |
| 66 | }*/ | 66 | } |
| 67 | /*$maxWeight = return_bytes(ini_get('upload_max_filesize'));*/ | 67 | $maxWeight = return_bytes(ini_get('upload_max_filesize')); |
| @@ -25,6 +25,7 @@ installation(); | |||
| 25 | 25 | ||
| 26 | 26 | ||
| 27 | // traitement des requêtes AJAX | 27 | // traitement des requêtes AJAX |
| 28 | // -> insertion d'une image dans l'éditeur | ||
| 28 | if(isset($_GET['action']) && isset($_GET['page']) && $_GET['action'] == 'upload_image') | 29 | if(isset($_GET['action']) && isset($_GET['page']) && $_GET['action'] == 'upload_image') |
| 29 | { | 30 | { |
| 30 | // sécurité !! | 31 | // sécurité !! |
| @@ -40,10 +41,45 @@ if(isset($_GET['action']) && isset($_GET['page']) && $_GET['action'] == 'upload_ | |||
| 40 | // paramètre "true" parce qu'on reçoit une requête AJAX | 41 | // paramètre "true" parce qu'on reçoit une requête AJAX |
| 41 | $Image = new Image(true); | 42 | $Image = new Image(true); |
| 42 | $Image->upload(); | 43 | $Image->upload(); |
| 44 | echo($Image->reponseAjax); // attendu par l'éditeur | ||
| 43 | } | 45 | } |
| 44 | exit; // stop !! | 46 | exit; // stop !! |
| 45 | } | 47 | } |
| 48 | // page restauration quand le fichier zip est lourd | ||
| 49 | // -> input file onchange | ||
| 50 | if(isset($_GET['action']) && $_GET['action'] == 'restauration' | ||
| 51 | && isset($_GET['file_name']) && isset($_GET['file_size'])) | ||
| 52 | { | ||
| 53 | if(!isset($_SESSION['admin']) || $_SESSION['admin'] != 1) | ||
| 54 | { | ||
| 55 | header('Location: index.php?erreur=file_infos_ajax'); | ||
| 56 | } | ||
| 57 | else | ||
| 58 | { | ||
| 59 | $_SESSION['fileSize'] = $_GET['file_size']; | ||
| 60 | $_SESSION['fileName'] = $_GET['file_name']; | ||
| 61 | //echo("file infos send"); | ||
| 62 | var_dump($_SESSION['fileName']); | ||
| 63 | exit(); // stop !! | ||
| 64 | } | ||
| 65 | } | ||
| 66 | // -> input submit onclick | ||
| 67 | if(isset($_GET['action']) && $_GET['action'] == 'restauration' | ||
| 68 | && isset($_GET['chunk_name']) && isset($_FILES['blob'])) | ||
| 69 | { | ||
| 46 | 70 | ||
| 71 | if(!isset($_SESSION['admin']) || $_SESSION['admin'] != 1) | ||
| 72 | { | ||
| 73 | header('Location: index.php?erreur=upload_ajax'); | ||
| 74 | } | ||
| 75 | else | ||
| 76 | { | ||
| 77 | require('controller/backup.php'); | ||
| 78 | uploadChunkAndMerge(); | ||
| 79 | echo('file send'); | ||
| 80 | exit(); // stop !! | ||
| 81 | } | ||
| 82 | } | ||
| 47 | 83 | ||
| 48 | // traitement des POST du ckeditor | 84 | // traitement des POST du ckeditor |
| 49 | // la fonction submitCKeditor est "autonome", elle n'affiche rien puis redirige sans GET | 85 | // la fonction submitCKeditor est "autonome", elle n'affiche rien puis redirige sans GET |
| @@ -230,12 +266,12 @@ elseif($_SESSION['admin'] == 1 && isset($_GET['action'])) | |||
| 230 | // sauvegarde du dossier 'data' | 266 | // sauvegarde du dossier 'data' |
| 231 | if($_GET['action'] == 'sauvegarde') | 267 | if($_GET['action'] == 'sauvegarde') |
| 232 | { | 268 | { |
| 233 | sauvegarder($_GET['from']); | 269 | pageSauvegarde($_GET['from']); |
| 234 | } | 270 | } |
| 235 | // restauration avec une sauvegarde | 271 | // restauration avec une sauvegarde |
| 236 | elseif($_GET['action'] == 'restauration') | 272 | elseif($_GET['action'] == 'restauration') |
| 237 | { | 273 | { |
| 238 | restaurer($_GET['from']); | 274 | pageRestauration($_GET['from']); |
| 239 | } | 275 | } |
| 240 | else | 276 | else |
| 241 | { | 277 | { |
diff --git a/model/Article.php b/model/Article.php index 4ef3a5b..4063feb 100644 --- a/model/Article.php +++ b/model/Article.php | |||
| @@ -87,7 +87,7 @@ class Article | |||
| 87 | 87 | ||
| 88 | // nommer les fichiers avec le timestamp pour: | 88 | // nommer les fichiers avec le timestamp pour: |
| 89 | // - les trier par ordre chronologique | 89 | // - les trier par ordre chronologique |
| 90 | // - rendre quasi impossible d'avoir deux fois le même nom (à la condition de gérer la "concurrence") | 90 | // - rendre quasi impossible d'avoir deux fois le même nom |
| 91 | $fileName = 'data/' . $this->page . '/' . $this->format . '/' . $this->time . '.' . $this->format; | 91 | $fileName = 'data/' . $this->page . '/' . $this->format . '/' . $this->time . '.' . $this->format; |
| 92 | 92 | ||
| 93 | $file = fopen($fileName, 'w'); // w pour créer ou écraser | 93 | $file = fopen($fileName, 'w'); // w pour créer ou écraser |
diff --git a/model/Image.php b/model/Image.php index e8bf3f9..05773e9 100644 --- a/model/Image.php +++ b/model/Image.php | |||
| @@ -4,7 +4,10 @@ | |||
| 4 | class Image | 4 | class Image |
| 5 | { | 5 | { |
| 6 | private $page; | 6 | private $page; |
| 7 | |||
| 7 | private $ajax; // vaut true avec le ckeditor | 8 | private $ajax; // vaut true avec le ckeditor |
| 9 | public $reponseAjax; | ||
| 10 | |||
| 8 | public $path; | 11 | public $path; |
| 9 | public $pathMini; | 12 | public $pathMini; |
| 10 | public $pathInfos; | 13 | public $pathInfos; |
| @@ -51,9 +54,8 @@ class Image | |||
| 51 | // retour des rêquetes AJAX | 54 | // retour des rêquetes AJAX |
| 52 | if($this->ajax && empty($Image->erreur)) | 55 | if($this->ajax && empty($Image->erreur)) |
| 53 | { | 56 | { |
| 54 | // nouveau chemin à renvoyer en format json | 57 | // chemin en JSON attendu par l'éditeur |
| 55 | $chemin = '{"url": "data/' . $this->page . '/images/' . $_FILES['upload']['name'] . '"}'; | 58 | $this->reponseAjax = '{"url": "data/' . $this->page . '/images/' . $_FILES['upload']['name'] . '"}'; |
| 56 | echo $chemin; | ||
| 57 | } | 59 | } |
| 58 | } | 60 | } |
| 59 | 61 | ||
diff --git a/public/css/accueil.css b/public/css/accueil.css index 0bf838d..8425cfa 100644 --- a/public/css/accueil.css +++ b/public/css/accueil.css | |||
| @@ -82,7 +82,6 @@ img | |||
| 82 | 82 | ||
| 83 | .boutonAnnuler:hover | 83 | .boutonAnnuler:hover |
| 84 | { | 84 | { |
| 85 | /*text-decoration: none;*/ | ||
| 86 | border: none; | 85 | border: none; |
| 87 | } | 86 | } |
| 88 | 87 | ||
| @@ -126,10 +125,6 @@ form | |||
| 126 | text-decoration: none; | 125 | text-decoration: none; |
| 127 | } | 126 | } |
| 128 | 127 | ||
| 129 | #courriel a:hover | ||
| 130 | { | ||
| 131 | /*padding: 5px;*/ | ||
| 132 | } | ||
| 133 | #courriel>button /* bouton pour remonter */ | 128 | #courriel>button /* bouton pour remonter */ |
| 134 | { | 129 | { |
| 135 | float: right; | 130 | float: right; |
| @@ -163,11 +158,6 @@ form | |||
| 163 | margin: 0px; | 158 | margin: 0px; |
| 164 | padding: 2px; | 159 | padding: 2px; |
| 165 | } | 160 | } |
| 166 | #modeAdmin>div p | ||
| 167 | { | ||
| 168 | /*margin: 5px;*/ | ||
| 169 | /*padding: 0px;*/ | ||
| 170 | } | ||
| 171 | #modeAdmin>p a | 161 | #modeAdmin>p a |
| 172 | { | 162 | { |
| 173 | text-decoration: none; | 163 | text-decoration: none; |
| @@ -176,26 +166,18 @@ form | |||
| 176 | 166 | ||
| 177 | #lienModeAdmin | 167 | #lienModeAdmin |
| 178 | { | 168 | { |
| 179 | margin: 0px 20px; | 169 | font-size: 90%; |
| 180 | } | 170 | margin-top: 10px; |
| 181 | 171 | margin-right: 30px; | |
| 182 | #lienModeAdmin p | ||
| 183 | { | ||
| 184 | text-align: right; | 172 | text-align: right; |
| 185 | /* enlever la bande bleue en dessous du bloc_page */ | 173 | /* enlever la bande bleue en dessous du bloc_page */ |
| 186 | margin-bottom: 0; | 174 | /*margin-bottom: 0;*/ |
| 187 | padding-bottom: 5px; | 175 | padding-bottom: 8px; |
| 188 | } | ||
| 189 | |||
| 190 | #lienModeAdmin p a | ||
| 191 | { | ||
| 192 | color: #666; | ||
| 193 | font-weight: bold; | ||
| 194 | padding: 2px; | ||
| 195 | } | 176 | } |
| 196 | 177 | ||
| 197 | #lienModeAdmin p a:hover | 178 | #lienModeAdmin a |
| 198 | { | 179 | { |
| 180 | text-decoration: none; | ||
| 199 | color: black; | 181 | color: black; |
| 200 | } | 182 | } |
| 201 | 183 | ||
| @@ -239,16 +221,17 @@ form | |||
| 239 | color: initial; | 221 | color: initial; |
| 240 | } | 222 | } |
| 241 | 223 | ||
| 224 | button | ||
| 225 | { | ||
| 226 | padding: 1px; | ||
| 227 | } | ||
| 228 | |||
| 242 | /* options au survol */ | 229 | /* options au survol */ |
| 243 | #options | 230 | #options |
| 244 | { | 231 | { |
| 245 | /*display: none;*/ | 232 | /*display: none;*/ |
| 246 | display: flex; | 233 | display: flex; |
| 247 | } | 234 | } |
| 248 | /*#modeAdmin:hover #options | ||
| 249 | { | ||
| 250 | display: flex; | ||
| 251 | }*/ | ||
| 252 | 235 | ||
| 253 | 236 | ||
| 254 | /* PC, y compris vieux écrans 800x600 */ | 237 | /* PC, y compris vieux écrans 800x600 */ |
| @@ -494,6 +477,11 @@ form | |||
| 494 | max-width: 180px; | 477 | max-width: 180px; |
| 495 | } | 478 | } |
| 496 | 479 | ||
| 480 | #lienModeAdmin | ||
| 481 | { | ||
| 482 | margin-right: 20px; | ||
| 483 | } | ||
| 484 | |||
| 497 | .zoneVideAdmin, #modeAdmin | 485 | .zoneVideAdmin, #modeAdmin |
| 498 | { | 486 | { |
| 499 | height: 61px; | 487 | height: 61px; |
| @@ -503,18 +491,6 @@ form | |||
| 503 | { | 491 | { |
| 504 | max-width: 380px; | 492 | max-width: 380px; |
| 505 | } | 493 | } |
| 506 | |||
| 507 | .boutonBackup | ||
| 508 | { | ||
| 509 | /*margin: 5px;*/ | ||
| 510 | /*padding: 1px;*/ | ||
| 511 | |||
| 512 | } | ||
| 513 | #modeAdmin button | ||
| 514 | { | ||
| 515 | font-size: 95%; | ||
| 516 | padding: 1px; | ||
| 517 | } | ||
| 518 | } | 494 | } |
| 519 | 495 | ||
| 520 | /* spécialement pour les petits smartphones*/ | 496 | /* spécialement pour les petits smartphones*/ |
diff --git a/public/file_upload.js b/public/file_upload.js new file mode 100644 index 0000000..8106806 --- /dev/null +++ b/public/file_upload.js | |||
| @@ -0,0 +1,103 @@ | |||
| 1 | // public/file_upload.js | ||
| 2 | |||
| 3 | // envoie gros fichier ZIP | ||
| 4 | // ce fichier est "caché", le serveur ne l'envoit | ||
| 5 | // qu'un utilisateur connecté et sur la page "restauration" | ||
| 6 | |||
| 7 | // -> input file onchange | ||
| 8 | function sendFileSize() | ||
| 9 | { | ||
| 10 | var tagId = 'archiveUpload'; | ||
| 11 | var fileInfos = getFileInfo(tagId); | ||
| 12 | //var fileSize = document.getElementById(tagId).files[0].size; | ||
| 13 | |||
| 14 | const xhr = new XMLHttpRequest(); | ||
| 15 | url = 'index.php?action=restauration&file_name='+fileInfos.name+'&file_size='+fileInfos.size; | ||
| 16 | xhr.open("GET", url); | ||
| 17 | xhr.send(); | ||
| 18 | } | ||
| 19 | |||
| 20 | // -> input submit onclick | ||
| 21 | function uploadDespiteServerMaxWeightLimit(maxPHPiniWeight, archiveFormat) | ||
| 22 | { | ||
| 23 | // dans <input id="archiveUpload" type="file" > | ||
| 24 | var tagId = 'archiveUpload'; | ||
| 25 | //var fileInfos = getFileInfo(tagId); | ||
| 26 | var file = document.getElementById(tagId).files[0]; | ||
| 27 | |||
| 28 | // si le le fichier est assez léger, javascript s'arrête ici | ||
| 29 | if(file.size > maxPHPiniWeight) | ||
| 30 | { | ||
| 31 | // découpage | ||
| 32 | // envoyer et recevoir des pointeurs pour les perfs | ||
| 33 | // chunksArray est un tableau de "blob" | ||
| 34 | var nbChunks = Math.ceil(file.size / maxPHPiniWeight); | ||
| 35 | var chunksArray = sliceFile(file, nbChunks); | ||
| 36 | |||
| 37 | // requêtes AJAX | ||
| 38 | chunkIndex = 0; // une variable globale | ||
| 39 | uploadChunksAJAX(chunksArray, tagId); | ||
| 40 | |||
| 41 | // annule l'envoi normal par POST | ||
| 42 | event.preventDefault(); | ||
| 43 | |||
| 44 | // vider le formulaire et recharger | ||
| 45 | // reload() est un F5 et non un Ctrl + F5 | ||
| 46 | //document.getElementById(tagId).value = ''; | ||
| 47 | //location.reload(); | ||
| 48 | |||
| 49 | location.href = "index.php?from=menu&action=restauration"; | ||
| 50 | } | ||
| 51 | } | ||
| 52 | |||
| 53 | function getFileInfo(tagId) | ||
| 54 | { | ||
| 55 | var infos = | ||
| 56 | { | ||
| 57 | name: document.getElementById(tagId).files[0].name, | ||
| 58 | size: document.getElementById(tagId).files[0].size, | ||
| 59 | type: document.getElementById(tagId).files[0].type, | ||
| 60 | } | ||
| 61 | |||
| 62 | return(infos); | ||
| 63 | } | ||
| 64 | |||
| 65 | function sliceFile(file, nbChunks) | ||
| 66 | { | ||
| 67 | var byteIndex = 0; // octet du début | ||
| 68 | var chunks = []; // données | ||
| 69 | |||
| 70 | for (var i = 0; i < nbChunks; i += 1) | ||
| 71 | { | ||
| 72 | // octet de fin | ||
| 73 | var byteEnd = Math.ceil((file.size / nbChunks) * (i + 1)); | ||
| 74 | |||
| 75 | // un morceau du fichier va dans une case du tableau | ||
| 76 | chunks.push(file.slice(byteIndex, byteEnd)); | ||
| 77 | |||
| 78 | // nouvel octet du début | ||
| 79 | byteIndex += (byteEnd - byteIndex); | ||
| 80 | } | ||
| 81 | |||
| 82 | return chunks; | ||
| 83 | } | ||
| 84 | |||
| 85 | function uploadChunksAJAX(chunksArray, tagId) | ||
| 86 | { | ||
| 87 | var fileName = document.getElementById(tagId).files[0].name; | ||
| 88 | var formData = new FormData(); | ||
| 89 | const xhr = new XMLHttpRequest(); | ||
| 90 | |||
| 91 | for(var i = 0; i < chunksArray.length; i++) | ||
| 92 | { | ||
| 93 | formData.append('blob', chunksArray[i]); | ||
| 94 | |||
| 95 | url = 'index.php?from=menu&action=restauration&chunk_name='+fileName+'_'+i; | ||
| 96 | // false => synchrone, déprécié parce que fige le navigateur | ||
| 97 | // mais ici on s'en fout | ||
| 98 | xhr.open("POST", url, false); | ||
| 99 | xhr.send(formData); | ||
| 100 | |||
| 101 | formData.delete('blob'); | ||
| 102 | } | ||
| 103 | } | ||
diff --git a/public/main.js b/public/main.js index 5ca23c7..ede1a30 100644 --- a/public/main.js +++ b/public/main.js | |||
| @@ -29,16 +29,7 @@ function confirmerSuppression() // appel 'onCLick' | |||
| 29 | 29 | ||
| 30 | // code exécuté à la validation du formulaire | 30 | // code exécuté à la validation du formulaire |
| 31 | function envoiDonnees() | 31 | function envoiDonnees() |
| 32 | { | 32 | {} |
| 33 | // supprimer le positionnement absolu de l'iframe | ||
| 34 | /*let balisesIframe = document.getElementsByTagName("iframe"); | ||
| 35 | for(var i = 0; i < balisesIframe.length; i++) | ||
| 36 | { | ||
| 37 | alert(balisesIframe[i].getAttribute("style")); // affiche le CSS | ||
| 38 | balisesIframe[i].removeAttribute("style"); | ||
| 39 | alert(balisesIframe[i].getAttribute("style")); // affiche null | ||
| 40 | }*/ | ||
| 41 | } | ||
| 42 | 33 | ||
| 43 | // bouton "mailto", le visiteur ne quitte pas la page | 34 | // bouton "mailto", le visiteur ne quitte pas la page |
| 44 | function clientCourriel() | 35 | function clientCourriel() |
| @@ -89,38 +80,3 @@ function nouveauMotdepasse(page) | |||
| 89 | alert('Le mot de passe a été modifié.'); | 80 | alert('Le mot de passe a été modifié.'); |
| 90 | window.setTimeout(location=('index.php?page=' + page + '&message=nouveau_mdp'), 0); | 81 | window.setTimeout(location=('index.php?page=' + page + '&message=nouveau_mdp'), 0); |
| 91 | } | 82 | } |
| 92 | |||
| 93 | // envoie gros fichier ZIP | ||
| 94 | // si le fichier ne passe pas la limite de l'hébergeur (php.ini) | ||
| 95 | // l'ouvrir en javascript chaque envoyer progressivement | ||
| 96 | function getFileInfo() | ||
| 97 | { | ||
| 98 | // l'idi est dans le formulaire | ||
| 99 | var name = document.getElementById('myFile').files[0].name; | ||
| 100 | var size = document.getElementById('myFile').files[0].size; | ||
| 101 | var type = document.getElementById('myFile').files[0].type; | ||
| 102 | var date = document.getElementById('myFile').files[0].lastModifiedDate; | ||
| 103 | |||
| 104 | var infos = name+" "+size+" "+type+" "+date; | ||
| 105 | alert(infos) | ||
| 106 | return(infos); | ||
| 107 | } | ||
| 108 | |||
| 109 | function extraireZIPetEnvoyerUnParUn(maxPHPiniWeight, archiveFormat) | ||
| 110 | { | ||
| 111 | // taille du fichier? | ||
| 112 | var fileInfos = getFileInfo(); | ||
| 113 | alert(fileInfos); | ||
| 114 | |||
| 115 | // taille limite autorisée? | ||
| 116 | // obtenue par php avec: ini_get('upload_max_filesize'); | ||
| 117 | |||
| 118 | // si le fichier est plus gros que la limite: | ||
| 119 | // extraire l'archive | ||
| 120 | // envoyer les fichiers un par un par des requêtes AJAX | ||
| 121 | // le serveur peut aussi limiter le nombre de fichiers | ||
| 122 | // lors d'un envoie multiple | ||
| 123 | // en les envoyant un par un ça devrait être bon | ||
| 124 | |||
| 125 | // sinon ne rien faire et laisser l'envoi normal se faire | ||
| 126 | } | ||
diff --git a/view/backup.php b/view/backup.php index 30b644b..bbea60d 100644 --- a/view/backup.php +++ b/view/backup.php | |||
| @@ -54,15 +54,15 @@ elseif(isset($_GET['action']) && $_GET['action'] == 'restauration') | |||
| 54 | ob_start(); | 54 | ob_start(); |
| 55 | ?> | 55 | ?> |
| 56 | <h2>Restauration des données à partir d'une sauvegarde.</h2> | 56 | <h2>Restauration des données à partir d'une sauvegarde.</h2> |
| 57 | <p>Vous devez avoir créé précédemment un fichier <i>melaineDATA</i><br/> | 57 | <p>Vous devez avoir créé précédemment un fichier dont le nom commence par <i>melaineDATA</i><br/> |
| 58 | à la page <i>Sauvegarder les données.</i></p><br/> | 58 | à la page <i>Sauvegarder les données.</i></p><br/> |
| 59 | 59 | ||
| 60 | <form method="post" enctype="multipart/form-data" action="index.php?from=<?= $from ?>&action=restauration" > | 60 | <form method="post" enctype="multipart/form-data" action="index.php?from=<?= $from ?>&action=restauration" > |
| 61 | <input type="file" name="archive" accept=".zip" class="boutonBackup" ><br/> | 61 | <input id="archiveUpload" type="file" name="archive" accept=".zip" class="boutonBackup" onchange="sendFileSize();" ><br/> |
| 62 | 62 | ||
| 63 | <!-- demande de confirmation en JS au submit --> | 63 | <!-- demande de confirmation en JS au submit --> |
| 64 | 64 | ||
| 65 | <input type="submit" class="boutonBackup" value="Valider" > | 65 | <input type="submit" class="boutonBackup" value="Valider" onclick="uploadDespiteServerMaxWeightLimit(<?= $maxWeight ?>);" > |
| 66 | <?= $message ?> | 66 | <?= $message ?> |
| 67 | </form> | 67 | </form> |
| 68 | <button class="boutonBackup" ><a href="index.php?page=<?= $from ?>" >Retour au site</a></button> | 68 | <button class="boutonBackup" ><a href="index.php?page=<?= $from ?>" >Retour au site</a></button> |
| @@ -82,7 +82,7 @@ elseif(isset($_GET['action']) && $_GET['action'] == 'restauration') | |||
| 82 | <?php | 82 | <?php |
| 83 | if(isset($_GET['action']) && $_GET['action'] == 'restauration') | 83 | if(isset($_GET['action']) && $_GET['action'] == 'restauration') |
| 84 | { | 84 | { |
| 85 | echo('<script type="text/javascript" src="public/main.js" ></script>'); | 85 | echo('<script type="text/javascript" src="public/file_upload.js" ></script>'); |
| 86 | } | 86 | } |
| 87 | ?> | 87 | ?> |
| 88 | <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | 88 | <meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
| @@ -91,5 +91,5 @@ if(isset($_GET['action']) && $_GET['action'] == 'restauration') | |||
| 91 | <div id="bloc_page" style="padding: 10px;" > | 91 | <div id="bloc_page" style="padding: 10px;" > |
| 92 | <?= $content ?> | 92 | <?= $content ?> |
| 93 | </div> | 93 | </div> |
| 94 | </body> | 94 | </body> |
| 95 | </html> \ No newline at end of file | 95 | </html> \ No newline at end of file |
diff --git a/view/template.php b/view/template.php index 93881f4..7fafbbb 100644 --- a/view/template.php +++ b/view/template.php | |||
| @@ -8,7 +8,7 @@ | |||
| 8 | <!-- partie que Melaine doit écrire --> | 8 | <!-- partie que Melaine doit écrire --> |
| 9 | <meta name="description" content="" /> | 9 | <meta name="description" content="" /> |
| 10 | 10 | ||
| 11 | <!-- <link rel="shortcut icon" type="image/x-icon" href="favicon.ico" /> --> | 11 | <!-- <link rel="shortcut icon" type="image/x-icon" href="public/favicon.ico" /> --> |
| 12 | <link rel="icon" type="image/png" href="public/mouette-logo.png" > | 12 | <link rel="icon" type="image/png" href="public/mouette-logo.png" > |
| 13 | <link rel="stylesheet" type="text/css" href="public/css/normalize.css"> | 13 | <link rel="stylesheet" type="text/css" href="public/css/normalize.css"> |
| 14 | <link rel="stylesheet" type="text/css" href="public/css/accueil.css" /> | 14 | <link rel="stylesheet" type="text/css" href="public/css/accueil.css" /> |
| @@ -57,7 +57,7 @@ if($_SESSION['admin'] == 0 && isset($_GET['page']) && $_GET['page'] != 'accueil' | |||
| 57 | { | 57 | { |
| 58 | ?> | 58 | ?> |
| 59 | <div id="lienModeAdmin" > | 59 | <div id="lienModeAdmin" > |
| 60 | <p><a href="index.php?page=connexion&from=<?= $page ?>" >Mode Administrateur</a></p> | 60 | <button><a href="index.php?page=connexion&from=<?= $page ?>" >Mode Administrateur</a></button> |
| 61 | </div> | 61 | </div> |
| 62 | <?php | 62 | <?php |
| 63 | } | 63 | } |
