diff --git a/CHANGES.md b/CHANGES.md index 62dcfbaf..66efc4f4 100755 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,12 +1,39 @@ # Changelog +## Version 12.3.01 +### Améliorations : +- Prise en charge PHP 8.2 +- "Minification" de la sortie HTML. +- Envoi d'eMail, PHPMailer : + - Mise à jour PHPMailer 6.7.1, support PHP 8 ; + - Personnalisation de l'adresse de l'expéditeur ; + - Prise en charge des langues de l'interface ; + - Correction d'un mauvais fonctionnement de la configuration d'un serveur SMTP personnalisée différent de celui de l'hôte. +- Amélioration de la prise en charge des mises à jour en ligne. +- Activation du bouton de mise à jour dans la barre d'administration lorsque le menu de configuration est ouvert est qu'une mise à jour en ligne est détectée. +- Gestion des langues : + - Le numéro de version d'une langue est le numéro de version de base de données + - A l'installation ou lors de l'accès à la fenêtre des langues, les dialogues sont actualisés. + - La fonction d'édition des langues de l'UI est neutralisée. +- Contrôle des prérequis, Zwii ne démarre pas si la version de PHP n'est pas conforme ou si un module PHP nécessaire n'est pas installé, si les fichiers de sécurité htaccess sont manquants. +### Corrections : +- Suppression des appels Google Analytics lors du chargement du gestionnaire de fichiers (RFM) dans TUI-image. +- Mauvais affichage du script ou du CSS déclarés dans une page. +- Choix de la langue dans TinyMCE et CodeMirror. +- Mauvaise application des fontes dans l'administration du thème. +- Corrige une mauvaise lecture du type de fonte éditée. +- Correction de petits bugs. +### Nouveautés : +- Remplacement du sélecteur de date Flatpickr par le sélecteur HTML 5 qui autorise les formats suivants : date, time, week, month, datetime-local. +- Paramétrage du délai de recherche automatique d'une mise à jour, tous les jours, deux jours, quatre jours, toutes les semaines, tous les mois. + ## Version 12.2.04 - Référencement incorrect de la langue grecque dans la base centrale. ## Version 12.2.03 - Corrections de bugs consécutifs au changement de format de languages.json -## Version 12.2.02 +## Version 12.2.02 (version non publiée) ### Corrections : - Gestion des plugins (modules) : - Corrige un bug dans l'acquisition des données du store. @@ -14,13 +41,13 @@ - Corrige un bug dans l'installation d'un module (dataDirectory). - Langues étrangères (v4) : corrige l'absence de spécificateur %s dans les traductions occasionnant des plantages lorsqu'une langue étrangère est active. -## Version 12.2.01 +## Version 12.2.01 (version non publiée) ### Correction : - Bug majeur lors de l'installation d'une version fraiche, erreur lors de la création de la base de données des langues. ### Amélioration : - Gestion des erreurs d'écritures à l'aide d'un contrôle des données écrites sur le disque. Cinq tentatives se terminent par un arrêt en cas d'impossibilité d'enregistrer les données. -## Version 12.2.00 +## Version 12.2.00 (version non publiée) ### Nouveautés : - Traduction des modules en anglais, grec, espagnol, italien et portugais. ### Amélioration : diff --git a/LISEZMOI.md b/LISEZMOI.md index 32aead6f..90172085 100644 --- a/LISEZMOI.md +++ b/LISEZMOI.md @@ -1,4 +1,4 @@ -# ZwiiCMS 12.2.04 +# ZwiiCMS 12.3.01 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. @@ -70,6 +70,7 @@ A l'occasion de l'installation d'une verion majeure, il est recommandé de réal [R] site Contenu du site [R] backup Sauvegardes automatiques + [R] i18N Langues de l'interface de Zwii [R] data Répertoire des données [R] fr Dossier localisé [F] page.json Données des pages @@ -90,6 +91,7 @@ A l'occasion de l'installation d'une verion majeure, il est recommandé de réal [F] custom.css Feuille de style de la personnalisation avancée [F] fonts.json Descripteur des fontes personnalisées [F] journal.log Journalisation des actions + [F] languages.json Configuration des langues de l'interface [F] theme.css Thème du site [F] theme.json Données du site [F] user.json Données des utilisateurs diff --git a/README.md b/README.md index 09ba5d81..0f9b8e1d 100755 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# ZwiiCMS 12.2.04 +# ZwiiCMS 12.3.01 Zwii is a database-less (flat-file) CMS that allows you to easily create and manage a web site without any programming knowledge. @@ -50,59 +50,61 @@ When installing a major version, it is recommended to make a backup copy. ## General tree structure -*Legend: [R] Directory - [F] File +*Legend: [D] Directory - [FILE] File ```` text -[R] core Core of the system - [R] class Classes - [R] layout Layout - [R] module Core modules - [R] vendor External libraries - [F] core.js.php Javascript core - [F] core.php PHP core +[DIR] core Core of the system + [DIR] class Classes + [DIR] layout Layout + [DIR] module Core modules + [DIR] vendor External libraries + [FILE] core.js.php Javascript core + [FILE] core.php PHP core -[R] module Page modules - [R] blog Blog - [R] form Form manager - [R] gallery Gallery - [R] news News - [R] redirection Redirection +[DIR] module Page modules + [DIR] blog Blog + [DIR] form Form manager + [DIR] gallery Gallery + [DIR] news News + [DIR] redirection Redirection -[R] site Site content - [R] backup Automatic backups - [R] data Data directory - [R] en Localized folder - [F] page.json Page data - [F] module.json Page module data - [F] local.json Language-specific site data - [R] content Folder of page contents - [F] home.html Sample home page content - [R] fonts Folder containing the installed fonts - [F] fonts.html File containing the fonts calls to load on cdnFonts - [F] fonts.css File containing the style sheet linked to the local fonts - [F] fonts.woff Local font files (woff, etc..) - [R] modules Customization of modules or own data - [F] admin.css Theme of administration pages - [F] admin.json Theme data for administration pages - [F] blacklist.json Logging of login attempts with unknown accounts - [F] config.json Site configuration - [F] core.json Core configuration - [F] custom.css Advanced customization stylesheet - [F] fonts.json Custom font descriptor - [F] journal.log Action logging - [F] theme.css Site theme - [F] theme.json Site data - [F] user.json User data - [F] .backup Marker for file backup if present - [R] file File manager upload directory - [R] source Various resources - [R] thumb Image thumbnails - [R] tmp Temporary directory +[DIR] site Site content + [DIR] backup Automatic backups + [DIR] i18N Zwii Interface languages + [DIR] data Data directory + [DIR] en Localized folder + [FILE] page.json Page data + [FILE] module.json Page module data + [FILE] local.json Language-specific site data + [DIR] content Folder of page contents + [FILE] home.html Sample home page content + [DIR] fonts Folder containing the installed fonts + [FILE] fonts.html File containing the fonts calls to load on cdnFonts + [FILE] fonts.css File containing the style sheet linked to the local fonts + [FILE] fonts.woff Local font files (woff, etc..) + [DIR] modules Customization of modules or own data + [FILE] admin.css Theme of administration pages + [FILE] admin.json Theme data for administration pages + [FILE] blacklist.json Logging of login attempts with unknown accounts + [FILE] config.json Site configuration + [FILE] core.json Core configuration + [FILE] custom.css Advanced customization stylesheet + [FILE] fonts.json Custom font descriptor + [FILE] journal.log Action logging + [FILE] languages.json Interface database languages + [FILE] theme.css Site theme + [FILE] theme.json Site data + [FILE] user.json User data + [FILE] .backup Marker for file backup if present + [DIR] file File manager upload directory + [DIR] source Various resources + [DIR] thumb Image thumbnails + [DIR] tmp Temporary directory -[F] index.php ZwiiCMS initialization file -[F] robots.txt Filtering of directories accessible to search engine robots -[F] sitemap.xml Sitemap -[F] sitemap.xml.gz Compressed version +[FILE] index.php ZwiiCMS initialization file +[FILE] robots.txt Filtering of directories accessible to search engine robots +[FILE] sitemap.xml Sitemap +[FILE] sitemap.xml.gz Compressed version The .htaccess files contribute to security by filtering access to sensitive directories. diff --git a/core/class/helper.class.php b/core/class/helper.class.php index 5935ef45..e3412e65 100644 --- a/core/class/helper.class.php +++ b/core/class/helper.class.php @@ -42,6 +42,15 @@ class helper } */ + + // La traduction existe déjà dans le core + /* + if (array_key_exists($text, core::$dialog) === false && !empty($text)) { + $dialogues = json_decode(file_get_contents('core/module/install/ressource/i18n/fr_FR.json' ), true); + $data = array_merge($dialogues,[$text => '']); + file_put_contents ('core/module/install/ressource/i18n/fr_FR.json', json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT), LOCK_EX); + } + */ return (array_key_exists($text, core::$dialog) && !empty(core::$dialog[$text]) ? core::$dialog[$text] : $text); } @@ -53,9 +62,7 @@ class helper public static function dateUTF8($format, $date) { require_once 'core/class/strftime/php-8.1-strftime.class.php'; - return mb_detect_encoding(\PHP81_BC\strftime($format, $date), 'UTF-8', true) - ? \PHP81_BC\strftime($format, $date) - : utf8_encode(\PHP81_BC\strftime($format, $date)); + return mb_convert_encoding(\PHP81_BC\strftime($format, $date), 'UTF-8', mb_list_encodings()); } /** @@ -361,9 +368,9 @@ class helper * Renvoie le numéro de version de Zwii est en ligne * @return string */ - public static function getOnlineVersion() + public static function getOnlineVersion($channel) { - return (helper::getUrlContents(common::ZWII_UPDATE_URL . common::ZWII_UPDATE_CHANNEL . '/version')); + return (helper::getUrlContents(common::ZWII_UPDATE_URL . $channel . '/version')); } @@ -371,9 +378,9 @@ class helper * Check si une nouvelle version de Zwii est disponible * @return bool */ - public static function checkNewVersion() + public static function checkNewVersion($channel) { - $version = helper::getOnlineVersion(); + $version = helper::getOnlineVersion($channel); if (!empty($version)) { return ((version_compare(common::ZWII_VERSION, $version)) === -1); } else { diff --git a/core/class/jsondb/JsonDb.class.php b/core/class/jsondb/JsonDb.class.php index 92734a33..7d5332a5 100644 --- a/core/class/jsondb/JsonDb.class.php +++ b/core/class/jsondb/JsonDb.class.php @@ -52,7 +52,8 @@ class JsonDb extends \Prowebcraft\Dot public function set($key, $value = null, $save = true) { parent::set($key, $value); - if ($save) $this->save(); + if ($save) + $this->save(); return $this; } @@ -68,7 +69,8 @@ class JsonDb extends \Prowebcraft\Dot public function add($key, $value = null, $pop = false, $save = true) { parent::add($key, $value, $pop); - if ($save) $this->save(); + if ($save) + $this->save(); return $this; } @@ -82,7 +84,8 @@ class JsonDb extends \Prowebcraft\Dot public function delete($key, $save = true) { parent::delete($key); - if ($save) $this->save(); + if ($save) + $this->save(); return $this; } @@ -98,7 +101,8 @@ class JsonDb extends \Prowebcraft\Dot public function clear($key = null, $format = false, $save = true) { parent::clear($key, $format); - if ($save) $this->save(); + if ($save) + $this->save(); return $this; } @@ -108,19 +112,20 @@ class JsonDb extends \Prowebcraft\Dot * @param bool $reload Reboot data? * @return array|mixed|null */ - protected function loadData($reload = false) { + 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)) { return null; // Rebuild database manage by CMS } else { if ($this->config['backup']) { - try { - //todo make backup of database - copy ($this->config['dir'] . DIRECTORY_SEPARATOR . $this->config['name'], $this->config['dir'] . DIRECTORY_SEPARATOR . $this->config['name'] . '.backup'); - } catch (\Exception $e) { + try { + //todo make backup of database + copy($this->config['dir'] . DIRECTORY_SEPARATOR . $this->config['name'], $this->config['dir'] . DIRECTORY_SEPARATOR . $this->config['name'] . '.backup'); + } catch (\Exception $e) { - } + } } } $this->data = json_decode(file_get_contents($this->db), true); @@ -135,22 +140,24 @@ class JsonDb extends \Prowebcraft\Dot /** * Save database */ - public function save() { - $lenght = strlen(json_encode($this->data)); - $try = 0; - while ($try < 5) { - $written = file_put_contents($this->db, json_encode($this->data), JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT|LOCK_EX); // Multi user get a locker - if ($written == $lenght) { + public function save() + { + $v = json_encode($this->data, JSON_UNESCAPED_UNICODE | LOCK_EX); + $l = strlen($v); + $t = 0; + while ($t < 5) { + $w = file_put_contents($this->db, $v); // Multi user get a locker + if ($w == $l) { break; } $try++; sleep(1); } - if ($written !== $lenght) { + if ($w !== $l) { exit('Erreur d\'écriture, les données n\'ont pas été sauvegardées'); } } -} +} \ No newline at end of file diff --git a/core/class/layout.class.php b/core/class/layout.class.php new file mode 100644 index 00000000..59596755 --- /dev/null +++ b/core/class/layout.class.php @@ -0,0 +1,1167 @@ +core = $core; + } + + /** + * Affiche le consentement aux cookies + */ + public function showCookies() + { + // La gestion des cookies est externalisée + if ($this->getData(['config', 'cookieConsent']) === false) { + return; + } + // Le cookie est déjà validé + if ($this->getInput('ZWII_COOKIE_CONSENT') === 'true') { + return; + } + $item = '
'; + // Bouton de fermeture + $item .= '
'; + $item .= template::ico('cancel'); + $item .= '
'; + // Texte de la popup + $item .= '

' . $this->getData(['locale', 'cookies', 'titleLabel']) . '

'; + $item .= '

' . $this->getData(['locale', 'cookies', 'mainLabel']) . '

'; + // Formulaire de réponse + if ( + $this->getData(['locale', 'homePageId']) === $this->getUrl(0) + ) { + $item .= '
'; + } else { + $item .= ''; + } + $item .= '

'; + $item .= ''; + $item .= '
'; + // mentions légales si la page est définie + $legalPage = $this->getData(['locale', 'legalPageId']); + if ($legalPage !== 'none') { + $item .= '

' . $this->getData(['locale', 'cookies', 'linkLegalLabel']) . '

'; + } + $item .= '
'; + echo $item; + } + + /** + * Formate le contenu de la page selon les gabarits + * @param Page par defaut + */ + public function showSection() + { + echo '
'; + // Récupérer la config de la page courante + $blocks = is_null($this->getData(['page', $this->getUrl(0), 'block'])) ? '12' : $this->getData(['page', $this->getUrl(0), 'block']); + $blocks = explode('-', $blocks); + // Initialiser + $blockleft = ''; + $blockright = ''; + switch (sizeof($blocks)) { + case 1: // une colonne + $content = 'col' . $blocks[0]; + break; + case 2: // 2 blocs + if ($blocks[0] < $blocks[1]) { // détermine la position de la colonne + $blockleft = 'col' . $blocks[0]; + $content = 'col' . $blocks[1]; + } else { + $content = 'col' . $blocks[0]; + $blockright = 'col' . $blocks[1]; + } + break; + case 3: // 3 blocs + $blockleft = 'col' . $blocks[0]; + $content = 'col' . $blocks[1]; + $blockright = 'col' . $blocks[2]; + } + // Page pleine pour la configuration des modules et l'édition des pages sauf l'affichage d'un article de blog + $pattern = ['config', 'edit', 'add', 'comment', 'data']; + if ( + (sizeof($blocks) === 1 || + in_array($this->getUrl(1), $pattern)) + ) { // Pleine page en mode configuration + $this->showContent(); + } else { + echo '
'; + /** + * Barre gauche + */ + if ($blockleft !== "") { + echo '
"; + } + /** + * Contenu de page + */ + echo '
'; + $this->showContent(); + echo '
'; + /** + * Barre droite + */ + if ($blockright !== "") { + echo '
'; + } + echo '
'; + } + echo '
'; + } + + /** + * Affiche le contenu + * @param Page par défaut + */ + public function showContent() + { + + if ( + $this->core->output['title'] + and ($this->getData(['page', $this->getUrl(0)]) === null + or $this->getData(['page', $this->getUrl(0), 'hideTitle']) === false + or $this->getUrl(1) === 'config' + ) + ) { + echo '

' . $this->core->output['title'] . '

'; + } + + echo $this->core->output['content']; + } + + /** + * Affiche le pied de page + */ + public function showFooter() + { + // Déterminer la position + $positionFixed = ''; + if ( + $this->getData(['theme', 'footer', 'position']) === 'site' + // Affiche toujours le pied de page pour l'édition du thème + or ($this->getData(['theme', 'footer', 'position']) === 'hide' + and $this->getUrl(0) === 'theme' + ) + ) { + $position = 'site'; + } else { + $position = 'body'; + if ($this->getData(['theme', 'footer', 'fixed']) === true) { + $positionFixed = ' footerbodyFixed'; + } + // Sortir de la division précédente + echo ''; + } + + echo $this->getData(['theme', 'footer', 'position']) === 'hide' ? '