plugin okay + new copyDir
This commit is contained in:
parent
19aa822c8e
commit
b23d9f8c9b
@ -35,6 +35,7 @@ class common {
|
||||
const DATA_DIR = 'site/data/';
|
||||
const FILE_DIR = 'site/file/';
|
||||
const TEMP_DIR = 'site/tmp/';
|
||||
const MODULE_DIR = 'module/';
|
||||
|
||||
// Miniatures de la galerie
|
||||
const THUMBS_SEPARATOR = 'mini_';
|
||||
@ -1137,30 +1138,52 @@ class common {
|
||||
* @param string $dst dossier destination
|
||||
* @return bool
|
||||
*/
|
||||
public function copyDir($src, $dst) {
|
||||
// Ouvrir le dossier source
|
||||
$dir = opendir($src);
|
||||
// Créer le dossier de destination
|
||||
if (!is_dir($dst))
|
||||
$success = mkdir($dst, 0755, true);
|
||||
else
|
||||
$success = true;
|
||||
function copyDir( string $sourceDirectory, string $destinationDirectory, string $childFolder = '') {
|
||||
|
||||
// Boucler dans le dossier source en l'absence d'échec de lecture écriture
|
||||
while( $success
|
||||
AND $file = readdir($dir) ) {
|
||||
if (( $file != '.' ) && ( $file != '..' )) {
|
||||
if ( is_dir($src . '/' . $file) ){
|
||||
// Appel récursif des sous-dossiers
|
||||
$success = $success OR $this->copyDir($src . '/' . $file, $dst . '/' . $file);
|
||||
$success = true;
|
||||
$directory = opendir($sourceDirectory);
|
||||
|
||||
if (is_dir($destinationDirectory) === false) {
|
||||
mkdir($destinationDirectory);
|
||||
}
|
||||
|
||||
if ($childFolder !== '') {
|
||||
if (is_dir("$destinationDirectory/$childFolder") === false) {
|
||||
mkdir("$destinationDirectory/$childFolder");
|
||||
}
|
||||
|
||||
while (($file = readdir($directory)) !== false) {
|
||||
if ($file === '.' || $file === '..') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_dir("$sourceDirectory/$file") === true) {
|
||||
$success = $success && $this->copyDir("$sourceDirectory/$file", "$destinationDirectory/$childFolder/$file");
|
||||
} else {
|
||||
$success = $success && copy("$sourceDirectory/$file", "$destinationDirectory/$childFolder/$file");
|
||||
}
|
||||
}
|
||||
|
||||
closedir($directory);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
while (($file = readdir($directory)) !== false) {
|
||||
if ($file === '.' || $file === '..') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_dir("$sourceDirectory/$file") === true) {
|
||||
$success = $success && $this->copyDir("$sourceDirectory/$file", "$destinationDirectory/$file");
|
||||
}
|
||||
else {
|
||||
$success = $success OR copy($src . '/' . $file, $dst . '/' . $file);
|
||||
$success = $success && copy("$sourceDirectory/$file", "$destinationDirectory/$file");
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir($dir);
|
||||
return $success;
|
||||
|
||||
closedir($directory);
|
||||
return($success);
|
||||
}
|
||||
|
||||
|
||||
@ -2160,9 +2183,9 @@ class common {
|
||||
elseif(
|
||||
$moduleId
|
||||
AND in_array($moduleId, self::$coreModuleIds) === false
|
||||
AND file_exists('module/' . $moduleId . '/vendor/' . $vendorName . '/inc.json')
|
||||
AND file_exists(self::MODULE_DIR . $moduleId . '/vendor/' . $vendorName . '/inc.json')
|
||||
) {
|
||||
$vendorPath = 'module/' . $moduleId . '/vendor/' . $vendorName . '/';
|
||||
$vendorPath = self::MODULE_DIR . $moduleId . '/vendor/' . $vendorName . '/';
|
||||
}
|
||||
// Sinon continue
|
||||
else {
|
||||
@ -2660,8 +2683,8 @@ class core extends common {
|
||||
require 'core/module/' . $classPath;
|
||||
}
|
||||
// Module
|
||||
elseif(is_readable('module/' . $classPath)) {
|
||||
require 'module/' . $classPath;
|
||||
elseif(is_readable(self::MODULE_DIR . $classPath)) {
|
||||
require self::MODULE_DIR . $classPath;
|
||||
}
|
||||
// Librairie
|
||||
elseif(is_readable('core/vendor/' . $classPath)) {
|
||||
@ -2945,7 +2968,7 @@ class core extends common {
|
||||
// Chemin en fonction d'un module du coeur ou d'un module
|
||||
$modulePath = in_array($moduleId, self::$coreModuleIds) ? 'core/' : '';
|
||||
// CSS
|
||||
$stylePath = $modulePath . 'module/' . $moduleId . '/view/' . $output['view'] . '/' . $output['view'] . '.css';
|
||||
$stylePath = $modulePath . self::MODULE_DIR . $moduleId . '/view/' . $output['view'] . '/' . $output['view'] . '.css';
|
||||
if(file_exists($stylePath)) {
|
||||
$this->addOutput([
|
||||
'style' => file_get_contents($stylePath)
|
||||
@ -2958,7 +2981,7 @@ class core extends common {
|
||||
}
|
||||
|
||||
// JS
|
||||
$scriptPath = $modulePath . 'module/' . $moduleId . '/view/' . $output['view'] . '/' . $output['view'] . '.js.php';
|
||||
$scriptPath = $modulePath . self::MODULE_DIR . $moduleId . '/view/' . $output['view'] . '/' . $output['view'] . '.js.php';
|
||||
if(file_exists($scriptPath)) {
|
||||
ob_start();
|
||||
include $scriptPath;
|
||||
@ -2967,7 +2990,7 @@ class core extends common {
|
||||
]);
|
||||
}
|
||||
// Vue
|
||||
$viewPath = $modulePath . 'module/' . $moduleId . '/view/' . $output['view'] . '/' . $output['view'] . '.php';
|
||||
$viewPath = $modulePath . self::MODULE_DIR . $moduleId . '/view/' . $output['view'] . '/' . $output['view'] . '.php';
|
||||
if(file_exists($viewPath)) {
|
||||
ob_start();
|
||||
include $viewPath;
|
||||
|
@ -31,7 +31,7 @@ class plugin extends common {
|
||||
|
||||
// URL des modules
|
||||
const BASEURL_STORE = 'https://store.zwiicms.fr/';
|
||||
const MODULE_STORE = '?modules/';
|
||||
const MODULE_STORE = 'modules-pour-zwii-v12/';
|
||||
|
||||
// Gestion des modules
|
||||
public static $modulesData = [];
|
||||
@ -100,14 +100,9 @@ class plugin extends common {
|
||||
*/
|
||||
private function install($moduleFileName, $checkValid){
|
||||
|
||||
/**
|
||||
* Initialisation des variables
|
||||
*/
|
||||
//$tempFolder = uniqid() . '/';
|
||||
$tempFolder = 'truc/';
|
||||
$notification = '';
|
||||
// Numéro de version du module déjà installé
|
||||
$versionInstalled = '';
|
||||
// Dossier temporaire
|
||||
$tempFolder = uniqid() . '/';
|
||||
//$tempFolder = 'truc/';
|
||||
|
||||
/**
|
||||
* Désarchivage
|
||||
@ -115,124 +110,144 @@ class plugin extends common {
|
||||
$zip = new ZipArchive();
|
||||
if ($zip->open($moduleFileName) === TRUE) {
|
||||
|
||||
/**
|
||||
* Création du dossier temporaire
|
||||
*/
|
||||
|
||||
//Création du dossier temporaire et extraction
|
||||
if (!is_dir (self::TEMP_DIR . $tempFolder) ) {
|
||||
mkdir (self::TEMP_DIR . $tempFolder, 0755);
|
||||
}
|
||||
|
||||
$zip->extractTo(self::TEMP_DIR . $tempFolder );
|
||||
// Lecture du descripteur de ressource
|
||||
$modulePath = self::TEMP_DIR . $tempFolder . 'module';
|
||||
if (file_exists(self::TEMP_DIR . $tempFolder . 'desc.json')
|
||||
) {
|
||||
$res = json_decode(file_get_contents(self::TEMP_DIR . $tempFolder . 'desc.json'), true);
|
||||
} else {
|
||||
return([
|
||||
'success' => false,
|
||||
'notification'=> 'Cette archive est invalide'
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Structure lue
|
||||
* $res ['name'] = id du module, correspond à la classe
|
||||
* $res ['realname'] = Nom complet du module
|
||||
* $res ['version'] = version du module
|
||||
* $res ['dirs'] @array
|
||||
* 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'
|
||||
*
|
||||
* Attention le dossier source est celui dans l'archive, la destination correspond à l’arborescence cible
|
||||
*/
|
||||
echo "<pre>";
|
||||
// Affectation
|
||||
$moduleName = $res ['name'];
|
||||
$modulePath = $res ['name'] . '/';
|
||||
$moduleFile = $res ['name'] . '.php' ;
|
||||
|
||||
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,
|
||||
'notification'=> 'Archive invalide, le descripteur est absent.'
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation des informations du descripteur
|
||||
*/
|
||||
if ( !is_dir ( self::TEMP_DIR . $tempFolder . $modulePath) ||
|
||||
!is_file (self::TEMP_DIR . $tempFolder . $modulePath . $moduleFile)
|
||||
) {
|
||||
return([
|
||||
'success' => false,
|
||||
'notification'=> 'Cette archive est invalide'
|
||||
]);
|
||||
}
|
||||
/**
|
||||
* Le module est-il installé ? Lire le numéro de version
|
||||
*/
|
||||
if (is_file( 'module/' . $modulePath . $moduleFile) ) {
|
||||
$c = helper::getModules();
|
||||
if (array_key_exists($moduleName, $c)) {
|
||||
$versionInstalled = $c[$moduleName]['version'];
|
||||
}
|
||||
}
|
||||
// Si version actuelle >= version indiquée dans UPDATE la mise à jour est validée
|
||||
$infoModules = helper::getModules();
|
||||
if( $infoModules[$moduleName]['update'] >= $update ) $valUpdate = true;
|
||||
|
||||
// Module déjà installé ?
|
||||
$moduleInstal = false;
|
||||
foreach($infoModules as $key=>$value ){
|
||||
if($moduleName === $key){
|
||||
$moduleInstal = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Validation de la maj si autorisation du concepteur du module ET
|
||||
// ( Version plus récente OU Check de forçage )
|
||||
$valNewVersion = floatval($version);
|
||||
$valInstalVersion = floatval( $infoModules[$moduleName]['version'] );
|
||||
$newVersion = false;
|
||||
if( $valNewVersion > $valInstalVersion ) $newVersion = true;
|
||||
$validMaj = $valUpdate && ( $newVersion || $checkValid);
|
||||
|
||||
// Nouvelle installation ou mise à jour du module
|
||||
if( ! $moduleInstal || $validMaj ){
|
||||
// Copie récursive des dossiers
|
||||
$this->copyDir( self::TEMP_DIR . $tempFolder, './' );
|
||||
$success = true;
|
||||
if( ! $moduleInstal ){
|
||||
$notification = 'Module '.$moduleName.' installé';
|
||||
}
|
||||
else{
|
||||
$notification = 'Module '.$moduleName.' mis à jour';
|
||||
}
|
||||
}
|
||||
else{
|
||||
$success = false;
|
||||
if( $valNewVersion == $valInstalVersion){
|
||||
$notification = ' Version détectée '.$version.' = à celle installée '.$infoModules[$moduleName]['version'];
|
||||
}
|
||||
else{
|
||||
$notification = ' Version détectée '.$version.' < à celle installée '.$infoModules[$moduleName]['version'];
|
||||
}
|
||||
if( $valUpdate === false){
|
||||
if( $infoModules[$moduleName]['update'] === $update ){
|
||||
$notification = ' Mise à jour par ce procédé interdite par le concepteur du module';
|
||||
}
|
||||
else{
|
||||
$notification = ' Mise à jour par ce procédé interdite, votre version est trop ancienne';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Supprimer le dossier temporaire même si le module est invalide
|
||||
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();
|
||||
} else {
|
||||
// erreur à l'ouverture
|
||||
$success = false;
|
||||
$notification = 'Impossible d\'ouvrir l\'archive';
|
||||
}
|
||||
return(['success' => $success,
|
||||
'notification'=> $notification
|
||||
return([
|
||||
'success' => false,
|
||||
'notification'=> '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'=> 'Archive invalide, l\'écriture dans le dossier core est interdite'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation de la présence du fichier de base du module
|
||||
*/
|
||||
if ( !file_exists(self::TEMP_DIR . $tempFolder . $module['name'] . '/' . $module['name'] . '.php')) {
|
||||
// Message de retour
|
||||
$this->removeDir(self::TEMP_DIR . $tempFolder);
|
||||
$zip->close();
|
||||
return([
|
||||
'success' => false,
|
||||
'notification'=> 'Cette archive est invalide, le fichier de classe est absent.'
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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') ) {
|
||||
$c = helper::getModules();
|
||||
if (array_key_exists($module['name'], $c)) {
|
||||
$versionInstalled = $c[$module['name']]['version'];
|
||||
}
|
||||
}
|
||||
|
||||
// Le module est installé, contrôle de la version
|
||||
$installOk = false;
|
||||
if ( isset($versionInstalled) === false ) {
|
||||
$installOk = true;
|
||||
} elseif ( version_compare($module['version'], $versionInstalled) >= 0 ) {
|
||||
$installOk = true;
|
||||
} else {
|
||||
if (version_compare($module['version'], $versionInstalled) === -1 ) {
|
||||
// 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();
|
||||
return([
|
||||
'success' => false,
|
||||
'notification'=> 'La version installée est plus récente, la mise à jour peut être forcée en cochant l\'option.'
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Installation ou mise à jour du module valides
|
||||
if ($installOk) {
|
||||
// Copie récursive des dossiers
|
||||
foreach ($module['dirs'] as $src => $dest) {
|
||||
if (!is_dir (self::TEMP_DIR . $tempFolder . $src)) {
|
||||
mkdir(self::TEMP_DIR . $tempFolder . $src);
|
||||
}
|
||||
$success = $this->copyDir( self::TEMP_DIR . $tempFolder . $src, $dest );
|
||||
}
|
||||
// Message de retour
|
||||
$t = isset($versionInstalled) ? ' actualisé' : 'installé';
|
||||
$this->removeDir(self::TEMP_DIR . $tempFolder);
|
||||
$zip->close();
|
||||
return(['success' => $success,
|
||||
'notification'=> $success ? 'Le module '.$module['name'].' a été ' . $t
|
||||
: 'Erreur inconnue, le module n\'est pas installé'
|
||||
]);
|
||||
} else {
|
||||
return([
|
||||
'success' => false,
|
||||
'notification'=> 'Une erreur inconnue s\est produite !'
|
||||
]);
|
||||
// Supprimer le dossier temporaire
|
||||
$this->removeDir(self::TEMP_DIR . $tempFolder);
|
||||
$zip->close();
|
||||
}
|
||||
} else {
|
||||
// Message de retour
|
||||
return(['success' => $success,
|
||||
'notification'=> 'Impossible d\'ouvrir l\'archive'
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/***
|
||||
* Installation d'un module à partir du gestionnaire de fichier
|
||||
@ -294,21 +309,19 @@ class plugin extends common {
|
||||
// Sauver les données du fichiers
|
||||
file_put_contents(self::FILE_DIR . 'source/modules/' . $moduleFile, $moduleData);
|
||||
|
||||
/**
|
||||
* $if( $moduleFile !== ''){
|
||||
* $success = [
|
||||
* 'success' => false,
|
||||
* 'notification'=> ''
|
||||
* ];
|
||||
* $state = $this->install(self::FILE_DIR.'source/modules/'.$moduleFile, false);
|
||||
*}
|
||||
*/
|
||||
// Installation directe
|
||||
if ( file_exists(self::FILE_DIR . 'source/modules/' . $moduleFile) ) {
|
||||
$r = $this->install(self::FILE_DIR . 'source/modules/' . $moduleFile, false);
|
||||
} else {
|
||||
$r['notification'] = 'Un problème est survenu, le module n\'est pas installé';
|
||||
$r['success'] = false;
|
||||
}
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
'redirect' => helper::baseUrl() . 'plugin/store',
|
||||
'notification' => $moduleFile . ' téléchargé dans le dossier modules du gestionnaire de fichiers',
|
||||
'state' => true
|
||||
'notification' => $r['notification'],
|
||||
'state' => $r['success']
|
||||
]);
|
||||
|
||||
}
|
||||
// Valeurs en sortie
|
||||
$this->addOutput([
|
||||
@ -548,7 +561,7 @@ class plugin extends common {
|
||||
|
||||
//Nom de l'archive
|
||||
$fileName = $this->getUrl(3) . '.zip';
|
||||
$this->makeZip ($tmpFolder . '/' . $fileName, 'module/' . $this->getUrl(3));
|
||||
$this->makeZip ($tmpFolder . '/' . $fileName, self::MODULE_DIR . $this->getUrl(3));
|
||||
|
||||
switch ($this->getUrl(2)) {
|
||||
case 'filemanager':
|
||||
|
@ -15,11 +15,18 @@
|
||||
'help' => 'Consulter l\'aide en ligne'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col3 offset7">
|
||||
<div class="col1 offset8">
|
||||
<?php echo template::button('configModulesStore', [
|
||||
'href' => helper::baseUrl() . 'plugin/store',
|
||||
'ico' => 'shopping-basket',
|
||||
'value' => 'Catalogue en ligne'
|
||||
'value' => template::ico('shopping-basket'),
|
||||
'help' => 'Installer depuis le catalogue en ligne'
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col1">
|
||||
<?php echo template::button('configStoreUpload', [
|
||||
'href' => helper::baseUrl() . 'plugin/upload',
|
||||
'value' => template::ico('file-archive'),
|
||||
'help' => 'Installer depuis une archive'
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -6,12 +6,6 @@
|
||||
'value' => template::ico('left')
|
||||
]); ?>
|
||||
</div>
|
||||
<div class="col2 offset9">
|
||||
<?php echo template::button('configStoreUpload', [
|
||||
'href' => helper::baseUrl() . 'plugin/upload',
|
||||
'value' => 'Installer'
|
||||
]); ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php if($module::$storeList): ?>
|
||||
<?php echo template::table([2, 2, 1, 2, 2, 1], $module::$storeList, ['Catégorie', 'Module', 'Version', 'Date', 'Pages', '']); ?>
|
||||
|
36
module/version/version.php
Normal file
36
module/version/version.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?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.
|
||||
*
|
||||
* @license GNU General Public License, version 3
|
||||
* @author : Frédéric Tempez <frederic.tempez@outlook.com> *
|
||||
* @copyright Copyright (C) 2018-2020, Frédéric Tempez
|
||||
* @link http://zwiicms.com/
|
||||
*/
|
||||
|
||||
class version extends common {
|
||||
|
||||
const VERSION = '1.0';
|
||||
const REALNAME = 'Version';
|
||||
const DELETE = true;
|
||||
const UPDATE = '0.0';
|
||||
const DATADIRECTORY = ''; // Contenu localisé inclus par défaut (page.json et module.json)
|
||||
|
||||
public static $actions = [
|
||||
'index'=> self::GROUP_VISITOR
|
||||
|
||||
];
|
||||
|
||||
/**
|
||||
* Retourne le numéro de version
|
||||
*/
|
||||
|
||||
public function index() {
|
||||
exit( common::ZWII_VERSION);
|
||||
}
|
||||
|
||||
}
|
1
module/version/view/index/index.php
Normal file
1
module/version/view/index/index.php
Normal file
@ -0,0 +1 @@
|
||||
<?php // Dummy file
|
Loading…
Reference in New Issue
Block a user