diff --git a/core/core.php b/core/core.php
index 47886918..be30cfef 100644
--- a/core/core.php
+++ b/core/core.php
@@ -1285,7 +1285,7 @@ class common
if (!$file->isDir()) {
$filePath = $file->getRealPath();
$relativePath = substr($filePath, strlen(realpath($folder)) + 1);
- $zip->addFile($filePath, $relativePath);
+ $zip->addFile($filePath, str_replace("\\", "/", $relativePath));
}
}
$zip->close();
diff --git a/core/module/config/config.php b/core/module/config/config.php
index 9f4c80da..3b0d3977 100644
--- a/core/module/config/config.php
+++ b/core/module/config/config.php
@@ -628,6 +628,7 @@ class config extends common
$fileName = self::DATA_DIR . 'journal.log';
if (file_exists($fileName)) {
ob_start();
+ header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $fileName . '"');
header('Content-Length: ' . filesize($fileName));
@@ -663,7 +664,9 @@ class config extends common
$data .= $key . ';' . $item['ip'] . ';' . $item['connectFail'] . PHP_EOL;
}
file_put_contents($fileName, $data, FILE_APPEND);
+ header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
+ header('Content-Transfer-Encoding: binary');
header('Content-Disposition: attachment; filename="' . $fileName . '"');
header('Content-Length: ' . filesize($fileName));
ob_clean();
diff --git a/core/module/plugin/plugin.php b/core/module/plugin/plugin.php
index 862b1a1f..2157f836 100644
--- a/core/module/plugin/plugin.php
+++ b/core/module/plugin/plugin.php
@@ -20,13 +20,18 @@ class plugin extends common
public static $actions = [
'index' => self::GROUP_ADMIN,
'delete' => self::GROUP_ADMIN,
- 'save' => self::GROUP_ADMIN, // Sauvegarde le module dans un fichier ZIP ou dans le gestionnaire
- 'dataExport' => self::GROUP_ADMIN, // Fonction muette d'exportation
- 'dataImport' => self::GROUP_ADMIN, // les données d'un module
+ 'save' => self::GROUP_ADMIN,
+ // Sauvegarde le module dans un fichier ZIP ou dans le gestionnaire
+ 'dataExport' => self::GROUP_ADMIN,
+ // Fonction muette d'exportation
+ 'dataImport' => self::GROUP_ADMIN,
+ // les données d'un module
'dataDelete' => self::GROUP_ADMIN,
'store' => self::GROUP_ADMIN,
- 'item' => self::GROUP_ADMIN, // détail d'un objet
- 'upload' => self::GROUP_ADMIN, // Téléverser catalogue
+ 'item' => self::GROUP_ADMIN,
+ // détail d'un objet
+ 'upload' => self::GROUP_ADMIN,
+ // Téléverser catalogue
'uploadItem' => self::GROUP_ADMIN // Téléverser par archive
];
@@ -51,8 +56,8 @@ class plugin extends common
/*
- * Effacement d'un module installé et non utilisé
- */
+ * Effacement d'un module installé et non utilisé
+ */
public function delete()
{
@@ -60,7 +65,7 @@ class plugin extends common
if ($this->getUrl(3) !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
- 'redirect' => helper::baseUrl() . 'plugin',
+ 'redirect' => helper::baseUrl() . 'plugin',
'state' => false,
'notification' => helper::translate('Action interdite')
]);
@@ -183,7 +188,7 @@ class plugin extends common
* Le module est-il déjà installé ?
* Si oui lire le numéro de version et le stocker dans $versionInstalled
*/
- if (is_file(self::MODULE_DIR . $module['name'] . '/' . $module['name'] . '.php')) {
+ if (is_file(self::MODULE_DIR . $module['name'] . '/' . $module['name'] . '.php')) {
$c = helper::getModules();
if (array_key_exists($module['name'], $c)) {
$versionInstalled = $c[$module['name']]['version'];
@@ -231,7 +236,7 @@ class plugin extends common
return ([
'success' => $success,
'notification' => $success ? sprintf(helper::translate('Le module %s a été %s'), $module['name'], $t)
- : helper::translate('Erreur inconnue, le module n\'est pas installé')
+ : helper::translate('Erreur inconnue, le module n\'est pas installé')
]);
} else {
return ([
@@ -260,7 +265,7 @@ class plugin extends common
if ($this->isPost()) {
// Installation d'un module
$checkValidMaj = $this->getInput('configModulesCheck', helper::FILTER_BOOLEAN);
- $zipFilename = $this->getInput('configModulesInstallation', helper::FILTER_STRING_SHORT);
+ $zipFilename = $this->getInput('configModulesInstallation', helper::FILTER_STRING_SHORT);
if ($zipFilename !== '') {
$state = $this->install(self::FILE_DIR . 'source/' . $zipFilename, $checkValidMaj);
}
@@ -286,7 +291,7 @@ class plugin extends common
if ($this->getUrl(3) !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
- 'redirect' => helper::baseUrl() . 'store',
+ 'redirect' => helper::baseUrl() . 'store',
'state' => false,
'notification' => helper::translate('Action interdite')
]);
@@ -318,7 +323,7 @@ class plugin extends common
}
// Valeurs en sortie
$this->addOutput([
- 'redirect' => helper::baseUrl() . 'plugin/store',
+ 'redirect' => helper::baseUrl() . 'plugin/store',
'notification' => $r['notification'],
'state' => $r['success']
]);
@@ -359,7 +364,7 @@ class plugin extends common
// Le module est installé et utilisé
if (array_key_exists($key, $inPages) === true) {
$class = 'buttonRed';
- $ico = template::ico('update');
+ $ico = template::ico('update');
$help = 'Mettre à jour le module attaché, une sauvegarde des données de module est recommandée !';
}
self::$storeList[] = [
@@ -370,7 +375,8 @@ class plugin extends common
implode(', ', array_keys($pagesInfos, $key)),
template::button('moduleExport' . $key, [
'class' => $class,
- 'href' => helper::baseUrl() . $this->getUrl(0) . '/uploadItem/' . $key . '/' . $_SESSION['csrf'], // appel de fonction vaut exécution, utiliser un paramètre
+ 'href' => helper::baseUrl() . $this->getUrl(0) . '/uploadItem/' . $key . '/' . $_SESSION['csrf'],
+ // appel de fonction vaut exécution, utiliser un paramètre
'value' => $ico,
'help' => $help
])
@@ -461,13 +467,13 @@ class plugin extends common
$infoModules[$key]['version'],
'',
$infoModules[$key]['delete'] === true
- ? template::button('moduleDelete' . $key, [
- 'class' => 'moduleDelete buttonRed',
- 'href' => helper::baseUrl() . $this->getUrl(0) . '/delete/' . $key . '/' . $_SESSION['csrf'],
- 'value' => template::ico('trash'),
- 'help' => 'Supprimer le module'
- ])
- : '',
+ ? template::button('moduleDelete' . $key, [
+ 'class' => 'moduleDelete buttonRed',
+ 'href' => helper::baseUrl() . $this->getUrl(0) . '/delete/' . $key . '/' . $_SESSION['csrf'],
+ 'value' => template::ico('trash'),
+ 'help' => 'Supprimer le module'
+ ])
+ : '',
];
}
@@ -513,19 +519,22 @@ class plugin extends common
self::$modulesData[] = [
$infoModules[$pagesInfos[$keyi18n][$keyPage]['moduleId']]['realName'] . ' (' . $pagesInfos[$keyi18n][$keyPage]['moduleId'] . ')',
$infoModules[$pagesInfos[$keyi18n][$keyPage]['moduleId']]['version'],
- template::flag($keyi18n, '20px') . ' ' . $pagesInfos[$keyi18n][$keyPage]['title'] . ' (' . $keyPage . ')',
+ template::flag($keyi18n, '20px') . ' ' . $pagesInfos[$keyi18n][$keyPage]['title'] . ' (' . $keyPage . ')',
template::button('dataExport' . $keyPage, [
- 'href' => helper::baseUrl() . $this->getUrl(0) . '/dataExport/filemanager/' . self::$i18nContent . '/' . $pagesInfos[$keyi18n][$keyPage]['moduleId'] . '/' . $keyPage . '/' . $_SESSION['csrf'], // appel de fonction vaut exécution, utiliser un paramètre
+ 'href' => helper::baseUrl() . $this->getUrl(0) . '/dataExport/filemanager/' . self::$i18nContent . '/' . $pagesInfos[$keyi18n][$keyPage]['moduleId'] . '/' . $keyPage . '/' . $_SESSION['csrf'],
+ // appel de fonction vaut exécution, utiliser un paramètre
'value' => template::ico('download-cloud'),
'help' => 'Sauvegarder les données du module dans le gestionnaire de fichiers'
]),
template::button('dataExport' . $keyPage, [
- 'href' => helper::baseUrl() . $this->getUrl(0) . '/dataExport/download/' . self::$i18nContent . '/' . $pagesInfos[$keyi18n][$keyPage]['moduleId'] . '/' . $keyPage . '/' . $_SESSION['csrf'], // appel de fonction vaut exécution, utiliser un paramètre
+ 'href' => helper::baseUrl() . $this->getUrl(0) . '/dataExport/download/' . self::$i18nContent . '/' . $pagesInfos[$keyi18n][$keyPage]['moduleId'] . '/' . $keyPage . '/' . $_SESSION['csrf'],
+ // appel de fonction vaut exécution, utiliser un paramètre
'value' => template::ico('download'),
'help' => 'Sauvegarder et télécharger les données du module'
]),
template::button('dataDelete' . $keyPage, [
- 'href' => helper::baseUrl() . $this->getUrl(0) . '/dataDelete/' . self::$i18nContent . '/' . $pagesInfos[$keyi18n][$keyPage]['moduleId'] . '/' . $keyPage . '/' . $_SESSION['csrf'], // appel de fonction vaut exécution, utiliser un paramètre
+ 'href' => helper::baseUrl() . $this->getUrl(0) . '/dataDelete/' . self::$i18nContent . '/' . $pagesInfos[$keyi18n][$keyPage]['moduleId'] . '/' . $keyPage . '/' . $_SESSION['csrf'],
+ // appel de fonction vaut exécution, utiliser un paramètre
'value' => template::ico('trash'),
'class' => 'buttonRed dataDelete',
'help' => 'Détacher le module de la page',
@@ -554,7 +563,7 @@ class plugin extends common
if ($this->getUrl(4) !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
- 'redirect' => helper::baseUrl() . 'plugin',
+ 'redirect' => helper::baseUrl() . 'plugin',
'state' => false,
'notification' => helper::translate('Action interdite')
]);
@@ -572,20 +581,20 @@ class plugin extends common
// Descripteur de l'archive
$infoModule = helper::getModules();
//Nom de l'archive
- $fileName = $moduleId . $infoModule[$moduleId]['version'] . '.zip';
+ $fileName = $moduleId . $infoModule[$moduleId]['version'] . '.zip';
// Régénération du module
$success = file_put_contents(self::MODULE_DIR . $moduleId . '/enum.json', json_encode($infoModule[$moduleId]));
// Construire l'archive
- $this->makeZip(self::TEMP_DIR . $fileName, self::MODULE_DIR . $moduleId);
+ $this->makeZip(self::TEMP_DIR . $fileName, self::MODULE_DIR . $moduleId);
switch ($action) {
case 'filemanager':
if (!file_exists(self::FILE_DIR . 'source/modules')) {
mkdir(self::FILE_DIR . 'source/modules');
}
- $success = $success && copy(self::TEMP_DIR . $fileName, self::FILE_DIR . 'source/modules/' . $moduleId . '.zip');
+ $success = $success && copy(self::TEMP_DIR . $fileName, self::FILE_DIR . 'source/modules/' . $moduleId . '.zip');
// Valeurs en sortie
$this->addOutput([
@@ -599,15 +608,16 @@ class plugin extends common
break;
case 'download':
default:
+
+ // Téléchargement du ZIP
+ header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
+ header('Content-Transfer-Encoding: binary');
header('Content-Disposition: attachment; filename="' . $fileName . '"');
- header('Content-Length: ' . filesize(self::TEMP_DIR . $fileName));
- ob_clean();
- ob_end_flush();
- readfile(self::TEMP_DIR . $fileName);
- // Nettoyage
- unlink(self::TEMP_DIR . $fileName);
- $this->removeDir($tmpFolder);
+ header('Content-Length: ' . filesize(self::TEMP_DIR . $fileName));
+ readfile(self::TEMP_DIR . $fileName);
+ // Nettoyage du dossier
+ unlink(self::TEMP_DIR . $fileName);
exit();
}
}
@@ -615,19 +625,19 @@ class plugin extends common
/*
- * Détacher un module d'une page en supprimant les données du module
- * 2 : i18n id
- * 3 : moduleId
- * 4 : pageId
- * 5 : CSRF
- */
+ * Détacher un module d'une page en supprimant les données du module
+ * 2 : i18n id
+ * 3 : moduleId
+ * 4 : pageId
+ * 5 : CSRF
+ */
public function dataDelete()
{
// Jeton incorrect
if ($this->getUrl(5) !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
- 'redirect' => helper::baseUrl() . 'plugin',
+ 'redirect' => helper::baseUrl() . 'plugin',
'state' => false,
'notification' => helper::translate('Action interdite')
]);
@@ -645,20 +655,20 @@ class plugin extends common
/*
- * Export des données d'un module
- * Structure de l'adresse reçue
- * 2 : i18n id
- * 3 : moduleId
- * 4 : pageId
- * 5 : CSRF
- */
+ * Export des données d'un module
+ * Structure de l'adresse reçue
+ * 2 : i18n id
+ * 3 : moduleId
+ * 4 : pageId
+ * 5 : CSRF
+ */
public function dataExport()
{
// Jeton incorrect
if ($this->getUrl(6) !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
- 'redirect' => helper::baseUrl() . 'plugin',
+ 'redirect' => helper::baseUrl() . 'plugin',
'state' => false,
'notification' => helper::translate('Action interdite')
]);
@@ -675,7 +685,7 @@ class plugin extends common
$moduleId = $this->getUrl(4);
$pageId = $this->getUrl(5);
- // DOnnèes du module de la page sléectionnée
+ // DOnnèes du module de la page sélectionnée
$moduleData = $this->getData(['module', $pageId]);
// Descripteur du module
@@ -687,16 +697,16 @@ class plugin extends common
$success = $success && is_int(file_put_contents($tmpFolder . '/enum.json', json_encode([$moduleId => $infoModule])));
// Le dossier du module s'il existe
- if (is_dir(self::DATA_DIR . $moduleId . '/' . $pageId)) {
+ if (is_dir(self::DATA_DIR . $moduleId . '/' . $pageId)) {
// Copier le dossier des données
- $success = $success && $this->copyDir(self::DATA_DIR . '/' . $moduleId . '/' . $pageId, $tmpFolder . '/dataDirectory');
+ $success = $success && $this->copyDir(self::DATA_DIR . '/' . $moduleId . '/' . $pageId, $tmpFolder . '/dataDirectory');
}
// Création du zip
- $fileName = $lang . '-' . $moduleId . '-' . $pageId . '.zip';
+ $fileName = $lang . '-' . $moduleId . '-' . $pageId . '.zip';
$this->makeZip(self::TEMP_DIR . $fileName, $tmpFolder);
- // Gestin de l'action
+ // Gestion de l'action
if ($success) {
switch ($action) {
case 'filemanager':
@@ -718,16 +728,16 @@ class plugin extends common
break;
case 'download':
default:
- if (file_exists(self::TEMP_DIR . $fileName)) {
- ob_start();
+ if (file_exists(self::TEMP_DIR . $fileName)) {
+ // Téléchargement du ZIP
+ header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
- header('Content-Disposition: attachment; filename="' . self::TEMP_DIR . $fileName . '"');
+ header('Content-Transfer-Encoding: binary');
+ header('Content-Disposition: attachment; filename="' . $fileName . '"');
header('Content-Length: ' . filesize(self::TEMP_DIR . $fileName));
- ob_clean();
- ob_end_flush();
readfile(self::TEMP_DIR . $fileName);
+ // Nettoyage du dossier
unlink(self::TEMP_DIR . $fileName);
- $this->removeDir($tmpFolder);
exit();
}
}
@@ -743,15 +753,15 @@ class plugin extends common
}
/*
- * Importer des données d'un module externes ou interne à module.json
- */
+ * Importer des données d'un module externes ou interne à module.json
+ */
public function dataImport()
{
// Soumission du formulaire d'importation du module dans une page libre
if ($this->isPost()) {
// Récupérer le fichier et le décompacter
- $zipFilename = $this->getInput('pluginImportFile', helper::FILTER_STRING_SHORT, true);
+ $zipFilename = $this->getInput('pluginImportFile', helper::FILTER_STRING_SHORT, true);
$pageId = $this->getInput('pluginImportPage', null, true);
$tmpFolder = uniqid();
@@ -759,15 +769,15 @@ class plugin extends common
mkdir(self::TEMP_DIR . $tmpFolder, 0755);
$zip = new ZipArchive();
if ($zip->open(self::FILE_DIR . 'source/' . $zipFilename) === TRUE) {
- $zip->extractTo(self::TEMP_DIR . $tmpFolder);
+ $zip->extractTo(self::TEMP_DIR . $tmpFolder);
}
// Lire le descripteur
- $descripteur = json_decode(file_get_contents(self::TEMP_DIR . $tmpFolder . '/enum.json'), true);
+ $descripteur = json_decode(file_get_contents(self::TEMP_DIR . $tmpFolder . '/enum.json'), true);
$moduleId = array_key_first($descripteur);
// Lecture des données du module
- $moduleData = json_decode(file_get_contents(self::TEMP_DIR . $tmpFolder . '/module.json'), true);
+ $moduleData = json_decode(file_get_contents(self::TEMP_DIR . $tmpFolder . '/module.json'), true);
// Chargement des données du module importé
$this->setData(['module', $pageId, $moduleData]);
@@ -777,9 +787,9 @@ class plugin extends common
// Copie des fichiers d'accompagnement
// Le dossier du module s'il existe
- if (is_dir($tmpFolder . '/dataDirectory')) {
+ if (is_dir($tmpFolder . '/dataDirectory')) {
// Copier le dossier des données
- $this->copyDir($tmpFolder . '/dataDirectory', self::DATA_DIR . '/' . $moduleId . '/' . $pageId);
+ $this->copyDir($tmpFolder . '/dataDirectory', self::DATA_DIR . '/' . $moduleId . '/' . $pageId);
}
// Supprimer le dossier temporaire
@@ -799,7 +809,7 @@ class plugin extends common
if ($this->getUrl(3) !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
- 'redirect' => helper::baseUrl() . 'plugin',
+ 'redirect' => helper::baseUrl() . 'plugin',
'state' => false,
'notification' => helper::translate('Action interdite')
]);
@@ -809,7 +819,7 @@ class plugin extends common
// Valeurs en sortie
$this->addOutput([
- 'redirect' => helper::baseUrl() . 'plugin',
+ 'redirect' => helper::baseUrl() . 'plugin',
'state' => true,
'notification' => helper::translate('Données importées')
]);
@@ -839,4 +849,4 @@ class plugin extends common
'view' => 'dataImport'
]);
}
-}
+}
\ No newline at end of file
diff --git a/module/form/enum.json b/module/form/enum.json
index da38fafb..257baa13 100644
--- a/module/form/enum.json
+++ b/module/form/enum.json
@@ -1 +1 @@
-{"name":"form","realName":"Formulaire","version":"3.3","update":"0.0","delete":true,"dataDirectory":""}
\ No newline at end of file
+{"name":"form","realName":"Formulaire","version":"3.4","update":"0.0","delete":true,"dataDirectory":""}
\ No newline at end of file
diff --git a/module/gallery/enum.json b/module/gallery/enum.json
index 0da657e4..29a49b79 100644
--- a/module/gallery/enum.json
+++ b/module/gallery/enum.json
@@ -1 +1 @@
-{"name":"gallery","realName":"Galerie","version":"3.61","update":"0.0","delete":true,"dataDirectory":"site\/data\/gallery\/"}
\ No newline at end of file
+{"name":"gallery","realName":"Galerie","version":"3.7","update":"0.0","delete":true,"dataDirectory":"site\/data\/gallery\/"}
\ No newline at end of file
diff --git a/module/redirection/enum.json b/module/redirection/enum.json
index 2e30beee..30e7773c 100644
--- a/module/redirection/enum.json
+++ b/module/redirection/enum.json
@@ -1 +1 @@
-{"name":"redirection","realName":"Redirection","version":"1.5","update":"0.0","delete":true,"dataDirectory":""}
\ No newline at end of file
+{"name":"redirection","realName":"Redirection","version":"1.6","update":"0.0","delete":true,"dataDirectory":""}
\ No newline at end of file