ZwiiCMS/core/module/plugin/plugin.php

805 lines
25 KiB
PHP
Raw Normal View History

2022-02-17 15:45:25 +01:00
<?php
/**
* This file is part of Zwii.
*
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
*
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
2022-09-29 08:45:59 +02:00
* @copyright Copyright (C) 2018-2022, Frédéric Tempez
2022-02-17 15:45:25 +01:00
* @license GNU General Public License, version 3
* @link http://zwiicms.fr/
*/
2022-09-29 08:45:59 +02:00
class plugin extends common
{
2022-02-17 15:45:25 +01:00
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
'dataDelete' => self::GROUP_ADMIN,
2022-02-17 15:45:25 +01:00
'store' => self::GROUP_ADMIN,
'item' => self::GROUP_ADMIN, // détail d'un objet
'upload' => self::GROUP_ADMIN, // Téléverser catalogue
2022-09-29 08:45:59 +02:00
'uploadItem' => self::GROUP_ADMIN // Téléverser par archive
2022-02-17 15:45:25 +01:00
];
// URL des modules
const BASEURL_STORE = 'https://store.zwiicms.fr/';
2022-05-15 17:32:24 +02:00
const MODULE_STORE = 'modules-pour-zwii-v115/';
2022-02-17 15:45:25 +01:00
// Gestion des modules
public static $modulesData = [];
public static $modulesOrphan = [];
public static $modulesInstalled = [];
// pour tests
public static $valeur = [];
// le catalogue
public static $storeList = [];
public static $storeItem = [];
// Liste de pages
public static $pagesList = [];
/*
* Effacement d'un module installé et non utilisé
*/
2022-09-29 08:45:59 +02:00
public function delete()
{
2022-02-17 15:45:25 +01:00
// Jeton incorrect
if ($this->getUrl(3) !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'plugin',
'state' => false,
2022-10-11 10:33:44 +02:00
'notification' => helper::translate('Action interdite')
2022-02-17 15:45:25 +01:00
]);
2022-09-29 08:45:59 +02:00
} else {
2022-02-17 15:45:25 +01:00
// Suppression des dossiers
$infoModules = helper::getModules();
$module = $this->getUrl(2);
//Liste des dossiers associés au module non effacés
2022-09-29 08:45:59 +02:00
if ($this->removeDir('./module/' . $module) === true) {
2022-02-17 15:45:25 +01:00
$success = true;
2022-09-29 08:45:59 +02:00
$notification = 'Module ' . $module . ' désinstallé';
if (($infoModules[$this->getUrl(2)]['dataDirectory'])) {
if (
2022-09-29 08:45:59 +02:00
is_dir($infoModules[$this->getUrl(2)]['dataDirectory'])
&& !$this->removeDir($infoModules[$this->getUrl(2)]['dataDirectory'])
) {
2022-10-11 11:44:48 +02:00
$notification = sprintf(helper::translate('Le module %s est désinstallé, il reste peut-être des données dans %s'), $module, $infoModules[$this->getUrl(2)]['dataDirectory']);
2022-02-17 15:45:25 +01:00
}
}
2022-09-29 08:45:59 +02:00
} else {
2022-02-17 15:45:25 +01:00
$success = false;
2022-10-11 10:33:44 +02:00
$notification = helper::translate('La suppression a échoué');
2022-02-17 15:45:25 +01:00
}
2022-02-17 15:45:25 +01:00
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'plugin',
'notification' => $notification,
'state' => $success
]);
}
}
/***
* Installation d'un module
* Fonction utilisée par upload et storeUpload
*/
2022-09-29 08:45:59 +02:00
private function install($moduleFileName, $checkValid)
{
2022-03-18 14:15:21 +01:00
2022-04-08 09:47:35 +02:00
// Dossier temporaire
$tempFolder = uniqid() . '/';
//$tempFolder = 'truc/';
2022-03-18 14:15:21 +01:00
/**
* Désarchivage
*/
2022-02-17 15:45:25 +01:00
$zip = new ZipArchive();
2022-03-18 14:15:21 +01:00
if ($zip->open($moduleFileName) === TRUE) {
2022-04-08 09:47:35 +02:00
//Création du dossier temporaire et extraction
2022-09-29 08:45:59 +02:00
if (!is_dir(self::TEMP_DIR . $tempFolder)) {
mkdir(self::TEMP_DIR . $tempFolder, 0755);
2022-03-18 14:15:21 +01:00
}
2022-09-29 08:45:59 +02:00
$zip->extractTo(self::TEMP_DIR . $tempFolder);
2022-04-08 09:47:35 +02:00
/**
* Lecture du descripteur de ressource
* $module ['name'] = id du module, correspond à la classe
* $module ['realname'] = Nom complet du module
* $module ['version'] = version du module
* $module ['dirs'] @array
* 'dossier' => 'destination',
* 'download" => 'module/download'
*/
2022-09-29 08:45:59 +02:00
if (file_exists(self::TEMP_DIR . $tempFolder . 'desc.json')) {
$module = json_decode(file_get_contents(self::TEMP_DIR . $tempFolder . 'desc.json'), true);
} else {
// Message de retour
$this->removeDir(self::TEMP_DIR . $tempFolder);
$zip->close();
return ([
'success' => false,
2022-10-11 10:33:44 +02:00
'notification' => helper::translate('Archive invalide, le descripteur est absent')
2022-09-29 08:45:59 +02:00
]);
2022-03-18 14:15:21 +01:00
}
/**
* Validation des informations du descripteur
*/
2022-04-08 09:47:35 +02:00
foreach ($module['dirs'] as $src => $dest) {
// Vérification de la présence des dossier décrits
2022-09-29 08:45:59 +02:00
if (!is_dir(self::TEMP_DIR . $tempFolder . $src)) {
2022-04-08 09:47:35 +02:00
// Message de retour
$this->removeDir(self::TEMP_DIR . $tempFolder);
$zip->close();
2022-09-29 08:45:59 +02:00
return ([
2022-04-08 09:47:35 +02:00
'success' => false,
2022-10-11 10:33:44 +02:00
'notification' => helper::translate('Archive invalide, les dossiers ne correspondent pas au descripteur')
2022-04-08 09:47:35 +02:00
]);
}
// Interdire l'écriture dans le dossier core
2022-09-29 08:45:59 +02:00
if (strstr($dest, 'core') !== false) {
2022-04-08 09:47:35 +02:00
// Message de retour
$this->removeDir(self::TEMP_DIR . $tempFolder);
$zip->close();
2022-09-29 08:45:59 +02:00
return ([
2022-03-18 14:15:21 +01:00
'success' => false,
2022-10-11 10:33:44 +02:00
'notification' => helper::translate('Archive invalide, l\'écriture dans le dossier core est interdite')
2022-03-18 14:15:21 +01:00
]);
2022-04-08 09:47:35 +02:00
}
2022-03-18 14:15:21 +01:00
}
2022-04-08 09:47:35 +02:00
2022-03-18 14:15:21 +01:00
/**
2022-04-08 09:47:35 +02:00
* Validation de la présence du fichier de base du module
2022-03-18 14:15:21 +01:00
*/
2022-09-29 08:45:59 +02:00
if (!file_exists(self::TEMP_DIR . $tempFolder . $module['name'] . '/' . $module['name'] . '.php')) {
2022-04-08 09:47:35 +02:00
// Message de retour
$this->removeDir(self::TEMP_DIR . $tempFolder);
$zip->close();
2022-09-29 08:45:59 +02:00
return ([
2022-04-08 09:47:35 +02:00
'success' => false,
2022-10-11 10:33:44 +02:00
'notification' => helper::translate('Archive invalide, le fichier de classe est absent')
2022-04-08 09:47:35 +02:00
]);
}
/**
* Le module est-il déjà installé ?
* Si oui lire le numéro de version et le stocker dans $versionInstalled
*/
2022-09-29 08:45:59 +02:00
if (is_file(self::MODULE_DIR . $module['name'] . '/' . $module['name'] . '.php')) {
2022-03-18 14:15:21 +01:00
$c = helper::getModules();
2022-04-08 09:47:35 +02:00
if (array_key_exists($module['name'], $c)) {
$versionInstalled = $c[$module['name']]['version'];
2022-02-17 15:45:25 +01:00
}
2022-03-18 14:15:21 +01:00
}
2022-02-17 15:45:25 +01:00
2022-04-08 09:47:35 +02:00
// Le module est installé, contrôle de la version
$installOk = false;
2022-09-29 08:45:59 +02:00
if (isset($versionInstalled) === false) {
2022-04-08 09:47:35 +02:00
$installOk = true;
2022-09-29 08:45:59 +02:00
} elseif (version_compare($module['version'], $versionInstalled) >= 0) {
2022-04-08 09:47:35 +02:00
$installOk = true;
} else {
2022-09-29 08:45:59 +02:00
if (version_compare($module['version'], $versionInstalled) === -1) {
2022-04-08 09:47:35 +02:00
// Contrôle du forçage
if ($this->getInput('configModulesCheck', helper::FILTER_BOOLEAN) === true) {
$installOk = true;
} else {
// Message de retour
$this->removeDir(self::TEMP_DIR . $tempFolder);
$zip->close();
2022-09-29 08:45:59 +02:00
return ([
2022-04-08 09:47:35 +02:00
'success' => false,
2022-10-11 10:33:44 +02:00
'notification' => helper::translate('La version installée est plus récente')
2022-04-08 09:47:35 +02:00
]);
2022-02-17 15:45:25 +01:00
}
2022-04-08 09:47:35 +02:00
}
}
// Installation ou mise à jour du module valides
if ($installOk) {
// Copie récursive des dossiers
foreach ($module['dirs'] as $src => $dest) {
2022-09-29 08:45:59 +02:00
if (!is_dir(self::TEMP_DIR . $tempFolder . $src)) {
2022-04-08 09:47:35 +02:00
mkdir(self::TEMP_DIR . $tempFolder . $src);
2022-02-17 15:45:25 +01:00
}
2022-09-29 08:45:59 +02:00
$success = $this->copyDir(self::TEMP_DIR . $tempFolder . $src, $dest);
2022-02-17 15:45:25 +01:00
}
2022-04-08 09:47:35 +02:00
// Message de retour
2022-10-11 10:33:44 +02:00
$t = isset($versionInstalled) ? helper::translate('actualisé') : helper::translate('installé');
2022-04-08 09:47:35 +02:00
$this->removeDir(self::TEMP_DIR . $tempFolder);
$zip->close();
2022-09-29 08:45:59 +02:00
return ([
'success' => $success,
2022-10-11 11:44:48 +02:00
'notification' => $success ? sprintf(helper::translate('Le module %s a été %s'), $module['name'], $t)
2022-10-11 10:33:44 +02:00
: helper::translate('Erreur inconnue, le module n\'est pas installé')
2022-04-08 09:47:35 +02:00
]);
} else {
2022-09-29 08:45:59 +02:00
return ([
2022-04-08 09:47:35 +02:00
'success' => false,
2022-10-11 10:33:44 +02:00
'notification' => helper::translate('Erreur inconnue, le module n\'est pas installé')
2022-04-08 09:47:35 +02:00
]);
// Supprimer le dossier temporaire
$this->removeDir(self::TEMP_DIR . $tempFolder);
$zip->close();
}
2022-02-17 15:45:25 +01:00
} else {
2022-04-08 09:47:35 +02:00
// Message de retour
2022-09-29 08:45:59 +02:00
return ([
'success' => false,
2022-10-11 10:33:44 +02:00
'notification' => helper::translate('Impossible d\'ouvrir l\'archive')
2022-04-08 09:47:35 +02:00
]);
2022-02-17 15:45:25 +01:00
}
}
/***
* Installation d'un module à partir du gestionnaire de fichier
*/
2022-09-29 08:45:59 +02:00
public function upload()
{
2022-02-17 15:45:25 +01:00
// Soumission du formulaire
2022-09-29 08:45:59 +02:00
if ($this->isPost()) {
2022-02-17 15:45:25 +01:00
// Installation d'un module
$checkValidMaj = $this->getInput('configModulesCheck', helper::FILTER_BOOLEAN);
$zipFilename = $this->getInput('configModulesInstallation', helper::FILTER_STRING_SHORT);
2022-09-29 08:45:59 +02:00
if ($zipFilename !== '') {
2022-02-17 15:45:25 +01:00
$success = [
'success' => false,
2022-09-29 08:45:59 +02:00
'notification' => ''
2022-02-17 15:45:25 +01:00
];
2022-09-29 08:45:59 +02:00
$state = $this->install(self::FILE_DIR . 'source/' . $zipFilename, $checkValidMaj);
2022-02-17 15:45:25 +01:00
}
$this->addOutput([
'redirect' => helper::baseUrl() . 'plugin',
'notification' => $state['notification'],
'state' => $state['success']
]);
}
// Valeurs en sortie
$this->addOutput([
2022-10-02 10:59:42 +02:00
'title' => helper::translate('Installer un module'),
2022-02-17 15:45:25 +01:00
'view' => 'upload'
]);
}
/***
* Installation d'un module depuis le catalogue
*/
2022-09-29 08:45:59 +02:00
public function uploadItem()
{
2022-02-17 15:45:25 +01:00
// Jeton incorrect
if ($this->getUrl(3) !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'store',
'state' => false,
2022-10-11 10:33:44 +02:00
'notification' => helper::translate('Action interdite')
2022-02-17 15:45:25 +01:00
]);
} else {
// Récupérer le module en ligne
$moduleName = $this->getUrl(2);
// Informations sur les module en ligne
2022-02-25 11:24:16 +01:00
$store = json_decode(helper::getUrlContents(self::BASEURL_STORE . self::MODULE_STORE . 'list'), true);
2022-02-17 15:45:25 +01:00
// Url du module à télécharger
$moduleFilePath = $store[$moduleName]['file'];
// Télécharger le fichier
2022-02-25 11:24:16 +01:00
$moduleData = helper::getUrlContents(self::BASEURL_STORE . self::FILE_DIR . 'source/' . $moduleFilePath);
2022-02-17 15:45:25 +01:00
// Extraire de l'arborescence
2022-09-29 08:45:59 +02:00
$d = explode('/', $moduleFilePath);
$moduleFile = $d[count($d) - 1];
2022-02-17 15:45:25 +01:00
// Créer le dossier modules
if (!is_dir(self::FILE_DIR . 'source/modules')) {
2022-09-29 08:45:59 +02:00
mkdir(self::FILE_DIR . 'source/modules', 0755);
2022-02-17 15:45:25 +01:00
}
// Sauver les données du fichiers
file_put_contents(self::FILE_DIR . 'source/modules/' . $moduleFile, $moduleData);
2022-04-08 09:47:35 +02:00
// Installation directe
2022-09-29 08:45:59 +02:00
if (file_exists(self::FILE_DIR . 'source/modules/' . $moduleFile)) {
2022-04-08 09:47:35 +02:00
$r = $this->install(self::FILE_DIR . 'source/modules/' . $moduleFile, false);
} else {
2022-10-11 11:44:48 +02:00
$r['notification'] = helper::translate('Erreur inconnue, le module n\'est pas installé');
2022-04-08 09:47:35 +02:00
$r['success'] = false;
}
// Valeurs en sortie
2022-02-17 15:45:25 +01:00
$this->addOutput([
'redirect' => helper::baseUrl() . 'plugin/store',
2022-04-08 09:47:35 +02:00
'notification' => $r['notification'],
'state' => $r['success']
2022-02-17 15:45:25 +01:00
]);
}
// Valeurs en sortie
$this->addOutput([
2022-10-02 10:59:42 +02:00
'title' => helper::translate('Catalogue de modules'),
2022-02-17 15:45:25 +01:00
'view' => 'store'
]);
}
/**
* Catalogue des modules sur le site ZwiiCMS.fr
*/
2022-09-29 08:45:59 +02:00
public function store()
{
2022-02-25 11:24:16 +01:00
$store = json_decode(helper::getUrlContents(self::BASEURL_STORE . self::MODULE_STORE . 'list'), true);
2022-02-17 15:45:25 +01:00
if ($store) {
// Modules installés
$infoModules = helper::getModules();
// Clés moduleIds dans les pages
2022-09-29 08:45:59 +02:00
$inPages = helper::arrayColumn($this->getData(['page']), 'moduleId', 'SORT_DESC');
foreach ($inPages as $key => $value) {
$pagesInfos[$this->getData(['page', $key, 'title'])] = $value;
2022-02-17 15:45:25 +01:00
}
// Parcourir les données des modules
2022-09-29 08:45:59 +02:00
foreach ($store as $key => $value) {
2022-02-17 15:45:25 +01:00
// Module non installé
$ico = template::ico('download');
$class = '';
2022-03-16 12:56:58 +01:00
$help = 'Télécharger le module dans le gestionnaire de fichiers';
2022-02-17 15:45:25 +01:00
// Le module est installé
2022-09-29 08:45:59 +02:00
if (array_key_exists($key, $infoModules) === true) {
2022-02-17 15:45:25 +01:00
$class = 'buttonGreen';
$ico = template::ico('update');
2022-03-16 12:56:58 +01:00
$help = 'Mettre à jour le module orphelin';
2022-02-17 15:45:25 +01:00
}
// Le module est installé et utilisé
2022-09-29 08:45:59 +02:00
if (in_array($key, $inPages) === true) {
2022-02-17 15:45:25 +01:00
$class = 'buttonRed';
$ico = template::ico('update');
2022-03-16 12:56:58 +01:00
$help = 'Mettre à jour le module attaché, une sauvegarde des données de module est recommandée !';
2022-02-17 15:45:25 +01:00
}
2022-09-29 08:45:59 +02:00
self::$storeList[] = [
2022-02-17 15:45:25 +01:00
$store[$key]['category'],
2022-09-29 08:45:59 +02:00
'<a href="' . self::BASEURL_STORE . self::MODULE_STORE . $key . '" target="_blank" >' . $store[$key]['title'] . '</a>',
2022-02-17 15:45:25 +01:00
$store[$key]['version'],
helper::dateUTF8('%d %B %Y', $store[$key]['versionDate']),
2022-09-29 08:45:59 +02:00
implode(', ', array_keys($pagesInfos, $key)),
2022-02-17 15:45:25 +01:00
template::button('moduleExport' . $key, [
2022-09-29 08:45:59 +02:00
'class' => $class,
'href' => helper::baseUrl() . $this->getUrl(0) . '/uploadItem/' . $key . '/' . $_SESSION['csrf'], // appel de fonction vaut exécution, utiliser un paramètre
'value' => $ico,
'help' => $help
])
2022-02-17 15:45:25 +01:00
];
}
}
// Valeurs en sortie
$this->addOutput([
2022-10-02 10:59:42 +02:00
'title' => helper::translate('Catalogue de modules'),
2022-02-17 15:45:25 +01:00
'view' => 'store'
]);
}
/**
* Détail d'un objet du catalogue
*/
2022-09-29 08:45:59 +02:00
public function item()
{
2022-02-25 11:24:16 +01:00
$store = json_decode(helper::getUrlContents(self::BASEURL_STORE . self::MODULE_STORE . 'list'), true);
2022-09-29 08:45:59 +02:00
self::$storeItem = $store[$this->getUrl(2)];
self::$storeItem['fileDate'] = helper::dateUTF8('%d %B %Y', self::$storeItem['fileDate']);
2022-02-17 15:45:25 +01:00
// Valeurs en sortie
$this->addOutput([
2022-10-02 10:59:42 +02:00
'title' => helper::translate('Module ' . self::$storeItem['title']),
2022-02-17 15:45:25 +01:00
'view' => 'item'
]);
}
/**
* Gestion des modules
*/
2022-09-29 08:45:59 +02:00
public function index()
{
2022-02-17 15:45:25 +01:00
// Tableau des langues rédigées
2022-09-26 14:54:15 +02:00
foreach (self::$languages as $key => $value) {
2022-09-29 08:45:59 +02:00
if (
$this->getData(['config', 'i18n', $key]) === 'site' ||
$key === 'fr_FR'
) {
2022-02-17 15:45:25 +01:00
$i18nSites[$key] = $value;
}
}
// Lister les modules installés
$infoModules = helper::getModules();
// Parcourir les langues du site traduit et recherche les modules affectés à des pages
2022-09-29 08:45:59 +02:00
foreach ($i18nSites as $keyi18n => $valuei18n) {
2022-02-17 15:45:25 +01:00
// Clés moduleIds dans les pages de la langue
$pages = json_decode(file_get_contents(self::DATA_DIR . $keyi18n . '/' . 'page.json'), true);
// Extraire les clés des modules
2022-09-29 08:45:59 +02:00
$pagesModules[$keyi18n] = array_filter(helper::arrayColumn($pages['page'], 'moduleId', 'SORT_DESC'), 'strlen');
2022-02-17 15:45:25 +01:00
// Générer ls liste des pages avec module pour la sauvegarde ou le backup
2022-09-29 08:45:59 +02:00
foreach ($pagesModules[$keyi18n] as $key => $value) {
2022-02-17 15:45:25 +01:00
if (!empty($value)) {
2022-09-29 08:45:59 +02:00
$pagesInfos[$keyi18n][$key]['pageId'] = $key;
$pagesInfos[$keyi18n][$key]['title'] = $this->getData(['page', $key, 'title']);
$pagesInfos[$keyi18n][$key]['moduleId'] = $value;
}
2022-02-17 15:45:25 +01:00
}
}
// Recherche des modules orphelins dans toutes les langues
2022-09-29 08:45:59 +02:00
$orphans = $installed = array_flip(array_keys($infoModules));
foreach ($i18nSites as $keyi18n => $valuei18n) {
2022-02-17 15:45:25 +01:00
// Générer la liste des modules orphelins
2022-09-29 08:45:59 +02:00
foreach ($infoModules as $key => $value) {
2022-02-17 15:45:25 +01:00
// Supprimer les éléments affectés
2022-09-29 08:45:59 +02:00
if (array_search($key, $pagesModules[$keyi18n])) {
unset($orphans[$key]);
2022-02-17 15:45:25 +01:00
}
}
}
$orphans = array_flip($orphans);
// Mise en forme du tableau des modules orphelins
if (isset($orphans)) {
foreach ($orphans as $key) {
// Construire le tableau de sortie
2022-09-29 08:45:59 +02:00
self::$modulesOrphan[] = [
$infoModules[$key]['realName'],
2022-02-17 15:45:25 +01:00
$key,
2022-09-29 08:45:59 +02:00
$infoModules[$key]['version'],
2022-02-17 15:45:25 +01:00
'',
2022-09-29 08:45:59 +02:00
$infoModules[$key]['delete'] === true
2022-02-17 15:45:25 +01:00
? template::button('moduleDelete' . $key, [
2022-09-29 08:45:59 +02:00
'class' => 'moduleDelete buttonRed',
'href' => helper::baseUrl() . $this->getUrl(0) . '/delete/' . $key . '/' . $_SESSION['csrf'],
'value' => template::ico('trash'),
'help' => 'Supprimer le module'
])
2022-02-17 15:45:25 +01:00
: '',
];
2022-02-17 15:45:25 +01:00
}
}
// Modules installés non orphelins
// Mise en forme du tableau des modules utilisés
if (isset($installed)) {
foreach (array_flip($installed) as $key) {
// Construire le tableau de sortie
2022-09-29 08:45:59 +02:00
self::$modulesInstalled[] = [
$infoModules[$key]['realName'],
2022-02-17 15:45:25 +01:00
$key,
2022-09-29 08:45:59 +02:00
$infoModules[$key]['version'],
2022-02-17 15:45:25 +01:00
'',
template::button('moduleSave' . $key, [
2022-09-29 08:45:59 +02:00
'href' => helper::baseUrl() . $this->getUrl(0) . '/save/filemanager/' . $key . '/' . $_SESSION['csrf'],
2022-02-17 15:45:25 +01:00
'value' => template::ico('download-cloud'),
'help' => 'Sauvegarder le module dans le gestionnaire de fichiers'
]),
template::button('moduleDownload' . $key, [
2022-09-29 08:45:59 +02:00
'href' => helper::baseUrl() . $this->getUrl(0) . '/save/download/' . $key . '/' . $_SESSION['csrf'],
2022-02-17 15:45:25 +01:00
'value' => template::ico('download'),
'help' => 'Sauvegarder et télécharger le module'
])
];
2022-02-17 15:45:25 +01:00
}
}
// Mise en forme du tableau des modules employés dans les pages
// Avec les commandes de sauvegarde et de restauration
2022-09-02 18:45:55 +02:00
$keyi18n = self::$i18nContent;
2022-09-29 08:45:59 +02:00
if (
isset($pagesInfos) &&
is_array($pagesInfos[self::$i18nContent])
) {
foreach ($pagesInfos[self::$i18nContent] as $keyPage => $value) {
if (isset($infoModules[$pagesInfos[$keyi18n][$keyPage]['moduleId']])) {
2022-09-05 21:03:38 +02:00
// Co[nstruire le tableau de sortie
self::$modulesData[] = [
2022-09-29 08:45:59 +02:00
$infoModules[$pagesInfos[$keyi18n][$keyPage]['moduleId']]['realName'],
2022-09-05 21:03:38 +02:00
$pagesInfos[$keyi18n][$keyPage]['moduleId'],
2022-09-29 08:45:59 +02:00
$infoModules[$pagesInfos[$keyi18n][$keyPage]['moduleId']]['version'],
2022-09-05 21:03:38 +02:00
//template::flag($keyi18n, '20px'),
2022-09-29 08:45:59 +02:00
'<a href ="' . helper::baseUrl() . $keyPage . '" target="_blank">' . $pagesInfos[$keyi18n][$keyPage]['title'] . ' (' . $keyPage . ')</a>',
2022-09-05 21:03:38 +02:00
template::button('dataExport' . $keyPage, [
2022-09-29 08:45:59 +02:00
'href' => helper::baseUrl() . $this->getUrl(0) . '/dataExport/' . $keyi18n . '/' . $pagesInfos[$keyi18n][$keyPage]['moduleId'] . '/' . $keyPage . '/' . $_SESSION['csrf'], // appel de fonction vaut exécution, utiliser un paramètre
'value' => template::ico('download'),
'help' => 'Exporter les données du module'
2022-09-05 21:03:38 +02:00
]),
template::button('dataDelete' . $keyPage, [
2022-09-29 08:45:59 +02:00
'href' => helper::baseUrl() . $this->getUrl(0) . '/dataDelete/' . $keyi18n . '/' . $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',
])
2022-09-05 21:03:38 +02:00
];
} else {
self::$modulesData[] = [];
}
2022-02-17 15:45:25 +01:00
}
}
2022-02-17 15:45:25 +01:00
2022-09-05 21:03:38 +02:00
2022-02-17 15:45:25 +01:00
// Valeurs en sortie
$this->addOutput([
2022-10-02 10:59:42 +02:00
'title' => helper::translate('Gestion des modules'),
2022-02-17 15:45:25 +01:00
'view' => 'index'
]);
}
/**
* Sauvegarde un module sans les données
*/
2022-09-29 08:45:59 +02:00
public function save()
{
2022-02-17 15:45:25 +01:00
// Jeton incorrect
if ($this->getUrl(4) !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'plugin',
'state' => false,
2022-10-11 10:33:44 +02:00
'notification' => helper::translate('Action interdite')
2022-02-17 15:45:25 +01:00
]);
} else {
2022-02-17 15:45:25 +01:00
// Créer un dossier temporaire
$tmpFolder = self::TEMP_DIR . uniqid();
if (!is_dir($tmpFolder)) {
mkdir($tmpFolder, 0755);
}
2022-10-16 08:16:04 +02:00
// Descripteur de l'archive
$infoModule = helper::getModules();
2022-02-17 15:45:25 +01:00
//Nom de l'archive
2022-10-16 08:16:04 +02:00
$fileName = $this->getUrl(3) . $infoModule [$this->getUrl(3)]['version'] . '.zip';
// Création du descripteur si absent
if (!file_exists(self::MODULE_DIR . $this->getUrl(3) . '/descripteur.json')) {
$success = file_put_contents(self::MODULE_DIR . $this->getUrl(3) . '/descripteur.json', json_encode([$this->getUrl(3) => $infoModule[$this->getUrl(3)]]));
}
// Construire l'archive
2022-09-29 08:45:59 +02:00
$this->makeZip($tmpFolder . '/' . $fileName, self::MODULE_DIR . $this->getUrl(3));
2022-02-17 15:45:25 +01:00
switch ($this->getUrl(2)) {
case 'filemanager':
if (!file_exists(self::FILE_DIR . 'source/modules')) {
mkdir(self::FILE_DIR . 'source/modules');
}
2022-10-16 08:16:04 +02:00
$success .= copy($tmpFolder . '/' . $fileName, self::FILE_DIR . 'source/modules/' . $this->getUrl(3) . '.zip');
2022-02-17 15:45:25 +01:00
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'plugin',
2022-10-11 10:33:44 +02:00
'notification' => $success ? $this->getUrl(3) . helper::translate('Archive copiée dans le dossier Module du gestionnaire de fichier') : helper::translate('Erreur de copie'),
2022-02-17 15:45:25 +01:00
'state' => $success
]);
2022-10-16 08:16:04 +02:00
// Nettoyage
unlink($tmpFolder . '/' . $fileName);
$this->removeDir($tmpFolder);
2022-02-17 15:45:25 +01:00
break;
case 'download':
2022-02-17 15:45:25 +01:00
default:
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $fileName . '"');
header('Content-Length: ' . filesize($tmpFolder . '/' . $fileName));
ob_clean();
2022-02-17 15:45:25 +01:00
ob_end_flush();
2022-09-29 08:45:59 +02:00
readfile($tmpFolder . '/' . $fileName);
2022-10-16 08:16:04 +02:00
// Nettoyage
unlink($tmpFolder . '/' . $fileName);
$this->removeDir($tmpFolder);
2022-02-17 15:45:25 +01:00
exit();
}
}
2022-09-29 08:45:59 +02:00
}
2022-02-17 15:45:25 +01:00
/*
* Détacher un module d'une page en supprimant les données du module
* 2 : i18n id
* 3 : moduleId
* 4 : pageId
* 5 : CSRF
*/
2022-09-29 08:45:59 +02:00
public function dataDelete()
{
2022-02-17 15:45:25 +01:00
// Jeton incorrect
if ($this->getUrl(5) !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'plugin',
'state' => false,
2022-10-11 10:33:44 +02:00
'notification' => helper::translate('Action interdite')
2022-02-17 15:45:25 +01:00
]);
} else {
$this->setData(['page', $this->getUrl(4), 'moduleId', '']);
$this->deleteData(['module', $this->getUrl(4)]);
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'plugin',
2022-10-11 11:44:48 +02:00
'notification' => sprintf(helper::translate('Le module %s de la page %s a été supprimé'), $this->getUrl(3), $this->getUrl(4)),
2022-02-17 15:45:25 +01:00
'state' => true
]);
}
}
/*
* Export des données d'un module
* Structure de l'adresse reçue
* 2 : i18n id
* 3 : moduleId
* 4 : pageId
* 5 : CSRF
*/
2022-09-29 08:45:59 +02:00
public function dataExport()
{
2022-02-17 15:45:25 +01:00
// Jeton incorrect
if ($this->getUrl(5) !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'plugin',
'state' => false,
2022-10-11 10:33:44 +02:00
'notification' => helper::translate('Action interdite')
2022-02-17 15:45:25 +01:00
]);
} else {
// Créer un dossier temporaire
$tmpFolder = self::TEMP_DIR . uniqid();
if (!is_dir($tmpFolder)) {
mkdir($tmpFolder, 0755);
}
2022-02-17 15:45:25 +01:00
// Copie des infos sur le module
2022-09-29 08:45:59 +02:00
$modulesData = json_decode(file_get_contents(self::DATA_DIR . $this->getUrl(2) . '/module.json'), true);
$moduleData = $modulesData['module'][$this->getUrl(4)];
$success = file_put_contents($tmpFolder . '/module.json', json_encode($moduleData));
2022-02-17 15:45:25 +01:00
// Le dossier du module s'il existe
2022-09-29 08:45:59 +02:00
if (is_dir(self::DATA_DIR . $this->getUrl(3) . '/' . $this->getUrl(4))) {
2022-02-17 15:45:25 +01:00
// Copier le dossier des données
$success .= $this->copyDir(self::DATA_DIR . $this->getUrl(3) . '/' . $this->getUrl(4), $tmpFolder);
}
2022-02-17 15:45:25 +01:00
// création du zip
2022-09-29 08:45:59 +02:00
if ($success) {
2022-02-17 15:45:25 +01:00
$fileName = $this->getUrl(2) . '-' . $this->getUrl(3) . '-' . $this->getUrl(4) . '.zip';
2022-09-29 08:45:59 +02:00
$this->makeZip($fileName, $tmpFolder);
2022-02-17 15:45:25 +01:00
if (file_exists($fileName)) {
ob_start();
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $fileName . '"');
header('Content-Length: ' . filesize($fileName));
ob_clean();
2022-02-17 15:45:25 +01:00
ob_end_flush();
2022-09-29 08:45:59 +02:00
readfile($fileName);
2022-02-17 15:45:25 +01:00
unlink($fileName);
$this->removeDir($tmpFolder);
exit();
}
} else {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'plugin',
2022-10-11 10:33:44 +02:00
'notification' => helper::translate('Erreur inconnue'),
2022-02-17 15:45:25 +01:00
'state' => false
]);
}
2022-02-17 15:45:25 +01:00
}
}
/*
* Importer des données d'un module externes ou interne à module.json
*/
2022-09-29 08:45:59 +02:00
public function dataImport()
{
2022-02-17 15:45:25 +01:00
// Soumission du formulaire d'importation du module dans une page libre
2022-09-29 08:45:59 +02:00
if ($this->isPost()) {
2022-02-17 15:45:25 +01:00
// Récupérer le fichier et le décompacter
$zipFilename = $this->getInput('pluginImportFile', helper::FILTER_STRING_SHORT, true);
$targetPage = $this->getInput('pluginImportPage', helper::FILTER_STRING_SHORT, true);
$tempFolder = uniqid();
// Extraction dans un dossier temporaire
2022-09-29 08:45:59 +02:00
mkdir(self::TEMP_DIR . $tempFolder, 0755);
2022-02-17 15:45:25 +01:00
$zip = new ZipArchive();
if ($zip->open(self::FILE_DIR . 'source/' . $zipFilename) === TRUE) {
2022-09-29 08:45:59 +02:00
$zip->extractTo(self::TEMP_DIR . $tempFolder);
2022-02-17 15:45:25 +01:00
}
2022-02-17 15:45:25 +01:00
// Lire le descripteur
$descripteur = json_decode(file_get_contents(self::TEMP_DIR . $tempFolder . '/descripteur.json'), true);
2022-02-17 15:45:25 +01:00
// Lecture des données du module
2022-09-29 08:45:59 +02:00
$moduleData = json_decode(file_get_contents(self::TEMP_DIR . $tempFolder . '/module.json'), true);
2022-02-17 15:45:25 +01:00
// Chargement des données du module importé
2022-09-29 08:45:59 +02:00
$this->setData(['module', $targetPage, $moduleData]);
2022-02-17 15:45:25 +01:00
// Intégration des données du module importé dans la page
2022-09-29 08:45:59 +02:00
$this->setData(['page', $targetPage, 'moduleId', array_key_first($descripteur)]);
2022-02-17 15:45:25 +01:00
// Supprimer le dossier temporaire
$this->removeDir(self::TEMP_DIR . $tempFolder);
$zip->close();
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'plugin',
'state' => true,
2022-10-11 10:33:44 +02:00
'notification' => helper::translate('Données importées')
2022-02-17 15:45:25 +01:00
]);
}
// Bouton d'importation des données d'un module spécifique
2022-09-29 08:45:59 +02:00
if (count(explode('/', $this->getUrl())) === 6) {
// Jeton incorrect
if ($this->getUrl(3) !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'plugin',
'state' => false,
2022-10-11 10:33:44 +02:00
'notification' => helper::translate('Action interdite')
2022-09-29 08:45:59 +02:00
]);
}
2022-02-17 15:45:25 +01:00
// Traitement
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'plugin',
'state' => true,
2022-10-11 10:33:44 +02:00
'notification' => helper::translate('Données importées')
2022-02-17 15:45:25 +01:00
]);
}
2022-02-17 15:45:25 +01:00
/**
* Liste des pages sans module
* et ne sont pas des barres latérales
*/
self::$pagesList = $this->getHierarchy(null, null, null);
2022-09-29 08:45:59 +02:00
foreach (self::$pagesList as $page => $pageId) {
if (
$this->getData(['page', $page, 'block']) === 'bar' ||
2022-02-17 15:45:25 +01:00
//$this->getData(['page',$page,'disable']) === true ||
2022-09-29 08:45:59 +02:00
$this->getData(['page', $page, 'moduleId']) !== ''
2022-02-17 15:45:25 +01:00
) {
unset(self::$pagesList[$page]);
}
}
self::$pagesList = array_keys(self::$pagesList);
// Valeurs en sortie
$this->addOutput([
2022-10-02 10:59:42 +02:00
'title' => helper::translate('Importer des données de module'),
2022-02-17 15:45:25 +01:00
'view' => 'dataImport'
]);
}
}