From 31b1561750fa0bd71b08b88be8b7419329b42f89 Mon Sep 17 00:00:00 2001 From: Fred Tempez Date: Tue, 10 Dec 2019 10:53:31 +0100 Subject: [PATCH] =?UTF-8?q?[10.0.001.dev]=20Int=C3=A9gration=20gestion=20d?= =?UTF-8?q?onn=C3=A9es=20manque=20l'import?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/core.php | 398 +++++---- core/module/config/config.php | 160 +++- core/module/config/view/index/index.js.php | 16 + core/module/config/view/index/index.php | 125 ++- core/module/config/view/manage/manage.php | 100 +++ core/module/install/install.php | 76 +- core/module/install/ressource/defaultdata.php | 770 ++++++++++-------- core/vendor/jsondb/Dot.php | 316 +++++++ core/vendor/jsondb/JsonDb.php | 138 ++++ 9 files changed, 1443 insertions(+), 656 deletions(-) create mode 100644 core/module/config/view/index/index.js.php create mode 100644 core/module/config/view/manage/manage.php create mode 100644 core/vendor/jsondb/Dot.php create mode 100644 core/vendor/jsondb/JsonDb.php diff --git a/core/core.php b/core/core.php index 2810a273..542acce3 100644 --- a/core/core.php +++ b/core/core.php @@ -34,7 +34,7 @@ class common { const TEMP_DIR = 'site/tmp/'; // Numéro de version - const ZWII_VERSION = '10.0.000.dev'; + const ZWII_VERSION = '10.0.001.dev'; public static $actions = []; public static $coreModuleIds = [ @@ -47,6 +47,14 @@ class common { 'theme', 'user' ]; + public static $dataStage = [ + 'config', + 'core', + 'module', + 'page', + 'user', + 'theme' + ]; private $data = []; private $hierarchy = [ 'all' => [], @@ -59,6 +67,8 @@ class common { ]; public static $inputBefore = []; public static $inputNotices = []; + public static $importNotices = []; + public static $coreNotices = []; public $output = [ 'access' => true, 'content' => '', @@ -133,24 +143,24 @@ class common { $this->input['_COOKIE'] = $_COOKIE; } - // Import des données d'une version 8 - $this->importData(); - - // Génère le fichier de données lorque les deux fichiers sont absents ou seulement le thème est - installation fraîche par défaut - if(file_exists(self::DATA_DIR.'core.json') === false OR - file_exists(self::DATA_DIR.'theme.json') === false) { - include_once('core/module/install/ressource/defaultdata.php'); - $this->setData([install::$defaultData]); - $this->saveData(); - chmod(self::DATA_DIR.'core.json', 0755); - chmod(self::DATA_DIR.'theme.json', 0755); - } - - // Import des données d'un fichier data.json déjà présent - if($this->data === []) { - $this->readData(); + // Import version 9 + if (file_exists(self::DATA_DIR . 'core.json') === true && + $this->getData(['core','dataVersion']) < 10000 && + $this->getData(['core','dataVersion']) !== 0) { // Retour d'importation ne pas déclencher l'import + $this->importData(); + common::$importNotices [] = "Importation réalisée avec succès" ; + //echo ''; + } + // Installation fraîche, initialisation des modules manquants + // La langue d'installation par défaut est fr + foreach (self::$dataStage as $stageId) { + $folder = $this->dirData ($stageId, 'fr'); + if (file_exists($folder . $stageId .'.json') === false) { + $this->initData($stageId,'fr'); + common::$coreNotices [] = $stageId ; + } } - + // Utilisateur connecté if($this->user === []) { $this->user = $this->getData(['user', $this->getInput('ZWII_USER_ID')]); @@ -223,62 +233,6 @@ class common { $this->update(); } - /** - * Lecture des fichiers de données - * - */ - public function readData() { - // Trois tentatives - for($i = 0; $i < 3; $i++) { - $this->setData([json_decode(file_get_contents(self::DATA_DIR.'core.json'), true) + json_decode(file_get_contents(self::DATA_DIR.'theme.json'), true)]); - if($this->data) { - break; - } - elseif($i === 2) { - exit('Unable to read data file.'); - } - // Pause de 10 millisecondes - usleep(10000); - } - } - - /** - * Import des données de la version 8 - * Converti un fichier de données data.json puis le renomme - */ - public function importData() { - if(file_exists(self::DATA_DIR.'data.json')) { - // Trois tentatives - for($i = 0; $i < 3; $i++) { - $tempData = [json_decode(file_get_contents(self::DATA_DIR.'data.json'), true)]; - if($tempData) { - for($i = 0; $i < 3; $i++) { - if(file_put_contents(self::DATA_DIR.'core.json', json_encode(array_slice($tempData[0],0,5)), LOCK_EX) !== false) { - break; - } - // Pause de 10 millisecondes - usleep(10000); - } - for($i = 0; $i < 3; $i++) { - if(file_put_contents(self::DATA_DIR.'theme.json', json_encode(array_slice($tempData[0],5)), LOCK_EX) !== false) { - break; - } - // Pause de 10 millisecondes - usleep(10000); - } - rename (self::DATA_DIR.'data.json',self::DATA_DIR.'imported_data.json'); - break; - } - elseif($i === 2) { - exit('Unable to read data file.'); - } - // Pause de 10 millisecondes - usleep(10000); - } - - } - } - /** * Ajoute les valeurs en sortie * @param array $output Valeurs en sortie @@ -317,28 +271,45 @@ class common { * Supprime des données * @param array $keys Clé(s) des données */ - public function deleteData($keys) { + public function deleteData($keys) { + //Retourne une chaine contenant le dossier à créer + $folder = $this->dirData ($keys[0],'fr'); + // Constructeur JsonDB + require_once "core/vendor/jsondb/Dot.php"; + require_once "core/vendor/jsondb/JsonDb.php"; + $db = new \Prowebcraft\JsonDb([ + 'name' => $keys[0] . '.json', + 'dir' => $folder, + 'template' => self::TEMP_DIR . 'data.template.json' + ]); switch(count($keys)) { - case 1 : - unset($this->data[$keys[0]]); + case 1: + $db->delete($keys[0]); + $db->save(); break; case 2: - unset($this->data[$keys[0]][$keys[1]]); + $db->delete($keys[0].'.'.$keys[1]); + $db->save(); break; case 3: - unset($this->data[$keys[0]][$keys[1]][$keys[2]]); + $db->delete($keys[0].'.'.$keys[1].'.'.$keys[2]); + $db->save(); break; case 4: - unset($this->data[$keys[0]][$keys[1]][$keys[2]][$keys[3]]); + $db->delete($keys[0].'.'.$keys[1].'.'.$keys[2].'.'.$keys[3]); + $db->save(); break; case 5: - unset($this->data[$keys[0]][$keys[1]][$keys[2]][$keys[3]][$keys[4]]); + $db->delete($keys[0].'.'.$keys[1].'.'.$keys[2].'.'.$keys[3].'.'.$keys[4]); + $db->save(); break; case 6: - unset($this->data[$keys[0]][$keys[1]][$keys[2]][$keys[3]][$keys[4]][$keys[5]]); + $db->delete($keys[0].'.'.$keys[1].'.'.$keys[2].'.'.$keys[3].'.'.$keys[4].'.'.$keys[5]); + $db->save(); break; case 7: - unset($this->data[$keys[0]][$keys[1]][$keys[2]][$keys[3]][$keys[4]][$keys[5]][$keys[6]]); + $db->delete($keys[0].'.'.$keys[1].'.'.$keys[2].'.'.$keys[3].'.'.$keys[4].'.'.$keys[5].'.'.$keys[6]); + $db->save(); break; } } @@ -373,24 +344,43 @@ class common { * @return mixed */ public function getData($keys = null) { - // Retourne l'ensemble des données - if($keys === null) { - return $this->data; - } - // Décent dans les niveaux de la variable $data - $data = $this->data; - foreach($keys as $key) { - // Si aucune donnée n'existe retourne null - if(isset($data[$key]) === false) { - return null; - } - // Sinon décent dans les niveaux - else { - $data = $data[$key]; + + if (count($keys) >= 1) { + //Retourne une chaine contenant le dossier à créer + $folder = $this->dirData ($keys[0],'fr'); + // Constructeur JsonDB + require_once "core/vendor/jsondb/Dot.php"; + require_once "core/vendor/jsondb/JsonDb.php"; + $db = new \Prowebcraft\JsonDb([ + 'name' => $keys[0] . '.json', + 'dir' => $folder, + 'template' => self::TEMP_DIR . 'data.template.json' + ]); + switch(count($keys)) { + case 1: + $tempData = $db->get($keys[0]); + break; + case 2: + $tempData = $db->get($keys[0].'.'.$keys[1]); + break; + case 3: + $tempData = $db->get($keys[0].'.'.$keys[1].'.'.$keys[2]); + break; + case 4: + $tempData = $db->get($keys[0].'.'.$keys[1].'.'.$keys[2].'.'.$keys[3]); + break; + case 5: + $tempData = $db->get($keys[0].'.'.$keys[1].'.'.$keys[2].'.'.$keys[3].'.'.$keys[4]); + break; + case 6: + $tempData = $db->get($keys[0].'.'.$keys[1].'.'.$keys[2].'.'.$keys[3].'.'.$keys[4].'.'.$keys[5]); + break; + case 7: + $tempData = $db->get($keys[0].'.'.$keys[1].'.'.$keys[2].'.'.$keys[3].'.'.$keys[4].'.'.$keys[5].'.'.$keys[6]); + break; } + return $tempData; } - // Retourne les données - return $data; } /** @@ -523,35 +513,55 @@ class common { } /** - * Enregistre les données dans deux fichiers séparés + * Import des données de la version 9 + * Convertit un fichier de données data.json puis le renomme */ - public function saveData() { - // Save config core page module et user - // 5 premières clés principales - // Trois tentatives + public function importData($keepUsers = false) { + // Trois tentatives de lecture for($i = 0; $i < 3; $i++) { - if(file_put_contents(self::DATA_DIR.'core.json', json_encode(array_slice($this->getData(),0,5)) , LOCK_EX) !== false) { + $tempData=json_decode(file_get_contents(self::DATA_DIR.'core.json'), true); + $tempTheme=json_decode(file_get_contents(self::DATA_DIR.'theme.json'), true); + if($tempData && $tempTheme) { + // Backup + rename (self::DATA_DIR.'core.json',self::DATA_DIR.'imported_core.json'); + rename (self::DATA_DIR.'theme.json',self::DATA_DIR.'imported_theme.json'); break; } + elseif($i === 2) { + exit('Impossible de lire les données à importer.'); + } // Pause de 10 millisecondes usleep(10000); } - // Save theme - // dernière clé principale - // Trois tentatives - for($i = 0; $i < 3; $i++) { - if(file_put_contents(self::DATA_DIR.'theme.json', json_encode(array_slice($this->getData(),5)), LOCK_EX) !== false) { - break; - } - // Pause de 10 millisecondes - usleep(10000); + + // Dossier de langues + if (!file_exists(self::DATA_DIR . '/fr')) { + mkdir (self::DATA_DIR . '/fr'); } + // Ecriture des données + $this->setData(['config',$tempData['config']]); + $this->setData(['core',$tempData['core']]); + $this->setData(['page',$tempData['page']]); + // Import des modules + $this->setData(['module',$tempData['module']]); + // Import des users sauvegardés si option active + if ($keepUsers === false) { + $this->setData(['user',$tempData['user']]); + } + // Import du theme + $this->setData(['theme',$tempTheme['theme']]); + + // Nettoyage du fichier de thème pour forcer une régénération + if (file_exists(self::DATA_DIR . '/theme.css')) { // On ne sait jamais + unlink (self::DATA_DIR . '/theme.css'); + } } + /** * Génére un fichier json avec la liste des pages * -*/ + */ public function pages2Json() { // Sauve la liste des pages pour TinyMCE $parents = []; @@ -609,11 +619,27 @@ class common { } } + /** + * Retourne une chemin localisé pour l'enregistrement des données + * @param $stageId nom du module + * @param $lang langue des pages + * @return string du dossier à créer + */ + public function dirData($id, $lang) { + // Sauf pour les pages et les modules + if ($id === 'page' || + $id === 'module') { + $folder = self::DATA_DIR . $lang . '/' ; + } else { + $folder = self::DATA_DIR; + } + return ($folder); + } + /** * Génére un fichier robots.txt à l'installation * Si le fichier exite déjà les commandes sont ajoutées */ - public function createRobots() { $robotValue = @@ -772,34 +798,89 @@ class common { } } + /** - * Insert des données + * Sauvegarde des données * @param array $keys Clé(s) des données */ - public function setData($keys) { - switch(count($keys)) { - case 1: - $this->data = $keys[0]; - break; + public function setData($keys = NULL) { + + // Pas d'enregistrement lorsque'une notice est présente + if (!empty(self::$inputNotices)) { + return false; + } + + //Retourne une chaine contenant le dossier à créer + $folder = $this->dirData ($keys[0],'fr'); + // Constructeur JsonDB + require_once "core/vendor/jsondb/Dot.php"; + require_once "core/vendor/jsondb/JsonDb.php"; + $db = new \Prowebcraft\JsonDb([ + 'name' => $keys[0] . '.json', + 'dir' => $folder, + 'template' => self::TEMP_DIR . 'data.template.json' + ]); + + switch(count($keys)) { case 2: - $this->data[$keys[0]] = $keys[1]; + $db->set($keys[0],$keys[1]); + $db->save(); break; case 3: - $this->data[$keys[0]][$keys[1]] = $keys[2]; + $db->set($keys[0].'.'.$keys[1],$keys[2]); + $db->save(); break; case 4: - $this->data[$keys[0]][$keys[1]][$keys[2]] = $keys[3]; + $db->set($keys[0].'.'.$keys[1].'.'.$keys[2],$keys[3]); + $db->save(); break; case 5: - $this->data[$keys[0]][$keys[1]][$keys[2]][$keys[3]] = $keys[4]; + $db->set($keys[0].'.'.$keys[1].'.'.$keys[2].'.'.$keys[3],$keys[4]); + $db->save(); break; case 6: - $this->data[$keys[0]][$keys[1]][$keys[2]][$keys[3]][$keys[4]] = $keys[5]; + $db->set($keys[0].'.'.$keys[1].'.'.$keys[2].'.'.$keys[3].'.'.$keys[4],$keys[5]); + $db->save(); break; case 7: - $this->data[$keys[0]][$keys[1]][$keys[2]][$keys[3]][$keys[4]][$keys[5]] = $keys[6]; + $db->set($keys[0].'.'.$keys[1].'.'.$keys[2].'.'.$keys[3].'.'.$keys[4].'.'.$keys[5],$keys[6]); + $db->save(); break; } + return true; + } + + /** + * Initialisation des données + * @param array $module : nom du module à générer + * choix valides : core config user theme page module + */ + public function initData($module, $lang = 'fr', $sampleSite = false) { + + // Tableau avec les données vierges + require_once('core/module/install/ressource/defaultdata.php'); + + // Stockage dans un sous-dossier localisé + // Le dossier de langue existe t-il ? + if (!file_exists(self::DATA_DIR . '/' . $lang)) { + mkdir (self::DATA_DIR . '/' . $lang); + } + $folder = $this->dirData ($module,$lang); + // Constructeur JsonDB + require_once "core/vendor/jsondb/Dot.php"; + require_once "core/vendor/jsondb/JsonDb.php"; + $db = new \Prowebcraft\JsonDb([ + 'name' => $module . '.json', + 'dir' => $folder, + 'template' => self::TEMP_DIR . 'data.template.json' + ]); + if ($sampleSite === true) { + $db->set($module,init::$siteData[$module]); + } else { + $db->set($module,init::$defaultData[$module]); + } + + $db->save; } /** @@ -810,7 +891,7 @@ class common { if($this->getData(['core', 'dataVersion']) < 810) { $this->setData(['config', 'timezone', 'Europe/Paris']); $this->setData(['core', 'dataVersion', 810]); - $this->saveData(); + //$this->SaveData(); } // Version 8.2.0 if($this->getData(['core', 'dataVersion']) < 820) { @@ -823,56 +904,56 @@ class common { $this->setData(['theme', 'header', 'fontSize', '2em']); $this->setData(['theme', 'footer', 'textColor', 'rgba(33, 34, 35, 1)']); $this->setData(['core', 'dataVersion', 820]); - $this->saveData(); + //$this->SaveData(); } // Version 8.2.2 if($this->getData(['core', 'dataVersion']) < 822) { $this->setData(['config', 'maintenance', false]); $this->setData(['core', 'dataVersion', 822]); - $this->saveData(); + //$this->SaveData(); } // Version 8.2.6 if($this->getData(['core', 'dataVersion']) < 826) { $this->setData(['theme','header','linkHome',true]); $this->setData(['core', 'dataVersion', 826]); - $this->saveData(); + //$this->SaveData(); } // Version 8.3.1 if($this->getData(['core', 'dataVersion']) < 831) { $this->setData(['theme','header','imageContainer','auto']); $this->setData(['core', 'dataVersion', 831]); - $this->saveData(); + //$this->SaveData(); } // Version 8.4.0 if($this->getData(['core', 'dataVersion']) < 840) { $this->setData(['config','itemsperPage',10]); $this->setData(['core', 'dataVersion', 840]); - $this->saveData(); + //$this->SaveData(); } // Version 8.4.4 if($this->getData(['core', 'dataVersion']) < 844) { $this->setData(['core', 'dataVersion', 844]); - $this->saveData(); + //$this->SaveData(); } // Version 8.4.6 if($this->getData(['core', 'dataVersion']) < 846) { $this->setData(['config','itemsperPage',10]); $this->setData(['core', 'dataVersion', 846]); - $this->saveData(); + //$this->SaveData(); } // Version 8.5.0 if($this->getData(['core', 'dataVersion']) < 850) { $this->setData(['theme','menu','font','Open+Sans']); $this->setData(['core', 'dataVersion', 850]); - $this->saveData(); + //$this->SaveData(); } // Version 8.5.1 if($this->getData(['core', 'dataVersion']) < 851) { $this->setData(['config','itemsperPage',10]); $this->deleteData(['config','ItemsperPage']); $this->setData(['core', 'dataVersion', 851]); - $this->saveData(); + //$this->SaveData(); } // Version 9.0.0 if($this->getData(['core', 'dataVersion']) < 9000) { @@ -882,13 +963,13 @@ class common { } $this->setData(['theme', 'menu','fixed',false]); $this->setData(['core', 'dataVersion', 9000]); - $this->saveData(); + //$this->SaveData(); } // Version 9.0.01 if($this->getData(['core', 'dataVersion']) < 9001) { $this->deleteData(['config', 'social', 'googleplusId']); $this->setData(['core', 'dataVersion', 9001]); - $this->saveData(); + //$this->SaveData(); } // Version 9.0.08 if($this->getData(['core', 'dataVersion']) < 9008) { @@ -897,31 +978,31 @@ class common { $this->setData(['theme', 'footer', 'fontSize','.8em']); $this->setData(['theme', 'footer', 'font','Open+Sans']); $this->setData(['core', 'dataVersion', 9008]); - $this->saveData(); + //$this->SaveData(); } // Version 9.0.09 if($this->getData(['core', 'dataVersion']) < 9009) { $this->setData(['core', 'dataVersion', 9009]); - $this->saveData(); + //$this->SaveData(); } // Version 9.0.10 if($this->getData(['core', 'dataVersion']) < 9010) { $this->deleteData(['config', 'social', 'googleplusId']); $this->setData(['core', 'dataVersion', 9010]); - $this->saveData(); + //$this->SaveData(); } // Version 9.0.11 if($this->getData(['core', 'dataVersion']) < 9011) { if ($this->getData(['theme','menu','position']) === 'body') $this->setData(['theme','menu','position','site']); $this->setData(['core', 'dataVersion', 9011]); - $this->saveData(); + //$this->SaveData(); } // Version 9.0.17 if($this->getData(['core', 'dataVersion']) < 9017) { $this->setData(['theme','footer','displayVersion', true ]); $this->setData(['core', 'dataVersion', 9017]); - $this->saveData(); + //$this->SaveData(); } // Version 9.1.0 if($this->getData(['core', 'dataVersion']) < 9100) { @@ -929,7 +1010,7 @@ class common { $this->setData(['theme','footer','displaySiteMap', true ]); $this->setData(['theme','footer','displayCopyright', true ]); $this->setData(['core', 'dataVersion', 9100]); - $this->saveData(); + //$this->SaveData(); } // Version 9.2.00 if($this->getData(['core', 'dataVersion']) < 9200) { @@ -939,7 +1020,7 @@ class common { $this->setData(['theme','footer','displaySearch', false ]); $this->setData(['config','social','githubId', '' ]); $this->setData(['core', 'dataVersion', 9200]); - $this->saveData(); + //$this->SaveData(); } // Version 9.2.05 if($this->getData(['core', 'dataVersion']) < 9205) { @@ -956,7 +1037,7 @@ class common { rmdir ('core/vendor/swiper/'); } $this->setData(['core', 'dataVersion', 9205]); - $this->saveData(); + //$this->SaveData(); } // Version 9.2.10 if($this->getData(['core', 'dataVersion']) < 9210) { @@ -1007,7 +1088,7 @@ class common { } } $this->setData(['core', 'dataVersion', 9210]); - $this->saveData(); + //$this->SaveData(); } // Version 9.2.11 if($this->getData(['core', 'dataVersion']) < 9211) { @@ -1015,14 +1096,14 @@ class common { $this->setData(['core', 'lastAutoUpdate', $autoUpdate]); $this->setData(['config','autoUpdate', true]); $this->setData(['core', 'dataVersion', 9211]); - $this->saveData(); + //$this->SaveData(); } // Version 9.2.12 if($this->getData(['core', 'dataVersion']) < 9212) { $this->setData(['theme','menu', 'activeColorAuto',true]); $this->setData(['theme','menu', 'activeColor','rgba(255, 255, 255, 1)']); $this->setData(['core', 'dataVersion', 9212]); - $this->saveData(); + //$this->SaveData(); } } } @@ -1056,7 +1137,7 @@ class core extends common { // Date de la dernière suppression $this->setData(['core', 'lastClearTmp', $lastClearTmp]); // Enregistre les données - $this->saveData(); + //$this->SaveData(); } // Backup automatique des données $lastBackup = mktime(0, 0, 0); @@ -1070,7 +1151,7 @@ class core extends common { // Date du dernier backup $this->setData(['core', 'lastBackup', $lastBackup]); // Enregistre les données - $this->saveData(); + //$this->SaveData(); // Supprime les backups de plus de 30 jours $iterator = new DirectoryIterator(self::BACKUP_DIR); foreach($iterator as $fileInfos) { @@ -1380,7 +1461,7 @@ class core extends common { // Enregistrement des données if($output['state'] !== false) { $this->setData([$module->getData()]); - $this->saveData(); + //$this->SaveData(); } // Notification if($output['notification']) { @@ -2433,6 +2514,15 @@ class layout extends common { * Affiche la notification */ public function showNotification() { + if(common::$inputNotices) { + $notification = 'Impossible de soumettre le formulaire, car il contient des erreurs'; + $notificationClass = 'notificationError'; + } + if (common::$coreNotices) { + $notification = 'Données absentes, restauration de

| '; + foreach (common::$coreNotices as $item) $notification .= $item . ' | '; + $notificationClass = 'notificationError'; + } if(common::$inputNotices) { $notification = 'Impossible de soumettre le formulaire, car il contient des erreurs'; $notificationClass = 'notificationError'; diff --git a/core/module/config/config.php b/core/module/config/config.php index 09fc87b6..869b46e2 100755 --- a/core/module/config/config.php +++ b/core/module/config/config.php @@ -19,7 +19,9 @@ class config extends common { 'configMetaImage' => self::GROUP_ADMIN, 'generateFiles' => self::GROUP_ADMIN, 'updateRobots' => self::GROUP_ADMIN, - 'index' => self::GROUP_ADMIN + 'index' => self::GROUP_ADMIN, + 'manage' => self::GROUP_ADMIN, + 'updateBaseUrl' => self::GROUP_ADMIN ]; public static $timezones = [ @@ -148,7 +150,7 @@ class config extends common { public function generateFiles() { // Mettre à jour le site map - $successSitemap=$this->createSitemap('all'); + $successSitemap=$this->createSitemap(); // Creer un fichier robots.txt $successRobots=$this->updateRobots(); @@ -199,16 +201,17 @@ class config extends common { * Sauvegarde des données */ public function backup() { - // Creation du ZIP - $fileName = date('Y-m-d-h-i-s', time()) . '.zip'; + $fileName = str_replace('/','',helper::baseUrl(false,false)) . '-'. date('Y-m-d-h-i-s', time()) . '.zip'; $zip = new ZipArchive(); if($zip->open(self::TEMP_DIR . $fileName, ZipArchive::CREATE) === TRUE){ - foreach(configHelper::scanDir('site/') as $file) { + foreach(core::scanDir(self::DATA_DIR) as $file) { $zip->addFile($file); } } $zip->close(); + // Enregistre la date de backup manuel + $this->setData(['core', 'lastBackup', mktime(0, 0, 0)]); // Téléchargement du ZIP header('Content-Transfer-Encoding: binary'); header('Content-Disposition: attachment; filename="' . $fileName . '"'); @@ -255,7 +258,105 @@ class config extends common { ]); } + /** + * Procédure d'importation + */ + public function manage() { + // Soumission du formulaire + if($this->isPost()) { + //if ($this->getInput('configManageImportFile')) + $fileZip = $this->getInput('configManageImportFile'); + $file_parts = pathinfo($fileZip); + $folder = date('Y-m-d-h-i-s', time()); + $zip = new ZipArchive(); + if ($file_parts['extension'] !== 'zip') { + // Valeurs en sortie erreur + $this->addOutput([ + 'notification' => 'Le fichier n\'est pas une archive valide', + 'redirect' => helper::baseUrl() . 'config/manage', + 'state' => false + ]); + } + $successOpen = $zip->open(self::FILE_DIR . 'source/' . $fileZip); + if ($successOpen === FALSE) { + // Valeurs en sortie erreur + $this->addOutput([ + 'notification' => 'Impossible de lire l\'archive', + 'redirect' => helper::baseUrl() . 'config/manage', + 'state' => false + ]); + } + // Lire le contenu de l'archive dans le tableau files + for( $i = 0; $i < $zip->numFiles; $i++ ){ + $stat = $zip->statIndex( $i ); + $files [] = ( basename( $stat['name'] )); + } + + // Détermination de la version à installer + if (in_array('theme.json',$files) === true && + in_array('core.json',$files) === true && + in_array ('user.json', $files) === false ) { + // V9 pas de fichier user dans l'archive + // Stocker le choix de conserver les users installées + $version = '9'; + + } elseif (in_array('theme.json',$files) === true && + in_array('core.json',$files) === true && + in_array ('user.json', $files) === true && + in_array ('config.json', $files) === true ) { + // V10 valide + $version = '10'; + // Option active, les users sont stockées + if ($this->getInput('configManageImportUser', helper::FILTER_BOOLEAN) === true ) { + $users = $this->getData(['user']); + } + + } else { // Version invalide + // Valeurs en sortie erreur + $this->addOutput([ + 'notification' => 'Cette archive n\'est pas une sauvegarde valide', + 'redirect' => helper::baseUrl() . 'config/manage', + 'state' => false + ]); + } + + // Extraire le zip + $success = $zip->extractTo( '.' ); + // Fermer l'archive + $zip->close(); + + // Restaurer les users originaux d'une v10 si option cochée + if (!empty($users) && + $version === '10' && + $this->getInput('configManageImportUser', helper::FILTER_BOOLEAN) === true) { + $this->setData(['user',$users]); + } + + if ($version === '9' ) { + $this->importData($this->getInput('configManageImportUser', helper::FILTER_BOOLEAN)); + $this->setData(['core','dataVersion',0]); + } + + // Met à jours les URL dans les contenus de page + + // Message de notification + $notification = $success === true ? 'Sauvegarde importée avec succès' : 'Erreur d\'extraction'; + $redirect = $this->getInput('configManageImportUser', helper::FILTER_BOOLEAN) === true ? helper::baseUrl() . 'config/manage' : helper::baseUrl() . 'user/login/'; + // Valeurs en sortie erreur + $this->addOutput([ + 'notification' => $notification, + 'redirect' =>$redirect, + 'state' => $success + ]); + } + // Valeurs en sortie + $this->addOutput([ + 'title' => 'Sauvegarder / Restaurer', + 'view' => 'manage' + ]); + } + /** * Configuration @@ -268,6 +369,7 @@ class config extends common { } else { $legalPageId = ''; } + $this->setData([ 'config', [ @@ -276,8 +378,6 @@ class config extends common { 'maintenance' => $this->getInput('configMaintenance', helper::FILTER_BOOLEAN), 'cookieConsent' => $this->getInput('configCookieConsent', helper::FILTER_BOOLEAN), 'favicon' => $this->getInput('configFavicon'), - 'homePageId' => $this->getInput('configHomePageId', helper::FILTER_ID, true), - 'metaDescription' => $this->getInput('configMetaDescription', helper::FILTER_STRING_LONG, true), 'social' => [ 'facebookId' => $this->getInput('configSocialFacebookId'), 'linkedinId' => $this->getInput('configSocialLinkedinId'), @@ -288,12 +388,15 @@ class config extends common { 'githubId' => $this->getInput('configSocialGithubId') ], 'timezone' => $this->getInput('configTimezone', helper::FILTER_STRING_SHORT, true), - 'title' => $this->getInput('configTitle', helper::FILTER_STRING_SHORT, true), 'itemsperPage' => $this->getInput('itemsperPage', helper::FILTER_INT,true), 'legalPageId' => $this->getInput('configLegalPageId'), + 'metaDescription' => $this->getInput('configMetaDescription', helper::FILTER_STRING_LONG, true), + 'title' => $this->getInput('configTitle', helper::FILTER_STRING_SHORT, true), + 'googTransLogo' => $this->getInput('configdGoogTransLogo', helper::FILTER_BOOLEAN), 'autoUpdate' => $this->getInput('configAutoUpdate', helper::FILTER_BOOLEAN) ] ]); + if(self::$inputNotices === []) { // Ecrire les fichiers de script file_put_contents(self::DATA_DIR . 'head.inc.html',$this->getInput('configScriptHead',null)); @@ -351,31 +454,28 @@ class config extends common { 'view' => 'index' ]); } - -} - -class configHelper extends helper { - + /** - * Scan le contenu d'un dossier et de ses sous-dossiers - * @param string $dir Dossier à scanner - * @return array + * Met à jour les données de site avec l'adresse trannsmise */ - public static function scanDir($dir) { - $dirContent = []; - $iterator = new DirectoryIterator($dir); - foreach($iterator as $fileInfos) { - if(in_array($fileInfos->getFilename(), ['.', '..', 'backup'])) { - continue; - } - elseif($fileInfos->isDir()) { - $dirContent = array_merge($dirContent, self::scanDir($fileInfos->getPathname())); - } - else { - $dirContent[] = $fileInfos->getPathname(); + public function updateBaseUrl () { + $old = $this->getInput('configManageBaseURLToConvert'); + $new = $this->getInput('configManageCurrentURL'); + foreach($this->getHierarchy(null,null,null) as $parentId => $childIds) { + $content = $this->getData(['page',$parentId,'content']); + $replace = str_replace( $old . '/site/' , $new . 'site/', $content) ; + $this->setData(['page',$parentId,'content', $replace ]); + foreach($childIds as $childId) { + $content = $this->getData(['page',$childId,'content']); + $replace = str_replace( $old . '/site/' , $new . 'site/', $content) ; + $this->setData(['page',$childId,'content', $replace ]); } } - return $dirContent; + $this->setData(['core','baseUrl',helper::baseUrl(false,false)]); + // Valeurs en sortie + $this->addOutput([ + 'title' => 'Sauvegarder / Restaurer', + 'view' => 'manage' + ]); } - } diff --git a/core/module/config/view/index/index.js.php b/core/module/config/view/index/index.js.php new file mode 100644 index 00000000..d6c43a6b --- /dev/null +++ b/core/module/config/view/index/index.js.php @@ -0,0 +1,16 @@ +/** + * 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 Frédéric Tempez + * @copyright Copyright (C) 2018-2020, Frédéric Tempez + * @license GNU General Public License, version 3 + * @link http://zwiicms.com/ + */ + +/** + * Modification de l'affichage de l'icône de langues + */ + diff --git a/core/module/config/view/index/index.php b/core/module/config/view/index/index.php index 35ed1696..d6f1da76 100755 --- a/core/module/config/view/index/index.php +++ b/core/module/config/view/index/index.php @@ -1,4 +1,5 @@ +

'Accueil' ]); ?>
-
+
+ helper::baseUrl() . 'config/manage', + 'value' => 'Sauvegarder / Restaurer' + ]); ?> +
+
@@ -20,7 +27,8 @@
getData(['page']), 'title', 'SORT_ASC'), [ 'label' => 'Page d\'accueil', - 'selected' => $this->getData(['config', 'homePageId']) + 'selected' =>$this->getData(['config', 'homePageId']), + 'help' => 'La page d\'accueil doit être définie dans une des pages de la langue sélectionnée' ]); ?>
@@ -40,7 +48,7 @@
-
+

Réglages

@@ -77,67 +85,81 @@ 'help' => 'Les mentions légales sont obligatoires en France' ]); ?>
-
-
-
- $this->getData(['config', 'cookieConsent']) - ]); ?> -
-
-
- helper::checkRewrite(), - 'help' => 'Vérifiez d\'abord que votre serveur l\'autorise : ce n\'est pas le cas chez Free.' - ]); ?> -
+
+
+ $this->getData(['config', 'cookieConsent']) + ]); ?> +
+
+ helper::checkRewrite(), + 'help' => 'Vérifiez d\'abord que votre serveur l\'autorise : ce n\'est pas le cas chez Free.' + ]); ?> +
- +
+
+ $this->getData(['config', 'maintenance']) + ]); ?> +
+
+ $this->getData(['config', 'autoUpdate']), + 'help' => 'Vérifie une fois par jour l\'existence d\'une mise à jour.' + ]); ?> +
+
+
+

Réseaux sociaux

-
+
'Saisissez votre ID : https://www.facebook.com/[ID].', 'label' => 'Facebook', 'value' => $this->getData(['config', 'social', 'facebookId']) ]); ?>
-
+
'Saisissez votre ID : https://www.instagram.com/[ID].', 'label' => 'Instagram', 'value' => $this->getData(['config', 'social', 'instagramId']) ]); ?>
-
- 'Saisissez votre ID : https://www.youtube.com/channel/[ID].', - 'label' => 'Youtube', - 'value' => $this->getData(['config', 'social', 'youtubeId']) - ]); ?> -
-
+
-
- 'Saisissez votre ID : https://twitter.com/[ID].', - 'label' => 'Twitter', +
+ 'Saisissez votre ID : https://www.youtube.com/channel/[ID].', + 'label' => 'Youtube', + 'value' => $this->getData(['config', 'social', 'youtubeId']) + ]); ?> +
+
+ 'Saisissez votre ID : https://twitter.com/[ID].', + 'label' => 'Twitter', 'value' => $this->getData(['config', 'social', 'twitterId']) ]); ?>
-
+
+
+
'Saisissez votre ID : https://pinterest.com/[ID].', 'label' => 'Pinterest', 'value' => $this->getData(['config', 'social', 'pinterestId']) ]); ?>
-
+
'Saisissez votre ID Linkedin : https://fr.linkedin.com/in/[ID].', 'label' => 'Linkedin', @@ -146,7 +168,7 @@
-
+
'Saisissez votre ID Github : https://github.com/[ID].', 'label' => 'Github', @@ -156,36 +178,8 @@
-
-
-
-
-

Gestion et sauvegarde

-
-
- $this->getData(['config', 'maintenance']) - ]); ?> - $this->getData(['config', 'autoUpdate']), - 'help' => 'Vérifie une fois par jour l\'existence d\'une mise à jour.' - ]); ?> - $this->getData(['config', 'autoBackup']), - 'help' => 'Le fichier de données est copié quotidiennement dans le dossier \'site/backup\'. La sauvegarde est conservée pendant 30 jours.' - ]); ?> -
-
-
-
- helper::baseUrl() . 'config/backup', - 'value' => 'Exporter une copie du site
(données, thème et fichiers)' - ]); ?> -
-
-
-
+

Référencement

@@ -304,4 +298,5 @@
+
diff --git a/core/module/config/view/manage/manage.php b/core/module/config/view/manage/manage.php new file mode 100644 index 00000000..7b2770d6 --- /dev/null +++ b/core/module/config/view/manage/manage.php @@ -0,0 +1,100 @@ + +
+
+
+ 'buttonGrey', + 'href' => helper::baseUrl() . 'config', + 'ico' => 'left', + 'value' => 'Retour' + ]); ?> +
+
+ 'Enregister' + ]); ?> +
+
+
+
+
+

Sauvegarde du site (données et thème)

+
+
+ helper::baseUrl() . 'config/backup', + 'value' => 'Générer et télécharger
une archive des données de site', + ]); ?> +
+
+
+ $this->getData(['config', 'autoBackup']), + 'help' => '

Une archive contenant le dossier /site/data est copiée dans le dossier \'site/backup\'. La sauvegarde est conservée pendant 30 jours.

Les fichiers du site ne sont pas sauvegardés automatiquement.

' + ]); ?> +
+
+
+
+
+

Restauration ou transfert d'un site

+
+ 'Sélectionnez une archive au format ZIP', + 'type' => 2, + 'help' => 'L\'archive a été déposée dans le gestionaire de fichiers. Les archives inférieures à la version 9 ne sont pas acceptées.' + ]); ?> +
+
+ true + ]); ?> +
+
+
+
+
+
+
+

Conversion des URL après transfert de site

+
+
+ getData(['core', 'baseUrl'])) ) { + $baseUrlValue = 'Pas de donnée dans la sauvegarde'; + $buttonClass = 'disabled'; + } elseif ($this->getData(['core', 'baseUrl']) === '') { + $baseUrlValue = '/'; + $buttonClass = (helper::baseUrl(false,false) !== $this->getData(['core', 'baseUrl']) ) ? '' : 'disabled'; + } else { + $baseUrlValue = $this->getData(['core', 'baseUrl']); + $buttonClass = (helper::baseUrl(false,false) !== $this->getData(['core', 'baseUrl']) ) ? '' : 'disabled'; + } + echo template::text('configManageBaseURLToConvert', [ + 'label' => 'Dossier d\'installation de l\'archive' , + 'value' => $baseUrlValue, + 'readonly' => true, + 'help' => 'Lors de la restauration d\'un backup d\'une version 9.2.10 ou supérieure, l\'URL de base est stockée dans la configuration sinon cette donnée est vide.' + ]); ?> +
+
+ 'Dossier du site actuel', + 'value' => helper::baseUrl(false,false), + 'readonly' => true, + 'help' => 'Dossier du site installé.' + ]); ?> +
+
+ helper::baseUrl() . 'config/updateBaseUrl', + 'class' => $buttonClass, + 'value' => 'convertir' + ]); ?> +
+
+
+
+
+
+ diff --git a/core/module/install/install.php b/core/module/install/install.php index ed2219c2..9e49f967 100755 --- a/core/module/install/install.php +++ b/core/module/install/install.php @@ -12,6 +12,7 @@ * @link http://zwiicms.com/ */ + class install extends common { public static $actions = [ @@ -33,13 +34,14 @@ class install extends common { if($this->getData(['user']) !== []) { // Valeurs en sortie $this->addOutput([ - 'access' => false + 'access' => false ]); } // Accès autorisé else { // Soumission du formulaire if($this->isPost()) { + //$sent = $success = false; // Double vérification pour le mot de passe if($this->getInput('installPassword', helper::FILTER_STRING_SHORT, true) !== $this->getInput('installConfirmPassword', helper::FILTER_STRING_SHORT, true)) { self::$inputNotices['installConfirmPassword'] = 'Incorrect'; @@ -50,35 +52,15 @@ class install extends common { $userMail = $this->getInput('installMail', helper::FILTER_MAIL, true); $userId = $this->getInput('installId', helper::FILTER_ID, true); // Configure certaines données par défaut - if ($this->getInput('installDefaultData',helper::FILTER_BOOLEAN) === FALSE) { - foreach($this->getHierarchy(null, false) as $parentPageId => $childrenPageIds) { - if ( $parentPageId !== 'accueil') { - if ($this->getdata(['page',$parentPageId,'moduleId'])) { - $this->deleteData(['page',$parentPageId]); - } - } - foreach($childrenPageIds as $childKey) { - $this->deleteData(['page', $childKey]); - } - } - // Effacer les barres - $this->deleteData(['page', 'barre']); - $this->deleteData(['page', 'barrelateraleavecmenu']); - // Effacer les modules - $this->deleteData(['module']); - // Ajouter ici la liste des pages privées qui ne sont pas vues lors de l'installation. - $this->deleteData(['page', 'privee']); - // Effacer les fichiers par défaut - if (is_dir(self::FILE_DIR.'source/galerie')) { - $this->removeAll(self::FILE_DIR.'source/galerie'); - $this->removeAll(self::FILE_DIR.'thumb/galerie'); - } + if ($this->getInput('installDefaultData',helper::FILTER_BOOLEAN) === TRUE) { + $this->initData('page','fr',true); + $this->initData('module','fr',true); } else { $this->setData(['module', 'blog', 'mon-premier-article', 'userId', $userId]); $this->setData(['module', 'blog', 'mon-deuxieme-article', 'userId', $userId]); $this->setData(['module', 'blog', 'mon-troisieme-article', 'userId', $userId]); } - $this->setData([ + $success = $this->setData([ 'user', $userId, [ @@ -89,28 +71,32 @@ class install extends common { 'mail' => $userMail, 'password' => $this->getInput('installPassword', helper::FILTER_PASSWORD, true) ] - ]); - // Envoie le mail - $sent = $this->sendMail( - $userMail, - 'Installation de votre site', - 'Bonjour' . ' ' . $userFirstname . ' ' . $userLastname . ',

' . - 'Voici les détails de votre installation.

' . - 'URL du site : ' . helper::baseUrl(false) . '
' . - 'Identifiant du compte : ' . $this->getInput('installId') . '
' - ); - // Générer un fichier robots.txt - $this->createRobots(); - // Créer sitemap - $this->createSitemap('all'); - // Valeurs en sortie - $this->addOutput([ - 'redirect' => helper::baseUrl(false), - 'notification' => ($sent === true ? 'Installation terminée' : $sent), - 'state' => ($sent === true ? true : null) ]); + if ($success === true) { // Formulaire complété envoi du mail + // Envoie le mail + $sent = $this->sendMail( + $userMail, + 'Installation de votre site', + 'Bonjour' . ' ' . $userFirstname . ' ' . $userLastname . ',

' . + 'Voici les détails de votre installation.

' . + 'URL du site : ' . helper::baseUrl(false) . '
' . + 'Identifiant du compte : ' . $this->getInput('installId') . '
' + ); + // Stocker le dossier d'installation + $this->setData(['core', 'baseUrl', helper::baseUrl(false,false) ]); + // Générer un fichier robots.txt + $this->createRobots(); + // Créer sitemap + $this->createSitemap(); + // Valeurs en sortie + $this->addOutput([ + 'redirect' => helper::baseUrl(false), + 'notification' => ($sent === true ? 'Installation terminée' : $sent), + 'state' => ($sent === true ? true : null) + ]); + } } - + // Valeurs en sortie $this->addOutput([ 'display' => self::DISPLAY_LAYOUT_LIGHT, diff --git a/core/module/install/ressource/defaultdata.php b/core/module/install/ressource/defaultdata.php index cedc1ac6..d4af6a90 100644 --- a/core/module/install/ressource/defaultdata.php +++ b/core/module/install/ressource/defaultdata.php @@ -1,15 +1,14 @@ [ 'analyticsId' => '', 'autoBackup' => true, 'cookieConsent' => true, 'favicon' => 'favicon.ico', 'homePageId' => 'accueil', - 'maintenance' => false, - 'metaDescription' => 'Zwii est un CMS sans base de données qui permet de créer et gérer facilement un site web sans aucune connaissance en programmation.', + 'maintenance' => false, 'social' => [ 'facebookId' => 'facebook', 'instagramId' => '', @@ -19,26 +18,28 @@ class install extends common { 'githubId' => '' ], 'timezone' => 'Europe/Paris', - 'title' => 'Zwii, votre site en quelques clics !', 'itemsperPage' => 10, - 'legalPageId' => '' + 'legalPageId' => '', + 'metaDescription' => 'Zwii est un CMS sans base de données qui permet de créer et gérer facilement un site web sans aucune connaissance en programmation.', + 'title' => 'Zwii, votre site en quelques clics !' ], 'core' => [ - 'dataVersion' => 0, + 'dataVersion' => 10000, 'lastBackup' => 0, 'lastClearTmp' => 0, 'baseUrl' => '' ], - 'page' => [ + 'page' => [ 'accueil' => [ 'typeMenu' => 'text', - 'iconUrl' => '', - 'disable' => false, + 'iconUrl' => '', + 'disable' => false, 'content' => '

Bienvenue sur votre nouveau site Zwii !

Un email contenant le récapitulatif de votre installation vient de vous être envoyé.

Connectez-vous dès maintenant à votre espace membre afin de créer un site à votre image ! Vous pourrez personnaliser le thème, créer des pages, ajouter des utilisateurs et bien plus encore !

Si vous avez besoin d\'aide ou si vous cherchez des informations sur Zwii, n\'hésitez pas à jeter un œil à notre forum.

', 'hideTitle' => false, + 'homePageId' => true, 'breadCrumb' => false, 'metaDescription' => '', 'metaTitle' => '', @@ -55,357 +56,9 @@ class install extends common { 'displayMenu' => 'none', 'hideMenuSide' => false, 'hideMenuChildren' =>false - ], - 'enfant' => [ - 'typeMenu' => 'text', - 'iconUrl' => '', - 'disable' => false, - 'content' => '

Vous pouvez assigner des parents à vos pages afin de mieux organiser votre menu !

-
-

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam interdum, neque non vulputate hendrerit, arcu turpis dapibus nisl, id scelerisque metus lectus vitae nisi. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec feugiat dolor et turpis finibus condimentum. Cras sit amet ligula sagittis justo.

-

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam interdum, neque non vulputate hendrerit, arcu turpis dapibus nisl, id scelerisque metus lectus vitae nisi. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec feugiat dolor et turpis finibus condimentum. Cras sit amet ligula sagittis justo.

-

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam interdum, neque non vulputate hendrerit, arcu turpis dapibus nisl, id scelerisque metus lectus vitae nisi. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec feugiat dolor et turpis finibus condimentum. Cras sit amet ligula sagittis justo.

-
', - 'hideTitle' => false, - 'breadCrumb' => true, - 'metaDescription' => '', - 'metaTitle' => '', - 'moduleId' => '', - 'modulePosition' => 'bottom', - 'parentPageId' => 'accueil', - 'position' => 1, - 'group' => self::GROUP_VISITOR, - 'targetBlank' => false, - 'title' => 'Enfant', - 'block' => '12', - 'barLeft' => '', - 'barRight' => '', - 'displayMenu' => 'none', - 'hideMenuSide' => false, - 'hideMenuChildren' =>false - ], - 'privee' => [ - 'typeMenu' => 'text', - 'iconUrl' => '', - 'disable' => false, - 'content' => '

Cette page n\'est visible que des membres de votre site !

-
-

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam interdum, neque non vulputate hendrerit, arcu turpis dapibus nisl, id scelerisque metus lectus vitae nisi. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec feugiat dolor et turpis finibus condimentum. Cras sit amet ligula sagittis justo.

-

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam interdum, neque non vulputate hendrerit, arcu turpis dapibus nisl, id scelerisque metus lectus vitae nisi. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec feugiat dolor et turpis finibus condimentum. Cras sit amet ligula sagittis justo.

-
', - 'hideTitle' => false, - 'breadCrumb' => true, - 'metaDescription' => '', - 'metaTitle' => '', - 'moduleId' => '', - 'parentPageId' => '', - 'modulePosition' => 'bottom', - 'position' => 2, - 'group' => self::GROUP_MEMBER, - 'targetBlank' => false, - 'title' => 'Privée', - 'block' => '12', - 'barLeft' => '', - 'barRight' => '', - 'displayMenu' => 'none', - 'hideMenuSide' => false, - 'hideMenuChildren' =>false - ], - 'mise-en-page' => [ - 'typeMenu' => 'text', - 'iconUrl' => '', - 'disable' => false, - 'content' => '

Vous pouvez ajouter une ou deux barres latérales aux pages de votre site. Cette mise en page se définit dans les paramètres de page et peut s\'appliquer à l\'ensemble du site ou à certaines pages en particulier, au gré de vos désirs.

-

Pour créer une barre latérale à partir d\'une "Nouvelle page" ou transformer une page existante en barre latérale, sélectionnez l\'option dans la liste des gabarits. On peut bien sûr définir autant de barres latérales qu\'on le souhaite.

-

Cette nouvelle fonctionnalité autorise toutes sortes d\'utilisations : texte, encadrés, images, vidéos... ou simple marge blanche. Seule restriction : on ne peut pas installer un module dans une barre latérale.

-

La liste des barres disponibles et leur emplacement s\'affichent en fonction du gabarit que vous aurez choisi.', - 'hideTitle' => false, - 'breadCrumb' => true, - 'metaDescription' => '', - 'metaTitle' => '', - 'moduleId' => '', - 'parentPageId' => 'accueil', - 'modulePosition' => 'bottom', - 'position' => 3, - 'group' => self::GROUP_VISITOR, - 'targetBlank' => false, - 'title' => 'Mise en page', - 'block' => '4-8', - 'barLeft' => 'barre', - 'barRight' => '', - 'displayMenu' => 'none', - 'hideMenuSide' => false, - 'hideMenuChildren' =>false - ], - 'menu-lateral' => [ - 'typeMenu' => 'text', - 'iconUrl' => '', - 'disable' => false, - 'content' => '

Cette page illustre la possibilité d\'ajouter un menu dans les barres latérales.
- Deux types de menus sont disponibles : l\'un reprenant les rubriques du menu principal comme celui-ci, l\'autre listant les pages d\'une même rubrique. Le choix du type de menu se fait dans la page de configuration d\'une barre latérale.

-

Pour ajouter un menu à une page, choisissez une barre latérale avec menu dans la page de configuration. Les bulles d\'aide de la rubrique "Menu" expliquent comment masquer une page.

', - 'hideTitle' => false, - 'breadCrumb' => true, - 'metaDescription' => '', - 'metaTitle' => '', - 'moduleId' => '', - 'parentPageId' => 'accueil', - 'modulePosition' => 'bottom', - 'position' => 3, - 'group' => self::GROUP_VISITOR, - 'targetBlank' => false, - 'title' => 'Menu latéral', - 'block' => '9-3', - 'barLeft' => '', - 'barRight' => 'barrelateraleavecmenu', - 'displayMenu' => 'none', - 'hideMenuSide' => false, - 'hideMenuChildren' =>false - ], - 'blog' => [ - 'typeMenu' => 'text', - 'iconUrl' => '', - 'disable' => false, - 'content' => '

Cette page contient une instance du module de blog. Cliquez sur un article afin de le lire et de poster des commentaires.

', - 'hideTitle' => false, - 'breadCrumb' => false, - 'metaDescription' => '', - 'metaTitle' => '', - 'moduleId' => 'blog', - 'modulePosition' => 'bottom', - 'parentPageId' => '', - 'position' => 4, - 'group' => self::GROUP_VISITOR, - 'targetBlank' => false, - 'title' => 'Blog', - 'block' => '12', - 'barLeft' => '', - 'barRight' => '', - 'displayMenu' => 'none', - 'hideMenuSide' => false, - 'hideMenuChildren' =>false - ], - 'galeries' => [ - 'typeMenu' => 'text', - 'iconUrl' => '', - 'disable' => false, - 'content' => '

Cette page contient une instance du module de galeries photos. Cliquez sur la galerie ci-dessous afin de voir les photos qu\'elle contient.

', - 'hideTitle' => false, - 'breadCrumb' => false, - 'metaDescription' => '', - 'metaTitle' => '', - 'moduleId' => 'gallery', - 'modulePosition' => 'bottom', - 'parentPageId' => '', - 'position' => 5, - 'group' => self::GROUP_VISITOR, - 'targetBlank' => false, - 'title' => 'Galeries', - 'block' => '12', - 'barLeft' => '', - 'barRight' => '', - 'displayMenu' => 'none', - 'hideMenuSide' => false, - 'hideMenuChildren' =>false - ], - 'site-de-zwii' => [ - 'typeMenu' => 'text', - 'iconUrl' => '', - 'disable' => false, - 'content' => "", - 'hideTitle' => false, - 'breadCrumb' => false, - 'metaDescription' => '', - 'metaTitle' => '', - 'moduleId' => 'redirection', - 'modulePosition' => 'bottom', - 'parentPageId' => '', - 'position' => 6, - 'group' => self::GROUP_VISITOR, - 'targetBlank' => true, - 'title' => 'Site de Zwii', - 'block' => '12', - 'barLeft' => '', - 'barRight' => '', - 'displayMenu' => 'none', - 'hideMenuSide' => false, - 'hideMenuChildren' =>false - ], - 'contact' => [ - 'typeMenu' => 'text', - 'iconUrl' => '', - 'disable' => false, - 'content' => '

Cette page contient un exemple de formulaire conçu à partir du module de génération de formulaires. Il est configuré pour envoyer les données saisies par mail aux administrateurs du site.

', - 'hideTitle' => false, - 'breadCrumb' => false, - 'metaDescription' => '', - 'metaTitle' => '', - 'moduleId' => 'form', - 'modulePosition' => 'bottom', - 'parentPageId' => '', - 'position' => 7, - 'group' => self::GROUP_VISITOR, - 'targetBlank' => false, - 'title' => 'Contact', - 'block' => '12', - 'barLeft' => '', - 'barRight' => '', - 'displayMenu' => 'none', - 'hideMenuSide' => false, - 'hideMenuChildren' =>false - ], - 'barre' => [ - 'typeMenu' => 'text', - 'iconUrl' => '', - 'disable' => false, - 'content' => '

ZwiiCMS

Le CMS sans base de données à l\'installation simple et rapide

', - 'hideTitle' => false, - 'breadCrumb' => false, - 'metaDescription' => '', - 'metaTitle' => '', - 'moduleId' => '', - 'modulePosition' => 'bottom', - 'parentPageId' => '', - 'position' => 0 , - 'group' => self::GROUP_VISITOR, - 'targetBlank' => false, - 'title' => 'Barre latérale', - 'block' => 'bar', - 'barLeft' => '', - 'barRight' => '', - 'displayMenu' => "none", - 'hideMenuSide' => false, - 'hideMenuChildren' =>false - ], - 'barrelateraleavecmenu' => [ - 'typeMenu' => 'text', - 'iconUrl' => '', - 'disable' => false, - 'content' => '

 

', - 'hideTitle' => false, - 'breadCrumb' => false, - 'metaDescription' => '', - 'metaTitle' => '', - 'moduleId' => '', - 'modulePosition' => 'bottom', - 'parentPageId' => '', - 'position' => 0 , - 'group' => self::GROUP_VISITOR, - 'targetBlank' => false, - 'title' => 'Barre latérale avec menu', - 'block' => 'bar', - 'barLeft' => '', - 'barRight' => '', - 'displayMenu' => "parents", - 'hideMenuSide' => false, - 'hideMenuChildren' =>false - ], - ], - 'module' => [ - 'blog' => [ - 'mon-premier-article' => [ - 'closeComment' => false, - 'comment' => [ - '58e11d09e5aff' => [ - 'author' => 'Rémi', - 'content' => 'Article bien rédigé et très pertinent, bravo !', - 'createdOn' => 1421748000, - 'userId' => '' - ] - ], - 'content' => '

Lorem ipsum dolor sit amet, consectetur adipiscing elit. In a placerat metus. Morbi luctus laoreet dolor et euismod. Phasellus eget eros ac eros pretium tincidunt. Sed maximus magna lectus, non vestibulum sapien pretium maximus. Donec convallis leo tortor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cras convallis lacus eu risus gravida varius. Etiam mattis massa vitae eros placerat bibendum.

Vivamus tempus magna augue, in bibendum quam blandit at. Morbi felis tortor, suscipit ut ipsum ut, volutpat consectetur orci. Nulla tincidunt quis ligula non viverra. Sed pretium dictum blandit. Donec fringilla, nunc at dictum pretium, arcu massa viverra leo, et porta turpis ipsum eget risus. Quisque quis maximus purus, in elementum arcu. Donec nisi orci, aliquam non luctus non, congue volutpat massa. Curabitur sed risus congue, porta arcu vel, tincidunt nisi. Duis tincidunt quam ut velit maximus ornare. Nullam sagittis, ante quis pharetra hendrerit, lorem massa dapibus mi, a hendrerit dolor odio nec augue. Nunc sem nisl, tincidunt vitae nunc et, viverra tristique diam. In eget dignissim lectus. Nullam volutpat lacus id ex dapibus viverra. Pellentesque ultricies lorem ut nunc elementum volutpat. Cras id ultrices justo.

Phasellus nec erat leo. Praesent at sem nunc. Vestibulum quis condimentum turpis. Cras semper diam vitae enim fringilla, ut fringilla mauris efficitur. In nec porttitor urna. Nam eros leo, vehicula eget lobortis sed, gravida id mauris. Nulla bibendum nunc tortor, non bibendum justo consectetur vel. Phasellus nec risus diam. In commodo tellus nec nulla fringilla, nec feugiat nunc consectetur. Etiam non eros sodales, sodales lacus vel, finibus leo. Quisque hendrerit tristique congue. Phasellus nec augue vitae libero elementum facilisis. Mauris pretium ornare nisi, non scelerisque velit consectetur sit amet.

', - 'picture' => 'galerie/landscape/meadow.jpg', - 'hidePicture' => false, - 'publishedOn' => 1548790902, - 'state' => true, - 'title' => 'Mon premier article', - 'userId' => '' // Géré au moment de l'installation - ], - 'mon-deuxieme-article' => [ - 'closeComment' => false, - 'comment' => [], - 'content' => '

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam lobortis eros pharetra metus rutrum pretium et sagittis mauris. Donec commodo venenatis sem nec suscipit. In tempor sollicitudin scelerisque. Etiam quis nibh eleifend, congue nisl quis, ultricies ipsum. Integer at est a eros vulputate pellentesque eu vitae tellus. Nullam suscipit quam nisl. Vivamus dui odio, luctus ac fringilla ultrices, eleifend vel sapien. Integer sem ex, lobortis eu mattis eu, condimentum non libero. Aliquam non porttitor elit, eu hendrerit neque. Praesent tortor urna, tincidunt sed dictum id, rutrum tempus sapien.

Donec accumsan ante ac odio laoreet porttitor. Pellentesque et leo a leo scelerisque mattis id vel elit. Quisque egestas congue enim nec semper. Morbi mollis nibh sapien. Nunc quis fringilla lorem. Donec vel venenatis nunc. Donec lectus velit, tempor sit amet dui sed, consequat commodo enim. Nam porttitor neque semper, dapibus nunc bibendum, lobortis urna. Morbi ullamcorper molestie lectus a elementum. Curabitur eu cursus orci, sed tristique justo. In massa lacus, imperdiet eu elit quis, consectetur maximus magna. Integer suscipit varius ante vitae egestas. Morbi scelerisque fermentum ipsum, euismod faucibus mi tincidunt id. Sed at consectetur velit. Ut fermentum nunc nibh, at commodo felis lacinia nec.

Nullam a justo quis lectus facilisis semper eget quis sem. Morbi suscipit erat sem, non fermentum nunc luctus vel. Proin venenatis quam ut arcu luctus efficitur. Interdum et malesuada fames ac ante ipsum primis in faucibus. Nam sollicitudin tristique nunc nec convallis. Maecenas id tortor semper, tempus nisl laoreet, cursus lacus. Aliquam sagittis est in leo congue, a pharetra felis aliquet. Nulla gravida lobortis sapien, quis viverra enim ullamcorper sed. Donec ultrices sem eu volutpat dapibus. Nam euismod, tellus eu congue mollis, massa nisi finibus odio, vitae porta arcu urna ac lorem. Sed faucibus dignissim pretium. Pellentesque eget ante tellus. Pellentesque a elementum odio, sit amet vulputate diam. Lorem ipsum dolor sit amet, consectetur adipiscing elit. In hendrerit consequat dolor, malesuada pellentesque tellus molestie non. Aenean quis purus a lectus pellentesque laoreet.

', - 'picture' => 'galerie/landscape/desert.jpg', - 'hidePicture' => false, - 'publishedOn' => 1550432502, - 'state' => true, - 'title' => 'Mon deuxième article', - 'userId' => '' // Géré au moment de l'installation - ], - 'mon-troisieme-article' => [ - 'closeComment' => true, - 'comment' => [], - 'content' => '

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut ut tempus nibh. Cras eget iaculis justo, ac laoreet lacus. Nunc tellus nulla, auctor id hendrerit eu, pellentesque in sapien. In hac habitasse platea dictumst. Aliquam leo urna, hendrerit id nunc eget, finibus maximus dolor. Sed rutrum sapien consectetur, tincidunt nulla at, blandit quam. Duis ex enim, vehicula vel nisi vitae, lobortis volutpat nisl. Vivamus enim libero, euismod nec risus vel, interdum placerat elit. In cursus sapien condimentum dui imperdiet, sed lobortis ante consectetur. Maecenas hendrerit eget felis non consequat.

Nullam nec risus non velit efficitur tempus eget tincidunt mauris. Etiam venenatis leo id justo sagittis, commodo dignissim sapien tristique. Vivamus finibus augue malesuada sapien gravida rutrum. Integer mattis lectus ac pulvinar scelerisque. Integer suscipit feugiat metus, ac molestie odio suscipit eget. Fusce at elit in tellus venenatis finibus id sit amet magna. Integer sodales luctus neque blandit posuere. Cras pellentesque dictum lorem eget vestibulum. Quisque vitae metus non nisi efficitur rhoncus ut vitae ipsum. Donec accumsan massa at est faucibus lacinia. Quisque imperdiet luctus neque eu vestibulum. Phasellus pellentesque felis ligula, id imperdiet elit ultrices eu.

', - 'picture' => 'galerie/landscape/iceberg.jpg', - 'hidePicture' => false, - 'publishedOn' => 1550864502, - 'state' => true, - 'title' => 'Mon troisième article', - 'userId' => '' // Géré au moment de l'installation - ] - ], - 'galeries' => [ - 'beaux-paysages' => [ - 'config' => [ - 'name' => 'Beaux paysages', - 'directory' => self::FILE_DIR.'source/galerie/landscape' - ], - 'legend' => [ - 'desert.jpg' => 'Un désert', - 'iceberg.jpg' => 'Un iceberg', - 'meadow.jpg' => 'Une prairie' - ] - ], - 'espace' => [ - 'config' => [ - 'name' => 'Espace', - 'directory' => self::FILE_DIR.'source/galerie/space' - ], - 'legend' => [ - 'earth.jpg' => 'La Terre et la Lune', - 'cosmos.jpg' => 'Le cosmos', - 'nebula.jpg' => 'Une nébuleuse' - ] - ] - ], - 'site-de-zwii' => [ - 'url' => 'https://zwiicms.com/', - 'count' => 0 - ], - 'contact' => [ - 'config' => [ - 'button' => '', - 'capcha' => true, - 'group' => self::GROUP_ADMIN, - 'pageId' => '', - 'subject' => '' - ], - 'data' => [], - 'input' => [ - [ - 'name' => 'Adresse mail', - 'position' => 1, - 'required' => true, - 'type' => 'mail', - 'values' => '' - ], - [ - 'name' => 'Sujet', - 'position' => 2, - 'required' => true, - 'type' => 'text', - 'values' => '' - ], - [ - 'name' => 'Message', - 'position' => 3, - 'required' => true, - 'type' => 'textarea', - 'values' => '' - ] - ] ] ], + 'module' => [], 'user' => [], 'theme' => [ 'body' => [ @@ -473,14 +126,15 @@ class install extends common { 'fontWeight' => 'normal', 'height' => '15px 10px', 'loginLink' => true, + 'burgerTitle' => true, 'margin' => false, 'position' => 'site-second', 'textAlign' => 'left', 'textColor' => 'rgba(255, 255, 255, 1)', 'textTransform' => 'none', 'fixed' => false, - 'activeColor' => 'rgba(255, 255, 255, 1)', - 'activeColorAuto' => true + 'activeColorAuto' => true, + 'activeColor' => 'rgba(255, 255, 255, 1)' ], 'site' => [ 'backgroundColor' => 'rgba(255, 255, 255, 1)', @@ -502,4 +156,396 @@ class install extends common { 'version' => 0, ] ]; -} + + + public static $siteData = [ + 'page' => [ + 'accueil' => [ + 'typeMenu' => 'text', + 'iconUrl' => '', + 'disable' => false, + 'content' => '

Bienvenue sur votre nouveau site Zwii !

+

Un email contenant le récapitulatif de votre installation vient de vous être envoyé.

+

Connectez-vous dès maintenant à votre espace membre afin de créer un site à votre image ! Vous pourrez personnaliser le thème, créer des pages, ajouter des utilisateurs et bien plus encore !

+

Si vous avez besoin d\'aide ou si vous cherchez des informations sur Zwii, n\'hésitez pas à jeter un œil à notre forum.

', + 'hideTitle' => false, + 'homePageId' => true, + 'breadCrumb' => false, + 'metaDescription' => '', + 'metaTitle' => '', + 'moduleId' => '', + 'modulePosition' => 'bottom', + 'parentPageId' => '', + 'position' => 1, + 'group' => self::GROUP_VISITOR, + 'targetBlank' => false, + 'title' => 'Accueil', + 'block' => '12', + 'barLeft' => '', + 'barRight' => '', + 'displayMenu' => 'none', + 'hideMenuSide' => false, + 'hideMenuChildren' =>false + ], + 'enfant' => [ + 'typeMenu' => 'text', + 'iconUrl' => '', + 'disable' => false, + 'content' => '

Vous pouvez assigner des parents à vos pages afin de mieux organiser votre menu !

+
+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam interdum, neque non vulputate hendrerit, arcu turpis dapibus nisl, id scelerisque metus lectus vitae nisi. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec feugiat dolor et turpis finibus condimentum. Cras sit amet ligula sagittis justo.

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam interdum, neque non vulputate hendrerit, arcu turpis dapibus nisl, id scelerisque metus lectus vitae nisi. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec feugiat dolor et turpis finibus condimentum. Cras sit amet ligula sagittis justo.

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam interdum, neque non vulputate hendrerit, arcu turpis dapibus nisl, id scelerisque metus lectus vitae nisi. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec feugiat dolor et turpis finibus condimentum. Cras sit amet ligula sagittis justo.

+
', + 'hideTitle' => false, + 'homePageId' => false, + 'breadCrumb' => true, + 'metaDescription' => '', + 'metaTitle' => '', + 'moduleId' => '', + 'modulePosition' => 'bottom', + 'parentPageId' => 'accueil', + 'position' => 1, + 'group' => self::GROUP_VISITOR, + 'targetBlank' => false, + 'title' => 'Enfant', + 'block' => '12', + 'barLeft' => '', + 'barRight' => '', + 'displayMenu' => 'none', + 'hideMenuSide' => false, + 'hideMenuChildren' =>false + ], + 'privee' => [ + 'typeMenu' => 'text', + 'iconUrl' => '', + 'disable' => false, + 'content' => '

Cette page n\'est visible que des membres de votre site !

+
+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam interdum, neque non vulputate hendrerit, arcu turpis dapibus nisl, id scelerisque metus lectus vitae nisi. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec feugiat dolor et turpis finibus condimentum. Cras sit amet ligula sagittis justo.

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam interdum, neque non vulputate hendrerit, arcu turpis dapibus nisl, id scelerisque metus lectus vitae nisi. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec feugiat dolor et turpis finibus condimentum. Cras sit amet ligula sagittis justo.

+
', + 'hideTitle' => false, + 'homePageId' => false, + 'breadCrumb' => true, + 'metaDescription' => '', + 'metaTitle' => '', + 'moduleId' => '', + 'parentPageId' => '', + 'modulePosition' => 'bottom', + 'position' => 2, + 'group' => self::GROUP_MEMBER, + 'targetBlank' => false, + 'title' => 'Privée', + 'block' => '12', + 'barLeft' => '', + 'barRight' => '', + 'displayMenu' => 'none', + 'hideMenuSide' => false, + 'hideMenuChildren' =>false + ], + 'mise-en-page' => [ + 'typeMenu' => 'text', + 'iconUrl' => '', + 'disable' => false, + 'content' => '

Vous pouvez ajouter une ou deux barres latérales aux pages de votre site. Cette mise en page se définit dans les paramètres de page et peut s\'appliquer à l\'ensemble du site ou à certaines pages en particulier, au gré de vos désirs.

+

Pour créer une barre latérale à partir d\'une "Nouvelle page" ou transformer une page existante en barre latérale, sélectionnez l\'option dans la liste des gabarits. On peut bien sûr définir autant de barres latérales qu\'on le souhaite.

+

Cette nouvelle fonctionnalité autorise toutes sortes d\'utilisations : texte, encadrés, images, vidéos... ou simple marge blanche. Seule restriction : on ne peut pas installer un module dans une barre latérale.

+

La liste des barres disponibles et leur emplacement s\'affichent en fonction du gabarit que vous aurez choisi.', + 'hideTitle' => false, + 'homePageId' => false, + 'breadCrumb' => true, + 'metaDescription' => '', + 'metaTitle' => '', + 'moduleId' => '', + 'parentPageId' => 'accueil', + 'modulePosition' => 'bottom', + 'position' => 3, + 'group' => self::GROUP_VISITOR, + 'targetBlank' => false, + 'title' => 'Mise en page', + 'block' => '4-8', + 'barLeft' => 'barre', + 'barRight' => '', + 'displayMenu' => 'none', + 'hideMenuSide' => false, + 'hideMenuChildren' =>false + ], + 'menu-lateral' => [ + 'typeMenu' => 'text', + 'iconUrl' => '', + 'disable' => false, + 'content' => '

Cette page illustre la possibilité d\'ajouter un menu dans les barres latérales.
+ Deux types de menus sont disponibles : l\'un reprenant les rubriques du menu principal comme celui-ci, l\'autre listant les pages d\'une même rubrique. Le choix du type de menu se fait dans la page de configuration d\'une barre latérale.

+

Pour ajouter un menu à une page, choisissez une barre latérale avec menu dans la page de configuration. Les bulles d\'aide de la rubrique "Menu" expliquent comment masquer une page.

', + 'hideTitle' => false, + 'homePageId' => false, + 'breadCrumb' => true, + 'metaDescription' => '', + 'metaTitle' => '', + 'moduleId' => '', + 'parentPageId' => 'accueil', + 'modulePosition' => 'bottom', + 'position' => 3, + 'group' => self::GROUP_VISITOR, + 'targetBlank' => false, + 'title' => 'Menu latéral', + 'block' => '9-3', + 'barLeft' => '', + 'barRight' => 'barrelateraleavecmenu', + 'displayMenu' => 'none', + 'hideMenuSide' => false, + 'hideMenuChildren' =>false + ], + 'blog' => [ + 'typeMenu' => 'text', + 'iconUrl' => '', + 'disable' => false, + 'content' => '

Cette page contient une instance du module de blog. Cliquez sur un article afin de le lire et de poster des commentaires.

', + 'hideTitle' => false, + 'homePageId' => false, + 'breadCrumb' => false, + 'metaDescription' => '', + 'metaTitle' => '', + 'moduleId' => 'blog', + 'modulePosition' => 'bottom', + 'parentPageId' => '', + 'position' => 4, + 'group' => self::GROUP_VISITOR, + 'targetBlank' => false, + 'title' => 'Blog', + 'block' => '12', + 'barLeft' => '', + 'barRight' => '', + 'displayMenu' => 'none', + 'hideMenuSide' => false, + 'hideMenuChildren' =>false + ], + 'galeries' => [ + 'typeMenu' => 'text', + 'iconUrl' => '', + 'disable' => false, + 'content' => '

Cette page contient une instance du module de galeries photos. Cliquez sur la galerie ci-dessous afin de voir les photos qu\'elle contient.

', + 'hideTitle' => false, + 'homePageId' => false, + 'breadCrumb' => false, + 'metaDescription' => '', + 'metaTitle' => '', + 'moduleId' => 'gallery', + 'modulePosition' => 'bottom', + 'parentPageId' => '', + 'position' => 5, + 'group' => self::GROUP_VISITOR, + 'targetBlank' => false, + 'title' => 'Galeries', + 'block' => '12', + 'barLeft' => '', + 'barRight' => '', + 'displayMenu' => 'none', + 'hideMenuSide' => false, + 'hideMenuChildren' =>false + ], + 'site-de-zwii' => [ + 'typeMenu' => 'text', + 'iconUrl' => '', + 'disable' => false, + 'content' => "", + 'hideTitle' => false, + 'homePageId' => false, + 'breadCrumb' => false, + 'metaDescription' => '', + 'metaTitle' => '', + 'moduleId' => 'redirection', + 'modulePosition' => 'bottom', + 'parentPageId' => '', + 'position' => 6, + 'group' => self::GROUP_VISITOR, + 'targetBlank' => true, + 'title' => 'Site de Zwii', + 'block' => '12', + 'barLeft' => '', + 'barRight' => '', + 'displayMenu' => 'none', + 'hideMenuSide' => false, + 'hideMenuChildren' =>false + ], + 'contact' => [ + 'typeMenu' => 'text', + 'iconUrl' => '', + 'disable' => false, + 'content' => '

Cette page contient un exemple de formulaire conçu à partir du module de génération de formulaires. Il est configuré pour envoyer les données saisies par mail aux administrateurs du site.

', + 'hideTitle' => false, + 'homePageId' => false, + 'breadCrumb' => false, + 'metaDescription' => '', + 'metaTitle' => '', + 'moduleId' => 'form', + 'modulePosition' => 'bottom', + 'parentPageId' => '', + 'position' => 7, + 'group' => self::GROUP_VISITOR, + 'targetBlank' => false, + 'title' => 'Contact', + 'block' => '12', + 'barLeft' => '', + 'barRight' => '', + 'displayMenu' => 'none', + 'hideMenuSide' => false, + 'hideMenuChildren' =>false + ], + 'barre' => [ + 'typeMenu' => 'text', + 'iconUrl' => '', + 'disable' => false, + 'content' => '

ZwiiCMS

Le CMS sans base de données à l\'installation simple et rapide

', + 'hideTitle' => false, + 'homePageId' => false, + 'breadCrumb' => false, + 'metaDescription' => '', + 'metaTitle' => '', + 'moduleId' => '', + 'modulePosition' => 'bottom', + 'parentPageId' => '', + 'position' => 0 , + 'group' => self::GROUP_VISITOR, + 'targetBlank' => false, + 'title' => 'Barre latérale', + 'block' => 'bar', + 'barLeft' => '', + 'barRight' => '', + 'displayMenu' => "none", + 'hideMenuSide' => false, + 'hideMenuChildren' =>false + ], + 'barrelateraleavecmenu' => [ + 'typeMenu' => 'text', + 'iconUrl' => '', + 'disable' => false, + 'content' => '

 

', + 'hideTitle' => false, + 'homePageId' => false, + 'breadCrumb' => false, + 'metaDescription' => '', + 'metaTitle' => '', + 'moduleId' => '', + 'modulePosition' => 'bottom', + 'parentPageId' => '', + 'position' => 0 , + 'group' => self::GROUP_VISITOR, + 'targetBlank' => false, + 'title' => 'Barre latérale avec menu', + 'block' => 'bar', + 'barLeft' => '', + 'barRight' => '', + 'displayMenu' => "parents", + 'hideMenuSide' => false, + 'hideMenuChildren' =>false + ], + ], + 'module' => [ + 'blog' => [ + 'mon-premier-article' => [ + 'closeComment' => false, + 'comment' => [ + '58e11d09e5aff' => [ + 'author' => 'Rémi', + 'content' => 'Article bien rédigé et très pertinent, bravo !', + 'createdOn' => 1421748000, + 'userId' => '' + ] + ], + 'content' => '

Lorem ipsum dolor sit amet, consectetur adipiscing elit. In a placerat metus. Morbi luctus laoreet dolor et euismod. Phasellus eget eros ac eros pretium tincidunt. Sed maximus magna lectus, non vestibulum sapien pretium maximus. Donec convallis leo tortor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cras convallis lacus eu risus gravida varius. Etiam mattis massa vitae eros placerat bibendum.

Vivamus tempus magna augue, in bibendum quam blandit at. Morbi felis tortor, suscipit ut ipsum ut, volutpat consectetur orci. Nulla tincidunt quis ligula non viverra. Sed pretium dictum blandit. Donec fringilla, nunc at dictum pretium, arcu massa viverra leo, et porta turpis ipsum eget risus. Quisque quis maximus purus, in elementum arcu. Donec nisi orci, aliquam non luctus non, congue volutpat massa. Curabitur sed risus congue, porta arcu vel, tincidunt nisi. Duis tincidunt quam ut velit maximus ornare. Nullam sagittis, ante quis pharetra hendrerit, lorem massa dapibus mi, a hendrerit dolor odio nec augue. Nunc sem nisl, tincidunt vitae nunc et, viverra tristique diam. In eget dignissim lectus. Nullam volutpat lacus id ex dapibus viverra. Pellentesque ultricies lorem ut nunc elementum volutpat. Cras id ultrices justo.

Phasellus nec erat leo. Praesent at sem nunc. Vestibulum quis condimentum turpis. Cras semper diam vitae enim fringilla, ut fringilla mauris efficitur. In nec porttitor urna. Nam eros leo, vehicula eget lobortis sed, gravida id mauris. Nulla bibendum nunc tortor, non bibendum justo consectetur vel. Phasellus nec risus diam. In commodo tellus nec nulla fringilla, nec feugiat nunc consectetur. Etiam non eros sodales, sodales lacus vel, finibus leo. Quisque hendrerit tristique congue. Phasellus nec augue vitae libero elementum facilisis. Mauris pretium ornare nisi, non scelerisque velit consectetur sit amet.

', + 'picture' => 'galerie/landscape/meadow.jpg', + 'hidePicture' => false, + 'publishedOn' => 1548790902, + 'state' => true, + 'title' => 'Mon premier article', + 'userId' => '' // Géré au moment de l'installation + ], + 'mon-deuxieme-article' => [ + 'closeComment' => false, + 'comment' => [], + 'content' => '

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam lobortis eros pharetra metus rutrum pretium et sagittis mauris. Donec commodo venenatis sem nec suscipit. In tempor sollicitudin scelerisque. Etiam quis nibh eleifend, congue nisl quis, ultricies ipsum. Integer at est a eros vulputate pellentesque eu vitae tellus. Nullam suscipit quam nisl. Vivamus dui odio, luctus ac fringilla ultrices, eleifend vel sapien. Integer sem ex, lobortis eu mattis eu, condimentum non libero. Aliquam non porttitor elit, eu hendrerit neque. Praesent tortor urna, tincidunt sed dictum id, rutrum tempus sapien.

Donec accumsan ante ac odio laoreet porttitor. Pellentesque et leo a leo scelerisque mattis id vel elit. Quisque egestas congue enim nec semper. Morbi mollis nibh sapien. Nunc quis fringilla lorem. Donec vel venenatis nunc. Donec lectus velit, tempor sit amet dui sed, consequat commodo enim. Nam porttitor neque semper, dapibus nunc bibendum, lobortis urna. Morbi ullamcorper molestie lectus a elementum. Curabitur eu cursus orci, sed tristique justo. In massa lacus, imperdiet eu elit quis, consectetur maximus magna. Integer suscipit varius ante vitae egestas. Morbi scelerisque fermentum ipsum, euismod faucibus mi tincidunt id. Sed at consectetur velit. Ut fermentum nunc nibh, at commodo felis lacinia nec.

Nullam a justo quis lectus facilisis semper eget quis sem. Morbi suscipit erat sem, non fermentum nunc luctus vel. Proin venenatis quam ut arcu luctus efficitur. Interdum et malesuada fames ac ante ipsum primis in faucibus. Nam sollicitudin tristique nunc nec convallis. Maecenas id tortor semper, tempus nisl laoreet, cursus lacus. Aliquam sagittis est in leo congue, a pharetra felis aliquet. Nulla gravida lobortis sapien, quis viverra enim ullamcorper sed. Donec ultrices sem eu volutpat dapibus. Nam euismod, tellus eu congue mollis, massa nisi finibus odio, vitae porta arcu urna ac lorem. Sed faucibus dignissim pretium. Pellentesque eget ante tellus. Pellentesque a elementum odio, sit amet vulputate diam. Lorem ipsum dolor sit amet, consectetur adipiscing elit. In hendrerit consequat dolor, malesuada pellentesque tellus molestie non. Aenean quis purus a lectus pellentesque laoreet.

', + 'picture' => 'galerie/landscape/desert.jpg', + 'hidePicture' => false, + 'publishedOn' => 1550432502, + 'state' => true, + 'title' => 'Mon deuxième article', + 'userId' => '' // Géré au moment de l'installation + ], + 'mon-troisieme-article' => [ + 'closeComment' => true, + 'comment' => [], + 'content' => '

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut ut tempus nibh. Cras eget iaculis justo, ac laoreet lacus. Nunc tellus nulla, auctor id hendrerit eu, pellentesque in sapien. In hac habitasse platea dictumst. Aliquam leo urna, hendrerit id nunc eget, finibus maximus dolor. Sed rutrum sapien consectetur, tincidunt nulla at, blandit quam. Duis ex enim, vehicula vel nisi vitae, lobortis volutpat nisl. Vivamus enim libero, euismod nec risus vel, interdum placerat elit. In cursus sapien condimentum dui imperdiet, sed lobortis ante consectetur. Maecenas hendrerit eget felis non consequat.

Nullam nec risus non velit efficitur tempus eget tincidunt mauris. Etiam venenatis leo id justo sagittis, commodo dignissim sapien tristique. Vivamus finibus augue malesuada sapien gravida rutrum. Integer mattis lectus ac pulvinar scelerisque. Integer suscipit feugiat metus, ac molestie odio suscipit eget. Fusce at elit in tellus venenatis finibus id sit amet magna. Integer sodales luctus neque blandit posuere. Cras pellentesque dictum lorem eget vestibulum. Quisque vitae metus non nisi efficitur rhoncus ut vitae ipsum. Donec accumsan massa at est faucibus lacinia. Quisque imperdiet luctus neque eu vestibulum. Phasellus pellentesque felis ligula, id imperdiet elit ultrices eu.

', + 'picture' => 'galerie/landscape/iceberg.jpg', + 'hidePicture' => false, + 'publishedOn' => 1550864502, + 'state' => true, + 'title' => 'Mon troisième article', + 'userId' => '' // Géré au moment de l'installation + ] + ], + 'galeries' => [ + 'beaux-paysages' => [ + 'config' => [ + 'name' => 'Beaux paysages', + 'directory' => self::FILE_DIR.'source/galerie/landscape' + ], + 'legend' => [ + 'desertjpg' => 'Un désert', + 'icebergjpg' => 'Un iceberg', + 'meadowjpg' => 'Une prairie' + ] + ], + 'espace' => [ + 'config' => [ + 'name' => 'Espace', + 'directory' => self::FILE_DIR.'source/galerie/space' + ], + 'legend' => [ + 'earthjpg' => 'La Terre et la Lune', + 'cosmosjpg' => 'Le cosmos', + 'nebulajpg' => 'Une nébuleuse' + ] + ] + ], + 'site-de-zwii' => [ + 'url' => 'https://zwiicms.com/', + 'count' => 0 + ], + 'contact' => [ + 'config' => [ + 'button' => '', + 'capcha' => true, + 'group' => self::GROUP_ADMIN, + 'pageId' => '', + 'subject' => '' + ], + 'data' => [], + 'input' => [ + [ + 'name' => 'Adresse mail', + 'position' => 1, + 'required' => true, + 'type' => 'mail', + 'values' => '' + ], + [ + 'name' => 'Sujet', + 'position' => 2, + 'required' => true, + 'type' => 'text', + 'values' => '' + ], + [ + 'name' => 'Message', + 'position' => 3, + 'required' => true, + 'type' => 'textarea', + 'values' => '' + ] + ] + ] + ] + ]; +} \ No newline at end of file diff --git a/core/vendor/jsondb/Dot.php b/core/vendor/jsondb/Dot.php new file mode 100644 index 00000000..3c4af643 --- /dev/null +++ b/core/vendor/jsondb/Dot.php @@ -0,0 +1,316 @@ +data = $data; + } + } + + /** + * Get value of path, default value if path doesn't exist or all data + * + * @param array $array Source Array + * @param mixed|null $key Path + * @param mixed|null $default Default value + * @return mixed Value of path + */ + public static function getValue($array, $key, $default = null) + { + if (is_string($key)) { + // Iterate path + $keys = explode('.', $key); + foreach ($keys as $key) { + if (!isset($array[$key])) { + return $default; + } + $array = &$array[$key]; + } + // Get value + return $array; + } elseif (is_null($key)) { + // Get all data + return $array; + } + return null; + } + + /** + * Set value or array of values to path + * + * @param array $array Target array with data + * @param mixed $key Path or array of paths and values + * @param mixed|null $value Value to set if path is not an array + */ + public static function setValue(&$array, $key, $value) + { + if (is_string($key)) { + // Iterate path + $keys = explode('.', $key); + foreach ($keys as $key) { + if (!isset($array[$key]) || !is_array($array[$key])) { + $array[$key] = []; + } + $array = &$array[$key]; + } + // Set value to path + $array = $value; + } elseif (is_array($key)) { + // Iterate array of paths and values + foreach ($key as $k => $v) { + self::setValue($array, $k, $v); + } + } + } + + /** + * Add value or array of values to path + * + * @param array $array Target array with data + * @param mixed $key Path or array of paths and values + * @param mixed|null $value Value to set if path is not an array + * @param boolean $pop Helper to pop out last key if value is an array + */ + public static function addValue(&$array, $key, $value = null, $pop = false) + { + if (is_string($key)) { + // Iterate path + $keys = explode('.', $key); + if ($pop === true) { + array_pop($keys); + } + foreach ($keys as $key) { + if (!isset($array[$key]) || !is_array($array[$key])) { + $array[$key] = []; + } + $array = &$array[$key]; + } + // Add value to path + $array[] = $value; + } elseif (is_array($key)) { + // Iterate array of paths and values + foreach ($key as $k => $v) { + self::addValue($array, $k, $v); + } + } + } + + /** + * Delete path or array of paths + * + * @param array $array Target array with data + * @param mixed $key Path or array of paths to delete + */ + public static function deleteValue(&$array, $key) + { + if (is_string($key)) { + // Iterate path + $keys = explode('.', $key); + $last = array_pop($keys); + foreach ($keys as $key) { + if (!isset($array[$key])) { + return; + } + $array = &$array[$key]; + } + if (isset($array[$last])) { + // Detele path + unset($array[$last]); + } + } elseif (is_array($key)) { + // Iterate array of paths + foreach ($key as $k) { + self::delete($k); + } + } + } + + + /** + * Get value of path, default value if path doesn't exist or all data + * + * @param mixed|null $key Path + * @param mixed|null $default Default value + * @return mixed Value of path + */ + public function get($key = null, $default = null) + { + return self::getValue($this->data, $key, $default); + } + + /** + * Set value or array of values to path + * + * @param mixed $key Path or array of paths and values + * @param mixed|null $value Value to set if path is not an array + */ + public function set($key, $value = null) + { + return self::setValue($this->data, $key, $value); + } + + /** + * Add value or array of values to path + * + * @param mixed $key Path or array of paths and values + * @param mixed|null $value Value to set if path is not an array + * @param boolean $pop Helper to pop out last key if value is an array + */ + public function add($key, $value = null, $pop = false) + { + return self::addValue($this->data, $key, $value, $pop); + } + + /** + * Check if path exists + * + * @param string $key Path + * @return boolean + */ + public function has($key) + { + $keys = explode('.', (string)$key); + $data = &$this->data; + foreach ($keys as $key) { + if (!isset($data[$key])) { + return false; + } + $data = &$data[$key]; + } + + return true; + } + + /** + * Delete path or array of paths + * + * @param mixed $key Path or array of paths to delete + */ + public function delete($key) + { + return self::deleteValue($this->data, $key); + } + + /** + * Delete all data, data from path or array of paths and + * optionally format path if it doesn't exist + * + * @param mixed|null $key Path or array of paths to clean + * @param boolean $format Format option + */ + public function clear($key = null, $format = false) + { + if (is_string($key)) { + // Iterate path + $keys = explode('.', $key); + $data = &$this->data; + foreach ($keys as $key) { + if (!isset($data[$key]) || !is_array($data[$key])) { + if ($format === true) { + $data[$key] = []; + } else { + return; + } + } + $data = &$data[$key]; + } + // Clear path + $data = []; + } elseif (is_array($key)) { + // Iterate array + foreach ($key as $k) { + $this->clear($k, $format); + } + } elseif (is_null($key)) { + // Clear all data + $this->data = []; + } + } + + /** + * Set data + * + * @param array $data + */ + public function setData(array $data) + { + $this->data = $data; + } + + /** + * Set data as a reference + * + * @param array $data + */ + public function setDataAsRef(array &$data) + { + $this->data = &$data; + } + + /** + * ArrayAccess abstract methods + */ + public function offsetSet($offset, $value) + { + $this->set($offset, $value); + } + + public function offsetExists($offset) + { + return $this->has($offset); + } + + public function offsetGet($offset) + { + return $this->get($offset); + } + + public function offsetUnset($offset) + { + $this->delete($offset); + } + + /** + * Magic methods + */ + public function __set($key, $value = null) + { + $this->set($key, $value); + } + + public function __get($key) + { + return $this->get($key); + } + + public function __isset($key) + { + return $this->has($key); + } + + public function __unset($key) + { + $this->delete($key); + } +} diff --git a/core/vendor/jsondb/JsonDb.php b/core/vendor/jsondb/JsonDb.php new file mode 100644 index 00000000..de755bc1 --- /dev/null +++ b/core/vendor/jsondb/JsonDb.php @@ -0,0 +1,138 @@ +config = array_merge([ + 'name' => 'data.json', + 'backup' => 5, + 'dir' => getcwd(), + 'template' => getcwd() . DIRECTORY_SEPARATOR . 'data.template.json' + ], $config); + $this->loadData(); + parent::__construct(); + } + + /** + * Set value or array of values to path + * + * @param mixed $key Path or array of paths and values + * @param mixed|null $value Value to set if path is not an array + * @param bool $save Сохранить данные в базу + * @return $this + */ + public function set($key, $value = null, $save = true) + { + parent::set($key, $value); + if ($save) $this->save(); + return $this; + } + + /** + * Add value or array of values to path + * + * @param mixed $key Path or array of paths and values + * @param mixed|null $value Value to set if path is not an array + * @param boolean $pop Helper to pop out last key if value is an array + * @param bool $save Сохранить данные в базу + * @return $this + */ + public function add($key, $value = null, $pop = false, $save = true) + { + parent::add($key, $value, $pop); + if ($save) $this->save(); + return $this; + } + + /** + * Delete path or array of paths + * + * @param mixed $key Path or array of paths to delete + * @param bool $save Сохранить данные в базу + * @return $this + */ + public function delete($key, $save = true) + { + parent::delete($key); + if ($save) $this->save(); + return $this; + } + + /** + * Delete all data, data from path or array of paths and + * optionally format path if it doesn't exist + * + * @param mixed|null $key Path or array of paths to clean + * @param boolean $format Format option + * @param bool $save Сохранить данные в базу + * @return $this + */ + public function clear($key = null, $format = false, $save = true) + { + parent::clear($key, $format); + if ($save) $this->save(); + return $this; + } + + + /** + * Загрузка локальной базы данных + * @param bool $reload + * Перезагрузить данные? + * @return array|mixed|null + */ + protected function loadData($reload = false) { + if ($this->data === null || $reload) { + $this->db = $this->config['dir'] . DIRECTORY_SEPARATOR . $this->config['name']; + if (!file_exists($this->db)) { + $templateFile = $this->config['template']; + if (file_exists($templateFile)) { + copy($templateFile, $this->db); + } else { + file_put_contents($this->db, '{}'); + } + } else { + if ($this->config['backup']) { + try { + //todo make backup of database + } catch (\Exception $e) { + + } + } + } + $this->data = json_decode(file_get_contents($this->db), true); + if (!$this->data === null) { + throw new \InvalidArgumentException('Database file ' . $this->db + . ' contains invalid json object. Please validate or remove file'); + } + } + return $this->data; + } + + /** + * Сохранение в локальную базу + */ + public function save() { + file_put_contents($this->db, json_encode($this->data, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT)); + } + + +}