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 >
2023-01-09 10:23:32 +01:00
* @ copyright Copyright ( C ) 2018 - 2023 , Frédéric Tempez
2022-12-29 17:02:20 +01:00
* @ license CC Attribution - NonCommercial - NoDerivatives 4.0 International
2022-02-17 15:45:25 +01:00
* @ 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 ,
2023-01-31 22:52:07 +01:00
'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
2022-02-25 10:04:46 +01:00
'dataDelete' => self :: GROUP_ADMIN ,
2022-02-17 15:45:25 +01:00
'store' => self :: GROUP_ADMIN ,
2023-01-31 22:52:07 +01:00
'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
2023-02-03 21:59:36 +01:00
const BASEURL_STORE = 'https://store.zwiicms.fr/' ;
2023-02-03 11:14:03 +01:00
const MODULE_STORE = '?modules/' ;
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 = [];
/*
2023-01-31 22:52:07 +01:00
* 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
2023-06-20 20:35:26 +02:00
// Action interdite
2023-06-29 10:30:12 +02:00
if ( $this -> getUser ( 'permission' , __CLASS__ , __FUNCTION__ ) !== true ) {
2022-02-17 15:45:25 +01:00
// Valeurs en sortie
$this -> addOutput ([
2023-06-29 10:30:12 +02:00
'access' => false
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' ])) {
2022-02-25 10:04:46 +01:00
if (
2022-09-29 08:45:59 +02:00
is_dir ( $infoModules [ $this -> getUrl ( 2 )][ 'dataDirectory' ])
2023-04-19 19:47:01 +02:00
|| ! $this -> removeDir ( $infoModules [ $this -> getUrl ( 2 )][ 'dataDirectory' ])
2022-09-29 08:45:59 +02:00
) {
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-25 10:04:46 +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 () . '/' ;
2022-03-18 14:15:21 +01:00
/**
* Désarchivage
*/
2022-02-17 15:45:25 +01:00
$zip = new ZipArchive ();
2022-12-20 12:19:42 +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-12-20 12:19:42 +01:00
if ( file_exists ( self :: TEMP_DIR . $tempFolder . 'enum.json' )) {
$module = json_decode ( file_get_contents ( self :: TEMP_DIR . $tempFolder . 'enum.json' ), true );
2022-09-29 08:45:59 +02:00
} 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-12-20 12:19:42 +01:00
if ( isset ( $module [ 'dirs' ])) {
foreach ( $module [ 'dirs' ] as $src => $dest ) {
// Vérification de la présence des dossier décrits
if ( ! is_dir ( self :: TEMP_DIR . $tempFolder . $src )) {
// Message de retour
$this -> removeDir ( self :: TEMP_DIR . $tempFolder );
$zip -> close ();
return ([
'success' => false ,
'notification' => helper :: translate ( 'Archive invalide, les dossiers ne correspondent pas au descripteur' )
]);
}
// Interdire l'écriture dans le dossier core
if ( strstr ( $dest , 'core' ) !== false ) {
// Message de retour
$this -> removeDir ( self :: TEMP_DIR . $tempFolder );
$zip -> close ();
return ([
'success' => false ,
'notification' => helper :: translate ( 'Archive invalide, l\'écriture dans le dossier core est interdite' )
]);
}
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-12-20 12:19:42 +01:00
if ( ! file_exists ( self :: TEMP_DIR . $tempFolder . $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
*/
2023-01-31 22:52:07 +01: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 ) {
2022-12-20 12:19:42 +01:00
// Copie du module
$success = $this -> copyDir ( self :: TEMP_DIR . $tempFolder , self :: MODULE_DIR . $module [ 'name' ]);
// Copie récursive des dossiers externes
2023-02-03 22:17:10 +01:00
if ( is_array ( $module [ 'dataDirectory' ])) {
foreach ( $module [ 'dataDirectory' ] as $src => $dest ) {
if ( ! is_dir ( self :: TEMP_DIR . $tempFolder . $src )) {
mkdir ( self :: TEMP_DIR . $tempFolder . $src );
}
2023-04-19 19:47:01 +02:00
$success = $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 ,
2023-04-19 19:47:01 +02:00
'notification' => $success
? sprintf ( helper :: translate ( 'Le module %s a été %s' ), $module [ 'name' ], $t )
: helper :: translate ( 'Erreur inconnue, le module n\'est pas installé' )
2022-04-08 09:47:35 +02:00
]);
} else {
2023-06-29 10:30:12 +02:00
// Supprimer le dossier temporaire
$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 ( 'Erreur inconnue, le module n\'est pas installé' )
2022-04-08 09:47:35 +02:00
]);
2023-06-29 10:30:12 +02:00
2022-04-08 09:47:35 +02:00
}
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
2023-06-29 17:01:27 +02:00
if (
2023-06-30 09:09:39 +02:00
$this -> getUser ( 'permission' , __CLASS__ , __FUNCTION__ ) === true &&
2023-06-29 17:01:27 +02:00
$this -> isPost ()
) {
2022-02-17 15:45:25 +01:00
// Installation d'un module
$checkValidMaj = $this -> getInput ( 'configModulesCheck' , helper :: FILTER_BOOLEAN );
2023-01-31 22:52:07 +01:00
$zipFilename = $this -> getInput ( 'configModulesInstallation' , helper :: FILTER_STRING_SHORT );
2022-09-29 08:45:59 +02:00
if ( $zipFilename !== '' ) {
$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 ()
{
2023-06-20 20:35:26 +02:00
// Action interdite
2023-06-29 10:30:12 +02:00
if ( $this -> getUser ( 'permission' , __CLASS__ , __FUNCTION__ ) !== true ) {
2022-02-17 15:45:25 +01:00
// Valeurs en sortie
$this -> addOutput ([
2023-06-29 10:30:12 +02:00
'access' => false
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 ([
2023-01-31 22:52:07 +01:00
'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 );
2023-02-02 16:12:27 +01:00
2022-02-17 15:45:25 +01:00
if ( $store ) {
// Modules installés
$infoModules = helper :: getModules ();
2023-02-03 16:14:06 +01:00
2022-02-17 15:45:25 +01:00
// Clés moduleIds dans les pages
2022-09-29 08:45:59 +02:00
$inPages = helper :: arrayColumn ( $this -> getData ([ 'page' ]), 'moduleId' , 'SORT_DESC' );
2023-02-03 16:14:06 +01:00
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 ) {
2023-02-03 16:14:06 +01:00
if ( empty ( $key )) {
continue ;
}
2023-02-03 22:17:10 +01:00
$pageInfos = array_keys ( $inPages , $key );
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é
2023-02-03 16:14:06 +01:00
if ( in_array ( $key , $inPages ) === true ) {
2022-02-17 15:45:25 +01:00
$class = 'buttonRed' ;
2023-01-31 22:52:07 +01:00
$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' ],
2022-10-09 10:50:28 +02:00
helper :: dateUTF8 ( '%d %B %Y' , $store [ $key ][ 'versionDate' ]),
2023-02-03 15:49:05 +01:00
implode ( ' - ' , $pageInfos ),
2022-02-17 15:45:25 +01:00
template :: button ( 'moduleExport' . $key , [
2022-09-29 08:45:59 +02:00
'class' => $class ,
2023-06-19 19:46:00 +02:00
'href' => helper :: baseUrl () . $this -> getUrl ( 0 ) . '/uploadItem/' . $key ,
2022-09-29 08:45:59 +02:00
'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 )];
2022-10-09 10:50:28 +02:00
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
2023-04-19 19:47:01 +02:00
$i18nSites = [];
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-10-18 11:53:53 +02:00
// tableau des langues installées
2023-04-19 19:47:01 +02:00
if (
2023-06-29 17:01:27 +02:00
is_dir ( self :: DATA_DIR . $key )
&& file_exists ( self :: DATA_DIR . $key . '/page.json' )
&& file_exists ( self :: DATA_DIR . $key . '/module.json' )
2023-04-19 19:47:01 +02:00
) {
2022-02-17 15:45:25 +01:00
$i18nSites [ $key ] = $value ;
}
}
2022-10-18 11:53:53 +02:00
2022-02-17 15:45:25 +01:00
// Lister les modules installés
$infoModules = helper :: getModules ();
// Parcourir les langues du site traduit et recherche les modules affectés à des pages
2022-10-18 11:53:53 +02:00
$pagesInfos = [];
2023-04-19 19:47:01 +02:00
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
2023-04-19 19:47:01 +02:00
$pages = json_decode ( file_get_contents ( self :: DATA_DIR . $keyi18n . '/page.json' ), true );
2022-02-17 15:45:25 +01:00
// 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
2022-10-18 11:53:53 +02:00
// Générer la liste des pages avec module de la langue par défaut
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 ;
2022-10-18 18:36:23 +02:00
$pagesInfos [ $keyi18n ][ $key ][ 'title' ] = $pages [ 'page' ][ $key ][ 'title' ];
2022-09-29 08:45:59 +02:00
$pagesInfos [ $keyi18n ][ $key ][ 'moduleId' ] = $value ;
2022-02-25 10:04:46 +01:00
}
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
2023-01-31 22:52:07 +01:00
? template :: button ( 'moduleDelete' . $key , [
'class' => 'moduleDelete buttonRed' ,
2023-06-19 19:46:00 +02:00
'href' => helper :: baseUrl () . $this -> getUrl ( 0 ) . '/delete/' . $key ,
2023-01-31 22:52:07 +01:00
'value' => template :: ico ( 'trash' ),
'help' => 'Supprimer le module'
])
: '' ,
2022-02-17 15:45:25 +01:00
2022-02-25 10:04:46 +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 , [
2023-06-19 19:46:00 +02:00
'href' => helper :: baseUrl () . $this -> getUrl ( 0 ) . '/save/filemanager/' . $key ,
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 , [
2023-06-19 19:46:00 +02:00
'href' => helper :: baseUrl () . $this -> getUrl ( 0 ) . '/save/download/' . $key ,
2022-02-17 15:45:25 +01:00
'value' => template :: ico ( 'download' ),
'help' => 'Sauvegarder et télécharger le module'
])
2022-02-25 10:04:46 +01:00
];
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-10-18 18:36:23 +02:00
self :: $modulesData [] = [];
2022-09-29 08:45:59 +02:00
if (
2022-12-19 08:46:45 +01:00
isset ( $pagesInfos )
2022-09-29 08:45:59 +02:00
) {
2022-10-18 18:36:23 +02:00
foreach ( $i18nSites as $keyi18n => $valuei18n ) {
2022-12-19 08:46:45 +01:00
if ( isset ( $pagesInfos [ $keyi18n ])) {
foreach ( $pagesInfos [ $keyi18n ] as $keyPage => $value ) {
if ( isset ( $infoModules [ $pagesInfos [ $keyi18n ][ $keyPage ][ 'moduleId' ]])) {
// Construire le tableau de sortie
self :: $modulesData [] = [
$infoModules [ $pagesInfos [ $keyi18n ][ $keyPage ][ 'moduleId' ]][ 'realName' ] . ' (' . $pagesInfos [ $keyi18n ][ $keyPage ][ 'moduleId' ] . ')' ,
$infoModules [ $pagesInfos [ $keyi18n ][ $keyPage ][ 'moduleId' ]][ 'version' ],
2023-01-31 22:52:07 +01:00
template :: flag ( $keyi18n , '20px' ) . ' <a href ="' . helper :: baseUrl () . $keyPage . '" target="_blank">' . $pagesInfos [ $keyi18n ][ $keyPage ][ 'title' ] . ' (' . $keyPage . ')</a>' ,
2022-12-19 08:46:45 +01:00
template :: button ( 'dataExport' . $keyPage , [
2023-06-19 19:46:00 +02:00
'href' => helper :: baseUrl () . $this -> getUrl ( 0 ) . '/dataExport/filemanager/' . self :: $i18nContent . '/' . $pagesInfos [ $keyi18n ][ $keyPage ][ 'moduleId' ] . '/' . $keyPage ,
2023-01-31 22:52:07 +01:00
// appel de fonction vaut exécution, utiliser un paramètre
2022-12-19 08:46:45 +01:00
'value' => template :: ico ( 'download-cloud' ),
'help' => 'Sauvegarder les données du module dans le gestionnaire de fichiers'
]),
template :: button ( 'dataExport' . $keyPage , [
2023-06-19 19:46:00 +02:00
'href' => helper :: baseUrl () . $this -> getUrl ( 0 ) . '/dataExport/download/' . self :: $i18nContent . '/' . $pagesInfos [ $keyi18n ][ $keyPage ][ 'moduleId' ] . '/' . $keyPage ,
2023-01-31 22:52:07 +01:00
// appel de fonction vaut exécution, utiliser un paramètre
2022-12-19 08:46:45 +01:00
'value' => template :: ico ( 'download' ),
'help' => 'Sauvegarder et télécharger les données du module'
]),
template :: button ( 'dataDelete' . $keyPage , [
2023-06-19 19:46:00 +02:00
'href' => helper :: baseUrl () . $this -> getUrl ( 0 ) . '/dataDelete/' . self :: $i18nContent . '/' . $pagesInfos [ $keyi18n ][ $keyPage ][ 'moduleId' ] . '/' . $keyPage ,
2023-01-31 22:52:07 +01:00
// appel de fonction vaut exécution, utiliser un paramètre
2022-12-19 08:46:45 +01:00
'value' => template :: ico ( 'trash' ),
'class' => 'buttonRed dataDelete' ,
'help' => 'Détacher le module de la page' ,
])
];
}
2022-10-18 18:36:23 +02:00
}
2022-09-05 21:03:38 +02:00
}
2022-02-17 15:45:25 +01:00
}
2022-08-23 20:58:23 +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 ()
{
2023-06-20 20:35:26 +02:00
// Action interdite
2023-06-29 10:30:12 +02:00
if ( $this -> getUser ( 'permission' , __CLASS__ , __FUNCTION__ ) !== true ) {
2022-02-17 15:45:25 +01:00
// Valeurs en sortie
$this -> addOutput ([
2023-06-29 10:30:12 +02:00
'access' => false
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-10-18 18:51:36 +02:00
$action = $this -> getUrl ( 2 );
2022-10-16 17:35:27 +02:00
$moduleId = $this -> getUrl ( 3 );
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
2023-01-31 22:52:07 +01:00
$fileName = $moduleId . $infoModule [ $moduleId ][ 'version' ] . '.zip' ;
2022-10-16 08:16:04 +02:00
2022-12-20 12:19:42 +01:00
// Régénération du module
2023-02-02 16:12:27 +01:00
$success = file_put_contents ( self :: MODULE_DIR . $moduleId . '/enum.json' , json_encode ( $infoModule [ $moduleId ], JSON_UNESCAPED_UNICODE ));
2022-10-16 08:16:04 +02:00
// Construire l'archive
2023-01-31 22:52:07 +01:00
$this -> makeZip ( self :: TEMP_DIR . $fileName , self :: MODULE_DIR . $moduleId );
2022-02-17 15:45:25 +01:00
2022-10-18 18:51:36 +02:00
switch ( $action ) {
2022-02-17 15:45:25 +01:00
case 'filemanager' :
if ( ! file_exists ( self :: FILE_DIR . 'source/modules' )) {
mkdir ( self :: FILE_DIR . 'source/modules' );
}
2023-04-19 19:47:01 +02:00
$success = $success || copy ( self :: TEMP_DIR . $fileName , self :: FILE_DIR . 'source/modules/' . $moduleId . '.zip' );
2022-02-17 15:45:25 +01:00
// Valeurs en sortie
$this -> addOutput ([
'redirect' => helper :: baseUrl () . 'plugin' ,
2022-12-20 14:09:06 +01:00
'notification' => $success ? helper :: translate ( 'Archive copiée dans le dossier Modules 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
2022-10-19 10:42:40 +02:00
unlink ( self :: TEMP_DIR . $fileName );
2022-10-16 08:16:04 +02:00
$this -> removeDir ( $tmpFolder );
2022-02-17 15:45:25 +01:00
break ;
2022-02-25 10:04:46 +01:00
case 'download' :
2022-02-17 15:45:25 +01:00
default :
2023-01-31 22:52:07 +01:00
// Téléchargement du ZIP
header ( 'Content-Description: File Transfer' );
2022-02-17 15:45:25 +01:00
header ( 'Content-Type: application/octet-stream' );
2023-01-31 22:52:07 +01:00
header ( 'Content-Transfer-Encoding: binary' );
2022-02-17 15:45:25 +01:00
header ( 'Content-Disposition: attachment; filename="' . $fileName . '"' );
2023-01-31 22:52:07 +01:00
header ( 'Content-Length: ' . filesize ( self :: TEMP_DIR . $fileName ));
readfile ( self :: TEMP_DIR . $fileName );
// Nettoyage du dossier
unlink ( self :: TEMP_DIR . $fileName );
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
/*
2023-01-31 22:52:07 +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 ()
{
2023-06-20 20:35:26 +02:00
// Action interdite
2023-06-29 10:30:12 +02:00
if ( $this -> getUser ( 'permission' , __CLASS__ , __FUNCTION__ ) !== true ) {
2022-02-17 15:45:25 +01:00
// Valeurs en sortie
$this -> addOutput ([
2023-06-29 10:30:12 +02:00
'access' => false
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
]);
}
}
/*
2023-01-31 22:52:07 +01:00
* Export des données d ' un module
* Structure de l ' adresse reçue
* 2 : i18n id
* 3 : moduleId
* 4 : pageId
*/
2022-09-29 08:45:59 +02:00
public function dataExport ()
{
2023-06-20 20:35:26 +02:00
// Action interdite
2023-06-29 10:30:12 +02:00
if ( $this -> getUser ( 'permission' , __CLASS__ , __FUNCTION__ ) !== true ) {
2022-02-17 15:45:25 +01:00
// Valeurs en sortie
$this -> addOutput ([
2023-06-29 10:30:12 +02:00
'access' => false
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-25 10:04:46 +01:00
2022-10-18 18:51:36 +02:00
$action = $this -> getUrl ( 2 );
$lang = $this -> getUrl ( 3 );
$moduleId = $this -> getUrl ( 4 );
$pageId = $this -> getUrl ( 5 );
2022-10-16 17:35:27 +02:00
2023-01-31 22:52:07 +01:00
// DOnnèes du module de la page sélectionnée
2022-10-16 17:35:27 +02:00
$moduleData = $this -> getData ([ 'module' , $pageId ]);
2022-02-17 15:45:25 +01:00
2022-10-16 17:35:27 +02:00
// Descripteur du module
$infoModules = helper :: getModules ();
$infoModule = $infoModules [ $moduleId ];
// Copier les données et le descripteur
2023-02-02 16:12:27 +01:00
$success = file_put_contents ( $tmpFolder . '/module.json' , json_encode ( $moduleData , JSON_UNESCAPED_UNICODE )) === false ? false : true ;
2022-12-19 08:46:45 +01:00
2023-04-19 19:47:01 +02:00
$success = $success || is_int ( file_put_contents ( $tmpFolder . '/enum.json' , json_encode ([ $moduleId => $infoModule ], JSON_UNESCAPED_UNICODE )));
2022-02-25 10:04:46 +01:00
// Le dossier du module s'il existe
2023-01-31 22:52:07 +01:00
if ( is_dir ( self :: DATA_DIR . $moduleId . '/' . $pageId )) {
2022-02-17 15:45:25 +01:00
// Copier le dossier des données
2023-04-19 19:47:01 +02:00
$success = $success || $this -> copyDir ( self :: DATA_DIR . '/' . $moduleId . '/' . $pageId , $tmpFolder . '/dataDirectory' );
2022-02-17 15:45:25 +01:00
}
2022-12-19 08:46:45 +01:00
2022-10-19 10:42:40 +02:00
// Création du zip
2023-01-31 22:52:07 +01:00
$fileName = $lang . '-' . $moduleId . '-' . $pageId . '.zip' ;
2022-10-19 10:42:40 +02:00
$this -> makeZip ( self :: TEMP_DIR . $fileName , $tmpFolder );
2022-12-19 08:46:45 +01:00
2023-01-31 22:52:07 +01:00
// Gestion de l'action
2022-09-29 08:45:59 +02:00
if ( $success ) {
2022-10-18 18:51:36 +02:00
switch ( $action ) {
case 'filemanager' :
2022-10-19 10:42:40 +02:00
if ( ! file_exists ( self :: FILE_DIR . 'source/modules' )) {
mkdir ( self :: FILE_DIR . 'source/modules' );
}
if ( file_exists ( self :: TEMP_DIR . $fileName )) {
2023-04-19 19:47:01 +02:00
$success = $success || copy ( self :: TEMP_DIR . $fileName , self :: FILE_DIR . 'source/modules/data' . $moduleId . '.zip' );
2022-10-19 10:42:40 +02:00
// Valeurs en sortie
$this -> addOutput ([
'redirect' => helper :: baseUrl () . 'plugin' ,
'notification' => $success ? helper :: translate ( 'Données copiées dans le dossier Module du gestionnaire de fichier' ) : helper :: translate ( 'Erreur de copie' ),
'state' => $success
]);
// Nettoyage
unlink ( self :: TEMP_DIR . $fileName );
$this -> removeDir ( $tmpFolder );
}
break ;
2022-10-18 18:51:36 +02:00
case 'download' :
default :
2023-01-31 22:52:07 +01:00
if ( file_exists ( self :: TEMP_DIR . $fileName )) {
// Téléchargement du ZIP
header ( 'Content-Description: File Transfer' );
2022-10-18 18:51:36 +02:00
header ( 'Content-Type: application/octet-stream' );
2023-01-31 22:52:07 +01:00
header ( 'Content-Transfer-Encoding: binary' );
header ( 'Content-Disposition: attachment; filename="' . $fileName . '"' );
2022-10-19 10:42:40 +02:00
header ( 'Content-Length: ' . filesize ( self :: TEMP_DIR . $fileName ));
readfile ( self :: TEMP_DIR . $fileName );
2023-01-31 22:52:07 +01:00
// Nettoyage du dossier
2022-10-19 10:42:40 +02:00
unlink ( self :: TEMP_DIR . $fileName );
2022-10-18 18:51:36 +02:00
exit ();
}
2022-02-17 15:45:25 +01:00
}
} 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-25 10:04:46 +01:00
}
2022-02-17 15:45:25 +01:00
}
}
/*
2023-01-31 22:52:07 +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
2023-06-29 17:01:27 +02:00
if (
2023-06-30 09:09:39 +02:00
$this -> getUser ( 'permission' , __CLASS__ , __FUNCTION__ ) === true &&
2023-06-29 17:01:27 +02:00
$this -> isPost ()
) {
2022-02-17 15:45:25 +01:00
// Récupérer le fichier et le décompacter
2023-01-31 22:52:07 +01:00
$zipFilename = $this -> getInput ( 'pluginImportFile' , helper :: FILTER_STRING_SHORT , true );
2022-10-17 17:41:15 +02:00
$pageId = $this -> getInput ( 'pluginImportPage' , null , true );
$tmpFolder = uniqid ();
2022-02-17 15:45:25 +01:00
// Extraction dans un dossier temporaire
2022-10-17 17:41:15 +02:00
mkdir ( self :: TEMP_DIR . $tmpFolder , 0755 );
2022-02-17 15:45:25 +01:00
$zip = new ZipArchive ();
if ( $zip -> open ( self :: FILE_DIR . 'source/' . $zipFilename ) === TRUE ) {
2023-01-31 22:52:07 +01:00
$zip -> extractTo ( self :: TEMP_DIR . $tmpFolder );
2022-02-17 15:45:25 +01:00
}
2022-02-25 10:04:46 +01:00
2022-02-17 15:45:25 +01:00
// Lire le descripteur
2023-01-31 22:52:07 +01:00
$descripteur = json_decode ( file_get_contents ( self :: TEMP_DIR . $tmpFolder . '/enum.json' ), true );
2022-10-17 17:41:15 +02:00
$moduleId = array_key_first ( $descripteur );
2022-02-25 10:04:46 +01:00
2022-02-17 15:45:25 +01:00
// Lecture des données du module
2023-01-31 22:52:07 +01:00
$moduleData = json_decode ( file_get_contents ( self :: TEMP_DIR . $tmpFolder . '/module.json' ), true );
2022-10-17 17:41:15 +02:00
2022-02-17 15:45:25 +01:00
// Chargement des données du module importé
2022-10-17 17:41:15 +02:00
$this -> setData ([ 'module' , $pageId , $moduleData ]);
2022-02-17 15:45:25 +01:00
// Intégration des données du module importé dans la page
2022-10-17 17:41:15 +02:00
$this -> setData ([ 'page' , $pageId , 'moduleId' , $moduleId ]);
// Copie des fichiers d'accompagnement
// Le dossier du module s'il existe
2023-01-31 22:52:07 +01:00
if ( is_dir ( $tmpFolder . '/dataDirectory' )) {
2022-10-17 17:41:15 +02:00
// Copier le dossier des données
2023-01-31 22:52:07 +01:00
$this -> copyDir ( $tmpFolder . '/dataDirectory' , self :: DATA_DIR . '/' . $moduleId . '/' . $pageId );
2022-10-17 17:41:15 +02:00
}
2022-02-17 15:45:25 +01:00
// Supprimer le dossier temporaire
2022-10-17 17:41:15 +02:00
$this -> removeDir ( self :: TEMP_DIR . $tmpFolder );
2022-02-17 15:45:25 +01:00
$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 ) {
2023-06-20 20:35:26 +02:00
// Action interdite
2023-06-19 19:46:00 +02:00
if ( $this -> checkCSRF ()) {
2022-09-29 08:45:59 +02:00
// Valeurs en sortie
$this -> addOutput ([
2023-01-31 22:52:07 +01:00
'redirect' => helper :: baseUrl () . 'plugin' ,
2022-09-29 08:45:59 +02:00
'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 ([
2023-01-31 22:52:07 +01:00
'redirect' => helper :: baseUrl () . 'plugin' ,
2022-02-17 15:45:25 +01:00
'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-25 10:04:46 +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-10-17 17:41:15 +02:00
foreach ( self :: $pagesList as $page => $value ) {
2022-09-29 08:45:59 +02:00
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 ]);
2022-10-17 17:41:15 +02:00
} else {
self :: $pagesList [ $page ] = $page ;
2022-02-17 15:45:25 +01:00
}
}
// 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'
]);
}
2023-01-31 22:52:07 +01:00
}