Compare commits

..

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

312 changed files with 1811 additions and 3410 deletions

2
.gitignore vendored
View File

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

View File

@ -32,16 +32,5 @@ Options -Indexes
Options -MultiViews Options -MultiViews
</IfModule> </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 ! # ne pas supprimer la ligne URL rewriting !
# URL rewriting # URL rewriting

1160
CHANGES.md

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
# ZwiiCMS 13.3.03 # ZwiiCMS 13.0.04
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. 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.
@ -13,15 +13,16 @@ ZwiiCMS a été créé par un développeur de talent, [Rémi Jean](https://remij
## Licence ## Licence
Cette œuvre est mise à disposition sous licence Attribution - Pas d'utilisation Commerciale - Pas de Modification 4.0 International. Cette œuvre est mise à disposition sous licence Attribution - Pas d'utilisation Commerciale - Pas de Modification 4.0 International.
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. 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.
## Téléchargement de ZwiiCMS ## Téléchargement de ZwiiCMS
Pour télécharger la dernière version publiée, rendez-vous : Pour télécharger la dernière version publiée, rendez-vous :
* sur [la page des mises à jour](https://forge.chapril.org/ZwiiCMS-Team/ZwiiCMS/releases) - sur [la page des mises à jour](https://forge.chapril.org/ZwiiCMS-Team/ZwiiCMS/releases)
* ou sur [la page de téléchargement du site](https://zwiicms.fr/telechargement) - ou sur [la page de téléchargement du site](https://zwiicms.fr/telechargement)
## Installation ## Installation
@ -29,6 +30,7 @@ Décompressez l'archive de Zwii et téléversez son contenu à la racine de votr
Vous trouverez de plus amples explications, en particulier pour une installation chez Free, dans la rubrique "Téléchargements" du forum. Vous trouverez de plus amples explications, en particulier pour une installation chez Free, dans la rubrique "Téléchargements" du forum.
## Procédures de mise à jour ## Procédures de mise à jour
A l'occasion de l'installation d'une verion majeure, il est recommandé de réaliser une copie de sauvegarde. A l'occasion de l'installation d'une verion majeure, il est recommandé de réaliser une copie de sauvegarde.
@ -45,6 +47,7 @@ A l'occasion de l'installation d'une verion majeure, il est recommandé de réal
* Décompressez la nouvelle version sur votre ordinateur. * Décompressez la nouvelle version sur votre ordinateur.
* Transférez son contenu sur votre serveur en activant le remplacement des fichiers. * Transférez son contenu sur votre serveur en activant le remplacement des fichiers.
## Arborescence générale ## Arborescence générale
*Légende : [R] Répertoire - [F] Fichier* *Légende : [R] Répertoire - [F] Fichier*
@ -76,9 +79,9 @@ A l'occasion de l'installation d'une verion majeure, il est recommandé de réal
[F] .default Indicateur de la langue de site par défaut [F] .default Indicateur de la langue de site par défaut
[R] content Dossier des contenus de page [R] content Dossier des contenus de page
[F] accueil.html Exemple contenu de la page d'accueil [F] accueil.html Exemple contenu de la page d'accueil
[R] font Dossier contenant les fontes installées [R] fonts Dossier contenant les fontes installées
[F] font.html Fichier contenant les appels des fontes à charger sur cdnFonts [F] font.html Fichier contenant les appels des fontes à charger sur cdnFonts
[F] font.css Fichier contenant la feuille de style liée aux polices de caractères locales [F] fonts.css Fichier contenant la feuille de style liée aux polices de caractères locales
[F] fontes.woff Fichiers locaux des fontes (woff, etc..) [F] fontes.woff Fichiers locaux des fontes (woff, etc..)
[R] modules Personnalisation des modules ou données propres [R] modules Personnalisation des modules ou données propres
[F] admin.css Thème des pages d'administration [F] admin.css Thème des pages d'administration

View File

@ -1,4 +1,4 @@
# ZwiiCMS 13.3.03 # ZwiiCMS 13.0.04
Zwii is a database-less (flat-file) CMS that allows you to easily create and manage a web site without any programming knowledge. Zwii is a database-less (flat-file) CMS that allows you to easily create and manage a web site without any programming knowledge.
@ -13,15 +13,16 @@ ZwiiCMS was created by a talented developer, [Rémi Jean](https://remijean.fr/).
## License ## License
This work is licensed under the Attribution-Noncommercial-No Derivative Works 4.0 International License. This work is licensed under the Attribution-Noncommercial-No Derivative Works 4.0 International License.
To view a copy of this license, visit <http://creativecommons.org/licenses/by-nc-nd/4.0/> or write to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/ or write to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
## Downloading ZwiiCMS ## Downloading ZwiiCMS
To download the latest released version, go to : To download the latest released version, go to :
* [the Updates page](https://forge.chapril.org/ZwiiCMS-Team/ZwiiCMS/releases) - [the Updates page](https://forge.chapril.org/ZwiiCMS-Team/ZwiiCMS/releases)
* or at [the site download page](https://zwiicms.fr/download) - or at [the site download page](https://zwiicms.fr/download)
## Installation ## Installation
@ -29,6 +30,7 @@ Unzip the Zwii archive and upload its contents to the root of your server or to
You will find more explanations, in particular for an installation at Free, in the "Downloads" section of the forum. You will find more explanations, in particular for an installation at Free, in the "Downloads" section of the forum.
## Update procedures ## Update procedures
When installing a major version, it is recommended to make a backup copy. When installing a major version, it is recommended to make a backup copy.
@ -45,6 +47,7 @@ When installing a major version, it is recommended to make a backup copy.
* Unzip the new version on your computer. * Unzip the new version on your computer.
* Transfer its content to your server by activating the file replacement. * Transfer its content to your server by activating the file replacement.
## General tree structure ## General tree structure
*Legend: [D] Directory - [FILE] File *Legend: [D] Directory - [FILE] File

View File

@ -77,7 +77,7 @@ class helper
// Créer la variable // Créer la variable
$data = array_merge($data, [$text => '']); $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);
} }
} }
@ -338,12 +338,13 @@ class helper
{ {
// N'interroge que le serveur Apache // N'interroge que le serveur Apache
if (strpos($_SERVER["SERVER_SOFTWARE"], 'Apache') > 0) { if (strpos($_SERVER["SERVER_SOFTWARE"], 'Apache') > 0) {
self::$rewriteStatus = false; self::$rewriteStatus === false;
} else { } elseif (self::$rewriteStatus === null) {
// Ouvre et scinde le fichier .htaccess // Ouvre et scinde le fichier .htaccess
$htaccess = explode('# URL rewriting', file_get_contents('.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 // 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; return self::$rewriteStatus;
} }
@ -367,7 +368,7 @@ class helper
$version = helper::getOnlineVersion($channel); $version = helper::getOnlineVersion($channel);
$update = false; $update = false;
if (!empty($version)) { if (!empty($version)) {
$update = version_compare(common::ZWII_VERSION, $version) == -1; $update = version_compare(common::ZWII_VERSION, $version) === -1;
} }
return $update; return $update;
} }

View File

@ -141,7 +141,7 @@ class Dot implements \ArrayAccess, \Iterator, \Countable
} elseif (is_array($key)) { } elseif (is_array($key)) {
// Iterate array of paths // Iterate array of paths
foreach ($key as $k) { 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 $db = '';
protected $data = null; protected $data = null;
protected $config = []; 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 = []) public function __construct($config = [])
{ {
@ -127,10 +121,10 @@ class JsonDb extends \Prowebcraft\Dot
} else { } else {
if ($this->config['backup']) { if ($this->config['backup']) {
try { try {
//todo make backup of database
copy($this->config['dir'] . DIRECTORY_SEPARATOR . $this->config['name'], $this->config['dir'] . DIRECTORY_SEPARATOR . $this->config['name'] . '.backup'); copy($this->config['dir'] . DIRECTORY_SEPARATOR . $this->config['name'], $this->config['dir'] . DIRECTORY_SEPARATOR . $this->config['name'] . '.backup');
} catch (\Exception $e) { } catch (\Exception $e) {
error_log('Erreur de chargement : ' . $e);
exit('Erreur de chargement : ' . $e);
} }
} }
} }
@ -148,40 +142,20 @@ class JsonDb extends \Prowebcraft\Dot
*/ */
public function save() public function save()
{ {
// Encode les données au format JSON avec les options spécifiées //$v = json_encode($this->data, JSON_UNESCAPED_UNICODE );
$encoded_data = json_encode($this->data, JSON_UNESCAPED_UNICODE | JSON_FORCE_OBJECT | JSON_PRETTY_PRINT); $v = json_encode($this->data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_FORCE_OBJECT);
$l = strlen($v);
// Vérifie la longueur de la chaîne JSON encodée $t = 0;
$encoded_length = strlen($encoded_data); while ($t < 5) {
$w = file_put_contents($this->db, $v); // Multi user get a locker
// Initialise le compteur de tentatives if ($w == $l) {
$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
break; break;
} }
$t++;
// Incrémente le compteur de tentatives }
$attempt++; if ($w !== $l) {
exit('Erreur d\'écriture, les données n\'ont pas été sauvegardées');
// Attente
sleep(1);
} }
// 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

@ -151,7 +151,7 @@ class layout extends common
} }
echo '</div>'; echo '</div>';
} }
echo '</section></main>'; echo '</main></section>';
} }
/** /**
@ -506,7 +506,7 @@ class layout extends common
} }
// Commandes pour les membres simples // Commandes pour les membres simples
if ( 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 && $this->getData(['theme', 'menu', 'memberBar']) === true
) { ) {
if ( if (
@ -911,7 +911,7 @@ class layout extends common
foreach (self::$languages as $key => $value) { foreach (self::$languages as $key => $value) {
if (is_dir(self::DATA_DIR . $key)) { if (is_dir(self::DATA_DIR . $key)) {
$location = helper::baseUrl() . 'language/content/' . $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" >'; $leftItems .= '<li><select id="barSelectLanguage" >';
@ -980,7 +980,7 @@ class layout extends common
// Bouton Ajouter une page // Bouton Ajouter une page
if ($this->getUser('permission', 'page', 'add')) { if ($this->getUser('permission', 'page', 'add')) {
$leftItems .= '<li>' . template::ico('plus', [ $leftItems .= '<li>' . template::ico('plus', [
'href' => helper::baseUrl() . 'page/add/' . self::$siteContent, 'href' => helper::baseUrl() . 'page/add',
'help' => 'Nouvelle page ou barre latérale' 'help' => 'Nouvelle page ou barre latérale'
]) . '</li>'; ]) . '</li>';
} }
@ -990,27 +990,23 @@ class layout extends common
// Sur une page sans module // Sur une page sans module
or $this->getData(['page', $this->getUrl(0), 'moduleId']) === '' or $this->getData(['page', $this->getUrl(0), 'moduleId']) === ''
// Sur une page avec un module invalide // 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'])) !class_exists($this->getData(['page', $this->getUrl(2), 'moduleId']))
) )
// Sur une page d'accueil // Sur une page d'accueil
or $this->getUrl(0) === '' or $this->getUrl(0) === ''
) { ) {
// Bouton Editer une page // Bouton Editer une page
if ( if ($this->getUser('permission', 'page', 'edit')) {
$this->getUser('permission', 'page', 'edit')
and $this->geturl(1) !== 'edit'
) {
$leftItems .= '<li>' . template::ico('pencil', [ $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' 'help' => 'Éditer la page'
]) . '</li>'; ]) . '</li>';
} }
// Bouton Editer le module d'une page // Bouton Editer le module d'une page
if ( if (
$this->getUser('permission', 'page', 'module') $this->getUser('permission', 'page', 'module')
and $this->geturl(1) !== 'edit' && $this->getData(['page', $this->getUrl(0), 'moduleId'])
and $this->getData(['page', $this->getUrl(0), 'moduleId'])
) { ) {
$leftItems .= '<li>' . template::ico('gear', [ $leftItems .= '<li>' . template::ico('gear', [
'href' => helper::baseUrl() . $this->getUrl(0) . '/config', 'href' => helper::baseUrl() . $this->getUrl(0) . '/config',
@ -1020,10 +1016,9 @@ class layout extends common
// Bouton dupliquer une page // Bouton dupliquer une page
if ( if (
$this->getUser('permission', 'page', 'duplicate') $this->getUser('permission', 'page', 'duplicate')
and $this->geturl(1) !== 'edit'
) { ) {
$leftItems .= '<li>' . template::ico('clone', [ $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' 'help' => 'Dupliquer la page'
]) ])
. '</li>'; . '</li>';
@ -1031,11 +1026,9 @@ class layout extends common
// Bouton Effacer une page // Bouton Effacer une page
if ( if (
$this->getUser('permission', 'page', 'delete') $this->getUser('permission', 'page', 'delete')
and $this->geturl(1) !== 'edit'
) { ) {
$leftItems .= '<li>' . template::ico('trash', [ $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', 'help' => 'Supprimer la page',
'id' => 'pageDelete' 'id' => 'pageDelete'
]) ])
@ -1175,7 +1168,7 @@ class layout extends common
{ {
// Import des fontes liées au thème // Import des fontes liées au thème
if (file_exists(self::DATA_DIR . 'font/font.html')) { if (file_exists(self::DATA_DIR . 'font/font.html')) {
include_once (self::DATA_DIR . 'font/font.html'); include_once(self::DATA_DIR . 'font/font.html');
} }
} }
@ -1237,8 +1230,8 @@ class layout extends common
public function showi18n($lang) public function showi18n($lang)
{ {
if ( if (
(isset($_SESSION['ZWII_SITE_CONTENT']) (isset($_SESSION['ZWII_CONTENT'])
and $_SESSION['ZWII_SITE_CONTENT'] === $lang and $_SESSION['ZWII_CONTENT'] === $lang
) )
) { ) {
$select = ' class="i18nFlagSelected" '; $select = ' class="i18nFlagSelected" ';
@ -1274,9 +1267,6 @@ class layout extends common
// Trouver la clé de l'élément recherché // Trouver la clé de l'élément recherché
$key = array_search($elementToFind, $hierarchy); $key = array_search($elementToFind, $hierarchy);
$previousPage = null;
$nextPage = null;
if ($key !== false) { if ($key !== false) {
// Trouver l'élément précédent // Trouver l'élément précédent
$previousKey = ($key > 0) ? $key - 1 : null; $previousKey = ($key > 0) ? $key - 1 : null;
@ -1299,9 +1289,7 @@ class layout extends common
$items = '<div class="navButton">'; $items = '<div class="navButton">';
$items .= '<div class="row">'; $items .= '<div class="row">';
$items .= '<div class="col1">'; $items .= '<div class="col1">';
if ( if ($previousPage !== null and $this->getData(['page', $this->getUrl(0), 'navLeft']) === $position) {
$previousPage !== null && $this->getData(['page', $this->getUrl(0), 'navLeft']) === $position
) {
$items .= template::button('navPreviousButtonLeft', [ $items .= template::button('navPreviousButtonLeft', [
'href' => helper::baseUrl() . $previousPage, 'href' => helper::baseUrl() . $previousPage,
'value' => template::ico($leftButton) 'value' => template::ico($leftButton)
@ -1309,7 +1297,7 @@ class layout extends common
} }
$items .= '</div>'; $items .= '</div>';
$items .= '<div class="col1 offset10">'; $items .= '<div class="col1 offset10">';
if ($nextPage !== null && $this->getData(['page', $this->getUrl(0), 'navRight']) === $position) { if ($nextPage !== null and $this->getData(['page', $this->getUrl(0), 'navRight']) === $position) {
$items .= template::button('navNextButtonRight', [ $items .= template::button('navNextButtonRight', [
'href' => helper::baseUrl() . $nextPage, 'href' => helper::baseUrl() . $nextPage,
'value' => template::ico($rightButton) 'value' => template::ico($rightButton)

View File

@ -15,12 +15,12 @@ class core extends common
} }
// Fuseau horaire // Fuseau horaire
common::$timezone = $this->getData(['config', 'timezone']); // Utile pour transmettre le timezone à la classe helper self::$timezone = $this->getData(['config', 'timezone']); // Utile pour transmettre le timezone à la classe helper
date_default_timezone_set(common::$timezone); date_default_timezone_set(self::$timezone);
// Supprime les fichiers temporaires // Supprime les fichiers temporaires
$lastClearTmp = mktime(0, 0, 0); $lastClearTmp = mktime(0, 0, 0);
if ($lastClearTmp > $this->getData(['core', 'lastClearTmp']) + 86400) { if ($lastClearTmp > $this->getData(['core', 'lastClearTmp']) + 86400) {
$iterator = new DirectoryIterator(common::TEMP_DIR); $iterator = new DirectoryIterator(self::TEMP_DIR);
foreach ($iterator as $fileInfos) { foreach ($iterator as $fileInfos) {
if ( if (
$fileInfos->isFile() && $fileInfos->isFile() &&
@ -43,11 +43,11 @@ class core extends common
and $this->getData(['user']) // Pas de backup pendant l'installation and $this->getData(['user']) // Pas de backup pendant l'installation
) { ) {
// Copie des fichier de données // 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 // Date du dernier backup
$this->setData(['core', 'lastBackup', $lastBackup]); $this->setData(['core', 'lastBackup', $lastBackup]);
// Supprime les backups de plus de 30 jours // Supprime les backups de plus de 30 jours
$iterator = new DirectoryIterator(common::BACKUP_DIR); $iterator = new DirectoryIterator(self::BACKUP_DIR);
foreach ($iterator as $fileInfos) { foreach ($iterator as $fileInfos) {
if ( if (
$fileInfos->isFile() $fileInfos->isFile()
@ -60,23 +60,23 @@ class core extends common
} }
// Crée le fichier de personnalisation avancée // Crée le fichier de personnalisation avancée
if (file_exists(common::DATA_DIR . 'custom.css') === false) { if (file_exists(self::DATA_DIR . 'custom.css') === false) {
$this->secure_file_put_contents(common::DATA_DIR . 'custom.css', file_get_contents('core/module/theme/resource/custom.css')); file_put_contents(self::DATA_DIR . 'custom.css', file_get_contents('core/module/theme/resource/custom.css'));
chmod(common::DATA_DIR . 'custom.css', 0755); chmod(self::DATA_DIR . 'custom.css', 0755);
} }
// Crée le fichier de personnalisation // Crée le fichier de personnalisation
if (file_exists(common::DATA_DIR . 'theme.css') === false) { if (file_exists(self::DATA_DIR . 'theme.css') === false) {
$this->secure_file_put_contents(common::DATA_DIR . 'theme.css', ''); file_put_contents(self::DATA_DIR . 'theme.css', '');
chmod(common::DATA_DIR . 'theme.css', 0755); chmod(self::DATA_DIR . 'theme.css', 0755);
} }
// Crée le fichier de personnalisation de l'administration // Crée le fichier de personnalisation de l'administration
if (file_exists(common::DATA_DIR . 'admin.css') === false) { if (file_exists(self::DATA_DIR . 'admin.css') === false) {
$this->secure_file_put_contents(common::DATA_DIR . 'admin.css', ''); file_put_contents(self::DATA_DIR . 'admin.css', '');
chmod(common::DATA_DIR . 'admin.css', 0755); chmod(self::DATA_DIR . 'admin.css', 0755);
} }
// Check la version rafraichissement du theme // 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'])))) { if (empty($cssVersion[1]) or $cssVersion[1] !== md5(json_encode($this->getData(['theme'])))) {
// Version // Version
$css = '/*' . md5(json_encode($this->getData(['theme']))) . '*/'; $css = '/*' . md5(json_encode($this->getData(['theme']))) . '*/';
@ -92,7 +92,7 @@ class core extends common
// Fonts disponibles // Fonts disponibles
$fontsAvailable['files'] = $this->getData(['font', 'files']); $fontsAvailable['files'] = $this->getData(['font', 'files']);
$fontsAvailable['imported'] = $this->getData(['font', 'imported']); $fontsAvailable['imported'] = $this->getData(['font', 'imported']);
$fontsAvailable['websafe'] = common::$fontsWebSafe; $fontsAvailable['websafe'] = self::$fontsWebSafe;
// Fontes installées // Fontes installées
$fonts = [ $fonts = [
@ -105,14 +105,53 @@ class core extends common
// Suppression des polices identiques // Suppression des polices identiques
$fonts = array_unique($fonts); $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 ($fonts as $fontId) {
foreach (['websafe', 'imported', 'files'] as $typeFont) { // Validité du tableau :
if (isset($fontsAvailable[$typeFont][$fontId])) { if (isset($fontsAvailable['files'][$fontId])) {
$fonts[$fontId] = $fontsAvailable[$typeFont][$fontId]['font-family']; 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 .= '#footerText > p {text-align:' . $this->getData(['theme', 'footer', 'textAlign']) . '}';
$css .= '#footerCopyright{text-align:' . $this->getData(['theme', 'footer', 'copyrightAlign']) . '}'; $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 // 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 // Effacer le cache pour tenir compte de la couleur de fond TinyMCE
header("Expires: Tue, 01 Jan 2000 00:00:00 GMT"); 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 // 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'])))) { if (empty($cssVersion[1]) or $cssVersion[1] !== md5(json_encode($this->getData(['admin'])))) {
// Version // Version
@ -293,7 +338,7 @@ class core extends common
// Fonts disponibles // Fonts disponibles
$fontsAvailable['files'] = $this->getData(['font', 'files']); $fontsAvailable['files'] = $this->getData(['font', 'files']);
$fontsAvailable['imported'] = $this->getData(['font', 'imported']); $fontsAvailable['imported'] = $this->getData(['font', 'imported']);
$fontsAvailable['websafe'] = common::$fontsWebSafe; $fontsAvailable['websafe'] = self::$fontsWebSafe;
/** /**
* Import des polices de caractères * Import des polices de caractères
@ -307,12 +352,44 @@ class core extends common
$fonts = array_unique($fonts); $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 ($fonts as $fontId) {
foreach (['websafe', 'imported', 'files'] as $typeFont) { // Validité du tableau :
if (isset($fontsAvailable[$typeFont][$fontId])) { if (isset($fontsAvailable['files'][$fontId])) {
$fonts[$fontId] = $fontsAvailable[$typeFont][$fontId]['font-family']; 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';
} }
} }
} }
@ -323,26 +400,6 @@ class core extends common
$css .= 'p, div, label, select, input, table, span {font-family:' . $fonts[$this->getData(['admin', 'fontText'])] . '}'; $css .= 'p, div, label, select, input, table, span {font-family:' . $fonts[$this->getData(['admin', 'fontText'])] . '}';
$css .= 'body,.row > div {font-size:' . $this->getData(['admin', 'fontSize']) . '}'; $css .= 'body,.row > div {font-size:' . $this->getData(['admin', 'fontSize']) . '}';
$css .= 'body h1, h2, h3, h4 a, h5, h6 {font-family:' . $fonts[$this->getData(['admin', 'fontTitle'])] . ';color:' . $this->getData(['admin', 'colorTitle']) . ';}'; $css .= 'body h1, h2, h3, h4 a, h5, h6 {font-family:' . $fonts[$this->getData(['admin', 'fontTitle'])] . ';color:' . $this->getData(['admin', 'colorTitle']) . ';}';
$css .= '.container {max-width:' . $this->getData(['admin', 'width']) . '}';
$margin = $this->getData(['theme', 'site', 'margin']) ? '0' : '20px';
// Marge supplémentaire lorsque le pied de page est fixe
if (
$this->getData(['theme', 'footer', 'fixed']) === true &&
$this->getData(['theme', 'footer', 'position']) === 'body'
) {
$marginBottomLarge = ((str_replace('px', '', $this->getData(['theme', 'footer', 'height'])) * 2) + 31) . 'px';
$marginBottomSmall = ((str_replace('px', '', $this->getData(['theme', 'footer', 'height'])) * 2) + 93) . 'px';
} else {
$marginBottomSmall = $margin;
$marginBottomLarge = $margin;
}
$css .= $this->getData(['admin', 'width']) === '100%'
? '@media (min-width: 769px) {#site{margin:0 auto ' . $marginBottomLarge . ' 0 !important;}}@media (max-width: 768px) {#site{margin:0 auto ' . $marginBottomSmall . ' 0 !important;}}#site.light{margin:5% auto !important;} body{margin:0 auto !important;} #bar{margin:0 auto !important;} body > header{margin:0 auto !important;} body > nav {margin: 0 auto !important;} body > footer {margin:0 auto !important;}'
: '@media (min-width: 769px) {#site{margin: ' . $margin . ' auto ' . $marginBottomLarge . ' auto !important;}}@media (max-width: 768px) {#site{margin: ' . $margin . ' auto ' . $marginBottomSmall . ' auto !important;}}#site.light{margin: 5% auto !important;} body{margin:0px 10px;} #bar{margin: 0 -10px;} body > header{margin: 0 -10px;} body > nav {margin: 0 -10px;} body > footer {margin: 0 -10px;} ';
$css .= $this->getData(['admin', 'width']) === '750px'
? '.button, button{font-size:0.8em;}'
: '';
// TinyMCE // TinyMCE
$colors = helper::colorVariants($this->getData(['admin', 'colorText'])); $colors = helper::colorVariants($this->getData(['admin', 'colorText']));
@ -367,7 +424,7 @@ class core extends common
// Bordure du contour TinyMCE // Bordure du contour TinyMCE
$css .= '.mce-tinymce{border: 1px solid ' . $this->getData(['admin', 'borderBlockColor']) . '!important;}'; $css .= '.mce-tinymce{border: 1px solid ' . $this->getData(['admin', 'borderBlockColor']) . '!important;}';
// Enregistre la personnalisation // 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 +440,8 @@ class core extends common
require 'core/module/' . $classPath; require 'core/module/' . $classPath;
} }
// Module // Module
elseif (is_readable(common::MODULE_DIR . $classPath)) { elseif (is_readable(self::MODULE_DIR . $classPath)) {
require common::MODULE_DIR . $classPath; require self::MODULE_DIR . $classPath;
} }
// Librairie // Librairie
elseif (is_readable('core/vendor/' . $classPath)) { elseif (is_readable('core/vendor/' . $classPath)) {
@ -416,7 +473,7 @@ class core extends common
// Force la déconnexion des membres bannis ou d'une seconde session // Force la déconnexion des membres bannis ou d'une seconde session
if ( if (
$this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD') $this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
and ($this->getUser('group') === common::GROUP_BANNED and ($this->getUser('group') === self::GROUP_BANNED
or ($_SESSION['csrf'] !== $this->getData(['user', $this->getUser('id'), 'accessCsrf']) or ($_SESSION['csrf'] !== $this->getData(['user', $this->getUser('id'), 'accessCsrf'])
and $this->getData(['config', 'connect', 'autoDisconnect']) === true) and $this->getData(['config', 'connect', 'autoDisconnect']) === true)
) )
@ -431,7 +488,7 @@ class core extends common
and $this->getUrl(1) !== 'login' and $this->getUrl(1) !== 'login'
and ($this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD') and ($this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD')
or ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD') or ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
and $this->getUser('group') < common::GROUP_ADMIN and $this->getUser('group') < self::GROUP_ADMIN
) )
) )
) { ) {
@ -444,11 +501,31 @@ class core extends common
exit(); 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 // Check l'accès à la page
$access = null; $access = null;
if ($this->getData(['page', $this->getUrl(0)]) !== null) { if ($this->getData(['page', $this->getUrl(0)]) !== null) {
if ( if (
$this->getData(['page', $this->getUrl(0), 'group']) === common::GROUP_VISITOR $this->getData(['page', $this->getUrl(0), 'group']) === self::GROUP_VISITOR
or ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD') or ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
// and $this->getUser('group') >= $this->getData(['page', $this->getUrl(0), 'group']) // and $this->getUser('group') >= $this->getData(['page', $this->getUrl(0), 'group'])
// Modification qui tient compte du profil de la page // Modification qui tient compte du profil de la page
@ -469,19 +546,11 @@ class core extends common
and $this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD') and $this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD')
) or ($this->getData(['page', $this->getUrl(0), 'disable']) === true ) or ($this->getData(['page', $this->getUrl(0), 'disable']) === true
and $this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD') and $this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
and $this->getUser('group') < common::GROUP_EDITOR and $this->getUser('group') < self::GROUP_EDITOR
) )
) { ) {
$access = false; $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 +572,9 @@ class core extends common
$this->getUser('id') && $this->getUser('id') &&
$userId !== $this->getUser('id') && $userId !== $this->getUser('id') &&
$this->getData(['user', $userId, 'accessUrl']) === $this->getUrl() && $this->getData(['user', $userId, 'accessUrl']) === $this->getUrl() &&
array_intersect($t, common::$concurrentAccess) && array_intersect($t, self::$concurrentAccess) &&
//array_intersect($t, common::$accessExclude) !== false && //array_intersect($t, self::$accessExclude) !== false &&
time() < $this->getData(['user', $userId, 'accessTimer']) + common::ACCESS_TIMER time() < $this->getData(['user', $userId, 'accessTimer']) + self::ACCESS_TIMER
) { ) {
$access = false; $access = false;
$accessInfo['userName'] = $this->getData(['user', $userId, 'lastname']) . ' ' . $this->getData(['user', $userId, 'firstname']); $accessInfo['userName'] = $this->getData(['user', $userId, 'lastname']) . ' ' . $this->getData(['user', $userId, 'firstname']);
@ -542,10 +611,10 @@ class core extends common
$inlineScript[] = $this->getData(['page', $this->getUrl(0), 'js']) === null ? '' : $this->getData(['page', $this->getUrl(0), 'js']); $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 // 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']); $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']); $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']); $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']); $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 +632,7 @@ class core extends common
$this->addOutput([ $this->addOutput([
'title' => $title, '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']), 'metaDescription' => $this->getData(['page', $this->getUrl(0), 'metaDescription']),
'metaTitle' => $this->getData(['page', $this->getUrl(0), 'metaTitle']), 'metaTitle' => $this->getData(['page', $this->getUrl(0), 'metaTitle']),
'typeMenu' => $this->getData(['page', $this->getUrl(0), 'typeMenu']), 'typeMenu' => $this->getData(['page', $this->getUrl(0), 'typeMenu']),
@ -589,7 +658,7 @@ class core extends common
: $this->getData(['page', $this->getUrl(0), 'metaDescription']); : $this->getData(['page', $this->getUrl(0), 'metaDescription']);
// Importe le CSS de la page principale // 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([ $this->addOutput([
'title' => $title, 'title' => $title,
@ -634,7 +703,7 @@ class core extends common
$output = $module->output; $output = $module->output;
// Check le groupe de l'utilisateur // Check le groupe de l'utilisateur
if ( if (
($module::$actions[$action] === common::GROUP_VISITOR ($module::$actions[$action] === self::GROUP_VISITOR
or ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD') or ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
and $this->getUser('group') >= $module::$actions[$action] and $this->getUser('group') >= $module::$actions[$action]
and $this->getUser('permission', $moduleId, $action) and $this->getUser('permission', $moduleId, $action)
@ -647,10 +716,10 @@ class core extends common
foreach ($_POST as $postId => $postValue) { foreach ($_POST as $postId => $postValue) {
if (is_array($postValue)) { if (is_array($postValue)) {
foreach ($postValue as $subPostId => $subPostValue) { foreach ($postValue as $subPostId => $subPostValue) {
common::$inputBefore[$postId . '_' . $subPostId] = $subPostValue; self::$inputBefore[$postId . '_' . $subPostId] = $subPostValue;
} }
} else { } else {
common::$inputBefore[$postId] = $postValue; self::$inputBefore[$postId] = $postValue;
} }
} }
} }
@ -690,9 +759,9 @@ class core extends common
// Contenu par vue // Contenu par vue
elseif ($output['view']) { elseif ($output['view']) {
// Chemin en fonction d'un module du coeur ou d'un module // 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 // 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)) { if (file_exists($stylePath)) {
$this->addOutput([ $this->addOutput([
'style' => file_get_contents($stylePath) 'style' => file_get_contents($stylePath)
@ -705,7 +774,7 @@ class core extends common
} }
// JS // 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)) { if (file_exists($scriptPath)) {
ob_start(); ob_start();
include $scriptPath; include $scriptPath;
@ -714,7 +783,7 @@ class core extends common
]); ]);
} }
// Vue // 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)) { if (file_exists($viewPath)) {
ob_start(); ob_start();
include $viewPath; include $viewPath;
@ -783,7 +852,7 @@ class core extends common
if ($accessInfo['userName']) { if ($accessInfo['userName']) {
$this->addOutput([ $this->addOutput([
'title' => 'Accès verrouillé', '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 { } else {
@ -795,35 +864,12 @@ class core extends common
} else { } else {
$this->addOutput([ $this->addOutput([
'title' => 'Accès interdit', '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'] === '') { } elseif ($this->output['content'] === '') {
http_response_code(404); 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 ( if (
$this->getData(['locale', 'page404']) !== 'none' $this->getData(['locale', 'page404']) !== 'none'
and $this->getData(['page', $this->getData(['locale', 'page404'])]) and $this->getData(['page', $this->getData(['locale', 'page404'])])
@ -832,7 +878,7 @@ class core extends common
} else { } else {
$this->addOutput([ $this->addOutput([
'title' => 'Page indisponible', '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 +901,25 @@ class core extends common
} }
switch ($this->output['display']) { switch ($this->output['display']) {
// Layout brut // Layout brut
case common::DISPLAY_RAW: case self::DISPLAY_RAW:
echo $this->output['content']; echo $this->output['content'];
break; break;
// Layout vide // Layout vide
case common::DISPLAY_LAYOUT_BLANK: case self::DISPLAY_LAYOUT_BLANK:
require 'core/layout/blank.php'; require 'core/layout/blank.php';
break; break;
// Affichage en JSON // Affichage en JSON
case common::DISPLAY_JSON: case self::DISPLAY_JSON:
header('Content-Type: application/json'); header('Content-Type: application/json');
echo json_encode($this->output['content']); echo json_encode($this->output['content']);
break; break;
// RSS feed // RSS feed
case common::DISPLAY_RSS: case self::DISPLAY_RSS:
header('Content-type: application/rss+xml; charset=UTF-8'); header('Content-type: application/rss+xml; charset=UTF-8');
echo $this->output['content']; echo $this->output['content'];
break; break;
// Layout allégé // Layout allégé
case common::DISPLAY_LAYOUT_LIGHT: case self::DISPLAY_LAYOUT_LIGHT:
ob_start(); ob_start();
require 'core/layout/light.php'; require 'core/layout/light.php';
$content = ob_get_clean(); $content = ob_get_clean();
@ -884,7 +930,7 @@ class core extends common
echo $content; echo $content;
break; break;
// Layout principal // Layout principal
case common::DISPLAY_LAYOUT_MAIN: case self::DISPLAY_LAYOUT_MAIN:
ob_start(); ob_start();
require 'core/layout/main.php'; require 'core/layout/main.php';
$content = ob_get_clean(); $content = ob_get_clean();

View File

@ -93,19 +93,19 @@ class template
// Icône de l'opérateur et calcul du résultat // Icône de l'opérateur et calcul du résultat
switch ($operator) { switch ($operator) {
case 1: case 1:
$operator = template::ico('plus', ['fontSize' => '2em;']); $operator = template::ico('plus');
$result = $firstNumber + $secondNumber; $result = $firstNumber + $secondNumber;
break; break;
case 2: case 2:
$operator = template::ico('minus', ['fontSize' => '2em;']); $operator = template::ico('minus');
$result = $firstNumber - $secondNumber; $result = $firstNumber - $secondNumber;
break; break;
case 3: case 3:
$operator = template::ico('cancel', ['fontSize' => '2em;']); $operator = template::ico('cancel');
$result = $firstNumber * $secondNumber; $result = $firstNumber * $secondNumber;
break; break;
case 4: case 4:
$operator = template::ico('divide', ['fontSize' => '2em;']); $operator = template::ico('divide');
$limit2 = [10, 10, 6, 5, 4, 3, 2, 2, 2, 2]; $limit2 = [10, 10, 6, 5, 4, 3, 2, 2, 2, 2];
for ($i = 1; $i <= $firstNumber; $i++) { for ($i = 1; $i <= $firstNumber; $i++) {
$limit = $limit2[$i - 1]; $limit = $limit2[$i - 1];
@ -134,7 +134,7 @@ class template
// Label // Label
$html .= self::label( $html .= self::label(
$attributes['id'], $attributes['id'],
'<img class="captcha' . ucFirst($attributes['type']) . '" src="' . helper::baseUrl(false) . 'site/tmp/' . $firstLetter . '.png" />&nbsp;<strong>' . $operator . '</strong>&nbsp;<img class="captcha' . ucFirst($attributes['type']) . '" src="' . helper::baseUrl(false) . 'site/tmp/' . $secondLetter . '.png" />' . template::ico('eq', ['fontSize' => '2em;']), '<img class="captcha' . ucFirst($attributes['type']) . '" src="' . helper::baseUrl(false) . 'site/tmp/' . $firstLetter . '.png" />&nbsp;<strong>' . $operator . '</strong>&nbsp;<img class="captcha' . ucFirst($attributes['type']) . '" src="' . helper::baseUrl(false) . 'site/tmp/' . $secondLetter . '.png" />' . template::ico('eq'),
[ [
'help' => $attributes['help'] 'help' => $attributes['help']
] ]
@ -358,7 +358,7 @@ class template
%s %s
data-lity data-lity
> >
' . self::ico('upload-cloud', ['margin' => 'right']) . ' ' . self::ico('upload', ['margin' => 'right']) . '
<span class="inputFileLabel"></span> <span class="inputFileLabel"></span>
</a>', </a>',
$attributes['class'], $attributes['class'],
@ -494,8 +494,8 @@ class template
$lang = $langId; $lang = $langId;
break; break;
case 'selected': case 'selected':
if (isset($_SESSION['ZWII_SITE_CONTENT'])) { if (isset($_SESSION['ZWII_CONTENT'])) {
$lang = $_SESSION['ZWII_SITE_CONTENT']; $lang = $_SESSION['ZWII_CONTENT'];
} else { } else {
$lang = 'fr_FR'; $lang = 'fr_FR';
} }
@ -686,8 +686,7 @@ class template
'label' => '', 'label' => '',
'name' => $nameId, 'name' => $nameId,
'selected' => '', 'selected' => '',
'font' => [], 'font' => []
'multiple' => ''
], $attributes); ], $attributes);
// Traduction de l'aide et de l'étiquette // Traduction de l'aide et de l'étiquette
$attributes['label'] = helper::translate($attributes['label']); $attributes['label'] = helper::translate($attributes['label']);
@ -716,11 +715,6 @@ class template
$attributes['class'] .= ' notice'; $attributes['class'] .= ' notice';
} }
$html .= self::notice($attributes['id'], $notice); $html .= self::notice($attributes['id'], $notice);
// Attribut multiple
if ($attributes['multiple'] === true) {
echo "ppp";
$attributes['multiple'] = 'multiple';
}
// Début sélection // Début sélection
$html .= sprintf( $html .= sprintf(
'<select %s>', '<select %s>',
@ -750,7 +744,6 @@ class template
return $html; return $html;
} }
/** /**
* Crée une bulle de dialogue * Crée une bulle de dialogue
* @param string $text Texte de la bulle * @param string $text Texte de la bulle

View File

@ -6,7 +6,7 @@
* @author Rémi Jean <remi.jean@outlook.com> * @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean * @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com> * @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 * @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/ * @link http://zwiicms.fr/
*/ */
@ -291,14 +291,14 @@ core.start = function () {
}); });
// Confirmation de mise à jour // Confirmation de mise à jour
$("#barUpdate").on("click", function () { $("#barUpdate").on("click", function () {
message = "<?php echo helper::translate('Mise à jour') . ' ?';?>"; message = "<?php echo helper::translate('Mettre à jour') . ' ?';?>";
return core.confirm(message, function () { return core.confirm(message, function () {
$(location).attr("href", $("#barUpdate").attr("href")); $(location).attr("href", $("#barUpdate").attr("href"));
}); });
}); });
// Confirmation de déconnexion // Confirmation de déconnexion
$("#barLogout").on("click", function () { $("#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 () { return core.confirm(message, function () {
$(location).attr("href", $("#barLogout").attr("href")); $(location).attr("href", $("#barLogout").attr("href"));
}); });
@ -462,7 +462,7 @@ $(document).ready(function () {
/** /**
* Chargement paresseux des images et des iframes * Chargement paresseux des images et des iframes
*/ */
$("img").attr("loading", "lazy"); $("img,picture,iframe").attr("loading", "lazy");
/** /**
* Effet accordéon * Effet accordéon
@ -532,7 +532,7 @@ $(document).ready(function () {
var langSelected = $(this).val(); var langSelected = $(this).val();
var langSelected = langSelected.split("/"); var langSelected = langSelected.split("/");
// Lit le cookie de langue // 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 // Découpe l'URL pour exclure le changement de page avec le thème
var url = window.location; var url = window.location;
var currentUrl = url.href.split("/"); var currentUrl = url.href.split("/");

View File

@ -8,7 +8,7 @@
* @author Rémi Jean <remi.jean@outlook.com> * @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean * @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com> * @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 * @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/ * @link http://zwiicms.fr/
*/ */
@ -51,27 +51,15 @@ class common
const ACCESS_TIMER = 1800; const ACCESS_TIMER = 1800;
// Numéro de version // Numéro de version
const ZWII_VERSION = '13.3.03'; const ZWII_VERSION = '13.0.04';
// URL autoupdate // URL autoupdate
const ZWII_UPDATE_URL = 'https://forge.chapril.org/ZwiiCMS-Team/cms-update/raw/branch/master/'; const ZWII_UPDATE_URL = 'https://forge.chapril.org/ZwiiCMS-Team/update/raw/branch/master/cms/';
const ZWII_UPDATE_CHANNEL = 'v13'; const ZWII_UPDATE_CHANNEL = 'v13';
// Valeurs possibles multiple de 10, 10 autorise 9 profils, 100 autorise 99 profils // Valeurs possibles multiple de 10, 10 autorise 9 profils, 100 autorise 99 profils
const MAX_PROFILS = 10; 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 $actions = [];
public static $coreModuleIds = [ public static $coreModuleIds = [
@ -146,7 +134,7 @@ class common
// 'codemirror', // Désactivé par défaut // 'codemirror', // Désactivé par défaut
'tippy', 'tippy',
'zwiico', 'zwiico',
//'imagemap', 'imagemap',
'simplelightbox' 'simplelightbox'
], ],
'view' => '' 'view' => ''
@ -182,7 +170,7 @@ class common
// Langue de l'interface sélectionnée // Langue de l'interface sélectionnée
public static $i18nUI = 'fr_FR'; public static $i18nUI = 'fr_FR';
// Langues de contenu // Langues de contenu
public static $siteContent = 'fr_FR'; public static $i18nContent = 'fr_FR';
public static $languages = [ public static $languages = [
'az_AZ' => 'Azərbaycan dili', 'az_AZ' => 'Azərbaycan dili',
'bg_BG' => 'български език', 'bg_BG' => 'български език',
@ -340,34 +328,36 @@ class common
$this->input['_COOKIE'] = $_COOKIE; $this->input['_COOKIE'] = $_COOKIE;
} }
// Extraction de la sesion
// $this->input['_SESSION'] = $_SESSION;
// Déterminer la langue du contenu du site // 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 // Déterminé par la session présente
self::$siteContent = $_SESSION['ZWII_SITE_CONTENT']; self::$i18nContent = $_SESSION['ZWII_CONTENT'];
} else { } else {
// Détermine la langue par défaut // Détermine la langue par défaut
foreach (self::$languages as $key => $value) { foreach (self::$languages as $key => $value) {
if (file_exists(self::DATA_DIR . $key . '/.default')) { if (file_exists(self::DATA_DIR . $key . '/.default')) {
self::$siteContent = $key; self::$i18nContent = $key;
$_SESSION['ZWII_SITE_CONTENT'] = $key; $_SESSION['ZWII_CONTENT'] = $key;
break; break;
} }
} }
} }
\setlocale(LC_ALL, self::$siteContent . '.UTF8'); \setlocale(LC_ALL, self::$i18nContent . '.UTF8');
// Instanciation de la classe des entrées / sorties // Instanciation de la classe des entrées / sorties
$this->jsonDB(self::$siteContent); $this->jsonDB(self::$i18nContent);
// Installation fraîche, initialisation des modules // Installation fraîche, initialisation des modules
if ($this->user === []) { if ($this->user === []) {
foreach ($this->dataFiles as $stageId => $item) { foreach ($this->dataFiles as $stageId => $item) {
$folder = $this->dataPath($stageId, self::$siteContent); $folder = $this->dataPath($stageId, self::$i18nContent);
if ( if (
file_exists($folder . $stageId . '.json') === false file_exists($folder . $stageId . '.json') === false
) { ) {
$this->initData($stageId, self::$siteContent); $this->initData($stageId, self::$i18nContent);
common::$coreNotices[] = $stageId; common::$coreNotices[] = $stageId;
} }
} }
@ -602,48 +592,10 @@ class common
public function setPage($page, $value, $lang) 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;
}
/** /**
* Effacer les données de la page * Effacer les données de la page
@ -757,65 +709,65 @@ class common
* Appelée par le core uniquement * Appelée par le core uniquement
*/ */
private function buildHierarchy() private function buildHierarchy()
{ {
$pages = helper::arrayColumn($this->getData(['page']), 'position', 'SORT_ASC'); $pages = helper::arrayColumn($this->getData(['page']), 'position', 'SORT_ASC');
// Parents // Parents
foreach ($pages as $pageId => $pagePosition) { foreach ($pages as $pageId => $pagePosition) {
if ( if (
// Page parent // Page parent
$this->getData(['page', $pageId, 'parentPageId']) === "" $this->getData(['page', $pageId, 'parentPageId']) === ""
// Ignore les pages dont l'utilisateur n'a pas accès // Ignore les pages dont l'utilisateur n'a pas accès
and ($this->getData(['page', $pageId, 'group']) === self::GROUP_VISITOR and ($this->getData(['page', $pageId, 'group']) === self::GROUP_VISITOR
or ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD') or ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
//and $this->getUser('group') >= $this->getData(['page', $pageId, 'group']) //and $this->getUser('group') >= $this->getData(['page', $pageId, 'group'])
// Modification qui tient compte du profil de la page // 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'])) and ($this->getUser('group') * self::MAX_PROFILS + $this->getUser('profil')) >= ($this->getData(['page', $pageId, 'group']) * self::MAX_PROFILS + $this->getData(['page', $pageId, 'profil']))
) )
) )
) { ) {
if ($pagePosition !== 0) { if ($pagePosition !== 0) {
$this->hierarchy['visible'][$pageId] = []; $this->hierarchy['visible'][$pageId] = [];
} }
if ($this->getData(['page', $pageId, 'block']) === 'bar') { if ($this->getData(['page', $pageId, 'block']) === 'bar') {
$this->hierarchy['bar'][$pageId] = []; $this->hierarchy['bar'][$pageId] = [];
} }
$this->hierarchy['all'][$pageId] = []; $this->hierarchy['all'][$pageId] = [];
} }
} }
// Enfants // Enfants
foreach ($pages as $pageId => $pagePosition) { foreach ($pages as $pageId => $pagePosition) {
if (
if ( // Page parent
// Page parent $parentId = $this->getData(['page', $pageId, 'parentPageId'])
$parentId = $this->getData(['page', $pageId, 'parentPageId']) // Ignore les pages dont l'utilisateur n'a pas accès
// Ignore les pages dont l'utilisateur n'a pas accès and (
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 or ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
$this->getData(['page', $parentId, 'group']) === self::GROUP_VISITOR //and $this->getUser('group') >= $this->getData(['page', $parentId, 'group'])
) //and $this->getUser('group') >= $this->getData(['page', $pageId, 'group'])
or (
$this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD') // Modification qui tient compte du profil de la page
and 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']))
$this->getUser('group') * self::MAX_PROFILS + $this->getUser('profil')) >= ($this->getData(['page', $pageId, 'group']) * self::MAX_PROFILS + $this->getData(['page', $pageId, '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']))
) )
) )
) { ) {
if ($pagePosition !== 0) { if ($pagePosition !== 0) {
$this->hierarchy['visible'][$parentId][] = $pageId; $this->hierarchy['visible'][$parentId][] = $pageId;
} }
if ($this->getData(['page', $pageId, 'block']) === 'bar') { if ($this->getData(['page', $pageId, 'block']) === 'bar') {
$this->hierarchy['bar'][$pageId] = []; $this->hierarchy['bar'][$pageId] = [];
} }
$this->hierarchy['all'][$parentId][] = $pageId; $this->hierarchy['all'][$parentId][] = $pageId;
} }
} }
} }
/** /**
* Génère un fichier json avec la liste des pages * Génère un fichier json avec la liste des pages
@ -834,7 +786,7 @@ class common
// Boucler sur les enfants et récupérer le tableau children avec la liste des enfants // Boucler sur les enfants et récupérer le tableau children avec la liste des enfants
foreach ($childIds as $childId) { foreach ($childIds as $childId) {
$children[] = [ $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 'value' => $rewrite . $childId
]; ];
} }
@ -842,18 +794,18 @@ class common
if (empty($childIds)) { if (empty($childIds)) {
// Pas d'enfant, uniquement l'entrée du parent // Pas d'enfant, uniquement l'entrée du parent
$parents[] = [ $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 'value' => $rewrite . $parentId
]; ];
} else { } else {
// Des enfants, on ajoute la page parent en premier // Des enfants, on ajoute la page parent en premier
array_unshift($children, [ 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 'value' => $rewrite . $parentId
]); ]);
// puis on ajoute les enfants au parent // puis on ajoute les enfants au parent
$parents[] = [ $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, 'value' => $rewrite . $parentId,
'menu' => $children '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 * @param int $key Clé de la valeur du groupe
* @return string|null * @return string|null
*/ */
public function getPermission($key1, $key2 = null) public function getPermission($key1, $key2 = null)
{ {
// User n'existe pas
// if (is_array($this->user) === false) {
// return false;
// Administrateur, toutes les permissions // Administrateur, toutes les permissions
if ($this->getUser('group') === self::GROUP_ADMIN) { if ($this->getUser('group') === self::GROUP_ADMIN) {
return true; return true;
} elseif ($this->getUser('group') <= self::GROUP_VISITOR) { // Groupe sans autorisation } elseif ($this->getUser('group') < 1) { // Groupe sans autorisation
return false; return false;
} elseif ( } elseif (
// Groupe avec profil, consultation des autorisations sur deux clés // Groupe avec profil, consultation des autorisations sur deux clés
@ -1016,14 +970,8 @@ class common
) { ) {
return $this->getData(['profil', $this->user['group'], $this->user['profil'], $key1]); return $this->getData(['profil', $this->user['group'], $this->user['profil'], $key1]);
} else { } else {
// Une permission non spécifiée dans le profil est autorisée selon la valeur de $actions // Une permission non spécifiée dans le profil est autorisée par défaut pour le fonctionnement de $action
if (class_exists($key1)) { return true;
$module = new $key1;
if (array_key_exists($key2, $module::$actions)) {
return $this->getUser('group') >= $module::$actions[$key2];
}
}
return false;
} }
} }
@ -1070,8 +1018,6 @@ class common
public function updateSitemap() public function updateSitemap()
{ {
// Le drapeau prend true quand au moins une page est trouvée
$flag = false;
// Rafraîchit la liste des pages après une modification de pageId notamment // Rafraîchit la liste des pages après une modification de pageId notamment
$this->buildHierarchy(); $this->buildHierarchy();
@ -1079,7 +1025,7 @@ class common
// Actualise la liste des pages pour TinyMCE // Actualise la liste des pages pour TinyMCE
$this->tinyMcePages(); $this->tinyMcePages();
//require_once 'core/vendor/sitemap/SitemapGenerator.php'; //require_once "core/vendor/sitemap/SitemapGenerator.php";
$timezone = $this->getData(['config', 'timezone']); $timezone = $this->getData(['config', 'timezone']);
$outputDir = getcwd(); $outputDir = getcwd();
@ -1115,18 +1061,16 @@ class common
// Cas de la page d'accueil ne pas dupliquer l'URL // Cas de la page d'accueil ne pas dupliquer l'URL
$pageId = ($parentPageId !== $this->getData(['locale', 'homePageId'])) ? $parentPageId : ''; $pageId = ($parentPageId !== $this->getData(['locale', 'homePageId'])) ? $parentPageId : '';
$sitemap->addUrl('/' . $pageId, $datetime); $sitemap->addUrl('/' . $pageId, $datetime);
$flag = true;
} }
// Articles du blog // Articles du blog
if ( if (
$this->getData(['page', $parentPageId, 'moduleId']) === 'blog' $this->getData(['page', $parentPageId, 'moduleId']) === 'blog' &&
&& !empty($this->getData(['module', $parentPageId])) !empty($this->getData(['module', $parentPageId]))
&& $this->getData(['module', $parentPageId, 'posts'])
) { ) {
foreach ($this->getData(['module', $parentPageId, 'posts']) as $articleId => $article) { foreach ($this->getData(['module', $parentPageId, 'posts']) as $articleId => $article) {
if ($this->getData(['module', $parentPageId, 'posts', $articleId, 'state']) === true) { if ($this->getData(['module', $parentPageId, 'posts', $articleId, 'state']) === true) {
$date = $this->getData(['module', $parentPageId, 'posts', $articleId, 'publishedOn']); $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)));
} }
} }
} }
@ -1138,7 +1082,6 @@ class common
// Cas de la page d'accueil ne pas dupliquer l'URL // Cas de la page d'accueil ne pas dupliquer l'URL
$pageId = ($childKey !== $this->getData(['locale', 'homePageId'])) ? $childKey : ''; $pageId = ($childKey !== $this->getData(['locale', 'homePageId'])) ? $childKey : '';
$sitemap->addUrl('/' . $childKey, $datetime); $sitemap->addUrl('/' . $childKey, $datetime);
$flag = true;
// La sous-page est un blog // La sous-page est un blog
if ( if (
@ -1155,10 +1098,6 @@ class common
} }
} }
if ($flag === false) {
return false;
}
// Flush all stored urls from memory to the disk and close all necessary tags. // Flush all stored urls from memory to the disk and close all necessary tags.
$sitemap->flush(); $sitemap->flush();
@ -1173,7 +1112,7 @@ class common
} }
$sitemap->updateRobots(); $sitemap->updateRobots();
} else { } 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 // Submit your sitemaps to Google, Yahoo, Bing and Ask.com
@ -1183,8 +1122,8 @@ class common
return (file_exists('sitemap.xml') && file_exists('robots.txt')); return (file_exists('sitemap.xml') && file_exists('robots.txt'));
}
}
/* /*
* Création d'une miniature * Création d'une miniature
@ -1254,8 +1193,9 @@ class common
* @param string|array $to Destinataire * @param string|array $to Destinataire
* @param string $subject Sujet * @param string $subject Sujet
* @param string $content Contenu * @param string $content Contenu
* @return bool
*/ */
public function sendMail($to, $subject, $content, $replyTo = null, $from = 'no-reply@localhost') public function sendMail($to, $subject, $content, $replyTo = null, $from = '')
{ {
// Layout // Layout
ob_start(); ob_start();
@ -1444,32 +1384,13 @@ class common
public function saveLog($message = '') public function saveLog($message = '')
{ {
// Journalisation // 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 .= helper::getIp($this->getData(['config', 'connect', 'anonymousIp'])) . ';';
$dataLog .= empty($this->getUser('id')) ? 'visitor;' : $this->getUser('id') . ';'; $dataLog .= empty($this->getUser('id')) ? 'visitor;' : $this->getUser('id') . ';';
$dataLog .= $message ? $this->getUrl() . ';' . $message : $this->getUrl(); $dataLog .= $message ? $this->getUrl() . ';' . $message : $this->getUrl();
$dataLog .= PHP_EOL; $dataLog .= PHP_EOL;
if ($this->getData(['config', 'connect', 'log'])) { 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);
}
}
/**
* Retourne la signature d'un utilisateur
*/
public function signature($userId)
{
switch ($this->getData(['user', $userId, 'signature'])) {
case 1:
return $userId;
case 2:
return $this->getData(['user', $userId, 'pseudo']);
case 3:
return $this->getData(['user', $userId, 'firstname']) . ' ' . $this->getData(['user', $userId, 'lastname']);
case 4:
return $this->getData(['user', $userId, 'lastname']) . ' ' . $this->getData(['user', $userId, 'firstname']);
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 // Créer les en-têtes du journal
$d = 'Date;Heure;IP;Id;Action' . PHP_EOL; $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 // Init préservation htaccess
$this->setData(['config', 'autoUpdateHtaccess', false]); $this->setData(['config', 'autoUpdateHtaccess', false]);
// Options de barre de membre simple // Options de barre de membre simple
@ -448,8 +448,8 @@ if ($this->getData(['core', 'dataVersion']) < 11000) {
// Liste des pages dans pageList // Liste des pages dans pageList
$hierarchy = array(); $hierarchy = array();
// Creation du contenu de la page // Creation du contenu de la page
if (!is_dir(self::DATA_DIR . self::$siteContent . '/content')) { if (!is_dir(self::DATA_DIR . self::$i18nContent . '/content')) {
mkdir(self::DATA_DIR . self::$siteContent . '/content', 0755); mkdir(self::DATA_DIR . self::$i18nContent . '/content', 0755);
} }
foreach ($this->getHierarchy() as $parentKey => $parentValue) { foreach ($this->getHierarchy() as $parentKey => $parentValue) {
$hierarchy[] = $parentKey; $hierarchy[] = $parentKey;
@ -459,7 +459,7 @@ if ($this->getData(['core', 'dataVersion']) < 11000) {
} }
foreach ($hierarchy as $parentKey => $parent) { foreach ($hierarchy as $parentKey => $parent) {
$content = $this->getData(['page', $parent, 'content']); $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->setPage($parent, $content, 'fr');
$this->setData(['page', $parent, 'content', $parent . '.html']); $this->setData(['page', $parent, 'content', $parent . '.html']);
} }
@ -574,7 +574,7 @@ if ($this->getData(['core', 'dataVersion']) < 11203) {
$success = false; $success = false;
// Boucler sur les pages // Boucler sur les pages
foreach ($this->getHierarchy() as $parentId => $childIds) { foreach ($this->getHierarchy() as $parentId => $childIds) {
$content = $this->getPage($parentId, self::$siteContent); $content = $this->getPage($parentId, self::$i18nContent);
$titre = $this->getData(['page', $parentId, 'title']); $titre = $this->getData(['page', $parentId, 'title']);
$content = $titre . ' ' . $content; $content = $titre . ' ' . $content;
$replace = str_replace('href="' . $old, 'href="' . $new, stripslashes($content), $c1); $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) { if ($c1 > 0 || $c2 > 0) {
$success = true; $success = true;
$this->setPage($parentId, $replace, self::$siteContent); $this->setPage($parentId, $replace, self::$i18nContent);
$c3 += $c1 + $c2; $c3 += $c1 + $c2;
} }
foreach ($childIds as $childId) { foreach ($childIds as $childId) {
$content = $this->getPage($childId, self::$siteContent); $content = $this->getPage($childId, self::$i18nContent);
$content = $titre . ' ' . $content; $content = $titre . ' ' . $content;
$replace = str_replace('href="' . $old, 'href="' . $new, stripslashes($content), $c1); $replace = str_replace('href="' . $old, 'href="' . $new, stripslashes($content), $c1);
$replace = str_replace('src="' . $old, 'src="' . $new, stripslashes($replace), $c2); $replace = str_replace('src="' . $old, 'src="' . $new, stripslashes($replace), $c2);
if ($c1 > 0 || $c2 > 0) { if ($c1 > 0 || $c2 > 0) {
$success = true; $success = true;
$this->setPage($childId, $replace, self::$siteContent); $this->setPage($childId, $replace, self::$i18nContent);
$c3 += $c1 + $c2; $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 = json_decode(file_get_contents(self::DATA_DIR . $key . '/locale.json'), true);
$d = array_merge($d['locale'], ['poweredPageLabel' => 'Motorisé par']); $d = array_merge($d['locale'], ['poweredPageLabel' => 'Motorisé par']);
$t['locale'] = $d; $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 // 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 ($languages as $langId) {
foreach ($hierarchy as $parentKey => $parent) { 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 // Supprime la clé OpenOgraph
$this->deleteData(['config', 'seo', 'keyApi']); $this->deleteData(['config', 'seo', 'keyApi']);
@ -1077,8 +1077,8 @@ if ($this->getData(['core', 'dataVersion']) < 13000) {
$this->setData(['core', 'dataVersion', 13000]); $this->setData(['core', 'dataVersion', 13000]);
} }
// Version 13.0.05 // Version 13.0.03
if ($this->getData(['core', 'dataVersion']) < 13005) { if ($this->getData(['core', 'dataVersion']) < 13003) {
if (is_dir('core/module/plugin/view/dataImport')) { if (is_dir('core/module/plugin/view/dataImport')) {
$this->deleteDir('core/module/plugin/view/dataImport'); $this->deleteDir('core/module/plugin/view/dataImport');
@ -1087,32 +1087,6 @@ if ($this->getData(['core', 'dataVersion']) < 13005) {
unlink('core/module/plugin/view/index/index.js.php'); unlink('core/module/plugin/view/index/index.js.php');
} }
// Installe l'adresse d'envoi si non spécifiée
if (empty($this->getData(['config', 'smtp', 'from']))) {
$this->setData(['config', 'smtp', 'from', 'no-reply@localhost']);
}
// Fixe la taille de l'administration identique à la taille de site
$size = $this->getData(['theme', 'site', 'width']);
$this->setData(['admin', 'width', $size]);
// Ancienne déclaration oubliée !!
if ($this->getData(['admin', 'backgroundColorButtonHelp']) === null) {
$this->setData(['admin', 'backgroundColorButtonHelp', 'rgba(255, 153, 0, 1)']);
}
// Mise à jour // Mise à jour
$this->setData(['core', 'dataVersion', 13005]); //$this->setData(['core', 'dataVersion', 13003]);
} }
// 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> * @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean * @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com> * @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 * @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/ * @link http://zwiicms.fr/
*/ */

View File

@ -1,5 +1,5 @@
<!DOCTYPE html> <!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> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta http-equiv="content-type" content="text/html; charset=UTF-8"> <meta http-equiv="content-type" content="text/html; charset=UTF-8">
@ -12,9 +12,6 @@
<?php $layout->showVendor(); ?> <?php $layout->showVendor(); ?>
<?php $layout->showStyle(); ?> <?php $layout->showStyle(); ?>
<?php $layout->showFonts(); ?> <?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/common.css">
<link rel="stylesheet" href="<?php echo helper::baseUrl(false); ?>core/layout/blank.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'); ?>"> <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> * @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean * @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com> * @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 * @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/ * @link http://zwiicms.fr/
*/ */
@ -1003,10 +1003,9 @@ footer #footerSocials .zwiico-twitch:hover {
max-width: 500px; max-width: 500px;
width: 100%; width: 100%;
margin: 16px auto; margin: 16px auto;
text-align: center; text-align: left;
border-radius: 2px; border-radius: 2px;
transition: background-color .3s ease-out; transition: background-color .3s ease-out;
z-index: 100;
} }
.speechBubble:before { .speechBubble:before {
@ -1819,7 +1818,4 @@ th.col12 {
.bannerDisplay { .bannerDisplay {
display: none; display: none;
} }
header {
background-size: cover !important;
}
} }

View File

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

View File

@ -1,5 +1,5 @@
<!DOCTYPE html> <!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> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta http-equiv="content-type" content="text/html; charset=UTF-8"> <meta http-equiv="content-type" content="text/html; charset=UTF-8">
@ -12,9 +12,6 @@
<?php $layout->showVendor(); ?> <?php $layout->showVendor(); ?>
<?php $layout->showStyle(); ?> <?php $layout->showStyle(); ?>
<?php $layout->showFonts(); ?> <?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/common.css">
<link rel="stylesheet" href="<?php echo helper::baseUrl(false); ?>core/layout/light.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'); ?>"> <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> <!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> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta http-equiv="content-type" content="text/html; charset=UTF-8"> <meta http-equiv="content-type" content="text/html; charset=UTF-8">

View File

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

View File

@ -9,7 +9,7 @@
* @author Rémi Jean <remi.jean@outlook.com> * @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean * @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com> * @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 * @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/ * @link http://zwiicms.fr/
*/ */
@ -523,7 +523,7 @@ class config extends common
) { ) {
// Ajout des lignes dans le .htaccess // Ajout des lignes dans le .htaccess
$fileContent = file_get_contents('.htaccess'); $fileContent = file_get_contents('.htaccess');
$rewriteData = $rewriteData = PHP_EOL .
'# URL rewriting' . PHP_EOL . '# URL rewriting' . PHP_EOL .
'<IfModule mod_rewrite.c>' . PHP_EOL . '<IfModule mod_rewrite.c>' . PHP_EOL .
"\tRewriteEngine on" . PHP_EOL . "\tRewriteEngine on" . PHP_EOL .
@ -532,9 +532,9 @@ class config extends common
"\tRewriteCond %{REQUEST_FILENAME} !-d" . PHP_EOL . "\tRewriteCond %{REQUEST_FILENAME} !-d" . PHP_EOL .
"\tRewriteRule ^(.*)$ index.php?$1 [L]" . PHP_EOL . "\tRewriteRule ^(.*)$ index.php?$1 [L]" . PHP_EOL .
'</IfModule>' . PHP_EOL . '</IfModule>' . PHP_EOL .
'# URL rewriting'; '# URL rewriting' . PHP_EOL;
$fileContent = str_replace('# URL rewriting', $rewriteData, $fileContent); $fileContent = str_replace('# URL rewriting', $rewriteData, $fileContent);
$this->secure_file_put_contents( file_put_contents(
'.htaccess', '.htaccess',
$fileContent $fileContent
); );
@ -550,7 +550,7 @@ class config extends common
$fileContent = file_get_contents('.htaccess'); $fileContent = file_get_contents('.htaccess');
$fileContent = explode('# URL rewriting', $fileContent); $fileContent = explode('# URL rewriting', $fileContent);
$fileContent = $fileContent[0] . '# URL rewriting' . $fileContent[2]; $fileContent = $fileContent[0] . '# URL rewriting' . $fileContent[2];
$this->secure_file_put_contents( file_put_contents(
'.htaccess', '.htaccess',
$fileContent $fileContent
); );
@ -585,7 +585,7 @@ class config extends common
// Variable de version // Variable de version
if (helper::checkNewVersion(common::ZWII_UPDATE_CHANNEL)) { if (helper::checkNewVersion(common::ZWII_UPDATE_CHANNEL)) {
self::$updateButtonText = helper::translate('Mise à jour'); self::$updateButtonText = helper::translate('Mettre à jour');
} }
@ -654,10 +654,10 @@ class config extends common
) { ) {
// Ecrire les fichiers de script // Ecrire les fichiers de script
if ($this->geturl(2) === 'head') { 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') { 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 // Valeurs en sortie
$this->addOutput([ $this->addOutput([
@ -699,7 +699,7 @@ class config extends common
unlink(self::DATA_DIR . 'journal.log'); unlink(self::DATA_DIR . 'journal.log');
// Créer les en-têtes des journaux // Créer les en-têtes des journaux
$d = 'Date;Heure;IP;Id;Action' . PHP_EOL; $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 // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'title' => helper::translate('Configuration'), 'title' => helper::translate('Configuration'),
@ -775,15 +775,15 @@ class config extends common
ob_start(); ob_start();
$fileName = self::TEMP_DIR . 'blacklist.log'; $fileName = self::TEMP_DIR . 'blacklist.log';
$d = 'Date dernière tentative;Heure dernière tentative;Id;Adresse IP;Nombre d\'échecs' . PHP_EOL; $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)) { if (file_exists($fileName)) {
$d = $this->getData(['blacklist']); $d = $this->getData(['blacklist']);
$data = ''; $data = '';
foreach ($d as $key => $item) { 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; $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-Description: File Transfer');
header('Content-Type: application/octet-stream'); header('Content-Type: application/octet-stream');
header('Content-Transfer-Encoding: binary'); header('Content-Transfer-Encoding: binary');
@ -902,19 +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';
}
}
} }

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

View File

@ -5,8 +5,8 @@
* file that was distributed with this source code. * file that was distributed with this source code.
* *
* @author Frédéric Tempez <frederic.tempez@outlook.com> * @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 * @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/ * @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> * @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean * @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com> * @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 * @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/ * @link http://zwiicms.fr/
*/ */

View File

@ -5,7 +5,7 @@
* file that was distributed with this source code. * file that was distributed with this source code.
* *
* @author Frédéric Tempez <frederic.tempez@outlook.com> * @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 * @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/ * @link http://zwiicms.fr/
*/ */
@ -71,7 +71,7 @@ $(document).ready(function () {
configLayout = "setup"; configLayout = "setup";
setCookie("configLayout", "setup"); setCookie("configLayout", "setup");
} }
$("#localeContainer").hide();
$("#socialContainer").hide(); $("#socialContainer").hide();
$("#connectContainer").hide(); $("#connectContainer").hide();
$("#networkContainer").hide(); $("#networkContainer").hide();
@ -158,22 +158,39 @@ $(document).ready(function () {
* Sélection de la page de configuration à afficher * Sélection de la page de configuration à afficher
*/ */
$("#configSetupButton").on("click", function () { $("#configSetupButton").on("click", function () {
$("#localeContainer").hide();
$("#socialContainer").hide(); $("#socialContainer").hide();
$("#connectContainer").hide(); $("#connectContainer").hide();
$("#networkContainer").hide(); $("#networkContainer").hide();
$("#setupContainer").show(); $("#setupContainer").show();
$("#configSetupButton").addClass("activeButton"); $("#configSetupButton").addClass("activeButton");
$("#configLocaleButton").removeClass("activeButton");
$("#configSocialButton").removeClass("activeButton"); $("#configSocialButton").removeClass("activeButton");
$("#configConnectButton").removeClass("activeButton"); $("#configConnectButton").removeClass("activeButton");
$("#configNetworkButton").removeClass("activeButton"); $("#configNetworkButton").removeClass("activeButton");
setCookie("configLayout", "setup"); 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 () { $("#configSocialButton").on("click", function () {
$("#connectContainer").hide(); $("#connectContainer").hide();
$("#setupContainer").hide(); $("#setupContainer").hide();
$("#localeContainer").hide();
$("#networkContainer").hide(); $("#networkContainer").hide();
$("#socialContainer").show(); $("#socialContainer").show();
$("#configSetupButton").removeClass("activeButton"); $("#configSetupButton").removeClass("activeButton");
$("#configLocaleButton").removeClass("activeButton");
$("#configSocialButton").addClass("activeButton"); $("#configSocialButton").addClass("activeButton");
$("#configConnectButton").removeClass("activeButton"); $("#configConnectButton").removeClass("activeButton");
$("#configNetworkButton").removeClass("activeButton"); $("#configNetworkButton").removeClass("activeButton");
@ -181,10 +198,12 @@ $(document).ready(function () {
}); });
$("#configConnectButton").on("click", function () { $("#configConnectButton").on("click", function () {
$("#setupContainer").hide(); $("#setupContainer").hide();
$("#localeContainer").hide();
$("#socialContainer").hide(); $("#socialContainer").hide();
$("#networkContainer").hide(); $("#networkContainer").hide();
$("#connectContainer").show(); $("#connectContainer").show();
$("#configSetupButton").removeClass("activeButton"); $("#configSetupButton").removeClass("activeButton");
$("#configLocaleButton").removeClass("activeButton");
$("#configSocialButton").removeClass("activeButton"); $("#configSocialButton").removeClass("activeButton");
$("#configConnectButton").addClass("activeButton"); $("#configConnectButton").addClass("activeButton");
$("#configNetworkButton").removeClass("activeButton"); $("#configNetworkButton").removeClass("activeButton");
@ -192,10 +211,12 @@ $(document).ready(function () {
}); });
$("#configNetworkButton").on("click", function () { $("#configNetworkButton").on("click", function () {
$("#setupContainer").hide(); $("#setupContainer").hide();
$("#localeContainer").hide();
$("#socialContainer").hide(); $("#socialContainer").hide();
$("#connectContainer").hide(); $("#connectContainer").hide();
$("#networkContainer").show(); $("#networkContainer").show();
$("#configSetupButton").removeClass("activeButton"); $("#configSetupButton").removeClass("activeButton");
$("#configLocaleButton").removeClass("activeButton");
$("#configSocialButton").removeClass("activeButton"); $("#configSocialButton").removeClass("activeButton");
$("#configConnectButton").removeClass("activeButton"); $("#configConnectButton").removeClass("activeButton");
$("#configNetworkButton").addClass("activeButton"); $("#configNetworkButton").addClass("activeButton");
@ -212,7 +233,7 @@ $(document).ready(function () {
// Mise en évidence des erreurs de saisie dans les boutons de sélection // 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) { $.each(containers, function (index, value) {
var a = $("div#" + value + "Container").find("input.notice").not(".displayNone"); var a = $("div#" + value + "Container").find("input.notice").not(".displayNone");
if (a.length > 0) { if (a.length > 0) {

View File

@ -9,20 +9,14 @@
</div> </div>
<div class="col1"> <div class="col1">
<?php /**echo template::button('configHelp', [ <?php /**echo template::button('configHelp', [
'class' => 'buttonHelp', 'class' => 'buttonHelp',
'href' => 'https://doc.zwiicms.fr/configuration-du-site', 'href' => 'https://doc.zwiicms.fr/configuration-du-site',
'target' => '_blank', 'target' => '_blank',
'value' => template::ico('help'), 'value' => template::ico('help'),
'help' => 'Consulter l\'aide en ligne' 'help' => 'Consulter l\'aide en ligne'
]); */?> ]); */ ?>
</div> </div>
<div class="col2 offset6"> <div class="col2 offset8">
<?php echo template::button('configLocaleButton', [
'value' => 'Identité',
'href' => helper::baseUrl() . 'language/site'
]); ?>
</div>
<div class="col2">
<?php echo template::submit('Submit'); ?> <?php echo template::submit('Submit'); ?>
</div> </div>
</div> </div>
@ -41,6 +35,7 @@
'value' => 'Connexion', 'value' => 'Connexion',
'class' => 'buttonTab' 'class' => 'buttonTab'
]); ?> ]); ?>
<?php echo template::button('configNetworkButton', [ <?php echo template::button('configNetworkButton', [
'value' => 'Réseau', 'value' => 'Réseau',
'class' => 'buttonTab' 'class' => 'buttonTab'

View File

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

View File

@ -5,7 +5,7 @@
* file that was distributed with this source code. * file that was distributed with this source code.
* *
* @author Frédéric Tempez <frederic.tempez@outlook.com> * @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 * @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/ * @link http://zwiicms.fr/
*/ */

View File

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

View File

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

View File

@ -48,7 +48,7 @@
<?php echo template::checkbox('configRewrite', true, 'Apache URL intelligentes', [ <?php echo template::checkbox('configRewrite', true, 'Apache URL intelligentes', [
'checked' => helper::checkRewrite(), 'checked' => helper::checkRewrite(),
'help' => 'Supprime le point d\'interrogation dans les URL, l\'option est indisponible avec les autres serveurs Web', '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>
</div> </div>

View File

@ -28,7 +28,7 @@
</div> </div>
<div class="row"> <div class="row">
<div class="col10 textAlignCenter"> <div class="col10 textAlignCenter">
<?php if( !empty($module::$imageOpenGraph['type']) ): ?> <?php if( $module::$imageOpenGraph['type']): ?>
<p> <p>
<?php echo sprintf('%s : <span id="screenType">%s</span>', helper::translate('Format'), $module::$imageOpenGraph['type']); ?> <?php echo sprintf('%s : <span id="screenType">%s</span>', helper::translate('Format'), $module::$imageOpenGraph['type']); ?>
</p> </p>

View File

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

View File

@ -8,7 +8,7 @@
* @author Rémi Jean <remi.jean@outlook.com> * @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean * @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com> * @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 * @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/ * @link http://zwiicms.fr/
*/ */
@ -30,7 +30,8 @@ class install extends common
'http://' => 'HTTP' 'http://' => 'HTTP'
]; ];
public static $updateButtonText = 'Réinstaller'; // Thèmes proposés à l'installation
public static $themes = [];
public static $newVersion; public static $newVersion;
@ -119,24 +120,24 @@ class install extends common
self::$i18nUI = $_SESSION['ZWII_UI']; self::$i18nUI = $_SESSION['ZWII_UI'];
self::$i18nUI = array_key_exists(self::$i18nUI, self::$languages) ? self::$i18nUI : 'fr_FR'; self::$i18nUI = array_key_exists(self::$i18nUI, self::$languages) ? self::$i18nUI : 'fr_FR';
// par défaut le contenu est la langue d'installation // 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 // Création du dossier de langue avec le marqueur de langue par défaut
if (!is_dir(self::DATA_DIR . $_SESSION['ZWII_SITE_CONTENT'])) { if (!is_dir(self::DATA_DIR . $_SESSION['ZWII_CONTENT'])) {
mkdir(self::DATA_DIR . $_SESSION['ZWII_SITE_CONTENT']); mkdir(self::DATA_DIR . $_SESSION['ZWII_CONTENT']);
touch(self::DATA_DIR . $_SESSION['ZWII_SITE_CONTENT'] . '/.default'); touch(self::DATA_DIR . $_SESSION['ZWII_CONTENT'] . '/.default');
} }
// Installation du site de test // Installation du site de test
if ( if (
$this->getInput('installDefaultData', helper::FILTER_BOOLEAN) === false $this->getInput('installDefaultData', helper::FILTER_BOOLEAN) === false
&& $_SESSION['ZWII_SITE_CONTENT'] === 'fr_FR' && $_SESSION['ZWII_CONTENT'] === 'fr_FR'
) { ) {
$sample = true; $sample = true;
} }
$this->initData('page', $_SESSION['ZWII_SITE_CONTENT'], $sample); $this->initData('page', $_SESSION['ZWII_CONTENT'], $sample);
$this->initData('module', $_SESSION['ZWII_SITE_CONTENT'], $sample); $this->initData('module', $_SESSION['ZWII_CONTENT'], $sample);
$this->initData('locale', $_SESSION['ZWII_SITE_CONTENT'], $sample); $this->initData('locale', $_SESSION['ZWII_CONTENT'], $sample);
// Création de l'utilisateur si les données sont complétées. // Création de l'utilisateur si les données sont complétées.
// success retour de l'enregistrement des données // success retour de l'enregistrement des données
@ -147,13 +148,12 @@ class install extends common
'firstname' => $userFirstname, 'firstname' => $userFirstname,
'forgot' => 0, 'forgot' => 0,
'group' => self::GROUP_ADMIN, 'group' => self::GROUP_ADMIN,
'profil' => 0,
'lastname' => $userLastname, 'lastname' => $userLastname,
'pseudo' => 'Admin', 'pseudo' => 'Admin',
'signature' => 1, 'signature' => 1,
'mail' => $userMail, 'mail' => $userMail,
'password' => $this->getInput('installPassword', helper::FILTER_PASSWORD, true), 'password' => $this->getInput('installPassword', helper::FILTER_PASSWORD, true),
'language' => $_SESSION['ZWII_SITE_CONTENT'] 'language' => $_SESSION['ZWII_CONTENT']
] ]
]); ]);
@ -167,12 +167,12 @@ class install extends common
'<strong>URL du site :</strong> <a href="' . helper::baseUrl(false) . '" target="_blank">' . helper::baseUrl(false) . '</a><br>' . '<strong>URL du site :</strong> <a href="' . helper::baseUrl(false) . '" target="_blank">' . helper::baseUrl(false) . '</a><br>' .
'<strong>Identifiant du compte :</strong> ' . $this->getInput('installId') . '<br>', '<strong>Identifiant du compte :</strong> ' . $this->getInput('installId') . '<br>',
null, null,
'no-reply@localhost' 'localhost'
); );
// Nettoyage fr par défaut // Nettoyage fr par défaut
if ( if (
$_SESSION['ZWII_SITE_CONTENT'] !== 'fr_FR' $_SESSION['ZWII_CONTENT'] !== 'fr_FR'
) { ) {
if (is_dir(self::DATA_DIR . 'fr_FR')) if (is_dir(self::DATA_DIR . 'fr_FR'))
$this->deleteDir(self::DATA_DIR . 'fr_FR'); $this->deleteDir(self::DATA_DIR . 'fr_FR');
@ -210,17 +210,40 @@ class install extends common
mkdir(self::DATA_DIR . 'font'); 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 // Copie des langues de l'UI et génération de la base de données
if (is_dir(self::I18N_DIR) === false) { if (is_dir(self::I18N_DIR) === false) {
mkdir(self::I18N_DIR); mkdir(self::I18N_DIR);
} }
// Créer la base de données des langues // 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); $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 // Fixe l'adresse from pour les envois d'email
$this->setData(['config', 'smtp', 'from', 'no-reply@' . str_replace('www.', '', $_SERVER['HTTP_HOST'])]); $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 // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'redirect' => helper::baseUrl(), 'redirect' => helper::baseUrl(),
@ -229,10 +252,17 @@ 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 // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'display' => self::DISPLAY_LAYOUT_LIGHT, 'display' => self::DISPLAY_LAYOUT_LIGHT,
'title' => helper::translate('Installation'), 'title' => helper::translate('ZwiiCMS Installation'),
'view' => 'postinstall' 'view' => 'postinstall'
]); ]);
} }
@ -267,18 +297,14 @@ class install extends common
$message = $success ? '' : 'Erreur de copie du fichier htaccess'; $message = $success ? '' : 'Erreur de copie du fichier htaccess';
} }
// Nettoyage des fichiers d'installation précédents // 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'); $success = unlink(self::TEMP_DIR . 'update.tar.gz');
$message = $success ? '' : 'Impossible d\'effacer la mise à jour précédente'; $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'); $success = unlink(self::TEMP_DIR . 'update.tar');
$message = $success ? '' : 'Impossible d\'effacer la mise à jour précédente'; $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 // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'display' => self::DISPLAY_JSON, 'display' => self::DISPLAY_JSON,
@ -290,9 +316,7 @@ class install extends common
break; break;
// Téléchargement // Téléchargement
case 2: case 2:
$success = true; file_put_contents(self::TEMP_DIR . 'update.tar.gz', helper::getUrlContents(common::ZWII_UPDATE_URL . common::ZWII_UPDATE_CHANNEL . '/update.tar.gz'));
$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'));
$md5origin = helper::getUrlContents(common::ZWII_UPDATE_URL . common::ZWII_UPDATE_CHANNEL . '/update.md5'); $md5origin = helper::getUrlContents(common::ZWII_UPDATE_URL . common::ZWII_UPDATE_CHANNEL . '/update.md5');
$md5origin = explode(' ', $md5origin); $md5origin = explode(' ', $md5origin);
$md5target = md5_file(self::TEMP_DIR . 'update.tar.gz'); $md5target = md5_file(self::TEMP_DIR . 'update.tar.gz');
@ -302,35 +326,27 @@ class install extends common
$message = ""; $message = "";
} else { } else {
$success = false; $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')) { if (file_exists(self::TEMP_DIR . 'update.tar.gz')) {
unlink(self::TEMP_DIR . 'update.tar.gz'); unlink(self::TEMP_DIR . 'update.tar.gz');
http_response_code(500); http_response_code(500);
} }
} }
// Sauvegarde le message dans le journal
if (!empty($message)) {
$this->saveLog($message);
}
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'display' => self::DISPLAY_JSON, 'display' => self::DISPLAY_JSON,
'content' => [ 'content' => [
'success' => $success, 'success' => $success,
'data' => json_encode($message, JSON_UNESCAPED_UNICODE) 'data' => $message
] ]
]); ]);
break; break;
// Installation // Installation
case 3: case 3:
$success = true; $success = true;
$message = '';
// Check la réécriture d'URL avant d'écraser les fichiers // Check la réécriture d'URL avant d'écraser les fichiers
if (helper::checkRewrite()) { $rewrite = helper::checkRewrite();
touch(self::DATA_DIR . '.rewrite');
}
// Décompression et installation // Décompression et installation
try { try {
// Décompression dans le dossier de fichier temporaires // Décompression dans le dossier de fichier temporaires
@ -339,11 +355,9 @@ class install extends common
// Installation // Installation
$pharData->extractTo(__DIR__ . '/../../../', null, true); $pharData->extractTo(__DIR__ . '/../../../', null, true);
} catch (Exception $e) { } catch (Exception $e) {
$message = $e->getMessage();
$success = false; $success = false;
http_response_code(500); http_response_code(500);
} }
// Nettoyage du dossier // Nettoyage du dossier
if (file_exists(self::TEMP_DIR . 'update.tar.gz')) { if (file_exists(self::TEMP_DIR . 'update.tar.gz')) {
unlink(self::TEMP_DIR . 'update.tar.gz'); unlink(self::TEMP_DIR . 'update.tar.gz');
@ -351,23 +365,19 @@ class install extends common
if (file_exists(self::TEMP_DIR . 'update.tar')) { if (file_exists(self::TEMP_DIR . 'update.tar')) {
unlink(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 // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'display' => self::DISPLAY_JSON, 'display' => self::DISPLAY_JSON,
'content' => [ 'content' => [
'success' => $success, 'success' => $success,
'data' => json_encode($message, JSON_UNESCAPED_UNICODE) 'data' => $rewrite
] ]
]); ]);
break; break;
// Configuration // Configuration
case 4: case 4:
$success = true; $success = true;
$message = ''; $rewrite = $this->getInput('data');
/** /**
* Restaure le fichier htaccess * Restaure le fichier htaccess
@ -377,18 +387,20 @@ class install extends common
$this->getData(['config', 'autoUpdateHtaccess']) === true $this->getData(['config', 'autoUpdateHtaccess']) === true
) { ) {
// L'écraser avec le backup // L'écraser avec le backup
$success = copy('.htaccess.bak', '.htaccess'); copy('.htaccess.bak', '.htaccess');
/*
if ($success === false) { if ($success === false) {
$message = helper::translate('La copie de sauvegarde du fichier htaccess n\'a pas été restaurée !'); $message = helper::translate('La copie de sauvegarde du fichier htaccess n\'a pas été restaurée !');
http_response_code(500); http_response_code(500);
} }
*/
// Effacer le backup // Effacer le backup
unlink('.htaccess.bak'); unlink('.htaccess.bak');
} else { } else {
/** /**
* Restaure la réécriture d'URL * 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'); $fileContent = file_get_contents('.htaccess');
$rewriteData = PHP_EOL . $rewriteData = PHP_EOL .
'# URL rewriting' . PHP_EOL . '# URL rewriting' . PHP_EOL .
@ -401,11 +413,10 @@ class install extends common
'</IfModule>' . PHP_EOL . '</IfModule>' . PHP_EOL .
'# URL rewriting' . PHP_EOL; '# URL rewriting' . PHP_EOL;
$fileContent = str_replace('# URL rewriting', $rewriteData, $fileContent); $fileContent = str_replace('# URL rewriting', $rewriteData, $fileContent);
$success = $this->secure_file_put_contents( file_put_contents(
'.htaccess', '.htaccess',
$fileContent $fileContent
); );
unlink(self::DATA_DIR . '.rewrite');
} }
} }
@ -417,6 +428,7 @@ class install extends common
$defaultLanguages = init::$defaultData['language']; $defaultLanguages = init::$defaultData['language'];
foreach ($installedLanguages as $key => $value) { foreach ($installedLanguages as $key => $value) {
//var_dump( $defaultLanguages[$key]['date'] > $value['date'] );
if ( if (
isset($defaultLanguages[$key]['date']) && isset($defaultLanguages[$key]['date']) &&
$defaultLanguages[$key]['date'] > $value['date'] && $defaultLanguages[$key]['date'] > $value['date'] &&
@ -428,16 +440,13 @@ class install extends common
$this->setData(['language', $key, $defaultLanguages[$key]]); $this->setData(['language', $key, $defaultLanguages[$key]]);
} }
} }
// Sauvegarde le message dans le journal
if (!empty($message)) {
$this->saveLog($message);
}
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'display' => self::DISPLAY_JSON, 'display' => self::DISPLAY_JSON,
'content' => [ 'content' => [
'success' => $success, 'success' => true,
'data' => json_encode($message, JSON_UNESCAPED_UNICODE) 'data' => ''
] ]
]); ]);
} }
@ -460,17 +469,10 @@ class install extends common
} else { } else {
// Nouvelle version // Nouvelle version
self::$newVersion = helper::getUrlContents(common::ZWII_UPDATE_URL . common::ZWII_UPDATE_CHANNEL . '/version'); self::$newVersion = helper::getUrlContents(common::ZWII_UPDATE_URL . common::ZWII_UPDATE_CHANNEL . '/version');
// Variable de version
if (helper::checkNewVersion(common::ZWII_UPDATE_CHANNEL)) {
self::$updateButtonText = helper::translate('Mise à jour');
}
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'display' => self::DISPLAY_LAYOUT_LIGHT, 'display' => self::DISPLAY_LAYOUT_LIGHT,
'title' => helper::translate(self::$updateButtonText), 'title' => helper::translate('Mise à jour'),
'view' => 'update' 'view' => 'update'
]); ]);
} }

View File

@ -26,7 +26,6 @@ class init extends common
'proxyType' => 'tcp://', 'proxyType' => 'tcp://',
'smtp' => [ 'smtp' => [
'enable' => false, 'enable' => false,
'from'=> 'no-reply@localhost'
], ],
'seo' => [ 'seo' => [
'robots' => true, 'robots' => true,
@ -281,22 +280,21 @@ class init extends common
'backgroundColorButtonGreen' => 'rgba(100, 207, 8, 1)', 'backgroundColorButtonGreen' => 'rgba(100, 207, 8, 1)',
'backgroundColorButtonHelp' => 'rgba(255, 153, 0, 1)', 'backgroundColorButtonHelp' => 'rgba(255, 153, 0, 1)',
'backgroundBlockColor' => 'rgba(236, 239, 241, 1)', 'backgroundBlockColor' => 'rgba(236, 239, 241, 1)',
'borderBlockColor' => 'rgba(190, 202, 209, 1)', 'borderBlockColor' => 'rgba(190, 202, 209, 1)'
'width' => '960px'
], ],
'blacklist' => [], 'blacklist' => [],
'language' => [ 'language' => [
"fr_FR" => [ "fr_FR" => [
"version" => 13007, "version" => 13000,
"date" => 1699354723 "date" => 1693425383
], ],
"es" => [ "es" => [
"version" => 13007, "version" => 13000,
"date" => 1699354723 "date" => 1693425383
], ],
"en_EN" => [ "en_EN" => [
"version" => 13007, "version" => 13000,
"date" => 1699354723 "date" => 1693425383
] ]
], ],
'profil' => [ 'profil' => [
@ -420,7 +418,7 @@ class init extends common
'copycut' => false, 'copycut' => false,
'chmod' => false, 'chmod' => false,
'share' => true, 'share' => true,
'path' => '/site/file/source/partage/', 'path' => './site/file/source/partage/',
], ],
'page' => [ 'page' => [
'add' => false, 'add' => false,
@ -506,7 +504,7 @@ class init extends common
'copycut' => false, 'copycut' => false,
'chmod' => false, 'chmod' => false,
'share' => true, 'share' => true,
'path' => '/site/file/source/partage/', 'path' => './site/file/source/partage/',
], ],
'page' => [ 'page' => [
'add' => false, 'add' => false,
@ -588,7 +586,7 @@ class init extends common
'copycut' => true, 'copycut' => true,
'chmod' => true, 'chmod' => true,
'share' => true, 'share' => true,
'path' => '/site/file/source/partage/', 'path' => './site/file/source/partage/',
], ],
'page' => [ 'page' => [
'add' => true, 'add' => true,

View File

@ -396,6 +396,7 @@
"Mise en page": "Layout", "Mise en page": "Layout",
"Mise à jour": "Update", "Mise à jour": "Update",
"Mise à jour automatisée": "Automated update", "Mise à jour automatisée": "Automated update",
"Mise à jour de ZwiiCMS": "Zwiicms update",
"Mise à jour terminée avec succès.": "Successful update completed.", "Mise à jour terminée avec succès.": "Successful update completed.",
"Modifications enregistrées": "Modifications recorded", "Modifications enregistrées": "Modifications recorded",
"Module": "Module", "Module": "Module",
@ -547,7 +548,7 @@
"Sauvegarde": "Backup", "Sauvegarde": "Backup",
"Sauvegarde automatique quotidienne du site": "Daily automatic backup of the site", "Sauvegarde automatique quotidienne du site": "Daily automatic backup of the site",
"Sauvegarde du thème dans le": "Backup of the theme in the", "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": "Backup",
"Sauvegarder et télécharger le module": "Save and download the module", "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", "Sauvegarder le module dans le gestionnaire de fichiers": "Save the module in the file manager",
@ -568,7 +569,7 @@
"Standard": "Standard", "Standard": "Standard",
"Style": "Style", "Style": "Style",
"Suppression interdite": "Deletion prohibited", "Suppression interdite": "Deletion prohibited",
"Suppression interdite, page active dans la configuration de la langue du site": "Deletion not allowed, page is active in the site's language configuration", "Suppression interdite, page active dans la configuration du site": "Deletion prohibited, active page in site configuration",
"Supprime le point d'interrogation dans les URL, l'option est indisponible avec les autres serveurs Web": "Deletes the question mark in the URLs, the option is unavailable with other web servers", "Supprime le point d'interrogation dans les URL, l'option est indisponible avec les autres serveurs Web": "Deletes the question mark in the URLs, the option is unavailable with other web servers",
"Supprimer": "Delete", "Supprimer": "Delete",
"Supprimer la page": "Delete the page", "Supprimer la page": "Delete the page",
@ -633,7 +634,7 @@
"Utilisateur inexistant": "Non-existent user", "Utilisateur inexistant": "Non-existent user",
"Utilisateur supprimé": "User deleted", "Utilisateur supprimé": "User deleted",
"Utilisateurs": "Users", "Utilisateurs": "Users",
"Valider": "Submit", "Valider": "To validate",
"Version": "Version", "Version": "Version",
"Version n°": "Version n°", "Version n°": "Version n°",
"Vider dossier sauvegardes auto": "Empty auto backup files", "Vider dossier sauvegardes auto": "Empty auto backup files",
@ -649,7 +650,7 @@
"jour": "day", "jour": "day",
"jours": "days", "jours": "days",
"sauvegardé avec succès": "successfully saved", "sauvegardé avec succès": "successfully saved",
"vers": "to", "vers ZwiiCMS": "to ZwiiCMS",
"À droite": "Right", "À droite": "Right",
"À gauche": "Left", "À gauche": "Left",
"À l'emplacement du mot clé [MODULE] dans la page": "At the location of the keyword [MODULE] on the page", "À l'emplacement du mot clé [MODULE] dans la page": "At the location of the keyword [MODULE] on the page",
@ -685,9 +686,5 @@
"Flèche": "Arrow", "Flèche": "Arrow",
"Modèle": "Template", "Modèle": "Template",
"Bouton de navigation droit": "Right Navigation Button", "Bouton de navigation droit": "Right Navigation Button",
"Bouton de navigation gauche": "Left Navigation Button", "Bouton de navigation gauche": "Left Navigation Button"
"Groupes / Profils": "Groups / Profiles",
"Prénom commence par": "First Name starts with",
"Nom commence par": "Last Name starts with",
"Impossible de réinitialiser le mot de passe de ce compte !": "Impossible to reset this account password!"
} }

View File

@ -396,6 +396,7 @@
"Mise en page": "Diseño", "Mise en page": "Diseño",
"Mise à jour": "actualización", "Mise à jour": "actualización",
"Mise à jour automatisée": "Actualización automática", "Mise à jour automatisée": "Actualización automática",
"Mise à jour de ZwiiCMS": "Actualización de ZwiiCMS",
"Mise à jour terminée avec succès.": "Actualización completada con éxito.", "Mise à jour terminée avec succès.": "Actualización completada con éxito.",
"Modifications enregistrées": "Cambios guardados", "Modifications enregistrées": "Cambios guardados",
"Module": "Módulo", "Module": "Módulo",
@ -547,7 +548,7 @@
"Sauvegarde": "Salvaguardad", "Sauvegarde": "Salvaguardad",
"Sauvegarde automatique quotidienne du site": "Copia de seguridad diaria automática del sitio", "Sauvegarde automatique quotidienne du site": "Copia de seguridad diaria automática del sitio",
"Sauvegarde du thème dans le": "Guardando tema en el", "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": "Para salvaguardar",
"Sauvegarder et télécharger le module": "Guardar y descargar módulo", "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", "Sauvegarder le module dans le gestionnaire de fichiers": "Guardar módulo en el administrador de archivos",
@ -568,7 +569,7 @@
"Standard": "Estándar", "Standard": "Estándar",
"Style": "Estilo", "Style": "Estilo",
"Suppression interdite": "Borrado prohibido", "Suppression interdite": "Borrado prohibido",
"Suppression interdite, page active dans la configuration de la langue du site": "Eliminación no permitida, la página está activa en la configuración de idioma del sitio", "Suppression interdite, page active dans la configuration du site": "Eliminación prohibida, página activa en la configuración del sitio",
"Supprime le point d'interrogation dans les URL, l'option est indisponible avec les autres serveurs Web": "Eliminar el signo de interrogación en las URL, la opción no está disponible con otros servidores web", "Supprime le point d'interrogation dans les URL, l'option est indisponible avec les autres serveurs Web": "Eliminar el signo de interrogación en las URL, la opción no está disponible con otros servidores web",
"Supprimer": "Borrar", "Supprimer": "Borrar",
"Supprimer la page": "Eliminar página", "Supprimer la page": "Eliminar página",
@ -649,7 +650,7 @@
"jour": "día", "jour": "día",
"jours": "días", "jours": "días",
"sauvegardé avec succès": "Guardado exitosamente", "sauvegardé avec succès": "Guardado exitosamente",
"vers": "hacia", "vers ZwiiCMS": "Hacia ZwiiCMS",
"À droite": "A la derecha", "À droite": "A la derecha",
"À gauche": "A la izquierda", "À gauche": "A la izquierda",
"À l'emplacement du mot clé [MODULE] dans la page": "En la ubicación de la palabra clave [MODULE] en la página", "À l'emplacement du mot clé [MODULE] dans la page": "En la ubicación de la palabra clave [MODULE] en la página",
@ -685,9 +686,5 @@
"Flèche": "Flecha", "Flèche": "Flecha",
"Modèle": "Plantilla", "Modèle": "Plantilla",
"Bouton de navigation droit": "Botón de navegación derecha", "Bouton de navigation droit": "Botón de navegación derecha",
"Bouton de navigation gauche": "Botón de navegación izquierda", "Bouton de navigation gauche": "Botón de navegación izquierda"
"Groupes / Profils": "Grupos / Perfiles",
"Prénom commence par": "El nombre comienza con",
"Nom commence par": "El apellido comienza con",
"Impossible de réinitialiser le mot de passe de ce compte !": "No puedo restablecer la contraseña de esta cuenta."
} }

View File

@ -396,6 +396,7 @@
"Mise en page": "", "Mise en page": "",
"Mise à jour": "", "Mise à jour": "",
"Mise à jour automatisée": "", "Mise à jour automatisée": "",
"Mise à jour de ZwiiCMS": "",
"Mise à jour terminée avec succès.": "", "Mise à jour terminée avec succès.": "",
"Modifications enregistrées": "", "Modifications enregistrées": "",
"Module": "", "Module": "",
@ -547,7 +548,7 @@
"Sauvegarde": "", "Sauvegarde": "",
"Sauvegarde automatique quotidienne du site": "", "Sauvegarde automatique quotidienne du site": "",
"Sauvegarde du thème dans le": "", "Sauvegarde du thème dans le": "",
"Sauvegarde générée avec succès": "", "Sauvegarde générée avec succès.": "",
"Sauvegarder": "", "Sauvegarder": "",
"Sauvegarder et télécharger le module": "", "Sauvegarder et télécharger le module": "",
"Sauvegarder le module dans le gestionnaire de fichiers": "", "Sauvegarder le module dans le gestionnaire de fichiers": "",
@ -568,7 +569,7 @@
"Standard": "", "Standard": "",
"Style": "", "Style": "",
"Suppression interdite": "", "Suppression interdite": "",
"Suppression interdite, page active dans la configuration de la langue du site": "", "Suppression interdite, page active dans la configuration du site": "",
"Supprime le point d'interrogation dans les URL, l'option est indisponible avec les autres serveurs Web": "", "Supprime le point d'interrogation dans les URL, l'option est indisponible avec les autres serveurs Web": "",
"Supprimer": "", "Supprimer": "",
"Supprimer la page": "", "Supprimer la page": "",
@ -649,7 +650,7 @@
"jour": "", "jour": "",
"jours": "", "jours": "",
"sauvegardé avec succès": "", "sauvegardé avec succès": "",
"vers": "", "vers ZwiiCMS": "",
"À droite": "", "À droite": "",
"À gauche": "", "À gauche": "",
"À l'emplacement du mot clé [MODULE] dans la page": "", "À l'emplacement du mot clé [MODULE] dans la page": "",
@ -685,9 +686,5 @@
"Flèche": "", "Flèche": "",
"Modèle": "", "Modèle": "",
"Bouton de navigation droit": "", "Bouton de navigation droit": "",
"Bouton de navigation gauche": "", "Bouton de navigation gauche": ""
"Groupes / Profils": "",
"Prénom commence par": "",
"Nom commence par": "",
"Impossible de réinitialiser le mot de passe de ce compte !": ""
} }

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

View File

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

View File

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

View File

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

View File

@ -1,7 +1,7 @@
function step(i, data) { function step(i, data) {
var errors = ["<?php echo helper::translate('Préparation de la mise à jour'); ?>", "<?php echo helper::translate('Téléchargement et validation de l\'archive'); ?>", "<?php echo helper::translate('Installation'); ?>", "<?php echo helper::translate('Configuration'); ?>"]; var errors = ["<?php echo helper::translate('Préparation de la mise à jour'); ?>", "<?php echo helper::translate('Téléchargement et validation de l\'archive'); ?>", "<?php echo helper::translate('Installation'); ?>", "<?php echo helper::translate('Configuration'); ?>"];
$(".installUpdateProgressText").hide(), $(".installUpdateProgressText[data-id=" + i + "]").show(); $(".installUpdateProgressText").hide(), $(".installUpdateProgressText[data-id=" + i + "]").show();
$("body").css("cursor", "wait"); $("body").css("cursor", "wait");
$.ajax({ $.ajax({
@ -12,6 +12,11 @@ function step(i, data) {
data: data data: data
}, },
success: function (result) { 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 () { setTimeout((function () {
if (4 === i) { if (4 === i) {
$("#installUpdateSuccess").show(); $("#installUpdateSuccess").show();
@ -55,13 +60,10 @@ function showError(step, message, errors) {
const jsonData = JSON.parse(jsonString); const jsonData = JSON.parse(jsonString);
// Afficher les résultats // Afficher les résultats
if (jsonData) { $("#installUpdateErrorMessage").html("<strong>Détails de l'erreur :</strong><br> " +
$("#installUpdateErrorMessage").html("<strong>Détails de l'erreur :</strong><br> " + jsonData.data.replace(/^"(.*)"$/, '$1') +
jsonData.data.replace(/^"(.*)"$/, '$1') + "<br>" +
"<br>" + warningMessage.replace(/<[^p].*?>/g, ""));
warningMessage.replace(/<[^p].*?>/g, ""));
}
} else { } else {
// Vous pouvez également faire quelque chose d'autre ici, par exemple, afficher un message à l'utilisateur, etc. // Vous pouvez également faire quelque chose d'autre ici, par exemple, afficher un message à l'utilisateur, etc.
$("#installUpdateErrorMessage").html(message); $("#installUpdateErrorMessage").html(message);

View File

@ -1,11 +1,11 @@
<div id="updateContainer"> <div id="updateContainer">
<p><strong> <p><strong>
<?php echo helper::translate('Version'); ?> <?php echo helper::translate('Mise à jour de ZwiiCMS'); ?>
&nbsp; &nbsp;
<?php echo self::ZWII_VERSION; ?> <?php echo self::ZWII_VERSION; ?>
<?php echo helper::translate('vers'); ?> <?php echo helper::translate('vers ZwiiCMS'); ?>
&nbsp; &nbsp;
<?php echo $module::$newVersion; ?> <?php echo $module::$newVersion; ?>.
</strong></p> </strong></p>
<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.'); ?> <?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> * @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean * @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com> * @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 * @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/ * @link http://zwiicms.fr/
*/ */
@ -99,7 +99,7 @@ class language extends common
is_array($descripteur['language'][$lang]) is_array($descripteur['language'][$lang])
) { ) {
if ($this->setData(['language', $lang, $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; $success = is_int($success) ? true : false;
} }
} }
@ -197,7 +197,7 @@ class language extends common
) { ) {
if (file_exists(self::DATA_DIR . $key . '/.default')) { if (file_exists(self::DATA_DIR . $key . '/.default')) {
$messageLocale = helper::translate('Langue par défaut'); $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'); $messageLocale = helper::translate('Langue du site sélectionnée');
} else { } else {
$messageLocale = ''; $messageLocale = '';
@ -245,7 +245,7 @@ class language extends common
// Langues disponibles en ligne // Langues disponibles en ligne
$storeUI = json_decode(helper::getUrlContents(self::ZWII_UI_URL . 'language.json'), true); $storeUI = json_decode(helper::getUrlContents(self::ZWII_UI_URL . 'language.json'), true);
$storeUI = $storeUI ? $storeUI['language'] : null; $storeUI = $storeUI['language'];
// Construction du tableau à partir des langues disponibles dans le store // Construction du tableau à partir des langues disponibles dans le store
foreach ($installedUI as $file => $value) { foreach ($installedUI as $file => $value) {
@ -255,23 +255,23 @@ class language extends common
self::$languagesUiInstalled[$file] = [ self::$languagesUiInstalled[$file] = [
template::flag($file, '20 %') . '&nbsp;' . self::$languages[$file], template::flag($file, '20 %') . '&nbsp;' . self::$languages[$file],
$value['version'], $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') : '', //self::$i18nUI === $file ? helper::translate('Interface') : '',
'', '',
/* /*
template::button('translateContentLanguageUIEdit' . $file, [ template::button('translateContentLanguageUIEdit' . $file, [
'href' => helper::baseUrl() . $this->getUrl(0) . '/edit/' . $file, 'href' => helper::baseUrl() . $this->getUrl(0) . '/edit/' . $file,
'value' => template::ico('pencil'), 'value' => template::ico('pencil'),
'help' => 'Éditer', 'help' => 'Éditer',
'disabled' => 'fr_FR' === $file 'disabled' => 'fr_FR' === $file
]), ]),
*/ */
template::button('translateContentLanguageUIDownload' . $file, [ template::button('translateContentLanguageUIDownload' . $file, [
'class' => isset($storeUI[$file]['version']) && version_compare($installedUI[$file]['version'], $storeUI[$file]['version']) < 0 ? 'buttonGreen' : '', 'class' => version_compare($installedUI[$file]['version'], $storeUI[$file]['version']) < 0 ? 'buttonGreen' : '',
'href' => helper::baseUrl() . $this->getUrl(0) . '/update/' . $file, 'href' => helper::baseUrl() . $this->getUrl(0) . '/update/' . $file,
'value' => template::ico('update'), 'value' => template::ico('update'),
'help' => 'Mise à jour', 'help' => 'Mettre à jour',
]), ]),
template::button('translateContentLanguageUIDelete' . $file, [ template::button('translateContentLanguageUIDelete' . $file, [
'class' => 'translateDelete buttonRed' . (in_array($file, $usersUI) ? ' disabled' : ''), 'class' => 'translateDelete buttonRed' . (in_array($file, $usersUI) ? ' disabled' : ''),
@ -283,38 +283,25 @@ class language extends common
} }
} }
// Construction du tableau à partir des langues disponibles dans le store // Construction du tableau à partir des langues disponibles dans le store
if ($storeUI) { foreach ($storeUI as $file => $value) {
foreach ($storeUI as $file => $value) {
// La langue est-elle installée ? // La langue est-elle installée ?
if (array_key_exists($file, $installedUI) === false) { if (array_key_exists($file, $installedUI) === false) {
self::$languagesStore[$file] = [ self::$languagesStore[$file] = [
template::flag($file, '20 %') . '&nbsp;' . self::$languages[$file], template::flag($file, '20 %') . '&nbsp;' . self::$languages[$file],
$value['version'], $value['version'],
helper::dateUTF8('%d/%m/%Y', $value['date'], self::$i18nUI), helper::dateUTF8('%d/%m/%Y', $value['date'], self::$i18nContent),
'', '',
template::button('translateContentLanguageUIDownload' . $file, [ template::button('translateContentLanguageUIDownload' . $file, [
'class' => 'buttonGreen', 'class' => 'buttonGreen',
'href' => helper::baseUrl() . $this->getUrl(0) . '/update/' . $file, 'href' => helper::baseUrl() . $this->getUrl(0) . '/update/' . $file,
'value' => template::ico('shopping-basket'), 'value' => template::ico('shopping-basket'),
'help' => 'Installer', 'help' => 'Installer',
]) ])
]; ];
}
} }
} }
// 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 // Valeurs en sortie
$this->addOutput([ $this->addOutput([
@ -425,12 +412,12 @@ class language extends common
]; ];
// Sauvegarde hors méthodes si la langue n'est pas celle de l'UI // 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 // Enregistrer les données par lecture directe du formulaire
$this->setData(['locale', $data['locale']]); $this->setData(['locale', $data['locale']]);
} else { } else {
// Sauver sur le disque // 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 // Valeurs en sortie
@ -445,7 +432,7 @@ class language extends common
//----------------------------------------- //-----------------------------------------
// La locale est-elle celle de la langue de l'UI ? // 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']); self::$locales[$lang]['locale'] = $this->getData(['locale']);
} else { } else {
// Lire les locales sans passer par les méthodes // Lire les locales sans passer par les méthodes
@ -512,7 +499,7 @@ class language extends common
$data[$key] = $target; $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 // Mettre à jour le descripteur
$this->setData([ $this->setData([
@ -546,7 +533,7 @@ class language extends common
$data[$key] = ''; $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 // Tableau des chaines à traduire dans la langue sélectionnée
foreach ($data as $key => $value) { foreach ($data as $key => $value) {
@ -700,7 +687,7 @@ class language extends common
) { ) {
// Stocker la sélection // Stocker la sélection
$_SESSION['ZWII_SITE_CONTENT'] = $lang; $_SESSION['ZWII_CONTENT'] = $lang;
} }
// Valeurs en sortie // Valeurs en sortie

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -9,7 +9,7 @@
* @author Rémi Jean <remi.jean@outlook.com> * @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean * @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com> * @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 * @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/ * @link http://zwiicms.fr/
*/ */
@ -68,10 +68,10 @@ class page extends common
public static $userProfils = []; public static $userProfils = [];
public static $navIconTemplate = [ public static $navIconTemplate = [
'dir' => 'Petit triangle', 'dir' => 'Petit triangle',
'open' => 'Grand triangle', 'open' => 'Grand triangle',
'big' => 'Flèche', 'big' => 'Flèche',
]; ];
public static $navIconPosition = [ public static $navIconPosition = [
'none' => 'Masqué', 'none' => 'Masqué',
@ -85,19 +85,8 @@ class page extends common
*/ */
public function duplicate() 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 // Adresse sans le token
$page = $this->getUrl(2); $page = $this->getUrl(2);
// La page n'existe pas // La page n'existe pas
if ( if (
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true || $this->getUser('permission', __CLASS__, __FUNCTION__) !== true ||
@ -129,7 +118,7 @@ class page extends common
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $pageId . '/' . self::$siteContent, 'redirect' => helper::baseUrl() . 'page/edit/' . $pageId,
'notification' => $notification, 'notification' => $notification,
'state' => true 'state' => true
]); ]);
@ -142,16 +131,6 @@ class page extends common
*/ */
public function add() 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) { if ($this->getUser('permission', __CLASS__, __FUNCTION__) !== true) {
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
@ -195,11 +174,11 @@ class page extends common
] ]
]); ]);
// Creation du contenu de la page // Creation du contenu de la page
if (!is_dir(self::DATA_DIR . self::$siteContent . '/content')) { if (!is_dir(self::DATA_DIR . self::$i18nContent . '/content')) {
mkdir(self::DATA_DIR . self::$siteContent . '/content', 0755); 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>'); //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::$siteContent); $this->setPage($pageId, '<p>Contenu de votre nouvelle page.</p>', self::$i18nContent);
// Met à jour le sitemap // Met à jour le sitemap
$this->updateSitemap(); $this->updateSitemap();
@ -219,16 +198,6 @@ class page extends common
*/ */
public function delete() 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 // $url prend l'adresse sans le token
$page = $this->getUrl(2); $page = $this->getUrl(2);
// La page n'existe pas // La page n'existe pas
@ -246,7 +215,7 @@ class page extends common
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'redirect' => helper::baseUrl() . 'config', 'redirect' => helper::baseUrl() . 'config',
'notification' => helper::translate('Suppression interdite, page active dans la configuration de la langue du site') 'notification' => helper::translate('Suppression interdite, page active dans la configuration du site')
]); ]);
} }
// Impossible de supprimer la page affectée // Impossible de supprimer la page affectée
@ -254,7 +223,7 @@ class page extends common
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'redirect' => helper::baseUrl() . 'config', 'redirect' => helper::baseUrl() . 'config',
'notification' => helper::translate('Suppression interdite, page active dans la configuration de la langue du site') 'notification' => helper::translate('Suppression interdite, page active dans la configuration du site')
]); ]);
} }
// Impossible de supprimer la page affectée // Impossible de supprimer la page affectée
@ -262,7 +231,7 @@ class page extends common
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'redirect' => helper::baseUrl() . 'config', 'redirect' => helper::baseUrl() . 'config',
'notification' => helper::translate('Suppression interdite, page active dans la configuration de la langue du site') 'notification' => helper::translate('Suppression interdite, page active dans la configuration du site')
]); ]);
} }
// Impossible de supprimer la page affectée // Impossible de supprimer la page affectée
@ -270,7 +239,7 @@ class page extends common
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'redirect' => helper::baseUrl() . 'config', 'redirect' => helper::baseUrl() . 'config',
'notification' => helper::translate('Suppression interdite, page active dans la configuration de la langue du site') 'notification' => helper::translate('Suppression interdite, page active dans la configuration du site')
]); ]);
} }
// Impossible de supprimer la page affectée // Impossible de supprimer la page affectée
@ -278,7 +247,7 @@ class page extends common
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'redirect' => helper::baseUrl() . 'config', 'redirect' => helper::baseUrl() . 'config',
'notification' => helper::translate('Suppression interdite, page active dans la configuration de la langue du site') 'notification' => helper::translate('Suppression interdite, page active dans la configuration du site')
]); ]);
} }
// Impossible de supprimer la page affectée // Impossible de supprimer la page affectée
@ -286,14 +255,14 @@ class page extends common
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'redirect' => helper::baseUrl() . 'config', 'redirect' => helper::baseUrl() . 'config',
'notification' => helper::translate('Suppression interdite, page active dans la configuration de la langue du site') 'notification' => helper::translate('Suppression interdite, page active dans la configuration du site')
]); ]);
} }
// Impossible de supprimer une page contenant des enfants // Impossible de supprimer une page contenant des enfants
elseif ($this->getHierarchy($page, null)) { elseif ($this->getHierarchy($page, null)) {
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $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') 'notification' => helper::translate('Impossible de supprimer une page contenant des pages enfants')
]); ]);
} }
@ -310,8 +279,8 @@ class page extends common
} }
// Effacer la page // Effacer la page
$this->deleteData(['page', $page]); $this->deleteData(['page', $page]);
if (file_exists(self::DATA_DIR . self::$siteContent . '/content/' . $page . '.html')) { if (file_exists(self::DATA_DIR . self::$i18nContent . '/content/' . $page . '.html')) {
unlink(self::DATA_DIR . self::$siteContent . '/content/' . $page . '.html'); unlink(self::DATA_DIR . self::$i18nContent . '/content/' . $page . '.html');
} }
$this->deleteData(['module', $page]); $this->deleteData(['module', $page]);
@ -333,17 +302,6 @@ class page extends common
*/ */
public function edit() 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 // La page n'existe pas
if ( if (
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true || $this->getUser('permission', __CLASS__, __FUNCTION__) !== true ||
@ -411,8 +369,8 @@ class page extends common
// Supprime l'ancienne page si l'id a changée // Supprime l'ancienne page si l'id a changée
if ($pageId !== $this->getUrl(2)) { if ($pageId !== $this->getUrl(2)) {
$this->deleteData(['page', $this->getUrl(2)]); $this->deleteData(['page', $this->getUrl(2)]);
if (file_exists(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::$siteContent . '/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 : // Traitement des pages spéciales affectées dans la config :
@ -550,11 +508,11 @@ class page extends common
]); ]);
// Creation du contenu de la page // Creation du contenu de la page
if (!is_dir(self::DATA_DIR . self::$siteContent . '/content')) { if (!is_dir(self::DATA_DIR . self::$i18nContent . '/content')) {
mkdir(self::DATA_DIR . self::$siteContent . '/content', 0755); 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)); $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 // Met à jour le sitemap
$this->updateSitemap(); $this->updateSitemap();
@ -581,9 +539,6 @@ class page extends common
} }
// Construction du formulaire // Construction du formulaire
// Met à jour le sitemap
$this->updateSitemap();
// Création du sélecteur de modules // Création du sélecteur de modules
self::$moduleIds = []; self::$moduleIds = [];
foreach (helper::getModules() as $key => $values) { foreach (helper::getModules() as $key => $values) {
@ -644,15 +599,14 @@ class page extends common
$css = $this->getInput('pageCssEditorContent', helper::FILTER_STRING_LONG) === null ? '' : $this->getInput('pageCssEditorContent', helper::FILTER_STRING_LONG); $css = $this->getInput('pageCssEditorContent', helper::FILTER_STRING_LONG) === null ? '' : $this->getInput('pageCssEditorContent', helper::FILTER_STRING_LONG);
// Enregistre le CSS // Enregistre le CSS
$this->setData([ $this->setData([
'page', 'page', $this->getUrl(2),
$this->getUrl(2),
'css', 'css',
$css $css
]); ]);
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'notification' => helper::translate('Modifications enregistrées'), '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 'state' => true
]); ]);
} }
@ -679,15 +633,14 @@ class page extends common
$js = $this->getInput('pageJsEditorContent', helper::FILTER_STRING_LONG) === null ? '' : $this->getInput('pageJsEditorContent', helper::FILTER_STRING_LONG); $js = $this->getInput('pageJsEditorContent', helper::FILTER_STRING_LONG) === null ? '' : $this->getInput('pageJsEditorContent', helper::FILTER_STRING_LONG);
// Enregistre le JS // Enregistre le JS
$this->setData([ $this->setData([
'page', 'page', $this->getUrl(2),
$this->getUrl(2),
'js', 'js',
$js $js
]); ]);
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'notification' => helper::translate('Modifications enregistrées'), '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 'state' => true
]); ]);
} }
@ -703,15 +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 * 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() public function getPageInfo()
{ {
$p = $this->getData(['page']); $p = $this->getData(['page']);
$d = array_map(function ($d) { $d = array_map(function ($d) {
unset ($d["css"], $d["js"]); unset($d["css"], $d["js"]);
return $d; return $d;
}, $p); }, $p);
return json_encode($d); return json_encode($d);
} }
} }

View File

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

View File

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

View File

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

View File

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

View File

@ -19,14 +19,14 @@
<div class="col1 offset6"> <div class="col1 offset6">
<?php echo template::button('pageEditDelete', [ <?php echo template::button('pageEditDelete', [
'class' => 'buttonRed', 'class' => 'buttonRed',
'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(2) . '/' . self::$siteContent, 'href' => helper::baseUrl() . 'page/delete/' . $this->getUrl(2),
'value' => template::ico('trash'), 'value' => template::ico('trash'),
'help' => 'Effacer la page' 'help' => 'Effacer la page'
]); ?> ]); ?>
</div> </div>
<div class="col1"> <div class="col1">
<?php echo template::button('pageEditDuplicate', [ <?php echo template::button('pageEditDuplicate', [
'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(2) . '/' . self::$siteContent, 'href' => helper::baseUrl() . 'page/duplicate/' . $this->getUrl(2),
'value' => template::ico('clone'), 'value' => template::ico('clone'),
'help' => 'Dupliquer la page' 'help' => 'Dupliquer la page'
]); ?> ]); ?>
@ -108,7 +108,7 @@
<div class="col12"> <div class="col12">
<?php echo template::textarea('pageEditContent', [ <?php echo template::textarea('pageEditContent', [
'class' => 'editorWysiwyg', 'class' => 'editorWysiwyg',
'value' => $this->getPage($this->getUrl(2), self::$siteContent) 'value' => $this->getPage($this->getUrl(2), self::$i18nContent)
]); ?> ]); ?>
</div> </div>
</div> </div>

View File

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

View File

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

View File

@ -9,7 +9,7 @@
* @author Rémi Jean <remi.jean@outlook.com> * @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean * @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com> * @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 * @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/ * @link http://zwiicms.fr/
*/ */
@ -314,7 +314,7 @@ class plugin extends common
mkdir(self::FILE_DIR . 'source/modules', 0755); mkdir(self::FILE_DIR . 'source/modules', 0755);
} }
// Sauver les données du fichiers // 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 // Installation directe
if (file_exists(self::FILE_DIR . 'source/modules/' . $moduleFile)) { if (file_exists(self::FILE_DIR . 'source/modules/' . $moduleFile)) {
@ -377,7 +377,7 @@ class plugin extends common
$store[$key]['category'], $store[$key]['category'],
'<a href="' . self::BASEURL_STORE . self::MODULE_STORE . $key . '" target="_blank" >' . $store[$key]['title'] . '</a>', '<a href="' . self::BASEURL_STORE . self::MODULE_STORE . $key . '" target="_blank" >' . $store[$key]['title'] . '</a>',
$store[$key]['version'], $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), implode(' - ', $pageInfos),
template::button('moduleExport' . $key, [ template::button('moduleExport' . $key, [
'class' => $class, 'class' => $class,
@ -403,7 +403,7 @@ class plugin extends common
{ {
$store = json_decode(helper::getUrlContents(self::BASEURL_STORE . self::MODULE_STORE . 'list'), true); $store = json_decode(helper::getUrlContents(self::BASEURL_STORE . self::MODULE_STORE . 'list'), true);
self::$storeItem = $store[$this->getUrl(2)]; 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 // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'title' => helper::translate('Module ' . self::$storeItem['title']), 'title' => helper::translate('Module ' . self::$storeItem['title']),
@ -531,19 +531,19 @@ class plugin extends common
$infoModules[$pagesInfos[$keyi18n][$keyPage]['moduleId']]['version'], $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::flag($keyi18n, '20px') . '&nbsp<a href ="' . helper::baseUrl() . $keyPage . '" target="_blank">' . $pagesInfos[$keyi18n][$keyPage]['title'] . ' (' . $keyPage . ')</a>',
template::button('dataExport' . $keyPage, [ 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 // appel de fonction vaut exécution, utiliser un paramètre
'value' => template::ico('download-cloud'), 'value' => template::ico('download-cloud'),
'help' => 'Sauvegarder les données du module dans le gestionnaire de fichiers' 'help' => 'Sauvegarder les données du module dans le gestionnaire de fichiers'
]), ]),
template::button('dataExport' . $keyPage, [ 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 // appel de fonction vaut exécution, utiliser un paramètre
'value' => template::ico('download'), 'value' => template::ico('download'),
'help' => 'Sauvegarder et télécharger les données du module' 'help' => 'Sauvegarder et télécharger les données du module'
]), ]),
template::button('dataDelete' . $keyPage, [ 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 // appel de fonction vaut exécution, utiliser un paramètre
'value' => template::ico('trash'), 'value' => template::ico('trash'),
'class' => 'buttonRed dataDelete', 'class' => 'buttonRed dataDelete',
@ -592,17 +592,15 @@ class plugin extends common
$fileName = $moduleId . str_replace('.', '-', $infoModule[$moduleId]['version']) . '.zip'; $fileName = $moduleId . str_replace('.', '-', $infoModule[$moduleId]['version']) . '.zip';
// Régénération du descripteur du module // Régénération du descripteur du module
$this->secure_file_put_contents(self::MODULE_DIR . $moduleId . '/enum.json', $infoModule[$moduleId]); file_put_contents(self::MODULE_DIR . $moduleId . '/enum.json', json_encode($infoModule[$moduleId], JSON_UNESCAPED_UNICODE));
// Construire l'archive // Construire l'archive
$this->makeZip($tmpFolder . $fileName, self::MODULE_DIR . $moduleId); $this->makeZip($tmpFolder . $fileName, self::MODULE_DIR . $moduleId);
switch ($action) { switch ($action) {
case 'filemanager': case 'filemanager':
if (is_dir(self::FILE_DIR . 'source/modules') === false) {
mkdir(self::FILE_DIR . 'source/modules');
}
$success = copy($tmpFolder . $fileName, self::FILE_DIR . 'source/modules/' . $fileName); $success = copy($tmpFolder . $fileName, self::FILE_DIR . 'source/modules/' . $fileName);
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'redirect' => helper::baseUrl() . 'plugin', 'redirect' => helper::baseUrl() . 'plugin',

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -11,7 +11,7 @@
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International * @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/ * @link http://zwiicms.fr/
* @copyright : Frédéric Tempez <frederic.tempez@outlook.com> * @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 class theme extends common
@ -214,7 +214,7 @@ class theme extends common
'750px' => '750 pixels', '750px' => '750 pixels',
'960px' => '960 pixels', '960px' => '960 pixels',
'1170px' => '1170 pixels', '1170px' => '1170 pixels',
'100%' => '100%', '100%' => '100%'
]; ];
public static $headerWide = [ public static $headerWide = [
'auto auto' => 'Automatique', 'auto auto' => 'Automatique',
@ -269,7 +269,6 @@ class theme extends common
'fontTitle' => $this->getInput('adminFontTitle'), 'fontTitle' => $this->getInput('adminFontTitle'),
'backgroundBlockColor' => $this->getInput('adminBackGroundBlockColor'), 'backgroundBlockColor' => $this->getInput('adminBackGroundBlockColor'),
'borderBlockColor' => $this->getInput('adminBorderBlockColor'), 'borderBlockColor' => $this->getInput('adminBorderBlockColor'),
'width' => $this->getInput('adminSiteWidth'),
] ]
]); ]);
// Valeurs en sortie // Valeurs en sortie
@ -304,7 +303,7 @@ class theme extends common
$this->isPost() $this->isPost()
) { ) {
// Enregistre le CSS // 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 // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'notification' => helper::translate('Modifications enregistrées'), 'notification' => helper::translate('Modifications enregistrées'),
@ -628,16 +627,16 @@ class theme extends common
// Toutes les fontes installées sont chargées // Toutes les fontes installées sont chargées
$this->setFonts('all'); $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 // Polices liées au thème
$fonts['Bannière'] = $this->getData(['theme', 'header', 'font']); $used = [
$fonts['Menu'] = $this->getData(['theme', 'menu', 'font']); 'Bannière' => $this->getData(['theme', 'header', 'font']),
$fonts['Titre'] = $this->getData(['theme', 'title', 'font']); 'Menu' => $this->getData(['theme', 'menu', 'font']),
$fonts['Texte'] = $this->getData(['theme', 'text', 'font']); 'Titre ' => $this->getData(['theme', 'title', 'font']),
$fonts['Pied de page'] = $this->getData(['theme', 'footer', '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 // Récupérer le détail des fontes installées
//$f = $this->getFonts(); //$f = $this->getFonts();
@ -649,23 +648,24 @@ class theme extends common
foreach ($f as $type => $typeValue) { foreach ($f as $type => $typeValue) {
if (is_array($typeValue)) { if (is_array($typeValue)) {
foreach ($typeValue as $fontId => $fontValue) { foreach ($typeValue as $fontId => $fontValue) {
// Recherche les correspondances // Fontes utilisées par les thèmes
$result = array_filter($fonts, function($value) use ($fontId) { $fontUsed[$fontId] = '';
return $value == $fontId; foreach ($used as $key => $value) {
}); if ($value === $fontId) {
$keyResults = array_keys($result); $fontUsed[$fontId] .= $key . '<br/>';
// Préparation du tableau }
}
self::$fontsDetail[] = [ self::$fontsDetail[] = [
$fontId, $fontId,
'<span style="font-family:' . $f[$type][$fontId]['font-family'] . '">' . $f[$type][$fontId]['name'] . '</span>', '<span style="font-family:' . $f[$type][$fontId]['font-family'] . '">' . $f[$type][$fontId]['name'] . '</span>',
$f[$type][$fontId]['font-family'], $f[$type][$fontId]['font-family'],
empty($keyResults) ? '' : '<span class="fontsList">' . implode('<br />', $keyResults) . '</span>', $fontUsed[$fontId],
$type, $type,
$type !== 'websafe' ? template::button('themeFontEdit' . $fontId, [ $type !== 'websafe' ? template::button('themeFontEdit' . $fontId, [
'class' => 'themeFontEdit', 'class' => 'themeFontEdit',
'href' => helper::baseUrl() . $this->getUrl(0) . '/fontEdit/' . $type . '/' . $fontId, 'href' => helper::baseUrl() . $this->getUrl(0) . '/fontEdit/' . $type . '/' . $fontId,
'value' => template::ico('pencil'), 'value' => template::ico('pencil'),
//'disabled' => !empty($fontUsed[$fontId]) 'disabled' => !empty($fontUsed[$fontId])
]) ])
: '', : '',
$type !== 'websafe' ? template::button('themeFontDelete' . $fontId, [ $type !== 'websafe' ? template::button('themeFontDelete' . $fontId, [
@ -683,10 +683,7 @@ class theme extends common
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'title' => helper::translate('Fontes'), 'title' => helper::translate('Fontes'),
'view' => 'font', 'view' => 'font'
'vendor' => [
'datatables'
]
]); ]);
} }
@ -703,8 +700,8 @@ class theme extends common
// Type d'import en ligne ou local // Type d'import en ligne ou local
$type = $this->getInput('fontAddUrl', helper::FILTER_BOOLEAN) ? 'imported' : 'files'; $type = $this->getInput('fontAddUrl', helper::FILTER_BOOLEAN) ? 'imported' : 'files';
$type === 'files' ? 'imported' : 'files'; $type === 'files' ? 'imported' : 'files';
$resource = $type === 'imported' ? $this->getInput('fontAddUrl', null) : $this->getInput('fontAddFile', null); $ressource = $type === 'imported' ? $this->getInput('fontAddUrl', null) : $this->getInput('fontAddFile', null);
if (!empty($resource)) { if (!empty($ressource)) {
$fontId = $this->getInput('fontAddFontId', null, true); $fontId = $this->getInput('fontAddFontId', null, true);
$fontName = $this->getInput('fontAddFontName', null, true); $fontName = $this->getInput('fontAddFontName', null, true);
$fontFamilyName = $this->getInput('fontAddFontFamilyName', null, true); $fontFamilyName = $this->getInput('fontAddFontFamilyName', null, true);
@ -716,21 +713,6 @@ class theme extends common
if (is_array($this->getData(['font', $type, $fontId]))) { if (is_array($this->getData(['font', $type, $fontId]))) {
$this->deleteData(['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 // Stocker la fonte
$this->setData([ $this->setData([
'font', 'font',
@ -739,16 +721,24 @@ class theme extends common
[ [
'name' => $fontName, 'name' => $fontName,
'font-family' => $fontFamilyName, 'font-family' => $fontFamilyName,
// Stocke l'URL our lien vers la fonte dans data 'resource' => $ressource
'resource' => $type === 'imported' ? $resource : self::DATA_DIR . 'font/' . basename($resource),
] ]
]); ]);
// 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 // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'notification' => $success ? helper::translate('Fonte actualisée') : helper::translate('Fonte non créée, ressource absente !'), 'notification' => helper::translate('Fonte créée'),
'redirect' => helper::baseUrl() . 'theme/font', 'redirect' => helper::baseUrl() . 'theme/fonts',
'state' => $success 'state' => true
]); ]);
} else { } else {
// Valeurs en sortie // Valeurs en sortie
@ -779,8 +769,8 @@ class theme extends common
) { ) {
// Type d'import en ligne ou local // Type d'import en ligne ou local
$type = $this->getInput('fontEditUrl', helper::FILTER_BOOLEAN) ? 'imported' : 'files'; $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); $fontId = $this->getInput('fontEditFontId', null, true);
$resource = $this->getData(['font', $type, $fontId, 'resource']);
$fontName = $this->getInput('fontEditFontName', null, true); $fontName = $this->getInput('fontEditFontName', null, true);
$fontFamilyName = $this->getInput('fontEditFontFamilyName', null, true); $fontFamilyName = $this->getInput('fontEditFontFamilyName', null, true);
@ -792,7 +782,6 @@ class theme extends common
$this->deleteData(['font', $type, $fontId]); $this->deleteData(['font', $type, $fontId]);
} }
// Stocker les fontes // Stocker les fontes
$this->setData([ $this->setData([
'font', 'font',
@ -801,14 +790,21 @@ class theme extends common
[ [
'name' => $fontName, 'name' => $fontName,
'font-family' => $fontFamilyName, '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 // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'notification' => helper::translate('Fonte actualisée'), 'notification' => helper::translate('Fonte actualisée'),
'redirect' => helper::baseUrl() . 'theme/font', 'redirect' => helper::baseUrl() . 'theme/fonts',
'state' => true 'state' => true
]); ]);
} }
@ -842,16 +838,15 @@ class theme extends common
// Effacer le fichier existant // Effacer le fichier existant
if ( if (
$this->getUrl(2) === 'files' && $this->getUrl(2) === 'file' &&
file_exists($this->getData(['font', 'files', $this->getUrl(3), 'resource'])) file_exists(self::DATA_DIR . $this->getUrl(2))
) { ) {
unlink(self::DATA_DIR . $this->getUrl(2));
unlink($this->getData(['font', 'files', $this->getUrl(3), 'resource']));
} }
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'redirect' => helper::baseUrl() . 'theme/font', 'redirect' => helper::baseUrl() . 'theme/fonts',
'notification' => helper::translate('Fonte supprimée'), 'notification' => helper::translate('Fonte supprimée'),
'state' => true 'state' => true
]); ]);
@ -1225,15 +1220,13 @@ class theme extends common
// Ajoute les fontes // Ajoute les fontes
$zip->addEmptyDir(self::DATA_DIR . 'font'); $zip->addEmptyDir(self::DATA_DIR . 'font');
$fonts = $this->getData(['font', 'files']); $fonts = $this->getData(['font', 'files']);
foreach ($fonts as $fontId => $fontInfo) { foreach ($fonts as $fontId => $fontName) {
$zip->addFile($fontInfo['resource'], $fontInfo['resource']); $zip->addFile(self::DATA_DIR . 'font/' . $fontName, self::DATA_DIR . 'font/' . $fontName);
} }
if (file_exists(self::DATA_DIR . 'font/font.html')) { if (file_exists(self::DATA_DIR . 'font/font.html')) {
$zip->addFile(self::DATA_DIR . 'font/font.html', 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; break;
} }
$ret = $zip->close(); $ret = $zip->close();
@ -1290,7 +1283,7 @@ class theme extends common
} }
// Sauvegarder la chaîne modifiée // Sauvegarder la chaîne modifiée
if ($count > 0) { if ($count > 0) {
$this->secure_file_put_contents($file, $data); file_put_contents($file, $data);
} }
// Retourner le nombre d'occurrences // Retourner le nombre d'occurrences
return ($count); return ($count);
@ -1380,13 +1373,13 @@ class theme extends common
($scope === 'user' && in_array($fontId, $fontsInstalled)) ($scope === 'user' && in_array($fontId, $fontsInstalled))
|| $scope === 'all' || $scope === 'all'
) { ) {
if (file_exists($fontValue['resource'])) { if (file_exists(self::DATA_DIR . 'font/' . $fontValue['resource'])) {
// Extension // Extension
$path_parts = pathinfo(helper::baseUrl(false) . self::DATA_DIR . 'font/' . $fontValue['resource']); $path_parts = pathinfo(helper::baseUrl(false) . self::DATA_DIR . 'font/' . $fontValue['resource']);
// Chargement de la police // Chargement de la police
$fileContentCss .= '@font-face {'; $fileContentCss .= '@font-face {';
$fileContentCss .= 'font-family:"' . $fontValue['name'] . '";'; $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 .= '}'; $fileContentCss .= '}';
// Préchargement // Préchargement
//$fileContent = '<link rel="preload" href="' . self::DATA_DIR . 'font/' . $fontValue['resource'] . '" type="font/woff" crossorigin="anonymous" as="font">' . $fileContent; //$fileContent = '<link rel="preload" href="' . self::DATA_DIR . 'font/' . $fontValue['resource'] . '" type="font/woff" crossorigin="anonymous" as="font">' . $fileContent;
@ -1396,8 +1389,8 @@ class theme extends common
} }
// Enregistre la personnalisation // 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 // 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> * @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean * @copyright Copyright (C) 2008-2018, Rémi Jean
* @author Frédéric Tempez <frederic.tempez@outlook.com> * @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 * @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/ * @link http://zwiicms.fr/
*/ */

View File

@ -32,16 +32,10 @@
<div class="row"> <div class="row">
<div class="col12"> <div class="col12">
<div class="block"> <div class="block">
<h4><?php echo helper::translate('Paramètres'); ?> <h4><?php echo helper::translate('Couleurs'); ?>
</h4> </h4>
<div class="row"> <div class="row">
<div class="col3"> <div class="col4">
<?php echo template::select('adminSiteWidth', $module::$siteWidths, [
'label' => 'Largeur',
'selected' => $this->getData(['admin', 'width'])
]); ?>
</div>
<div class="col3">
<?php echo template::text('adminBackgroundColor', [ <?php echo template::text('adminBackgroundColor', [
'class' => 'colorPicker', 'class' => 'colorPicker',
'help' => 'Couleur visible en l\'absence d\'une image.<br />Le curseur horizontal règle le niveau de transparence.', 'help' => 'Couleur visible en l\'absence d\'une image.<br />Le curseur horizontal règle le niveau de transparence.',
@ -49,7 +43,7 @@
'value' => $this->getData(['admin', 'backgroundColor']) 'value' => $this->getData(['admin', 'backgroundColor'])
]); ?> ]); ?>
</div> </div>
<div class="col3"> <div class="col4">
<?php echo template::text('adminColorTitle', [ <?php echo template::text('adminColorTitle', [
'class' => 'colorPicker', 'class' => 'colorPicker',
'help' => 'Couleur visible en l\'absence d\'une image.<br />Le curseur horizontal règle le niveau de transparence.', 'help' => 'Couleur visible en l\'absence d\'une image.<br />Le curseur horizontal règle le niveau de transparence.',
@ -57,7 +51,7 @@
'value' => $this->getData(['admin', 'colorTitle']) 'value' => $this->getData(['admin', 'colorTitle'])
]); ?> ]); ?>
</div> </div>
<div class="col3"> <div class="col4">
<?php echo template::text('adminColorText', [ <?php echo template::text('adminColorText', [
'class' => 'colorPicker', 'class' => 'colorPicker',
'help' => 'Couleur visible en l\'absence d\'une image.<br />Le curseur horizontal règle le niveau de transparence.', 'help' => 'Couleur visible en l\'absence d\'une image.<br />Le curseur horizontal règle le niveau de transparence.',
@ -83,7 +77,7 @@
'value' => $this->getData(['admin', 'borderBlockColor']) 'value' => $this->getData(['admin', 'borderBlockColor'])
]); ?> ]); ?>
</div> </div>
<div class="col4"> <div class="col3 offset1">
<?php echo template::text('adminColorHelp', [ <?php echo template::text('adminColorHelp', [
'class' => 'colorPicker', 'class' => 'colorPicker',
'help' => 'Couleur visible en l\'absence d\'une image.<br />Le curseur horizontal règle le niveau de transparence.', 'help' => 'Couleur visible en l\'absence d\'une image.<br />Le curseur horizontal règle le niveau de transparence.',

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -4,31 +4,8 @@
* file that was distributed with this source code. * file that was distributed with this source code.
* *
* @author Frédéric Tempez <frederic.tempez@outlook.com> * @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 * @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/ * @link http://zwiicms.fr/
*/ */
$(".themeFontDelete").on("click", (function() { $(".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"))}))}));
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,
"columnDefs": [{
target: 5,
orderable: false,
searchable: false
},
{
target: 6,
orderable: false,
searchable: false
}
]
});

View File

@ -24,7 +24,7 @@
</div> </div>
</div> </div>
<?php if ($module::$fontsDetail) : ?> <?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 else : ?>
<?php echo template::speech('Aucune fonte !'); ?> <?php echo template::speech('Aucune fonte !'); ?>
<?php endif; ?> <?php endif; ?>

View File

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

View File

@ -4,34 +4,8 @@
* file that was distributed with this source code. * file that was distributed with this source code.
* *
* @author Frédéric Tempez <frederic.tempez@outlook.com> * @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 * @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/ * @link http://zwiicms.fr/
*/ */
$("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()}));
$(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
}
});

View File

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

View File

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

View File

@ -4,7 +4,7 @@
* file that was distributed with this source code. * file that was distributed with this source code.
* *
* @author Frédéric Tempez <frederic.tempez@outlook.com> * @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 * @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/ * @link http://zwiicms.fr/
*/ */

View File

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

View File

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

View File

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

View File

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

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