Compare commits

..

No commits in common. "master" and "13.0.08" have entirely different histories.

258 changed files with 1831 additions and 2938 deletions

2
.gitignore vendored
View File

@ -9,5 +9,3 @@ site/i18n/*.json
core/vendor/tinymce/link_list.json
robots.txt
sitemap.xml
.gitignore
core/module/config/tool/data.key

View File

@ -32,16 +32,5 @@ Options -Indexes
Options -MultiViews
</IfModule>
# Enlever le slash final des URL
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} ^(.+)/$
RewriteRule ^ %1 [R=301,L]
# ne pas supprimer la ligne URL rewriting !
# URL rewriting

View File

@ -1,201 +1,13 @@
# Notes de mises à jour
## Versions 13.4.00
** Améliorations :**
- Change le mode d'authentification, le hash du mot de passe n'est plus stocké dans un cookie.
- Le sélecteur de fichier affiche le chemin d'accès du fichier présent dans le champ dans le gestionnaire de fichier.
- Slider en version 7.1, corrections diverses.
- Connexion persistante renforcée.
- Script Datatables.net filtrage des éléments, nombre d'éléments et position sur l'écran.
- Slider 7.2, le dossier sélectionné est affiché par défaut dans la page update.
- Augmente la dimension des miniatures après le transfert dans RFM.
- Search 3.3 n'effectue qu'une seule lecture du fichier module.json en prévention des bots agressifs.
- Modification du contenu de robots.txt afin de n'autoriser que les moteurs de recherche et d'interdire les bots.
- Suppression des cookies mémorisant le dernier onglet affiché dans l'édition de la page et dans la configuration du site. Cette information est désormais stockée dans la fiche de l'utilisateur connecté.
**Corrections : **
- Change les paramètres du cookie de consentement.
- Isole la session dans l'onglet actif.
- Edition de page, delete et duplicate renvoyant vers une mauvaise page.
- Supprime un warning à la création d'une page.
- Bouton de génération du site inopérant.
- Affichage intempestif des boutons de navigation de pages dans les vues des modules.
## Versions 13.3.06
** Corrections : **
- Corrige un bug de sécurité dans la gestion des profils.
- Répare le bouton d'effacement en mode édition d'une page.
- Corrige la feuille de style du slider les balises H1, H3 et A.
- Corrige l'absence de contenu de page lorsque le module est en position libre et que le mot clé [MODULE] n'a pas été inséré.
- Corrige l'option "Rester connecter sur ce navigateur' dont la connexion est désormais réellement persistante.
- Supprime un slash à la fin de l'URL du catalogue.
- Eviter un warning lors de la création d'une nouvelle page.
## Versions 13.3.05
** Corrections : **
- Corrige la génération des miniatures au format avif et webp.
- Corrige le filtre FLOAT du helper qui supprimait la virgule flottante.
- Corrige des bugs dans le module Slider qui passe en version 7.0, ajout d'une option d'étiquette sous les images.
** Modifications : **
- Mise à jour du module News 5.9, taille d'un bouton.
- Mise à jour du module Blog 7.10, bloque la soumission d'un commentaire vide.
- Ajoute les filtres DATE et TIME pour l'affichage correct des champs de formulaire.
## Versions 13.3.04
** Correction : **
- Mauvaise génération du descripteur d'un module lors de sa sauvegarde.
## Versions 13.3.03
** Corrections :**
- Le bug d'édition des pages avec Firefox est corrigé grâce à la suppression d'une commande forçant le chargement lassif des images dans core.js.php
- Dans la configuration, l'option Apache URL intelligente ne s'active que si le serveur est Apache et que le module Rewriter est actif. Ce qui exclut les autres serveurs non compatibles comme Nginx, Caddy etc.
- L'ajout d'un slash en fin d'adresse avec la réécriture active provoquait une mauvaise détermination des adresses des images dans TinyMCE. Résolution : une directive htaccess supprime tous les slashes en fin d'adresse.
- Lorsque la page est ouverte en édition, un clic sur le bouton édition dans la barre d'administration affiche une erreur, le lien étant incorrect. Afin d'éviter cette erreur et une redondance, le bouton d'édition est masqué lorsque la page est éditée.
- Quand des éléments inutiles sont ajoutés à l'adresse d'une page, une erreur 403 est levée.
## Versions 13.3.01 - 13.2.02
Livraison des modules blogs et news corrigeant un problème de flux RSS avec des méta vides.
## Version 13.3.00
Cette modification évite les problèmes d'édition de langues différentes dans des onglets différents du même navigateur.
## Version 13.2.02
Corrige un warning quand un module blog ou news ne contient pas d'article.
## Version 13.2.01
### Correction
Modification de la fonction d'écriture des données de la classe jsonDB dans le but de s'assurer de l'intégrité des données écrites. Un trafic intense en pointe sur des fichiers volumineux et sur un serveur peu puissant pouvait occasionner des erreurs d'écriture ou un mauvais formatage des données json.
## Version 13.1.08
### Corrections
- Corrige des erreurs quand une page parente ou des pages enfants ont des permissions limitées.
- Module Search 3.1 : initialisation du module après installation dans une page sans configuration par l'utilisateur.
### Améliorations
- Sauvegarde de l'état des sélecteurs dans les tables des fontes et des utilisateurs.
- Ajoute des contrôles d'intégrité des bases de données Json lors des opérations de chargement et de sauvegarde.
- Fournit une interface pour le contrôle des sauvegardes automatisées et de leur nettoyage par script CRON.
## Version 13.1.07
### Corrections
- Corrige une dépréciation de la sortie de la fonction Usort dans RFM.
- Module slider 6.4 : corrige plusieurs bugs dans les fonctions de tri
## Version 13.1.06
### Corrections
- Ajout d'utilisateur, étiquette non sauvegardée.
- Slider, corrige un tri non pris en compte.
## Version 13.1.05
### Corrections
- Corrige définitivement la fonction delete de la classe dot.
- Branche de mise à jour de la version 13.1.04 incorrecte.
## Version 13.1.04
### Corrections
- Evite une notice dans l'onglet social de la configuration lorsque l'image opengraph n'est pas spécifiée.
- Corrige une erreur dans la classe dot (fonction delete appelée statiquement)
- Ne redirige pas vers une page d'erreur (403 ou 404) après un login.
### Améliorations
- Mise à jour en ligne :restauration de la réécriture dans le fichier .htaccess de la racine, utilisation d'un fichier drapeau *.rewrite* pour conserver l'état de la réécriture afin de dédier la variable ```data``` (XHR) aux messages d'erreur.
- Journalise les erreurs de mise à jour automatique.
## Version 13.1.03
### Corrections
- Corrige un format de date dans la génération du sitemap.
- Limite l'affichage de l'icône du gestionnaire de fichiers dans le menu aux membres simples.
- Module blog ; format d'une variable de temps.
- Modules Blog et news, corrige un bug de paramètre de localisation erroné.
- Mot de passe oublié, une variable non définie affichant un warning.
### Améliorations
- Thèmes ; fontes : les fontes attribuées sont dans le thème administrateur sont prises en compte dans le blocage de l'effacement.
- Optimisation du code de discrimination.
## Version 13.1.02
### Corrections
- Thème ; fontes : corrige un problème lors de l'installation et de la désinstallation d'une fonte sous forme de fichier woff.
- Thème ; fontes : corrige un bug de redirection vers la liste des fontes après édition ou ajout.
- Utilisateur ; ajout : corrige la non prise en compte de la langue.
- Supprime le script imagemap non tenu à jour et bogué.
### Amélioration
- Thèmes ; fontes : filtrage et tri des fontes installées.
## Version 13.1.01
### Améliorations
- Cette version supprime le sélecteur de thème lors de l'installation.
- Modules news et blog :
- Nouvelle option ajoutant un bouton de retour dans la page de l'article.
- La mise en forme du bloc signature est homogénéisée.
- Profil des membres, corrige une impossibilité d'autoriser l'accès au gestionnaire de fichiers pour les membres non administrateurs.
### Corrections
- Corrige une mauvaise mise en forme du journal des évènements.
- Autres petites corrections.
## Version 13.1.00
### Améliorations
- La gestion des utilisateurs bénéficie de nouvelles fonctionnalités :
- Un champ étiquette optionnel peut être attribué aux utilisateurs, il contient des mots clés séparés par des espaces. Ces mots clés permettent de filtrer les utilisateurs.
- Un champ de recherche dynamique agissant sur l'ensemble des colonnes du tableau filtre les lignes.
- Le nombre d'éléments affichés est dynamique.
- La procédure d'import tient compte du champ étiquette et ajoute le champ profil.
- Affecte une icône home aux boutons de retour.
- Ajoute un lien de retour aux pages d'erreur 403 et d'erreur 404.
### Corrections
- Corrige un problème de permission non spécifiée dans un profil.
- Corrige des messages de dépréciation de fonctions dans RFM.
- Corrige un message de dépréciation lié à l'absence éventuel de titre court dans la génération du sitemap.
- Corrige la génération de la liste des pages selon la langue sélectionnée pour les liens TinyMCE
- Met à jour les profils dans le slider.
- Petites corrections.
# Changelog
## Version 13.0.08
### Corrections
## Corrections
-Corrige un bug dans la génération du sitemap.
## Version 13.0.07
### Corrections
## Corrections
- Module Slider (version 6.1), conformité de la largeur de l'image en pleine largeur lorsque le site est en largeur 100%.
- Gestion des extensions, création du dossier "Modules" absent lors de la copie de l'archive d'un module dans le gestionnaire de fichiers.
@ -838,7 +650,7 @@ TinyMCE, URL absolues, transformation autorisée en URL relative si effectuée m
- Modifications :
- Gestion des cookies :
- Options de personnalisation du message d'acceptation des cookies, acceptation ou refus du cookie Google Analytics, affichage de la page des mentions légales.
- Étiquette dans le footer permettant d'afficher la popup des cookies.
- Etiquette dans le footer permettant d'afficher la popup des cookies.
- Thème :
- Disposition des options de configuration du site.
- Bannière : le contenu peut être personnalisé à l'aide d'un éditeur. La bannière au-dessus du site peut s'étendre sur la largeur de la page.

View File

@ -1,4 +1,4 @@
# ZwiiCMS 13.4.00 version de test
# ZwiiCMS 13.0.08
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.

View File

@ -1,4 +1,4 @@
# ZwiiCMS 13.4.00 test version
# ZwiiCMS 13.0.08
Zwii is a database-less (flat-file) CMS that allows you to easily create and manage a web site without any programming knowledge.

View File

@ -8,7 +8,7 @@ class helper
/** Filtres personnalisés */
const FILTER_BOOLEAN = 1;
const FILTER_DATETIME = 2; // filtre pour le champ de formulaire A conserver pour la compatibilité
const FILTER_DATETIME = 2;
const FILTER_FLOAT = 3;
const FILTER_ID = 4;
const FILTER_INT = 5;
@ -16,14 +16,8 @@ class helper
const FILTER_PASSWORD = 7;
const FILTER_STRING_LONG = 8;
const FILTER_STRING_SHORT = 9;
const FILTER_TIMESTAMP = 10; // Saisie d'une date en locatime
const FILTER_TIMESTAMP = 10;
const FILTER_URL = 11;
const FILTER_DATE = 12; // filtre pour le champ de formulaire
const FILTER_TIME = 13; // filtre pour le champ de formulair
const FILTER_MONTH = 14; // filtre pour le champ de formulair
const FILTER_YEAR = 16; // filtre pour le champ de formulair
/**
@ -83,7 +77,7 @@ class helper
// Créer la variable
$data = array_merge($data, [$text => '']);
}
file_put_contents('site/i18n/' . $to . '.json', json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
file_put_contents('site/i18n/' . $to . '.json', json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT), LOCK_EX);
}
}
@ -344,12 +338,13 @@ class helper
{
// N'interroge que le serveur Apache
if (strpos($_SERVER["SERVER_SOFTWARE"], 'Apache') > 0) {
self::$rewriteStatus = false;
} else {
self::$rewriteStatus === false;
} elseif (self::$rewriteStatus === null) {
// Ouvre et scinde le fichier .htaccess
$htaccess = explode('# URL rewriting', file_get_contents('.htaccess'));
// Retourne un boolean en fonction du contenu de la partie réservée à l'URL rewriting
self::$rewriteStatus = (strpos($htaccess[1], 'RewriteEngine on') !== false);
//self::$rewriteStatus = (empty($htaccess[1]) === false);
self::$rewriteStatus = (strpos($htaccess[1], 'RewriteEngine on') > 0) ? true : false;
}
return self::$rewriteStatus;
}
@ -373,7 +368,7 @@ class helper
$version = helper::getOnlineVersion($channel);
$update = false;
if (!empty($version)) {
$update = version_compare(common::ZWII_VERSION, $version) == -1;
$update = version_compare(common::ZWII_VERSION, $version) === -1;
}
return $update;
}
@ -408,8 +403,8 @@ class helper
*/
public static function deleteCookie($cookieKey)
{
setcookie($cookieKey, '', time() - 3600, helper::baseUrl(false, false), '', false, true);
unset($_COOKIE[$cookieKey]);
setcookie($cookieKey, '', time() - 3600, helper::baseUrl(false, false), '', false, true);
}
/**
@ -432,8 +427,7 @@ class helper
$text = (int) $date->format('U');
break;
case self::FILTER_FLOAT:
$text = str_replace(',', '.', $text); // Remplacer les virgules par des points
$text = filter_var($text, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
$text = filter_var($text, FILTER_SANITIZE_NUMBER_FLOAT);
$text = (float) $text;
break;
case self::FILTER_ID:
@ -480,11 +474,6 @@ class helper
case self::FILTER_URL:
$text = filter_var($text, FILTER_SANITIZE_URL);
break;
case self::FILTER_DATE:
$text = date('Y-m-d', $text);
break;
case self::FILTER_TIME:
$text = date('H:i', $text);
}
return $text;
}

View File

@ -141,7 +141,7 @@ class Dot implements \ArrayAccess, \Iterator, \Countable
} elseif (is_array($key)) {
// Iterate array of paths
foreach ($key as $k) {
self::deleteValue($array, $k);
self::delete($k);
}
}
}

View File

@ -18,12 +18,6 @@ class JsonDb extends \Prowebcraft\Dot
protected $db = '';
protected $data = null;
protected $config = [];
// Tentative d'encodage après échec
const MAX_JSON_ENCODE_ATTEMPTS = 5;
// Tentative d'écriture après échec
const MAX_FILE_WRITE_ATTEMPTS = 5;
// Délais entre deux tentaives
const RETRY_DELAY_SECONDS = 1;
public function __construct($config = [])
{
@ -127,10 +121,10 @@ class JsonDb extends \Prowebcraft\Dot
} 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) {
error_log('Erreur de chargement : ' . $e);
exit('Erreur de chargement : ' . $e);
}
}
}
@ -148,41 +142,20 @@ class JsonDb extends \Prowebcraft\Dot
*/
public function save()
{
// Encode les données au format JSON avec les options spécifiées
//$encoded_data = json_encode($this->data, JSON_UNESCAPED_UNICODE | JSON_FORCE_OBJECT | JSON_PRETTY_PRINT);
$encoded_data = json_encode($this->data, JSON_UNESCAPED_UNICODE | JSON_FORCE_OBJECT);
// Vérifie la longueur de la chaîne JSON encodée
$encoded_length = strlen($encoded_data);
// Initialise le compteur de tentatives
$attempt = 0;
// Tente d'encoder les données en JSON et de les sauvegarder jusqu'à 5 fois en cas d'échec
while ($attempt < 5) {
// Essaye d'écrire les données encodées dans le fichier de base de données
$write_result = file_put_contents($this->db, $encoded_data, LOCK_EX); // Les utilisateurs multiples obtiennent un verrou
// Vérifie si l'écriture a réussi
if ($write_result === $encoded_length) {
// Sort de la boucle si l'écriture a réussi
//$v = json_encode($this->data, JSON_UNESCAPED_UNICODE );
$v = json_encode($this->data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_FORCE_OBJECT);
$l = strlen($v);
$t = 0;
while ($t < 5) {
$w = file_put_contents($this->db, $v); // Multi user get a locker
if ($w == $l) {
break;
}
// Incrémente le compteur de tentatives
$attempt++;
// Attente
sleep(1);
$t++;
}
if ($w !== $l) {
exit('Erreur d\'écriture, les données n\'ont pas été sauvegardées');
}
// Vérifie si l'écriture a échoué même après plusieurs tentatives
if ($write_result !== $encoded_length) {
// Enregistre un message d'erreur dans le journal des erreurs
error_log('Erreur d\'écriture, les données n\'ont pas été sauvegardées.');
// Affiche un message d'erreur et termine le script
exit('Erreur d\'écriture, les données n\'ont pas été sauvegardées.');
}
}
}

View File

@ -82,25 +82,17 @@ class layout extends common
$content = 'col' . $blocks[1];
$blockright = 'col' . $blocks[2];
}
// Toujours en pleine page pour la configuration des modules et l'édition des pages sauf l'affichage d'un article de blog
$pattern = ['config', 'edit', 'add', 'comment', 'data', 'option', 'theme', 'comment', 'article', 'data', 'gallery', 'update', 'users', 'validate'];
// 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
if (
($this->getData(['page', $this->getUrl(0), 'navLeft']) === 'top'
|| $this->getData(['page', $this->getUrl(0), 'navRight']) === 'top')
&& in_array($this->getUrl(1), $pattern) === false
) {
if ($this->getData(['page', $this->getUrl(0), 'navLeft']) === 'top' || $this->getData(['page', $this->getUrl(0), 'navRight']) === 'top') {
$this->showNavButtons('top');
}
$this->showContent();
if (
($this->getData(['page', $this->getUrl(0), 'navLeft']) === 'bottom'
|| $this->getData(['page', $this->getUrl(0), 'navRight']) === 'bottom')
&& in_array($this->getUrl(1), $pattern) === false
) {
if ($this->getData(['page', $this->getUrl(0), 'navLeft']) === 'bottom' || $this->getData(['page', $this->getUrl(0), 'navRight']) === 'bottom') {
$this->showNavButtons('bottom');
}
} else {
@ -159,7 +151,7 @@ class layout extends common
}
echo '</div>';
}
echo '</section></main>';
echo '</main></section>';
}
/**
@ -338,7 +330,7 @@ class layout extends common
// Affichage du lien de connexion
if (
($this->getData(['theme', 'footer', 'loginLink'])
and $this->isConnected() === false
and $this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD')
)
or $this->getUrl(0) === 'theme'
) {
@ -501,7 +493,7 @@ class layout extends common
// Lien de connexion
if (
($this->getData(['theme', 'menu', 'loginLink'])
and $this->isConnected() === false
and $this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD')
)
or $this->getUrl(0) === 'theme'
) {
@ -514,7 +506,7 @@ class layout extends common
}
// Commandes pour les membres simples
if (
$this->getUser('group') === self::GROUP_MEMBER
$this->getUser('group') >= self::GROUP_MEMBER && $this->getUser('group') < self::GROUP_ADMIN
&& $this->getData(['theme', 'menu', 'memberBar']) === true
) {
if (
@ -588,9 +580,9 @@ class layout extends common
if (
($this->getData(['page', $parentPageId, 'disable']) === true
and $this->isConnected() === false
and $this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD')
) or ($this->getData(['page', $parentPageId, 'disable']) === true
and $this->isConnected() === true
and $this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
and $this->getUser('group') < self::GROUP_EDITOR
)
) {
@ -654,9 +646,9 @@ class layout extends common
$items .= '<li id=' . $childKey . '>';
if (
($this->getData(['page', $childKey, 'disable']) === true
and $this->isConnected() === false
and $this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD')
) or ($this->getData(['page', $childKey, 'disable']) === true
and $this->isConnected() === true
and $this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
and $this->getUser('group') < self::GROUP_EDITOR
)
) {
@ -750,7 +742,7 @@ class layout extends common
$items .= '<li class="menuSideChild">';
if (
$this->getData(['page', $parentPageId, 'disable']) === true
and $this->isConnected() === false
and $this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD')
) {
$items .= '<a href="' . $this->getUrl(1) . '">';
} else {
@ -774,7 +766,7 @@ class layout extends common
if (
$this->getData(['page', $childKey, 'disable']) === true
and $this->isConnected() === false
and $this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD')
) {
$itemsChildren .= '<a href="' . $this->getUrl(1) . '">';
} else {
@ -910,7 +902,7 @@ class layout extends common
*/
public function showBar()
{
if ($this->isConnected() === true) {
if ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')) {
// Items de gauche
$leftItems = '';
// Sélecteur de langues
@ -919,7 +911,7 @@ class layout extends common
foreach (self::$languages as $key => $value) {
if (is_dir(self::DATA_DIR . $key)) {
$location = helper::baseUrl() . 'language/content/' . $key;
$leftItem .= '<option name="' . $key . '" value="' . $location . '" ' . ($key === self::$siteContent ? 'selected' : '') . '>' . $value . '</option>';
$leftItem .= '<option name="' . $key . '" value="' . $location . '" ' . ($key === self::$i18nContent ? 'selected' : '') . '>' . $value . '</option>';
}
}
$leftItems .= '<li><select id="barSelectLanguage" >';
@ -988,7 +980,7 @@ class layout extends common
// Bouton Ajouter une page
if ($this->getUser('permission', 'page', 'add')) {
$leftItems .= '<li>' . template::ico('plus', [
'href' => helper::baseUrl() . 'page/add/' . self::$siteContent,
'href' => helper::baseUrl() . 'page/add',
'help' => 'Nouvelle page ou barre latérale'
]) . '</li>';
}
@ -998,27 +990,23 @@ class layout extends common
// Sur une page sans module
or $this->getData(['page', $this->getUrl(0), 'moduleId']) === ''
// Sur une page avec un module invalide
or (!is_null($this->getData(['page', $this->getUrl(2), 'moduleId'])) and
or (!is_null($this->getData(['page', $this->getUrl(2), 'moduleId'])) &&
!class_exists($this->getData(['page', $this->getUrl(2), 'moduleId']))
)
// Sur une page d'accueil
or $this->getUrl(0) === ''
) {
// Bouton Editer une page
if (
$this->getUser('permission', 'page', 'edit')
and $this->geturl(1) !== 'edit'
) {
if ($this->getUser('permission', 'page', 'edit')) {
$leftItems .= '<li>' . template::ico('pencil', [
'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(0) . '/' . self::$siteContent,
'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(0),
'help' => 'Éditer la page'
]) . '</li>';
}
// Bouton Editer le module d'une page
if (
$this->getUser('permission', 'page', 'module')
and $this->geturl(1) !== 'edit'
and $this->getData(['page', $this->getUrl(0), 'moduleId'])
&& $this->getData(['page', $this->getUrl(0), 'moduleId'])
) {
$leftItems .= '<li>' . template::ico('gear', [
'href' => helper::baseUrl() . $this->getUrl(0) . '/config',
@ -1028,10 +1016,9 @@ class layout extends common
// Bouton dupliquer une page
if (
$this->getUser('permission', 'page', 'duplicate')
and $this->geturl(1) !== 'edit'
) {
$leftItems .= '<li>' . template::ico('clone', [
'href' => helper::baseUrl() . 'page/duplicate/' . $this->getUrl(0) . '/' . self::$siteContent,
'href' => helper::baseUrl() . 'page/duplicate/' . $this->getUrl(0),
'help' => 'Dupliquer la page'
])
. '</li>';
@ -1039,11 +1026,9 @@ class layout extends common
// Bouton Effacer une page
if (
$this->getUser('permission', 'page', 'delete')
and $this->geturl(1) !== 'edit'
) {
$leftItems .= '<li>' . template::ico('trash', [
'href' => helper::baseUrl() . 'page/delete/' . $this->getUrl(0) . '/' . self::$siteContent,
'href' => helper::baseUrl() . 'page/delete/' . $this->getUrl(0),
'help' => 'Supprimer la page',
'id' => 'pageDelete'
])
@ -1071,14 +1056,18 @@ class layout extends common
'help' => 'Thème',
'href' => helper::baseUrl() . 'theme'
]) . '</li>';
$rightItems .= '<li>' . template::ico('users', [
'help' => 'Utilisateurs',
'href' => helper::baseUrl() . 'user'
$rightItems .= '<li>' . template::ico('puzzle', [
'help' => 'Modules',
'href' => helper::baseUrl() . 'plugin'
]) . '</li>';
$rightItems .= '<li>' . template::ico('cog-alt', [
'help' => 'Configuration',
'href' => helper::baseUrl() . 'config'
]) . '</li>';
$rightItems .= '<li>' . template::ico('users', [
'help' => 'Utilisateurs',
'href' => helper::baseUrl() . 'user'
]) . '</li>';
// Mise à jour automatique
$today = mktime(0, 0, 0);
$checkUpdate = $this->getData(['core', 'lastAutoUpdate']);
@ -1096,45 +1085,15 @@ class layout extends common
) {
$this->setData(['core', 'updateAvailable', true]);
}
// Recherche de mise à jour des modules
$store = plugin::getStore();
if (is_array($store)) {
// Modules installés
$infoModules = helper::getModules();
// Clés moduleIds dans les pages
$inPages = helper::arrayColumn($this->getData(['page']), 'moduleId', 'SORT_DESC');
// Parcourir les données des modules
foreach ($store as $key => $value) {
if (empty($key)) {
continue;
}
// Mise à jour d'un module
if (array_key_exists($key, $infoModules) === true) {
$this->setData(['core', 'updateModuleAvailable', true]);
}
}
}
}
}
// Afficher le bouton : Mise à jour détectée + activée
if ($this->getData(['core', 'updateAvailable'])) {
$rightItems .= '<li><a href="' . helper::baseUrl() . 'install/update" data-tippy-content="Mettre à jour Zwii ' . common::ZWII_VERSION . ' vers ' . helper::getOnlineVersion(common::ZWII_UPDATE_CHANNEL) . '">' . template::ico('update colorRed') . '</a></li>';
}
}
if ($this->getData(['core', 'updateModuleAvailable'])) {
$rightItems .= '<li>' . template::ico('puzzle colorRed', [
'help' => 'Modules',
'href' => helper::baseUrl() . 'plugin'
]) . '</li>';
} else {
$rightItems .= '<li>' . template::ico('puzzle', [
'help' => 'Modules',
'href' => helper::baseUrl() . 'plugin'
]) . '</li>';
}
// Boutons depuis le groupe éditeur
if (
$this->getUser('group') >= self::GROUP_EDITOR
&& $this->getUser('permission', 'user', 'edit')
@ -1222,7 +1181,7 @@ class layout extends common
$vars = 'var baseUrl = ' . json_encode(helper::baseUrl(false)) . ';';
$vars .= 'var baseUrlQs = ' . json_encode(helper::baseUrl()) . ';';
if (
$this->isConnected() === true
$this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
and $this->getUser('group') >= self::GROUP_EDITOR
) {
$vars .= 'var privateKey = ' . json_encode(md5_file(self::DATA_DIR . 'core.json')) . ';';
@ -1271,8 +1230,8 @@ class layout extends common
public function showi18n($lang)
{
if (
(isset($_SESSION['ZWII_SITE_CONTENT'])
and $_SESSION['ZWII_SITE_CONTENT'] === $lang
(isset($_SESSION['ZWII_CONTENT'])
and $_SESSION['ZWII_CONTENT'] === $lang
)
) {
$select = ' class="i18nFlagSelected" ';

View File

@ -11,16 +11,16 @@ class core extends common
parent::__construct();
// Token CSRF
if (empty($_SESSION['csrf'])) {
$_SESSION['csrf'] = bin2hex(openssl_random_pseudo_bytes(64));
$_SESSION['csrf'] = bin2hex(openssl_random_pseudo_bytes(128));
}
// Fuseau horaire
common::$timezone = $this->getData(['config', 'timezone']); // Utile pour transmettre le timezone à la classe helper
date_default_timezone_set(common::$timezone);
self::$timezone = $this->getData(['config', 'timezone']); // Utile pour transmettre le timezone à la classe helper
date_default_timezone_set(self::$timezone);
// Supprime les fichiers temporaires
$lastClearTmp = mktime(0, 0, 0);
if ($lastClearTmp > $this->getData(['core', 'lastClearTmp']) + 86400) {
$iterator = new DirectoryIterator(common::TEMP_DIR);
$iterator = new DirectoryIterator(self::TEMP_DIR);
foreach ($iterator as $fileInfos) {
if (
$fileInfos->isFile() &&
@ -43,11 +43,11 @@ class core extends common
and $this->getData(['user']) // Pas de backup pendant l'installation
) {
// Copie des fichier de données
helper::autoBackup(common::BACKUP_DIR, ['backup', 'tmp', 'file']);
helper::autoBackup(self::BACKUP_DIR, ['backup', 'tmp', 'file']);
// Date du dernier backup
$this->setData(['core', 'lastBackup', $lastBackup]);
// Supprime les backups de plus de 30 jours
$iterator = new DirectoryIterator(common::BACKUP_DIR);
$iterator = new DirectoryIterator(self::BACKUP_DIR);
foreach ($iterator as $fileInfos) {
if (
$fileInfos->isFile()
@ -60,23 +60,23 @@ class core extends common
}
// Crée le fichier de personnalisation avancée
if (file_exists(common::DATA_DIR . 'custom.css') === false) {
$this->secure_file_put_contents(common::DATA_DIR . 'custom.css', file_get_contents('core/module/theme/resource/custom.css'));
chmod(common::DATA_DIR . 'custom.css', 0755);
if (file_exists(self::DATA_DIR . 'custom.css') === false) {
file_put_contents(self::DATA_DIR . 'custom.css', file_get_contents('core/module/theme/resource/custom.css'));
chmod(self::DATA_DIR . 'custom.css', 0755);
}
// Crée le fichier de personnalisation
if (file_exists(common::DATA_DIR . 'theme.css') === false) {
$this->secure_file_put_contents(common::DATA_DIR . 'theme.css', '');
chmod(common::DATA_DIR . 'theme.css', 0755);
if (file_exists(self::DATA_DIR . 'theme.css') === false) {
file_put_contents(self::DATA_DIR . 'theme.css', '');
chmod(self::DATA_DIR . 'theme.css', 0755);
}
// Crée le fichier de personnalisation de l'administration
if (file_exists(common::DATA_DIR . 'admin.css') === false) {
$this->secure_file_put_contents(common::DATA_DIR . 'admin.css', '');
chmod(common::DATA_DIR . 'admin.css', 0755);
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(common::DATA_DIR . 'theme.css'));
$cssVersion = preg_split('/\*+/', file_get_contents(self::DATA_DIR . 'theme.css'));
if (empty($cssVersion[1]) or $cssVersion[1] !== md5(json_encode($this->getData(['theme'])))) {
// Version
$css = '/*' . md5(json_encode($this->getData(['theme']))) . '*/';
@ -92,7 +92,7 @@ class core extends common
// Fonts disponibles
$fontsAvailable['files'] = $this->getData(['font', 'files']);
$fontsAvailable['imported'] = $this->getData(['font', 'imported']);
$fontsAvailable['websafe'] = common::$fontsWebSafe;
$fontsAvailable['websafe'] = self::$fontsWebSafe;
// Fontes installées
$fonts = [
@ -105,14 +105,53 @@ class core extends common
// Suppression des polices identiques
$fonts = array_unique($fonts);
/**
* Charge les fontes websafe
*/
$fontFile = '';
foreach ($fonts as $fontId) {
if (isset($fontsAvailable['websafe'][$fontId])) {
$fonts[$fontId] = $fontsAvailable['websafe'][$fontId]['font-family'];
}
}
/**
* Charge les fontes
* Chargement des polices en ligne dans un fichier font.html inclus dans main.php
*/
$fontFile = '';
$gf = false;
foreach ($fonts as $fontId) {
if (isset($fontsAvailable['imported'][$fontId])) {
$fontFile .= '<link href="' . $fontsAvailable['imported'][$fontId]['resource'] . '" rel="stylesheet">';
// Tableau pour la construction de la feuille de style
$fonts[$fontId] = $fontsAvailable['imported'][$fontId]['font-family'];
$gf = strpos($fontsAvailable['imported'][$fontId]['resource'], 'fonts.googleapis.com') === false ? $gf || false : $gf || true;
}
}
// Ajoute le préconnect des fontes Googles.
$fontFile = $gf ? '<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>' . $fontFile
: $fontFile;
// Enregistre la personnalisation
if (!is_dir(self::DATA_DIR . 'font')) {
mkdir(self::DATA_DIR . 'font');
}
file_put_contents(self::DATA_DIR . 'font/font.html', $fontFile);
/**
* Fontes installées localement
*/
foreach ($fonts as $fontId) {
foreach (['websafe', 'imported', 'files'] as $typeFont) {
if (isset($fontsAvailable[$typeFont][$fontId])) {
$fonts[$fontId] = $fontsAvailable[$typeFont][$fontId]['font-family'];
// Validité du tableau :
if (isset($fontsAvailable['files'][$fontId])) {
if (file_exists(self::DATA_DIR . 'font/' . $fontId)) {
// Chargement de la police
$css .= '@font-face {font-family:"' . $fontsAvailable['files'][$fontId]['font-family'] . '";';
$css .= 'src: url("' . helper::baseUrl(false) . self::DATA_DIR . 'font/' . $fontsAvailable['files'][$fontId]['resource'] . '");}';
// Tableau pour la construction de la feuille de style
$fonts[$fontId] = $fontsAvailable['files'][$fontId]['font-family'];
} else {
// Le fichier de font n'est pas disponible, fonte par défaut
$fonts[$fontId] = 'verdana';
}
}
}
@ -272,8 +311,14 @@ class core extends common
$css .= '#footerText > p {text-align:' . $this->getData(['theme', 'footer', 'textAlign']) . '}';
$css .= '#footerCopyright{text-align:' . $this->getData(['theme', 'footer', 'copyrightAlign']) . '}';
// Enregistre les fontes
if (!is_dir(self::DATA_DIR . 'font')) {
mkdir(self::DATA_DIR . 'font');
}
file_put_contents(self::DATA_DIR . 'font/font.html', $fontFile);
// Enregistre la personnalisation
$this->secure_file_put_contents(common::DATA_DIR . 'theme.css', $css);
file_put_contents(self::DATA_DIR . 'theme.css', $css);
// Effacer le cache pour tenir compte de la couleur de fond TinyMCE
header("Expires: Tue, 01 Jan 2000 00:00:00 GMT");
@ -284,7 +329,7 @@ class core extends common
}
// Check la version rafraichissement du theme admin
$cssVersion = preg_split('/\*+/', file_get_contents(common::DATA_DIR . 'admin.css'));
$cssVersion = preg_split('/\*+/', file_get_contents(self::DATA_DIR . 'admin.css'));
if (empty($cssVersion[1]) or $cssVersion[1] !== md5(json_encode($this->getData(['admin'])))) {
// Version
@ -293,7 +338,7 @@ class core extends common
// Fonts disponibles
$fontsAvailable['files'] = $this->getData(['font', 'files']);
$fontsAvailable['imported'] = $this->getData(['font', 'imported']);
$fontsAvailable['websafe'] = common::$fontsWebSafe;
$fontsAvailable['websafe'] = self::$fontsWebSafe;
/**
* Import des polices de caractères
@ -307,12 +352,44 @@ class core extends common
$fonts = array_unique($fonts);
/**
* Charge les fontes
* Charge les fontes websafe
*/
$fontFile = '';
foreach ($fonts as $fontId) {
if (isset($fontsAvailable['websafe'][$fontId])) {
$fonts[$fontId] = $fontsAvailable['websafe'][$fontId]['font-family'];
}
}
/**
* Chargement des polices en ligne dans un fichier font.html inclus dans main.php
*/
$fontFile = '';
foreach ($fonts as $fontId) {
if (isset($fontsAvailable['imported'][$fontId])) {
$fontFile .= '<link href="' . $fontsAvailable['imported'][$fontId]['resource'] . '" rel="stylesheet">';
// Tableau pour la construction de la feuille de style
$fonts[$fontId] = $fontsAvailable['imported'][$fontId]['font-family'];
}
}
// Enregistre la personnalisation
file_put_contents(self::DATA_DIR . 'font/font.html', $fontFile);
/**
* Fontes installées localement
*/
foreach ($fonts as $fontId) {
foreach (['websafe', 'imported', 'files'] as $typeFont) {
if (isset($fontsAvailable[$typeFont][$fontId])) {
$fonts[$fontId] = $fontsAvailable[$typeFont][$fontId]['font-family'];
// Validité du tableau :
if (isset($fontsAvailable['files'][$fontId])) {
if (file_exists(self::DATA_DIR . 'font/' . $fontId)) {
// Chargement de la police
$css .= '@font-face {font-family:"' . $fontsAvailable['files'][$fontId]['font-family'] . '";';
$css .= 'src: url("' . helper::baseUrl(false) . self::DATA_DIR . 'font/' . $fontsAvailable['files'][$fontId]['resource'] . '");}';
// Tableau pour la construction de la feuille de style
$fonts[$fontId] = $fontsAvailable['files'][$fontId]['font-family'];
} else {
// Le fichier de font n'est pas disponible, fonte par défaut
$fonts[$fontId] = 'verdana';
}
}
}
@ -367,7 +444,7 @@ class core extends common
// Bordure du contour TinyMCE
$css .= '.mce-tinymce{border: 1px solid ' . $this->getData(['admin', 'borderBlockColor']) . '!important;}';
// Enregistre la personnalisation
$this->secure_file_put_contents(common::DATA_DIR . 'admin.css', $css);
file_put_contents(self::DATA_DIR . 'admin.css', $css);
}
}
/**
@ -383,8 +460,8 @@ class core extends common
require 'core/module/' . $classPath;
}
// Module
elseif (is_readable(common::MODULE_DIR . $classPath)) {
require common::MODULE_DIR . $classPath;
elseif (is_readable(self::MODULE_DIR . $classPath)) {
require self::MODULE_DIR . $classPath;
}
// Librairie
elseif (is_readable('core/vendor/' . $classPath)) {
@ -415,8 +492,8 @@ class core extends common
// Force la déconnexion des membres bannis ou d'une seconde session
if (
$this->isConnected() === true
and ($this->getUser('group') === common::GROUP_BANNED
$this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
and ($this->getUser('group') === self::GROUP_BANNED
or ($_SESSION['csrf'] !== $this->getData(['user', $this->getUser('id'), 'accessCsrf'])
and $this->getData(['config', 'connect', 'autoDisconnect']) === true)
)
@ -429,9 +506,9 @@ class core extends common
$this->getData(['config', 'maintenance'])
and in_array($this->getUrl(0), ['maintenance', 'user']) === false
and $this->getUrl(1) !== 'login'
and ($this->isConnected() === false
or ($this->isConnected() === true
and $this->getUser('group') < common::GROUP_ADMIN
and ($this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD')
or ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
and $this->getUser('group') < self::GROUP_ADMIN
)
)
) {
@ -444,12 +521,32 @@ class core extends common
exit();
}
// Pour éviter une 404 sur une langue étrangère, bascule dans la langue correcte.
if (is_null($this->getData(['page', $this->getUrl(0)]))) {
foreach (self::$languages as $key => $value) {
if (
is_dir(self::DATA_DIR . $key) &&
file_exists(self::DATA_DIR . $key . '/page.json')
) {
$pagesId = json_decode(file_get_contents(self::DATA_DIR . $key . '/page.json'), true);
if (
is_array($pagesId['page']) &&
array_key_exists($this->getUrl(0), $pagesId['page'])
) {
$_SESSION['ZWII_CONTENT'] = $key;
header('Refresh:0; url=' . helper::baseUrl() . $this->getUrl(0));
exit();
}
}
}
}
// Check l'accès à la page
$access = null;
if ($this->getData(['page', $this->getUrl(0)]) !== null) {
if (
$this->getData(['page', $this->getUrl(0), 'group']) === common::GROUP_VISITOR
or ($this->isConnected() === true
$this->getData(['page', $this->getUrl(0), 'group']) === self::GROUP_VISITOR
or ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
// and $this->getUser('group') >= $this->getData(['page', $this->getUrl(0), 'group'])
// Modification qui tient compte du profil de la page
and ($this->getUser('group') * 10 + $this->getUser('profil')) >= ($this->getData(['page', $this->getUrl(0), 'group']) * 10 + $this->getData(['page', $this->getUrl(0), 'profil']))
@ -466,22 +563,14 @@ class core extends common
// Empêcher l'accès aux pages désactivées par URL directe
if (
($this->getData(['page', $this->getUrl(0), 'disable']) === true
and $this->isConnected() === false
and $this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD')
) or ($this->getData(['page', $this->getUrl(0), 'disable']) === true
and $this->isConnected() === true
and $this->getUser('group') < common::GROUP_EDITOR
and $this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
and $this->getUser('group') < self::GROUP_EDITOR
)
) {
$access = false;
}
// Lève une erreur si l'url est celle d'une page avec des éléments surnuméraires https://www.site.fr/page/truc
if (
array_key_exists($this->getUrl(0), $this->getData(['page']))
and $this->getUrl(1)
and $this->getData(['page', $this->getUrl(0), 'moduleId']) === ''
) {
$access = false;
}
}
/**
@ -503,9 +592,9 @@ class core extends common
$this->getUser('id') &&
$userId !== $this->getUser('id') &&
$this->getData(['user', $userId, 'accessUrl']) === $this->getUrl() &&
array_intersect($t, common::$concurrentAccess) &&
//array_intersect($t, common::$accessExclude) !== false &&
time() < $this->getData(['user', $userId, 'accessTimer']) + common::ACCESS_TIMER
array_intersect($t, self::$concurrentAccess) &&
//array_intersect($t, self::$accessExclude) !== false &&
time() < $this->getData(['user', $userId, 'accessTimer']) + self::ACCESS_TIMER
) {
$access = false;
$accessInfo['userName'] = $this->getData(['user', $userId, 'lastname']) . ' ' . $this->getData(['user', $userId, 'firstname']);
@ -515,7 +604,7 @@ class core extends common
}
// Accès concurrent stocke la page visitée
if (
$this->isConnected() === true
$this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
&& $this->getUser('id')
) {
$this->setData(['user', $this->getUser('id'), 'accessUrl', $this->getUrl()]);
@ -542,10 +631,10 @@ class core extends common
$inlineScript[] = $this->getData(['page', $this->getUrl(0), 'js']) === null ? '' : $this->getData(['page', $this->getUrl(0), 'js']);
// Importe le contenu, le CSS et le script des barres
$contentRight = $this->getData(['page', $this->getUrl(0), 'barRight']) ? $this->getPage($this->getData(['page', $this->getUrl(0), 'barRight']), common::$siteContent) : '';
$contentRight = $this->getData(['page', $this->getUrl(0), 'barRight']) ? $this->getPage($this->getData(['page', $this->getUrl(0), 'barRight']), self::$i18nContent) : '';
$inlineStyle[] = $this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barRight']), 'css']) === null ? '' : $this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barRight']), 'css']);
$inlineScript[] = $this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barRight']), 'js']) === null ? '' : $this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barRight']), 'js']);
$contentLeft = $this->getData(['page', $this->getUrl(0), 'barLeft']) ? $this->getPage($this->getData(['page', $this->getUrl(0), 'barLeft']), common::$siteContent) : '';
$contentLeft = $this->getData(['page', $this->getUrl(0), 'barLeft']) ? $this->getPage($this->getData(['page', $this->getUrl(0), 'barLeft']), self::$i18nContent) : '';
$inlineStyle[] = $this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barLeft']), 'css']) === null ? '' : $this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barLeft']), 'css']);
$inlineScript[] = $this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barLeft']), 'js']) === null ? '' : $this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barLeft']), 'js']);
@ -563,7 +652,7 @@ class core extends common
$this->addOutput([
'title' => $title,
'content' => $this->getPage($this->getUrl(0), common::$siteContent),
'content' => $this->getPage($this->getUrl(0), self::$i18nContent),
'metaDescription' => $this->getData(['page', $this->getUrl(0), 'metaDescription']),
'metaTitle' => $this->getData(['page', $this->getUrl(0), 'metaTitle']),
'typeMenu' => $this->getData(['page', $this->getUrl(0), 'typeMenu']),
@ -589,7 +678,7 @@ class core extends common
: $this->getData(['page', $this->getUrl(0), 'metaDescription']);
// Importe le CSS de la page principale
$pageContent = $this->getPage($this->getUrl(0), common::$siteContent);
$pageContent = $this->getPage($this->getUrl(0), self::$i18nContent);
$this->addOutput([
'title' => $title,
@ -634,8 +723,8 @@ class core extends common
$output = $module->output;
// Check le groupe de l'utilisateur
if (
($module::$actions[$action] === common::GROUP_VISITOR
or ($this->isConnected() === true
($module::$actions[$action] === self::GROUP_VISITOR
or ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
and $this->getUser('group') >= $module::$actions[$action]
and $this->getUser('permission', $moduleId, $action)
)
@ -647,10 +736,10 @@ class core extends common
foreach ($_POST as $postId => $postValue) {
if (is_array($postValue)) {
foreach ($postValue as $subPostId => $subPostValue) {
common::$inputBefore[$postId . '_' . $subPostId] = $subPostValue;
self::$inputBefore[$postId . '_' . $subPostId] = $subPostValue;
}
} else {
common::$inputBefore[$postId] = $postValue;
self::$inputBefore[$postId] = $postValue;
}
}
}
@ -690,9 +779,9 @@ class core extends common
// Contenu par vue
elseif ($output['view']) {
// Chemin en fonction d'un module du coeur ou d'un module
$modulePath = in_array($moduleId, common::$coreModuleIds) ? 'core/' : '';
$modulePath = in_array($moduleId, self::$coreModuleIds) ? 'core/' : '';
// CSS
$stylePath = $modulePath . common::MODULE_DIR . $moduleId . '/view/' . $output['view'] . '/' . $output['view'] . '.css';
$stylePath = $modulePath . self::MODULE_DIR . $moduleId . '/view/' . $output['view'] . '/' . $output['view'] . '.css';
if (file_exists($stylePath)) {
$this->addOutput([
'style' => file_get_contents($stylePath)
@ -705,7 +794,7 @@ class core extends common
}
// JS
$scriptPath = $modulePath . common::MODULE_DIR . $moduleId . '/view/' . $output['view'] . '/' . $output['view'] . '.js.php';
$scriptPath = $modulePath . self::MODULE_DIR . $moduleId . '/view/' . $output['view'] . '/' . $output['view'] . '.js.php';
if (file_exists($scriptPath)) {
ob_start();
include $scriptPath;
@ -714,7 +803,7 @@ class core extends common
]);
}
// Vue
$viewPath = $modulePath . common::MODULE_DIR . $moduleId . '/view/' . $output['view'] . '/' . $output['view'] . '.php';
$viewPath = $modulePath . self::MODULE_DIR . $moduleId . '/view/' . $output['view'] . '/' . $output['view'] . '.php';
if (file_exists($viewPath)) {
ob_start();
include $viewPath;
@ -723,7 +812,7 @@ class core extends common
$this->addOutput([
'content' => ob_get_clean() . ($output['showPageContent'] ? $pageContent : '')
]);
} elseif ($modpos === 'free' && strstr($pageContent, '[MODULE]')) {
} else if ($modpos === 'free') {
if (strstr($pageContent, '[MODULE]', true) === false) {
$begin = strstr($pageContent, '[]', true);
} else {
@ -783,7 +872,7 @@ class core extends common
if ($accessInfo['userName']) {
$this->addOutput([
'title' => 'Accès verrouillé',
'content' => template::speech('<p>' . sprintf(helper::translate('La page %s est ouverte par l\'utilisateur %s</p><p><a style="color:inherit" href="javascript:history.back()">%s</a></p>'), $accessInfo['pageId'], $accessInfo['userName'], helper::translate('Retour')))
'content' => template::speech(sprintf(helper::translate('La page %s est ouverte par l\'utilisateur %s'), $accessInfo['pageId'], $accessInfo['userName']))
]);
} else {
@ -795,35 +884,12 @@ class core extends common
} else {
$this->addOutput([
'title' => 'Accès interdit',
'content' => template::speech('<p>' . helper::translate('Vous n\'êtes pas autorisé à consulter cette page (erreur 403)') . '</p><p><a style="color:inherit" href="javascript:history.back()">' . helper::translate('Retour') . '</a></p>')
'content' => template::speech(helper::translate('Vous n\'êtes pas autorisé à consulter cette page (erreur 403)'))
]);
}
}
} elseif ($this->output['content'] === '') {
http_response_code(404);
// Pour éviter une 404, bascule dans l'espace correct si la page existe dans cette langue.
// Parcourir les espaces
foreach (common::$languages as $langId => $value) {
;
if (
// l'espace existe
is_dir(common::DATA_DIR . $langId) &&
file_exists(common::DATA_DIR . $langId . '/page.json')
) {
// Lire les données des pages
$pagesId = json_decode(file_get_contents(common::DATA_DIR . $langId . '/page.json'), true);
if (
// La page existe
is_array($pagesId['page']) &&
array_key_exists($this->getUrl(0), $pagesId['page'])
) {
// Basculer
$_SESSION['ZWII_SITE_CONTENT'] = $langId;
header('Refresh:0; url=' . helper::baseUrl() . $this->getUrl());
exit();
}
}
}
if (
$this->getData(['locale', 'page404']) !== 'none'
and $this->getData(['page', $this->getData(['locale', 'page404'])])
@ -832,7 +898,7 @@ class core extends common
} else {
$this->addOutput([
'title' => 'Page indisponible',
'content' => template::speech('<p>' . helper::translate('La page demandée n\'existe pas ou est introuvable (erreur 404)') . '</p><p><a style="color:inherit" href="javascript:history.back()">' . helper::translate('Retour') . '</a></p>')
'content' => template::speech(helper::translate('La page demandée n\'existe pas ou est introuvable (erreur 404)'))
]);
}
}
@ -855,25 +921,25 @@ class core extends common
}
switch ($this->output['display']) {
// Layout brut
case common::DISPLAY_RAW:
case self::DISPLAY_RAW:
echo $this->output['content'];
break;
// Layout vide
case common::DISPLAY_LAYOUT_BLANK:
case self::DISPLAY_LAYOUT_BLANK:
require 'core/layout/blank.php';
break;
// Affichage en JSON
case common::DISPLAY_JSON:
case self::DISPLAY_JSON:
header('Content-Type: application/json');
echo json_encode($this->output['content']);
break;
// RSS feed
case common::DISPLAY_RSS:
case self::DISPLAY_RSS:
header('Content-type: application/rss+xml; charset=UTF-8');
echo $this->output['content'];
break;
// Layout allégé
case common::DISPLAY_LAYOUT_LIGHT:
case self::DISPLAY_LAYOUT_LIGHT:
ob_start();
require 'core/layout/light.php';
$content = ob_get_clean();
@ -884,7 +950,7 @@ class core extends common
echo $content;
break;
// Layout principal
case common::DISPLAY_LAYOUT_MAIN:
case self::DISPLAY_LAYOUT_MAIN:
ob_start();
require 'core/layout/main.php';
$content = ob_get_clean();

View File

@ -128,17 +128,7 @@ class SitemapGenerator
*/
private $sampleRobotsLines = [
"User-agent: *",
"Disallow: /",
"User-agent: Googlebot",
"Allow: /",
"User-agent: bingbot",
"Allow: /",
"User-agent: Slurp",
"Allow: /",
"User-agent: DuckDuckBot",
"Allow: /",
"User-agent: Baiduspider",
"Allow: /"
];
/**
* @var array list of valid changefreq values according to the spec

View File

@ -224,7 +224,7 @@ class template
* Crée un champ date
* @param string $nameId Nom et id du champ
* @param array $attributes Attributs ($key => $value)
* @param string type date seule ; time heure seule ; datetime-local (jour et heure)
* @param string type date time datetime-local month week
* @return string
*/
public static function date($nameId, array $attributes = [])
@ -244,32 +244,17 @@ class template
'placeholder' => '',
'readonly' => false,
'value' => '',
'type' => 'date',
'type'=> 'date',
], $attributes);
// Traduction de l'aide et de l'étiquette
$attributes['label'] = helper::translate($attributes['label']);
$attributes['help'] = helper::translate($attributes['help']);
//$attributes['placeholder'] = helper::translate($attributes['placeholder']);
// Filtre selon le type
switch ($attributes['type']) {
case 'datetime-local':
$filter = helper::FILTER_TIMESTAMP;
break;
case 'date':
$filter = helper::FILTER_DATE; // Pour générer une valeur uniquement sur la date
break;
case 'time':
$filter = helper::FILTER_TIME; // Pour générer une valeur uniquement sur l'heure
break;
default:
$filter = null; // pas de filtre pour month and year
break;
}
// Sauvegarde des données en cas d'erreur
if ($attributes['before'] and array_key_exists($attributes['id'], common::$inputBefore)) {
$attributes['value'] = common::$inputBefore[$attributes['id']];
} else {
$attributes['value'] = ($attributes['value'] ? helper::filter($attributes['value'], $filter) : '');
$attributes['value'] = ($attributes['value'] ? helper::filter($attributes['value'], helper::FILTER_TIMESTAMP) : '');
}
// Début du wrapper
$html = '<div id="' . $attributes['id'] . 'Wrapper" class="inputWrapper ' . $attributes['classWrapper'] . '">';
@ -325,7 +310,6 @@ class template
'name' => $nameId,
'type' => 2,
'value' => '',
'folder' => '',
'language' => 'fr_FR'
], $attributes);
// Traduction de l'aide et de l'étiquette
@ -368,15 +352,13 @@ class template
'&field_id=' . $attributes['id'] .
'&type=' . $attributes['type'] .
'&akey=' . md5_file(core::DATA_DIR . 'core.json') .
// Ajoute le nom du dossier si la variable est passée
(!empty($attributes['folder']) ? '&fldr=' . $attributes['folder'] : '') .
($attributes['extensions'] ? '&extensions=' . $attributes['extensions'] : '')
. '"
class="inputFile %s %s"
%s
data-lity
>
' . self::ico('upload-cloud', ['margin' => 'right']) . '
' . self::ico('upload', ['margin' => 'right']) . '
<span class="inputFileLabel"></span>
</a>',
$attributes['class'],
@ -512,8 +494,8 @@ class template
$lang = $langId;
break;
case 'selected':
if (isset($_SESSION['ZWII_SITE_CONTENT'])) {
$lang = $_SESSION['ZWII_SITE_CONTENT'];
if (isset($_SESSION['ZWII_CONTENT'])) {
$lang = $_SESSION['ZWII_CONTENT'];
} else {
$lang = 'fr_FR';
}
@ -704,8 +686,7 @@ class template
'label' => '',
'name' => $nameId,
'selected' => '',
'font' => [],
'multiple' => ''
'font' => []
], $attributes);
// Traduction de l'aide et de l'étiquette
$attributes['label'] = helper::translate($attributes['label']);
@ -734,11 +715,6 @@ class template
$attributes['class'] .= ' notice';
}
$html .= self::notice($attributes['id'], $notice);
// Attribut multiple
if ($attributes['multiple'] === true) {
echo "ppp";
$attributes['multiple'] = 'multiple';
}
// Début sélection
$html .= sprintf(
'<select %s>',
@ -768,7 +744,6 @@ class template
return $html;
}
/**
* Crée une bulle de dialogue
* @param string $text Texte de la bulle
@ -923,7 +898,7 @@ class template
$html .= self::notice($attributes['id'], $notice);
// Texte
$html .= sprintf(
'<input type="' . $attributes['type'] . '" %s>',
'<input type="' . $attributes['type']. '" %s>',
helper::sprintAttributes($attributes)
);
// Fin du wrapper

View File

@ -6,7 +6,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
@ -216,14 +216,12 @@ core.start = function () {
// Variables des cookies
var getUrl = window.location;
var domain = "domain=" + getUrl.hostname + ";";
var basePath = getUrl.pathname.substring(0, getUrl.pathname.lastIndexOf('/') + 1);
var path = "path=" + basePath + ";";
var e = new Date();
e.setFullYear(e.getFullYear() + 1);
var expires = "expires=" + e.toUTCString() + ";";
var expires = "expires=" + e.toUTCString();
// Stocke le cookie d'acceptation
document.cookie = "ZWII_COOKIE_CONSENT=true; samesite=lax; " + domain + path + expires;
document.cookie = "ZWII_COOKIE_CONSENT=true;samesite=strict;" + domain + expires;
});
@ -293,14 +291,14 @@ core.start = function () {
});
// Confirmation de mise à jour
$("#barUpdate").on("click", function () {
message = "<?php echo helper::translate('Mise à jour') . ' ?';?>";
message = "<?php echo helper::translate('Mettre à jour') . ' ?';?>";
return core.confirm(message, function () {
$(location).attr("href", $("#barUpdate").attr("href"));
});
});
// Confirmation de déconnexion
$("#barLogout").on("click", function () {
message = "<?php echo helper::translate('Se déconnecter') . ' ?';?>";
message = "<?php echo helper::translate('Se déconnecter') . '?';?>";
return core.confirm(message, function () {
$(location).attr("href", $("#barLogout").attr("href"));
});
@ -464,7 +462,7 @@ $(document).ready(function () {
/**
* Chargement paresseux des images et des iframes
*/
$("img").attr("loading", "lazy");
$("img,picture,iframe").attr("loading", "lazy");
/**
* Effet accordéon
@ -534,7 +532,7 @@ $(document).ready(function () {
var langSelected = $(this).val();
var langSelected = langSelected.split("/");
// Lit le cookie de langue
var langSession = "<?php echo isset($_SESSION['ZWII_SITE_CONTENT']) ? $_SESSION['ZWII_SITE_CONTENT'] : '';?>";
var langSession = "<?php echo isset($_SESSION['ZWII_CONTENT']) ? $_SESSION['ZWII_CONTENT'] : '';?>";
// Découpe l'URL pour exclure le changement de page avec le thème
var url = window.location;
var currentUrl = url.href.split("/");

View File

@ -8,7 +8,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
@ -51,7 +51,7 @@ class common
const ACCESS_TIMER = 1800;
// Numéro de version
const ZWII_VERSION = '13.4.00.test4';
const ZWII_VERSION = '13.0.08';
// URL autoupdate
const ZWII_UPDATE_URL = 'https://forge.chapril.org/ZwiiCMS-Team/cms-update/raw/branch/master/';
@ -60,18 +60,6 @@ class common
// Valeurs possibles multiple de 10, 10 autorise 9 profils, 100 autorise 99 profils
const MAX_PROFILS = 10;
const MAX_FILE_WRITE_ATTEMPTS = 5;
/**
* Nombre maximal de tentatives d'encodage JSON
*/
const MAX_JSON_ENCODE_ATTEMPTS = 3;
/**
* Temps d'attente entre les tentatives en secondes
*/
const RETRY_DELAY_SECONDS = 1;
public static $actions = [];
public static $coreModuleIds = [
@ -146,7 +134,7 @@ class common
// 'codemirror', // Désactivé par défaut
'tippy',
'zwiico',
//'imagemap',
'imagemap',
'simplelightbox'
],
'view' => ''
@ -182,7 +170,7 @@ class common
// Langue de l'interface sélectionnée
public static $i18nUI = 'fr_FR';
// Langues de contenu
public static $siteContent = 'fr_FR';
public static $i18nContent = 'fr_FR';
public static $languages = [
'az_AZ' => 'Azərbaycan dili',
'bg_BG' => 'български език',
@ -340,34 +328,36 @@ class common
$this->input['_COOKIE'] = $_COOKIE;
}
// Extraction de la sesion
// $this->input['_SESSION'] = $_SESSION;
// Déterminer la langue du contenu du site
if (isset($_SESSION['ZWII_SITE_CONTENT'])) {
if (isset($_SESSION['ZWII_CONTENT'])) {
// Déterminé par la session présente
self::$siteContent = $_SESSION['ZWII_SITE_CONTENT'];
self::$i18nContent = $_SESSION['ZWII_CONTENT'];
} else {
// Détermine la langue par défaut
foreach (self::$languages as $key => $value) {
if (file_exists(self::DATA_DIR . $key . '/.default')) {
self::$siteContent = $key;
$_SESSION['ZWII_SITE_CONTENT'] = $key;
self::$i18nContent = $key;
$_SESSION['ZWII_CONTENT'] = $key;
break;
}
}
}
\setlocale(LC_ALL, self::$siteContent . '.UTF8');
\setlocale(LC_ALL, self::$i18nContent . '.UTF8');
// Instanciation de la classe des entrées / sorties
$this->jsonDB(self::$siteContent);
$this->jsonDB(self::$i18nContent);
// Installation fraîche, initialisation des modules
if ($this->user === []) {
foreach ($this->dataFiles as $stageId => $item) {
$folder = $this->dataPath($stageId, self::$siteContent);
$folder = $this->dataPath($stageId, self::$i18nContent);
if (
file_exists($folder . $stageId . '.json') === false
) {
$this->initData($stageId, self::$siteContent);
$this->initData($stageId, self::$i18nContent);
common::$coreNotices[] = $stageId;
}
}
@ -602,47 +592,9 @@ class common
public function setPage($page, $value, $lang)
{
return $this->secure_file_put_contents(self::DATA_DIR . $lang . '/content/' . $page . '.html', $value);
return file_put_contents(self::DATA_DIR . $lang . '/content/' . $page . '.html', $value);
}
/**
* Écrit les données dans un fichier avec plusieurs tentatives d'écriture et verrouillage
*
* @param string $filename Le nom du fichier
* @param string $data Les données à écrire dans le fichier
* @param int $flags Les drapeaux optionnels à passer à la fonction $this->secure_file_put_contents
* @return bool True si l'écriture a réussi, sinon false
*/
function secure_file_put_contents($filename, $data, $flags = 0)
{
// Initialise le compteur de tentatives
$attempts = 0;
// Convertit les données en chaîne de caractères
$serialized_data = serialize($data);
// Vérifie la longueur des données
$data_length = strlen($serialized_data);
// Effectue jusqu'à 5 tentatives d'écriture
while ($attempts < 5) {
// Essaye d'écrire les données dans le fichier avec verrouillage exclusif
$write_result = file_put_contents($filename, $data, LOCK_EX | $flags);
// Vérifie si l'écriture a réussi
if ($write_result !== false && $write_result === $data_length) {
// Sort de la boucle si l'écriture a réussi
return true;
}
// Incrémente le compteur de tentatives
$attempts++;
}
// Échec de l'écriture après plusieurs tentatives
return false;
}
/**
@ -768,7 +720,7 @@ class common
$this->getData(['page', $pageId, 'parentPageId']) === ""
// Ignore les pages dont l'utilisateur n'a pas accès
and ($this->getData(['page', $pageId, 'group']) === self::GROUP_VISITOR
or ($this->isConnected() === true
or ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
//and $this->getUser('group') >= $this->getData(['page', $pageId, 'group'])
// Modification qui tient compte du profil de la page
and ($this->getUser('group') * self::MAX_PROFILS + $this->getUser('profil')) >= ($this->getData(['page', $pageId, 'group']) * self::MAX_PROFILS + $this->getData(['page', $pageId, 'profil']))
@ -787,21 +739,21 @@ class common
}
// Enfants
foreach ($pages as $pageId => $pagePosition) {
if (
// Page parent
$parentId = $this->getData(['page', $pageId, 'parentPageId'])
// Ignore les pages dont l'utilisateur n'a pas accès
and (
(
$this->getData(['page', $pageId, 'group']) === self::GROUP_VISITOR
and
$this->getData(['page', $parentId, 'group']) === self::GROUP_VISITOR
($this->getData(['page', $pageId, 'group']) === self::GROUP_VISITOR
and $this->getData(['page', $parentId, 'group']) === self::GROUP_VISITOR
)
or (
$this->isConnected() === true
and
$this->getUser('group') * self::MAX_PROFILS + $this->getUser('profil')) >= ($this->getData(['page', $pageId, 'group']) * self::MAX_PROFILS + $this->getData(['page', $pageId, 'profil'])
or ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
//and $this->getUser('group') >= $this->getData(['page', $parentId, 'group'])
//and $this->getUser('group') >= $this->getData(['page', $pageId, 'group'])
// Modification qui tient compte du profil de la page
and ($this->getUser('group') * self::MAX_PROFILS + $this->getUser('profil')) >= ($this->getData(['page', $this->$parentId, 'group']) * self::MAX_PROFILS + $this->getData(['page', $this->$parentId, 'profil']))
and ($this->getUser('group') * self::MAX_PROFILS + $this->getUser('profil')) >= ($this->getData(['page', $this->$pageId, 'group']) * self::MAX_PROFILS + $this->getData(['page', $pageId, 'profil']))
)
)
@ -834,7 +786,7 @@ class common
// Boucler sur les enfants et récupérer le tableau children avec la liste des enfants
foreach ($childIds as $childId) {
$children[] = [
'title' => '↳' . html_entity_decode($this->getData(['page', $childId, 'title']), ENT_QUOTES),
'title' => '↳' . html_entity_decode($this->getData(['page', $childId, 'shortTitle']), ENT_QUOTES),
'value' => $rewrite . $childId
];
}
@ -842,18 +794,18 @@ class common
if (empty($childIds)) {
// Pas d'enfant, uniquement l'entrée du parent
$parents[] = [
'title' => html_entity_decode($this->getData(['page', $parentId, 'title']), ENT_QUOTES),
'title' => html_entity_decode($this->getData(['page', $parentId, 'shortTitle']), ENT_QUOTES),
'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),
'title' => html_entity_decode($this->getData(['page', $parentId, 'shortTitle']), ENT_QUOTES),
'value' => $rewrite . $parentId
]);
// puis on ajoute les enfants au parent
$parents[] = [
'title' => html_entity_decode($this->getData(['page', $parentId, 'title']), ENT_QUOTES),
'title' => html_entity_decode($this->getData(['page', $parentId, 'shortTitle']), ENT_QUOTES),
'value' => $rewrite . $parentId,
'menu' => $children
];
@ -986,17 +938,19 @@ class common
}
/**
* Retourne les permissions de l'utilisateur connecté
* Retourne les permission de l'utilisateur connecté
* @param int $key Clé de la valeur du groupe
* @return string|null
*/
public function getPermission($key1, $key2 = null)
{
// User n'existe pas
// if (is_array($this->user) === false) {
// return false;
// Administrateur, toutes les permissions
if ($this->getUser('group') === self::GROUP_ADMIN) {
return true;
} elseif ($this->getUser('group') <= self::GROUP_VISITOR) { // Groupe sans autorisation
} elseif ($this->getUser('group') < 1) { // Groupe sans autorisation
return false;
} elseif (
// Groupe avec profil, consultation des autorisations sur deux clés
@ -1016,28 +970,12 @@ class common
) {
return $this->getData(['profil', $this->user['group'], $this->user['profil'], $key1]);
} else {
// Une permission non spécifiée dans le profil est autorisée selon la valeur de $actions
if (class_exists($key1)) {
$module = new $key1;
if (array_key_exists($key2, $module::$actions)) {
return $this->getUser('group') >= $module::$actions[$key2];
}
}
return false;
// Une permission non spécifiée dans le profil est autorisée par défaut pour le fonctionnement de $action
return true;
}
}
/**
* @return bool l'utilisateur est connecté true sinon false
*/
public function isConnected() {
return (
!empty($this->getUser('authKey'))
&&
$this->getUser('authKey') === $this->getInput('ZWII_AUTH_KEY'));
}
/**
* Check qu'une valeur est transmise par la méthode _POST
* @return bool
@ -1129,14 +1067,13 @@ class common
}
// Articles du blog
if (
$this->getData(['page', $parentPageId, 'moduleId']) === 'blog'
&& !empty($this->getData(['module', $parentPageId]))
&& $this->getData(['module', $parentPageId, 'posts'])
$this->getData(['page', $parentPageId, 'moduleId']) === 'blog' &&
!empty($this->getData(['module', $parentPageId]))
) {
foreach ($this->getData(['module', $parentPageId, 'posts']) as $articleId => $article) {
if ($this->getData(['module', $parentPageId, 'posts', $articleId, 'state']) === true) {
$date = $this->getData(['module', $parentPageId, 'posts', $articleId, 'publishedOn']);
$sitemap->addUrl('/' . $parentPageId . '/' . $articleId, DateTime::createFromFormat('U', $date));
$sitemap->addUrl('/' . $parentPageId . '/' . $articleId, new DateTime("@{$date}", new DateTimeZone($timezone)));
}
}
}
@ -1183,7 +1120,7 @@ class common
}
$sitemap->updateRobots();
} else {
$this->secure_file_put_contents('robots.txt', 'User-agent: *' . PHP_EOL . 'Disallow: /');
file_put_contents('robots.txt', 'User-agent: *' . PHP_EOL . 'Disallow: /');
}
// Submit your sitemaps to Google, Yahoo, Bing and Ask.com
@ -1227,10 +1164,11 @@ class common
$source_image = imagecreatefromwebp($src);
break;
case 'avif':
$source_image = imagecreatefromavif($src);
$source_image = function_exists('imagecreatefromavif') ? imagecreatefromavif($src) : null;
break;
}
// Image valide
if (is_object($source_image)) {
if ($source_image) {
$width = imagesx($source_image);
$height = imagesy($source_image);
/* find the "desired height" of this thumbnail, relative to the desired width */
@ -1247,9 +1185,9 @@ class common
return (imagepng($virtual_image, $dest));
case 'image/gif':
return (imagegif($virtual_image, $dest));
case 'image/webp':
case 'webp':
return (imagewebp($virtual_image, $dest));
case 'image/avif':
case 'avif':
return (imageavif($virtual_image, $dest));
}
} else {
@ -1263,6 +1201,7 @@ class common
* @param string|array $to Destinataire
* @param string $subject Sujet
* @param string $content Contenu
* @return bool
*/
public function sendMail($to, $subject, $content, $replyTo = null, $from = 'no-reply@localhost')
{
@ -1453,13 +1392,13 @@ class common
public function saveLog($message = '')
{
// Journalisation
$dataLog = helper::dateUTF8('%Y%m%d', time(), self::$i18nUI) . ';' . helper::dateUTF8('%H:%M', time(), self::$i18nUI). ';';
$dataLog = helper::dateUTF8('%Y %m %d', time(), self::$i18nContent) . ' - ' . helper::dateUTF8('%H:%M', time(), self::$i18nContent);
$dataLog .= helper::getIp($this->getData(['config', 'connect', 'anonymousIp'])) . ';';
$dataLog .= empty($this->getUser('id')) ? 'visitor;' : $this->getUser('id') . ';';
$dataLog .= $message ? $this->getUrl() . ';' . $message : $this->getUrl();
$dataLog .= PHP_EOL;
if ($this->getData(['config', 'connect', 'log'])) {
$this->secure_file_put_contents(self::DATA_DIR . 'journal.log', $dataLog, FILE_APPEND);
file_put_contents(self::DATA_DIR . 'journal.log', $dataLog, FILE_APPEND);
}
}
@ -1471,12 +1410,16 @@ class common
switch ($this->getData(['user', $userId, 'signature'])) {
case 1:
return $userId;
break;
case 2:
return $this->getData(['user', $userId, 'pseudo']);
break;
case 3:
return $this->getData(['user', $userId, 'firstname']) . ' ' . $this->getData(['user', $userId, 'lastname']);
break;
case 4:
return $this->getData(['user', $userId, 'lastname']) . ' ' . $this->getData(['user', $userId, 'firstname']);
break;
default:
return $this->getData(['user', $userId, 'firstname']);
}

View File

@ -135,7 +135,7 @@ if ($this->getData(['core', 'dataVersion']) < 10200) {
}
// Créer les en-têtes du journal
$d = 'Date;Heure;IP;Id;Action' . PHP_EOL;
$this->secure_file_put_contents(self::DATA_DIR . 'journal.log', $d);
file_put_contents(self::DATA_DIR . 'journal.log', $d);
// Init préservation htaccess
$this->setData(['config', 'autoUpdateHtaccess', false]);
// Options de barre de membre simple
@ -448,8 +448,8 @@ if ($this->getData(['core', 'dataVersion']) < 11000) {
// Liste des pages dans pageList
$hierarchy = array();
// Creation du contenu de la page
if (!is_dir(self::DATA_DIR . self::$siteContent . '/content')) {
mkdir(self::DATA_DIR . self::$siteContent . '/content', 0755);
if (!is_dir(self::DATA_DIR . self::$i18nContent . '/content')) {
mkdir(self::DATA_DIR . self::$i18nContent . '/content', 0755);
}
foreach ($this->getHierarchy() as $parentKey => $parentValue) {
$hierarchy[] = $parentKey;
@ -459,7 +459,7 @@ if ($this->getData(['core', 'dataVersion']) < 11000) {
}
foreach ($hierarchy as $parentKey => $parent) {
$content = $this->getData(['page', $parent, 'content']);
//$this->secure_file_put_contents(self::DATA_DIR . self::$siteContent . '/content/' . $parent . '.html', $content);
//file_put_contents(self::DATA_DIR . self::$i18nContent . '/content/' . $parent . '.html', $content);
$this->setPage($parent, $content, 'fr');
$this->setData(['page', $parent, 'content', $parent . '.html']);
}
@ -574,7 +574,7 @@ if ($this->getData(['core', 'dataVersion']) < 11203) {
$success = false;
// Boucler sur les pages
foreach ($this->getHierarchy() as $parentId => $childIds) {
$content = $this->getPage($parentId, self::$siteContent);
$content = $this->getPage($parentId, self::$i18nContent);
$titre = $this->getData(['page', $parentId, 'title']);
$content = $titre . ' ' . $content;
$replace = str_replace('href="' . $old, 'href="' . $new, stripslashes($content), $c1);
@ -582,17 +582,17 @@ if ($this->getData(['core', 'dataVersion']) < 11203) {
if ($c1 > 0 || $c2 > 0) {
$success = true;
$this->setPage($parentId, $replace, self::$siteContent);
$this->setPage($parentId, $replace, self::$i18nContent);
$c3 += $c1 + $c2;
}
foreach ($childIds as $childId) {
$content = $this->getPage($childId, self::$siteContent);
$content = $this->getPage($childId, self::$i18nContent);
$content = $titre . ' ' . $content;
$replace = str_replace('href="' . $old, 'href="' . $new, stripslashes($content), $c1);
$replace = str_replace('src="' . $old, 'src="' . $new, stripslashes($replace), $c2);
if ($c1 > 0 || $c2 > 0) {
$success = true;
$this->setPage($childId, $replace, self::$siteContent);
$this->setPage($childId, $replace, self::$i18nContent);
$c3 += $c1 + $c2;
}
}
@ -982,7 +982,7 @@ if ($this->getData(['core', 'dataVersion']) < 12309) {
$d = json_decode(file_get_contents(self::DATA_DIR . $key . '/locale.json'), true);
$d = array_merge($d['locale'], ['poweredPageLabel' => 'Motorisé par']);
$t['locale'] = $d;
$this->secure_file_put_contents(self::DATA_DIR . $key . '/locale.json', $t);
file_put_contents(self::DATA_DIR . $key . '/locale.json', json_encode($t));
}
}
@ -1053,7 +1053,7 @@ if ($this->getData(['core', 'dataVersion']) < 13000) {
}
// Mise à jour des pages, le profil est mis à 0 pour les groupes sans profil et 1 pour es groupes avec profil
$currentlanguage = self::$siteContent;
$currentlanguage = self::$i18nContent;
foreach ($languages as $langId) {
foreach ($hierarchy as $parentKey => $parent) {
@ -1068,7 +1068,7 @@ if ($this->getData(['core', 'dataVersion']) < 13000) {
}
}
}
$_SESSION['ZWII_SITE_CONTENT'] = $currentlanguage;
$_SESSION['ZWII_CONTENT'] = $currentlanguage;
// Supprime la clé OpenOgraph
$this->deleteData(['config', 'seo', 'keyApi']);
@ -1100,19 +1100,6 @@ if ($this->getData(['core', 'dataVersion']) < 13005) {
if ($this->getData(['admin', 'backgroundColorButtonHelp']) === null) {
$this->setData(['admin', 'backgroundColorButtonHelp', 'rgba(255, 153, 0, 1)']);
}
// Mise à jour
$this->setData(['core', 'dataVersion', 13005]);
}
// Version 13.1.01
if ($this->getData(['core', 'dataVersion']) < 13101) {
// Supprime le choix du thème à l'installation
if (is_dir('core/module/install/ressource/themes')) {
$this->deleteDir('core/module/install/ressource/themes') ;
}
// Mise à jour
$this->setData(['core', 'dataVersion', 13101]);
}

View File

@ -6,7 +6,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html prefix="og: http://ogp.me/ns#" lang="<?php echo substr(self::$siteContent, 0, 2); ?>">
<html prefix="og: http://ogp.me/ns#" lang="<?php echo substr(self::$i18nContent, 0, 2); ?>">
<head>
<meta charset="UTF-8">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
@ -12,9 +12,6 @@
<?php $layout->showVendor(); ?>
<?php $layout->showStyle(); ?>
<?php $layout->showFonts(); ?>
<?php if (file_exists(self::DATA_DIR . 'font/font.css')): ?>
<link rel="stylesheet" href="<?php echo helper::baseUrl(false) . self::DATA_DIR; ?>font/font.css?<?php echo md5_file(self::DATA_DIR . 'font/font.css'); ?>">
<?php endif; ?>
<link rel="stylesheet" href="<?php echo helper::baseUrl(false); ?>core/layout/common.css">
<link rel="stylesheet" href="<?php echo helper::baseUrl(false); ?>core/layout/blank.css">
<link rel="stylesheet" href="<?php echo helper::baseUrl(false) . self::DATA_DIR; ?>theme.css?<?php echo md5_file(self::DATA_DIR.'theme.css'); ?>">

View File

@ -6,7 +6,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
@ -1003,10 +1003,9 @@ footer #footerSocials .zwiico-twitch:hover {
max-width: 500px;
width: 100%;
margin: 16px auto;
text-align: center;
text-align: left;
border-radius: 2px;
transition: background-color .3s ease-out;
z-index: 100;
}
.speechBubble:before {
@ -1819,7 +1818,4 @@ th.col12 {
.bannerDisplay {
display: none;
}
header {
background-size: cover !important;
}
}

View File

@ -6,7 +6,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html prefix="og: http://ogp.me/ns#" lang="<?php echo substr(self::$siteContent, 0, 2); ?>">
<html prefix="og: http://ogp.me/ns#" lang="<?php echo substr(self::$i18nContent, 0, 2); ?>">
<head>
<meta charset="UTF-8">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
@ -12,9 +12,6 @@
<?php $layout->showVendor(); ?>
<?php $layout->showStyle(); ?>
<?php $layout->showFonts(); ?>
<?php if (file_exists(self::DATA_DIR . 'font/font.css')): ?>
<link rel="stylesheet" href="<?php echo helper::baseUrl(false) . self::DATA_DIR; ?>font/font.css?<?php echo md5_file(self::DATA_DIR . 'font/font.css'); ?>">
<?php endif; ?>
<link rel="stylesheet" href="<?php echo helper::baseUrl(false); ?>core/layout/common.css">
<link rel="stylesheet" href="<?php echo helper::baseUrl(false); ?>core/layout/light.css">
<link rel="stylesheet" href="<?php echo helper::baseUrl(false) . self::DATA_DIR; ?>theme.css?<?php echo md5_file(self::DATA_DIR.'theme.css'); ?>">

View File

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="<?php echo substr(self::$siteContent, 0, 2);?>">
<html xmlns="http://www.w3.org/1999/xhtml" lang="<?php echo substr(self::$i18nContent, 0, 2);?>">
<head>
<meta charset="UTF-8">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">

View File

@ -1,6 +1,5 @@
<!DOCTYPE html>
<html prefix="og: http://ogp.me/ns#" lang="<?php echo substr(self::$siteContent, 0, 2); ?>">
<html prefix="og: http://ogp.me/ns#" lang="<?php echo substr(self::$i18nContent, 0, 2); ?>">
<head>
<meta charset="UTF-8">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
@ -14,23 +13,15 @@
<?php $layout->showFavicon(); ?>
<?php $layout->showVendor(); ?>
<?php $layout->showFonts(); ?>
<?php if (file_exists(self::DATA_DIR . 'font/font.css')): ?>
<link rel="stylesheet" href="<?php echo helper::baseUrl(false) . self::DATA_DIR; ?>font/font.css?<?php echo md5_file(self::DATA_DIR . 'font/font.css'); ?>">
<?php endif; ?>
<link rel="stylesheet"
href="<?php echo helper::baseUrl(false); ?>core/layout/common.css?<?php echo md5_file('core/layout/common.css'); ?>">
<link rel="stylesheet"
href="<?php echo helper::baseUrl(false) . self::DATA_DIR; ?>theme.css?<?php echo md5_file(self::DATA_DIR . 'theme.css'); ?>">
<link rel="stylesheet"
href="<?php echo helper::baseUrl(false) . self::DATA_DIR; ?>custom.css?<?php echo md5_file(self::DATA_DIR . 'custom.css'); ?>">
<link rel="stylesheet" href="<?php echo helper::baseUrl(false); ?>core/layout/common.css?<?php echo md5_file('core/layout/common.css'); ?>">
<link rel="stylesheet" href="<?php echo helper::baseUrl(false) . self::DATA_DIR; ?>theme.css?<?php echo md5_file(self::DATA_DIR . 'theme.css'); ?>">
<link rel="stylesheet" href="<?php echo helper::baseUrl(false) . self::DATA_DIR; ?>custom.css?<?php echo md5_file(self::DATA_DIR . 'custom.css'); ?>">
<!-- Détection RSS -->
<?php if (
($this->getData(['page', $this->getUrl(0), 'moduleId']) === 'blog'
<?php if (($this->getData(['page', $this->getUrl(0), 'moduleId']) === 'blog'
or $this->getData(['page', $this->getUrl(0), 'moduleId']) === 'news')
and $this->getData(['module', $this->getUrl(0), 'config', 'feeds']) === TRUE
): ?>
<link rel="alternate" type="application/rss+xml"
href="'<?php echo helper::baseUrl() . $this->getUrl(0) . '/rss'; ?>" title="fLUX rss">
) : ?>
<link rel="alternate" type="application/rss+xml" href="'<?php echo helper::baseUrl() . $this->getUrl(0) . '/rss'; ?>" title="fLUX rss">
<?php endif; ?>
<?php $layout->showStyle(); ?>
<?php $layout->showInlineStyle(); ?>
@ -39,22 +30,21 @@
include(self::DATA_DIR . 'head.inc.html');
} ?>
</head>
<body>
<!-- Barre d'administration -->
<?php if ($this->getUser('group') > self::GROUP_MEMBER): ?>
<?php if ($this->getUser('group') > self::GROUP_MEMBER) : ?>
<?php $layout->showBar(); ?>
<?php endif; ?>
<!-- Notifications -->
<?php $layout->showNotification(); ?>
<!-- Menu dans le fond du site avant la bannière -->
<?php if ($this->getData(['theme', 'menu', 'position']) === 'body-first' || $this->getData(['theme', 'menu', 'position']) === 'top'): ?>
<?php if ($this->getData(['theme', 'menu', 'position']) === 'body-first' || $this->getData(['theme', 'menu', 'position']) === 'top') : ?>
<!-- Détermine si le menu est fixe en haut de page lorsque l'utilisateur n'est pas connecté -->
<?php
if (
$this->getData(['theme', 'menu', 'position']) === 'top'
and $this->getData(['theme', 'menu', 'fixed']) === true
and $this->isConnected() === true
and $this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
and $this->getUser('group') > self::GROUP_MEMBER
) {
echo '<nav id="navfixedconnected" >';
@ -66,8 +56,7 @@
<div id="toggle">
<?php echo $this->getData(['theme', 'menu', 'burgerContent']) === 'title' ? '<div id="burgerText">' . $this->getData(['locale', 'title']) . '</div>' : ''; ?>
<?php echo $this->getData(['theme', 'menu', 'burgerContent']) === 'logo' ? '<div id="burgerLogo"><img src="' . helper::baseUrl(false) . self::FILE_DIR . 'source/' . $this->getData(['theme', 'menu', 'burgerLogo']) . '"></div>' : ''; ?>
<?php echo template::ico('menu', ['fontSize' => '2em']); ?>
</div>
<?php echo template::ico('menu', ['fontSize' => '2em']); ?></div>
<!-- fin du menu burger -->
<?php
$menuClass = $this->getData(['theme', 'menu', 'position']) === 'top' ? 'class="container-large"' : 'class="container"';
@ -79,7 +68,7 @@
</nav>
<?php endif; ?>
<!-- Bannière dans le fond du site -->
<?php if ($this->getData(['theme', 'header', 'position']) === 'body'): ?>
<?php if ($this->getData(['theme', 'header', 'position']) === 'body') : ?>
<?php echo ($this->getData(['theme', 'header', 'linkHomePage']) && $this->getData(['theme', 'header', 'feature']) === 'wallpaper') ? '<a href="' . helper::baseUrl(false) . '">' : ''; ?>
<?php
$headerClass = $this->getData(['theme', 'header', 'position']) === 'hide' ? 'displayNone' : '';
@ -87,19 +76,17 @@
$headerClass .= $this->getData(['theme', 'header', 'wide']) === 'none' ? '' : 'container';
?>
<header <?php echo empty($headerClass) ? '' : 'class="' . $headerClass . '"'; ?>>
<?php if ($this->getData(['theme', 'header', 'feature']) === 'wallpaper'): ?>
<?php if ($this->getData(['theme', 'header', 'feature']) === 'wallpaper') : ?>
<?php if (
$this->getData(['theme', 'header', 'textHide']) === false
// Affiche toujours le titre de la bannière pour l'édition du thème
or ($this->getUrl(0) === 'theme' and $this->getUrl(1) === 'header')
): ?>
<span id="themeHeaderTitle">
<?php echo $this->getData(['locale', 'title']); ?>
</span>
<?php else: ?>
) : ?>
<span id="themeHeaderTitle"><?php echo $this->getData(['locale', 'title']); ?></span>
<?php else : ?>
<span id="themeHeaderTitle">&nbsp;</span>
<?php endif; ?>
<?php else: ?>
<?php else : ?>
<div id="featureContent">
<?php echo $this->getData(['theme', 'header', 'featureContent']); ?>
</div>
@ -108,36 +95,31 @@
<?php echo ($this->getData(['theme', 'header', 'linkHomePage']) && $this->getData(['theme', 'header', 'feature']) === 'wallpaper') ? '</a>' : ''; ?>
<?php endif; ?>
<!-- Menu dans le fond du site après la bannière -->
<?php if ($this->getData(['theme', 'menu', 'position']) === 'body-second'): ?>
<?php if ($this->getData(['theme', 'menu', 'position']) === 'body-second') : ?>
<nav>
<!-- Menu burger -->
<div id="toggle">
<?php echo $this->getData(['theme', 'menu', 'burgerContent']) === 'title' ? '<div id="burgerText">' . $this->getData(['locale', 'title']) . '</div>' : ''; ?>
<?php echo $this->getData(['theme', 'menu', 'burgerContent']) === 'logo' ? '<div id="burgerLogo"><img src="' . helper::baseUrl(false) . self::FILE_DIR . 'source/' . $this->getData(['theme', 'menu', 'burgerLogo']) . '"></div>' : ''; ?>
<?php echo template::ico('menu', ['fontSize' => '2em']); ?>
</div>
<?php echo template::ico('menu', ['fontSize' => '2em']); ?></div>
<!-- fin du menu burger -->
<?php
$menuClass = $this->getData(['theme', 'menu', 'wide']) === 'none' ? 'class="container-large"' : 'class="container"';
?>
<div id="menu" <?php echo $menuClass; ?>>
<?php $layout->showMenu(); ?>
</div>
<?php $layout->showMenu(); ?></div>
</nav>
<?php endif; ?>
<!-- Site -->
<div id="site" class="container">
<?php if ($this->getData(['theme', 'menu', 'position']) === 'site-first'): ?>
<?php if ($this->getData(['theme', 'menu', 'position']) === 'site-first') : ?>
<!-- Menu dans le site avant la bannière -->
<nav>
<div id="toggle">
<?php echo $this->getData(['theme', 'menu', 'burgerContent']) === 'title' ? '<div id="burgerText">' . $this->getData(['locale', 'title']) . '</div>' : ''; ?>
<?php echo $this->getData(['theme', 'menu', 'burgerContent']) === 'logo' ? '<div id="burgerLogo"><img src="' . helper::baseUrl(false) . self::FILE_DIR . 'source/' . $this->getData(['theme', 'menu', 'burgerLogo']) . '"></div>' : ''; ?>
<?php echo template::ico('menu', ['fontSize' => '2em']); ?>
</div>
<div id="menu" class="container">
<?php $layout->showMenu(); ?>
</div>
<?php echo template::ico('menu', ['fontSize' => '2em']); ?></div>
<div id="menu" class="container"><?php $layout->showMenu(); ?></div>
</nav>
<?php endif; ?>
<?php if (
@ -146,7 +128,7 @@
or ($this->getData(['theme', 'header', 'position']) === 'hide'
and $this->getUrl(0) === 'theme'
)
): ?>
) : ?>
<!-- Bannière dans le site -->
<?php echo ($this->getData(['theme', 'header', 'linkHomePage']) && $this->getData(['theme', 'header', 'feature']) === 'wallpaper') ? '<a href="' . helper::baseUrl(false) . '">' : ''; ?>
<?php
@ -154,19 +136,17 @@
$headerClass .= $this->getData(['theme', 'header', 'tinyHidden']) ? ' bannerDisplay ' : '';
?>
<header <?php echo empty($headerClass) ? '' : 'class="' . $headerClass . '"'; ?>>
<?php if ($this->getData(['theme', 'header', 'feature']) === 'wallpaper'): ?>
<?php if ($this->getData(['theme', 'header', 'feature']) === 'wallpaper') : ?>
<?php if (
$this->getData(['theme', 'header', 'textHide']) === false
// Affiche toujours le titre de la bannière pour l'édition du thème
or ($this->getUrl(0) === 'theme' and $this->getUrl(1) === 'header')
): ?>
<span id="themeHeaderTitle">
<?php echo $this->getData(['locale', 'title']); ?>
</span>
<?php else: ?>
) : ?>
<span id="themeHeaderTitle"><?php echo $this->getData(['locale', 'title']); ?></span>
<?php else : ?>
<span id="themeHeaderTitle">&nbsp;</span>
<?php endif; ?>
<?php else: ?>
<?php else : ?>
<div id="featureContent">
<?php echo $this->getData(['theme', 'header', 'featureContent']); ?>
</diV>
@ -181,17 +161,14 @@
or ($this->getData(['theme', 'menu', 'position']) === 'hide'
and $this->getUrl(0) === 'theme'
)
): ?>
) : ?>
<!-- Menu dans le site après la bannière -->
<nav <?php if ($this->getData(['theme', 'menu', 'position']) === 'hide'): ?>class="displayNone" <?php endif; ?>>
<nav <?php if ($this->getData(['theme', 'menu', 'position']) === 'hide') : ?>class="displayNone" <?php endif; ?>>
<div id="toggle">
<?php echo $this->getData(['theme', 'menu', 'burgerContent']) === 'title' ? '<div id="burgerText">' . $this->getData(['locale', 'title']) . '</div>' : ''; ?>
<?php echo $this->getData(['theme', 'menu', 'burgerContent']) === 'logo' ? '<div id="burgerLogo"><img src="' . helper::baseUrl(false) . self::FILE_DIR . 'source/' . $this->getData(['theme', 'menu', 'burgerLogo']) . '"></div>' : ''; ?>
<?php echo template::ico('menu', ['fontSize' => '2em']); ?>
</div>
<div id="menu" class="container">
<?php $layout->showMenu(); ?>
</div>
<?php echo template::ico('menu', ['fontSize' => '2em']); ?></div>
<div id="menu" class="container"><?php $layout->showMenu(); ?></div>
</nav>
<?php endif; ?>
<!-- Corps de page -->
@ -201,9 +178,7 @@
<!-- Fin du site -->
<?php echo $this->getData(['theme', 'footer', 'position']) === 'site' ? '</div>' : ''; ?>
<!-- Lien remonter en haut -->
<div id="backToTop">
<?php echo template::ico('up'); ?>
</div>
<div id="backToTop"><?php echo template::ico('up'); ?></div>
<!-- Affichage du consentement aux cookies-->
<?php $layout->showCookies(); ?>
<!-- Les scripts -->
@ -211,7 +186,7 @@
<!-- Script perso dans body -->
<?php if (file_exists(self::DATA_DIR . 'body.inc.html')) {
include(self::DATA_DIR . 'body.inc.html');
} ?>
}?>
</body>
</html>

View File

@ -9,7 +9,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
@ -22,7 +22,7 @@ class config extends common
'copyBackups' => self::GROUP_ADMIN,
'delBackups' => self::GROUP_ADMIN,
'configMetaImage' => self::GROUP_ADMIN,
'sitemap' => self::GROUP_ADMIN,
'siteMap' => self::GROUP_ADMIN,
'index' => self::GROUP_ADMIN,
'restore' => self::GROUP_ADMIN,
'updateBaseUrl' => self::GROUP_ADMIN,
@ -30,8 +30,7 @@ class config extends common
'logReset' => self::GROUP_ADMIN,
'logDownload' => self::GROUP_ADMIN,
'blacklistReset' => self::GROUP_ADMIN,
'blacklistDownload' => self::GROUP_ADMIN,
'register' => self::GROUP_ADMIN,
'blacklistDownload' => self::GROUP_ADMIN
];
public static $timezones = [
@ -212,7 +211,7 @@ class config extends common
* Sitemap compressé et non compressé
* Robots.txt
*/
public function sitemap()
public function siteMap()
{
// La page n'existe pas
if (
@ -524,7 +523,7 @@ class config extends common
) {
// Ajout des lignes dans le .htaccess
$fileContent = file_get_contents('.htaccess');
$rewriteData =
$rewriteData = PHP_EOL .
'# URL rewriting' . PHP_EOL .
'<IfModule mod_rewrite.c>' . PHP_EOL .
"\tRewriteEngine on" . PHP_EOL .
@ -533,9 +532,9 @@ class config extends common
"\tRewriteCond %{REQUEST_FILENAME} !-d" . PHP_EOL .
"\tRewriteRule ^(.*)$ index.php?$1 [L]" . PHP_EOL .
'</IfModule>' . PHP_EOL .
'# URL rewriting';
'# URL rewriting' . PHP_EOL;
$fileContent = str_replace('# URL rewriting', $rewriteData, $fileContent);
$this->secure_file_put_contents(
file_put_contents(
'.htaccess',
$fileContent
);
@ -551,7 +550,7 @@ class config extends common
$fileContent = file_get_contents('.htaccess');
$fileContent = explode('# URL rewriting', $fileContent);
$fileContent = $fileContent[0] . '# URL rewriting' . $fileContent[2];
$this->secure_file_put_contents(
file_put_contents(
'.htaccess',
$fileContent
);
@ -586,7 +585,7 @@ class config extends common
// Variable de version
if (helper::checkNewVersion(common::ZWII_UPDATE_CHANNEL)) {
self::$updateButtonText = helper::translate('Mise à jour');
self::$updateButtonText = helper::translate('Mettre à jour');
}
@ -655,10 +654,10 @@ class config extends common
) {
// Ecrire les fichiers de script
if ($this->geturl(2) === 'head') {
$this->secure_file_put_contents(self::DATA_DIR . 'head.inc.html', $this->getInput('configScriptHead', null));
file_put_contents(self::DATA_DIR . 'head.inc.html', $this->getInput('configScriptHead', null));
}
if ($this->geturl(2) === 'body') {
$this->secure_file_put_contents(self::DATA_DIR . 'body.inc.html', $this->getInput('configScriptBody', null));
file_put_contents(self::DATA_DIR . 'body.inc.html', $this->getInput('configScriptBody', null));
}
// Valeurs en sortie
$this->addOutput([
@ -700,7 +699,7 @@ class config extends common
unlink(self::DATA_DIR . 'journal.log');
// Créer les en-têtes des journaux
$d = 'Date;Heure;IP;Id;Action' . PHP_EOL;
$this->secure_file_put_contents(self::DATA_DIR . 'journal.log', $d);
file_put_contents(self::DATA_DIR . 'journal.log', $d);
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Configuration'),
@ -776,15 +775,15 @@ class config extends common
ob_start();
$fileName = self::TEMP_DIR . 'blacklist.log';
$d = 'Date dernière tentative;Heure dernière tentative;Id;Adresse IP;Nombre d\'échecs' . PHP_EOL;
$this->secure_file_put_contents($fileName, $d);
file_put_contents($fileName, $d);
if (file_exists($fileName)) {
$d = $this->getData(['blacklist']);
$data = '';
foreach ($d as $key => $item) {
$data .= helper::dateUTF8('%Y %m %d', $item['lastFail'], self::$i18nUI) . ' - ' . helper::dateUTF8('%H:%M', time(), self::$i18nUI);
$data .= helper::dateUTF8('%Y %m %d', $item['lastFail'], self::$i18nContent) . ' - ' . helper::dateUTF8('%H:%M', time(), self::$i18nContent);
$data .= $key . ';' . $item['ip'] . ';' . $item['connectFail'] . PHP_EOL;
}
$this->secure_file_put_contents($fileName, $data, FILE_APPEND);
file_put_contents($fileName, $data, FILE_APPEND);
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Transfer-Encoding: binary');
@ -903,41 +902,4 @@ class config extends common
]);
}
}
/**
* Fonction pour vérifier la présence du module de réécriture
* @return bool
*/
public function isModRewriteEnabled()
{
// Check if Apache and mod_rewrite is loaded
if (function_exists('apache_get_modules')) {
$modules = apache_get_modules();
return in_array('mod_rewrite', $modules);
} else {
// Fallback if not using Apache or unable to detect modules
return getenv('HTTP_MOD_REWRITE') == 'On' || getenv('REDIRECT_STATUS') == '200';
}
}
/**
* Stocke la variable dans les paramètres de l'utilisateur pour activer la tab à sa prochaine visite
* @return never
*/
public function register(): void
{
$this->setData([
'user',
$this->getUser('id'),
'view',
[
'config' => $this->getUrl(2),
'page' => $this->getData(['user', $this->getUser('id'), 'view', 'page']),
]
]);
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'config/' . $this->getUrl(2),
]);
}
}

View File

@ -1,4 +0,0 @@
<Files "data.key">
Order Allow,Deny
Deny from all
</Files>

View File

@ -1,47 +0,0 @@
<?php
/*
Ce script PHP est conçu pour être appelé via une requête HTTP GET avec une clé spécifique pour déclencher la création d'une archive ZIP de sauvegarde.
Exemple d'appel dans une URL :
http://example.com/chemin/vers/autobackup.php?key=your_secret_key
La clé doit être fournie en tant que paramètre "key" dans l'URL et correspondre à celle stockée dans le fichier "data.key" pour que la création de l'archive soit autorisée. Si la clé est valide, le script parcourt le répertoire spécifié et ajoute les fichiers à l'archive ZIP. Si la clé est invalide ou absente, le script affiche un message d'erreur et termine son exécution.
*/
// Vérification de la clé
if (isset ($_GET['key'])) {
$key = $_GET['key'];
$storedKey = file_get_contents('data.key');
if ($key !== $storedKey) {
http_response_code(401);
exit();
}
// Création du ZIP
$filter = ['backup', 'tmp'];
$fileName = date('Y-m-d-H-i-s', time()) . '-rolling-backup.zip';
$zip = new ZipArchive();
$zip->open('../../../../site/backup/' . $fileName, ZipArchive::CREATE | ZipArchive::OVERWRITE);
$directory = '../../../../site';
$files = new RecursiveIteratorIterator(
new RecursiveCallbackFilterIterator(
new RecursiveDirectoryIterator(
$directory,
RecursiveDirectoryIterator::SKIP_DOTS
),
function ($fileInfo, $key, $iterator) use ($filter) {
return $fileInfo->isFile() || !in_array($fileInfo->getBaseName(), $filter);
}
)
);
foreach ($files as $name => $file) {
if (!$file->isDir()) {
$filePath = $file->getRealPath();
$relativePath = substr($filePath, strlen(realpath($directory)) + 1);
$zip->addFile($filePath, $relativePath);
}
}
$zip->close();
http_response_code(201);
}

View File

@ -1,49 +0,0 @@
<?php
/*
Ce script PHP est conçu pour supprimer les fichiers ayant l'extension 'tar.gz' dans un répertoire de sauvegarde si leur dernière modification remonte à un certain nombre de jours spécifié via une requête HTTP GET.
Exemple d'appel dans une URL avec le nombre de jours spécifié :
http://example.com/chemin/vers/script.php?days=7&key=your_secret_key
Le script vérifie également la présence et la validité d'une clé spécifique pour déclencher son exécution. La clé doit être fournie en tant que paramètre "key" dans l'URL et correspondre à celle stockée dans le fichier "data.key" pour que la suppression des fichiers soit autorisée. Si la clé est invalide ou absente, le script affiche un message d'erreur et termine son exécution.
*/
// Vérification de la clé
if (isset ($_GET['key'])) {
// Récupération de la clé fournie en GET
$key = $_GET['key'];
// Récupération de la clé stockée dans le fichier data.key
$storedKey = file_get_contents('data.key');
// Vérification de correspondance entre les clés
if ($key !== $storedKey) {
http_response_code(401);
exit();
}
// Récupère le nombre de jours à partir de la variable GET 'days'
$days = isset ($_GET['days']) ? (int) $_GET['days'] : 1; // Par défaut à 1 si non spécifié
// Chemin vers le répertoire contenant les fichiers
$directory = '../../../../site/backup/'; // Remplacez par le chemin réel
// Convertit le nombre de jours en secondes
$timeLimit = strtotime("-$days days");
// Crée un nouvel objet DirectoryIterator
foreach (new DirectoryIterator($directory) as $file) {
// Vérifie si l'élément courant est un fichier et a l'extension 'tar.gz'
if ($file->isFile() && $file->getExtension() === 'tar.gz') {
// Vérifie si le fichier a été modifié avant la limite de temps
if ($file->getMTime() < $timeLimit) {
// Supprime le fichier
unlink($file->getRealPath());
}
}
}
// Si la clé est manquante, affiche un message d'erreur et arrête l'exécution du script
http_response_code(201);
}

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -5,8 +5,8 @@
* file that was distributed with this source code.
*
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
$(document).ready((function(){$("#configBackupForm").submit((function(e){e.preventDefault();var url="<?php echo helper::baseUrl() . $this->getUrl(0); ?>/backup",message_success="<?php echo helper::translate('Sauvegarde générée avec succès'); ?>",message_error="<?php echo helper::translate('Erreur : sauvegarde non générée !'); ?>",message_title="<?php echo helper::translate('Sauvegarder'); ?>";$.ajax({type:"POST",url:url,data:$("form").serialize(),success:function(data){$("body, .button").css("cursor","default"),core.alert(message_success)},error:function(data){$("body, .button").css("cursor","default"),core.alert(message_error)},complete:function(){$("#configBackupSubmit").removeClass("disabled").prop("disabled",!1),$("#configBackupSubmit").removeClass("uniqueSubmission").prop("uniqueSubmission",!1),$("#configBackupSubmit span").removeClass("zwiico-spin animate-spin"),$("#configBackupSubmit span").addClass("zwiico-check zwiico-margin-right").text(message_title)}})})),$("#configBackupSubmit").on("click",(function(){if($("input[name=configBackupOption]").is(":checked")){var message_warning="<?php echo helper::translate('La sauvegarde des fichiers peut prendre du temps. Continuer ?'); ?>";return core.confirm(message_warning,(function(){$("body, .button").css("cursor","wait"),$("form#configBackupForm").submit()}))}}))}));
$(document).ready((function(){$("#configBackupForm").submit((function(e){e.preventDefault();var url="<?php echo helper::baseUrl() . $this->getUrl(0); ?>/backup",message_success="<?php echo helper::translate('Sauvegarde générée avec succès.'); ?>",message_error="<?php echo helper::translate('Erreur : sauvegarde non générée !'); ?>",message_title="<?php echo helper::translate('Sauvegarder'); ?>";$.ajax({type:"POST",url:url,data:$("form").serialize(),success:function(data){$("body, .button").css("cursor","default"),core.alert(message_success)},error:function(data){$("body, .button").css("cursor","default"),core.alert(message_error)},complete:function(){$("#configBackupSubmit").removeClass("disabled").prop("disabled",!1),$("#configBackupSubmit").removeClass("uniqueSubmission").prop("uniqueSubmission",!1),$("#configBackupSubmit span").removeClass("zwiico-spin animate-spin"),$("#configBackupSubmit span").addClass("zwiico-check zwiico-margin-right").text(message_title)}})})),$("#configBackupSubmit").on("click",(function(){if($("input[name=configBackupOption]").is(":checked")){var message_warning="<?php echo helper::translate('La sauvegarde des fichiers peut prendre du temps. Continuer ?'); ?>";return core.confirm(message_warning,(function(){$("body, .button").css("cursor","wait"),$("form#configBackupForm").submit()}))}}))}));

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -5,7 +5,7 @@
* file that was distributed with this source code.
*
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
@ -66,12 +66,12 @@ $(document).ready(function () {
$("#connectCaptchaStrong").prop("checked", false);
}
var configLayout = "<?php echo $this->getData(['user', $this->getUser('id'), 'view', 'config']);?>";
// Non défini, valeur par défaut
if (configLayout == "") {
var configLayout = getCookie("configLayout");
if (configLayout == null) {
configLayout = "setup";
setCookie("configLayout", "setup");
}
$("#localeContainer").hide();
$("#socialContainer").hide();
$("#connectContainer").hide();
$("#networkContainer").hide();
@ -158,44 +158,69 @@ $(document).ready(function () {
* Sélection de la page de configuration à afficher
*/
$("#configSetupButton").on("click", function () {
$("#localeContainer").hide();
$("#socialContainer").hide();
$("#connectContainer").hide();
$("#networkContainer").hide();
$("#setupContainer").show();
$("#configSetupButton").addClass("activeButton");
$("#configLocaleButton").removeClass("activeButton");
$("#configSocialButton").removeClass("activeButton");
$("#configConnectButton").removeClass("activeButton");
$("#configNetworkButton").removeClass("activeButton");
setCookie("configLayout", "setup");
});
$("#configLocaleButton").on("click", function () {
$("#setupContainer").hide();
$("#socialContainer").hide();
$("#connectContainer").hide();
$("#networkContainer").hide();
$("#localeContainer").show();
$("#configSetupButton").removeClass("activeButton");
$("#configLocaleButton").addClass("activeButton");
$("#configSocialButton").removeClass("activeButton");
$("#configConnectButton").removeClass("activeButton");
$("#configNetworkButton").removeClass("activeButton");
setCookie("configLayout", "locale");
});
$("#configSocialButton").on("click", function () {
$("#connectContainer").hide();
$("#setupContainer").hide();
$("#localeContainer").hide();
$("#networkContainer").hide();
$("#socialContainer").show();
$("#configSetupButton").removeClass("activeButton");
$("#configLocaleButton").removeClass("activeButton");
$("#configSocialButton").addClass("activeButton");
$("#configConnectButton").removeClass("activeButton");
$("#configNetworkButton").removeClass("activeButton");
setCookie("configLayout", "social");
});
$("#configConnectButton").on("click", function () {
$("#setupContainer").hide();
$("#localeContainer").hide();
$("#socialContainer").hide();
$("#networkContainer").hide();
$("#connectContainer").show();
$("#configSetupButton").removeClass("activeButton");
$("#configLocaleButton").removeClass("activeButton");
$("#configSocialButton").removeClass("activeButton");
$("#configConnectButton").addClass("activeButton");
$("#configNetworkButton").removeClass("activeButton");
setCookie("configLayout", "connect");
});
$("#configNetworkButton").on("click", function () {
$("#setupContainer").hide();
$("#localeContainer").hide();
$("#socialContainer").hide();
$("#connectContainer").hide();
$("#networkContainer").show();
$("#configSetupButton").removeClass("activeButton");
$("#configLocaleButton").removeClass("activeButton");
$("#configSocialButton").removeClass("activeButton");
$("#configConnectButton").removeClass("activeButton");
$("#configNetworkButton").addClass("activeButton");
setCookie("configLayout", "network");
});
@ -208,7 +233,7 @@ $(document).ready(function () {
// Mise en évidence des erreurs de saisie dans les boutons de sélection
var containers = ["setup", "social", "connect", "network"];
var containers = ["setup", "locale", "social", "connect", "network"];
$.each(containers, function (index, value) {
var a = $("div#" + value + "Container").find("input.notice").not(".displayNone");
if (a.length > 0) {
@ -261,6 +286,7 @@ $(document).ready(function () {
$('span#screenWeight').each(function(index){
var weight = parseFloat($(this).text());
var fileType = $('span#screenType').eq(index).text();
console.log(weight);
if ((fileType === "jpg" || fileType === "jpeg") && weight < 5000000) {
$(this).css("color", "green");
} else {
@ -281,6 +307,28 @@ $(document).ready(function () {
});
function setCookie(name, value, days) {
var expires = "";
if (days) {
var date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
expires = "; expires=" + date.toUTCString();
}
document.cookie = name + "=" + (value || "") + expires + "; path=/; samesite=lax";
}
function getCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') c = c.substring(1, c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
}
return null;
}
// Define function to capitalize the first letter of a string
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);

View File

@ -7,13 +7,16 @@
'value' => template::ico('home')
]); ?>
</div>
<div class="col2 offset6">
<?php echo template::button('configLocaleButton', [
'value' => 'Identité',
'href' => helper::baseUrl() . 'language/site'
]); ?>
<div class="col1">
<?php /**echo template::button('configHelp', [
'class' => 'buttonHelp',
'href' => 'https://doc.zwiicms.fr/configuration-du-site',
'target' => '_blank',
'value' => template::ico('help'),
'help' => 'Consulter l\'aide en ligne'
]); */ ?>
</div>
<div class="col2">
<div class="col2 offset8">
<?php echo template::submit('Submit'); ?>
</div>
</div>
@ -21,24 +24,21 @@
<div class="tab">
<?php echo template::button('configSetupButton', [
'value' => 'Configuration',
'class' => 'buttonTab',
'href' => helper::baseUrl() . 'config/register/setup'
'class' => 'buttonTab'
]); ?>
<?php echo template::button('configSocialButton', [
'value' => 'Référencement',
'class' => 'buttonTab',
'href' => helper::baseUrl() . 'config/register/social'
'class' => 'buttonTab'
]); ?>
<?php echo template::button('configConnectButton', [
'value' => 'Connexion',
'class' => 'buttonTab',
'href' => helper::baseUrl() . 'config/register/connect'
'class' => 'buttonTab'
]); ?>
<?php echo template::button('configNetworkButton', [
'value' => 'Réseau',
'class' => 'buttonTab',
'href' => helper::baseUrl() . 'config/register/network'
'class' => 'buttonTab'
]); ?>
</div>

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -5,7 +5,7 @@
* file that was distributed with this source code.
*
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -7,7 +7,7 @@
'value' => template::ico('left')
]); ?>
</div>
<div class="col2 offset9">
<div class="col2 offset8">
<?php echo template::submit('configManageSubmit', [
'value' => 'Valider',
'ico' => 'check'

View File

@ -3,6 +3,12 @@
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Paramètres'); ?>
<!--<span id="setupHelpButton" class="helpDisplayButton">
<a href="https://doc.zwiicms.fr/parametres" target="_blank" title="Cliquer pour consulter l'aide en ligne">
<?php //echo template::ico('help', ['margin' => 'left']);
?>
</a>-->
</span>
</h4>
<div class="row">
<div class="col4">
@ -11,8 +17,7 @@
'language' => $this->getData(['user', $this->getUser('id'), 'language']),
'help' => 'Pensez à supprimer le cache de votre navigateur si la favicon ne change pas.',
'label' => 'Favicon',
'value' => $this->getData(['config', 'favicon']),
'folder' => $this->getData(['config', 'favicon']) ? dirname($this->getData(['config', 'favicon'])) : ''
'value' => $this->getData(['config', 'favicon'])
]); ?>
</div>
<div class="col4">
@ -21,8 +26,7 @@
'language' => $this->getData(['user', $this->getUser('id'), 'language']),
'help' => 'Sélectionnez une icône adaptée à un thème sombre.<br>Pensez à supprimer le cache de votre navigateur si la favicon ne change pas.',
'label' => 'Favicon thème sombre',
'value' => $this->getData(['config', 'faviconDark']),
'folder' => $this->getData(['config', 'faviconDark']) ? dirname($this->getData(['config', 'faviconDark'])) : ''
'value' => $this->getData(['config', 'faviconDark'])
]); ?>
</div>
<div class="col4">
@ -44,7 +48,7 @@
<?php echo template::checkbox('configRewrite', true, 'Apache URL intelligentes', [
'checked' => helper::checkRewrite(),
'help' => 'Supprime le point d\'interrogation dans les URL, l\'option est indisponible avec les autres serveurs Web',
'disabled' => stripos($_SERVER["SERVER_SOFTWARE"], 'Apache') === false and $module->isModRewriteEnabled()
'disabled' => stripos($_SERVER["SERVER_SOFTWARE"], 'nginx')
]); ?>
</div>
</div>
@ -55,6 +59,12 @@
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Mise à jour automatisée'); ?>
<!--<span id="updateHelpButton" class="helpDisplayButton">
<a href="https://doc.zwiicms.fr/mise-a-jour" target="_blank" title="Cliquer pour consulter l'aide en ligne">
<?php //echo template::ico('help', ['margin' => 'left']);
?>
</a>
</span>-->
</h4>
<div class="row">
<div class="col6">
@ -80,8 +90,8 @@
]); ?>
</div>
<div class="col3 offset1 verticalAlignBottom">
<pre>Version installée : <strong><?php echo common::ZWII_VERSION; ?></strong></pre>
<pre>Version en ligne : <strong><?php echo helper::getOnlineVersion(common::ZWII_UPDATE_CHANNEL); ?></strong></pre>
<pre>Version installée : <strong><?php echo common::ZWII_VERSION ; ?></strong></pre>
<pre>Version en ligne : <strong><?php echo helper::getOnlineVersion(common::ZWII_UPDATE_CHANNEL) ; ?></strong></pre>
</div>
<div class="col3 offset2 verticalAlignBottom">
<?php echo template::button('configUpdateForced', [
@ -99,6 +109,12 @@
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Maintenance'); ?>
<!--<span id="maintenanceHelpButton" class="helpDisplayButton">
<a href="https://doc.zwiicms.fr/mode-maintenance" target="_blank" title="Cliquer pour consulter l'aide en ligne">
<?php //echo template::ico('help', ['margin' => 'left']);
?>
</a>
</span>-->
</h4>
<div class="row">
<div class="col6">
@ -153,6 +169,12 @@
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Scripts externes'); ?>
<!--<span id="specialeHelpButton" class="helpDisplayButton">
<a href="https://doc.zwiicms.fr/scripts-externes" target="_blank" title="Cliquer pour consulter l'aide en ligne">
<?php //echo template::ico('help', ['margin' => 'left']);
?>
</a>
</span>-->
</h4>
<div class="row">
<div class="col4 offset1 verticalAlignBottom">
@ -176,21 +198,13 @@
<div class="row">
<div class="col12">
<div class="block">
<h4>ZwiiCMS <a href="https://zwiicms.fr" target="_blank">Site Web</a> - <a
href="https://forum.zwiicms.fr" target="_blank">Forum</a>
<h4>ZwiiCMS <a href="https://zwiicms.fr" target="_blank">Site Web</a> - <a href="https://forum.zwiicms.fr" target="_blank">Forum</a>
</h4>
<div class="row textAlignCenter">
<div class="col12">
<a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/4.0/"><img
alt="Licence Creative Commons" style="border-width:0"
src="https://i.creativecommons.org/l/by-nc-nd/4.0/88x31.png" /></a>
<p>Cette œuvre est mise à disposition selon les termes de la <a rel="license"
href="http://creativecommons.org/licenses/by-nc-nd/4.0/">Licence Creative Commons
Attribution - Pas d&#39;Utilisation Commerciale - Pas de Modification 4.0
International.</a></p>
<p>Pour voir une copie de cette licence, visitez
http://creativecommons.org/licenses/by-nc-nd/4.0/ ou écrivez à Creative Commons, PO Box
1866, Mountain View, CA 94042, USA.</p>
<a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/4.0/"><img alt="Licence Creative Commons" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-nd/4.0/88x31.png" /></a>
<p>Cette œuvre est mise à disposition selon les termes de la <a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/4.0/">Licence Creative Commons Attribution - Pas d&#39;Utilisation Commerciale - Pas de Modification 4.0 International.</a></p>
<p>Pour voir une copie de cette licence, visitez http://creativecommons.org/licenses/by-nc-nd/4.0/ ou écrivez à Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.</p>
</div>
</div>
</div>

View File

@ -4,6 +4,11 @@
<div class="block">
<h4>
<?php echo helper::translate('Capture d\'écran Open Graph'); ?>
<!--<span id="specialeHelpButton" class="helpDisplayButton">
<a href="https://doc.zwiicms.fr/referencement" target="_blank" title="Cliquer pour consulter l'aide en ligne">
<?php //echo template::ico('help', ['margin' => 'left']); ?>
</a>
</span>-->
</h4>
<div class="row">
<div class="col6">
@ -13,7 +18,6 @@
'language' => $this->getData(['user', $this->getUser('id'), 'language']),
'label' => 'Image Open Graph',
'value' => $this->getData(['config', 'seo', 'openGraphImage']),
'folder' => $this->getData(['config', 'seo', 'openGraphImage']) ? dirname($this->getData(['config', 'seo', 'openGraphImage'])) : '',
'type' => 1,
'help' => sprintf('%s : JPG - PNG<br />', helper::translate('Format')) .
sprintf('%s : 1200 x 630 pixels<br />', helper::translate('Dimensions minimales')) .
@ -24,7 +28,7 @@
</div>
<div class="row">
<div class="col10 textAlignCenter">
<?php if( !empty($module::$imageOpenGraph['type']) ): ?>
<?php if( $module::$imageOpenGraph['type']): ?>
<p>
<?php echo sprintf('%s : <span id="screenType">%s</span>', helper::translate('Format'), $module::$imageOpenGraph['type']); ?>
</p>
@ -80,6 +84,12 @@
<div class="col12">
<div class="block">
<h4>
<?php echo helper::translate('Réseaux sociaux'); ?>
<!--<span id="specialeHelpButton" class="helpDisplayButton">
<a href="https://doc.zwiicms.fr/reseaux-sociaux" target="_blank" title="Cliquer pour consulter l'aide en ligne">
<?php //echo template::ico('help', ['margin' => 'left']); ?>
</a>
</span>-->
</h4>
<div class="row">
<div class="col3">

View File

@ -8,7 +8,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -8,7 +8,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
@ -32,6 +32,9 @@ class install extends common
public static $updateButtonText = 'Réinstaller';
// Thèmes proposés à l'installation
public static $themes = [];
public static $newVersion;
// Fichiers des Interface
@ -119,24 +122,24 @@ class install extends common
self::$i18nUI = $_SESSION['ZWII_UI'];
self::$i18nUI = array_key_exists(self::$i18nUI, self::$languages) ? self::$i18nUI : 'fr_FR';
// par défaut le contenu est la langue d'installation
$_SESSION['ZWII_SITE_CONTENT'] = self::$i18nUI;
$_SESSION['ZWII_CONTENT'] = self::$i18nUI;
// Création du dossier de langue avec le marqueur de langue par défaut
if (!is_dir(self::DATA_DIR . $_SESSION['ZWII_SITE_CONTENT'])) {
mkdir(self::DATA_DIR . $_SESSION['ZWII_SITE_CONTENT']);
touch(self::DATA_DIR . $_SESSION['ZWII_SITE_CONTENT'] . '/.default');
if (!is_dir(self::DATA_DIR . $_SESSION['ZWII_CONTENT'])) {
mkdir(self::DATA_DIR . $_SESSION['ZWII_CONTENT']);
touch(self::DATA_DIR . $_SESSION['ZWII_CONTENT'] . '/.default');
}
// Installation du site de test
if (
$this->getInput('installDefaultData', helper::FILTER_BOOLEAN) === false
&& $_SESSION['ZWII_SITE_CONTENT'] === 'fr_FR'
&& $_SESSION['ZWII_CONTENT'] === 'fr_FR'
) {
$sample = true;
}
$this->initData('page', $_SESSION['ZWII_SITE_CONTENT'], $sample);
$this->initData('module', $_SESSION['ZWII_SITE_CONTENT'], $sample);
$this->initData('locale', $_SESSION['ZWII_SITE_CONTENT'], $sample);
$this->initData('page', $_SESSION['ZWII_CONTENT'], $sample);
$this->initData('module', $_SESSION['ZWII_CONTENT'], $sample);
$this->initData('locale', $_SESSION['ZWII_CONTENT'], $sample);
// Création de l'utilisateur si les données sont complétées.
// success retour de l'enregistrement des données
@ -147,13 +150,12 @@ class install extends common
'firstname' => $userFirstname,
'forgot' => 0,
'group' => self::GROUP_ADMIN,
'profil' => 0,
'lastname' => $userLastname,
'pseudo' => 'Admin',
'signature' => 1,
'mail' => $userMail,
'password' => $this->getInput('installPassword', helper::FILTER_PASSWORD, true),
'language' => $_SESSION['ZWII_SITE_CONTENT']
'language' => $_SESSION['ZWII_CONTENT']
]
]);
@ -172,7 +174,7 @@ class install extends common
// Nettoyage fr par défaut
if (
$_SESSION['ZWII_SITE_CONTENT'] !== 'fr_FR'
$_SESSION['ZWII_CONTENT'] !== 'fr_FR'
) {
if (is_dir(self::DATA_DIR . 'fr_FR'))
$this->deleteDir(self::DATA_DIR . 'fr_FR');
@ -210,17 +212,40 @@ class install extends common
mkdir(self::DATA_DIR . 'font');
}
// Installation du thème sélectionné
$dataThemes = json_decode(file_get_contents('core/module/install/ressource/themes/themes.json'), true);
$dataThemes = $dataThemes['themes'];
$themeFilename = $dataThemes[$this->getInput('installTheme', helper::FILTER_STRING_SHORT)]['filename'];
if ($themeFilename !== '') {
$theme = new theme;
$theme->import('core/module/install/ressource/themes/' . $themeFilename);
}
// Copie des thèmes dans les fichiers
if (!is_dir(self::FILE_DIR . 'source/theme')) {
mkdir(self::FILE_DIR . 'source/theme');
}
$this->copyDir('core/module/install/ressource/themes', self::FILE_DIR . 'source/theme');
unlink(self::FILE_DIR . 'source/theme/themes.json');
// Copie des langues de l'UI et génération de la base de données
if (is_dir(self::I18N_DIR) === false) {
mkdir(self::I18N_DIR);
}
// Créer la base de données des langues
// copy('core/module/install/ressource/i18n/language.json', self::DATA_DIR . 'language.json');
$this->copyDir('core/module/install/ressource/i18n', self::I18N_DIR);
// unlink(self::I18N_DIR . 'language.json');
// Fixe l'adresse from pour les envois d'email
$this->setData(['config', 'smtp', 'from', 'no-reply@' . str_replace('www.', '', $_SERVER['HTTP_HOST'])]);
// Supprimé à cause de l'écrasement des bases
//$this->setData(['module', 'blog', 'posts', 'mon-premier-article', 'userId', $userId]);
//$this->setData(['module', 'blog', 'posts', 'mon-deuxieme-article', 'userId', $userId]);
//$this->setData(['module', 'blog', 'posts', 'mon-troisieme-article', 'userId', $userId]);
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl(),
@ -229,6 +254,13 @@ class install extends common
]);
}
// Affichage du formulaire
// Récupération de la liste des thèmes
$dataThemes = json_decode(file_get_contents('core/module/install/ressource/themes/themes.json'), true);
$dataThemes = $dataThemes['themes'];
self::$themes = helper::arrayColumn($dataThemes, 'name');
// Valeurs en sortie
$this->addOutput([
'display' => self::DISPLAY_LAYOUT_LIGHT,
@ -267,18 +299,14 @@ class install extends common
$message = $success ? '' : 'Erreur de copie du fichier htaccess';
}
// Nettoyage des fichiers d'installation précédents
if ($success && file_exists(self::TEMP_DIR . 'update.tar.gz')) {
if (file_exists(self::TEMP_DIR . 'update.tar.gz') && $success) {
$success = unlink(self::TEMP_DIR . 'update.tar.gz');
$message = $success ? '' : 'Impossible d\'effacer la mise à jour précédente';
}
if ($success && file_exists(self::TEMP_DIR . 'update.tar')) {
if (file_exists(self::TEMP_DIR . 'update.tar') && $success) {
$success = unlink(self::TEMP_DIR . 'update.tar');
$message = $success ? '' : 'Impossible d\'effacer la mise à jour précédente';
}
// Sauvegarde le message dans le journal
if (!empty($message)) {
$this->saveLog($message);
}
// Valeurs en sortie
$this->addOutput([
'display' => self::DISPLAY_JSON,
@ -290,9 +318,7 @@ class install extends common
break;
// Téléchargement
case 2:
$success = true;
$message = '';
$this->secure_file_put_contents(self::TEMP_DIR . 'update.tar.gz', helper::getUrlContents(common::ZWII_UPDATE_URL . common::ZWII_UPDATE_CHANNEL . '/update.tar.gz'));
file_put_contents(self::TEMP_DIR . 'update.tar.gz', helper::getUrlContents(common::ZWII_UPDATE_URL . common::ZWII_UPDATE_CHANNEL . '/update.tar.gz'));
$md5origin = helper::getUrlContents(common::ZWII_UPDATE_URL . common::ZWII_UPDATE_CHANNEL . '/update.md5');
$md5origin = explode(' ', $md5origin);
$md5target = md5_file(self::TEMP_DIR . 'update.tar.gz');
@ -302,35 +328,27 @@ class install extends common
$message = "";
} else {
$success = false;
$message = 'Erreur de téléchargement ou de somme de contrôle';
$message = json_encode('Erreur de téléchargement ou de somme de contrôle', JSON_UNESCAPED_UNICODE);
if (file_exists(self::TEMP_DIR . 'update.tar.gz')) {
unlink(self::TEMP_DIR . 'update.tar.gz');
http_response_code(500);
}
}
// Sauvegarde le message dans le journal
if (!empty($message)) {
$this->saveLog($message);
}
// Valeurs en sortie
$this->addOutput([
'display' => self::DISPLAY_JSON,
'content' => [
'success' => $success,
'data' => json_encode($message, JSON_UNESCAPED_UNICODE)
'data' => $message
]
]);
break;
// Installation
case 3:
$success = true;
$message = '';
// Check la réécriture d'URL avant d'écraser les fichiers
if (helper::checkRewrite()) {
touch(self::DATA_DIR . '.rewrite');
}
$rewrite = helper::checkRewrite();
// Décompression et installation
try {
// Décompression dans le dossier de fichier temporaires
@ -339,11 +357,9 @@ class install extends common
// Installation
$pharData->extractTo(__DIR__ . '/../../../', null, true);
} catch (Exception $e) {
$message = $e->getMessage();
$success = false;
http_response_code(500);
}
// Nettoyage du dossier
if (file_exists(self::TEMP_DIR . 'update.tar.gz')) {
unlink(self::TEMP_DIR . 'update.tar.gz');
@ -351,16 +367,12 @@ class install extends common
if (file_exists(self::TEMP_DIR . 'update.tar')) {
unlink(self::TEMP_DIR . 'update.tar');
}
// Sauvegarde le message dans le journal
if (!empty($message)) {
$this->saveLog($message);
}
// Valeurs en sortie
$this->addOutput([
'display' => self::DISPLAY_JSON,
'content' => [
'success' => $success,
'data' => json_encode($message, JSON_UNESCAPED_UNICODE)
'data' => $rewrite
]
]);
break;
@ -368,6 +380,7 @@ class install extends common
case 4:
$success = true;
$message = '';
$rewrite = $this->getInput('data');
/**
* Restaure le fichier htaccess
@ -388,7 +401,7 @@ class install extends common
/**
* Restaure la réécriture d'URL
*/
if (file_exists(self::DATA_DIR . '.rewrite')) { // Ajout des lignes dans le .htaccess
if ($rewrite === 'true') { // Ajout des lignes dans le .htaccess
$fileContent = file_get_contents('.htaccess');
$rewriteData = PHP_EOL .
'# URL rewriting' . PHP_EOL .
@ -401,11 +414,10 @@ class install extends common
'</IfModule>' . PHP_EOL .
'# URL rewriting' . PHP_EOL;
$fileContent = str_replace('# URL rewriting', $rewriteData, $fileContent);
$success = $this->secure_file_put_contents(
$success = file_put_contents(
'.htaccess',
$fileContent
);
unlink(self::DATA_DIR . '.rewrite');
}
}
@ -417,6 +429,7 @@ class install extends common
$defaultLanguages = init::$defaultData['language'];
foreach ($installedLanguages as $key => $value) {
//var_dump( $defaultLanguages[$key]['date'] > $value['date'] );
if (
isset($defaultLanguages[$key]['date']) &&
$defaultLanguages[$key]['date'] > $value['date'] &&
@ -428,10 +441,7 @@ class install extends common
$this->setData(['language', $key, $defaultLanguages[$key]]);
}
}
// Sauvegarde le message dans le journal
if (!empty($message)) {
$this->saveLog($message);
}
// Valeurs en sortie
$this->addOutput([
'display' => self::DISPLAY_JSON,
@ -463,7 +473,7 @@ class install extends common
// Variable de version
if (helper::checkNewVersion(common::ZWII_UPDATE_CHANNEL)) {
self::$updateButtonText = helper::translate('Mise à jour');
self::$updateButtonText = helper::translate('Mettre à jour');
}

View File

@ -420,7 +420,7 @@ class init extends common
'copycut' => false,
'chmod' => false,
'share' => true,
'path' => '/site/file/source/partage/',
'path' => './site/file/source/partage/',
],
'page' => [
'add' => false,
@ -506,7 +506,7 @@ class init extends common
'copycut' => false,
'chmod' => false,
'share' => true,
'path' => '/site/file/source/partage/',
'path' => './site/file/source/partage/',
],
'page' => [
'add' => false,
@ -588,7 +588,7 @@ class init extends common
'copycut' => true,
'chmod' => true,
'share' => true,
'path' => '/site/file/source/partage/',
'path' => './site/file/source/partage/',
],
'page' => [
'add' => true,

View File

@ -547,7 +547,7 @@
"Sauvegarde": "Backup",
"Sauvegarde automatique quotidienne du site": "Daily automatic backup of the site",
"Sauvegarde du thème dans le": "Backup of the theme in the",
"Sauvegarde générée avec succès": "Successfully generated backup.",
"Sauvegarde générée avec succès.": "Successfully generated backup.",
"Sauvegarder": "Backup",
"Sauvegarder et télécharger le module": "Save and download the module",
"Sauvegarder le module dans le gestionnaire de fichiers": "Save the module in the file manager",

View File

@ -547,7 +547,7 @@
"Sauvegarde": "Salvaguardad",
"Sauvegarde automatique quotidienne du site": "Copia de seguridad diaria automática del sitio",
"Sauvegarde du thème dans le": "Guardando tema en el",
"Sauvegarde générée avec succès": "Copia de seguridad generada con éxito",
"Sauvegarde générée avec succès.": "Copia de seguridad generada con éxito",
"Sauvegarder": "Para salvaguardar",
"Sauvegarder et télécharger le module": "Guardar y descargar módulo",
"Sauvegarder le module dans le gestionnaire de fichiers": "Guardar módulo en el administrador de archivos",

View File

@ -547,7 +547,7 @@
"Sauvegarde": "",
"Sauvegarde automatique quotidienne du site": "",
"Sauvegarde du thème dans le": "",
"Sauvegarde générée avec succès": "",
"Sauvegarde générée avec succès.": "",
"Sauvegarder": "",
"Sauvegarder et télécharger le module": "",
"Sauvegarder le module dans le gestionnaire de fichiers": "",

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,24 @@
{
"themes": {
"defaut": {
"name": "Le thème par défaut, ambiance bleu et montagne",
"filename": ""
},
"moderne": {
"name": "Thème avec la nouvelle bannière personnalisable",
"filename": "theme_moderne.zip"
},
"affaire": {
"name": "Thème affaire, bannière centre d'appel, ambiance prune",
"filename": "theme_affaire.zip"
},
"black": {
"name": "Thème de nuit, ambiance nocturne",
"filename": "theme_orange_black.zip"
},
"facebook": {
"name": "Thème Facebook ancienne génération, pas de bannière, menu fixe fond bleu",
"filename": "theme_old_facebook.zip"
}
}
}

View File

@ -1,18 +0,0 @@
/**
* This file is part of Zwii.
*
* For full copyright and license information, please see the LICENSE
* file that was distributed with this source code.
*
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
/** NE PAS EFFACER
* admin.css
*/

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -6,7 +6,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -94,6 +94,9 @@
</div>
<div class="row">
<div class="col12">
<?php echo template::select('installTheme', $module::$themes, [
'label' => 'Thème'
]); ?>
<?php echo template::hidden('installLanguage', [
'value' => $this->getUrl(2)
]); ?>

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -12,6 +12,11 @@ function step(i, data) {
data: data
},
success: function (result) {
// if (result.success != "1") { // Vérification de la propriété "success"
// Appel de la fonction de gestion d'erreur
// showError(i, result, errors);
// return;
//}
setTimeout((function () {
if (4 === i) {
$("#installUpdateSuccess").show();
@ -55,13 +60,10 @@ function showError(step, message, errors) {
const jsonData = JSON.parse(jsonString);
// Afficher les résultats
if (jsonData) {
$("#installUpdateErrorMessage").html("<strong>Détails de l'erreur :</strong><br> " +
jsonData.data.replace(/^"(.*)"$/, '$1') +
"<br>" +
warningMessage.replace(/<[^p].*?>/g, ""));
}
} else {
// Vous pouvez également faire quelque chose d'autre ici, par exemple, afficher un message à l'utilisateur, etc.
$("#installUpdateErrorMessage").html(message);

View File

@ -5,7 +5,7 @@
<?php echo self::ZWII_VERSION; ?>
<?php echo helper::translate('vers'); ?>
&nbsp;
<?php echo $module::$newVersion; ?>
<?php echo $module::$newVersion; ?>.
</strong></p>
<p>
<?php echo helper::translate('Afin d\'assurer le bon fonctionnement de Zwii, veuillez ne pas fermer cette page avant la fin de l\'opération.'); ?>

View File

@ -8,7 +8,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
@ -99,7 +99,7 @@ class language extends common
is_array($descripteur['language'][$lang])
) {
if ($this->setData(['language', $lang, $descripteur['language'][$lang]])) {
$success = $this->secure_file_put_contents(self::I18N_DIR . $lang . '.json', $languageData);
$success = file_put_contents(self::I18N_DIR . $lang . '.json', json_encode($languageData, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
$success = is_int($success) ? true : false;
}
}
@ -197,7 +197,7 @@ class language extends common
) {
if (file_exists(self::DATA_DIR . $key . '/.default')) {
$messageLocale = helper::translate('Langue par défaut');
} elseif (isset($_SESSION['ZWII_SITE_CONTENT']) && $_SESSION['ZWII_SITE_CONTENT'] === $key) {
} elseif (isset($_SESSION['ZWII_CONTENT']) && $_SESSION['ZWII_CONTENT'] === $key) {
$messageLocale = helper::translate('Langue du site sélectionnée');
} else {
$messageLocale = '';
@ -255,7 +255,7 @@ class language extends common
self::$languagesUiInstalled[$file] = [
template::flag($file, '20 %') . '&nbsp;' . self::$languages[$file],
$value['version'],
helper::dateUTF8('%d/%m/%Y', $value['date'], self::$i18nUI),
helper::dateUTF8('%d/%m/%Y', $value['date'], self::$i18nContent),
//self::$i18nUI === $file ? helper::translate('Interface') : '',
'',
/*
@ -271,7 +271,7 @@ class language extends common
'class' => isset($storeUI[$file]['version']) && version_compare($installedUI[$file]['version'], $storeUI[$file]['version']) < 0 ? 'buttonGreen' : '',
'href' => helper::baseUrl() . $this->getUrl(0) . '/update/' . $file,
'value' => template::ico('update'),
'help' => 'Mise à jour',
'help' => 'Mettre à jour',
]),
template::button('translateContentLanguageUIDelete' . $file, [
'class' => 'translateDelete buttonRed' . (in_array($file, $usersUI) ? ' disabled' : ''),
@ -291,7 +291,7 @@ class language extends common
self::$languagesStore[$file] = [
template::flag($file, '20 %') . '&nbsp;' . self::$languages[$file],
$value['version'],
helper::dateUTF8('%d/%m/%Y', $value['date'], self::$i18nUI),
helper::dateUTF8('%d/%m/%Y', $value['date'], self::$i18nContent),
'',
template::button('translateContentLanguageUIDownload' . $file, [
'class' => 'buttonGreen',
@ -304,17 +304,6 @@ class language extends common
}
}
// Pointer vers la fenêtre
switch ($this->getUrl(1)) {
case 'interface':
setcookie('translateLayout', 'ui', time() + 3600, '/', '', false, false);
break;
case 'site':
setcookie('translateLayout', 'content', time() + 3600, '/', '', false, false);
break;
default:
break;
}
// Valeurs en sortie
$this->addOutput([
@ -425,12 +414,12 @@ class language extends common
];
// Sauvegarde hors méthodes si la langue n'est pas celle de l'UI
if ($lang === self::$siteContent) {
if ($lang === self::$i18nContent) {
// Enregistrer les données par lecture directe du formulaire
$this->setData(['locale', $data['locale']]);
} else {
// Sauver sur le disque
$this->secure_file_put_contents(self::DATA_DIR . $lang . '/locale.json', $data);
file_put_contents(self::DATA_DIR . $lang . '/locale.json', json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT), LOCK_EX);
}
// Valeurs en sortie
@ -445,7 +434,7 @@ class language extends common
//-----------------------------------------
// La locale est-elle celle de la langue de l'UI ?
if ($lang === self::$siteContent) {
if ($lang === self::$i18nContent) {
self::$locales[$lang]['locale'] = $this->getData(['locale']);
} else {
// Lire les locales sans passer par les méthodes
@ -512,7 +501,7 @@ class language extends common
$data[$key] = $target;
}
}
$this->secure_file_put_contents(self::I18N_DIR . $lang . '.json', $data);
file_put_contents(self::I18N_DIR . $lang . '.json', json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT), LOCK_EX);
// Mettre à jour le descripteur
$this->setData([
@ -546,7 +535,7 @@ class language extends common
$data[$key] = '';
}
}
$this->secure_file_put_contents(self::I18N_DIR . $lang . '.json', $data);
file_put_contents(self::I18N_DIR . $lang . '.json', json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT), LOCK_EX);
// Tableau des chaines à traduire dans la langue sélectionnée
foreach ($data as $key => $value) {
@ -700,7 +689,7 @@ class language extends common
) {
// Stocker la sélection
$_SESSION['ZWII_SITE_CONTENT'] = $lang;
$_SESSION['ZWII_CONTENT'] = $lang;
}
// Valeurs en sortie

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -6,7 +6,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -4,7 +4,7 @@
<?php echo template::button('translateFormBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl(),
'value' => template::ico('home')
'value' => template::ico('left')
]); ?>
</div>
<div class="col1">

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -107,7 +107,7 @@
<div class="block">
<h4><?php echo helper::translate('Étiquettes des pages spéciales'); ?>
<!--<span id="labelHelpButton" class="helpDisplayButton" title="Cliquer pour consulter l'aide en ligne">
<a href="https://doc.zwiicms.fr/Étiquettes-des-pages-speciales" target="_blank">
<a href="https://doc.zwiicms.fr/etiquettes-des-pages-speciales" target="_blank">
<?php //echo template::ico('help', ['margin' => 'left']); ?>
</a>
</span>-->

View File

@ -8,7 +8,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
@ -41,7 +41,7 @@ class maintenance extends common
? ''
: $this->getData(['page', $this->getData(['locale', 'page302']), 'title']),
//'content' => $this->getdata(['page',$this->getData(['locale','page302']),'content']),
'content' => $this->getPage($this->getData(['locale', 'page302']), self::$siteContent),
'content' => $this->getPage($this->getData(['locale', 'page302']), self::$i18nContent),
'view' => 'index'
]);
} else {

View File

@ -9,7 +9,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
@ -23,8 +23,7 @@ class page extends common
'edit' => self::GROUP_EDITOR,
'duplicate' => self::GROUP_EDITOR,
'jsEditor' => self::GROUP_EDITOR,
'cssEditor' => self::GROUP_EDITOR,
'register' => self::GROUP_EDITOR,
'cssEditor' => self::GROUP_EDITOR
];
public static $pagesNoParentId = [
'' => 'Aucune'
@ -86,19 +85,8 @@ class page extends common
*/
public function duplicate()
{
// La session ne correspond pas au site ouvert dans cet onglet
if (
// Contrôle la présence de l'id de langue uniquement si l'id est fourni afin de ne pas bloquer les modules non mis à jour
$this->getUrl(3) && $this->getUrl(3) != self::$siteContent
) {
$_SESSION['ZWII_SITE_CONTENT'] = $this->getUrl(3);
header('Refresh:0; url=' . helper::baseUrl() . $this->getUrl());
exit();
}
// Adresse sans le token
$page = $this->getUrl(2);
// La page n'existe pas
if (
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true ||
@ -130,7 +118,7 @@ class page extends common
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $pageId . '/' . self::$siteContent,
'redirect' => helper::baseUrl() . 'page/edit/' . $pageId,
'notification' => $notification,
'state' => true
]);
@ -143,16 +131,6 @@ class page extends common
*/
public function add()
{
// La session ne correspond pas au site ouvert dans cet onglet
if (
// Contrôle la présence de l'id de langue uniquement si l'id est fourni afin de ne pas bloquer les modules non mis à jour
$this->getUrl(3) && $this->getUrl(3) != self::$siteContent
) {
$_SESSION['ZWII_SITE_CONTENT'] = $this->getUrl(3);
header('Refresh:0; url=' . helper::baseUrl() . $this->getUrl());
exit();
}
if ($this->getUser('permission', __CLASS__, __FUNCTION__) !== true) {
// Valeurs en sortie
$this->addOutput([
@ -196,14 +174,14 @@ class page extends common
]
]);
// Creation du contenu de la page
if (!is_dir(self::DATA_DIR . self::$siteContent . '/content')) {
mkdir(self::DATA_DIR . self::$siteContent . '/content', 0755);
if (!is_dir(self::DATA_DIR . self::$i18nContent . '/content')) {
mkdir(self::DATA_DIR . self::$i18nContent . '/content', 0755);
}
//$this->secure_file_put_contents(self::DATA_DIR . self::$siteContent . '/content/' . $pageId . '.html', '<p>Contenu de votre nouvelle page.</p>');
$this->setPage($pageId, '<p>Contenu de votre nouvelle page.</p>', self::$siteContent);
//file_put_contents(self::DATA_DIR . self::$i18nContent . '/content/' . $pageId . '.html', '<p>Contenu de votre nouvelle page.</p>');
$this->setPage($pageId, '<p>Contenu de votre nouvelle page.</p>', self::$i18nContent);
// Ne met à jour le sitemap pour éviter un warning, de toute manière la nouvelle page doit être éditée.
// $this->updateSitemap();
// Met à jour le sitemap
$this->updateSitemap();
// Valeurs en sortie
$this->addOutput([
@ -220,16 +198,6 @@ class page extends common
*/
public function delete()
{
// La session ne correspond pas au site ouvert dans cet onglet
if (
// Contrôle la présence de l'id de langue uniquement si l'id est fourni afin de ne pas bloquer les modules non mis à jour
$this->getUrl(3) && $this->getUrl(3) != self::$siteContent
) {
$_SESSION['ZWII_SITE_CONTENT'] = $this->getUrl(3);
header('Refresh:0; url=' . helper::baseUrl() . $this->getUrl());
exit();
}
// $url prend l'adresse sans le token
$page = $this->getUrl(2);
// La page n'existe pas
@ -294,7 +262,7 @@ class page extends common
elseif ($this->getHierarchy($page, null)) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $page . '/' . self::$siteContent,
'redirect' => helper::baseUrl() . 'page/edit/' . $page,
'notification' => helper::translate('Impossible de supprimer une page contenant des pages enfants')
]);
}
@ -311,8 +279,8 @@ class page extends common
}
// Effacer la page
$this->deleteData(['page', $page]);
if (file_exists(self::DATA_DIR . self::$siteContent . '/content/' . $page . '.html')) {
unlink(self::DATA_DIR . self::$siteContent . '/content/' . $page . '.html');
if (file_exists(self::DATA_DIR . self::$i18nContent . '/content/' . $page . '.html')) {
unlink(self::DATA_DIR . self::$i18nContent . '/content/' . $page . '.html');
}
$this->deleteData(['module', $page]);
@ -334,17 +302,6 @@ class page extends common
*/
public function edit()
{
// La session ne correspond pas au site ouvert dans cet onglet
if (
// Contrôle la présence de l'id de langue uniquement si l'id est fourni afin de ne pas bloquer les modules non mis à jour
$this->getUrl(3) && $this->getUrl(3) != self::$siteContent
) {
$_SESSION['ZWII_SITE_CONTENT'] = $this->getUrl(3);
header('Refresh:0; url=' . helper::baseUrl() . $this->getUrl());
exit();
}
// La page n'existe pas
if (
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true ||
@ -412,8 +369,8 @@ class page extends common
// Supprime l'ancienne page si l'id a changée
if ($pageId !== $this->getUrl(2)) {
$this->deleteData(['page', $this->getUrl(2)]);
if (file_exists(self::DATA_DIR . self::$siteContent . '/content/' . $this->getUrl(2) . '.html')) {
unlink(self::DATA_DIR . self::$siteContent . '/content/' . $this->getUrl(2) . '.html');
if (file_exists(self::DATA_DIR . self::$i18nContent . '/content/' . $this->getUrl(2) . '.html')) {
unlink(self::DATA_DIR . self::$i18nContent . '/content/' . $this->getUrl(2) . '.html');
}
}
// Traitement des pages spéciales affectées dans la config :
@ -551,11 +508,11 @@ class page extends common
]);
// Creation du contenu de la page
if (!is_dir(self::DATA_DIR . self::$siteContent . '/content')) {
mkdir(self::DATA_DIR . self::$siteContent . '/content', 0755);
if (!is_dir(self::DATA_DIR . self::$i18nContent . '/content')) {
mkdir(self::DATA_DIR . self::$i18nContent . '/content', 0755);
}
$content = empty($this->getInput('pageEditContent', null)) ? '<p></p>' : str_replace('<p></p>', '<p>&nbsp;</p>', $this->getInput('pageEditContent', null));
$this->setPage($pageId, $content, self::$siteContent);
$this->setPage($pageId, $content, self::$i18nContent);
// Met à jour le sitemap
$this->updateSitemap();
@ -582,9 +539,6 @@ class page extends common
}
// Construction du formulaire
// Met à jour le sitemap
$this->updateSitemap();
// Création du sélecteur de modules
self::$moduleIds = [];
foreach (helper::getModules() as $key => $values) {
@ -645,15 +599,14 @@ class page extends common
$css = $this->getInput('pageCssEditorContent', helper::FILTER_STRING_LONG) === null ? '' : $this->getInput('pageCssEditorContent', helper::FILTER_STRING_LONG);
// Enregistre le CSS
$this->setData([
'page',
$this->getUrl(2),
'page', $this->getUrl(2),
'css',
$css
]);
// Valeurs en sortie
$this->addOutput([
'notification' => helper::translate('Modifications enregistrées'),
'redirect' => helper::baseUrl() . 'page/edit/' . $this->getUrl(2) . '/' . self::$siteContent,
'redirect' => helper::baseUrl() . 'page/edit/' . $this->getUrl(2),
'state' => true
]);
}
@ -680,15 +633,14 @@ class page extends common
$js = $this->getInput('pageJsEditorContent', helper::FILTER_STRING_LONG) === null ? '' : $this->getInput('pageJsEditorContent', helper::FILTER_STRING_LONG);
// Enregistre le JS
$this->setData([
'page',
$this->getUrl(2),
'page', $this->getUrl(2),
'js',
$js
]);
// Valeurs en sortie
$this->addOutput([
'notification' => helper::translate('Modifications enregistrées'),
'redirect' => helper::baseUrl() . 'page/edit/' . $this->getUrl(2) . '/' . self::$siteContent,
'redirect' => helper::baseUrl() . 'page/edit/' . $this->getUrl(2),
'state' => true
]);
}
@ -704,36 +656,16 @@ class page extends common
/**
* Retourne les informations sur les pages en omettant les clés CSS et JS qui occasionnent des bugs d'affichage dans l'éditeur de page
* @return string tableau associatif des pages dans le menu
* @return array tableau associatif des pages dans le menu
*/
public function getPageInfo()
{
$p = $this->getData(['page']);
$d = array_map(function ($d) {
unset ($d["css"], $d["js"]);
unset($d["css"], $d["js"]);
return $d;
}, $p);
return json_encode($d);
}
/**
* Stocke la variable dans les paramètres de l'utilisateur pour activer la tab à sa prochaine visite
* @return never
*/
public function register(): void
{
$this->setData([
'user',
$this->getUser('id'),
'view',
[
'page' => $this->getUrl(2),
'config' => $this->getData(['user', $this->getUser('id'), 'view', 'config']),
]
]);
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $this->getUrl(3) . '/' . self::$siteContent,
]);
}
}

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -3,7 +3,7 @@
<div class="col1">
<?php echo template::button('pageCssEditorBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(2) . '/' . self::$siteContent,
'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(2),
'value' => template::ico('left')
]); ?>
</div>

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @authorFrédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
@ -15,7 +15,7 @@
/**
* Confirmation de suppression
*/
$("#pageEditDelete").on("click", function() {
$("#pageEditDelete").on("click", function() {
var _this = $(this);
var message_delete = "<?php echo helper::translate('Confirmer la suppression de la page'); ?>";
return core.confirm(message_delete, function() {
@ -67,19 +67,16 @@ $( document ).ready(function() {
/**
* Sélection des onglets
*/
var pageLayout = "<?php echo $this->getData(['user', $this->getUser('id'), 'view', 'page']);?>";
console.log(pageLayout);
// Non défini, valeur par défaut
if (pageLayout == "") {
var pageLayout = getCookie("pageLayout");
if (pageLayout == null) {
pageLayout = "content";
setCookie("pageLayout", "content");
}
// Tout cacher
$("#pageEditContentContainer").hide();
$("#pageEditExtensionContainer").hide();
$("#pageEditPositionContainer").hide();
$("#pageEditLayoutContainer").hide();
$("#pageEditPermissionContainer").hide();
// Afficher la bonne tab
$("#pageEdit" + capitalizeFirstLetter(pageLayout) + "Container").show();
$("#pageEdit" + capitalizeFirstLetter(pageLayout) + "Button").addClass("activeButton");
@ -298,6 +295,7 @@ $( document ).ready(function() {
$("#PageEditPositionButton").removeClass("activeButton");
$("#pageEditLayoutButton").removeClass("activeButton");
$("#pageEditPermissionButton").removeClass("activeButton");
setCookie("pageLayout", "content");
});
$("#pageEditExtensionButton").on("click", function () {
$("#pageEditContentContainer").hide();
@ -310,6 +308,7 @@ $( document ).ready(function() {
$("#PageEditPositionButton").removeClass("activeButton");
$("#pageEditLayoutButton").removeClass("activeButton");
$("#pageEditPermissionButton").removeClass("activeButton");
setCookie("pageLayout", "extension");
});
$("#PageEditPositionButton").on("click", function () {
$("#pageEditContentContainer").hide();
@ -322,6 +321,7 @@ $( document ).ready(function() {
$("#PageEditPositionButton").addClass("activeButton");
$("#pageEditLayoutButton").removeClass("activeButton");
$("#pageEditPermissionButton").removeClass("activeButton");
setCookie("pageLayout", "position");
});
$("#pageEditLayoutButton").on("click", function () {
$("#pageEditContentContainer").hide();
@ -334,6 +334,7 @@ $( document ).ready(function() {
$("#PageEditPositionButton").removeClass("activeButton");
$("#pageEditLayoutButton").addClass("activeButton");
$("#pageEditPermissionButton").removeClass("activeButton");
setCookie("pageLayout", "layout");
});
$("#pageEditPermissionButton").on("click", function () {
$("#pageEditContentContainer").hide();
@ -346,6 +347,7 @@ $( document ).ready(function() {
$("#pageEditPositionButton").removeClass("activeButton");
$("#pageEditLayoutButton").removeClass("activeButton");
$("#pageEditPermissionButton").addClass("activeButton");
setCookie("pageLayout", "permission");
});
/**
@ -720,6 +722,30 @@ function buildPagesList(extraPosition) {
positionDOM.val(positionSelected);
};
/**
* Cookies
*/
function setCookie(name, value, days) {
var expires = "";
if (days) {
var date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
expires = "; expires=" + date.toUTCString();
}
document.cookie = name + "=" + (value || "") + expires + "; path=/; samesite=lax";
}
function getCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') c = c.substring(1, c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
}
return null;
}
// Define function to capitalize the first letter of a string
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);

View File

@ -7,17 +7,26 @@
'value' => template::ico('left')
]); ?>
</div>
<div class="col1 offset7">
<div class="col1">
<?php /**echo template::button('pageEditHelp', [
'href' => 'https://doc.zwiicms.fr/edition-des-pages',
'target' => '_blank',
'value' => template::ico('help'),
'class' => 'buttonHelp',
'help' => 'Consulter l\'aide en ligne'
]); */?>
</div>
<div class="col1 offset6">
<?php echo template::button('pageEditDelete', [
'class' => 'buttonRed',
'href' => helper::baseUrl() . 'page/delete/' . $this->getUrl(2) . '/' . self::$siteContent,
'href' => helper::baseUrl() . 'page/delete/' . $this->getUrl(2),
'value' => template::ico('trash'),
'help' => 'Effacer la page'
]); ?>
</div>
<div class="col1">
<?php echo template::button('pageEditDuplicate', [
'href' => helper::baseUrl() . 'page/duplicate/' . $this->getUrl(2) . '/' . self::$siteContent,
'href' => helper::baseUrl() . 'page/duplicate/' . $this->getUrl(2),
'value' => template::ico('clone'),
'help' => 'Dupliquer la page'
]); ?>
@ -28,31 +37,27 @@
]); ?>
</div>
</div>
<div class="tab">
<?php echo template::button('pageEditContentButton', [
'value' => 'Contenu',
'class' => 'buttonTab',
'href' => helper::baseUrl() . 'page/register/content/' . $this->geturl(2)
'class' => 'buttonTab'
]); ?>
<?php echo template::button('pageEditPositionButton', [
<?php echo template::button('PageEditPositionButton', [
'value' => 'Menu',
'class' => 'buttonTab',
'href' => helper::baseUrl() . 'page/register/position/' . $this->geturl(2)
'class' => 'buttonTab'
]); ?>
<?php echo template::button('pageEditExtensionButton', [
'value' => 'Extension',
'class' => 'buttonTab',
'href' => helper::baseUrl() . 'page/register/extension/' . $this->geturl(2)
'class' => 'buttonTab'
]); ?>
<?php echo template::button('pageEditLayoutButton', [
'value' => 'Mise en page',
'class' => 'buttonTab',
'href' => helper::baseUrl() . 'page/register/layout/' . $this->geturl(2)
'class' => 'buttonTab'
]); ?>
<?php echo template::button('pageEditPermissionButton', [
'value' => 'Permission',
'class' => 'buttonTab',
'href' => helper::baseUrl() . 'page/register/permission/' . $this->geturl(2)
'class' => 'buttonTab'
]); ?>
</div>
@ -62,6 +67,11 @@
<div class="block">
<h4>
<?php echo helper::translate('Titres'); ?>
<!--<span id="infoHelpButton" class="helpDisplayButton">
<a href="https://doc.zwiicms.fr/informations-generales" target="_blank" title="Cliquer pour consulter l'aide en ligne">
<?php //echo template::ico('help', ['margin' => 'left']); ?>
</a>
</span>-->
</h4>
<div class="row">
<div class="col8">
@ -98,7 +108,7 @@
<div class="col12">
<?php echo template::textarea('pageEditContent', [
'class' => 'editorWysiwyg',
'value' => $this->getPage($this->getUrl(2), self::$siteContent)
'value' => $this->getPage($this->getUrl(2), self::$i18nContent)
]); ?>
</div>
</div>
@ -110,6 +120,11 @@
<div class="block">
<h4>
<?php echo helper::translate('Emplacement dans le menu'); ?>
<!--<span id="positionHelpButton" class="helpDisplayButton">
<a href="https://doc.zwiicms.fr/emplacement-dans-le-menu" target="_blank" title="Cliquer pour consulter l'aide en ligne">
<?php //echo template::ico('help', ['margin' => 'left']); ?>
</a>
</span>-->
</h4>
<div class="blockContainer">
<div class="row">
@ -161,6 +176,11 @@
<div class="block">
<h4>
<?php echo helper::translate('Options avancées'); ?>
<!--<span id="advancedHelpButton" class="helpDisplayButton">
<a href="https://doc.zwiicms.fr/options-d-emplacement-avancee" target="_blank" title="Cliquer pour consulter l'aide en ligne">
<?php //echo template::ico('help', ['margin' => 'left']); ?>
</a>
</span>-->
</h4>
<div class="blockContainer">
<div class="row">
@ -175,8 +195,7 @@
'help' => 'Sélectionnez une image ou une icône de petite dimension',
'language' => $this->getData(['user', $this->getUser('id'), 'language']),
'label' => 'Icône',
'value' => $this->getData(['page', $this->getUrl(2), 'iconUrl']),
'folder' => $this->getData(['page', $this->getUrl(2), 'iconUrl']) ? dirname($this->getData(['page', $this->getUrl(2), 'iconUrl'])) : '',
'value' => $this->getData(['page', $this->getUrl(2), 'iconUrl'])
]); ?>
</div>
</div>
@ -273,6 +292,11 @@
<div class="block">
<h4>
<?php echo helper::translate('Mise en page'); ?>
<!--<span id="layoutHelpButton" class="helpDisplayButton">
<a href="https://doc.zwiicms.fr/mise-en-page-2" target="_blank" title="Cliquer pour consulter l'aide en ligne">
<?php //echo template::ico('help', ['margin' => 'left']); ?>
</a>
</span>-->
</h4>
<div class="blockContainer">
<div class="row">
@ -348,6 +372,11 @@
<div class="block">
<h4>
<?php echo helper::translate('Permission et référencement'); ?>
<!--<span id="seoHelpButton" class="helpDisplayButton">
<a href="https://doc.zwiicms.fr/permission-et-referencement" target="_blank" title="Cliquer pour consulter l'aide en ligne">
<?php //echo template::ico('help', ['margin' => 'left']); ?>
</a>
</span>-->
</h4>
<div class="blockContainer">
<div class="row">
@ -395,4 +424,5 @@
</div>
</div>
</div>
<?php echo template::formClose(); ?>

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -3,7 +3,7 @@
<div class="col1">
<?php echo template::button('pageJsEditorBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(2) . '/' . self::$siteContent,
'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(2),
'value' => template::ico('left')
]); ?>
</div>

View File

@ -9,7 +9,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
@ -22,7 +22,7 @@ class plugin extends common
'delete' => self::GROUP_ADMIN,
'save' => self::GROUP_ADMIN,
'store' => self::GROUP_ADMIN,
//'item' => self::GROUP_ADMIN,
'item' => self::GROUP_ADMIN,
// détail d'un objet
'upload' => self::GROUP_ADMIN,
// Téléverser catalogue
@ -314,7 +314,7 @@ class plugin extends common
mkdir(self::FILE_DIR . 'source/modules', 0755);
}
// Sauver les données du fichiers
$this->secure_file_put_contents(self::FILE_DIR . 'source/modules/' . $moduleFile, $moduleData);
file_put_contents(self::FILE_DIR . 'source/modules/' . $moduleFile, $moduleData);
// Installation directe
if (file_exists(self::FILE_DIR . 'source/modules/' . $moduleFile)) {
@ -330,7 +330,6 @@ class plugin extends common
'state' => $r['success']
]);
}
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Catalogue de modules'),
@ -378,7 +377,7 @@ class plugin extends common
$store[$key]['category'],
'<a href="' . self::BASEURL_STORE . self::MODULE_STORE . $key . '" target="_blank" >' . $store[$key]['title'] . '</a>',
$store[$key]['version'],
helper::dateUTF8('%d %B %Y', $store[$key]['versionDate'], self::$i18nUI),
helper::dateUTF8('%d %B %Y', $store[$key]['versionDate'], self::$i18nContent),
implode(' - ', $pageInfos),
template::button('moduleExport' . $key, [
'class' => $class,
@ -404,7 +403,7 @@ class plugin extends common
{
$store = json_decode(helper::getUrlContents(self::BASEURL_STORE . self::MODULE_STORE . 'list'), true);
self::$storeItem = $store[$this->getUrl(2)];
self::$storeItem['fileDate'] = helper::dateUTF8('%d %B %Y', self::$storeItem['fileDate'], self::$i18nUI);
self::$storeItem['fileDate'] = helper::dateUTF8('%d %B %Y', self::$storeItem['fileDate'], self::$i18nContent);
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Module ' . self::$storeItem['title']),
@ -412,15 +411,6 @@ class plugin extends common
]);
}
/**
* Retourne le contenu du store en ligne
* @return mixed
*/
public static function getStore() {
$store = json_decode(helper::getUrlContents(self::BASEURL_STORE . self::MODULE_STORE . 'list'), true);
return $store;
}
/**
* Gestion des modules
*/
@ -541,19 +531,19 @@ class plugin extends common
$infoModules[$pagesInfos[$keyi18n][$keyPage]['moduleId']]['version'],
template::flag($keyi18n, '20px') . '&nbsp<a href ="' . helper::baseUrl() . $keyPage . '" target="_blank">' . $pagesInfos[$keyi18n][$keyPage]['title'] . ' (' . $keyPage . ')</a>',
template::button('dataExport' . $keyPage, [
'href' => helper::baseUrl() . $this->getUrl(0) . '/dataExport/filemanager/' . self::$siteContent . '/' . $pagesInfos[$keyi18n][$keyPage]['moduleId'] . '/' . $keyPage,
'href' => helper::baseUrl() . $this->getUrl(0) . '/dataExport/filemanager/' . self::$i18nContent . '/' . $pagesInfos[$keyi18n][$keyPage]['moduleId'] . '/' . $keyPage,
// appel de fonction vaut exécution, utiliser un paramètre
'value' => template::ico('download-cloud'),
'help' => 'Sauvegarder les données du module dans le gestionnaire de fichiers'
]),
template::button('dataExport' . $keyPage, [
'href' => helper::baseUrl() . $this->getUrl(0) . '/dataExport/download/' . self::$siteContent . '/' . $pagesInfos[$keyi18n][$keyPage]['moduleId'] . '/' . $keyPage,
'href' => helper::baseUrl() . $this->getUrl(0) . '/dataExport/download/' . self::$i18nContent . '/' . $pagesInfos[$keyi18n][$keyPage]['moduleId'] . '/' . $keyPage,
// appel de fonction vaut exécution, utiliser un paramètre
'value' => template::ico('download'),
'help' => 'Sauvegarder et télécharger les données du module'
]),
template::button('dataDelete' . $keyPage, [
'href' => helper::baseUrl() . $this->getUrl(0) . '/dataDelete/' . self::$siteContent . '/' . $pagesInfos[$keyi18n][$keyPage]['moduleId'] . '/' . $keyPage,
'href' => helper::baseUrl() . $this->getUrl(0) . '/dataDelete/' . self::$i18nContent . '/' . $pagesInfos[$keyi18n][$keyPage]['moduleId'] . '/' . $keyPage,
// appel de fonction vaut exécution, utiliser un paramètre
'value' => template::ico('trash'),
'class' => 'buttonRed dataDelete',
@ -566,9 +556,6 @@ class plugin extends common
}
}
// Désactive l'icône rouge
$this->setData(['core', 'updateModuleAvailable', false]);
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Gestion des modules'),

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -3,7 +3,7 @@
<?php echo template::button('configModulesBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl(),
'value' => template::ico('home')
'value' => template::ico('left')
]); ?>
</div>
<div class="col1">

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -8,7 +8,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -11,7 +11,7 @@
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
* @copyright : Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
*/
class theme extends common
@ -304,7 +304,7 @@ class theme extends common
$this->isPost()
) {
// Enregistre le CSS
$this->secure_file_put_contents(self::DATA_DIR . 'custom.css', $this->getInput('themeAdvancedCss', null));
file_put_contents(self::DATA_DIR . 'custom.css', $this->getInput('themeAdvancedCss', null));
// Valeurs en sortie
$this->addOutput([
'notification' => helper::translate('Modifications enregistrées'),
@ -628,16 +628,16 @@ class theme extends common
// Toutes les fontes installées sont chargées
$this->setFonts('all');
// Polices liées au thème admin
$fonts['Titre (admin)'] = $this->getData(['admin', 'fontTitle']);
$fonts['Texte (admin)'] = $this->getData(['admin', 'fontText']);
// Polices liées au thème
$fonts['Bannière'] = $this->getData(['theme', 'header', 'font']);
$fonts['Menu'] = $this->getData(['theme', 'menu', 'font']);
$fonts['Titre'] = $this->getData(['theme', 'title', 'font']);
$fonts['Texte'] = $this->getData(['theme', 'text', 'font']);
$fonts['Pied de page'] = $this->getData(['theme', 'footer', 'font']);
$used = [
'Bannière' => $this->getData(['theme', 'header', 'font']),
'Menu' => $this->getData(['theme', 'menu', 'font']),
'Titre ' => $this->getData(['theme', 'title', 'font']),
'Texte' => $this->getData(['theme', 'text', 'font']),
'Pied de page' => $this->getData(['theme', 'footer', 'font']),
'Titre (admin)' => $this->getData(['admin', 'fontTitle']),
'Admin (texte)' => $this->getData(['admin', 'fontText'])
];
// Récupérer le détail des fontes installées
//$f = $this->getFonts();
@ -649,23 +649,24 @@ class theme extends common
foreach ($f as $type => $typeValue) {
if (is_array($typeValue)) {
foreach ($typeValue as $fontId => $fontValue) {
// Recherche les correspondances
$result = array_filter($fonts, function($value) use ($fontId) {
return $value == $fontId;
});
$keyResults = array_keys($result);
// Préparation du tableau
// Fontes utilisées par les thèmes
$fontUsed[$fontId] = '';
foreach ($used as $key => $value) {
if ($value === $fontId) {
$fontUsed[$fontId] .= $key . '<br/>';
}
}
self::$fontsDetail[] = [
$fontId,
'<span style="font-family:' . $f[$type][$fontId]['font-family'] . '">' . $f[$type][$fontId]['name'] . '</span>',
$f[$type][$fontId]['font-family'],
empty($keyResults) ? '' : '<span class="fontsList">' . implode('<br />', $keyResults) . '</span>',
$fontUsed[$fontId],
$type,
$type !== 'websafe' ? template::button('themeFontEdit' . $fontId, [
'class' => 'themeFontEdit',
'href' => helper::baseUrl() . $this->getUrl(0) . '/fontEdit/' . $type . '/' . $fontId,
'value' => template::ico('pencil'),
//'disabled' => !empty($fontUsed[$fontId])
'disabled' => !empty($fontUsed[$fontId])
])
: '',
$type !== 'websafe' ? template::button('themeFontDelete' . $fontId, [
@ -683,10 +684,7 @@ class theme extends common
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Fontes'),
'view' => 'font',
'vendor' => [
'datatables'
]
'view' => 'font'
]);
}
@ -703,8 +701,8 @@ class theme extends common
// Type d'import en ligne ou local
$type = $this->getInput('fontAddUrl', helper::FILTER_BOOLEAN) ? 'imported' : 'files';
$type === 'files' ? 'imported' : 'files';
$resource = $type === 'imported' ? $this->getInput('fontAddUrl', null) : $this->getInput('fontAddFile', null);
if (!empty($resource)) {
$ressource = $type === 'imported' ? $this->getInput('fontAddUrl', null) : $this->getInput('fontAddFile', null);
if (!empty($ressource)) {
$fontId = $this->getInput('fontAddFontId', null, true);
$fontName = $this->getInput('fontAddFontName', null, true);
$fontFamilyName = $this->getInput('fontAddFontFamilyName', null, true);
@ -716,21 +714,6 @@ class theme extends common
if (is_array($this->getData(['font', $type, $fontId]))) {
$this->deleteData(['font', $type, $fontId]);
}
// Paramètres de la sortie vrai par défaut, c'est une fonte en ligne
$success = true;
// Copier la fonte si le nom du fichier est fourni
if (!is_dir(self::DATA_DIR . 'font/')) {
mkdir(self::DATA_DIR . 'font/');
}
if (
$type === 'files' &&
file_exists(self::FILE_DIR . 'source/' . $resource)
) {
$success = copy(self::FILE_DIR . 'source/' . $resource, self::DATA_DIR . 'font/' . basename($resource));
}
// Stocker la fonte
$this->setData([
'font',
@ -739,16 +722,24 @@ class theme extends common
[
'name' => $fontName,
'font-family' => $fontFamilyName,
// Stocke l'URL our lien vers la fonte dans data
'resource' => $type === 'imported' ? $resource : self::DATA_DIR . 'font/' . basename($resource),
'resource' => $ressource
]
]);
// Copier la fonte si le nom du fichier est fourni
if (
$type === 'files' &&
file_exists(self::FILE_DIR . 'source/' . $ressource)
) {
copy(self::FILE_DIR . 'source/' . $ressource, self::DATA_DIR . 'font/' . $ressource);
}
// Valeurs en sortie
$this->addOutput([
'notification' => $success ? helper::translate('Fonte actualisée') : helper::translate('Fonte non créée, ressource absente !'),
'redirect' => helper::baseUrl() . 'theme/font',
'state' => $success
'notification' => helper::translate('Fonte créée'),
'redirect' => helper::baseUrl() . 'theme/fonts',
'state' => true
]);
} else {
// Valeurs en sortie
@ -779,8 +770,8 @@ class theme extends common
) {
// Type d'import en ligne ou local
$type = $this->getInput('fontEditUrl', helper::FILTER_BOOLEAN) ? 'imported' : 'files';
$ressource = $type === 'imported' ? $this->getInput('fontEditUrl', null) : $this->getInput('fontEditFile', null);
$fontId = $this->getInput('fontEditFontId', null, true);
$resource = $this->getData(['font', $type, $fontId, 'resource']);
$fontName = $this->getInput('fontEditFontName', null, true);
$fontFamilyName = $this->getInput('fontEditFontFamilyName', null, true);
@ -792,7 +783,6 @@ class theme extends common
$this->deleteData(['font', $type, $fontId]);
}
// Stocker les fontes
$this->setData([
'font',
@ -801,14 +791,21 @@ class theme extends common
[
'name' => $fontName,
'font-family' => $fontFamilyName,
'resource' => $resource
'resource' => $ressource
]
]);
// Copier la fonte si le nom du fichier est fourni
if (
$type === 'files' &&
file_exists(self::FILE_DIR . 'source/' . $ressource)
) {
copy(self::FILE_DIR . 'source/' . $ressource, self::DATA_DIR . 'font/' . $ressource);
}
// Valeurs en sortie
$this->addOutput([
'notification' => helper::translate('Fonte actualisée'),
'redirect' => helper::baseUrl() . 'theme/font',
'redirect' => helper::baseUrl() . 'theme/fonts',
'state' => true
]);
}
@ -842,16 +839,15 @@ class theme extends common
// Effacer le fichier existant
if (
$this->getUrl(2) === 'files' &&
file_exists($this->getData(['font', 'files', $this->getUrl(3), 'resource']))
$this->getUrl(2) === 'file' &&
file_exists(self::DATA_DIR . $this->getUrl(2))
) {
unlink($this->getData(['font', 'files', $this->getUrl(3), 'resource']));
unlink(self::DATA_DIR . $this->getUrl(2));
}
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'theme/font',
'redirect' => helper::baseUrl() . 'theme/fonts',
'notification' => helper::translate('Fonte supprimée'),
'state' => true
]);
@ -1225,15 +1221,13 @@ class theme extends common
// Ajoute les fontes
$zip->addEmptyDir(self::DATA_DIR . 'font');
$fonts = $this->getData(['font', 'files']);
foreach ($fonts as $fontId => $fontInfo) {
$zip->addFile($fontInfo['resource'], $fontInfo['resource']);
foreach ($fonts as $fontId => $fontName) {
$zip->addFile(self::DATA_DIR . 'font/' . $fontName, self::DATA_DIR . 'font/' . $fontName);
}
if (file_exists(self::DATA_DIR . 'font/font.html')) {
$zip->addFile(self::DATA_DIR . 'font/font.html', self::DATA_DIR . 'font/font.html');
}
if (file_exists(self::DATA_DIR . 'font/font.css')) {
$zip->addFile(self::DATA_DIR . 'font/font.css', self::DATA_DIR . 'font/font.css');
}
break;
}
$ret = $zip->close();
@ -1290,7 +1284,7 @@ class theme extends common
}
// Sauvegarder la chaîne modifiée
if ($count > 0) {
$this->secure_file_put_contents($file, $data);
file_put_contents($file, $data);
}
// Retourner le nombre d'occurrences
return ($count);
@ -1380,13 +1374,13 @@ class theme extends common
($scope === 'user' && in_array($fontId, $fontsInstalled))
|| $scope === 'all'
) {
if (file_exists($fontValue['resource'])) {
if (file_exists(self::DATA_DIR . 'font/' . $fontValue['resource'])) {
// Extension
$path_parts = pathinfo(helper::baseUrl(false) . self::DATA_DIR . 'font/' . $fontValue['resource']);
// Chargement de la police
$fileContentCss .= '@font-face {';
$fileContentCss .= 'font-family:"' . $fontValue['name'] . '";';
$fileContentCss .= 'src: url("' . helper::baseUrl(false) . $fontValue['resource'] . '") format("' . $path_parts['extension'] . '");';
$fileContentCss .= 'src: url("' . $fontValue['resource'] . '") format("' . $path_parts['extension'] . '");';
$fileContentCss .= '}';
// Préchargement
//$fileContent = '<link rel="preload" href="' . self::DATA_DIR . 'font/' . $fontValue['resource'] . '" type="font/woff" crossorigin="anonymous" as="font">' . $fileContent;
@ -1396,8 +1390,8 @@ class theme extends common
}
// Enregistre la personnalisation
$this->secure_file_put_contents(self::DATA_DIR . 'font/font.html', $fileContent);
file_put_contents(self::DATA_DIR . 'font/font.html', $fileContent);
// Enregistre la personnalisation
$this->secure_file_put_contents(self::DATA_DIR . 'font/font.css', $fileContentCss);
file_put_contents(self::DATA_DIR . 'font/font.css', $fileContentCss);
}
}

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -6,7 +6,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -7,7 +7,7 @@
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @link http://zwiicms.fr/
*/

View File

@ -6,7 +6,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -7,7 +7,15 @@
'value' => template::ico('left')
]); ?>
</div>
<div class="col2 offset9">
<div class="col1">
<?php /* echo template::button('themeBodyHelp', [
'href' => 'https://doc.zwiicms.fr/arriere-plan',
'target' => '_blank',
'value' => template::ico('help'),
'class' => 'buttonHelp'
]); */ ?>
</div>
<div class="col2 offset8">
<?php echo template::submit('themeBodySubmit'); ?>
</div>
</div>
@ -60,8 +68,7 @@
'language' => $this->getData(['user', $this->getUser('id'), 'language']),
'label' => 'Arrière plan',
'type' => 1,
'value' => $imageFile,
'folder' => $imageFile ? dirname($imageFile) : ''
'value' => $imageFile
]); ?>
</div>
</div>

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -4,32 +4,8 @@
* file that was distributed with this source code.
*
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
$(".themeFontDelete").on("click", (function() {
var _this = $(this);
return core.confirm("Êtes-vous sûr de vouloir supprimer cette fonte ?", (function() {
$(location).attr("href", _this.attr("href"))
}))
}));
$('#dataTables').DataTable({
language: {
url: "core/vendor/datatables/french.json",
},
locale: 'fr',
stateSave: true,
"lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "Tout"]],
"columnDefs": [{
target: 5,
orderable: false,
searchable: false
},
{
target: 6,
orderable: false,
searchable: false
}
]
});
$(".themeFontDelete").on("click",(function(){var _this=$(this);return core.confirm("Êtes-vous sûr de vouloir supprimer cette fonte ?",(function(){$(location).attr("href",_this.attr("href"))}))}));

View File

@ -24,7 +24,7 @@
</div>
</div>
<?php if ($module::$fontsDetail) : ?>
<?php echo template::table([2, 2, 3, 2, 1, 1, 1], $module::$fontsDetail, ['FontId', 'Nom', 'Famille', 'Affectation', 'Origine', '', ''], ['id' => 'dataTables']); ?>
<?php echo template::table([2, 2, 3, 2, 1, 1, 1], $module::$fontsDetail, ['FontId', 'Nom', 'Famille', 'Affectation', 'Origine', '', '']); ?>
<?php else : ?>
<?php echo template::speech('Aucune fonte !'); ?>
<?php endif; ?>

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -4,34 +4,8 @@
* file that was distributed with this source code.
*
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
$(document).ready(function () {
$("input[name=fontAddFontImported]").on("click", (function () {
$("input[name=fontAddFontImported]").is(":checked") ? $("input[name=fontAddFontFile]").prop("checked", !1) : $("input[name=fontAddFontFile]").prop("checked", !0), $("#containerFontAddFile").hide(), $("#containerFontAddUrl").show()
})), $("input[name=fontAddFontFile]").on("click", (function () {
$("input[name=fontAddFontFile]").is(":checked") ? $("input[name=fontAddFontImported]").prop("checked", !1) : $("input[name=fontAddFontImported]").prop("checked", !0), $("#containerFontAddFile").show(), $("#containerFontAddUrl").hide()
}));
// Exemple d'utilisation : appel de la fonction à chaque saisie dans le champ texte
$('#fontAddFontId').on('input', function () {
cleanString();
});
// Fonction pour supprimer les espaces et convertir en minuscules
function cleanString() {
var champTexte = $('#fontAddFontId');
var texte = champTexte.val();
texte = texte.replace(/\s/g, ''); // Supprimer les espaces
texte = texte.toLowerCase(); // Convertir en minuscules
champTexte.val(texte); // Mettre à jour le champ texte avec la nouvelle valeur
}
});
$("input[name=fontAddFontImported]").on("click",(function(){$("input[name=fontAddFontImported]").is(":checked")?$("input[name=fontAddFontFile]").prop("checked",!1):$("input[name=fontAddFontFile]").prop("checked",!0),$("#containerFontAddFile").hide(),$("#containerFontAddUrl").show()})),$("input[name=fontAddFontFile]").on("click",(function(){$("input[name=fontAddFontFile]").is(":checked")?$("input[name=fontAddFontImported]").prop("checked",!1):$("input[name=fontAddFontImported]").prop("checked",!0),$("#containerFontAddFile").show(),$("#containerFontAddUrl").hide()}));

View File

@ -3,7 +3,7 @@
<div class="col1">
<?php echo template::button('fontAddBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'theme/font',
'href' => helper::baseUrl() . 'theme/fonts',
'value' => template::ico('left')
]); ?>
</div>

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -4,7 +4,7 @@
* file that was distributed with this source code.
*
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

View File

@ -3,7 +3,7 @@
<div class="col1">
<?php echo template::button('fontEditBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'theme/font',
'href' => helper::baseUrl() . 'theme/fonts',
'value' => template::ico('left')
]); ?>
</div>
@ -44,8 +44,7 @@
<?php echo template::text('fontEditFontId', [
'autocomplete' => 'off',
'label' => 'Identifiant (sans espace ni majuscule)',
'value' => $this->getUrl(3),
'readonly' => true
'value' => $this->getUrl(3)
]); ?>
</div>
<div class="col6">
@ -67,10 +66,10 @@
</div>
<div class="row" id="containerfontEditFile">
<div class="col12">
<?php echo template::text('fontEditFile', [
<?php echo template::file('fontEditFile', [
'label' => 'Fichier de fonte (Format WOFF)',
'value' => $this->getUrl(2) === 'files' ? $this->getData(['font', $this->getUrl(2), $this->getUrl(3), 'resource']) : '',
'readonly' => true
'language' => $this->getData(['user', $this->getUser('id'), 'language']),
'value' => $this->getUrl(2) === 'files' ? $this->getData(['font', $this->getUrl(2), $this->getUrl(3), 'resource']) : ''
]); ?>
</div>
</div>

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

File diff suppressed because one or more lines are too long

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2024, Frédéric Tempez
* @copyright Copyright (C) 2018-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/

Some files were not shown because too many files have changed in this diff Show More