From 94e65e92aaa68dd511027d9369fba30470b37929 Mon Sep 17 00:00:00 2001 From: fredtempez Date: Tue, 22 Dec 2020 22:01:10 +0100 Subject: [PATCH 1/5] verrouillage des fchiers ouverts --- CHANGES.md | 3 +++ README.md | 2 +- core/class/jsondb/JsonDb.class.php | 15 ++++++++++++--- core/core.php | 8 +++++--- 4 files changed, 21 insertions(+), 7 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 61ae9a44..2ff14c07 100755 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,8 @@ # Changelog +## Version 10.3.13 +Modification : + - Verouillage des fichiers de données ouverts en écriture. ## Version 10.3.12 Correction : diff --git a/README.md b/README.md index 557c8c18..a8d8d670 100755 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ![](https://img.shields.io/github/last-commit/fredtempez/ZwiiCMS/master) ![](https://img.shields.io/github/release-date/fredtempez/ZwiiCMS) -# ZwiiCMS 10.3.12 +# ZwiiCMS 10.3.13 Zwii est un CMS sans base de données (flat-file) qui permet de créer et gérer facilement un site web sans aucune connaissance en programmation. diff --git a/core/class/jsondb/JsonDb.class.php b/core/class/jsondb/JsonDb.class.php index 3e9ce04c..05566c29 100755 --- a/core/class/jsondb/JsonDb.class.php +++ b/core/class/jsondb/JsonDb.class.php @@ -108,8 +108,7 @@ class JsonDb extends \Prowebcraft\Dot } else { $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'); + throw new \InvalidArgumentException('Erreur de lecture du fichier de données ' . $this->db); } } } @@ -120,6 +119,16 @@ class JsonDb extends \Prowebcraft\Dot * Saving to local database */ public function save() { - file_put_contents($this->db, json_encode($this->data, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT)); + // 3 essais + for($i = 0; $i < 4; $i++) { + if(file_put_contents($this->db, json_encode($this->data, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT|LOCK_EX)) !== false) { + break; + } + // Pause de 10 millisecondes + usleep(10000); + if ($i === 4) { + throw new \InvalidArgumentException('Erreur d\'écriture du fichier de données ' . $this->db); + } + } } } diff --git a/core/core.php b/core/core.php index 25e6df47..bbb5aee1 100755 --- a/core/core.php +++ b/core/core.php @@ -40,7 +40,7 @@ class common { const ACCESS_TIMER = 1800; // Numéro de version - const ZWII_VERSION = '10.3.12'; + const ZWII_VERSION = '10.3.13'; const ZWII_UPDATE_CHANNEL = "v10"; public static $actions = []; @@ -617,7 +617,8 @@ class common { $this->setData(['theme',$tempData['theme']]); // Import des users sauvegardés si option active - if ($keepUsers === false) { + if ($keepUsers === false + AND $tempData['user'] !== NULL) { $this->setData(['user',$tempData['user']]); } @@ -1878,7 +1879,8 @@ class core extends common { } } // Accès concurrent stocke la page visitée - if ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')) { + if ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD') + AND $this->getUser('id') ) { $this->setData(['user',$this->getUser('id'),'accessUrl',$this->getUrl()]); $this->setData(['user',$this->getUser('id'),'accessTimer',time()]); } From 311deabfb4d40fef35d7e7b5ecca91630d8550e9 Mon Sep 17 00:00:00 2001 From: fredtempez Date: Tue, 22 Dec 2020 22:15:02 +0100 Subject: [PATCH 2/5] gtag anonymous --- CHANGES.md | 1 + core/core.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 2ff14c07..5aaf3506 100755 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,6 +3,7 @@ ## Version 10.3.13 Modification : - Verouillage des fichiers de données ouverts en écriture. + - Google Analytics, option d'anonymisation. ## Version 10.3.12 Correction : diff --git a/core/core.php b/core/core.php index bbb5aee1..40b50aca 100755 --- a/core/core.php +++ b/core/core.php @@ -2205,7 +2205,7 @@ class layout extends common { window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag("js", new Date()); - gtag("config","'. $code .'"); + gtag("config","'. $code .'",{ "anonymize_ip": true }); '; } } From 72e12e17c0b3d46e4c952d172bc51efb8568015d Mon Sep 17 00:00:00 2001 From: fredtempez Date: Tue, 22 Dec 2020 22:29:25 +0100 Subject: [PATCH 3/5] =?UTF-8?q?nombre=20d'essais=20en=20cas=20de=20fichier?= =?UTF-8?q?=20verrouill=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/class/jsondb/JsonDb.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/class/jsondb/JsonDb.class.php b/core/class/jsondb/JsonDb.class.php index 05566c29..1425f92f 100755 --- a/core/class/jsondb/JsonDb.class.php +++ b/core/class/jsondb/JsonDb.class.php @@ -120,13 +120,13 @@ class JsonDb extends \Prowebcraft\Dot */ public function save() { // 3 essais - for($i = 0; $i < 4; $i++) { + for($i = 0; $i <=3; $i++) { if(file_put_contents($this->db, json_encode($this->data, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT|LOCK_EX)) !== false) { break; } // Pause de 10 millisecondes usleep(10000); - if ($i === 4) { + if ($i === 3) { throw new \InvalidArgumentException('Erreur d\'écriture du fichier de données ' . $this->db); } } From 23fdca6c529030de609b828ce7b0fd7043f32743 Mon Sep 17 00:00:00 2001 From: fredtempez Date: Wed, 23 Dec 2020 17:33:57 +0100 Subject: [PATCH 4/5] gestion d'erreur par exception --- core/class/jsondb/JsonDb.class.php | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/core/class/jsondb/JsonDb.class.php b/core/class/jsondb/JsonDb.class.php index 1425f92f..2faec075 100755 --- a/core/class/jsondb/JsonDb.class.php +++ b/core/class/jsondb/JsonDb.class.php @@ -106,9 +106,17 @@ class JsonDb extends \Prowebcraft\Dot if (!file_exists($this->db)) { return null; } else { - $this->data = json_decode(file_get_contents($this->db), true); + // 3 essais + for($i = 0; $i <3; $i++) { + if ($this->data = json_decode(@file_get_contents($this->db), true) ) { + break; + } + // Pause de 10 millisecondes + usleep(10000); + } + // Gestion de l'erreur if (!$this->data === null) { - throw new \InvalidArgumentException('Erreur de lecture du fichier de données ' . $this->db); + throw new \Exception('Erreur de lecture du fichier de données ' . $this->db); } } } @@ -120,14 +128,14 @@ class JsonDb extends \Prowebcraft\Dot */ public function save() { // 3 essais - for($i = 0; $i <=3; $i++) { - if(file_put_contents($this->db, json_encode($this->data, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT|LOCK_EX)) !== false) { - break; + for($i = 0; $i <3; $i++) { + if(@file_put_contents($this->db, json_encode($this->data, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT|LOCK_EX)) !== false) { + break; } // Pause de 10 millisecondes usleep(10000); - if ($i === 3) { - throw new \InvalidArgumentException('Erreur d\'écriture du fichier de données ' . $this->db); + if ($i === 2) { + throw new \Exception('Erreur d\'écriture du fichier de données ' . $this->db ); } } } From 1fc11e26b76d457775722d1a22d8c3c97bbbb12f Mon Sep 17 00:00:00 2001 From: fredtempez Date: Fri, 25 Dec 2020 20:15:56 +0100 Subject: [PATCH 5/5] Version finale de la classe jsondb --- .gitignore | 9 ++---- CHANGES.md | 49 ++++++++++++++++-------------- core/class/jsondb/JsonDb.class.php | 39 +++++++++++++++--------- core/core.php | 45 +++++++++++---------------- 4 files changed, 70 insertions(+), 72 deletions(-) diff --git a/.gitignore b/.gitignore index 8a247dc6..d33073ef 100755 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,8 @@ site/backup/* site/data/*.json site/data/*.css site/data/fr/*.json +site/data/fr/*.back +site/data/*.back # Fichiers uploadés @@ -36,9 +38,4 @@ site/data/journal.log .DS_Store site/.DS_Store site/file/.DS_Store -site/tmp/5f7f5e998762c.png -site/tmp/5f7f5e9987628.png -site/tmp/5f7f5ea3e983b.png -site/tmp/5f7f5ea3e9837.png -site/tmp/5f7f5ea20d5eb.png -site/tmp/5f7f5ea20d5ee.png + diff --git a/CHANGES.md b/CHANGES.md index 5aaf3506..4b8eb5e3 100755 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,8 +1,11 @@ # Changelog ## Version 10.3.13 -Modification : - - Verouillage des fichiers de données ouverts en écriture. +Modifications : + - Système de données (JsonDN) : + - Verrouillage des fichiers de données ouverts en écriture. + - Message d'erreur littéral. + - Sauvegarde des fichiers de données après un effacement et une écriture. - Google Analytics, option d'anonymisation. ## Version 10.3.12 @@ -27,7 +30,7 @@ Modification : Corrections : - Configuration : persistance de l'ouverture des blocs. - Réinitialisation du mot de passe : - - Remise à zéro du timer après renouvellement du mot de passe. + - Remise à zéro du timer après renouvèlement du mot de passe. - Affichage de le fenêtre "Nouveau mot de passe" allégée. - Redirection sur la page d'accueil. - Modules news et blog : transparence icône RSS. @@ -44,7 +47,7 @@ Corrections : ## version 10.3.06 - Correction : - - Edition de page avec module, le changement de mise en page désactive le bouton d'option du module. + - Édition de page avec module, le changement de mise en page désactive le bouton d'option du module. - Modification : - Modules News et Blog : ajout de l'option flux RSS. L'option est activée par défaut. @@ -104,7 +107,7 @@ Corrections : ## version 10.3.00 - Corrections : - - Bloquage de l'incrémentation de l'id de page lorsque deux pages ont le même nom. + - Incrémentation de l'id de page bloquée lorsque deux pages ont le même nom. - Login : l'option "Se souvenir de moi" est fonctionnelle. - Menu : déplacement de la classe "active". - Le titre dans la configuration du module non affiché si le titre de la page est masqué. @@ -121,7 +124,7 @@ Corrections : - Configuration du site : - Pages 403 (accès interdit), 404 (page introuvable) et site en maintenance personnalisables - Sauvegarde du site dans une archive : animation d'attente avec message de confirmation ou d'erreur ; le nom de l'archive prend le nom du sous-domaine s'il existe. - - Captcha : addition présentée en lettres sous la forme d'images, réponse en chiffres ; correction du nom de la fonction (capcha en captcha). + - Captcha : addition présentée en lettres sous la forme d'images, réponse en chiffres ; correction du nom de la fonction (captcha en captcha). - Page : - Duplication d'une page. - Mise à jour : @@ -160,7 +163,7 @@ Corrections : ## version 10.2.03 - Corrections : - Les entrées de menu disposent d'une classe par groupe de parent en lieu et place des ids. - - Edition du compte de l'utilisateur, empêcher le préremplissage de l'ancien mot de passe. + - Édition du compte de l'utilisateur, empêcher le pré-remplissage de l'ancien mot de passe. - Reformulation du mail de confirmation d'inscription. - Champ de sélection de fichiers, suppression de la couleur des URL lors d'un survol - Modifications : @@ -177,7 +180,7 @@ Corrections : - Optimisation et correction de l'algorithme de contrôle d'accès. - Erreur des noms de champ barre des membres dans le pied de page. - Génération de l'image tag, amélioration du code et du message d'erreur. - - Edition de page, erreur lors de la sélection d'une icône de menu. + - Édition de page, erreur lors de la sélection d'une icône de menu. - Problème lors de l'installation, impossibilité d'obtenir l'écran de configuration. ## version 10.2.00 @@ -185,11 +188,11 @@ Corrections : - jQuery v3.5.1 - Nouveautés : - Gestion des accès concurrents : - - deux utilisateurs ne peuvent accèder en modification à la même page du site ou de configuration + - deux utilisateurs ne peuvent accéder en modification à la même page du site ou de configuration - la connexion d'un utilisateur sur un autre poste ou navigateur déconnecte la session précédente. - sécurisation du login - journalisation de l'utilisation du site - - Ecran de configuration et d'édition des pages, les blocs sont pliables et dépliables afin d'alléger l'occupation sur l'écran. Le statut des blocs (fermés ; ouverts) est persistante au cours de la session. + - Écran de configuration et d'édition des pages, les blocs sont pliables et dépliables afin d'alléger l'occupation sur l'écran. Le statut des blocs (fermés ; ouverts) est persistante au cours de la session. - Modifications : - Thème, les sélecteurs de couleur affiche la valeur RGBa d'une couleur différente de celle de la sélection. - Thème de l'administration, amélioration du rendu. @@ -263,16 +266,16 @@ Corrections : - Améliorations : - Architecture de stockage des données. - Les données sont désormais stockées dans des fichiers distincts (core, config, theme, user, page et module). - - Les données relatives aux pages et aux modules sont stockées dans un dossier localisé fr par défaut en préaration de la version multilangues. + - Les données relatives aux pages et aux modules sont stockées dans un dossier localisé fr par défaut en préparation de la version multi-langues. - Gestion des données : - Le système ne conserve plus en mémoire l'intégralité des données de site comme dans les versions précédentes. - Les données du site sont chargées à la demande au lieu d'être lues dans leur intégralité. - Les mises à jour et effacements sont appliquées en direct sur le disque. - Modifications : - Module gallery optimisé, tri dynamique, choix du thème. - - Module blog présentation optimisée avec options de position de l'image, la métadescription est le contenu de l'article. + - Module blog présentation optimisée avec options de position de l'image, la méta-description est le contenu de l'article. - Chargement paresseux des images. - - Edition de page : suppression de l'option d'ouverture dans une lity. + - Édition de page : suppression de l'option d'ouverture dans une lity. - Protection des données des modules en cas de changement lors de l'édition d'une page. Corrections de bug : - Mise à jour automatique : procédure modifiée, désactivée si allow_url_fopen = off sur le serveur @@ -397,7 +400,7 @@ Corrections de bug : - L'effet de couleur de fond personnalisé d'une page sélectionnée dans le menu est limité aux pages parents. - Améliorations : - Affichage du contenu seul d'une page du site dans une popup Lity sans menu, bannière et pied de page. - - Editeur de texte ; effet accordéon, les accordéons peuvent être tous refermés. + - Éditeur de texte ; effet accordéon, les accordéons peuvent être tous refermés. - Thème ; menu : lorsque le menu est réduit, le titre du site peut être inséré à la gauche du menu burger. ## version 9.2.14 @@ -429,7 +432,7 @@ Corrections de bug : - Supprimer le forçage de l'affichage des médias à 100% - Activer le dimensionnement des médias - Module Form : - - Etiquette de séparation + - Étiquette de séparation - Checkbox retourne un astérisque plutôt que 1 - Thème - Menu : - Couleur de fond de la page sélectionnée @@ -439,7 +442,7 @@ Corrections de bug : - Corrections : - Marge du pied de page par défaut 5px - Installation sans site exemple : suppression des barres latérales - - Edition de page : + - Édition de page : - Affichage de l'option Fil d'ariane alors que le titre est masqué. - Page parente, l'option "ne pas afficher les pages enfants dans le menu horizontal" est incompatible avec une page désactivée : désactivation et masquage lorsque la page est désactivée. - Mauvais encodage des titres de pages perturbant l'affichage des caractères spéciaux ( ex: apostrophes ). @@ -469,7 +472,7 @@ Corrections de bug : ## Version 9.2.08 - Correction : - - Edition de page : bug empêchant le paramétrage d'un module après un changement de gabarit. + - Édition de page : bug empêchant le paramétrage d'un module après un changement de gabarit. - Modification : - Aide de l'édition des pages @@ -509,7 +512,7 @@ Corrections de bug : ## Version 9.2.01 - Corrections : - Sauvegarde du thème : prise en compte du fichier custom.css - - Edition de page : libellés + - Édition de page : libellés - Thème ; footer : marges du pied de page placé hors du site - Thème ; footer : aperçu du texte personnalisé @@ -575,7 +578,7 @@ Corrections de bug : - Réécriture activée après chaque mise à jour auto. - Modifications : - Thème 100% fluide sans marge - - Ecran de smartphone (ex : iPhone 6) : adaptation de la barre d'administration : le username est masqué et la taille des icônes est augmentée + - Écran de smartphone (ex : iPhone 6) : adaptation de la barre d'administration : le username est masqué et la taille des icônes est augmentée - Chemins vers les données dans des constantes - Modèles de bannières de plusieurs dimensions - Hauteur de police par défaut 13px @@ -665,7 +668,7 @@ Corrections de bug : ## Version 9.0.18 - Correction : - - Etat par défaut du numéro de version mal récupéré + - État par défaut du numéro de version mal récupéré ## Version 9.0.17 - Mises à jour : @@ -680,7 +683,7 @@ Corrections de bug : ## Version 9.0.16 - Correction : - - Nom de page constitué de caractères filtrés empchant la création d'un Id valide. + - Nom de page constitué de caractères filtrés empêchant la création d'un Id valide. - Module Gallery : bouton de fermeture sous Edge ## Version 9.0.15 @@ -705,7 +708,7 @@ Corrections de bug : ## Version 9.0.12 - Corrections : - Configuration de Tippy pour l'utilisation de l'argument title dans les balises a et img. Data-tippy-content reste un argument reconnu - - Bug de la redirection lorsqu'un dossier porte le nom d'une page, le contrôle de cohérence est déplacé dans page. + - Bug de la redirection lorsque un dossier porte le nom d'une page, le contrôle de cohérence est déplacé dans page. ## Version 9.0.11 - Corrections : @@ -755,7 +758,7 @@ Corrections de bug : - Thème : - nouvelle position du menu dans le site quand la bannière est au-dessus. - Simplification et ordre des libellés position du menu par rapport à la bannière - - Editeur de texte, scrolle lorsque l'éditeur est ouvert, la barre d'outil se colle sous la barre d'administration. + - Éditeur de texte, scrolle lorsque l'éditeur est ouvert, la barre d'outil se colle sous la barre d'administration. - TinyMCE : - liste des pages du site dans la fenêtre des liens - option lightbox pour l'affichage d'images ou de liens diff --git a/core/class/jsondb/JsonDb.class.php b/core/class/jsondb/JsonDb.class.php index 2faec075..35ec9608 100755 --- a/core/class/jsondb/JsonDb.class.php +++ b/core/class/jsondb/JsonDb.class.php @@ -22,10 +22,10 @@ class JsonDb extends \Prowebcraft\Dot public function __construct($config = []) { $this->config = array_merge([ - 'name' => 'data.json', - 'backup' => 5, - 'dir' => getcwd(), - 'template' => getcwd() . DIRECTORY_SEPARATOR . 'data.template.json' + 'name' => 'data.json', + 'backup' => false, + 'dir' => getcwd() + //'template' => getcwd() . DIRECTORY_SEPARATOR . 'data.template.json' ], $config); $this->loadData(); parent::__construct(); @@ -116,7 +116,7 @@ class JsonDb extends \Prowebcraft\Dot } // Gestion de l'erreur if (!$this->data === null) { - throw new \Exception('Erreur de lecture du fichier de données ' . $this->db); + exit ('JsonDB : Erreur de lecture du fichier de données ' . $this->db .'. Aucune donnée lisible, essayez dans quelques instants ou vérifiez le système de fichiers.'); } } } @@ -127,16 +127,25 @@ class JsonDb extends \Prowebcraft\Dot * Saving to local database */ public function save() { - // 3 essais - for($i = 0; $i <3; $i++) { - if(@file_put_contents($this->db, json_encode($this->data, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT|LOCK_EX)) !== false) { - break; - } - // Pause de 10 millisecondes - usleep(10000); - if ($i === 2) { - throw new \Exception('Erreur d\'écriture du fichier de données ' . $this->db ); + // Backup file + if ($this->config['backup']) { + copy ($this->db, $this->db . '.back'); + } + if ( is_writable($this->db) ) { + // 3 essais + for($i = 0; $i < 3; $i++) { + if( @file_put_contents($this->db, json_encode($this->data, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT|LOCK_EX)) !== false) { + break; + } + // Pause de 10 millisecondes + usleep(10000); + } - } + if ($i === 2) { + exit ('Jsondb : Erreur d\'écriture dans le fichier de données ' . $this->db . '. Vérifiez le système de fichiers.' ); + } + } else { + exit ('Jsondb : Écriture interdite dans le fichier de données ' . $this->db .'. Vérifiez les permissions.' ); + } } } diff --git a/core/core.php b/core/core.php index 40b50aca..b7098275 100755 --- a/core/core.php +++ b/core/core.php @@ -325,36 +325,30 @@ class common { // Constructeur JsonDB $db = new \Prowebcraft\JsonDb([ 'name' => $keys[0] . '.json', - 'dir' => $folder + 'dir' => $folder, + 'backup' => true ]); switch(count($keys)) { case 1: - $db->delete($keys[0]); - $db->save(); + $db->delete($keys[0], true); break; case 2: - $db->delete($keys[0].'.'.$keys[1]); - $db->save(); + $db->delete($keys[0].'.'.$keys[1],true); break; case 3: - $db->delete($keys[0].'.'.$keys[1].'.'.$keys[2]); - $db->save(); + $db->delete($keys[0].'.'.$keys[1].'.'.$keys[2], true); break; case 4: - $db->delete($keys[0].'.'.$keys[1].'.'.$keys[2].'.'.$keys[3]); - $db->save(); + $db->delete($keys[0].'.'.$keys[1].'.'.$keys[2].'.'.$keys[3], true); break; case 5: - $db->delete($keys[0].'.'.$keys[1].'.'.$keys[2].'.'.$keys[3].'.'.$keys[4]); - $db->save(); + $db->delete($keys[0].'.'.$keys[1].'.'.$keys[2].'.'.$keys[3].'.'.$keys[4], true); break; case 6: - $db->delete($keys[0].'.'.$keys[1].'.'.$keys[2].'.'.$keys[3].'.'.$keys[4].'.'.$keys[5]); - $db->save(); + $db->delete($keys[0].'.'.$keys[1].'.'.$keys[2].'.'.$keys[3].'.'.$keys[4].'.'.$keys[5], true); break; case 7: - $db->delete($keys[0].'.'.$keys[1].'.'.$keys[2].'.'.$keys[3].'.'.$keys[4].'.'.$keys[5].'.'.$keys[6]); - $db->save(); + $db->delete($keys[0].'.'.$keys[1].'.'.$keys[2].'.'.$keys[3].'.'.$keys[4].'.'.$keys[5].'.'.$keys[6], true); break; } } @@ -966,33 +960,28 @@ class common { // Constructeur JsonDB $db = new \Prowebcraft\JsonDb([ 'name' => $keys[0] . '.json', - 'dir' => $folder + 'dir' => $folder, + 'backup' => true ]); switch(count($keys)) { case 2: - $db->set($keys[0],$keys[1]); - $db->save(); + $db->set($keys[0],$keys[1], true); break; case 3: - $db->set($keys[0].'.'.$keys[1],$keys[2]); - $db->save(); + $db->set($keys[0].'.'.$keys[1],$keys[2], true); break; case 4: - $db->set($keys[0].'.'.$keys[1].'.'.$keys[2],$keys[3]); - $db->save(); + $db->set($keys[0].'.'.$keys[1].'.'.$keys[2],$keys[3], true); break; case 5: - $db->set($keys[0].'.'.$keys[1].'.'.$keys[2].'.'.$keys[3],$keys[4]); - $db->save(); + $db->set($keys[0].'.'.$keys[1].'.'.$keys[2].'.'.$keys[3],$keys[4], true); break; case 6: - $db->set($keys[0].'.'.$keys[1].'.'.$keys[2].'.'.$keys[3].'.'.$keys[4],$keys[5]); - $db->save(); + $db->set($keys[0].'.'.$keys[1].'.'.$keys[2].'.'.$keys[3].'.'.$keys[4],$keys[5], true); break; case 7: - $db->set($keys[0].'.'.$keys[1].'.'.$keys[2].'.'.$keys[3].'.'.$keys[4].'.'.$keys[5],$keys[6]); - $db->save(); + $db->set($keys[0].'.'.$keys[1].'.'.$keys[2].'.'.$keys[3].'.'.$keys[4].'.'.$keys[5],$keys[6], true); break; } return true;