From 77c930d737726429edbdd831df2231d9bbee87df Mon Sep 17 00:00:00 2001 From: Fred Tempez Date: Sun, 24 May 2020 19:59:21 +0200 Subject: [PATCH] =?UTF-8?q?10.2=20acc=C3=A8s=20concurrents=20WIP?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGES.md | 291 +++++++++++++------------ core/core.php | 443 ++++++++++++++++++++------------------ core/module/user/user.php | 2 + 3 files changed, 389 insertions(+), 347 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 5d6ba90c..a3c3bba3 100755 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,14 +1,23 @@ # Changelog +## version 10.2.000 +- Nouveautés : + - Gestion des accès concurrents : + - 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. +- 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. + ## version 10.1.000 -- Nouveautés : +- Nouveautés : - Distinction entre le thème du site et celui de l'administration. Sauvegarde et restauration de l'un ou de l'autre. - - Thème du site : + - Thème du site : - Amélioration de l'aperçu du thème du site et de body. - Couleur de l'encadrement et la bordure des blocs. - Couleur du texte de la page active - Menu : les entrées de menu disposent d'un id afin de faciliter la personnalisation CSS -- Corrections : +- Corrections : - Configuration SMTP : sur-cryptage du mot de passe. - Warning dans la génération du sitemap en l'absence d'article. - Quelques corrections liées à l'hébergeur Free. @@ -17,20 +26,20 @@ - Modifications : - Optimisation des opérations de disque, mise en cache en lecture des données de pages. Aucun cache en écriture. - Compatibilité des URL avec Microsoft IIS (c) -- Mise à jour : +- Mise à jour : - TinyMCE 4.9.10 ## version 10.0.092 - Nouveautés : - Compatibilité avec l'hébergeur free.fr - - Configuration : + - Configuration : - Options de réglage d'un serveur SMTP pour l'envoi des emails. - Édition des scripts pour head et body dans une fenêtre dédiée. - Thème : - Thème des boutons des pages d'administration. -- Modification : +- Modification : - Masque de configuration : changement de libellés. -- Scripts externes: +- Scripts externes: - Suppression du script fullPage.js - Ajout de l'extension SMTP de PHPMailer @@ -57,7 +66,7 @@ Corrections de bug : - Mise à jour automatique : procédure modifiée, désactivée si allow_url_fopen = off sur le serveur ## version 9.2.28 -- Corrections : +- Corrections : - Mise à jour auto fonctionnelle - Décalage du thème hors de l'écran @@ -66,7 +75,7 @@ Corrections de bug : - Pages d'administration, thème spécifique - Thème inactif lorsque la réécriture est activée. - Couleur du texte des boutons gris dans l'interface d'administration. - - TinyMCE : + - TinyMCE : - La taille de la police et la couleur sont celles définies dans le thème du site. - Zone d'édition, padding de 5 px à gauche et à droite. - Barre, sélecteur de page : couleur et taille fixe de la police. @@ -79,43 +88,43 @@ Corrections de bug : - TinymCE : Menu sticky + options de barre d'outils ## version 9.2.25 -- Corrections : +- Corrections : - Décalage du site dans SimpleLightbox. - Zindex du pied de page en position fixe, sous la barre de consentement aux cookies. -- Modifications : +- Modifications : - Désactivation de l'application du thème dans les pages d'administration. Création d'un aperçu dans Thème Site. - Optimisation configuration simpleLightBox. - Syntaxe colorée dans TinyMCE Codemirror. - Configuration barre d'outils et menu. - - Module news : déplacement des styles dans common.css. Couleur de police de la signature dans custom.css- - + - Module news : déplacement des styles dans common.css. Couleur de police de la signature dans custom.css- + ## version 9.2.24 -- Corrections : +- Corrections : - Mauvaise configuration de SimpleLightBox - Thème : marges du menu en position en-dehors du site ## version 9.2.23 -- Nouveautés : +- Nouveautés : - Configuration du réseau : proxy http ou tcp sans authentification. - Menu burger remplacé pour une croix quand ouvert. -- Corrections : +- Corrections : - Fonction magic_quotes dépréciée supprimée. - Mise à jour en ligne : - problème lors du stockage de décompte de la date de dernière vérification. - réinitialisation du décompte de vérification lors de l'activation de l'option. - - Thème, Menu : + - Thème, Menu : - Problème avec le menu fixe en-dehors du site et la barre d'outils de TinyMCE sous le menu. Solution, en édition de page l'option de menu fixe est temporairement désactivée. - Alignement avec le contenu du menu dans le site incorrecte. - Disparition de la position et de l'alignement du menu. -- Modifications : +- Modifications : - TinyMCE : libellé des fonctions "Afficher dans" - TinyMCE : nouvelle organisation de la barre d'outils. - Module Form : option permettant d'ajouter le premier mail dans le formulaire au message de notification (Reply To) afin de répondre directement au message. - - Configuration du site : + - Configuration du site : - bouton affichant le numéro de la version en ligne. - uniformisation de la position des champs de saisie. - - Galerie : position du champ de tri des images. -- Mise à jour : + - Galerie : position du champ de tri des images. +- Mise à jour : - SimpleLightBox passe en version 2.1.2 ## version 9.2.22 @@ -123,9 +132,9 @@ Corrections de bug : - Aperçu de la police dans les sélecteurs. - Gestion du canal de mise à jour selon la version installée - Module Blog : position des boutons d'édition de l'article au-dessus des commentaires. - - Module Gallery : + - Module Gallery : - choix de la vignette d'album - - Ordres de tri des images d'une galerie, ascendant, descendant ou sans + - Ordres de tri des images d'une galerie, ascendant, descendant ou sans - Tri, ordre naturel de la galerie et des images de la galerie - Mises à jour : - Configurations Code Mirror pour TinyMCE et standalone @@ -133,11 +142,11 @@ Corrections de bug : ## version 9.2.21 - Correction : - Footer / Texte personnalisé : suppression des sauts de ligne et de paragraphe. -- Modification : +- Modification : - Thème / Body, couleurs de l'icône retour en haut de page perso personnalisables. ## version 9.2.20 -- Corrections : +- Corrections : - Footer / Texte personnalisé : problème d'alignement des colonnes - Variable non déclarée dans main.php provoquant un warning @@ -150,7 +159,7 @@ Corrections de bug : - Corrections : - Conformité balise p dans span (footer). - Petites corrections. -- Modifications : +- Modifications : - Installation par défaut : livraison d'une page de mentions légales. - Image du fond (body), options responsive cover et contain. - Réseaux sociaux, icône Youtube chaîne ou utilisateur. @@ -166,7 +175,7 @@ Corrections de bug : - Sauvegarde manuelle des données de site (dossiers file et data). - Modification : - Stocke la réécriture d'url dans baseUrl en cas de changement d'arborescence lors d'un transfert de site. -- Correction : +- Correction : - Problème lors de la mise à jour de la variable dataVersion. ## version 9.2.15 @@ -174,7 +183,7 @@ Corrections de bug : - Sauvegarde des données de site. - Couleur du titre de site dans le menu réduit. - L'effet de couleur de fond personnalisé d'une page sélectionnée dans le menu est limité aux pages parents. -- Améliorations : +- 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. - Thème ; menu : lorsque le menu est réduit, le titre du site peut être inséré à la gauche du menu burger. @@ -183,25 +192,25 @@ Corrections de bug : - Mise à jour : - Script d'upload du gestionnaire de fichiers - Modifications : - - Thème : optimisation des masques de saisie pour le site en largeur 750px. -- Corrections : - - Thème : gestion d'erreur lors de l'import d'un thème issu d'une version inférieure. + - Thème : optimisation des masques de saisie pour le site en largeur 750px. +- Corrections : + - Thème : gestion d'erreur lors de l'import d'un thème issu d'une version inférieure. ## version 9.2.13 - Corrections : - Gestionnaire de fichiers, modifications des paramètres des miniatures. - Filtrage du nom des pages dans la fenêtre d'édition des pages. - Format de date dans le module Blog - - Module Form : + - Module Form : - correction des options de champ pour le type étiquette -- Modifications : +- Modifications : - Suppression d'options inutiles dans l'édition d'une page de type de barre latérale. - - Module Form : - - édition : champs d’options condensés - - édition : ordre des champs dans le sélecteur - + - Module Form : + - édition : champs d’options condensés + - édition : ordre des champs dans le sélecteur + ## version 9.2.12 -- Modifications +- Modifications - TinyMCE : - Ajout d'un template effet accordéon. - Supprimer le filtrage des éléments. @@ -215,30 +224,30 @@ Corrections de bug : - Effet bord arrondi, page sélectionnée ## version 9.2.11 -- Corrections : +- Corrections : - Marge du pied de page par défaut 5px - Installation sans site exemple : suppression des barres latérales - - Edition de page : + - Edition 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 ). -- Modifications : +- Modifications : - Recherche d'une mise à jour en ligne, s'effectue une fois par jour et devient optionnelle. - Amélioration de l'écran d'édition des pages. - iframe responsive ## version 9.2.10 -- Modifications préparatoires à la version 10 : +- Modifications préparatoires à la version 10 : - Lors de l'installation, stockage de l'url de base dans l'éventualité de la restauration d'un backup et de son installation dans une autre arborescence. - Modification des clés identifiant les légendes du module Gallery : suppression du point de séparation du nom de fichier de l'extension. - Modifications : - Thème, bannière : nouvelle option de hauteur calculée à partir de la dimension de l'image sélectionnée. - Thème, bannière : informations sur l'image sélectionnée (largeur et hauteur). - Thème, pied de page : réactivation de l'aperçu. -- Corrections : - - Thème, bannière : problème empêchant la bannière d'être cliquable lorsque la hauteur "responsive" de la bannière était sélectionnée. +- Corrections : + - Thème, bannière : problème empêchant la bannière d'être cliquable lorsque la hauteur "responsive" de la bannière était sélectionnée. - Responsive File manager : erreur empêchant l'extraction d'une archive ZIP. -- Mise à jour : +- Mise à jour : - CodeMirror 5.49.2 et modification des modules installés ## version 9.2.09 @@ -249,33 +258,33 @@ 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. -- Modification : +- Modification : - Aide de l'édition des pages - + ## Version 9.2.07 -- Modification : +- Modification : - Balise responsive - Placement possible de tous les modules - Commande de placement libre des modules et du menu latéral [MENU] et [MODULE] ## Version 9.2.06 -- Correction : +- Correction : - Validation html - - Syntaxe du fichier robots.txt + - Syntaxe du fichier robots.txt ## Version 9.2.05 - Correction : - Suppression totale de Swiper (dossier source et template Tinymce) ## Version 9.2.04 -- Correction : +- Correction : - Conserver htaccess dans le dossier temp lors du nettoyage -- Suppression : +- Suppression : - Swiper ## Version 9.2.03 - Corrections : - - Menu fixe en dehors du site : + - Menu fixe en dehors du site : - overlay du sous-menu activé au-dessus de la page - impossibilité de sélectionner un élément sous un sous-menu - Modules : les modes de gestion s'affichent en pleine page - réécriture du code. @@ -286,7 +295,7 @@ Corrections de bug : - Gestion d'erreur lors de l'installation automatisée d'une mise à jour ## Version 9.2.01 -- Corrections : +- Corrections : - Sauvegarde du thème : prise en compte du fichier custom.css - Edition de page : libellés - Thème ; footer : marges du pied de page placé hors du site @@ -306,31 +315,31 @@ Corrections de bug : - Correction : - Menu : alignement avec le contenu, couleur de l'arrière-plan -## Version 9.1.14 +## Version 9.1.14 - Correction : - Validation w3C : espace manquant ## Version 9.1.13 -- Corrections : +- Corrections : - Erreur du sitemap.xml lorsqu'un blog ne contient pas d'article. - OpenGraph : erreur lors de la suppression de l'imagette si absente. ## Version 9.1.12 -- Amélioration : +- Amélioration : - Contrôle d'erreur dans la gestion de l'imagette OpenGraph -- Correction : +- Correction : - Sitemap.xml : prendre en compte les sous-pages d'une page parente masquée ## Version 9.1.11 -- Correction : +- Correction : - Générateur de sitemap.xml, correction de syntaxe. ## Version 9.1.10 -- Améliorations : +- Améliorations : - Page sitemap et sitemap.xml : les articles de blog avec le statut brouillon sont masqués. - Sitemap.xml : ajout de la date de publication des articles. - Réseau social : Github. -- Correction : +- Correction : - Suppression du ? dans les URLs vers les fichiers sitemap de robots.txt ## Version 9.1.09 @@ -343,56 +352,56 @@ Corrections de bug : - Prends en compte les articles de blog - Affiche les pages désactivées sans lien - Prends en compte les droits de l'utilisateur -- Corrections : +- Corrections : - Déclaration de localisation manquante dans mail.php - Bug avec le formulaire - - Désactivation url upload dans RFM + - Désactivation url upload dans RFM ## Version 9.1.08 -- Corrections : +- Corrections : - Validation du code html et du CSS commun - Réécriture activée après chaque mise à jour auto. -- Modifications : +- 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 - Chemins vers les données dans des constantes - Modèles de bannières de plusieurs dimensions - Hauteur de police par défaut 13px -- Mises à jour : +- Mises à jour : - TinyMCE 4.9.4 - PHPMailer 6.07 - Jquery 3.4.1 ## Version 9.1.07 -- Correction : +- Correction : - Ajout d'un utilisateur : autres contrôles avant envoi d'un mail de confirmation - Suppression : - Include de script.inc.php et head.inc.html dans main.php ## Version 9.1.06 -- Corrections : +- Corrections : - Ajout d'un utilisateur : pas d'envoi du mail de confirmation si les mots de passe ne sont pas identiques. - Mise à jour automatique : effacement des archives téléchargées - Z-index des sous-menus augmentés à 8 ; problème d'affichage avec codemirror -- Modification : +- Modification : - Include de script.inc.php et head.inc.html dans main.php ## Version 9.1.05 -- Correction : +- Correction : - Site par défaut : lien Zwii masqué du menu horizontal -- Modifications : +- Modifications : - Présentation de l'édition des pages - - Largeur dynamique du bouton envoyer dans le formulaire + - Largeur dynamique du bouton envoyer dans le formulaire - Lien dans le footer vers le site Zwii - Redirection, écran de confirmation ## Version 9.1.04 -- Corrections : +- Corrections : - Edition de page : problème mise en page - Module Form (v1.9) : position et largeur des boutons - Thème Pied de page : problème d'affichage - Thème Site : boutons tronqués en 750px : 750px = 0.8em -- Modification : +- Modification : - Aperçu de la bannière en mode responsive ## Version 9.1.03 @@ -406,12 +415,12 @@ Corrections de bug : - Suppression Include ## Version 9.1.01 -- Modifications : +- Modifications : - Amélioration de l'algorithme de gestion des barres - Script Google Analytics - Menu : effet de surimpression pages filles - Réorganisation de l'écran d'édition des pages - - Blog : notification hiérarchique lors de la rédaction d'un commentaire + - Blog : notification hiérarchique lors de la rédaction d'un commentaire - Form : notification hiérarchique de la réception d'un message - Thème header : hauteur proportionnelle de la bannière (responsive) - Ajouts : @@ -421,60 +430,60 @@ Corrections de bug : - Option de masquage des pages enfants dans le menu principal - Petits écrans, ordre des blocs : Page - Barre Gauche - Barre Droite - Intégration de la classe Swiper http://idangero.us/swiper/ - - Intégration de l'URL canonical + - Intégration de l'URL canonical - Icône de suppression des pages dans la barre d'administration - Gestion du sitemap.xml et du robots.txt - Corrections : - Form : option de redirection ## Version 9.0.21 -- Mise à jour : +- Mise à jour : - Code Mirror v5.46 -- Corrections : +- Corrections : - Liens de l'éditeur de page : impossibilité de sélectionner un lien vers une page parente - Export des données du site, problème lors de la création de l'arborescence. ## Version 9.0.20 -- Correction : +- Correction : - Footer : Taille de la police du numéro de version ## Version 9.0.19 -- Correction : - - Alignement du menu - +- Correction : + - Alignement du menu + ## Version 9.0.18 -- Correction : - - Etat par défaut du numéro de version mal récupéré +- Correction : + - Etat par défaut du numéro de version mal récupéré ## Version 9.0.17 - Mises à jour : - simpleLightBox 1.17.0 -- Correction : +- Correction : - Marges pour les petits écrans en mode connecté - Ajustement CSS du pied de page - - Harmonisation du contenu des bulles d'aide -- Modifications : + - Harmonisation du contenu des bulles d'aide +- Modifications : - Ajout du numéro de version dans le pied de page activable dans la configuration du thème - - Désactivation Aviary dans Responsive FileManager + - Désactivation Aviary dans Responsive FileManager ## Version 9.0.16 -- Correction : +- Correction : - Nom de page constitué de caractères filtrés empchant la création d'un Id valide. - Module Gallery : bouton de fermeture sous Edge ## Version 9.0.15 -- Corrections : +- Corrections : - Débordement dans le pied de page quand le copyright est à droite -- Modifications : +- Modifications : - Petits écrans, menu d'administration icônes plus grandes - - Masquage de l'icône de gestion du compte + - Masquage de l'icône de gestion du compte ## Version 9.0.14 -- Corrections : +- Corrections : - Débordement dans le pied de page quand le copyright est à droite -- Modifications : +- Modifications : - Petits écrans, menu d'administration plus icônes plus grandes - - Masquage de l'icône de gestion du compte + - Masquage de l'icône de gestion du compte ## Version 9.0.13 - Modifications : @@ -516,7 +525,7 @@ Corrections de bug : - Blog 1.3 : image en tête d'article correctement affichée avec effet responsive. - TinyMCE : taille des miniatures générées par défaut 480 x 320 en vue d'un affichage correct dans le module blog - Pied de page : correction d'un problème d'affichage sur des écrans inférieurs à 992px - + ## Version 9.0.07 - Correction : - Disparition du menu quand la bannière est masquée @@ -526,12 +535,12 @@ Corrections de bug : ## Version 9.0.06 - Correction : - Configuration des modes de codemirror -- Modifications : +- Modifications : - TinyMCE : libellés fenêtre des liens ## Version 9.0.05 - Modifications : - - Thème : + - 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. @@ -541,8 +550,8 @@ Corrections de bug : usages : https://sorgalla.com/lity/ ## Version 9.0.04 -- Corrections : - - Module form 1.6 : +- Corrections : + - Module form 1.6 : - erreur lors de la non sélection d'un groupe - captcha inefficace - Pour les testeurs : la mise à jour automatique n'est plus proposée lors d'une régression, lorsque le numéro de version en ligne est inférieur à celui de la version installée. @@ -550,7 +559,7 @@ Corrections de bug : - Redimensionnement des images map : permet d'obtenir des images map fonctionnelles lorsque les dimensions de l'image sont réduites par le thème ou la taille de l'écran. - La carte peut être générée par https://www.image-map.net/ - Article (en) : https://blog.travismclarke.com/project/imagemap/ - - Git : https://github.com/clarketm/image-map + - Git : https://github.com/clarketm/image-map ## Version 9.0.03 @@ -565,12 +574,12 @@ Corrections de bug : ## Version 9.0.01 -- Modifications : +- Modifications : - Abandon de l'envoi masqué des mails du formulaire - Effacement Google+ des réseaux sociaux - Rétablissement du background du header - Opération sur un mauvais type affichant une notice -- Correction : +- Correction : - La bannière hors site cliquable replacée dans le header - Hauteur du footer hors site non appliquée @@ -585,8 +594,8 @@ Corrections de bug : - Nouvelle option de position fixe du menu type Facebook lorsque le menu et en haut de page et hors du site - Nettoyage des images effacées - Gabarits de pages : deux barres latérales, une à droite ou à gauche contenant des informations fixes. - - Libellé Modérateur devient Editeur - - Editeur de texte : + - Libellé Modérateur devient Editeur + - Editeur de texte : - VisualBlocks dans TinyMCE - CodeMirror dans TinyMCE - Affichage de la version proposée dans la popup de mise à jour @@ -594,17 +603,17 @@ Corrections de bug : - Case à cocher dans les formulaires - Bouton d'export au format CSV - Bouton effacer toutes les données - - Notification d'un membre ou email libre + - Notification d'un membre ou email libre - Edition de page : - masquage des options inutiles selon le module - nouvelle option : fil d'ariane des pages filles - Barre d'administration fixe -Correctif : +Correctif : - amélioration contre mesure CSRF - Erreur dans la procédure d'update suite à un ancien numéro de versions sur 4 digits -Mise à jour : +Mise à jour : - TinyColoPicker - PhpMailer 6.0.6 - Responsive FileManager version 9.14.0 @@ -616,37 +625,37 @@ Mise à jour : * Correction : - Module Form : faille CSRF gestion data - Problème empêchant la suppression d'une galerie -* Modification : +* Modification : - Module Form : Bouton tout effacer - + ## Version 8.5.8 * Correction : - Erreur dans la procédure d'update suite à un ancien numéro de versions sur 4 digits ## Version 8.5.7 -* Correction : +* Correction : - Message d'erreur ecran modification du compte ## Version 8.5.6 -* Correction : +* Correction : - Destruction de la session au logout - Thème : aperçu de la modification de la barre de menu au-dessus du site -* Modification : +* Modification : - Mise à jour RFM 9.14 - Amélioration de la contre mesure CRSF - Libellé dans TinyMCE (gabarit) - - Setlocal modification des paramètres FR + - Setlocal modification des paramètres FR ## Version 8.5.5 -* Correction : +* Correction : - Faille CSRF lors de l'effacement d'un membre - Faille CSRF lors de l'effacement d'une galerie - - Faille CSRF lors de l'effacement d'un article de blog + - Faille CSRF lors de l'effacement d'un article de blog - Faille CSRF lors de l'effacement d'un article de news - Taille de la police dans le footer impossible à modifier ## Version 8.5.4 -* Correction : +* Correction : - Faille CSRF lors de l'effacement d'une page ## Verison 8.5.3 @@ -660,40 +669,40 @@ Mise à jour : - Bloc des colonnes dans et hors site : - \#footersiteLeft, \#footerbodyLef - \#footersiteCenter, \#footerbodyCenter - - \#footersiteRight, \#footerbodyRight + - \#footersiteRight, \#footerbodyRight ## Version 8.5.2 -* Correction : +* Correction : - Thème menu : aperçu quand le menu est au-dessus et en-dehors du site - + ## Version 8.5.1 * Correction : - Nom de variable incorrect ## Version 8.5.0 -* Correction : +* Correction : - Suppression popup active par défaut dans le menu - Suppression option de titre de page dans le menu Icone + Texte -* Modification : +* Modification : - Thème du menu : sélection de la police de caractère ## Version 8.4.9 * Correction : - Adresse d'une page inactive -* Modification : +* Modification : - Blog : masquer une image dans l'article tout en conservant la miniature dans l'index -## version 8.4.8 -* Correction : +## version 8.4.8 +* Correction : - Fautes de frappe ## Version 8.4.7 * correction : - - Chaine de mise à jour des variables internes + - Chaine de mise à jour des variables internes ## Version 8.4.6 -* corrections : +* corrections : - Encodage des dates dans la liste des articles news et blog - Variable itemsperPage stockée dans le mauvais type @@ -704,11 +713,11 @@ Mise à jour : - Inversion de deux balises dans Socials ## Version 8.4.4 -* Correction : - - Valeur par défaut et d'update des éléments du footer dans les blocks +* Correction : + - Valeur par défaut et d'update des éléments du footer dans les blocks ## Version 8.4.3 -* Correction : +* Correction : - URL incorrecte dans Metaimage - Erreur dans la génération du sitemap - Taille du texte de la bannnière maximale relative (vmax) @@ -732,39 +741,39 @@ Mise à jour : - Position des modules Galerie et Form dans une page ; haut ; bas ou libre avec les doubles crochets insérés dans l'article [] - Prise en compte des balises OpenGraph obligatoires title , description, type et images - Modification de la position des boutons retour et éditer lors de l'affichage d'un article si connecté - - Mise en forme de la composition des articles et des news + - Mise en forme de la composition des articles et des news - Suppression du message de l'édition des redirections -* Corrections : +* Corrections : - Accès aux pages désactivées par le sitemap - Réduction du temps d'affichage des notifications - Image responsive en en-tête de l'article d'un blog - Mise à jour du gestionnaire de fichiers en version 9.13.1 ## version 8.3.13 : -* Modifications : +* Modifications : - Bannière "responsive", nouvelles options de positionnement - Bouton Edit dans Blog - Options de position des menus selon la position de la bannière - Bouton Edition dans un article du blog - Balise ALT dans les images du menu - Correction RFM - + ## version 8.3.12 : -* Modification : +* Modification : - bouton de retour dans la page d'un article de blog * Correction : - - miniatures des exemples + - miniatures des exemples ## version 8.3.11 : -* Modifications : +* Modifications : - Thème : menu et sous menu sous forme de texte ou d'image (avec ou sans bulle) - Thème : nouvelle option permettant de cliquer sur la bannière afin de revenir à la racine du site - Thème : le menu peut être positionné en haut et hors de site sur la largeur de l'écran - - Page : nouvelle option permettant désactiver une page dans le menu. Cette option permet soit de mettre une page en maintenance tout en la laissant active dans le menu, soit de créer une entrée de menu principal sans contenu + - Page : nouvelle option permettant désactiver une page dans le menu. Cette option permet soit de mettre une page en maintenance tout en la laissant active dans le menu, soit de créer une entrée de menu principal sans contenu - nouvelle option : la bannière devient cliquable et renvoie vers la page d'accueil - nom des dossiers des images exemples -* Corrections : +* Corrections : - bug des commentaires non déposés quand connecté - bug présent depuis au moins la version 8.1 et qui faisait boucler l'édition d'une page avec un module de redirection; Après édition, un clic sur retour ou enregistrer renvoie vers la page d'accueil en édition. - affichage d'une erreur 404 si le contenu d'une page est supprimé @@ -773,7 +782,7 @@ Mise à jour : - nouvelles icones d'exemple pour les menus ## 8.2.9 * Correction : filemanger : erreur dans la navigation du filemanager dans la sélection de la favicon -* Modification : on peut effacer le contenu d'une page sans provoquer d'erreur 404 +* Modification : on peut effacer le contenu d'une page sans provoquer d'erreur 404 ## 8.2.8 * Correction : filemanager problème de lecture d'une seule extension ## 8.2.7 diff --git a/core/core.php b/core/core.php index 33498b07..0aec7377 100755 --- a/core/core.php +++ b/core/core.php @@ -35,8 +35,8 @@ class common { const THUMBS_SEPARATOR = 'mini_'; const THUMBS_WIDTH = 640; - // Numéro de version - const ZWII_VERSION = '10.1.001.dev1'; + // Numéro de version + const ZWII_VERSION = '10.2.00.dev3'; const ZWII_UPDATE_CHANNEL = "v10"; public static $actions = []; @@ -53,12 +53,19 @@ class common { public static $dataStage = [ 'config', 'core', - 'module', + 'module', 'page', 'user', 'theme', 'admin' ]; + public static $accessList = [ + 'user', + 'theme', + 'config', + 'edit', + 'config' + ]; private $data = []; private $hierarchy = [ 'all' => [], @@ -82,7 +89,7 @@ class common { 'metaDescription' => '', 'metaTitle' => '', 'notification' => '', - 'redirect' => '', + 'redirect' => '', 'script' => '', 'showBarEditButton' => false, 'showPageContent' => false, @@ -95,7 +102,7 @@ class common { 'normalize', 'lity', 'filemanager', - 'flatpickr', + 'flatpickr', // 'tinycolorpicker', Désactivé par défaut // 'tinymce', Désactivé par défaut // 'codemirror', // Désactivé par défaut @@ -147,14 +154,14 @@ class common { $this->input['_COOKIE'] = $_COOKIE; } - // Import version 9 - if (file_exists(self::DATA_DIR . 'core.json') === true && - $this->getData(['core','dataVersion']) < 10000) { + // Import version 9 + if (file_exists(self::DATA_DIR . 'core.json') === true && + $this->getData(['core','dataVersion']) < 10000) { $keepUsers = isset($_SESSION['KEEP_USERS']) ? $_SESSION['KEEP_USERS'] : false; $this->importData($keepUsers); unset ($_SESSION['KEEP_USERS']); - // Réinstaller htaccess - copy('core/module/install/ressource/.htaccess', self::DATA_DIR . '.htaccess'); + // Réinstaller htaccess + copy('core/module/install/ressource/.htaccess', self::DATA_DIR . '.htaccess'); common::$importNotices [] = "Importation réalisée avec succès" ; //echo ''; } @@ -166,7 +173,7 @@ class common { $this->initData($stageId,'fr'); common::$coreNotices [] = $stageId ; } - } + } // Utilisateur connecté if($this->user === []) { @@ -260,7 +267,7 @@ class common { ) ); stream_context_set_default($context); - } + } } /** @@ -301,7 +308,7 @@ 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 @@ -323,7 +330,7 @@ class common { break; case 3: $db->delete($keys[0].'.'.$keys[1].'.'.$keys[2]); - $db->save(); + $db->save(); break; case 4: $db->delete($keys[0].'.'.$keys[1].'.'.$keys[2].'.'.$keys[3]); @@ -348,24 +355,24 @@ class common { /** * Récupérer une copie d'écran du site Web pour le tag image si le fichier n'existe pas * En local, copie du site décran de ZwiiCMS - */ + */ public function makeImageTag () { if (!file_exists(self::FILE_DIR.'source/screenshot.png')) - { - if ( strpos(helper::baseUrl(false),'localhost') == 0 AND strpos(helper::baseUrl(false),'127.0.0.1') == 0) { - $googlePagespeedData = helper::urlGetContents('https://www.googleapis.com/pagespeedonline/v2/runPagespeed?url='. helper::baseUrl(false) .'&screenshot=true'); + { + if ( strpos(helper::baseUrl(false),'localhost') == 0 AND strpos(helper::baseUrl(false),'127.0.0.1') == 0) { + $googlePagespeedData = helper::urlGetContents('https://www.googleapis.com/pagespeedonline/v2/runPagespeed?url='. helper::baseUrl(false) .'&screenshot=true'); if ($googlePagespeedData !== false) { $googlePagespeedData = json_decode($googlePagespeedData, true); $screenshot = $googlePagespeedData['screenshot']['data']; $screenshot = str_replace(array('_','-'),array('/','+'),$screenshot); $data = 'data:image/jpeg;base64,'.$screenshot; - $data = base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $data)); + $data = base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $data)); file_put_contents( self::FILE_DIR.'source/screenshot.png',$data); } } } } - + /** @@ -374,7 +381,7 @@ class common { * @return mixed */ public function getData($keys = []) { - + if (count($keys) >= 1) { // Lecture d'une donnée de page en cache if ($keys[0] === 'page') { @@ -406,7 +413,7 @@ class common { switch(count($keys)) { case 1: $tempData = $db->get($keys[0]); - break; + break; case 2: $tempData = $db->get($keys[0].'.'.$keys[1]); break; @@ -467,7 +474,7 @@ class common { */ public function getHierarchy($parentId = null, $onlyVisible = true, $onlyBlock = false) { $hierarchy = $onlyVisible ? $this->hierarchy['visible'] : $this->hierarchy['all']; - $hierarchy = $onlyBlock ? $this->hierarchy['bar'] : $hierarchy; + $hierarchy = $onlyBlock ? $this->hierarchy['bar'] : $hierarchy; // Enfants d'un parent if($parentId) { if(array_key_exists($parentId, $hierarchy)) { @@ -520,7 +527,7 @@ class common { // La clef est une chaine else { foreach($this->input as $type => $values) { - // Champ obligatoire + // Champ obligatoire if($required) { $this->addRequiredInputNotices($key); } @@ -619,26 +626,26 @@ class common { // Ecriture des données $this->setData(['config',$tempData['config']]); - $this->setData(['core',$tempData['core']]); + $this->setData(['core',$tempData['core']]); $this->setData(['page',$tempData['page']]); - $this->setData(['module',$tempData['module']]); + $this->setData(['module',$tempData['module']]); $this->setData(['theme',$tempData['theme']]); // Import des users sauvegardés si option active if ($keepUsers === false) { - $this->setData(['user',$tempData['user']]); + $this->setData(['user',$tempData['user']]); } // 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 @@ -648,30 +655,30 @@ class common { foreach($this->getHierarchy(null,false,false) as $parentId => $childIds) { $children = []; // Exclure les barres - if ($this->getData(['page', $parentId, 'block']) !== 'bar' ) { + if ($this->getData(['page', $parentId, 'block']) !== 'bar' ) { // Boucler sur les enfants et récupérer le tableau children avec la liste des enfants - foreach($childIds as $childId) { + foreach($childIds as $childId) { $children [] = [ 'title' => ' » '. html_entity_decode($this->getData(['page', $childId, 'title']), ENT_QUOTES) , 'value'=> $rewrite.$childId - ]; + ]; } - // Traitement - if (empty($childIds)) { + // Traitement + if (empty($childIds)) { // Pas d'enfant, uniuement l'entrée du parent $parents [] = ['title' => html_entity_decode($this->getData(['page', $parentId, 'title']), ENT_QUOTES) , - 'value'=> $rewrite.$parentId - ]; + 'value'=> $rewrite.$parentId + ]; } else { // Des enfants, on ajoute la page parent en premier array_unshift ($children , ['title' => html_entity_decode($this->getData(['page', $parentId, 'title']), ENT_QUOTES) , - 'value'=> $rewrite.$parentId - ]); + 'value'=> $rewrite.$parentId + ]); // puis on ajoute les enfants au parent $parents [] = ['title' => html_entity_decode($this->getData(['page', $parentId, 'title']), ENT_QUOTES) , - 'value'=> $rewrite.$parentId , - 'menu' => $children - ]; - } + 'value'=> $rewrite.$parentId , + 'menu' => $children + ]; + } } } // Sitemap et Search @@ -686,7 +693,7 @@ class common { 'value' => '#', 'menu' => $children ]; - + // Enregistrement : 3 tentatives for($i = 0; $i < 3; $i++) { if (file_put_contents ('core/vendor/tinymce/link_list.json', json_encode($parents), LOCK_EX) !== false) { @@ -694,7 +701,7 @@ class common { } // Pause de 10 millisecondes usleep(10000); - } + } } /** @@ -720,17 +727,17 @@ class common { */ public function createRobots() { - $robotValue = + $robotValue = PHP_EOL . '# ZWII CONFIG ---------' . PHP_EOL . 'User-agent: *' . PHP_EOL . - 'Allow: /site/file/' .PHP_EOL . + 'Allow: /site/file/' .PHP_EOL . 'Disallow: /site/' .PHP_EOL . 'Sitemap: ' . helper::baseUrl(false) . 'sitemap.xml' . PHP_EOL . 'Sitemap: ' . helper::baseUrl(false) . 'sitemap.xml.gz' . PHP_EOL . '# ZWII CONFIG ---------' . PHP_EOL ; - if (file_exists('robots.txt')) { + if (file_exists('robots.txt')) { return(file_put_contents( 'robots.txt', $robotValue, @@ -750,7 +757,7 @@ class common { * Génére un fichier un fchier sitemap.xml * https://github.com/icamys/php-sitemap-generator * $command valeurs possible - * all : génére un site map complet + * all : génére un site map complet * Sinon contient id de la page à créer */ @@ -771,14 +778,14 @@ class common { // sitemap file name $sitemap->sitemapFileName = "sitemap.xml"; - + $datetime = new DateTime(date('c')); $datetime->format(DateTime::ATOM); // Updated ISO8601 // sitemap index file name $sitemap->sitemapIndexFileName = "sitemap-index.xml"; foreach($this->getHierarchy(null, null, null) as $parentPageId => $childrenPageIds) { // Exclure les barres et les pages non publiques et les pages masquées - if ($this->getData(['page',$parentPageId,'group']) !== 0 || + if ($this->getData(['page',$parentPageId,'group']) !== 0 || $this->getData(['page', $parentPageId, 'block']) === 'bar' ) { continue; } @@ -800,32 +807,32 @@ class common { if($this->getData(['module',$childKey,$articleId,'state']) === true) { $date = $this->getData(['module',$childKey,$articleId,'publishedOn']); $sitemap->addUrl( $childKey . '/' . $articleId , new DateTime("@{$date}",new DateTimeZone($timezone))); - } + } } - } + } } // Articles du blog if ($this->getData(['page', $parentPageId, 'moduleId']) === 'blog' && - !empty($this->getData(['module',$parentPageId])) ) { + !empty($this->getData(['module',$parentPageId])) ) { foreach($this->getData(['module',$parentPageId]) as $articleId => $article) { - if($this->getData(['module',$parentPageId,$articleId,'state']) === true) { + if($this->getData(['module',$parentPageId,$articleId,'state']) === true) { $date = $this->getData(['module',$parentPageId,$articleId,'publishedOn']); $sitemap->addUrl( $parentPageId . '/' . $articleId , new DateTime("@{$date}",new DateTimeZone($timezone))); } } } - } - + } + // generating internally a sitemap $sitemap->createSitemap(); // writing early generated sitemap to file $sitemap->writeSitemap(); - + return(file_exists('sitemap.xml')); } - + /* * Création d'une miniature * Fonction utilisée lors de la mise à jour d'une version 9 à une version 10 @@ -855,13 +862,13 @@ class common { // Image valide if ($source_image) { $width = imagesx($source_image); - $height = imagesy($source_image); + $height = imagesy($source_image); /* find the "desired height" of this thumbnail, relative to the desired width */ - $desired_height = floor($height * ($desired_width / $width)); + $desired_height = floor($height * ($desired_width / $width)); /* create a new, "virtual" image */ - $virtual_image = imagecreatetruecolor($desired_width, $desired_height); + $virtual_image = imagecreatetruecolor($desired_width, $desired_height); /* copy source image at a resized size */ - imagecopyresampled($virtual_image, $source_image, 0, 0, 0, 0, $desired_width, $desired_height, $width, $height); + imagecopyresampled($virtual_image, $source_image, 0, 0, 0, 0, $desired_width, $desired_height, $width, $height); switch(mime_content_type($src) ) { case 'image/jpeg': case 'image/jpg': @@ -873,7 +880,7 @@ class common { case 'image/gif': return (imagegif($virtual_image, $dest)); break; - } + } } else { return (false); } @@ -892,20 +899,20 @@ class common { // Layout ob_start(); - include 'core/layout/mail.php'; + include 'core/layout/mail.php'; $layout = ob_get_clean(); $mail = new PHPMailer\PHPMailer\PHPMailer; - $mail->CharSet = 'UTF-8'; + $mail->CharSet = 'UTF-8'; // Mail try{ // Paramètres SMTP if ($this->getdata(['config','smtp','enable'])) { - //$mail->SMTPDebug = PHPMailer\PHPMailer\SMTP::DEBUG_SERVER; + //$mail->SMTPDebug = PHPMailer\PHPMailer\SMTP::DEBUG_SERVER; $mail->isSMTP(); $mail->SMTPAutoTLS = false; $mail->Host = $this->getdata(['config','smtp','host']); $mail->Port = (int) $this->getdata(['config','smtp','port']); - if ($this->getData(['config','smtp','auth'])) { + if ($this->getData(['config','smtp','auth'])) { $mail->Username = $this->getData(['config','smtp','username']); $mail->Password = helper::decrypt($this->getData(['config','smtp','username']),$this->getData(['config','smtp','password'])); $mail->SMTPAuth = $this->getData(['config','smtp','auth']); @@ -920,12 +927,12 @@ class common { // Fin SMTP } else { $host = str_replace('www.', '', $_SERVER['HTTP_HOST']); - $mail->setFrom('no-reply@' . $host, $this->getData(['config', 'title'])); + $mail->setFrom('no-reply@' . $host, $this->getData(['config', 'title'])); if (is_null($replyTo)) { $mail->addReplyTo('no-reply@' . $host, $this->getData(['config', 'title'])); } else { $mail->addReplyTo($replyTo); - } + } } if(is_array($to)) { foreach($to as $userMail) { @@ -962,7 +969,7 @@ class common { if (!empty(self::$inputNotices)) { return false; } - + //Retourne une chaine contenant le dossier à créer $folder = $this->dirData ($keys[0],'fr'); // Constructeur JsonDB @@ -972,14 +979,14 @@ class common { 'template' => self::TEMP_DIR . 'data.template.json' ]); - switch(count($keys)) { + switch(count($keys)) { case 2: $db->set($keys[0],$keys[1]); $db->save(); break; case 3: $db->set($keys[0].'.'.$keys[1],$keys[2]); - $db->save(); + $db->save(); break; case 4: $db->set($keys[0].'.'.$keys[1].'.'.$keys[2],$keys[3]); @@ -1003,13 +1010,13 @@ class common { /** * Initialisation des données - * @param array $module : nom du module à générer + * @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'); + require_once('core/module/install/ressource/defaultdata.php'); // Stockage dans un sous-dossier localisé // Le dossier de langue existe t-il ? @@ -1030,7 +1037,7 @@ class common { } else { $db->set($module,init::$defaultData[$module]); } - + $db->save; } @@ -1039,17 +1046,17 @@ class common { * Mises à jour */ private function update() { - + // Version 9.0.0 if($this->getData(['core', 'dataVersion']) < 9000) { $this->deleteData(['theme', 'site', 'block']); if ($this->getData(['theme','menu','position']) === 'body-top') { $this->setData(['theme','menu','position','top']); } - $this->setData(['theme', 'menu','fixed',false]); + $this->setData(['theme', 'menu','fixed',false]); $this->setData(['core', 'dataVersion', 9000]); //$this->SaveData(); - } + } // Version 9.0.01 if($this->getData(['core', 'dataVersion']) < 9001) { $this->deleteData(['config', 'social', 'googleplusId']); @@ -1061,7 +1068,7 @@ class common { $this->setData(['theme', 'footer', 'textTransform','none']); $this->setData(['theme', 'footer', 'fontWeight','normal']); $this->setData(['theme', 'footer', 'fontSize','.8em']); - $this->setData(['theme', 'footer', 'font','Open+Sans']); + $this->setData(['theme', 'footer', 'font','Open+Sans']); $this->setData(['core', 'dataVersion', 9008]); //$this->SaveData(); } @@ -1072,7 +1079,7 @@ class common { } // Version 9.0.10 if($this->getData(['core', 'dataVersion']) < 9010) { - $this->deleteData(['config', 'social', 'googleplusId']); + $this->deleteData(['config', 'social', 'googleplusId']); $this->setData(['core', 'dataVersion', 9010]); //$this->SaveData(); } @@ -1100,7 +1107,7 @@ class common { // Version 9.2.00 if($this->getData(['core', 'dataVersion']) < 9200) { $this->setData(['theme','footer','template', 3 ]); - $this->setData(['theme','footer','margin', true ]); + $this->setData(['theme','footer','margin', true ]); $this->setData(['theme','footer','displayLegal', !empty($this->getdata(['config','legalPageId'])) ]); $this->setData(['theme','footer','displaySearch', false ]); $this->setData(['config','social','githubId', '' ]); @@ -1126,14 +1133,14 @@ class common { } // Version 9.2.10 if($this->getData(['core', 'dataVersion']) < 9210) { - + // Utile pour l'installation d'un backup sur un autre serveur //$this->setData(['core', 'baseUrl', helper::baseUrl(false,false) ]); // Suppression d'une option de hauteur de la bannière if ($this->getData(['theme', 'header','height']) === 'none') { $this->setData(['theme', 'header','height','150px']); - } + } // Changer le nom de la clé linkHome -> linkHomePage $this->setdata(['theme','header','linkHomePage',$this->getData(['theme','header','linkHome'])]); $this->deleteData(['theme','header','linkHome']); @@ -1148,32 +1155,32 @@ class common { foreach ($parentValue as $childKey) { $pageList [] = $childKey; } - } + } // Parcourir toutes les pages foreach ($pageList as $parentKey => $parent) { //La page a une galerie if ($this->getData(['page',$parent,'moduleId']) === 'gallery' ) { // Lire les données du module // Parcourir les dossiers de la galerie - $tempData = $this->getData(['module', $parent]); + $tempData = $this->getData(['module', $parent]); foreach ($tempData as $galleryKey => $galleryItem) { foreach ($galleryItem as $legendKey => $legendValue) { // Recherche la clé des légendes if ($legendKey === 'legend') { - foreach ($legendValue as $itemKey=>$itemValue) { + foreach ($legendValue as $itemKey=>$itemValue) { // Ancien nom avec un point devant l'extension ? if (strpos($itemKey,'.') > 0) { // Créer une nouvelle clé $this->setData(['module', $parent, $galleryKey, 'legend',str_replace('.','',$itemKey),$itemValue]); // Supprimer la valeur $this->deleteData(['module', $parent, $galleryKey, 'legend',$itemKey]); - } + } } } } } } - } + } $this->setData(['core', 'dataVersion', 9210]); } // Version 9.2.11 @@ -1195,7 +1202,7 @@ class common { // Données de la barre de langue dans le menu $this->setData(['theme','menu','burgerTitle',true]); $this->setData(['core', 'dataVersion', 9215]); - } + } // Version 9.2.16 if($this->getData(['core', 'dataVersion']) < 9216) { // Utile pour l'installation d'un backup sur un autre serveur @@ -1210,7 +1217,7 @@ class common { $this->setData(['theme', 'body', 'toTopbackgroundColor', 'rgba(33, 34, 35, .8)' ]); $this->setData(['theme', 'body', 'toTopColor', 'rgba(255, 255, 255, 1)' ]); $this->setData(['core', 'dataVersion', 9221]); - } + } // Version 9.2.23 if($this->getData(['core', 'dataVersion']) < 9223) { // Utile pour l'installation d'un backup sur un autre serveur @@ -1219,15 +1226,15 @@ class common { $this->setData(['config', 'proxyPort', '' ]); $this->setData(['config', 'proxyType', 'tcp://' ]); $this->setData(['core', 'dataVersion', 9223]); - } + } // Version 9.2.27 if($this->getData(['core', 'dataVersion']) < 9227) { // Forcer la régénération du thème if (file_exists(self::DATA_DIR.'theme.css')) { unlink (self::DATA_DIR.'theme.css'); - } + } $this->setData(['core', 'dataVersion', 9227]); - } + } // Version 10.0.00 if($this->getData(['core', 'dataVersion']) < 10000) { $this->setData(['config', 'faviconDark','faviconDark.ico']); @@ -1240,13 +1247,13 @@ class common { foreach ($parentValue as $childKey) { $pageList [] = $childKey; } - } + } // Mise à jour des données pour la galerie v2 foreach ($pageList as $parentKey => $parent) { //La page a une galerie if ($this->getData(['page',$parent,'moduleId']) === 'gallery' ) { // Parcourir les dossiers de la galerie - $tempData = $this->getData(['module', $parent]); + $tempData = $this->getData(['module', $parent]); $i = 1; foreach ($tempData as $galleryKey => $galleryItem) { // Ordre de tri des galeries @@ -1256,7 +1263,7 @@ class common { // Position de la galerie, tri manuel if ( $this->getdata(['module',$parent,$galleryKey,'config','position']) === NULL) { $this->setdata(['module',$parent,$galleryKey,'config','position',$i++]); - } + } // Positions des images, tri manuel if ( $this->getdata(['module',$parent,$galleryKey,'positions']) === NULL) { $c = count($this->getdata(['module',$parent,$galleryKey,'legend'])); @@ -1267,22 +1274,22 @@ class common { if (is_dir($this->getdata(['module',$parent,$galleryKey,'config','directory']))) { $iterator = new DirectoryIterator($this->getdata(['module',$parent,$galleryKey,'config','directory'])); foreach($iterator as $fileInfos) { - if($fileInfos->isDot() === false AND $fileInfos->isFile() AND @getimagesize($fileInfos->getPathname())) { + if($fileInfos->isDot() === false AND $fileInfos->isFile() AND @getimagesize($fileInfos->getPathname())) { $this->setdata(['module',$parent,$galleryKey,'config','homePicture',$fileInfos->getFilename()]); break; } } } - } - } + } + } } - } + } // Contrôle des options php.ini pour la mise à jour auto if (helper::urlGetContents('http://zwiicms.com/update/' . common::ZWII_UPDATE_CHANNEL . '/version') === false) { $this->setData(['config','autoUpdate',false]); } - $this->setData(['core', 'dataVersion', 10000]); + $this->setData(['core', 'dataVersion', 10000]); } // Version 10.0.092 if ($this->getData(['core', 'dataVersion']) < 10092) { @@ -1305,9 +1312,9 @@ class common { if ($this->getData(['core', 'dataVersion']) < 10093) { // Déplacement du fichier admin.css dans data if (file_exists('core/layout/admin.css')) { - copy('core/layout/admin.css',self::DATA_DIR.'admin.css'); + copy('core/layout/admin.css',self::DATA_DIR.'admin.css'); unlink('core/layout/admin.css'); - } + } //Déplacement d'un fichier de ressources if (file_exists('core/module/config/ressource/.htaccess')) { unlink('core/module/config/ressource/.htaccess'); @@ -1340,7 +1347,7 @@ class core extends common { if($lastClearTmp > $this->getData(['core', 'lastClearTmp']) + 86400) { $iterator = new DirectoryIterator(self::TEMP_DIR); foreach($iterator as $fileInfos) { - if( $fileInfos->isFile() && + if( $fileInfos->isFile() && $fileInfos->getBasename() !== '.htaccess' && $fileInfos->getBasename() !== '.gitkeep' ) { @@ -1389,7 +1396,7 @@ class core extends common { if(file_exists(self::DATA_DIR.'admin.css') === false) { file_put_contents(self::DATA_DIR.'admin.css', ''); chmod(self::DATA_DIR.'admin.css', 0755); - } + } // Check la version rafraichissement du theme $cssVersion = preg_split('/\*+/', file_get_contents(self::DATA_DIR.'theme.css')); if(empty($cssVersion[1]) OR $cssVersion[1] !== md5(json_encode($this->getData(['theme'])))) { @@ -1416,9 +1423,9 @@ class core extends common { $css .= 'body,.block h4{color:' . $this->getData(['theme', 'text', 'textColor']) . '}'; $css .= 'select,input[type=\'email\'],input[type=\'text\'],textarea{color:' . $this->getData(['theme', 'text', 'backgroundColor']) . '}'; // Couleur fixée dans admin.css - //$css .= '.button.buttonGrey,.button.buttonGrey:hover{color:' . $this->getData(['theme', 'text', 'textColor']) . '}'; + //$css .= '.button.buttonGrey,.button.buttonGrey:hover{color:' . $this->getData(['theme', 'text', 'textColor']) . '}'; $css .= '.container{max-width:' . $this->getData(['theme', 'site', 'width']) . '}'; - $margin = $this->getData(['theme', 'site', 'margin']) ? '0' : '20px'; + $margin = $this->getData(['theme', 'site', 'margin']) ? '0' : '20px'; $css .= $this->getData(['theme', 'site', 'width']) === '100%' ? '#site{margin:0 auto !important;} body{margin:0 auto !important;} #bar{margin:0 auto !important;} body > header{margin:0 auto !important;} body > nav {margin: 0 auto !important;} body > footer {margin:0 auto !important;}': "#site{margin: " . $margin . " auto !important;} body{margin:0px 10px;} #bar{margin: 0 -10px;} body > header{margin: 0 -10px;} body > nav {margin: 0 -10px;} body > footer {margin: 0 -10px;} "; $css .= $this->getData(['theme', 'site', 'width']) === '750px' ? '.button, button{font-size:0.8em;}' : ''; $css .= '#site{background-color:' . $this->getData(['theme', 'site', 'backgroundColor']) . ';border-radius:' . $this->getData(['theme', 'site', 'radius']) . ';box-shadow:' . $this->getData(['theme', 'site', 'shadow']) . ' #212223;}'; @@ -1430,7 +1437,7 @@ class core extends common { $css .= '.speechBubble:before{border-color:' . $colors['normal'] . ' transparent transparent transparent}'; $css .= '.button:hover,button[type=\'submit\']:hover,.pagination a:hover,input[type=\'checkbox\']:not(:active):checked:hover + label:before,input[type=\'checkbox\']:active + label:before,input[type=\'radio\']:checked:hover + label:before,input[type=\'radio\']:not(:checked):active + label:before{background-color:' . $colors['darken'] . '}'; $css .= '.helpButton span:hover{color:' . $colors['darken'] . '}'; - $css .= '.button:active,button[type=\'submit\']:active,.pagination a:active{background-color:' . $colors['veryDarken'] . '}'; + $css .= '.button:active,button[type=\'submit\']:active,.pagination a:active{background-color:' . $colors['veryDarken'] . '}'; $colors = helper::colorVariants($this->getData(['theme', 'title', 'textColor'])); $css .= 'h1,h2,h3,h4,h5,h6{color:' . $colors['normal'] . ';font-family:"' . str_replace('+', ' ', $this->getData(['theme', 'title', 'font'])) . '",sans-serif;font-weight:' . $this->getData(['theme', 'title', 'fontWeight']) . ';text-transform:' . $this->getData(['theme', 'title', 'textTransform']) . '}'; // Les blocs @@ -1459,20 +1466,20 @@ class core extends common { $colors = helper::colorVariants($this->getData(['theme', 'header', 'textColor'])); $css .= 'header span{color:' . $colors['normal'] . ';font-family:"' . str_replace('+', ' ', $this->getData(['theme', 'header', 'font'])) . '",sans-serif;font-weight:' . $this->getData(['theme', 'header', 'fontWeight']) . ';font-size:' . $this->getData(['theme', 'header', 'fontSize']) . ';text-transform:' . $this->getData(['theme', 'header', 'textTransform']) . '}'; // Menu - $colors = helper::colorVariants($this->getData(['theme', 'menu', 'backgroundColor'])); + $colors = helper::colorVariants($this->getData(['theme', 'menu', 'backgroundColor'])); $css .= 'nav,nav a{background-color:' . $colors['normal'] . '}'; $css .= 'nav a,#toggle span,nav a:hover{color:' . $this->getData(['theme', 'menu', 'textColor']) . '}'; $css .= 'nav a:hover{background-color:' . $colors['darken'] . '}'; $css .= 'nav a.active{color:' . $this->getData(['theme','menu','activeTextColor']) . ';}'; if ($this->getData(['theme','menu','activeColorAuto']) === true) { - $css .= 'nav a.active{background-color:' . $colors['veryDarken'] . '}'; + $css .= 'nav a.active{background-color:' . $colors['veryDarken'] . '}'; } else { $css .= 'nav a.active{background-color:' . $this->getData(['theme','menu','activeColor']) . '}'; /*$color2 = helper::colorVariants($this->getData(['theme', 'menu', 'textColor'])); $css .= 'nav a.active{color:' . $color2['text'] . '}';*/ - } + } $css .= 'nav #burgerText{color:' . $colors['text'] . '}'; - $css .= 'nav .navLevel1 a.active {border-radius:' . $this->getData(['theme', 'menu', 'radius']) . '}'; + $css .= 'nav .navLevel1 a.active {border-radius:' . $this->getData(['theme', 'menu', 'radius']) . '}'; $css .= '#menu{text-align:' . $this->getData(['theme', 'menu', 'textAlign']) . '}'; if($this->getData(['theme', 'menu', 'margin'])) { if( @@ -1483,7 +1490,7 @@ class core extends common { } else { $css .= 'nav{padding:0 10px}'; - } + } } else { $css .= 'nav{margin:0}'; } @@ -1493,7 +1500,7 @@ class core extends common { $css .= 'nav{padding:0 10px;}'; } - $css .= '#toggle span,#menu a{padding:' . $this->getData(['theme', 'menu', 'height']) .';font-family:"' . str_replace('+', ' ', $this->getData(['theme', 'menu', 'font'])) . '",sans-serif;font-weight:' . $this->getData(['theme', 'menu', 'fontWeight']) . ';font-size:' . $this->getData(['theme', 'menu', 'fontSize']) . ';text-transform:' . $this->getData(['theme', 'menu', 'textTransform']) . '}'; + $css .= '#toggle span,#menu a{padding:' . $this->getData(['theme', 'menu', 'height']) .';font-family:"' . str_replace('+', ' ', $this->getData(['theme', 'menu', 'font'])) . '",sans-serif;font-weight:' . $this->getData(['theme', 'menu', 'fontWeight']) . ';font-size:' . $this->getData(['theme', 'menu', 'fontSize']) . ';text-transform:' . $this->getData(['theme', 'menu', 'textTransform']) . '}'; // Pied de page $colors = helper::colorVariants($this->getData(['theme', 'footer', 'backgroundColor'])); if($this->getData(['theme', 'footer', 'margin'])) { @@ -1509,7 +1516,7 @@ class core extends common { $css .= '#footerSocials{text-align:' . $this->getData(['theme', 'footer', 'socialsAlign']) . '}'; $css .= '#footerText > p {text-align:' . $this->getData(['theme', 'footer', 'textAlign']) . '}'; $css .= '#footerCopyright{text-align:' . $this->getData(['theme', 'footer', 'copyrightAlign']) . '}'; - // Marge supplémentaire lorsque le pied de page est fixe + // Marge supplémentaire lorsque le pied de page est fixe if ( $this->getData(['theme', 'footer', 'fixed']) === true && $this->getData(['theme', 'footer', 'position']) === 'body') { $css .= "@media (min-width: 769px) { #site {margin-bottom: 100px;} }"; @@ -1542,7 +1549,7 @@ class core extends common { $colors = helper::colorVariants($this->getData(['admin','backgroundColorButtonGrey'])); $css .= '.button.buttonGrey {background: ' . $colors['normal'] . ';color: ' . $this->getData(['admin','colorButtonText']) . ';}.button.buttonGrey:hover {background:' . $colors['darken'] . '}.button.buttonGrey:active {background:' . $colors['veryDarken'] . '}'; $colors = helper::colorVariants($this->getData(['admin','backgroundColorButtonRed'])); - $css .= '.button.buttonRed {background: ' . $colors['normal'] . ';color: ' . $this->getData(['admin','colorButtonText']) . ';}.button.buttonRed:hover {background:' . $colors['darken'] . '}.button.buttonRed:active {background:' . $colors['veryDarken'] . '}'; + $css .= '.button.buttonRed {background: ' . $colors['normal'] . ';color: ' . $this->getData(['admin','colorButtonText']) . ';}.button.buttonRed:hover {background:' . $colors['darken'] . '}.button.buttonRed:active {background:' . $colors['veryDarken'] . '}'; $colors = helper::colorVariants($this->getData(['admin','backgroundColorButtonGreen'])); $css .= 'button[type=submit] {background-color: ' . $colors['normal'] . ';color: ' . $this->getData(['admin','colorButtonText']) . '}button[type=submit]:hover {background-color: ' . $colors['darken'] . ';color: ' . $this->getData(['admin','colorButtonText']) .';}button[type=submit]:active {background-color: ' . $colors['darken'] . ';color: ' . $this->getData(['admin','colorButtonText']) .';}'; $colors = helper::colorVariants($this->getData(['admin','backgroundBlockColor'])); @@ -1585,10 +1592,11 @@ class core extends common { header('Location:' . helper::baseUrl() . 'install'); exit(); } - // Force la déconnexion des membres bannis + // Force la déconnexion des membres bannis ou d'une seconde session if ( $this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD') - AND $this->getUser('group') === self::GROUP_BANNED + AND ( $this->getUser('group') === self::GROUP_BANNED + OR $_SESSION['csrf'] !== $this->getData(['user',$this->getUser('id'),'accessCsrf']) ) ) { $user = new user; $user->logout(); @@ -1616,6 +1624,7 @@ class core extends common { } // Check l'accès à la page $access = null; + $accessInfo['user'] = ''; if($this->getData(['page', $this->getUrl(0)]) !== null) { if( $this->getData(['page', $this->getUrl(0), 'group']) === self::GROUP_VISITOR @@ -1635,19 +1644,34 @@ class core extends common { } } } + // Controle si la page demandée est en édition oua ccès à la gestion du site + foreach($this->getData(['user']) as $userId => $userIds){ + $t = explode('/',$this->getData(['user', $userId, 'accessUrl'])); + if ( $this->getData(['user', $userId,'accessUrl']) === $this->getUrl() && + $userId !== $this->getuser('id') && + array_intersect($t,self::$accessList) ) { + $access = false; + $accessInfo['user'] = $this->getData(['user', $userId, 'lastname']) . ' ' . $this->getData(['user', $userId, 'firstname']); + } + } + // Accès concurrent stocke la page visitée + if ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')) { + $this->setData(['user',$this->getuser('id'),'accessUrl',$this->getUrl()]); + $this->setData(['user',$this->getuser('id'),'acessTime',time()]); + } // Breadcrumb $title = $this->getData(['page', $this->getUrl(0), 'title']); if (!empty($this->getData(['page', $this->getUrl(0), 'parentPageId'])) && $this->getData(['page', $this->getUrl(0), 'breadCrumb'])) { - $title = 'getData(['page', $this->getUrl(0), 'parentPageId']) . '">' . ucfirst($this->getData(['page',$this->getData(['page', $this->getUrl(0), 'parentPageId']), 'title'])) . ' › '. - $this->getData(['page', $this->getUrl(0), 'title']); - } - + $this->getData(['page', $this->getUrl(0), 'title']); + } + // Importe la page if( $this->getData(['page', $this->getUrl(0)]) !== null @@ -1668,14 +1692,14 @@ class core extends common { } // Importe le module else { - // Id du module, et valeurs en sortie de la page si il s'agit d'un module de page + // Id du module, et valeurs en sortie de la page si il s'agit d'un module de page if($access AND $this->getData(['page', $this->getUrl(0), 'moduleId'])) { $moduleId = $this->getData(['page', $this->getUrl(0), 'moduleId']); $this->addOutput([ 'title' => $title, // Meta description = 160 premiers caractères de l'article - 'metaDescription' => $this->getData(['page',$this->getUrl(0),'moduleId']) === 'blog' && !empty($this->getUrl(1)) + 'metaDescription' => $this->getData(['page',$this->getUrl(0),'moduleId']) === 'blog' && !empty($this->getUrl(1)) ? strip_tags(substr($this->getData(['module',$this->getUrl(0),$this->getUrl(1),'content']) ,0,159)) : $this->getData(['page', $this->getUrl(0), 'metaDescription']), 'metaTitle' => $this->getData(['page', $this->getUrl(0), 'metaTitle']), @@ -1754,15 +1778,15 @@ class core extends common { if($output['redirect']) { http_response_code(301); header('Location:' . $output['redirect']); - exit(); + exit(); } - } + } // Données en sortie applicables même lorsqu'une notice est présente // Affichage - if($output['display']) { + if($output['display']) { $this->addOutput([ 'display' => $output['display'] - ]); + ]); } // Contenu brut if($output['content']) { @@ -1825,7 +1849,7 @@ class core extends common { 'vendor' => array_merge($this->output['vendor'], $output['vendor']) ]); } - if($output['title'] !== null) { + if($output['title'] !== null) { $this->addOutput([ 'title' => $output['title'] ]); @@ -1852,10 +1876,17 @@ class core extends common { } if($access === false) { http_response_code(403); - $this->addOutput([ - 'title' => 'Erreur 403', - 'content' => template::speech('Vous n\'êtes pas autorisé à accéder à cette page...') - ]); + if ($accessInfo['user']) { + $this->addOutput([ + 'title' => 'Accès verrouillé', + 'content' => template::speech('La page demandée est ouverte par l\'utilisateur ' . $accessInfo['user'] . '. Merci de patienter.') + ]); + } else { + $this->addOutput([ + 'title' => 'Erreur 403', + 'content' => template::speech('Vous n\'êtes pas autorisé à accéder à cette page...') + ]); + } } elseif($this->output['content'] === '') { http_response_code(404); @@ -1882,7 +1913,7 @@ class core extends common { 'metaDescription' => $this->getData(['config', 'metaDescription']) ]); } - + switch($this->output['display']) { // Layout vide case self::DISPLAY_LAYOUT_BLANK: @@ -1900,11 +1931,11 @@ class core extends common { // Layout principal case self::DISPLAY_LAYOUT_MAIN: require 'core/layout/main.php'; - break; + break; // Layout brut case self::DISPLAY_RAW: echo $this->output['content']; - break; + break; } } @@ -1940,7 +1971,7 @@ class layout extends common { /** * Affiche le contenu - * @param Page par défaut + * @param Page par défaut */ public function showContent() { if( @@ -1959,7 +1990,7 @@ class layout extends common { /** * Affiche le contenu de la barre gauche - * + * */ public function showBarContentLeft() { // Détermine si le menu est présent @@ -1970,13 +2001,13 @@ class layout extends common { // $mark contient 0 le menu est positionné à la fin du contenu $contentLeft = str_replace ('[]','[MENU]',$this->core->output['contentLeft']); $contentLeft = str_replace ('[menu]','[MENU]',$contentLeft); - $mark = strrpos($contentLeft,'[MENU]') !== false ? strrpos($contentLeft,'[MENU]') : strlen($contentLeft); - echo substr($contentLeft,0,$mark); + $mark = strrpos($contentLeft,'[MENU]') !== false ? strrpos($contentLeft,'[MENU]') : strlen($contentLeft); + echo substr($contentLeft,0,$mark); echo ''; - echo substr($contentLeft,$mark+6,strlen($contentLeft)); - } + echo substr($contentLeft,$mark+6,strlen($contentLeft)); + } } /** @@ -1991,13 +2022,13 @@ class layout extends common { // $mark contient 0 le menu est positionné à la fin du contenu $contentRight = str_replace ('[]','[MENU]',$this->core->output['contentRight']); $contentRight = str_replace ('[menu]','[MENU]',$contentRight); - $mark = strrpos($contentRight,'[MENU]') !== false ? strrpos($contentRight,'[MENU]') : strlen($contentRight); - echo substr($contentRight,0,$mark); + $mark = strrpos($contentRight,'[MENU]') !== false ? strrpos($contentRight,'[MENU]') : strlen($contentRight); + echo substr($contentRight,0,$mark); echo ''; - echo substr($contentRight,$mark+6,strlen($contentRight)); - } + echo substr($contentRight,$mark+6,strlen($contentRight)); + } } /** @@ -2016,18 +2047,18 @@ class layout extends common { // Ouverture Bloc copyright $items = '
'; $items .= ''; - // Affichage de motorisé par + // Affichage de motorisé par $items .= 'getData(['theme','footer','displayCopyright']) === false ? 'class="displayNone"' : ''; $items .= '>Motorisé par '; // Toujours afficher le nom du CMS $items .= ''; - $items .= 'ZwiiCMS'; + $items .= 'ZwiiCMS'; $items .= ''; // Affichage du numéro de version $items .= 'getData(['theme','footer','displayVersion']) === false ? ' class="displayNone"' : ''; - $items .= '> '. common::ZWII_VERSION ; + $items .= '> '. common::ZWII_VERSION ; $items .= ''; // Affichage du sitemap $items .= 'getData(['config','legalPageId']) !== '') { $items .= ' | Mentions légales'; } - $items .= ''; - // Affichage du lien de connexion + $items .= ''; + // Affichage du lien de connexion if( ( $this->getData(['theme', 'footer', 'loginLink']) @@ -2054,18 +2085,18 @@ class layout extends common { ) OR $this->getUrl(0) === 'theme' ) { - $items .= 'getUrl(0) === 'theme' ? 'class="displayNone"' : '') . - '> | getUrl(0) === 'theme' ? 'class="displayNone"' : '') . + '> | Connexion'; } // Fermeture du bloc copyright $items .= '
'; echo $items; } - - + + /** * Affiche les réseaux sociaux */ @@ -2100,7 +2131,7 @@ class layout extends common { case 'youtubeUserId': $socialUrl = 'https://www.youtube.com/user/'; $title = 'YouTube'; - break; + break; case 'githubId': $socialUrl = 'https://www.github.com/'; $title = 'Github'; @@ -2124,7 +2155,7 @@ class layout extends common { */ public function showFavicon() { // Light scheme - $favicon = $this->getData(['config', 'favicon']); + $favicon = $this->getData(['config', 'favicon']); if($favicon && file_exists(self::FILE_DIR.'source/' . $favicon) ) { @@ -2133,13 +2164,13 @@ class layout extends common { echo ''; } // Dark scheme - $faviconDark = $this->getData(['config', 'faviconDark']); + $faviconDark = $this->getData(['config', 'faviconDark']); if(!empty($faviconDark) && file_exists(self::FILE_DIR.'source/' . $faviconDark) ) { echo ''; echo ''; - } + } } @@ -2151,19 +2182,19 @@ class layout extends common { $items = ''; $currentPageId = $this->getData(['page', $this->getUrl(0)]) ? $this->getUrl(0) : $this->getUrl(2); foreach($this->getHierarchy() as $parentPageId => $childrenPageIds) { - // Passer les entrées masquées + // Passer les entrées masquées // Propriétés de l'item $active = ($parentPageId === $currentPageId OR in_array($currentPageId, $childrenPageIds)) ? ' class="active"' : ''; $targetBlank = $this->getData(['page', $parentPageId, 'targetBlank']) ? ' target="_blank"' : ''; // Mise en page de l'item $items .= '
  • '; - + if ( $this->getData(['page',$parentPageId,'disable']) === true AND $this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD') ) {$items .= ''; } else { - $items .= ''; + $items .= ''; } switch ($this->getData(['page', $parentPageId, 'typeMenu'])) { @@ -2195,29 +2226,29 @@ class layout extends common { $disableChild = 0; foreach($childrenPageIds as $childKey) { $totalChild += 1; - } + } if($childrenPageIds && $disableChild !== $totalChild && $this->getdata(['page',$parentPageId,'hideMenuChildren']) === false) { $items .= template::ico('down', 'left'); } - // ------------------------------------------------ + // ------------------------------------------------ $items .= ''; if ($this->getdata(['page',$parentPageId,'hideMenuChildren']) === true || empty($childrenPageIds)) { continue; } $items .= '