Compare commits

..

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

378 changed files with 5327 additions and 14415 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

1224
CHANGES.md

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
# ZwiiCMS 13.3.02 # ZwiiCMS 12.3.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*
@ -73,12 +76,11 @@ A l'occasion de l'installation d'une verion majeure, il est recommandé de réal
[F] page.json Données des pages [F] page.json Données des pages
[F] module.json Données des modules de pages [F] module.json Données des modules de pages
[F] local.json Données du site propres à la langue [F] local.json Données du site propres à la langue
[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] fonts.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
@ -87,10 +89,9 @@ A l'occasion de l'installation d'une verion majeure, il est recommandé de réal
[F] config.json Configuration du site [F] config.json Configuration du site
[F] core.json Configuration du noyau [F] core.json Configuration du noyau
[F] custom.css Feuille de style de la personnalisation avancée [F] custom.css Feuille de style de la personnalisation avancée
[F] font.json Descripteur des fontes personnalisées [F] fonts.json Descripteur des fontes personnalisées
[F] journal.log Journalisation des activités [F] journal.log Journalisation des actions
[F] language.json Langues de l'interface [F] languages.json Configuration des langues de l'interface
[F] profil.json Profils des utilisateurs
[F] theme.css Thème du site [F] theme.css Thème du site
[F] theme.json Données du site [F] theme.json Données du site
[F] user.json Données des utilisateurs [F] user.json Données des utilisateurs

View File

@ -1,4 +1,4 @@
# ZwiiCMS 13.3.02 # ZwiiCMS 12.3.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/telechargement)
## 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
@ -74,7 +77,6 @@ text
[FILE] page.json Page data [FILE] page.json Page data
[FILE] module.json Page module data [FILE] module.json Page module data
[FILE] local.json Language-specific site data [FILE] local.json Language-specific site data
[FILE] .default Unique file of default site language
[DIR] content Folder of page contents [DIR] content Folder of page contents
[FILE] home.html Sample home page content [FILE] home.html Sample home page content
[DIR] fonts Folder containing the installed fonts [DIR] fonts Folder containing the installed fonts
@ -88,13 +90,12 @@ text
[FILE] config.json Site configuration [FILE] config.json Site configuration
[FILE] core.json Core configuration [FILE] core.json Core configuration
[FILE] custom.css Advanced customization stylesheet [FILE] custom.css Advanced customization stylesheet
[FILE] font.json Custom font descriptor [FILE] fonts.json Custom font descriptor
[FILE] journal.log Activities logging [FILE] journal.log Action logging
[FILE] language.json Interface languages database [FILE] languages.json Interface database languages
[FILE] profil.json Users profiles database
[FILE] theme.css Site theme [FILE] theme.css Site theme
[FILE] theme.json Site database [FILE] theme.json Site data
[FILE] user.json User database [FILE] user.json User data
[FILE] .backup Marker for file backup if present [FILE] .backup Marker for file backup if present
[DIR] file File manager upload directory [DIR] file File manager upload directory
[DIR] source Various resources [DIR] source Various resources

View File

@ -2,11 +2,8 @@
class autoload { class autoload {
public static function autoloader () { public static function autoloader () {
require_once 'core/core.php';
require_once 'core/class/router.class.php';
require_once 'core/class/helper.class.php'; require_once 'core/class/helper.class.php';
require_once 'core/class/template.class.php'; require_once 'core/class/template.class.php';
require_once 'core/class/layout.class.php';
require_once 'core/class/sitemap/Runtime.class.php'; require_once 'core/class/sitemap/Runtime.class.php';
require_once 'core/class/sitemap/FileSystem.class.php'; require_once 'core/class/sitemap/FileSystem.class.php';
require_once 'core/class/sitemap/SitemapGenerator.class.php'; require_once 'core/class/sitemap/SitemapGenerator.class.php';

View File

@ -26,15 +26,31 @@ class helper
public static function translate($text) public static function translate($text)
{ {
/*
*
$target = 'redirection';
$url = $_SERVER['QUERY_STRING'];
$module = explode('/', $url);
if ( $module[0] === $target)
{
// La traduction existe déjà dans le core
if (array_key_exists($text, core::$dialog) === false && !empty($text)) {
$dialogues = json_decode(file_get_contents('module/' . $target . '/i18n/fr_FR.json' ), true);
$data = array_merge($dialogues,[$text => '']);
file_put_contents ('module/' . $target . '/i18n/fr_FR.json', json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT), LOCK_EX);
}
}
*/
// La traduction existe déjà dans le core // La traduction existe déjà dans le core
/* /*
if (array_key_exists($text, core::$dialog) === false && !empty($text)) { if (array_key_exists($text, core::$dialog) === false && !empty($text)) {
$dialogues = json_decode(file_get_contents('core/module/install/ressource/i18n/fr_FR.json' ), true); $dialogues = json_decode(file_get_contents('core/module/install/ressource/i18n/fr_FR.json' ), true);
$data = array_merge($dialogues,[$text => '']); $data = array_merge($dialogues,[$text => '']);
file_put_contents ('core/module/install/ressource/i18n/fr_FR.json', json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT), LOCK_EX); file_put_contents ('core/module/install/ressource/i18n/fr_FR.json', json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT), LOCK_EX);
} }
*/ */
return (array_key_exists($text, core::$dialog) && !empty(core::$dialog[$text]) ? core::$dialog[$text] : $text); return (array_key_exists($text, core::$dialog) && !empty(core::$dialog[$text]) ? core::$dialog[$text] : $text);
} }
@ -43,41 +59,40 @@ class helper
* Date au format time() * Date au format time()
* $format strftime * $format strftime
*/ */
public static function dateUTF8($format, $date, $locale = 'fr_FR') public static function dateUTF8($format, $date)
{ {
require_once 'core/class/strftime/php-8.1-strftime.class.php'; require_once 'core/class/strftime/php-8.1-strftime.class.php';
return mb_convert_encoding(\PHP81_BC\strftime($format, $date, $locale), 'UTF-8', mb_list_encodings()); return mb_convert_encoding(\PHP81_BC\strftime($format, $date), 'UTF-8', mb_list_encodings());
} }
/** /**
* Fonction pour assurer la traduction des messages * Fonction pour assurer la traduction des messages
*/ */
public static function googleTranslate($to, $text) public static function googleTranslate($to, $text){
{
if (!file_exists('site/i18n/' . $to . '.json')) { if (!file_exists('site/i18n/' . $to . '.json')) {
file_put_contents('site/i18n/' . $to . '.json', json_encode([])); file_put_contents ('site/i18n/' . $to . '.json', json_encode([]));
} }
if (!empty($text)) { if (!empty($text)) {
//Lecture des données en ligne //Lecture des données en ligne
$data = json_decode(file_get_contents('site/i18n/' . $to . '.json'), true); $data = json_decode(file_get_contents('site/i18n/' . $to . '.json'), true);
// Mode traduction // Mode traduction
if ($to !== 'fr_FR') { if ($to !== 'fr_FR') {
$arrayjson = json_decode(file_get_contents('https://clients5.google.com/translate_a/t?client=dict-chrome-ex&sl=auto&tl=' . $to . '&q=' . rawurlencode($text)), true); $arrayjson = json_decode(file_get_contents('https://clients5.google.com/translate_a/t?client=dict-chrome-ex&sl=auto&tl=' . $to . '&q=' . rawurlencode($text)),true);
$response = $arrayjson[0][0]; $response = $arrayjson[0][0];
// Captation // Captation
if ($data !== '') { if ($data !== '') {
if (array_key_exists($text, $data)) { if (array_key_exists($text, $data) ) {
$data[$text] = $response; $data[$text] = $response;
} else { } else {
$data = array_merge($data, [$text => $response]); $data = array_merge($data,[$text => $response]);
} }
} }
// Mode alimentation des chaines // Mode alimentation des chaines
} else { } else {
// 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);
} }
} }
@ -194,12 +209,12 @@ class helper
// Creation du ZIP // Creation du ZIP
$baseName = str_replace('/', '', helper::baseUrl(false, false)); $baseName = str_replace('/', '', helper::baseUrl(false, false));
$baseName = empty($baseName) ? 'ZwiiCMS' : $baseName; $baseName = empty($baseName) ? 'ZwiiCMS' : $baseName;
$fileName = $baseName . '-backup-' . date('Y-m-d-H-i-s', time()) . '.zip'; $fileName = $baseName . '-backup-' . date('Y-m-d-H-i-s', time()) . '.zip';
$zip = new ZipArchive(); $zip = new ZipArchive();
$zip->open($folder . $fileName, ZipArchive::CREATE | ZipArchive::OVERWRITE); $zip->open($folder . $fileName, ZipArchive::CREATE | ZipArchive::OVERWRITE);
$directory = 'site/'; $directory = 'site/';
//$filter = array('backup','tmp','file'); //$filter = array('backup','tmp','file');
$files = new RecursiveIteratorIterator( $files = new RecursiveIteratorIterator(
new RecursiveCallbackFilterIterator( new RecursiveCallbackFilterIterator(
new RecursiveDirectoryIterator( new RecursiveDirectoryIterator(
$directory, $directory,
@ -228,7 +243,7 @@ class helper
* du nom réel * du nom réel
* du numéro de version * du numéro de version
*/ */
public static function getModules() public static function getModules()
{ {
$modules = array(); $modules = array();
$dirs = array_diff(scandir('module'), array('..', '.')); $dirs = array_diff(scandir('module'), array('..', '.'));
@ -270,7 +285,7 @@ class helper
$dataDirectory = ''; $dataDirectory = '';
} }
// Affection // Affection
$modules[$value] = [ $modules[$value] = [
'name' => $value, 'name' => $value,
'realName' => $realName, 'realName' => $realName,
'version' => $version, 'version' => $version,
@ -366,11 +381,11 @@ class helper
public static function checkNewVersion($channel) public static function checkNewVersion($channel)
{ {
$version = helper::getOnlineVersion($channel); $version = helper::getOnlineVersion($channel);
$update = false;
if (!empty($version)) { if (!empty($version)) {
$update = version_compare(common::ZWII_VERSION, $version) == -1; return ((version_compare(common::ZWII_VERSION, $version)) === -1);
} else {
return false;
} }
return $update;
} }
@ -388,12 +403,12 @@ class helper
'darken' => 'rgba(' . max(0, $rgba[0] - 15) . ',' . max(0, $rgba[1] - 15) . ',' . max(0, $rgba[2] - 15) . ',' . $rgba[3] . ')', 'darken' => 'rgba(' . max(0, $rgba[0] - 15) . ',' . max(0, $rgba[1] - 15) . ',' . max(0, $rgba[2] - 15) . ',' . $rgba[3] . ')',
'veryDarken' => 'rgba(' . max(0, $rgba[0] - 20) . ',' . max(0, $rgba[1] - 20) . ',' . max(0, $rgba[2] - 20) . ',' . $rgba[3] . ')', 'veryDarken' => 'rgba(' . max(0, $rgba[0] - 20) . ',' . max(0, $rgba[1] - 20) . ',' . max(0, $rgba[2] - 20) . ',' . $rgba[3] . ')',
'text' => self::relativeLuminanceW3C($rgba) > .22 ? "#222" : "#DDD", 'text' => self::relativeLuminanceW3C($rgba) > .22 ? "#222" : "#DDD",
'rgb' => 'rgb(' . $rgba[0] . ',' . $rgba[1] . ',' . $rgba[2] . ')', 'rgb' => 'rgb(' . $rgba[0] . ',' . $rgba[1] . ',' . $rgba[2] . ')',
'invert' => 'rgba (' . 'invert' => 'rgba (' .
($rgba[0] < 128 ? 255 : 0) . ',' . ($rgba[0] < 128 ? 255 : 0) . ',' .
($rgba[1] < 128 ? 255 : 0) . ',' . ($rgba[1] < 128 ? 255 : 0) . ',' .
($rgba[1] < 128 ? 255 : 0) . ',' . ($rgba[1] < 128 ? 255 : 0) . ',' .
($rgba[0] < 128 ? 255 : 0) . ')' ($rgba[0] < 128 ? 255 : 0) . ')'
]; ];
} }
@ -432,13 +447,11 @@ class helper
break; break;
case self::FILTER_ID: case self::FILTER_ID:
$text = mb_strtolower($text, 'UTF-8'); $text = mb_strtolower($text, 'UTF-8');
$text = strip_tags( $text = strip_tags(str_replace(
str_replace( explode(',', 'á,à,â,ä,ã,å,ç,é,è,ê,ë,í,ì,î,ï,ñ,ó,ò,ô,ö,õ,ú,ù,û,ü,ý,ÿ,\',", '),
explode(',', 'á,à,â,ä,ã,å,ç,é,è,ê,ë,í,ì,î,ï,ñ,ó,ò,ô,ö,õ,ú,ù,û,ü,ý,ÿ,\',", '), explode(',', 'a,a,a,a,a,a,c,e,e,e,e,i,i,i,i,n,o,o,o,o,o,u,u,u,u,y,y,-,-,-'),
explode(',', 'a,a,a,a,a,a,c,e,e,e,e,i,i,i,i,n,o,o,o,o,o,u,u,u,u,y,y,-,-,-'), $text
$text ));
)
);
$text = preg_replace('/([^a-z0-9-])/', '', $text); $text = preg_replace('/([^a-z0-9-])/', '', $text);
// Supprime les emoji // Supprime les emoji
$text = preg_replace('/[[:^print:]]/', '', $text); $text = preg_replace('/[[:^print:]]/', '', $text);
@ -558,7 +571,7 @@ class helper
* @param null|int $sufix Suffixe de l'url * @param null|int $sufix Suffixe de l'url
* @return array * @return array
*/ */
public static function pagination($array, $url, $item, $suffix = null) public static function pagination($array, $url, $item, $sufix = null)
{ {
// Scinde l'url // Scinde l'url
$url = explode('/', $url); $url = explode('/', $url);
@ -582,7 +595,7 @@ class helper
if ($nbPage > 1) { if ($nbPage > 1) {
for ($i = 1; $i <= $nbPage; $i++) { for ($i = 1; $i <= $nbPage; $i++) {
$disabled = ($i === $currentPage) ? ' class="disabled"' : false; $disabled = ($i === $currentPage) ? ' class="disabled"' : false;
$pages .= '<a href="' . helper::baseUrl() . $urlCurrent . '/' . $i . $suffix . '"' . $disabled . '>' . $i . '</a>'; $pages .= '<a href="' . helper::baseUrl() . $urlCurrent . '/' . $i . $sufix . '"' . $disabled . '>' . $i . '</a>';
} }
$pages = '<div class="pagination">' . $pages . '</div>'; $pages = '<div class="pagination">' . $pages . '</div>';
} }
@ -675,11 +688,10 @@ class helper
* @param string $string la chaine à coder * @param string $string la chaine à coder
* @return string * @return string
*/ */
public static function encrypt($string, $key) public static function encrypt($string, $key) {
{
$encrypted = openssl_encrypt($string, "AES-256-CBC", $key, 0, substr(md5($key), 0, 16)); $encrypted = openssl_encrypt($string, "AES-256-CBC", $key, 0, substr(md5($key), 0, 16));
return base64_encode($encrypted); return base64_encode($encrypted);
} }
/** /**
* Décryptage * Décryptage
@ -687,10 +699,9 @@ class helper
* @param string $string la chaine à décoder * @param string $string la chaine à décoder
* @return string * @return string
*/ */
public static function decrypt($string, $key) public static function decrypt($string, $key) {
{
$decrypted = openssl_decrypt(base64_decode($string), "AES-256-CBC", $key, 0, substr(md5($key), 0, 16)); $decrypted = openssl_decrypt(base64_decode($string), "AES-256-CBC", $key, 0, substr(md5($key), 0, 16));
return $decrypted; return $decrypted;
} }
} }

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 = [])
{ {
@ -121,16 +115,16 @@ class JsonDb extends \Prowebcraft\Dot
protected function loadData($reload = false) protected function loadData($reload = false)
{ {
if ($this->data === null || $reload) { if ($this->data === null || $reload) {
$this->db = $this->config['dir'] . $this->config['name']; $this->db = $this->config['dir'] . DIRECTORY_SEPARATOR . $this->config['name'];
if (!file_exists($this->db)) { if (!file_exists($this->db)) {
return null; // Rebuild database manage by CMS return null; // Rebuild database manage by CMS
} 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,22 @@ 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); $l = strlen($v);
$t = 0;
// Vérifie la longueur de la chaîne JSON encodée while ($t < 5) {
$encoded_length = strlen($encoded_data); $w = file_put_contents($this->db, $v); // Multi user get a locker
if ($w == $l) {
// Initialise le compteur de tentatives
$attempt = 0;
// Tente d'encoder les données en JSON et de les sauvegarder jusqu'à 5 fois en cas d'échec
while ($attempt < 5) {
// Essaye d'écrire les données encodées dans le fichier de base de données
$write_result = file_put_contents($this->db, $encoded_data, LOCK_EX); // Les utilisateurs multiples obtiennent un verrou
// Vérifie si l'écriture a réussi
if ($write_result === $encoded_length) {
// Sort de la boucle si l'écriture a réussi
break; break;
} }
$try++;
// Incrémente le compteur de tentatives
$attempt++;
// Attente
sleep(1); sleep(1);
} }
if ($w !== $l) {
// Vérifie si l'écriture a échoué même après plusieurs tentatives exit('Erreur d\'écriture, les données n\'ont pas été sauvegardées');
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

@ -55,9 +55,9 @@ class layout extends common
* Formate le contenu de la page selon les gabarits * Formate le contenu de la page selon les gabarits
* @param Page par defaut * @param Page par defaut
*/ */
public function showMain() public function showSection()
{ {
echo '<main><section>'; echo '<section>';
// Récupérer la config de la page courante // Récupérer la config de la page courante
$blocks = is_null($this->getData(['page', $this->getUrl(0), 'block'])) ? '12' : $this->getData(['page', $this->getUrl(0), 'block']); $blocks = is_null($this->getData(['page', $this->getUrl(0), 'block'])) ? '12' : $this->getData(['page', $this->getUrl(0), 'block']);
$blocks = explode('-', $blocks); $blocks = explode('-', $blocks);
@ -88,19 +88,13 @@ class layout extends common
(sizeof($blocks) === 1 || (sizeof($blocks) === 1 ||
in_array($this->getUrl(1), $pattern)) in_array($this->getUrl(1), $pattern))
) { // Pleine page en mode configuration ) { // Pleine page en mode configuration
if ($this->getData(['page', $this->getUrl(0), 'navLeft']) === 'top' || $this->getData(['page', $this->getUrl(0), 'navRight']) === 'top') {
$this->showNavButtons('top');
}
$this->showContent(); $this->showContent();
if ($this->getData(['page', $this->getUrl(0), 'navLeft']) === 'bottom' || $this->getData(['page', $this->getUrl(0), 'navRight']) === 'bottom') {
$this->showNavButtons('bottom');
}
} else { } else {
echo '<div class="row siteContainer">'; echo '<div class="row siteContainer">';
/** /**
* Barre gauche * Barre gauche
*/ */
if ($blockleft !== '') { if ($blockleft !== "") {
echo '<div class="' . $blockleft . '" id="contentLeft"><aside>'; echo '<div class="' . $blockleft . '" id="contentLeft"><aside>';
// Détermine si le menu est présent // Détermine si le menu est présent
if ($this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barLeft']), 'displayMenu']) === 'none') { if ($this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barLeft']), 'displayMenu']) === 'none') {
@ -123,14 +117,12 @@ class layout extends common
* Contenu de page * Contenu de page
*/ */
echo '<div class="' . $content . '" id="contentSite">'; echo '<div class="' . $content . '" id="contentSite">';
$this->showNavButtons('top');
$this->showContent(); $this->showContent();
$this->showNavButtons('bottom');
echo '</div>'; echo '</div>';
/** /**
* Barre droite * Barre droite
*/ */
if ($blockright !== '') { if ($blockright !== "") {
echo '<div class="' . $blockright . '" id="contentRight"><aside>'; echo '<div class="' . $blockright . '" id="contentRight"><aside>';
// Détermine si le menu est présent // Détermine si le menu est présent
if ($this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barRight']), 'displayMenu']) === 'none') { if ($this->getData(['page', $this->getData(['page', $this->getUrl(0), 'barRight']), 'displayMenu']) === 'none') {
@ -151,7 +143,7 @@ class layout extends common
} }
echo '</div>'; echo '</div>';
} }
echo '</section></main>'; echo '</section>';
} }
/** /**
@ -288,8 +280,7 @@ class layout extends common
// Affichage de motorisé par // Affichage de motorisé par
$items .= '<span id="footerDisplayCopyright" '; $items .= '<span id="footerDisplayCopyright" ';
$items .= $this->getData(['theme', 'footer', 'displayCopyright']) === false ? 'class="displayNone"' : ''; $items .= $this->getData(['theme', 'footer', 'displayCopyright']) === false ? 'class="displayNone"' : '';
$label = empty($this->getData(['locale', 'poweredPageLabel'])) ? 'Motorisé par' : $this->getData(['locale', 'poweredPageLabel']); $items .= '>Motorisé&nbsp;par&nbsp;</span>';
$items .= '><wbr>&nbsp;' . $label . '&nbsp;</span>';
// Toujours afficher le nom du CMS // Toujours afficher le nom du CMS
$items .= '<span id="footerZwiiCMS">'; $items .= '<span id="footerZwiiCMS">';
$items .= '<a href="https://zwiicms.fr/" onclick="window.open(this.href);return false" >ZwiiCMS</a>'; $items .= '<a href="https://zwiicms.fr/" onclick="window.open(this.href);return false" >ZwiiCMS</a>';
@ -325,7 +316,7 @@ class layout extends common
$items .= '<span id="footerDisplayCookie"'; $items .= '<span id="footerDisplayCookie"';
$items .= ($this->getData(['config', 'cookieConsent']) === true && $this->getData(['theme', 'footer', 'displayCookie']) === true) ? '>' : ' class="displayNone" >'; $items .= ($this->getData(['config', 'cookieConsent']) === true && $this->getData(['theme', 'footer', 'displayCookie']) === true) ? '>' : ' class="displayNone" >';
$label = empty($this->getData(['locale', 'cookies', 'cookiesFooterText'])) ? 'Cookies' : $this->getData(['locale', 'cookies', 'cookiesFooterText']); $label = empty($this->getData(['locale', 'cookies', 'cookiesFooterText'])) ? 'Cookies' : $this->getData(['locale', 'cookies', 'cookiesFooterText']);
$items .= '<wbr>&nbsp;|&nbsp;<a href="javascript:void(0)" id="footerLinkCookie">' . $label . '</a>'; $items .= '<wbr>&nbsp;|&nbsp;<a href="javascript:void(0)" class="skiptranslate" id="footerLinkCookie">' . $label . '</a>';
$items .= '</span>'; $items .= '</span>';
// Affichage du lien de connexion // Affichage du lien de connexion
if ( if (
@ -345,14 +336,19 @@ class layout extends common
} }
// Affichage de la barre de membre simple // Affichage de la barre de membre simple
if ( if (
$this->getUser('group') >= self::GROUP_MEMBER && $this->getUser('group') < self::GROUP_ADMIN $this->getUser('group') === self::GROUP_MEMBER
&& $this->getData(['theme', 'footer', 'memberBar']) === true && $this->getData(['theme', 'footer', 'memberBar']) === true
) { ) {
$items .= '<span id="footerDisplayMemberAccount"'; $items .= '<span id="footerDisplayMemberAccount"';
$items .= $this->getData(['theme', 'footer', 'displaymemberAccount']) === false ? ' class="displayNone">' : '>'; $items .= $this->getData(['theme', 'footer', 'displaymemberAccount']) === false ? ' class="displayNone">' : '>';
$items .= '<wbr>&nbsp;|&nbsp;'; $items .= '<wbr>&nbsp;|&nbsp;' .
template::ico('user', [
'margin' => 'all',
'help' => 'Mon compte',
'href' => helper::baseUrl() . 'user/edit/' . $this->getUser('id') . '/' . $_SESSION['csrf']
]);
if ( if (
$this->getUser('permission', 'filemanager') === true $this->getData(['user', $this->getUser('id'), 'files']) === true
) { ) {
$items .= '<wbr>' . template::ico('folder', [ $items .= '<wbr>' . template::ico('folder', [
'href' => helper::baseUrl(false) . 'core/vendor/filemanager/dialog.php?type=0&akey=' . md5_file(self::DATA_DIR . 'core.json') . '&lang=' . $this->getData(['user', $this->getUser('id'), 'language']), 'href' => helper::baseUrl(false) . 'core/vendor/filemanager/dialog.php?type=0&akey=' . md5_file(self::DATA_DIR . 'core.json') . '&lang=' . $this->getData(['user', $this->getUser('id'), 'language']),
@ -361,15 +357,6 @@ class layout extends common
'help' => 'Fichiers du site' 'help' => 'Fichiers du site'
]); ]);
} }
if (
$this->getUser('permission', 'user', 'edit') === true
) {
$items .= '<wbr>' . template::ico('user', [
'margin' => 'all',
'help' => 'Mon compte',
'href' => helper::baseUrl() . 'user/edit/' . $this->getUser('id')
]);
}
$items .= '<wbr>' . template::ico('logout', [ $items .= '<wbr>' . template::ico('logout', [
'margin' => 'all', 'margin' => 'all',
'help' => 'Déconnecter', 'help' => 'Déconnecter',
@ -443,7 +430,7 @@ class layout extends common
$socialUrl = ''; $socialUrl = '';
} }
if ($socialId !== '') { if ($socialId !== '') {
$socials .= '<a href="' . $socialUrl . $socialId . '" onclick="window.open(this.href);return false" data-tippy-content="' . $title . '" alt="' . $title . '">' . template::ico(substr(str_replace('User', '', $socialName), 0, -2)) . '</a>'; $socials .= '<a href="' . $socialUrl . $socialId . '" onclick="window.open(this.href);return false" data-tippy-content="' . $title . '">' . template::ico(substr(str_replace('User', '', $socialName), 0, -2)) . '</a>';
} }
} }
if ($socials !== '') { if ($socials !== '') {
@ -506,12 +493,11 @@ 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->getData(['theme', 'menu', 'memberBar']) === true && $this->getData(['theme', 'menu', 'memberBar']) === true
) { ) {
if ( if (
$this->getUser('group') >= self::GROUP_MEMBER && $this->getData(['user', $this->getUser('id'), 'files']) === true
$this->getUser('permission', 'filemanager') === true
) { ) {
$itemsRight .= '<li>' . template::ico('folder', [ $itemsRight .= '<li>' . template::ico('folder', [
'href' => helper::baseUrl(false) . 'core/vendor/filemanager/dialog.php?type=0&akey=' . md5_file(self::DATA_DIR . 'core.json') . '&lang=' . $this->getData(['user', $this->getUser('id'), 'language']), 'href' => helper::baseUrl(false) . 'core/vendor/filemanager/dialog.php?type=0&akey=' . md5_file(self::DATA_DIR . 'core.json') . '&lang=' . $this->getData(['user', $this->getUser('id'), 'language']),
@ -519,15 +505,11 @@ class layout extends common
'help' => 'Fichiers du site' 'help' => 'Fichiers du site'
]) . '</li>'; ]) . '</li>';
} }
if ( $itemsRight .= '<li>' . template::ico('user', [
$this->getUser('permission', 'user', 'edit') === true 'help' => 'Mon compte',
) { 'margin' => 'right',
$itemsRight .= '<li>' . template::ico('user', [ 'href' => helper::baseUrl() . 'user/edit/' . $this->getUser('id') . '/' . $_SESSION['csrf']
'help' => 'Mon compte', ]) . '</li>';
'margin' => 'right',
'href' => helper::baseUrl() . 'user/edit/' . $this->getUser('id')
]) . '</li>';
}
$itemsRight .= '<li>' . $itemsRight .= '<li>' .
template::ico('logout', [ template::ico('logout', [
'help' => 'Déconnecter', 'help' => 'Déconnecter',
@ -537,7 +519,7 @@ class layout extends common
} }
// Retourne les items du menu // Retourne les items du menu
echo '<ul class="navMain" id="menuLeft">' . $itemsLeft . '</ul><ul class="navMain" id="menuRight">' . $itemsRight; echo '<ul class="navMain" id="menuLeft">' . $itemsLeft . '</ul><ul class="navMain" id="menuRight">' . $itemsRight;
// Drapeau les langues // Drapeau les langues des langues selon l'existance des dossiers
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)) {
$t[] = $this->showi18n($key); $t[] = $this->showi18n($key);
@ -583,7 +565,7 @@ class layout extends common
and $this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD') and $this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD')
) or ($this->getData(['page', $parentPageId, 'disable']) === true ) or ($this->getData(['page', $parentPageId, 'disable']) === true
and $this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD') and $this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
and $this->getUser('group') < self::GROUP_EDITOR and $this->getUser('group') < self::GROUP_MODERATOR
) )
) { ) {
$pageUrl = ($this->getData(['locale', 'homePageId']) === $this->getUrl(0)) ? helper::baseUrl(false) : helper::baseUrl() . $this->getUrl(0); $pageUrl = ($this->getData(['locale', 'homePageId']) === $this->getUrl(0)) ? helper::baseUrl(false) : helper::baseUrl() . $this->getUrl(0);
@ -649,7 +631,7 @@ class layout extends common
and $this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD') and $this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD')
) or ($this->getData(['page', $childKey, 'disable']) === true ) or ($this->getData(['page', $childKey, 'disable']) === true
and $this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD') and $this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
and $this->getUser('group') < self::GROUP_EDITOR and $this->getUser('group') < self::GROUP_MODERATOR
) )
) { ) {
$pageUrl = ($this->getData(['locale', 'homePageId']) === $this->getUrl(0)) ? helper::baseUrl(false) : helper::baseUrl() . $this->getUrl(0); $pageUrl = ($this->getData(['locale', 'homePageId']) === $this->getUrl(0)) ? helper::baseUrl(false) : helper::baseUrl() . $this->getUrl(0);
@ -832,33 +814,11 @@ class layout extends common
*/ */
public function showMetaImage() public function showMetaImage()
{ {
$imagePath = self::FILE_DIR . 'source/' . $this->getData(['config', 'seo', 'openGraphImage']); $items = '<meta property="og:image" content="' . helper::baseUrl(false) . self::FILE_DIR . 'source/screenshot.jpg" />';
if ( $items .= '<meta property="og:image:type" content="image/jpeg" />';
$this->getData(['config', 'seo', 'openGraphImage']) $items .= '<meta property="og:image:width" content="1200" />';
&& file_exists($imagePath) $items .= '<meta property="og:image:height" content="627" />';
) { echo $items;
$typeMime = exif_imagetype($imagePath);
switch ($typeMime) {
case IMAGETYPE_JPEG:
$typeMime = 'image/jpeg';
break;
case IMAGETYPE_PNG:
$typeMime = 'image/png';
break;
default:
// Type incorrect
return;
}
$imageSize = getimagesize($imagePath);
$wide = $imageSize[0];
$height = $imageSize[1];
//Sortie
$items = '<meta property="og:image" content="' . helper::baseUrl(false) . self::FILE_DIR . 'source/' . $this->getData(['config', 'seo', 'openGraphImage']) . '" />';
$items .= '<meta property="og:image:type" content="' . $typeMime . '" />';
$items .= '<meta property="og:image:width" content="' . $wide . '" />';
$items .= '<meta property="og:image:height" content="' . $height . '" />';
echo $items;
}
} }
/** /**
@ -906,30 +866,27 @@ class layout extends common
// Items de gauche // Items de gauche
$leftItems = ''; $leftItems = '';
// Sélecteur de langues // Sélecteur de langues
if ($this->getUser('group') >= self::GROUP_EDITOR) { if ($this->getUser('group') >= self::GROUP_MODERATOR) {
$c = 0;
$leftItem = ''; $leftItem = '';
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; $c++;
$leftItem .= '<option name="' . $key . '" value="' . $location . '" ' . ($key === self::$siteContent ? 'selected' : '') . '>' . $value . '</option>'; $location = helper::baseUrl() . 'translate/content/' . $key;
$leftItem .= '<option name="' . $key . '" value="' . $location . '" ' . ($key === self::$i18nContent ? 'selected' : '') . '>' . $value . '</option>';
} }
} }
$leftItems .= '<li><select id="barSelectLanguage" >'; if ($c > 1) {
$leftItems .= $leftItem; $leftItems .= '<li><select id="barSelectLanguage" >';
$leftItems .= '</select></li>'; $leftItems .= $leftItem;
$leftItems .= '</select></li>';
}
} }
if ($this->getUser('group') >= self::GROUP_ADMIN) {
$leftItems .= '<li>' . template::ico('flag', [
'help' => 'Langues',
'href' => helper::baseUrl() . 'language'
]) . '</li>';
}
// Liste des pages // Liste des pages
if ($this->getUser('group') >= self::GROUP_EDITOR) { if ($this->getUser('group') >= self::GROUP_MODERATOR) {
$leftItems .= '<li><select id="barSelectPage">'; $leftItems .= '<li><select id="barSelectPage">';
$leftItems .= '<option value="">' . helper::translate('Pages du site') . '</option>'; $leftItems .= '<option value="">Pages du site</option>';
$leftItems .= '<optgroup label="' . helper::translate('Pages orphelines') . '">'; $leftItems .= '<optgroup label="Pages orphelines">';
$orpheline = true; $orpheline = true;
$currentPageId = $this->getData(['page', $this->getUrl(0)]) ? $this->getUrl(0) : $this->getUrl(2); $currentPageId = $this->getData(['page', $this->getUrl(0)]) ? $this->getUrl(0) : $this->getUrl(2);
foreach ($this->getHierarchy(null, false) as $parentPageId => $childrenPageIds) { foreach ($this->getHierarchy(null, false) as $parentPageId => $childrenPageIds) {
@ -938,7 +895,7 @@ class layout extends common
$orpheline $orpheline
) { ) {
$orpheline = false; $orpheline = false;
$leftItems .= '<optgroup label="' . helper::translate('Pages dans le menu') . '">'; $leftItems .= '<optgroup label="Pages dans le menu">';
} }
// Exclure les barres // Exclure les barres
if ($this->getData(['page', $parentPageId, 'block']) !== 'bar') { if ($this->getData(['page', $parentPageId, 'block']) !== 'bar') {
@ -968,7 +925,7 @@ class layout extends common
} }
$leftItems .= '</optgroup' > $leftItems .= '</optgroup' >
// Afficher les barres // Afficher les barres
$leftItems .= '<optgroup label="' . helper::translate('Barres latérales') . '">'; $leftItems .= '<optgroup label="Barres latérales">';
foreach ($this->getHierarchy(null, false, true) as $parentPageId => $childrenPageIds) { foreach ($this->getHierarchy(null, false, true) as $parentPageId => $childrenPageIds) {
$leftItems .= '<option value="' . helper::baseUrl() . $parentPageId . '"' . ($parentPageId === $currentPageId ? ' selected' : false) . '>' . $this->getData(['page', $parentPageId, 'shortTitle']) . '</option>'; $leftItems .= '<option value="' . helper::baseUrl() . $parentPageId . '"' . ($parentPageId === $currentPageId ? ' selected' : false) . '>' . $this->getData(['page', $parentPageId, 'shortTitle']) . '</option>';
foreach ($childrenPageIds as $childKey) { foreach ($childrenPageIds as $childKey) {
@ -977,13 +934,10 @@ class layout extends common
} }
$leftItems .= '</optgroup>'; $leftItems .= '</optgroup>';
$leftItems .= '</select></li>'; $leftItems .= '</select></li>';
// Bouton Ajouter une page $leftItems .= '<li>' . template::ico('plus', [
if ($this->getUser('permission', 'page', 'add')) { 'href' => helper::baseUrl() . 'page/add',
$leftItems .= '<li>' . template::ico('plus', [ 'help' => 'Nouvelle page ou barre latérale'
'href' => helper::baseUrl() . 'page/add/' . self::$siteContent, ]) . '</li>';
'help' => 'Nouvelle page ou barre latérale'
]) . '</li>';
}
if ( if (
// Sur un module de page qui autorise le bouton de modification de la page // Sur un module de page qui autorise le bouton de modification de la page
$this->core->output['showBarEditButton'] $this->core->output['showBarEditButton']
@ -996,55 +950,33 @@ class layout extends common
// Sur une page d'accueil // Sur une page d'accueil
or $this->getUrl(0) === '' or $this->getUrl(0) === ''
) { ) {
// Bouton Editer une page $leftItems .= '<li>' . template::ico('pencil', [
if ($this->getUser('permission', 'page', 'edit')) { 'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(0),
$leftItems .= '<li>' . template::ico('pencil', [ 'help' => 'Éditer la page'
'href' => helper::baseUrl() . 'page/edit/' . $this->getUrl(0) . '/' . self::$siteContent, ]) . '</li>';
'help' => 'Éditer la page' if ($this->getData(['page', $this->getUrl(0), 'moduleId'])) {
]) . '</li>';
}
// Bouton Editer le module d'une page
if (
$this->getUser('permission', 'page', 'module')
&& $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',
'help' => 'Module de la page' 'help' => 'Module de la page'
]) . '</li>'; ]) . '</li>';
} }
// Bouton dupliquer une page $leftItems .= '<li>' . template::ico('clone', [
if ( 'href' => helper::baseUrl() . 'page/duplicate/' . $this->getUrl(0) . '&csrf=' . $_SESSION['csrf'],
$this->getUser('permission', 'page', 'duplicate') 'help' => 'Dupliquer la page'
) { ])
$leftItems .= '<li>' . template::ico('clone', [ . '</li>';
'href' => helper::baseUrl() . 'page/duplicate/' . $this->getUrl(0) . '/' . self::$siteContent,
'help' => 'Dupliquer la page' $leftItems .= '<li>' . template::ico('trash', [
]) 'href' => helper::baseUrl() . 'page/delete/' . $this->getUrl(0) . '&csrf=' . $_SESSION['csrf'],
. '</li>'; 'help' => 'Supprimer la page',
} 'id' => 'pageDelete'
// Bouton Effacer une page ])
if ( . '</li>';
$this->getUser('permission', 'page', 'delete')
) {
$leftItems .= '<li>' . template::ico('trash', [
'href' => helper::baseUrl() . 'page/delete/' . $this->getUrl(0) . '/' . self::$siteContent,
'help' => 'Supprimer la page',
'id' => 'pageDelete'
])
. '</li>';
}
} }
} }
// Items de droite // Items de droite
$rightItems = ''; $rightItems = '';
if ( if ($this->getUser('group') >= self::GROUP_MODERATOR) {
$this->getUser('group') >= self::GROUP_EDITOR
&& $this->getUser(
'permission',
'filemanager'
)
) {
$rightItems .= '<li>' . template::ico('folder', [ $rightItems .= '<li>' . template::ico('folder', [
'help' => 'Fichiers', 'help' => 'Fichiers',
'href' => helper::baseUrl(false) . 'core/vendor/filemanager/dialog.php?type=0&akey=' . md5_file(self::DATA_DIR . 'core.json') . '&lang=' . $this->getData(['user', $this->getUser('id'), 'language']), 'href' => helper::baseUrl(false) . 'core/vendor/filemanager/dialog.php?type=0&akey=' . md5_file(self::DATA_DIR . 'core.json') . '&lang=' . $this->getData(['user', $this->getUser('id'), 'language']),
@ -1060,6 +992,10 @@ class layout extends common
'help' => 'Modules', 'help' => 'Modules',
'href' => helper::baseUrl() . 'plugin' 'href' => helper::baseUrl() . 'plugin'
]) . '</li>'; ]) . '</li>';
$rightItems .= '<li>' . template::ico('flag', [
'help' => 'Multilingue',
'href' => helper::baseUrl() . 'translate'
]) . '</li>';
$rightItems .= '<li>' . template::ico('cog-alt', [ $rightItems .= '<li>' . template::ico('cog-alt', [
'help' => 'Configuration', 'help' => 'Configuration',
'href' => helper::baseUrl() . 'config' 'href' => helper::baseUrl() . 'config'
@ -1068,6 +1004,7 @@ class layout extends common
'help' => 'Utilisateurs', 'help' => 'Utilisateurs',
'href' => helper::baseUrl() . 'user' 'href' => helper::baseUrl() . 'user'
]) . '</li>'; ]) . '</li>';
// Mise à jour automatique // Mise à jour automatique
$today = mktime(0, 0, 0); $today = mktime(0, 0, 0);
$checkUpdate = $this->getData(['core', 'lastAutoUpdate']); $checkUpdate = $this->getData(['core', 'lastAutoUpdate']);
@ -1094,12 +1031,8 @@ class layout extends common
$rightItems .= '<li><a href="' . helper::baseUrl() . 'install/update" data-tippy-content="Mettre à jour Zwii ' . common::ZWII_VERSION . ' vers ' . helper::getOnlineVersion(common::ZWII_UPDATE_CHANNEL) . '">' . template::ico('update colorRed') . '</a></li>'; $rightItems .= '<li><a href="' . helper::baseUrl() . 'install/update" data-tippy-content="Mettre à jour Zwii ' . common::ZWII_VERSION . ' vers ' . helper::getOnlineVersion(common::ZWII_UPDATE_CHANNEL) . '">' . template::ico('update colorRed') . '</a></li>';
} }
} }
if ( if ($this->getUser('group') >= self::GROUP_MODERATOR) {
$this->getUser('group') >= self::GROUP_EDITOR $rightItems .= '<li><a href="' . helper::baseUrl() . 'user/edit/' . $this->getUser('id') . '/' . $_SESSION['csrf'] .
&& $this->getUser('permission', 'user', 'edit')
) {
$rightItems .= '<li><a href="' . helper::baseUrl() . 'user/edit/' . $this->getUser('id') .
'" data-tippy-content="' . helper::translate('Configurer mon compte') . '">' . '" data-tippy-content="' . helper::translate('Configurer mon compte') . '">' .
template::ico('user', ['margin' => 'right']) . '<span id="displayUsername">' . $this->getUser('firstname') . ' ' . $this->getUser('lastname') . template::ico('user', ['margin' => 'right']) . '<span id="displayUsername">' . $this->getUser('firstname') . ' ' . $this->getUser('lastname') .
'</span></a></li>'; '</span></a></li>';
@ -1167,8 +1100,8 @@ class layout extends common
public function showFonts() public function showFonts()
{ {
// 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 . 'fonts/fonts.html')) {
include_once(self::DATA_DIR . 'font/font.html'); include_once(self::DATA_DIR . 'fonts/fonts.html');
} }
} }
@ -1182,7 +1115,7 @@ class layout extends common
$vars .= 'var baseUrlQs = ' . json_encode(helper::baseUrl()) . ';'; $vars .= 'var baseUrlQs = ' . json_encode(helper::baseUrl()) . ';';
if ( if (
$this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD') $this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
and $this->getUser('group') >= self::GROUP_EDITOR and $this->getUser('group') >= self::GROUP_MODERATOR
) { ) {
$vars .= 'var privateKey = ' . json_encode(md5_file(self::DATA_DIR . 'core.json')) . ';'; $vars .= 'var privateKey = ' . json_encode(md5_file(self::DATA_DIR . 'core.json')) . ';';
} }
@ -1230,85 +1163,22 @@ class layout extends common
public function showi18n($lang) public function showi18n($lang)
{ {
if ( if (
(isset($_SESSION['ZWII_SITE_CONTENT']) is_dir(self::DATA_DIR . $lang)
and $_SESSION['ZWII_SITE_CONTENT'] === $lang
)
) { ) {
$select = ' class="i18nFlagSelected" '; if (
} else { (isset($_COOKIE['ZWII_CONTENT'])
$select = ' class="i18nFlag" '; and $_COOKIE['ZWII_CONTENT'] === $lang
} )
) {
$select = ' class="i18nFlagSelected" ';
} else {
$select = ' class="i18nFlag" ';
}
$items = '<li>'; $items = '<li>';
$items .= '<a href="' . helper::baseUrl() . 'language/content/' . $lang . '"><img ' . $select . ' alt="' . self::$languages[$lang] . '" src="' . helper::baseUrl(false) . 'core/vendor/i18n/png/' . $lang . '.png"/></a>'; $items .= '<a href="' . helper::baseUrl() . 'translate/content/' . $lang . '"><img ' . $select . ' alt="' . self::$languages[$lang] . '" src="' . helper::baseUrl(false) . 'core/vendor/i18n/png/' . $lang . '.png"/></a>';
$items .= '</li>'; $items .= '</li>';
}
return $items; return $items;
} }
// Affiche une icône de navigation
// @param $position string 'top' or 'bottom
public function showNavButtons($position)
{
// Boutons par défaut
$leftButton = 'left';
$rightButton = 'right-dir';
// Déterminer la hiérarchie des pages
$hierarchy = array();
foreach ($this->getHierarchy() as $parentKey => $parentValue) {
$hierarchy[] = $parentKey;
foreach ($parentValue as $childKey) {
$hierarchy[] = $childKey;
}
}
// Parcourir la hiérarchie et rechercher les éléments avant et après
$elementToFind = $this->getUrl(0);
// Trouver la clé de l'élément recherché
$key = array_search($elementToFind, $hierarchy);
$previousPage = null;
$nextPage = null;
if ($key !== false) {
// Trouver l'élément précédent
$previousKey = ($key > 0) ? $key - 1 : null;
$previousValue = ($previousKey !== null) ? $hierarchy[$previousKey] : null;
// Trouver l'élément suivant
$nextKey = ($key < count($hierarchy) - 1) ? $key + 1 : null;
$nextValue = ($nextKey !== null) ? $hierarchy[$nextKey] : null;
$previousPage = $previousValue;
$nextPage = $nextValue;
}
// Jeux d'icônes sinon celui par défaut
if ($this->getData(['page', $this->getUrl(0), 'navTemplate'])) {
$leftButton = self::$navIconTemplate[$this->getData(['page', $this->getUrl(0), 'navTemplate'])]['left'];
$rightButton = self::$navIconTemplate[$this->getData(['page', $this->getUrl(0), 'navTemplate'])]['right'];
}
$items = '<div class="navButton">';
$items .= '<div class="row">';
$items .= '<div class="col1">';
if (
$previousPage !== null && $this->getData(['page', $this->getUrl(0), 'navLeft']) === $position
) {
$items .= template::button('navPreviousButtonLeft', [
'href' => helper::baseUrl() . $previousPage,
'value' => template::ico($leftButton)
]);
}
$items .= '</div>';
$items .= '<div class="col1 offset10">';
if ($nextPage !== null && $this->getData(['page', $this->getUrl(0), 'navRight']) === $position) {
$items .= template::button('navNextButtonRight', [
'href' => helper::baseUrl() . $nextPage,
'value' => template::ico($rightButton)
]);
}
$items .= '</div></div></div>';
echo $items;
}
} }

View File

@ -1,5 +1,12 @@
<?php <?php
/**
* Chargement des classes filles
* router : aiguillage des pages
*/
require_once('core/class/layout.class.php');
class core extends common class core extends common
{ {
@ -11,16 +18,16 @@ class core extends common
parent::__construct(); parent::__construct();
// Token CSRF // Token CSRF
if (empty($_SESSION['csrf'])) { if (empty($_SESSION['csrf'])) {
$_SESSION['csrf'] = bin2hex(openssl_random_pseudo_bytes(128)); $_SESSION['csrf'] = bin2hex(openssl_random_pseudo_bytes(32));
} }
// 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 +50,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 +67,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']))) . '*/';
@ -90,9 +97,9 @@ class core extends common
*/ */
// Fonts disponibles // Fonts disponibles
$fontsAvailable['files'] = $this->getData(['font', 'files']); $fontsAvailable['files'] = $this->getData(['fonts', 'files']);
$fontsAvailable['imported'] = $this->getData(['font', 'imported']); $fontsAvailable['imported'] = $this->getData(['fonts', 'imported']);
$fontsAvailable['websafe'] = common::$fontsWebSafe; $fontsAvailable['websafe'] = self::$fontsWebSafe;
// Fontes installées // Fontes installées
$fonts = [ $fonts = [
@ -105,14 +112,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 fonts.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 . 'fonts')) {
mkdir(self::DATA_DIR . 'fonts');
}
file_put_contents(self::DATA_DIR . 'fonts/fonts.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 . 'fonts/' . $fontId)) {
// Chargement de la police
$css .= '@font-face {font-family:"' . $fontsAvailable['files'][$fontId]['font-family'] . '";';
$css .= 'src: url("' . helper::baseUrl(false) . self::DATA_DIR . 'fonts/' . $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';
} }
} }
} }
@ -263,7 +309,7 @@ class core extends common
$css .= 'footer span, #footerText > p {color:' . $this->getData(['theme', 'footer', 'textColor']) . ';font-family:' . $fonts[$this->getData(['theme', 'footer', 'font'])] . ';font-weight:' . $this->getData(['theme', 'footer', 'fontWeight']) . ';font-size:' . $this->getData(['theme', 'footer', 'fontSize']) . ';text-transform:' . $this->getData(['theme', 'footer', 'textTransform']) . '}'; $css .= 'footer span, #footerText > p {color:' . $this->getData(['theme', 'footer', 'textColor']) . ';font-family:' . $fonts[$this->getData(['theme', 'footer', 'font'])] . ';font-weight:' . $this->getData(['theme', 'footer', 'fontWeight']) . ';font-size:' . $this->getData(['theme', 'footer', 'fontSize']) . ';text-transform:' . $this->getData(['theme', 'footer', 'textTransform']) . '}';
$css .= 'footer {background-color:' . $colors['normal'] . ';color:' . $this->getData(['theme', 'footer', 'textColor']) . '}'; $css .= 'footer {background-color:' . $colors['normal'] . ';color:' . $this->getData(['theme', 'footer', 'textColor']) . '}';
//$css .= 'footer a{color:' . $this->getData(['theme', 'footer', 'textColor']) . '}'; $css .= 'footer a{color:' . $this->getData(['theme', 'footer', 'textColor']) . '}';
$css .= 'footer #footersite > div {margin:' . $this->getData(['theme', 'footer', 'height']) . ' 0}'; $css .= 'footer #footersite > div {margin:' . $this->getData(['theme', 'footer', 'height']) . ' 0}';
$css .= 'footer #footerbody > div {margin:' . $this->getData(['theme', 'footer', 'height']) . ' 0}'; $css .= 'footer #footerbody > div {margin:' . $this->getData(['theme', 'footer', 'height']) . ' 0}';
@ -272,8 +318,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 . 'fonts')) {
mkdir(self::DATA_DIR . 'fonts');
}
file_put_contents(self::DATA_DIR . 'fonts/fonts.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,16 +336,16 @@ 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
$css = '/*' . md5(json_encode($this->getData(['admin']))) . '*/'; $css = '/*' . md5(json_encode($this->getData(['admin']))) . '*/';
// Fonts disponibles // Fonts disponibles
$fontsAvailable['files'] = $this->getData(['font', 'files']); $fontsAvailable['files'] = $this->getData(['fonts', 'files']);
$fontsAvailable['imported'] = $this->getData(['font', 'imported']); $fontsAvailable['imported'] = $this->getData(['fonts', 'imported']);
$fontsAvailable['websafe'] = common::$fontsWebSafe; $fontsAvailable['websafe'] = self::$fontsWebSafe;
/** /**
* Import des polices de caractères * Import des polices de caractères
@ -307,12 +359,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 fonts.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 . 'fonts/fonts.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 . 'fonts/' . $fontId)) {
// Chargement de la police
$css .= '@font-face {font-family:"' . $fontsAvailable['files'][$fontId]['font-family'] . '";';
$css .= 'src: url("' . helper::baseUrl(false) . self::DATA_DIR . 'fonts/' . $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 +407,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 +431,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 +447,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)) {
@ -398,6 +462,7 @@ class core extends common
public function router() public function router()
{ {
//
$layout = new layout($this); $layout = new layout($this);
// Installation // Installation
@ -409,14 +474,19 @@ class core extends common
header('Location:' . helper::baseUrl() . 'install'); header('Location:' . helper::baseUrl() . 'install');
exit(); exit();
} }
// Journalisation // Journalisation
$this->saveLog(); $dataLog = helper::dateUTF8('%Y %m %d', time()) . ' - ' . helper::dateUTF8('%H:%M', time());
$dataLog .= helper::getIp($this->getData(['config', 'connect', 'anonymousIp'])) . ';';
$dataLog .= $this->getUser('id') ? $this->getUser('id') . ';' : 'anonyme' . ';';
$dataLog .= $this->getUrl();
$dataLog .= PHP_EOL;
if ($this->getData(['config', 'connect', 'log'])) {
file_put_contents(self::DATA_DIR . 'journal.log', $dataLog, FILE_APPEND);
}
// 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 +501,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
) )
) )
) { ) {
@ -443,16 +513,13 @@ class core extends common
header('Location:' . helper::baseUrl() . 'maintenance'); header('Location:' . helper::baseUrl() . 'maintenance');
exit(); 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
and ($this->getUser('group') * 10 + $this->getUser('profil')) >= ($this->getData(['page', $this->getUrl(0), 'group']) * 10 + $this->getData(['page', $this->getUrl(0), 'profil']))
) )
) { ) {
$access = true; $access = true;
@ -469,7 +536,7 @@ 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_MODERATOR
) )
) { ) {
$access = false; $access = false;
@ -486,23 +553,21 @@ class core extends common
*/ */
$accessInfo['userName'] = ''; $accessInfo['userName'] = '';
$accessInfo['pageId'] = ''; $accessInfo['pageId'] = '';
if ($this->getData(['user'])) { foreach ($this->getData(['user']) as $userId => $userIds) {
foreach ($this->getData(['user']) as $userId => $userIds) { if (!is_null($this->getData(['user', $userId, 'accessUrl']))) {
if (!is_null($this->getData(['user', $userId, 'accessUrl']))) { $t = explode('/', $this->getData(['user', $userId, 'accessUrl']));
$t = explode('/', $this->getData(['user', $userId, 'accessUrl'])); }
} if (
if ( $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, self::$accessList) &&
array_intersect($t, common::$concurrentAccess) && array_intersect($t, self::$accessExclude) !== false &&
//array_intersect($t, common::$accessExclude) !== false && time() < $this->getData(['user', $userId, 'accessTimer']) + self::ACCESS_TIMER
time() < $this->getData(['user', $userId, 'accessTimer']) + common::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']); $accessInfo['pageId'] = end($t);
$accessInfo['pageId'] = end($t);
}
} }
} }
// Accès concurrent stocke la page visitée // Accès concurrent stocke la page visitée
@ -534,10 +599,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']);
@ -555,7 +620,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']),
@ -581,7 +646,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,
@ -626,10 +691,9 @@ 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 $output['access'] === true and $output['access'] === true
@ -639,10 +703,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;
} }
} }
} }
@ -682,9 +746,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)
@ -697,7 +761,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;
@ -706,7 +770,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;
@ -775,7 +839,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 {
@ -787,34 +851,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'])])
@ -823,7 +865,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)'))
]); ]);
} }
} }
@ -846,43 +888,41 @@ 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(); // Supprime les espaces, les sauts de ligne, les tabulations et autres caractères inutiles
$content = preg_replace('/[\t ]+/u', ' ', ob_get_clean());
// Convertit la chaîne en UTF-8 pour conserver les caractères accentués // Convertit la chaîne en UTF-8 pour conserver les caractères accentués
$content = mb_convert_encoding($content, 'UTF-8', 'UTF-8'); $content = mb_convert_encoding($content, 'UTF-8', 'UTF-8');
// Supprime les espaces, les sauts de ligne, les tabulations et autres caractères inutiles
$content = preg_replace('/[\t ]+/u', ' ', $content);
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(); // Supprime les espaces, les sauts de ligne, les tabulations et autres caractères inutiles
$content = preg_replace('/[\t ]+/u', ' ', ob_get_clean());
// Convertit la chaîne en UTF-8 pour conserver les caractères accentués // Convertit la chaîne en UTF-8 pour conserver les caractères accentués
$content = mb_convert_encoding($content, 'UTF-8', 'UTF-8'); $content = mb_convert_encoding($content, 'UTF-8', 'UTF-8');
// Supprime les espaces, les sauts de ligne, les tabulations et autres caractères inutiles
$content = preg_replace('/[\t ]+/u', ' ', $content);
echo $content; echo $content;
break; break;
} }

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" /> en chiffres ?',
[ [
'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'],
@ -397,7 +397,7 @@ class template
$html = '<form id="' . $id . '" method="post">'; $html = '<form id="' . $id . '" method="post">';
// Stock le token CSRF // Stock le token CSRF
$html .= self::hidden('csrf', [ $html .= self::hidden('csrf', [
'value' => htmlentities($_SESSION['csrf'], ENT_QUOTES | ENT_HTML5, 'UTF-8') 'value' => $_SESSION['csrf']
]); ]);
// Retourne le html // Retourne le html
return $html; return $html;
@ -494,8 +494,8 @@ class template
$lang = $langId; $lang = $langId;
break; break;
case 'selected': case 'selected':
if (isset($_SESSION['ZWII_SITE_CONTENT'])) { if (isset($_COOKIE['ZWII_CONTENT'])) {
$lang = $_SESSION['ZWII_SITE_CONTENT']; $lang = $_COOKIE['ZWII_CONTENT'];
} else { } else {
$lang = 'fr_FR'; $lang = 'fr_FR';
} }
@ -686,16 +686,15 @@ class template
'label' => '', 'label' => '',
'name' => $nameId, 'name' => $nameId,
'selected' => '', 'selected' => '',
'font' => [], 'fonts' => []
'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']);
$attributes['help'] = helper::translate($attributes['help']); $attributes['help'] = helper::translate($attributes['help']);
// Stocker les fontes et remettre à zéro le tableau des fontes transmis pour éviter une erreur de sprintAttributes // Stocker les fontes et remettre à zéro le tableau des fontes transmis pour éviter une erreur de sprintAttributes
if (empty($attributes['font']) === false) { if (empty($attributes['fonts']) === false) {
$fonts = $attributes['font']; $fonts = $attributes['fonts'];
$attributes['font'] = []; $attributes['fonts'] = [];
} }
// Sauvegarde des données en cas d'erreur // Sauvegarde des données en cas d'erreur
if ($attributes['before'] and array_key_exists($attributes['id'], common::$inputBefore)) { if ($attributes['before'] and array_key_exists($attributes['id'], common::$inputBefore)) {
@ -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"));
}); });
@ -532,14 +532,14 @@ $(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 langCookie = getCookie('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("/");
// Change si différent, corrige le problème avec le thème et le rechargement de la langue. // Change si différent, corrige le problème avec le thème et le rechargement de la langue.
if ((currentUrl !== "?theme" || if ((currentUrl !== "?theme" ||
currentUrl !== "theme") && currentUrl !== "theme") &&
langSelected[6] !== langSession langSelected[6] !== langCookie
) { ) {
//$(location).attr("href", langUrl); //$(location).attr("href", langUrl);
var select = document.getElementById("barSelectLanguage"); var select = document.getElementById("barSelectLanguage");

View File

@ -8,12 +8,16 @@
* @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/
*/ */
/**
* Chargement des classes filles
* router : aiguillage des pages
*/
require_once('core/class/router.class.php');
class common class common
{ {
@ -27,8 +31,6 @@ class common
const GROUP_BANNED = -1; const GROUP_BANNED = -1;
const GROUP_VISITOR = 0; const GROUP_VISITOR = 0;
const GROUP_MEMBER = 1; const GROUP_MEMBER = 1;
const GROUP_EDITOR = 2;
// Groupe MODERATOR, compatibilité avec les anciens modules :
const GROUP_MODERATOR = 2; const GROUP_MODERATOR = 2;
const GROUP_ADMIN = 3; const GROUP_ADMIN = 3;
const SIGNATURE_ID = 1; const SIGNATURE_ID = 1;
@ -50,58 +52,43 @@ class common
// Contrôle d'édition temps maxi en secondes avant déconnexion 30 minutes // Contrôle d'édition temps maxi en secondes avant déconnexion 30 minutes
const ACCESS_TIMER = 1800; const ACCESS_TIMER = 1800;
// Numéro de version // Numéro de version et branche pour l'auto-update
const ZWII_VERSION = '13.3.02'; const ZWII_VERSION = '12.3.04';
const ZWII_DATAVERSION = 12301;
// 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/';
const ZWII_UPDATE_CHANNEL = 'v13'; const ZWII_UPDATE_CHANNEL = "v12";
// Valeurs possibles multiple de 10, 10 autorise 9 profils, 100 autorise 99 profils // URL langues de l'UI en ligne
const MAX_PROFILS = 10; const ZWII_UI_URL = 'https://forge.chapril.org/ZwiiCMS-Team/zwiicms-translations/raw/branch/master/';
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 = [
"config", 'config',
"dashboard", 'install',
"install", 'maintenance',
"language", 'page',
"maintenance", 'sitemap',
"page", 'theme',
"plugin", 'user',
"sitemap", 'translate',
"theme", 'plugin'
"user"
]; ];
public static $concurrentAccess = [ public static $accessList = [
"config", 'user',
"edit", 'theme',
"language", 'config',
"plugin", 'edit',
"theme", 'config',
"user" 'translate'
];
public static $accessExclude = [
'login',
'logout'
]; ];
/*
Cette variable est supprimée du test dans le routeur.
public static $accessExclude = [
'login',
'logout',
"maintenance",
];
*/
private $data = []; private $data = [];
private $hierarchy = [ private $hierarchy = [
'all' => [], 'all' => [],
@ -115,6 +102,7 @@ class common
public static $inputBefore = []; public static $inputBefore = [];
public static $inputNotices = []; public static $inputNotices = [];
public static $importNotices = []; public static $importNotices = [];
public static $captchaNotices = [];
public static $coreNotices = []; public static $coreNotices = [];
public $output = [ public $output = [
'access' => true, 'access' => true,
@ -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' => ''
@ -155,24 +143,24 @@ class common
self::GROUP_BANNED => 'Banni', self::GROUP_BANNED => 'Banni',
self::GROUP_VISITOR => 'Visiteur', self::GROUP_VISITOR => 'Visiteur',
self::GROUP_MEMBER => 'Membre', self::GROUP_MEMBER => 'Membre',
self::GROUP_EDITOR => 'Éditeur', self::GROUP_MODERATOR => 'Éditeur',
self::GROUP_ADMIN => 'Administrateur' self::GROUP_ADMIN => 'Administrateur'
]; ];
public static $groupEdits = [ public static $groupEdits = [
self::GROUP_BANNED => 'Banni', self::GROUP_BANNED => 'Banni',
self::GROUP_MEMBER => 'Membre', self::GROUP_MEMBER => 'Membre',
self::GROUP_EDITOR => 'Éditeur', self::GROUP_MODERATOR => 'Éditeur',
self::GROUP_ADMIN => 'Administrateur' self::GROUP_ADMIN => 'Administrateur'
]; ];
public static $groupNews = [ public static $groupNews = [
self::GROUP_MEMBER => 'Membre', self::GROUP_MEMBER => 'Membre',
self::GROUP_EDITOR => 'Éditeur', self::GROUP_MODERATOR => 'Éditeur',
self::GROUP_ADMIN => 'Administrateur' self::GROUP_ADMIN => 'Administrateur'
]; ];
public static $groupPublics = [ public static $groupPublics = [
self::GROUP_VISITOR => 'Visiteur', self::GROUP_VISITOR => 'Visiteur',
self::GROUP_MEMBER => 'Membre', self::GROUP_MEMBER => 'Membre',
self::GROUP_EDITOR => 'Éditeur', self::GROUP_MODERATOR => 'Éditeur',
self::GROUP_ADMIN => 'Administrateur' self::GROUP_ADMIN => 'Administrateur'
]; ];
@ -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' => 'български език',
@ -229,6 +217,8 @@ class common
private $url = ''; private $url = '';
// Données de site // Données de site
private $user = []; private $user = [];
// Drapeau de sauvegarde
private $saveFlag = false;
// Descripteur de données Entrées / Sorties // Descripteur de données Entrées / Sorties
// Liste ici tous les fichiers de données // Liste ici tous les fichiers de données
@ -237,14 +227,13 @@ class common
'blacklist' => '', 'blacklist' => '',
'config' => '', 'config' => '',
'core' => '', 'core' => '',
'font' => '', 'fonts' => '',
'module' => '', 'module' => '',
'locale' => '', 'locale' => '',
'page' => '', 'page' => '',
'theme' => '', 'theme' => '',
'user' => '', 'user' => '',
'language' => '', 'languages' => '',
'profil' => '',
]; ];
public static $fontsWebSafe = [ public static $fontsWebSafe = [
@ -310,21 +299,6 @@ class common
] ]
]; ];
// Boutons de navigation dans la page
public static $navIconTemplate = [
'open' => [
'left' => 'left-open',
'right' => 'right-open',
],
'dir' => [
'left' => 'left',
'right' => 'right-dir',
],
'big' => [
'left' => 'left-big',
'right' => 'right-big',
],
];
/** /**
* Constructeur commun * Constructeur commun
@ -341,69 +315,65 @@ class common
} }
// Déterminer la langue du contenu du site // Déterminer la langue du contenu du site
if (isset($_SESSION['ZWII_SITE_CONTENT'])) { if (isset($this->input['_COOKIE']['ZWII_CONTENT'])) {
// Déterminé par la session présente // Déterminé par le cookie
self::$siteContent = $_SESSION['ZWII_SITE_CONTENT']; self::$i18nContent = $this->input['_COOKIE']['ZWII_CONTENT'];
} else { \setlocale(LC_ALL, self::$i18nContent . '.UTF8');
// Détermine la langue par défaut
foreach (self::$languages as $key => $value) {
if (file_exists(self::DATA_DIR . $key . '/.default')) {
self::$siteContent = $key;
$_SESSION['ZWII_SITE_CONTENT'] = $key;
break;
}
}
} }
\setlocale(LC_ALL, self::$siteContent . '.UTF8');
// Instanciation de la classe des entrées / sorties // Instanciation de la classe des entrées / sorties
$this->jsonDB(self::$siteContent); // Récupère les descripteurs
foreach ($this->dataFiles as $keys => $value) {
// Constructeur JsonDB
$this->dataFiles[$keys] = new \Prowebcraft\JsonDb([
'name' => $keys . '.json',
'dir' => $this->dataPath($keys, self::$i18nContent),
'backup' => file_exists('site/data/.backup')
]);
}
// 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;
} }
} }
} }
// Récupère un utilisateur connecté // Langue de l'administration
if ($this->getData(['user']) !== []) {
// Langue sélectionnée dans le compte, la langue du cookie sinon celle du compte ouvert
self::$i18nUI = $this->getData(['user', $this->getUser('id'), 'language']) ? $this->getData(['user', $this->getUser('id'), 'language']) : $this->getInput('ZWII_UI');
// Validation de la langue
self::$i18nUI = (empty(self::$i18nUI) || is_null(self::$i18nUI))
&& !file_exists(self::I18N_DIR . self::$i18nUI . '.json')
? 'fr_FR'
: self::$i18nUI;
} else {
// Installation
self::$i18nUI = $this->getInput('ZWII_UI') ? $this->getInput('ZWII_UI') : 'fr_FR';
}
// Stocker le cookie de langue pour l'éditeur de texte
setcookie('ZWII_UI', self::$i18nUI, time() + 3600, helper::baseUrl(false, false), '', false, false);
// Utilisateur connecté
if ($this->user === []) { if ($this->user === []) {
$this->user = $this->getData(['user', $this->getInput('ZWII_USER_ID')]); $this->user = $this->getData(['user', $this->getInput('ZWII_USER_ID')]);
} }
// Langue de l'administration si le user est connecté
if ($this->getData(['user', $this->getUser('id'), 'language'])) {
// Langue sélectionnée dans le compte, la langue du cookie sinon celle du compte ouvert
self::$i18nUI = $this->getData(['user', $this->getUser('id'), 'language']);
// Validation de la langue
self::$i18nUI = isset(self::$i18nUI) && file_exists(self::I18N_DIR . self::$i18nUI . '.json')
? self::$i18nUI
: 'fr_FR';
} else {
if (isset($_SESSION['ZWII_UI'])) {
self::$i18nUI = $_SESSION['ZWII_UI'];
} elseif (isset($_COOKIE['ZWII_UI'])) {
self::$i18nUI = $_COOKIE['ZWII_UI'];
} else {
self::$i18nUI = 'fr_FR';
}
$_SESSION['ZWII_UI'] = self::$i18nUI;
}
// Stocker le cookie de langue pour l'éditeur de texte
setcookie('ZWII_UI', self::$i18nUI, time() + 3600, helper::baseUrl(false, false), '', false, false);
// Construit la liste des pages parents/enfants // Construit la liste des pages parents/enfants
if ($this->hierarchy['all'] === []) { if ($this->hierarchy['all'] === []) {
$this->buildHierarchy(); $this->buildHierarchy();
} }
// Construit l'url // Construit l'url
if ($this->url === '') { if ($this->url === '') {
if ($url = $_SERVER['QUERY_STRING']) { if ($url = $_SERVER['QUERY_STRING']) {
@ -432,6 +402,12 @@ class common
} }
} }
// Mise à jour des données core selon la version du jeu de données
if ($this->getData(['core', 'dataVersion']) < common::ZWII_DATAVERSION) {
include('core/include/update.inc.php');
}
// Données de proxy // Données de proxy
$proxy = $this->getData(['config', 'proxyType']) . $this->getData(['config', 'proxyUrl']) . ':' . $this->getData(['config', 'proxyPort']); $proxy = $this->getData(['config', 'proxyType']) . $this->getData(['config', 'proxyUrl']) . ':' . $this->getData(['config', 'proxyPort']);
if ( if (
@ -453,9 +429,6 @@ class common
stream_context_set_default($context); stream_context_set_default($context);
} }
// Mise à jour des données core
include('core/include/update.inc.php');
} }
@ -490,11 +463,11 @@ class common
} }
/** /**
* Check du token CSRF * Check du token CSRF (true = bo
*/ */
public function checkCSRF() public function checkCSRF()
{ {
return ((empty($_POST['csrf']) or hash_equals($_POST['csrf'], $_SESSION['csrf']) === false) === false); return ((empty($_POST['csrf']) or hash_equals($_SESSION['csrf'], $_POST['csrf']) === false) === false);
} }
/** /**
@ -560,6 +533,7 @@ class common
*/ */
public function getData($keys = []) public function getData($keys = [])
{ {
// Eviter une requete vide // Eviter une requete vide
if (count($keys) >= 1) { if (count($keys) >= 1) {
// descripteur de la base // descripteur de la base
@ -602,48 +576,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
@ -656,74 +592,73 @@ class common
return unlink(self::DATA_DIR . $lang . '/content/' . $this->getData(['page', $page, 'content'])); return unlink(self::DATA_DIR . $lang . '/content/' . $this->getData(['page', $page, 'content']));
} }
public function jsonDB($lang)
{
// Instanciation de la classe des entrées / sorties
// Récupère les descripteurs
foreach ($this->dataFiles as $keys => $value) {
// Constructeur JsonDB;
$this->dataFiles[$keys] = new \Prowebcraft\JsonDb([
'name' => $keys . '.json',
'dir' => $this->dataPath($keys, $lang),
'backup' => file_exists('site/data/.backup')
]);
}
}
/** /**
* Initialisation des données * Initialisation des données
* @param string $module : nom du module à générer * @param array $module : nom du module à générer
* @param string $lang la langue à créer
* @param bool $sampleSite créer un site exemple en FR
* choix valides : core config user theme page module * choix valides : core config user theme page module
*/ */
public function initData($module, $lang, $sampleSite = false) public function initData($module, $lang, $sampleSite = false)
{ {
// Créer la base de données des langues
if ($module === 'languages') {
copy('core/module/install/ressource/i18n/languages.json', self::DATA_DIR . 'languages.json');
$this->copyDir('core/module/install/ressource/i18n', self::I18N_DIR);
unlink(self::I18N_DIR . 'languages.json');
return;
}
// Tableau avec les données vierges // Tableau avec les données vierges
require_once('core/module/install/ressource/defaultdata.php'); require_once('core/module/install/ressource/defaultdata.php');
// Stockage dans un sous-dossier localisé
if (!file_exists(self::DATA_DIR . $lang)) { if (!file_exists(self::DATA_DIR . $lang)) {
mkdir(self::DATA_DIR . $lang, 0755); mkdir(self::DATA_DIR . $lang, 0755);
} }
$db = $this->dataFiles[$module];
// Localisation if ($sampleSite === true && $lang === 'fr_FR') {
if ( $db->set($module, init::$siteData[$module]);
$module === 'page' ||
$module === 'module' ||
$module === 'locale'
) {
// Création des sous-dossiers localisés
if (!file_exists(self::DATA_DIR . $lang)) {
mkdir(self::DATA_DIR . $lang, 0755);
}
if (!file_exists(self::DATA_DIR . $lang . '/content')) {
mkdir(self::DATA_DIR . $lang . '/content', 0755);
}
// Site en français avec site exemple
if ($lang == 'fr_FR' && $sampleSite === true) {
$this->setData([$module, init::$siteTemplate[$module]]);
// Création des pages
foreach (init::$siteContent as $key => $value) {
$this->setPage($key, $value, 'fr_FR');
}
// Version en langue étrangère ou fr_FR sans site de test
} else {
// En_EN par défaut si le contenu localisé n'est pas traduit
$langDefault = array_key_exists($lang, init::$defaultDataI18n) === true ? $lang : 'default';
// Charger les données de cette langue
$this->setData([$module, init::$defaultDataI18n[$langDefault][$module]]);
// Créer la page d'accueil, une seule page dans cette configuration
$pageId = init::$defaultDataI18n[$langDefault]['locale']['homePageId'];
$content = init::$defaultDataI18n[$langDefault]['html'];
$this->setPage($pageId, $content, $lang);
//file_put_contents(self::DATA_DIR . $lang . '/content/' . init::$defaultDataI18n[$langDefault]['page'][$pageId]['content'], $content);
}
} else { } else {
// Installation des données des autres modules cad theme profil font config, admin et core $db->set($module, init::$defaultData[$module]);
$this->setData([$module, init::$defaultData[$module]]);
} }
$db->save;
// Créer le jeu de pages du site de test
if ($module === 'page') {
$langFolder = $lang . '/content/';
// Dossier des pages
if (!is_dir(self::DATA_DIR . $langFolder)) {
mkdir(self::DATA_DIR . $langFolder, 0755);
}
// Site de test ou page simple
if ($lang === 'fr_FR') {
if ($sampleSite === true) {
foreach (init::$siteContent as $key => $value) {
// Creation du contenu de la page
if (!empty($this->getData(['page', $key, 'content']))) {
file_put_contents(self::DATA_DIR . $langFolder . $this->getData(['page', $key, 'content']), $value);
}
}
} else {
// Créer la page d'accueil
file_put_contents(self::DATA_DIR . $langFolder . 'accueil.html', '<p>Contenu de votre nouvelle page.</p>');
}
} else {
// En_EN si le contenu localisé n'est pas traduit
if (!isset(init::$defaultDataI18n[$lang])) {
$lang = 'en_EN';
}
// Messages localisés
$this->setData(['locale', init::$defaultDataI18n[$lang]['locale']]);
// Page dans une autre langue, page d'accueil
$this->setData(['page', init::$defaultDataI18n[$lang]['page']]);
// Créer la page d'accueil
$pageId = init::$defaultDataI18n[$lang]['locale']['homePageId'];
$content = init::$defaultDataI18n[$lang]['html'];
file_put_contents(self::DATA_DIR . $langFolder . init::$defaultDataI18n[$lang]['page'][$pageId]['content'], $content);
}
}
} }
@ -757,65 +692,57 @@ 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 )
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) {
) $this->hierarchy['visible'][$pageId] = [];
) { }
if ($pagePosition !== 0) { if ($this->getData(['page', $pageId, 'block']) === 'bar') {
$this->hierarchy['visible'][$pageId] = []; $this->hierarchy['bar'][$pageId] = [];
} }
if ($this->getData(['page', $pageId, 'block']) === 'bar') { $this->hierarchy['all'][$pageId] = [];
$this->hierarchy['bar'][$pageId] = []; }
} }
$this->hierarchy['all'][$pageId] = []; // Enfants
} foreach ($pages as $pageId => $pagePosition) {
} if (
// Enfants // Page parent
foreach ($pages as $pageId => $pagePosition) { $parentId = $this->getData(['page', $pageId, 'parentPageId'])
// Ignore les pages dont l'utilisateur n'a pas accès
if ( and (
// Page parent ($this->getData(['page', $pageId, 'group']) === self::GROUP_VISITOR
$parentId = $this->getData(['page', $pageId, 'parentPageId']) and $this->getData(['page', $parentId, 'group']) === self::GROUP_VISITOR
// Ignore les pages dont l'utilisateur n'a pas accès )
and ( or ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
( and $this->getUser('group') >= $this->getData(['page', $parentId, 'group'])
$this->getData(['page', $pageId, 'group']) === self::GROUP_VISITOR and $this->getUser('group') >= $this->getData(['page', $pageId, 'group'])
and )
$this->getData(['page', $parentId, 'group']) === self::GROUP_VISITOR )
) ) {
or ( if ($pagePosition !== 0) {
$this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD') $this->hierarchy['visible'][$parentId][] = $pageId;
and }
$this->getUser('group') * self::MAX_PROFILS + $this->getUser('profil')) >= ($this->getData(['page', $pageId, 'group']) * self::MAX_PROFILS + $this->getData(['page', $pageId, 'profil']) if ($this->getData(['page', $pageId, 'block']) === 'bar') {
$this->hierarchy['bar'][$pageId] = [];
) }
) $this->hierarchy['all'][$parentId][] = $pageId;
) { }
if ($pagePosition !== 0) { }
$this->hierarchy['visible'][$parentId][] = $pageId; }
}
if ($this->getData(['page', $pageId, 'block']) === 'bar') {
$this->hierarchy['bar'][$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 +761,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' => '&nbsp;»&nbsp;' . html_entity_decode($this->getData(['page', $childId, 'shortTitle']), ENT_QUOTES),
'value' => $rewrite . $childId 'value' => $rewrite . $childId
]; ];
} }
@ -842,18 +769,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
]; ];
@ -970,14 +897,12 @@ class common
* @param int $key Clé de la valeur * @param int $key Clé de la valeur
* @return string|null * @return string|null
*/ */
public function getUser($key, $perm1 = null, $perm2 = null) public function getUser($key)
{ {
if (is_array($this->user) === false) { if (is_array($this->user) === false) {
return false; return false;
} elseif ($key === 'id') { } elseif ($key === 'id') {
return $this->getInput('ZWII_USER_ID'); return $this->getInput('ZWII_USER_ID');
} elseif ($key === 'permission') {
return $this->getPermission($perm1, $perm2);
} elseif (array_key_exists($key, $this->user)) { } elseif (array_key_exists($key, $this->user)) {
return $this->user[$key]; return $this->user[$key];
} else { } else {
@ -985,49 +910,6 @@ class common
} }
} }
/**
* Retourne les permissions de l'utilisateur connecté
* @param int $key Clé de la valeur du groupe
* @return string|null
*/
public function getPermission($key1, $key2 = null)
{
// Administrateur, toutes les permissions
if ($this->getUser('group') === self::GROUP_ADMIN) {
return true;
} elseif ($this->getUser('group') <= self::GROUP_VISITOR) { // Groupe sans autorisation
return false;
} elseif (
// Groupe avec profil, consultation des autorisations sur deux clés
$key1
&& $key2
&& $this->user
&& $this->getData(['profil', $this->user['group'], $this->user['profil'], $key1])
&& array_key_exists($key2, $this->getData(['profil', $this->user['group'], $this->user['profil'], $key1]))
) {
return $this->getData(['profil', $this->user['group'], $this->user['profil'], $key1, $key2]);
// Groupe avec profil, consultation des autorisations sur une seule clé
} elseif (
$key1
&& $this->user
&& $this->getData(['profil', $this->user['group'], $this->user['profil']])
&& array_key_exists($key1, $this->getData(['profil', $this->user['group'], $this->user['profil']]))
) {
return $this->getData(['profil', $this->user['group'], $this->user['profil'], $key1]);
} else {
// Une permission non spécifiée dans le profil est autorisée selon la valeur de $actions
if (class_exists($key1)) {
$module = new $key1;
if (array_key_exists($key2, $module::$actions)) {
return $this->getUser('group') >= $module::$actions[$key2];
}
}
return false;
}
}
/** /**
* Check qu'une valeur est transmise par la méthode _POST * Check qu'une valeur est transmise par la méthode _POST
* @return bool * @return bool
@ -1070,8 +952,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 +959,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();
@ -1102,7 +982,7 @@ class common
$datetime = new DateTime(date('c')); $datetime = new DateTime(date('c'));
$datetime->format(DateTime::ATOM); // Updated ISO8601 $datetime->format(DateTime::ATOM); // Updated ISO8601
foreach ($this->getHierarchy() as $parentPageId => $childrenPageIds) { foreach ($this->getHierarchy(null, null, null) as $parentPageId => $childrenPageIds) {
// Exclure les barres et les pages non publiques et les pages masquées // Exclure les barres et les pages non publiques et les pages masquées
if ( if (
$this->getData(['page', $parentPageId, 'group']) !== 0 || $this->getData(['page', $parentPageId, 'group']) !== 0 ||
@ -1115,18 +995,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 +1016,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 +1032,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 +1046,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 +1056,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
@ -1216,9 +1089,6 @@ class common
case 'webp': case 'webp':
$source_image = imagecreatefromwebp($src); $source_image = imagecreatefromwebp($src);
break; break;
case 'avif':
$source_image = function_exists('imagecreatefromavif') ? imagecreatefromavif($src) : null;
break;
} }
// Image valide // Image valide
if ($source_image) { if ($source_image) {
@ -1239,9 +1109,7 @@ class common
case 'image/gif': case 'image/gif':
return (imagegif($virtual_image, $dest)); return (imagegif($virtual_image, $dest));
case 'webp': case 'webp':
return (imagewebp($virtual_image, $dest)); $source_image = imagecreatefromwebp($src);
case 'avif':
return (imageavif($virtual_image, $dest));
} }
} else { } else {
return (false); return (false);
@ -1254,8 +1122,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();
@ -1334,13 +1203,13 @@ class common
* Effacer un dossier non vide. * Effacer un dossier non vide.
* @param string URL du dossier à supprimer * @param string URL du dossier à supprimer
*/ */
public function deleteDir($path) public function removeDir($path)
{ {
foreach (new DirectoryIterator($path) as $item) { foreach (new DirectoryIterator($path) as $item) {
if ($item->isFile()) if ($item->isFile())
@unlink($item->getRealPath()); @unlink($item->getRealPath());
if (!$item->isDot() && $item->isDir()) if (!$item->isDot() && $item->isDir())
$this->deleteDir($item->getRealPath()); $this->removeDir($item->getRealPath());
} }
return (rmdir($path)); return (rmdir($path));
} }
@ -1436,40 +1305,4 @@ class common
} }
$zip->close(); $zip->close();
} }
/**
* Journalisation
*/
public function saveLog($message = '')
{
// Journalisation
$dataLog = helper::dateUTF8('%Y%m%d', time(), self::$i18nUI) . ';' . helper::dateUTF8('%H:%M', time(), self::$i18nUI). ';';
$dataLog .= helper::getIp($this->getData(['config', 'connect', 'anonymousIp'])) . ';';
$dataLog .= empty($this->getUser('id')) ? 'visitor;' : $this->getUser('id') . ';';
$dataLog .= $message ? $this->getUrl() . ';' . $message : $this->getUrl();
$dataLog .= PHP_EOL;
if ($this->getData(['config', 'connect', 'log'])) {
$this->secure_file_put_contents(self::DATA_DIR . 'journal.log', $dataLog, FILE_APPEND);
}
}
/**
* 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

@ -9,8 +9,8 @@ if(version_compare(PHP_VERSION, '7.2.0', '<') ) {
} }
if ( version_compare(PHP_VERSION, '8.3.999', '>') ) { if ( version_compare(PHP_VERSION, '8.2.999', '>') ) {
exit('PHP 8.3 pas encore supporté, installez PHP 7.n ou PHP 8.1.n - PHP 8.3 not yet supported, install PHP 7.n or PHP 8.1.n'); exit('PHP 8.2 pas encore supporté, installez PHP 7.n ou PHP 8.1.n - PHP 8.2 not yet supported, install PHP 7.n or PHP 8.1.n');
} }
/** /**
@ -34,11 +34,11 @@ $b = false;
foreach ($e as $k => $v) { foreach ($e as $k => $v) {
if (array_search($v,$m) === false) { if (array_search($v,$m) === false) {
$b = true; $b = true;
echo '<pre><p>Module PHP : ' . $v . ' manquant - Module PHP ' . $v . ' missing.</p></pre>'; echo '<pre><p>Module ' . $v . ' manquant - Module ' . $v . ' missing.</p></pre>';
} }
} }
if ($b) if ($b)
exit('<pre><p>ZwiiCMS ne peut pas démarrer ; activez les extensions requises dans PHP.ini- ZwiiCMS cannot start, enabled PHP missing extensions into PHP.ini</p></pre>'); exit('<pre><p>ZwiiCMS ne peut pas démarrer ; activez les extensions requises - ZwiiCMS cannot start, enabled missing extensions.</p></pre>');
/** /**
* Contrôle les htacess * Contrôle les htacess
*/ */
@ -48,9 +48,9 @@ $d = [
'site/data/', 'site/data/',
'site/backup/', 'site/backup/',
'site/tmp/', 'site/tmp/',
// 'site/i18n/', pas contrôler pour éviter les pbs de mise à jour 'site/i18n/'
]; ];
foreach ($d as $key) { foreach ($d as $key) {
if (file_exists($key . '.htaccess') === false) if (file_exists($key . '.htaccess') === false)
exit('<pre>ZwiiCMS ne peut pas démarrer, le fichier ' .$key . '.htaccess est manquant.<br />ZwiiCMS cannot start, file ' . $key . '.htaccess is missing.</pre>' ); exit('<pre>ZwiiCMS ne peut pas démarrer, le fichier ' .$key . '.htaccess est manquant.<br />ZwiiCMS cannot start, file ' . $key . '.htaccess is missing manquant.</pre>' );
} }

View File

@ -5,12 +5,10 @@
* */ * */
if (file_exists('site/data/core.json')) { if (file_exists('site/data/core.json')) {
$core = json_decode(file_get_contents('site/data/core.json'), true); $version = json_decode(file_get_contents('site/data/core.json'), true);
$version = $core['core']['dataVersion'];
// Avant version 12.0.00 // Avant version 12.0.00
if ( if ($version['core']['dataVersion'] < 12000) {
$version < 12000
) {
// Correspondance pour les dossiers de langue à convertir // Correspondance pour les dossiers de langue à convertir
$languages = [ $languages = [
'fr' => 'fr_FR', 'fr' => 'fr_FR',
@ -26,27 +24,7 @@ if (file_exists('site/data/core.json')) {
$end = rename('site/data/' . $key, 'site/data/' . $value); $end = rename('site/data/' . $key, 'site/data/' . $value);
} }
} }
sleep(1); sleep(1);
} }
}
// Renomme les bases de données
if (
$version < 12400
) {
// Renommage les fichiers de données au pluriel
$t = [
'site/data/languages.json' => 'site/data/language.json',
'site/data/fonts.json' => 'site/data/font.json'
];
foreach ($t as $k => $v) {
if (file_exists($k)) {
$d = file_get_contents($k);
$d = str_replace('"' . basename($k, '.json') . '"' , '"' . basename($v, '.json') . '"', $d);
file_put_contents($v, $d);
unlink($k);
}
}
}
}

View File

@ -3,11 +3,7 @@
/** /**
* Mises à jour suivant les versions de Zwii * Mises à jour suivant les versions de Zwii
*/ */
if ($this->getData(['core', 'dataVersion']) < 9227) {
// Pas d'installation depuis une version inférieur
if (
$this->getData(['core', 'dataVersion']) < 9227
) {
// Arrêt du script // Arrêt du script
exit('ZwiiCMS version 12 est incompatible avec la base de données installée. L\'installation d\'une version intermédiaire 10 ou 11 est nécessaire.'); exit('ZwiiCMS version 12 est incompatible avec la base de données installée. L\'installation d\'une version intermédiaire 10 ou 11 est nécessaire.');
} }
@ -18,15 +14,15 @@ if ($this->getData(['core', 'dataVersion']) < 10000) {
//---------------------------------------- //----------------------------------------
// Mettre à jour les données des galeries // Mettre à jour les données des galeries
$hierarchy = array(); $pageList = array();
foreach ($this->getHierarchy() as $parentKey => $parentValue) { foreach ($this->getHierarchy(null, null, null) as $parentKey => $parentValue) {
$hierarchy[] = $parentKey; $pageList[] = $parentKey;
foreach ($parentValue as $childKey) { foreach ($parentValue as $childKey) {
$hierarchy[] = $childKey; $pageList[] = $childKey;
} }
} }
// Mise à jour des données pour la galerie v2 // Mise à jour des données pour la galerie v2
foreach ($hierarchy as $parentKey => $parent) { foreach ($pageList as $parentKey => $parent) {
//La page a une galerie //La page a une galerie
if ($this->getData(['page', $parent, 'moduleId']) === 'gallery') { if ($this->getData(['page', $parent, 'moduleId']) === 'gallery') {
// Parcourir les dossiers de la galerie // Parcourir les dossiers de la galerie
@ -135,7 +131,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
@ -179,15 +175,15 @@ if ($this->getData(['core', 'dataVersion']) < 10300) {
$this->setData(['config', 'searchPageId', '']); $this->setData(['config', 'searchPageId', '']);
// Mettre à jour les données des galeries // Mettre à jour les données des galeries
$hierarchy = array(); foreach ($this->getHierarchy() as $parentKey => $parentValue) { $pageList = array(); foreach ($this->getHierarchy(null, null, null) as $parentKey => $parentValue) {
$hierarchy[] = $parentKey; $pageList[] = $parentKey;
foreach ($parentValue as $childKey) { foreach ($parentValue as $childKey) {
$hierarchy[] = $childKey; $pageList[] = $childKey;
} }
} }
// Mise à jour des données de thème de la galerie // Mise à jour des données de thème de la galerie
// Les données de thème sont communes au site // Les données de thème sont communes au site
foreach ($hierarchy as $parentKey => $parent) { foreach ($pageList as $parentKey => $parent) {
//La page a une galerie //La page a une galerie
if ($this->getData(['page', $parent, 'moduleId']) === 'gallery') { if ($this->getData(['page', $parent, 'moduleId']) === 'gallery') {
foreach ($this->getData(['module', $parent]) as $galleryKey => $galleryItem) { foreach ($this->getData(['module', $parent]) as $galleryKey => $galleryItem) {
@ -239,15 +235,15 @@ if ($this->getData(['core', 'dataVersion']) < 10304) {
// Version 10.3.06 // Version 10.3.06
if ($this->getData(['core', 'dataVersion']) < 10306) { if ($this->getData(['core', 'dataVersion']) < 10306) {
// Liste des pages // Liste des pages
$hierarchy = array(); $pageList = array();
foreach ($this->getHierarchy() as $parentKey => $parentValue) { foreach ($this->getHierarchy(null, null, null) as $parentKey => $parentValue) {
$hierarchy[] = $parentKey; $pageList[] = $parentKey;
foreach ($parentValue as $childKey) { foreach ($parentValue as $childKey) {
$hierarchy[] = $childKey; $pageList[] = $childKey;
} }
} }
// Mettre à jour les données des blogs les articles sont dans posts // Mettre à jour les données des blogs les articles sont dans posts
foreach ($hierarchy as $parentKey => $parent) { foreach ($pageList as $parentKey => $parent) {
//La page a un blog //La page a un blog
if ($this->getData(['page', $parent, 'moduleId']) === 'blog') { if ($this->getData(['page', $parent, 'moduleId']) === 'blog') {
if (is_array($this->getData(['module', $parent]))) { if (is_array($this->getData(['module', $parent]))) {
@ -262,7 +258,7 @@ if ($this->getData(['core', 'dataVersion']) < 10306) {
} }
} }
} }
foreach ($hierarchy as $parentKey => $parent) { foreach ($pageList as $parentKey => $parent) {
//La page a une news //La page a une news
if ($this->getData(['page', $parent, 'moduleId']) === 'news') { if ($this->getData(['page', $parent, 'moduleId']) === 'news') {
if (is_array($this->getData(['module', $parent]))) { if (is_array($this->getData(['module', $parent]))) {
@ -297,16 +293,16 @@ if ($this->getData(['core', 'dataVersion']) < 10400) {
// Ajouter les champs de blog v3 // Ajouter les champs de blog v3
// Liste des pages dans pageList // Liste des pages dans pageList
$hierarchy = array(); $pageList = array();
foreach ($this->getHierarchy() as $parentKey => $parentValue) { foreach ($this->getHierarchy(null, null, null) as $parentKey => $parentValue) {
$hierarchy[] = $parentKey; $pageList[] = $parentKey;
foreach ($parentValue as $childKey) { foreach ($parentValue as $childKey) {
$hierarchy[] = $childKey; $pageList[] = $childKey;
} }
} }
// Parcourir pageList et rechercher les modules de blog // Parcourir pageList et rechercher les modules de blog
foreach ($hierarchy as $parentKey => $parent) { foreach ($pageList as $parentKey => $parent) {
//La page est un blog //La page est un blog
if ($this->getData(['page', $parent, 'moduleId']) === 'blog') { if ($this->getData(['page', $parent, 'moduleId']) === 'blog') {
$articleIds = array_keys(helper::arrayColumn($this->getData(['module', $parent, 'posts']), 'publishedOn', 'SORT_DESC')); $articleIds = array_keys(helper::arrayColumn($this->getData(['module', $parent, 'posts']), 'publishedOn', 'SORT_DESC'));
@ -388,15 +384,15 @@ if ($this->getData(['core', 'dataVersion']) < 10600) {
// Mise à jour des données des modules autonomes // Mise à jour des données des modules autonomes
// Liste des pages dans pageList // Liste des pages dans pageList
$hierarchy = array(); $pageList = array();
foreach ($this->getHierarchy() as $parentKey => $parentValue) { foreach ($this->getHierarchy(null, null, null) as $parentKey => $parentValue) {
$hierarchy[] = $parentKey; $pageList[] = $parentKey;
foreach ($parentValue as $childKey) { foreach ($parentValue as $childKey) {
$hierarchy[] = $childKey; $pageList[] = $childKey;
} }
} }
// Parcourir pageList et rechercher les modules au CSS autonomes // Parcourir pageList et rechercher les modules au CSS autonomes
foreach ($hierarchy as $parentKey => $parent) { foreach ($pageList as $parentKey => $parent) {
if ( if (
$this->getData(['page', $parent, 'moduleId']) === 'search' $this->getData(['page', $parent, 'moduleId']) === 'search'
|| $this->getData(['page', $parent, 'moduleId']) === 'gallery' || $this->getData(['page', $parent, 'moduleId']) === 'gallery'
@ -446,20 +442,20 @@ if ($this->getData(['core', 'dataVersion']) < 11000) {
// Externaliser les contenus des pages // Externaliser les contenus des pages
// Liste des pages dans pageList // Liste des pages dans pageList
$hierarchy = array(); $pageList = 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(null, null, null) as $parentKey => $parentValue) {
$hierarchy[] = $parentKey; $pageList[] = $parentKey;
foreach ($parentValue as $childKey) { foreach ($parentValue as $childKey) {
$hierarchy[] = $childKey; $pageList[] = $childKey;
} }
} }
foreach ($hierarchy as $parentKey => $parent) { foreach ($pageList 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']);
} }
@ -509,13 +505,13 @@ if ($this->getData(['core', 'dataVersion']) < 11200) {
$this->setData(['config', 'connect', 'captchaType', 'alpha']); $this->setData(['config', 'connect', 'captchaType', 'alpha']);
// Ajout de la variable shortTitle basée sur Title // Ajout de la variable shortTitle basée sur Title
foreach ($this->getHierarchy() as $parentKey => $parentValue) { foreach ($this->getHierarchy(null, null, null) as $parentKey => $parentValue) {
$hierarchy[] = $parentKey; $pageList[] = $parentKey;
foreach ($parentValue as $childKey) { foreach ($parentValue as $childKey) {
$hierarchy[] = $childKey; $pageList[] = $childKey;
} }
} }
foreach ($hierarchy as $parentKey => $parent) { foreach ($pageList as $parentKey => $parent) {
$this->setData(['page', $parent, 'shortTitle', $this->getData(['page', $parent, 'title'])]); $this->setData(['page', $parent, 'shortTitle', $this->getData(['page', $parent, 'title'])]);
} }
@ -573,8 +569,8 @@ if ($this->getData(['core', 'dataVersion']) < 11203) {
$c3 = 0; $c3 = 0;
$success = false; $success = false;
// Boucler sur les pages // Boucler sur les pages
foreach ($this->getHierarchy() as $parentId => $childIds) { foreach ($this->getHierarchy(null, null, null) 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 +578,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;
} }
} }
@ -669,13 +665,13 @@ if ($this->getData(['core', 'dataVersion']) < 11300) {
if ($this->getData(['core', 'dataVersion']) < 11303) { if ($this->getData(['core', 'dataVersion']) < 11303) {
// Ajout de la variable shortTitle basée sur Title // Ajout de la variable shortTitle basée sur Title
foreach ($this->getHierarchy() as $parentKey => $parentValue) { foreach ($this->getHierarchy(null, null, null) as $parentKey => $parentValue) {
$hierarchy[] = $parentKey; $pageList[] = $parentKey;
foreach ($parentValue as $childKey) { foreach ($parentValue as $childKey) {
$hierarchy[] = $childKey; $pageList[] = $childKey;
} }
} }
foreach ($hierarchy as $parentKey => $parent) { foreach ($pageList as $parentKey => $parent) {
$this->setData(['page', $parent, 'extraPosition', false]); $this->setData(['page', $parent, 'extraPosition', false]);
} }
@ -688,10 +684,10 @@ if ($this->getData(['core', 'dataVersion']) < 11303) {
if ($this->getData(['core', 'dataVersion']) < 11306) { if ($this->getData(['core', 'dataVersion']) < 11306) {
// Supprime les fontes déclarées en double par la version précédentes // Supprime les fontes déclarées en double par la version précédentes
$files = $this->getData(['font', 'files']); $files = $this->getData(['fonts', 'files']);
foreach ($files as $fontId => $fontFile) { foreach ($files as $fontId => $fontFile) {
if (!is_null($this->getData(['font', 'imported', $fontId]))) { if (!is_null($this->getData(['fonts', 'imported', $fontId]))) {
$this->deleteData(['font', 'imported', $fontId]); $this->deleteData(['fonts', 'imported', $fontId]);
} }
} }
// Mise à jour // Mise à jour
@ -703,7 +699,7 @@ if ($this->getData(['core', 'dataVersion']) < 11400) {
// Effacer le dossier // Effacer le dossier
if (is_dir('core/module/addon')) { if (is_dir('core/module/addon')) {
$this->deleteDir('core/module/addon'); $this->removeDir('core/module/addon');
} }
@ -801,9 +797,7 @@ if ($this->getData(['core', 'dataVersion']) < 11400) {
]; ];
// Conversion des fontes locales // Conversion des fontes locales
$files = $this->getData(['fonts', 'files']);
$files = $this->getData(['font', 'files']);
if (is_array($files)) { if (is_array($files)) {
foreach ($files as $fontId => $fontName) { foreach ($files as $fontId => $fontName) {
if ( if (
@ -811,7 +805,7 @@ if ($this->getData(['core', 'dataVersion']) < 11400) {
&& file_exists(self::DATA_DIR . 'fonts/' . $fontName) && file_exists(self::DATA_DIR . 'fonts/' . $fontName)
) { ) {
$this->setData([ $this->setData([
'font', 'fonts',
'files', 'files',
$fontId, $fontId,
[ [
@ -825,12 +819,12 @@ if ($this->getData(['core', 'dataVersion']) < 11400) {
} }
// Consersion des fontes importées // Consersion des fontes importées
$imported = $this->getData(['font', 'imported']); $imported = $this->getData(['fonts', 'imported']);
if (is_array($imported)) { if (is_array($imported)) {
foreach ($imported as $fontId => $fontUrl) { foreach ($imported as $fontId => $fontUrl) {
if (gettype($fontUrl) === 'string') { if (gettype($fontUrl) === 'string') {
$this->setData([ $this->setData([
'font', 'fonts',
'imported', 'imported',
$fontId, $fontId,
[ [
@ -845,7 +839,7 @@ if ($this->getData(['core', 'dataVersion']) < 11400) {
// Importation des fontes exemples // Importation des fontes exemples
$template = $fonts; $template = $fonts;
foreach ($template as $fontId => $fontValue) { foreach ($template as $fontId => $fontValue) {
$this->setData(['font', 'imported', $fontId, $fontValue]); $this->setData(['fonts', 'imported', $fontId, $fontValue]);
} }
// Redirection des pages d'administration vers la bannière de connexion // Redirection des pages d'administration vers la bannière de connexion
@ -903,10 +897,10 @@ if ($this->getData(['core', 'dataVersion']) < 12000) {
// Supprimer les fichier associés // Supprimer les fichier associés
if (is_dir('core/module/translate/ressource')) { if (is_dir('core/module/translate/ressource')) {
$this->deleteDir('core/module/translate/ressource'); $this->removeDir('core/module/translate/ressource');
} }
if (is_dir('core/vendor/i18n/css')) { if (is_dir('core/vendor/i18n/css')) {
$this->deleteDir('core/vendor/i18n/css'); $this->removeDir('core/vendor/i18n/css');
} }
if (file_exists('core/vendor/i18n/inc.json')) { if (file_exists('core/vendor/i18n/inc.json')) {
unlink('core/vendor/i18n/inc.json'); unlink('core/vendor/i18n/inc.json');
@ -941,7 +935,7 @@ if ($this->getData(['core', 'dataVersion']) < 12301) {
// Nettoyage de flatPickr // Nettoyage de flatPickr
if (is_dir('core/vendor/flatpickr')) { if (is_dir('core/vendor/flatpickr')) {
$this->deleteDir('core/vendor/flatpickr'); $this->removeDir('core/vendor/flatpickr');
} }
// email reply // email reply
@ -950,169 +944,4 @@ if ($this->getData(['core', 'dataVersion']) < 12301) {
// Mise à jour // Mise à jour
$this->setData(['core', 'dataVersion', 12301]); $this->setData(['core', 'dataVersion', 12301]);
}
// Version 12.3.08
if ($this->getData(['core', 'dataVersion']) < 12308) {
// Langue par défaut
$l = [
'fr_FR' => 'Français',
'en_EN' => 'English',
'es' => 'Español',
];
foreach ($l as $key => $value) {
if (is_dir(self::DATA_DIR . $key)) {
touch(self::DATA_DIR . $key . '/.default');
break;
}
}
// Mise à jour
$this->setData(['core', 'dataVersion', 12308]);
}
// Version 12.3.09
if ($this->getData(['core', 'dataVersion']) < 12309) {
// Mettre à jour les locales
foreach (self::$languages as $key => $value) {
// tableau des langues installées
if (is_dir(self::DATA_DIR . $key)) {
$d = json_decode(file_get_contents(self::DATA_DIR . $key . '/locale.json'), true);
$d = array_merge($d['locale'], ['poweredPageLabel' => 'Motorisé par']);
$t['locale'] = $d;
$this->secure_file_put_contents(self::DATA_DIR . $key . '/locale.json', $t);
}
}
// Mise à jour
$this->setData(['core', 'dataVersion', 12309]);
}
// Version 13.0.00
if ($this->getData(['core', 'dataVersion']) < 13000) {
// Nettoyage du dossier de langue d'installation'
if (file_exists('core/vendor/tinymce/langs/langs.zip'))
unlink('core/vendor/tinymce/langs/langs.zip');
if (file_exists('core/module/install/ressource/i18n/de.json'))
unlink('core/module/install/ressource/i18n/de.json');
if (file_exists('core/module/install/ressource/i18n/it.json'))
unlink('core/module/install/ressource/i18n/it.json');
if (file_exists('core/module/install/ressource/i18n/pt_PT.json'))
unlink('core/module/install/ressource/i18n/pt_PT.json');
if (file_exists('core/module/install/ressource/i18n/gr_GR.json'))
unlink('core/module/install/ressource/i18n/gr_GR.json');
// Création du dossier partage pour les nouveaux droits
if (!is_dir(self::FILE_DIR . 'source/partage')) {
mkdir(self::FILE_DIR . 'source/partage');
}
// Efface le dossier translate
if (is_dir('core/module/translate')) {
$this->deleteDir('core/module/translate');
}
// Renomme le fichier et le dossier des fontes
if (file_exists(self::DATA_DIR . 'fonts/fonts.html')) {
rename(self::DATA_DIR . 'fonts/fonts.html', self::DATA_DIR . 'fonts/font.html');
}
if (is_dir(self::DATA_DIR . 'fonts')) {
rename(self::DATA_DIR . 'fonts', self::DATA_DIR . 'font');
}
// Ajouter le prénom comme pseudo et le pseudo comme signature
foreach ($this->getData(['user']) as $userId => $userIds) {
switch ($this->getData(['user', $userId, 'group'])) {
case '1':
case '2':
$this->setData(['user', $userId, 'profil', 1]);
break;
default:
$this->setData(['user', $userId, 'profil', 0]);
break;
}
}
// Récupérer la liste de toutes les pages dans toutes langues
$hierarchy = array();
$languages = array();
// Tableau des langues non installées
foreach (self::$languages as $key => $value) {
if (is_dir(self::DATA_DIR . $key))
$languages[] = $key;
foreach ($this->getHierarchy() as $parentKey => $parentValue) {
$hierarchy[] = $parentKey;
foreach ($parentValue as $childKey) {
$hierarchy[] = $childKey;
}
}
}
// Mise à jour des pages, le profil est mis à 0 pour les groupes sans profil et 1 pour es groupes avec profil
$currentlanguage = self::$siteContent;
foreach ($languages as $langId) {
foreach ($hierarchy as $parentKey => $parent) {
switch ($this->getData(['page', $parent, 'group'])) {
case 1:
case 2:
$this->setData(['page', $parent, 'profil', 1]);
break;
default:
$this->setData(['page', $parent, 'profil', 0]);
break;
}
}
}
$_SESSION['ZWII_SITE_CONTENT'] = $currentlanguage;
// Supprime la clé OpenOgraph
$this->deleteData(['config', 'seo', 'keyApi']);
// Mise à jour
$this->setData(['core', 'dataVersion', 13000]);
}
// Version 13.0.05
if ($this->getData(['core', 'dataVersion']) < 13005) {
if (is_dir('core/module/plugin/view/dataImport')) {
$this->deleteDir('core/module/plugin/view/dataImport');
}
if (file_exists('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
$this->setData(['core', 'dataVersion', 13005]);
}
// Version 13.1.01
if ($this->getData(['core', 'dataVersion']) < 13101) {
// Supprime le choix du thème à l'installation
if (is_dir('core/module/install/ressource/themes')) {
$this->deleteDir('core/module/install/ressource/themes') ;
}
// Mise à jour
$this->setData(['core', 'dataVersion', 13101]);
} }

View File

@ -6,7 +6,7 @@
* @author Rémi Jean <remi.jean@outlook.com> * @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/
*/ */
@ -18,14 +18,6 @@
/* Site */ /* Site */
#site { #site {
max-width: 600px !important; max-width: 600px !important;
border-radius: 5px !important;
}
#site > section:not(.message),
input[type='password'], input[type='text']
{
background-color: rgba(255, 255, 255, 1) !important;
color: rgba(33, 34, 35, 1) !important;
} }
section { section {

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,29 +161,24 @@
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 -->
<?php $layout->showMain(); ?> <?php $layout->showSection(); ?>
<!-- footer --> <!-- footer -->
<?php $layout->showFooter(); ?> <?php $layout->showFooter(); ?>
<!-- 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/
*/ */
@ -34,119 +34,119 @@ class config extends common
]; ];
public static $timezones = [ public static $timezones = [
'Pacific/Midway' => '(GMT-11:00) Midway Island', 'Pacific/Midway' => '(GMT-11:00) Midway Island',
'US/Samoa' => '(GMT-11:00) Samoa', 'US/Samoa' => '(GMT-11:00) Samoa',
'US/Hawaii' => '(GMT-10:00) Hawaii', 'US/Hawaii' => '(GMT-10:00) Hawaii',
'US/Alaska' => '(GMT-09:00) Alaska', 'US/Alaska' => '(GMT-09:00) Alaska',
'US/Pacific' => '(GMT-08:00) Pacific Time (US &amp; Canada)', 'US/Pacific' => '(GMT-08:00) Pacific Time (US &amp; Canada)',
'America/Tijuana' => '(GMT-08:00) Tijuana', 'America/Tijuana' => '(GMT-08:00) Tijuana',
'US/Arizona' => '(GMT-07:00) Arizona', 'US/Arizona' => '(GMT-07:00) Arizona',
'US/Mountain' => '(GMT-07:00) Mountain Time (US &amp; Canada)', 'US/Mountain' => '(GMT-07:00) Mountain Time (US &amp; Canada)',
'America/Chihuahua' => '(GMT-07:00) Chihuahua', 'America/Chihuahua' => '(GMT-07:00) Chihuahua',
'America/Mazatlan' => '(GMT-07:00) Mazatlan', 'America/Mazatlan' => '(GMT-07:00) Mazatlan',
'America/Mexico_City' => '(GMT-06:00) Mexico City', 'America/Mexico_City' => '(GMT-06:00) Mexico City',
'America/Monterrey' => '(GMT-06:00) Monterrey', 'America/Monterrey' => '(GMT-06:00) Monterrey',
'Canada/Saskatchewan' => '(GMT-06:00) Saskatchewan', 'Canada/Saskatchewan' => '(GMT-06:00) Saskatchewan',
'US/Central' => '(GMT-06:00) Central Time (US &amp; Canada)', 'US/Central' => '(GMT-06:00) Central Time (US &amp; Canada)',
'US/Eastern' => '(GMT-05:00) Eastern Time (US &amp; Canada)', 'US/Eastern' => '(GMT-05:00) Eastern Time (US &amp; Canada)',
'US/East-Indiana' => '(GMT-05:00) Indiana (East)', 'US/East-Indiana' => '(GMT-05:00) Indiana (East)',
'America/Bogota' => '(GMT-05:00) Bogota', 'America/Bogota' => '(GMT-05:00) Bogota',
'America/Lima' => '(GMT-05:00) Lima', 'America/Lima' => '(GMT-05:00) Lima',
'America/Caracas' => '(GMT-04:30) Caracas', 'America/Caracas' => '(GMT-04:30) Caracas',
'Canada/Atlantic' => '(GMT-04:00) Atlantic Time (Canada)', 'Canada/Atlantic' => '(GMT-04:00) Atlantic Time (Canada)',
'America/La_Paz' => '(GMT-04:00) La Paz', 'America/La_Paz' => '(GMT-04:00) La Paz',
'America/Santiago' => '(GMT-04:00) Santiago', 'America/Santiago' => '(GMT-04:00) Santiago',
'Canada/Newfoundland' => '(GMT-03:30) Newfoundland', 'Canada/Newfoundland' => '(GMT-03:30) Newfoundland',
'America/Buenos_Aires' => '(GMT-03:00) Buenos Aires', 'America/Buenos_Aires' => '(GMT-03:00) Buenos Aires',
'Greenland' => '(GMT-03:00) Greenland', 'Greenland' => '(GMT-03:00) Greenland',
'Atlantic/Stanley' => '(GMT-02:00) Stanley', 'Atlantic/Stanley' => '(GMT-02:00) Stanley',
'Atlantic/Azores' => '(GMT-01:00) Azores', 'Atlantic/Azores' => '(GMT-01:00) Azores',
'Atlantic/Cape_Verde' => '(GMT-01:00) Cape Verde Is.', 'Atlantic/Cape_Verde' => '(GMT-01:00) Cape Verde Is.',
'Africa/Casablanca' => '(GMT) Casablanca', 'Africa/Casablanca' => '(GMT) Casablanca',
'Europe/Dublin' => '(GMT) Dublin', 'Europe/Dublin' => '(GMT) Dublin',
'Europe/Lisbon' => '(GMT) Lisbon', 'Europe/Lisbon' => '(GMT) Lisbon',
'Europe/London' => '(GMT) London', 'Europe/London' => '(GMT) London',
'Africa/Monrovia' => '(GMT) Monrovia', 'Africa/Monrovia' => '(GMT) Monrovia',
'Europe/Amsterdam' => '(GMT+01:00) Amsterdam', 'Europe/Amsterdam' => '(GMT+01:00) Amsterdam',
'Europe/Belgrade' => '(GMT+01:00) Belgrade', 'Europe/Belgrade' => '(GMT+01:00) Belgrade',
'Europe/Berlin' => '(GMT+01:00) Berlin', 'Europe/Berlin' => '(GMT+01:00) Berlin',
'Europe/Bratislava' => '(GMT+01:00) Bratislava', 'Europe/Bratislava' => '(GMT+01:00) Bratislava',
'Europe/Brussels' => '(GMT+01:00) Brussels', 'Europe/Brussels' => '(GMT+01:00) Brussels',
'Europe/Budapest' => '(GMT+01:00) Budapest', 'Europe/Budapest' => '(GMT+01:00) Budapest',
'Europe/Copenhagen' => '(GMT+01:00) Copenhagen', 'Europe/Copenhagen' => '(GMT+01:00) Copenhagen',
'Europe/Ljubljana' => '(GMT+01:00) Ljubljana', 'Europe/Ljubljana' => '(GMT+01:00) Ljubljana',
'Europe/Madrid' => '(GMT+01:00) Madrid', 'Europe/Madrid' => '(GMT+01:00) Madrid',
'Europe/Paris' => '(GMT+01:00) Paris', 'Europe/Paris' => '(GMT+01:00) Paris',
'Europe/Prague' => '(GMT+01:00) Prague', 'Europe/Prague' => '(GMT+01:00) Prague',
'Europe/Rome' => '(GMT+01:00) Rome', 'Europe/Rome' => '(GMT+01:00) Rome',
'Europe/Sarajevo' => '(GMT+01:00) Sarajevo', 'Europe/Sarajevo' => '(GMT+01:00) Sarajevo',
'Europe/Skopje' => '(GMT+01:00) Skopje', 'Europe/Skopje' => '(GMT+01:00) Skopje',
'Europe/Stockholm' => '(GMT+01:00) Stockholm', 'Europe/Stockholm' => '(GMT+01:00) Stockholm',
'Europe/Vienna' => '(GMT+01:00) Vienna', 'Europe/Vienna' => '(GMT+01:00) Vienna',
'Europe/Warsaw' => '(GMT+01:00) Warsaw', 'Europe/Warsaw' => '(GMT+01:00) Warsaw',
'Europe/Zagreb' => '(GMT+01:00) Zagreb', 'Europe/Zagreb' => '(GMT+01:00) Zagreb',
'Europe/Athens' => '(GMT+02:00) Athens', 'Europe/Athens' => '(GMT+02:00) Athens',
'Europe/Bucharest' => '(GMT+02:00) Bucharest', 'Europe/Bucharest' => '(GMT+02:00) Bucharest',
'Africa/Cairo' => '(GMT+02:00) Cairo', 'Africa/Cairo' => '(GMT+02:00) Cairo',
'Africa/Harare' => '(GMT+02:00) Harare', 'Africa/Harare' => '(GMT+02:00) Harare',
'Europe/Helsinki' => '(GMT+02:00) Helsinki', 'Europe/Helsinki' => '(GMT+02:00) Helsinki',
'Europe/Istanbul' => '(GMT+02:00) Istanbul', 'Europe/Istanbul' => '(GMT+02:00) Istanbul',
'Asia/Jerusalem' => '(GMT+02:00) Jerusalem', 'Asia/Jerusalem' => '(GMT+02:00) Jerusalem',
'Europe/Kiev' => '(GMT+02:00) Kyiv', 'Europe/Kiev' => '(GMT+02:00) Kyiv',
'Europe/Minsk' => '(GMT+02:00) Minsk', 'Europe/Minsk' => '(GMT+02:00) Minsk',
'Europe/Riga' => '(GMT+02:00) Riga', 'Europe/Riga' => '(GMT+02:00) Riga',
'Europe/Sofia' => '(GMT+02:00) Sofia', 'Europe/Sofia' => '(GMT+02:00) Sofia',
'Europe/Tallinn' => '(GMT+02:00) Tallinn', 'Europe/Tallinn' => '(GMT+02:00) Tallinn',
'Europe/Vilnius' => '(GMT+02:00) Vilnius', 'Europe/Vilnius' => '(GMT+02:00) Vilnius',
'Asia/Baghdad' => '(GMT+03:00) Baghdad', 'Asia/Baghdad' => '(GMT+03:00) Baghdad',
'Asia/Kuwait' => '(GMT+03:00) Kuwait', 'Asia/Kuwait' => '(GMT+03:00) Kuwait',
'Europe/Moscow' => '(GMT+03:00) Moscow', 'Europe/Moscow' => '(GMT+03:00) Moscow',
'Africa/Nairobi' => '(GMT+03:00) Nairobi', 'Africa/Nairobi' => '(GMT+03:00) Nairobi',
'Asia/Riyadh' => '(GMT+03:00) Riyadh', 'Asia/Riyadh' => '(GMT+03:00) Riyadh',
'Europe/Volgograd' => '(GMT+03:00) Volgograd', 'Europe/Volgograd' => '(GMT+03:00) Volgograd',
'Asia/Tehran' => '(GMT+03:30) Tehran', 'Asia/Tehran' => '(GMT+03:30) Tehran',
'Asia/Baku' => '(GMT+04:00) Baku', 'Asia/Baku' => '(GMT+04:00) Baku',
'Asia/Muscat' => '(GMT+04:00) Muscat', 'Asia/Muscat' => '(GMT+04:00) Muscat',
'Asia/Tbilisi' => '(GMT+04:00) Tbilisi', 'Asia/Tbilisi' => '(GMT+04:00) Tbilisi',
'Asia/Yerevan' => '(GMT+04:00) Yerevan', 'Asia/Yerevan' => '(GMT+04:00) Yerevan',
'Asia/Kabul' => '(GMT+04:30) Kabul', 'Asia/Kabul' => '(GMT+04:30) Kabul',
'Asia/Yekaterinburg' => '(GMT+05:00) Ekaterinburg', 'Asia/Yekaterinburg' => '(GMT+05:00) Ekaterinburg',
'Asia/Karachi' => '(GMT+05:00) Karachi', 'Asia/Karachi' => '(GMT+05:00) Karachi',
'Asia/Tashkent' => '(GMT+05:00) Tashkent', 'Asia/Tashkent' => '(GMT+05:00) Tashkent',
'Asia/Kolkata' => '(GMT+05:30) Kolkata', 'Asia/Kolkata' => '(GMT+05:30) Kolkata',
'Asia/Kathmandu' => '(GMT+05:45) Kathmandu', 'Asia/Kathmandu' => '(GMT+05:45) Kathmandu',
'Asia/Almaty' => '(GMT+06:00) Almaty', 'Asia/Almaty' => '(GMT+06:00) Almaty',
'Asia/Dhaka' => '(GMT+06:00) Dhaka', 'Asia/Dhaka' => '(GMT+06:00) Dhaka',
'Asia/Novosibirsk' => '(GMT+06:00) Novosibirsk', 'Asia/Novosibirsk' => '(GMT+06:00) Novosibirsk',
'Asia/Bangkok' => '(GMT+07:00) Bangkok', 'Asia/Bangkok' => '(GMT+07:00) Bangkok',
'Asia/Jakarta' => '(GMT+07:00) Jakarta', 'Asia/Jakarta' => '(GMT+07:00) Jakarta',
'Asia/Krasnoyarsk' => '(GMT+07:00) Krasnoyarsk', 'Asia/Krasnoyarsk' => '(GMT+07:00) Krasnoyarsk',
'Asia/Chongqing' => '(GMT+08:00) Chongqing', 'Asia/Chongqing' => '(GMT+08:00) Chongqing',
'Asia/Hong_Kong' => '(GMT+08:00) Hong Kong', 'Asia/Hong_Kong' => '(GMT+08:00) Hong Kong',
'Asia/Irkutsk' => '(GMT+08:00) Irkutsk', 'Asia/Irkutsk' => '(GMT+08:00) Irkutsk',
'Asia/Kuala_Lumpur' => '(GMT+08:00) Kuala Lumpur', 'Asia/Kuala_Lumpur' => '(GMT+08:00) Kuala Lumpur',
'Australia/Perth' => '(GMT+08:00) Perth', 'Australia/Perth' => '(GMT+08:00) Perth',
'Asia/Singapore' => '(GMT+08:00) Singapore', 'Asia/Singapore' => '(GMT+08:00) Singapore',
'Asia/Taipei' => '(GMT+08:00) Taipei', 'Asia/Taipei' => '(GMT+08:00) Taipei',
'Asia/Ulaanbaatar' => '(GMT+08:00) Ulaan Bataar', 'Asia/Ulaanbaatar' => '(GMT+08:00) Ulaan Bataar',
'Asia/Urumqi' => '(GMT+08:00) Urumqi', 'Asia/Urumqi' => '(GMT+08:00) Urumqi',
'Asia/Seoul' => '(GMT+09:00) Seoul', 'Asia/Seoul' => '(GMT+09:00) Seoul',
'Asia/Tokyo' => '(GMT+09:00) Tokyo', 'Asia/Tokyo' => '(GMT+09:00) Tokyo',
'Asia/Yakutsk' => '(GMT+09:00) Yakutsk', 'Asia/Yakutsk' => '(GMT+09:00) Yakutsk',
'Australia/Adelaide' => '(GMT+09:30) Adelaide', 'Australia/Adelaide' => '(GMT+09:30) Adelaide',
'Australia/Darwin' => '(GMT+09:30) Darwin', 'Australia/Darwin' => '(GMT+09:30) Darwin',
'Australia/Brisbane' => '(GMT+10:00) Brisbane', 'Australia/Brisbane' => '(GMT+10:00) Brisbane',
'Australia/Canberra' => '(GMT+10:00) Canberra', 'Australia/Canberra' => '(GMT+10:00) Canberra',
'Pacific/Guam' => '(GMT+10:00) Guam', 'Pacific/Guam' => '(GMT+10:00) Guam',
'Australia/Hobart' => '(GMT+10:00) Hobart', 'Australia/Hobart' => '(GMT+10:00) Hobart',
'Australia/Melbourne' => '(GMT+10:00) Melbourne', 'Australia/Melbourne' => '(GMT+10:00) Melbourne',
'Pacific/Port_Moresby' => '(GMT+10:00) Port Moresby', 'Pacific/Port_Moresby' => '(GMT+10:00) Port Moresby',
'Australia/Sydney' => '(GMT+10:00) Sydney', 'Australia/Sydney' => '(GMT+10:00) Sydney',
'Asia/Vladivostok' => '(GMT+10:00) Vladivostok', 'Asia/Vladivostok' => '(GMT+10:00) Vladivostok',
'Asia/Magadan' => '(GMT+11:00) Magadan', 'Asia/Magadan' => '(GMT+11:00) Magadan',
'Pacific/Auckland' => '(GMT+12:00) Auckland', 'Pacific/Auckland' => '(GMT+12:00) Auckland',
'Pacific/Fiji' => '(GMT+12:00) Fiji', 'Pacific/Fiji' => '(GMT+12:00) Fiji',
'Asia/Kamchatka' => '(GMT+12:00) Kamchatka' 'Asia/Kamchatka' => '(GMT+12:00) Kamchatka'
]; ];
// Type de proxy // Type de proxy
public static $proxyType = [ public static $proxyType = [
@ -187,7 +187,7 @@ class config extends common
]; ];
public static $captchaTypes = [ public static $captchaTypes = [
'num' => 'Chiffres', 'num' => 'Chiffres',
'alpha' => 'Lettres' 'alpha' => 'Lettres'
]; ];
public static $updateDelay = [ public static $updateDelay = [
86400 => '1', 86400 => '1',
@ -204,8 +204,6 @@ class config extends common
public static $onlineVersion = ''; public static $onlineVersion = '';
public static $updateButtonText = 'Réinstaller'; public static $updateButtonText = 'Réinstaller';
public static $imageOpenGraph = [];
/** /**
* Génére les fichiers pour les crawlers * Génére les fichiers pour les crawlers
* Sitemap compressé et non compressé * Sitemap compressé et non compressé
@ -213,26 +211,16 @@ class config extends common
*/ */
public function siteMap() public function siteMap()
{ {
// La page n'existe pas
if (
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true
) {
// Valeurs en sortie
$this->addOutput([
'access' => false
]);
} else {
// Mettre à jour le site map
$successSitemap = $this->updateSitemap();
// Valeurs en sortie // Mettre à jour le site map
$this->addOutput([ $successSitemap = $this->updateSitemap();
'redirect' => helper::baseUrl() . 'config',
'notification' => $successSitemap ? helper::translate('La carte du site a été mise à jour') : helper::translate('Echec de l\'écriture, vérifiez les permissions'),
'state' => $successSitemap
]);
}
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'config',
'notification' => $successSitemap ? helper::translate('La carte du site a été mise à jour') : helper::translate('Echec de l\'écriture, vérifiez les permissions'),
'state' => $successSitemap
]);
} }
@ -242,10 +230,7 @@ class config extends common
public function backup() public function backup()
{ {
// Soumission du formulaire // Soumission du formulaire
if ( if ($this->isPost()) {
$this->getUser('permission', __CLASS__, __FUNCTION__) === true &&
$this->isPost()
) {
// Creation du ZIP // Creation du ZIP
$filter = $this->getInput('configBackupOption', helper::FILTER_BOOLEAN) === true ? ['backup', 'tmp'] : ['backup', 'tmp', 'file']; $filter = $this->getInput('configBackupOption', helper::FILTER_BOOLEAN) === true ? ['backup', 'tmp'] : ['backup', 'tmp', 'file'];
$fileName = helper::autoBackup(self::TEMP_DIR, $filter); $fileName = helper::autoBackup(self::TEMP_DIR, $filter);
@ -301,8 +286,10 @@ class config extends common
} }
} }
// Traitement des données reçues valides. // Traitement des données reçues valides.
if (!empty($token) && $data !== false) { if (!empty($token) && $data !== false) {
$data = json_decode($data, true); $data = json_decode($data, true);
$img = $data['screenshot']; $img = $data['screenshot'];
// Effacer l'image et la miniature png // Effacer l'image et la miniature png
@ -315,9 +302,9 @@ class config extends common
$success = copy($img, self::FILE_DIR . 'source/screenshot.jpg'); $success = copy($img, self::FILE_DIR . 'source/screenshot.jpg');
} }
$notification = empty($token) $notification = empty($token)
? 'La clé de l\'API ne peut pas être vide' ? 'La clé de l\'API ne peut pas être vide'
: ($success === false ? 'Service en ligne inaccessible' : 'Capture d\'écran générée avec succès'); : ($success === false ? 'Service en ligne inaccessible' : 'Capture d\'écran générée avec succès');
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
@ -333,10 +320,7 @@ class config extends common
public function restore() public function restore()
{ {
// Soumission du formulaire // Soumission du formulaire
if ( if ($this->isPost()) {
$this->getUser('permission', __CLASS__, __FUNCTION__) === true &&
$this->isPost()
) {
$success = false; $success = false;
@ -365,7 +349,12 @@ class config extends common
'state' => false 'state' => false
]); ]);
} }
// Lire le contenu de l'archive dans le tableau files
/*
for ($i = 0; $i < $zip->numFiles; $i++) {
$stat = $zip->statIndex($i);
$files[] = (basename($stat['name']));
}*/
// Extraction de l'archive dans un dossier temporaire // Extraction de l'archive dans un dossier temporaire
$tmpDir = uniqid(8); $tmpDir = uniqid(8);
$success = $zip->extractTo(self::TEMP_DIR . $tmpDir); $success = $zip->extractTo(self::TEMP_DIR . $tmpDir);
@ -373,7 +362,7 @@ class config extends common
$data = json_decode(file_get_contents(self::TEMP_DIR . $tmpDir . '/data/core.json'), true); $data = json_decode(file_get_contents(self::TEMP_DIR . $tmpDir . '/data/core.json'), true);
$dataVersion = $data['core']['dataVersion']; $dataVersion = $data['core']['dataVersion'];
// Version non prises en charge <9 ou erreur d'extraction // Version non prises en charge <9 ou erreur d'extraction
if (intval(substr($dataVersion, 0, 1)) <= 9 or !$success) { if (intval(substr($dataVersion, 0, 1)) <= 9 or !$success) {
// Valeurs en sortie erreur // Valeurs en sortie erreur
$this->addOutput([ $this->addOutput([
'title' => helper::translate('Restaurer'), 'title' => helper::translate('Restaurer'),
@ -393,7 +382,7 @@ class config extends common
// Copie dans le dossier /site/data // Copie dans le dossier /site/data
$success = $this->copyDir(self::TEMP_DIR . $tmpDir, 'site/'); $success = $this->copyDir(self::TEMP_DIR . $tmpDir, 'site/');
$this->deleteDir(self::TEMP_DIR . $tmpDir); $this->removeDir(self::TEMP_DIR . $tmpDir);
// Restaurer les users originaux d'une v10 si option cochée // Restaurer les users originaux d'une v10 si option cochée
if ( if (
@ -404,8 +393,8 @@ class config extends common
} }
// Message de notification // Message de notification
$notification = $success === true ? 'Restauration effectuée avec succès' : 'Erreur inconnue'; $notification = $success === true ? 'Restauration effectuée avec succès' : 'Erreur inconnue';
$redirect = $this->getInput('configRestoreImportUser', helper::FILTER_BOOLEAN) === true ? helper::baseUrl() . 'config/restore' : helper::baseUrl() . 'user/login/'; $redirect = $this->getInput('configRestoreImportUser', helper::FILTER_BOOLEAN) === true ? helper::baseUrl() . 'config/restore' : helper::baseUrl() . 'user/login/';
// Valeurs en sortie erreur // Valeurs en sortie erreur
$this->addOutput([ $this->addOutput([
'redirect' => $redirect, 'redirect' => $redirect,
@ -428,10 +417,7 @@ class config extends common
public function index() public function index()
{ {
// Soumission du formulaire // Soumission du formulaire
if ( if ($this->isPost()) {
$this->getUser('permission', __CLASS__, __FUNCTION__) === true &&
$this->isPost()
) {
// Basculement en mise à jour auto, remise à 0 du compteur // Basculement en mise à jour auto, remise à 0 du compteur
if ( if (
@ -469,7 +455,7 @@ class config extends common
'redditId' => $this->getInput('socialRedditId'), 'redditId' => $this->getInput('socialRedditId'),
'twitchId' => $this->getInput('socialTwitchId'), 'twitchId' => $this->getInput('socialTwitchId'),
'vimeoId' => $this->getInput('socialVimeoId'), 'vimeoId' => $this->getInput('socialVimeoId'),
'steamId' => $this->getInput('socialSteamId'), 'steamId' =>$this->getInput('socialSteamId'),
], ],
'smtp' => [ 'smtp' => [
'enable' => $this->getInput('smtpEnable', helper::FILTER_BOOLEAN), 'enable' => $this->getInput('smtpEnable', helper::FILTER_BOOLEAN),
@ -478,12 +464,12 @@ class config extends common
'auth' => $this->getInput('smtpAuth', helper::FILTER_BOOLEAN), 'auth' => $this->getInput('smtpAuth', helper::FILTER_BOOLEAN),
'secure' => $this->getInput('smtpSecure', helper::FILTER_STRING_SHORT), 'secure' => $this->getInput('smtpSecure', helper::FILTER_STRING_SHORT),
'username' => $this->getInput('smtpUsername', helper::FILTER_STRING_SHORT), 'username' => $this->getInput('smtpUsername', helper::FILTER_STRING_SHORT),
'password' => helper::encrypt($this->getInput('smtpPassword', helper::FILTER_STRING_SHORT), $this->getInput('smtpHost', helper::FILTER_STRING_SHORT)), 'password' => helper::encrypt($this->getInput('smtpPassword', helper::FILTER_STRING_SHORT),$this->getInput('smtpHost', helper::FILTER_STRING_SHORT)),
'from' => $this->getInput('smtpFrom', helper::FILTER_MAIL, true), 'from' => $this->getInput('smtpFrom', helper::FILTER_MAIL, true),
], ],
'seo' => [ 'seo' => [
'robots' => $this->getInput('seoRobots', helper::FILTER_BOOLEAN), 'robots' => $this->getInput('seoRobots', helper::FILTER_BOOLEAN),
'openGraphImage' => $this->getInput('seoOpenGraphImage', helper::FILTER_STRING_SHORT), 'keyApi' => $this->getInput('seoKeyApi', helper::FILTER_STRING_SHORT),
], ],
'connect' => [ 'connect' => [
'attempt' => $this->getInput('connectAttempt', helper::FILTER_INT), 'attempt' => $this->getInput('connectAttempt', helper::FILTER_INT),
@ -508,8 +494,7 @@ class config extends common
unlink($filename); unlink($filename);
} }
} }
if (file_exists('site/data/.backup')) if (file_exists('site/data/.backup')) unlink('site/data/.backup');
unlink('site/data/.backup');
} else { } else {
touch('site/data/.backup'); touch('site/data/.backup');
} }
@ -523,8 +508,8 @@ 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 = PHP_EOL . $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 .
"\tRewriteBase " . helper::baseUrl(false, false) . PHP_EOL . "\tRewriteBase " . helper::baseUrl(false, false) . PHP_EOL .
@ -534,7 +519,7 @@ class config 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);
$this->secure_file_put_contents( file_put_contents(
'.htaccess', '.htaccess',
$fileContent $fileContent
); );
@ -550,7 +535,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,58 +570,14 @@ 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');
} }
// Sélecteur de délais, compléter avec la traduction en jours // Sélecteur de délais, compléter avec la traduction en jours
foreach (self::$updateDelay as $key => $value) { foreach(self::$updateDelay as $key => $value) {
self::$updateDelay[$key] = $key === 86400 ? $value . ' ' . helper::translate('jour') : $value . ' ' . helper::translate('jours'); self::$updateDelay[$key] = $key === 86400 ? $value . ' ' . helper::translate('jour') : $value . ' ' . helper::translate('jours');
} }
// Paramètres de l'image OpenGraph
$imagePath = self::FILE_DIR . 'source/' . $this->getData(['config', 'seo', 'openGraphImage']);
// Par défaut
self::$imageOpenGraph['type'] = '';
self::$imageOpenGraph['size'] = '';
self::$imageOpenGraph['wide'] = '';
self::$imageOpenGraph['height'] = '';
self::$imageOpenGraph['ratio'] = 0;
if (
$this->getData(['config', 'seo', 'openGraphImage'])
&& file_exists($imagePath)
) {
// Infos sur l'image Open Graph
$typeMime = exif_imagetype($imagePath);
switch ($typeMime) {
case IMAGETYPE_JPEG:
$typeMime = 'jpeg';
break;
case IMAGETYPE_PNG:
$typeMime = 'png';
break;
default:
$typeMime = image_type_to_mime_type($typeMime);
}
self::$imageOpenGraph['type'] = $typeMime;
$imageSize = getimagesize($imagePath);
self::$imageOpenGraph['wide'] = $imageSize[0];
self::$imageOpenGraph['height'] = $imageSize[1];
self::$imageOpenGraph['ratio'] = self::$imageOpenGraph['wide'] / self::$imageOpenGraph['height'];
self::$imageOpenGraph['size'] = filesize($imagePath);
$tailleEnOctets = filesize($imagePath);
if ($tailleEnOctets >= 1024 * 1024) {
// Si la taille est supérieure ou égale à 1 Mo, afficher en mégaoctets
self::$imageOpenGraph['size'] = round($tailleEnOctets / (1024 * 1024), 2) . ' Mo';
} else {
// Sinon, afficher en kilooctets
self::$imageOpenGraph['size'] = round($tailleEnOctets / 1024, 2) . ' Ko';
}
}
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'title' => helper::translate('Configuration'), 'title' => helper::translate('Configuration'),
@ -648,16 +589,13 @@ class config extends common
public function script() public function script()
{ {
// Soumission du formulaire // Soumission du formulaire
if ( if ($this->isPost()) {
$this->getUser('permission', __CLASS__, __FUNCTION__) === true &&
$this->isPost()
) {
// 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([
@ -686,36 +624,26 @@ class config extends common
public function logReset() public function logReset()
{ {
// Action interdite if (file_exists(self::DATA_DIR . 'journal.log')) {
if ( unlink(self::DATA_DIR . 'journal.log');
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true // Créer les en-têtes des journaux
) { $d = 'Date;Heure;IP;Id;Action' . PHP_EOL;
file_put_contents(self::DATA_DIR . 'journal.log', $d);
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'access' => false 'title' => helper::translate('Configuration'),
'view' => 'index',
'notification' => helper::translate('Journal réinitialisé avec succès'),
'state' => true
]); ]);
} else { } else {
if (file_exists(self::DATA_DIR . 'journal.log')) { // Valeurs en sortie
unlink(self::DATA_DIR . 'journal.log'); $this->addOutput([
// Créer les en-têtes des journaux 'title' => helper::translate('Configuration'),
$d = 'Date;Heure;IP;Id;Action' . PHP_EOL; 'view' => 'index',
$this->secure_file_put_contents(self::DATA_DIR . 'journal.log', $d); 'notification' => helper::translate('Aucun journal à effacer'),
// Valeurs en sortie 'state' => false
$this->addOutput([ ]);
'title' => helper::translate('Configuration'),
'view' => 'index',
'notification' => helper::translate('Journal réinitialisé avec succès'),
'state' => true
]);
} else {
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Configuration'),
'view' => 'index',
'notification' => helper::translate('Aucun journal à effacer'),
'state' => false
]);
}
} }
} }
@ -726,35 +654,25 @@ class config extends common
*/ */
public function logDownload() public function logDownload()
{ {
// Action interdite $fileName = self::DATA_DIR . 'journal.log';
if ( if (file_exists($fileName)) {
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true ob_start();
) { header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $fileName . '"');
header('Content-Length: ' . filesize($fileName));
ob_clean();
ob_end_flush();
readfile($fileName);
exit();
} else {
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'access' => false 'title' => helper::translate('Configuration'),
'view' => 'index',
'notification' => helper::translate('Aucun fichier journal à télécharger'),
'state' => false
]); ]);
} else {
$fileName = self::DATA_DIR . 'journal.log';
if (file_exists($fileName)) {
ob_start();
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $fileName . '"');
header('Content-Length: ' . filesize($fileName));
ob_clean();
ob_end_flush();
readfile($fileName);
exit();
} else {
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Configuration'),
'view' => 'index',
'notification' => helper::translate('Aucun fichier journal à télécharger'),
'state' => false
]);
}
} }
} }
@ -763,46 +681,36 @@ class config extends common
*/ */
public function blacklistDownload() public function blacklistDownload()
{ {
// Action interdite ob_start();
if ( $fileName = self::TEMP_DIR . 'blacklist.log';
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true $d = 'Date dernière tentative;Heure dernière tentative;Id;Adresse IP;Nombre d\'échecs' . PHP_EOL;
) { file_put_contents($fileName, $d);
if (file_exists($fileName)) {
$d = $this->getData(['blacklist']);
$data = '';
foreach ($d as $key => $item) {
$data .= helper::dateUTF8('%Y %m %d', $item['lastFail']) . ' - ' . helper::dateUTF8('%H:%M', time());
$data .= $key . ';' . $item['ip'] . ';' . $item['connectFail'] . PHP_EOL;
}
file_put_contents($fileName, $data, FILE_APPEND);
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Transfer-Encoding: binary');
header('Content-Disposition: attachment; filename="' . $fileName . '"');
header('Content-Length: ' . filesize($fileName));
ob_clean();
ob_end_flush();
readfile($fileName);
unlink(self::TEMP_DIR . 'blacklist.log');
exit();
} else {
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'access' => false 'title' => helper::translate('Confighelper::translate(uration'),
'view' => 'index',
'notification' => helper::translate('Aucune liste noire à télécharger'),
'state' => false
]); ]);
} else {
ob_start();
$fileName = self::TEMP_DIR . 'blacklist.log';
$d = 'Date dernière tentative;Heure dernière tentative;Id;Adresse IP;Nombre d\'échecs' . PHP_EOL;
$this->secure_file_put_contents($fileName, $d);
if (file_exists($fileName)) {
$d = $this->getData(['blacklist']);
$data = '';
foreach ($d as $key => $item) {
$data .= helper::dateUTF8('%Y %m %d', $item['lastFail'], self::$i18nUI) . ' - ' . helper::dateUTF8('%H:%M', time(), self::$i18nUI);
$data .= $key . ';' . $item['ip'] . ';' . $item['connectFail'] . PHP_EOL;
}
$this->secure_file_put_contents($fileName, $data, FILE_APPEND);
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Transfer-Encoding: binary');
header('Content-Disposition: attachment; filename="' . $fileName . '"');
header('Content-Length: ' . filesize($fileName));
ob_clean();
ob_end_flush();
readfile($fileName);
unlink(self::TEMP_DIR . 'blacklist.log');
exit();
} else {
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Configuration'),
'view' => 'index',
'notification' => helper::translate('Aucune liste noire à télécharger'),
'state' => false
]);
}
} }
} }
@ -812,33 +720,23 @@ class config extends common
public function blacklistReset() public function blacklistReset()
{ {
// Action interdite if (file_exists(self::DATA_DIR . 'blacklist.json')) {
if ( $this->setData(['blacklist', []]);
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true
) {
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'access' => false 'title' => helper::translate('Configuration'),
'view' => 'index',
'notification' => helper::translate('Liste noire réinitialisée avec succès'),
'state' => true
]); ]);
} else { } else {
if (file_exists(self::DATA_DIR . 'blacklist.json')) { // Valeurs en sortie
$this->setData(['blacklist', []]); $this->addOutput([
// Valeurs en sortie 'title' => helper::translate('Configuration'),
$this->addOutput([ 'view' => 'index',
'title' => helper::translate('Configuration'), 'notification' => helper::translate('Aucune liste noire à effacer'),
'view' => 'index', 'state' => false
'notification' => helper::translate('Liste noire réinitialisée avec succès'), ]);
'state' => true
]);
} else {
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Configuration'),
'view' => 'index',
'notification' => helper::translate('Aucune liste noire à effacer'),
'state' => false
]);
}
} }
} }
@ -847,26 +745,16 @@ class config extends common
*/ */
public function copyBackups() public function copyBackups()
{ {
// Action interdite
if (
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true
) {
// Valeurs en sortie
$this->addOutput([
'access' => false
]);
} else {
$success = $this->copyDir(self::BACKUP_DIR, self::FILE_DIR . 'source/backup'); $success = $this->copyDir(self::BACKUP_DIR, self::FILE_DIR . 'source/backup');
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'title' => helper::translate('Configuration'), 'title' => helper::translate('Configuration'),
'view' => 'index', 'view' => 'index',
'notification' => $success ? helper::translate('Copie terminée avec succès') : helper::translate('Copie terminée avec des erreurs'), 'notification' => $success ? helper::translate('Copie terminée avec succès') : helper::translate('Copie terminée avec des erreurs'),
'state' => $success 'state' => $success
]); ]);
}
} }
/** /**
@ -874,32 +762,22 @@ class config extends common
*/ */
public function delBackups() public function delBackups()
{ {
// Action interdite $path = realpath(self::BACKUP_DIR);
if ( $success = $fail = 0;
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)) as $filename) {
) { if (strpos($filename, '.zip')) {
// Valeurs en sortie
$this->addOutput([
'access' => false
]);
} else {
$path = realpath(self::BACKUP_DIR);
$success = $fail = 0;
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)) as $filename) {
if (strpos($filename, '.zip')) {
$r = unlink($filename); $r = unlink($filename);
$success = $r === true ? $success + 1 : $success; $success = $r === true ? $success + 1 : $success;
$fail = $r === false ? $fail + 1 : $fail; $fail = $r === false ? $fail + 1 : $fail;
}
} }
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Configuration'),
'view' => 'index',
'notification' => $success . helper::translate('Fichiers effacés') . ' - ' . helper::translate('Échecs') . ': ' . $fail,
'state' => true
]);
} }
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Configuration'),
'view' => 'index',
'notification' => $success . helper::translate('Fichiers effacés') . ' - ' . helper::translate('Échecs') . ': ' . $fail,
'state' => true
]);
} }
} }

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/
*/ */
@ -53,15 +53,3 @@
.activeButton { .activeButton {
background-color: #00BFFF; background-color: #00BFFF;
} }
.greenInfo, .redInfo {
font-weight: bold;
}
.greenInfo {
color: green;
}
.redInfo {
color: red;
}

File diff suppressed because one or more lines are too long

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 @@
'value' => template::ico('left') 'value' => template::ico('left')
]); ?> ]); ?>
</div> </div>
<div class="col2 offset9"> <div class="col2 offset8">
<?php echo template::submit('configRestoreSubmit', [ <?php echo template::submit('configRestoreSubmit', [
'value' => 'Restaurer', 'value' => 'Restaurer',
'uniqueSubmission' => true, 'uniqueSubmission' => true,

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

@ -89,11 +89,11 @@
'selected' => $this->getData(['config', 'autoUpdateDelay']), 'selected' => $this->getData(['config', 'autoUpdateDelay']),
]); ?> ]); ?>
</div> </div>
<div class="col3 offset1 verticalAlignBottom"> <div class="col3 offset2 verticalAlignBottom">
<pre>Version installée : <strong><?php echo common::ZWII_VERSION ; ?></strong></pre> <pre>Version installée : <strong><?php echo common::ZWII_VERSION ; ?></strong></pre>
<pre>Version en ligne : <strong><?php echo helper::getOnlineVersion(common::ZWII_UPDATE_CHANNEL) ; ?></strong></pre> <pre>Version en ligne : <strong><?php echo helper::getOnlineVersion(common::ZWII_UPDATE_CHANNEL) ; ?></strong></pre>
</div> </div>
<div class="col3 offset2 verticalAlignBottom"> <div class="col3 verticalAlignBottom">
<?php echo template::button('configUpdateForced', [ <?php echo template::button('configUpdateForced', [
'ico' => 'download-cloud', 'ico' => 'download-cloud',
'href' => helper::baseUrl() . 'install/update', 'href' => helper::baseUrl() . 'install/update',

View File

@ -11,47 +11,33 @@
</span>--> </span>-->
</h4> </h4>
<div class="row"> <div class="row">
<div class="col6"> <div class="col7">
<div class="row"> <div class="row">
<div class="col12"> <div class="col12">
<?php echo template::file('seoOpenGraphImage', [ <?php echo template::text('seoKeyApi', [
'language' => $this->getData(['user', $this->getUser('id'), 'language']), 'label' => 'Clé de l\'API <a href="https://app.screenshotapi.net/" target="_blank">ScreenShotApi</a>',
'label' => 'Image Open Graph', 'value' => $this->getData(['config', 'seo', 'keyApi']),
'value' => $this->getData(['config', 'seo', 'openGraphImage']), 'help' => 'Créez un compte gratuit, recopier la clé , puis valider le formulaire avant de cliquer sur le bouton de génération'
'type' => 1,
'help' => sprintf('%s : JPG - PNG<br />', helper::translate('Format')) .
sprintf('%s : 1200 x 630 pixels<br />', helper::translate('Dimensions minimales')) .
sprintf('%s : 1.91:1<br />', helper::translate('Ratio')) .
sprintf('%s : %s, %s<br />', helper::translate('Taille maximale du fichier'), helper::translate('5 Mo pour les images JPEG'), helper::translate('1 Mo pour les images PNG'))
]); ?> ]); ?>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col10 textAlignCenter"> <div class="col6 offset3">
<?php if( !empty($module::$imageOpenGraph['type']) ): ?> <?php echo template::button('socialMetaImage', [
<p> 'href' => helper::baseUrl() . 'config/configMetaImage',
<?php echo sprintf('%s : <span id="screenType">%s</span>', helper::translate('Format'), $module::$imageOpenGraph['type']); ?> 'value' => 'Générer une capture Open Graph'
</p> ]); ?>
<p>
<?php echo sprintf('%s : <span id="screenWide">%s</span> x <span id="screenHeight">%s</span> pixels', helper::translate('Dimensions minimales'), $module::$imageOpenGraph['wide'], $module::$imageOpenGraph['height'] ); ?>
</p>
<p>
<?php echo sprintf('%s : <span id="screenRatio">%s</span><span id="screenFract">:1</span>' , helper::translate('Ratio'), round($module::$imageOpenGraph['ratio'], 2)); ?>
</p>
<p>
<?php echo sprintf('%s : <span id="screenWeight">%s</span>', helper::translate('Poids'), $module::$imageOpenGraph['size']); ?>
</p>
<?php endif; ?>
</div> </div>
</div> </div>
</div> </div>
<div class="col6"> <div class="col5">
<?php if ( <?php if (file_exists(self::FILE_DIR . 'source/screenshot.jpg')): ?>
$this->getData(['config', 'seo', 'openGraphImage']) && <div class="row">
file_exists(self::FILE_DIR . 'source/' . $this->getData(['config', 'seo', 'openGraphImage'])) <div class="col8 offset2 textAlignCenter">
): ?> <img src="<?php echo helper::baseUrl(false) . self::FILE_DIR . 'source/screenshot.jpg'; ?>"
<img data-tippy-content="Cette capture d'écran est nécessaire aux partages sur les réseaux sociaux. Elle est régénérée lorsque le fichier 'screenshot.jpg' est effacé du gestionnaire de fichiers." />
src="<?php echo self::FILE_DIR . 'source/' . $this->getData(['config', 'seo', 'openGraphImage']); ?>" /> </div>
</div>
<?php endif; ?> <?php endif; ?>
</div> </div>
</div> </div>

View File

@ -1,50 +0,0 @@
<?php
/**
* 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/
*/
class dashboard extends common
{
public static $actions = [
'index' => self::GROUP_ADMIN,
];
public static $infos = [];
/**
* Dashboard
*/
public function index()
{
self::$infos['webserver'] = $_SERVER['SERVER_SOFTWARE'];
self::$infos['php']['version'] = phpversion();
self::$infos['php']['extension'] = get_loaded_extensions();
self::$infos['system']['memory'] = memory_get_usage() . ' octets';
self::$infos['system']['peek'] = 'Pic de mémoire utilisée : ' . memory_get_peak_usage() . ' octets';
$loadAverage = sys_getloadavg();
self::$infos['system']['charge'] = 'Charge moyenne (1 min / 5 min / 15 min) : ' . implode(' / ', $loadAverage) . '</P>';
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Tableau de bord'),
'view' => 'index'
]);
}
}

View File

@ -1,54 +0,0 @@
<?php echo template::formOpen('dashboard'); ?>
<div class="row">
<div class="col1">
<?php echo template::button('dashboardFormBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl(false),
'value' => template::ico('home')
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>
<?php echo helper::translate('Système'); ?>
</h4>
<div class="row">
<div class="col6">
<p>
<?php echo helper::translate('Serveur Web'); ?>
</p>
<p>
<?php echo $module::$infos['webserver']; ?>
</p>
</div>
<div class="col6">
<p>
<?php echo helper::translate('PHP') . ' ' . $module::$infos['php']['version']; ?>
</p>
<p>
<?php echo implode(' - ', $module::$infos['php']['extension']); ?>
</p>
</div>
</div>
<div class="row">
<div class="col12">
<p>
<?php echo helper::translate('Mémoire'); ?>
</p>
<p>
<?php echo $module::$infos['system']['memory']; ?>
</p>
<p>
<?php echo $module::$infos['system']['charge']; ?>
</p>
<p>
<?php echo $module::$infos['system']['peek']; ?>
</p>
</div>
</div>
</div>
</div>
</div>

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;
@ -49,35 +50,33 @@ class install extends common
'access' => false 'access' => false
]); ]);
} }
// Accès autorisé
// Soumission du formulaire // Soumission du formulaire
if ( if ($this->isPost()) {
//$this->getUser('permission', __CLASS__, __FUNCTION__) === true &&
$this->isPost()
) {
$lang = $this->getInput('installLanguage'); $lang = $this->getInput('installLanguage');
// Pour la suite de l'installation // Place le cookie pour la suite de l'installation
// setcookie('ZWII_UI', $lang, time() + 3600, helper::baseUrl(false, false), '', false, false); setcookie('ZWII_UI', $lang, time() + 3600, helper::baseUrl(false, false), '', false, false);
$_SESSION['ZWII_UI'] = $this->getInput('installLanguage');
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'redirect' => helper::baseUrl() . 'install/postinstall' 'redirect' => helper::baseUrl() . 'install/postinstall/' . $lang
]); ]);
} }
//Nettoyage anciennes installations
helper::deleteCookie('ZWII_CONTENT');
// Liste des langues UI disponibles // Liste des langues UI disponibles
if (is_dir(self::I18N_DIR)) { if (is_dir(self::I18N_DIR)) {
foreach ($this->getData(['language']) as $lang => $value) { foreach ($this->getData(['languages']) as $lang => $value) {
self::$i18nFiles[$lang] = self::$languages[$lang]; self::$i18nFiles[$lang] = self::$languages[$lang];
;
} }
} }
$this->addOutput([ $this->addOutput([
'display' => self::DISPLAY_LAYOUT_LIGHT, 'display' => self::DISPLAY_LAYOUT_LIGHT,
'title' => helper::translate('ZwiiCMS Installation'), 'title' => helper::translate('Installation'),
'view' => 'index' 'view' => 'index'
]); ]);
} }
@ -97,13 +96,19 @@ class install extends common
// Accès autorisé // Accès autorisé
else { else {
// Soumission du formulaire // Soumission du formulaire
if ( if ($this->isPost()) {
//$this->getUser('permission', __CLASS__, __FUNCTION__) !== true &&
$this->isPost()
) {
$success = true; $success = true;
// Validation de la langue transmise
self::$i18nUI = $this->getUrl(2);
self::$i18nUI = array_key_exists(self::$i18nUI, self::$languages) ? self::$i18nUI : 'fr_FR';
// par défaut le contenu est la langue d'installation
self::$i18nContent = self::$i18nUI;
setcookie('ZWII_CONTENT', self::$i18nContent, time() + 3600, helper::baseUrl(false, false), '', helper::isHttps(), true);
// Double vérification pour le mot de passe // Double vérification pour le mot de passe
if ($this->getInput('installPassword', helper::FILTER_STRING_SHORT, true) !== $this->getInput('installConfirmPassword', helper::FILTER_STRING_SHORT, true)) { if ($this->getInput('installPassword', helper::FILTER_STRING_SHORT, true) !== $this->getInput('installConfirmPassword', helper::FILTER_STRING_SHORT, true)) {
self::$inputNotices['installConfirmPassword'] = 'Incorrect'; self::$inputNotices['installConfirmPassword'] = 'Incorrect';
@ -115,120 +120,136 @@ class install extends common
$userMail = $this->getInput('installMail', helper::FILTER_MAIL, true); $userMail = $this->getInput('installMail', helper::FILTER_MAIL, true);
$userId = $this->getInput('installId', helper::FILTER_ID, true); $userId = $this->getInput('installId', helper::FILTER_ID, true);
// Validation de la langue transmise
self::$i18nUI = $_SESSION['ZWII_UI'];
self::$i18nUI = array_key_exists(self::$i18nUI, self::$languages) ? self::$i18nUI : 'fr_FR';
// par défaut le contenu est la langue d'installation
$_SESSION['ZWII_SITE_CONTENT'] = self::$i18nUI;
// Création du dossier de langue avec le marqueur de langue par défaut
if (!is_dir(self::DATA_DIR . $_SESSION['ZWII_SITE_CONTENT'])) {
mkdir(self::DATA_DIR . $_SESSION['ZWII_SITE_CONTENT']);
touch(self::DATA_DIR . $_SESSION['ZWII_SITE_CONTENT'] . '/.default');
}
// Installation du site de test
if (
$this->getInput('installDefaultData', helper::FILTER_BOOLEAN) === false
&& $_SESSION['ZWII_SITE_CONTENT'] === 'fr_FR'
) {
$sample = true;
}
$this->initData('page', $_SESSION['ZWII_SITE_CONTENT'], $sample);
$this->initData('module', $_SESSION['ZWII_SITE_CONTENT'], $sample);
$this->initData('locale', $_SESSION['ZWII_SITE_CONTENT'], $sample);
// 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
$this->setData([ $success = $this->setData([
'user', 'user',
$userId, $userId,
[ [
'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' => self::$i18nUI
] ]
]); ]);
// Envoie le mail // Compte créé, envoi du mail et création des données du site
// Sent contient true si réussite sinon code erreur d'envoi en clair if ($success) { // Formulaire complété envoi du mail
$this->sendMail( // Envoie le mail
$userMail, // Sent contient true si réussite sinon code erreur d'envoi en clair
'Installation de votre site', $sent = $this->sendMail(
'Bonjour' . ' <strong>' . $userFirstname . ' ' . $userLastname . '</strong>,<br><br>' . $userMail,
'Voici les détails de votre installation.<br><br>' . 'Installation de votre site',
'<strong>URL du site :</strong> <a href="' . helper::baseUrl(false) . '" target="_blank">' . helper::baseUrl(false) . '</a><br>' . 'Bonjour' . ' <strong>' . $userFirstname . ' ' . $userLastname . '</strong>,<br><br>' .
'<strong>Identifiant du compte :</strong> ' . $this->getInput('installId') . '<br>', 'Voici les détails de votre installation.<br><br>' .
null, '<strong>URL du site :</strong> <a href="' . helper::baseUrl(false) . '" target="_blank">' . helper::baseUrl(false) . '</a><br>' .
'no-reply@localhost' '<strong>Identifiant du compte :</strong> ' . $this->getInput('installId') . '<br>',
); null,
$this->getData(['config', 'smtp', 'from']),
);
// Nettoyage fr par défaut // Installation du site de test
if ( if (
$_SESSION['ZWII_SITE_CONTENT'] !== 'fr_FR' $this->getInput('installDefaultData', helper::FILTER_BOOLEAN) === false
) { && self::$i18nContent === 'fr_FR'
if (is_dir(self::DATA_DIR . 'fr_FR')) ) {
$this->deleteDir(self::DATA_DIR . 'fr_FR'); $this->initData('page', self::$i18nContent, true);
} $this->initData('module', self::$i18nContent, true);
$this->setData(['module', 'blog', 'posts', 'mon-premier-article', 'userId', $userId]);
// Sauvegarder la configuration du Proxy $this->setData(['module', 'blog', 'posts', 'mon-deuxieme-article', 'userId', $userId]);
$this->setData(['config', 'proxyType', $this->getInput('installProxyType')]); $this->setData(['module', 'blog', 'posts', 'mon-troisieme-article', 'userId', $userId]);
$this->setData(['config', 'proxyUrl', $this->getInput('installProxyUrl')]);
$this->setData(['config', 'proxyPort', $this->getInput('installProxyPort', helper::FILTER_INT)]);
// Images exemples livrées dans tous les cas
try {
// Décompression dans le dossier de fichier temporaires
if (file_exists(self::TEMP_DIR . 'files.tar.gz')) {
unlink(self::TEMP_DIR . 'files.tar.gz');
} }
if (file_exists(self::TEMP_DIR . 'files.tar')) {
unlink(self::TEMP_DIR . 'files.tar'); // Jeu réduit pour les pages étrangères
if (self::$i18nContent !== 'fr_FR') {
$this->initData('page', self::$i18nContent, false);
$this->initData('module', self::$i18nContent, false);
// Supprime l'installation FR générée par défaut.
$this->removeDir(self::DATA_DIR . 'fr_FR');
} }
copy('core/module/install/ressource/files.tar.gz', self::TEMP_DIR . 'files.tar.gz');
$pharData = new PharData(self::TEMP_DIR . 'files.tar.gz'); // Sauvegarder la configuration du Proxy
$pharData->decompress(); $this->setData(['config', 'proxyType', $this->getInput('installProxyType')]);
// Installation $this->setData(['config', 'proxyUrl', $this->getInput('installProxyUrl')]);
$pharData->extractTo(__DIR__ . '/../../../', null, true); $this->setData(['config', 'proxyPort', $this->getInput('installProxyPort', helper::FILTER_INT)]);
} catch (Exception $e) {
$success = $e->getMessage(); // Images exemples livrées dans tous les cas
try {
// Décompression dans le dossier de fichier temporaires
if (file_exists(self::TEMP_DIR . 'files.tar.gz')) {
unlink(self::TEMP_DIR . 'files.tar.gz');
}
if (file_exists(self::TEMP_DIR . 'files.tar')) {
unlink(self::TEMP_DIR . 'files.tar');
}
copy('core/module/install/ressource/files.tar.gz', self::TEMP_DIR . 'files.tar.gz');
$pharData = new PharData(self::TEMP_DIR . 'files.tar.gz');
$pharData->decompress();
// Installation
$pharData->extractTo(__DIR__ . '/../../../', null, true);
} catch (Exception $e) {
$success = $e->getMessage();
}
// Nettoyage
unlink(self::TEMP_DIR . 'files.tar.gz');
unlink(self::TEMP_DIR . 'files.tar');
// Créer le dossier des fontes
if (!is_dir(self::DATA_DIR . 'fonts')) {
mkdir(self::DATA_DIR . 'fonts');
}
// Installation du thème sélectionné
$dataThemes = json_decode(file_get_contents('core/module/install/ressource/themes/themes.json'), true);
$dataThemes = $dataThemes['themes'];
$themeFilename = $dataThemes[$this->getInput('installTheme', helper::FILTER_STRING_SHORT)]['filename'];
if ($themeFilename !== '') {
$theme = new theme;
$theme->import('core/module/install/ressource/themes/' . $themeFilename);
}
// Copie des thèmes dans les fichiers
if (!is_dir(self::FILE_DIR . 'source/theme')) {
mkdir(self::FILE_DIR . 'source/theme');
}
$this->copyDir('core/module/install/ressource/themes', self::FILE_DIR . 'source/theme');
unlink(self::FILE_DIR . 'source/theme/themes.json');
// Copie des langues de l'UI et génération de la base de données
if (is_dir(self::I18N_DIR) === false) {
mkdir(self::I18N_DIR);
}
// Créer la base de données des langues
copy('core/module/install/ressource/i18n/languages.json', self::DATA_DIR . 'languages.json');
$this->copyDir('core/module/install/ressource/i18n', self::I18N_DIR);
unlink(self::I18N_DIR . 'languages.json');
// Fixe l'adresse from pour les envois d'email
$this->setData(['config', 'smtp', 'from', 'no-reply@' . str_replace('www.', '', $_SERVER['HTTP_HOST'])]);
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl(true) . $this->getData(['locale', 'homePageId']),
'notification' => $sent === true ? helper::translate('Installation terminée') : $sent,
'state' => ($sent === true && $success === true) ? true : null
]);
} }
// Nettoyage
unlink(self::TEMP_DIR . 'files.tar.gz');
unlink(self::TEMP_DIR . 'files.tar');
// Créer le dossier des fontes
if (!is_dir(self::DATA_DIR . 'font')) {
mkdir(self::DATA_DIR . 'font');
}
// Copie des langues de l'UI et génération de la base de données
if (is_dir(self::I18N_DIR) === false) {
mkdir(self::I18N_DIR);
}
// Créer la base de données des langues
$this->copyDir('core/module/install/ressource/i18n', self::I18N_DIR);
// Fixe l'adresse from pour les envois d'email
$this->setData(['config', 'smtp', 'from', 'no-reply@' . str_replace('www.', '', $_SERVER['HTTP_HOST'])]);
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl(),
'notification' => helper::translate('Installation terminée'),
'state' => true
]);
} }
// 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,
@ -243,204 +264,147 @@ class install extends common
*/ */
public function steps() public function steps()
{ {
// Action interdite switch ($this->getInput('step', helper::FILTER_INT)) {
if ( // Préparation
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true case 1:
) { $success = true;
// Valeurs en sortie $message = '';
$this->addOutput([ // RAZ la mise à jour auto
'access' => false $this->setData(['core', 'updateAvailable', false]);
]); // Backup du dossier Data
} else { helper::autoBackup(self::BACKUP_DIR, ['backup', 'tmp', 'file']);
switch ($this->getInput('step', helper::FILTER_INT)) { // Sauvegarde htaccess
// Préparation if ($this->getData(['config', 'autoUpdateHtaccess'])) {
case 1: $success = copy('.htaccess', '.htaccess' . '.bak');
$success = true; $message = 'Erreur de copie du fichier htaccess';
$message = ''; }
// RAZ la mise à jour auto // Nettoyage des fichiers d'installation précédents
$this->setData(['core', 'updateAvailable', false]); if (file_exists(self::TEMP_DIR . 'update.tar.gz') && $success) {
// Backup du dossier Data $success = $success || unlink(self::TEMP_DIR . 'update.tar.gz');
helper::autoBackup(self::BACKUP_DIR, ['backup', 'tmp', 'file']); $message = 'Impossible d\'effacer la mise à jour précédente';
// Sauvegarde htaccess }
if ($this->getData(['config', 'autoUpdateHtaccess'])) { if (file_exists(self::TEMP_DIR . 'update.tar') && $success) {
$success = copy('.htaccess', '.htaccess' . '.bak'); $success = $success || unlink(self::TEMP_DIR . 'update.tar');
$message = $success ? '' : 'Erreur de copie du fichier htaccess'; $message = 'Impossible d\'effacer la mise à jour précédente';
} }
// Nettoyage des fichiers d'installation précédents // Valeurs en sortie
if ($success && file_exists(self::TEMP_DIR . 'update.tar.gz')) { $this->addOutput([
$success = unlink(self::TEMP_DIR . 'update.tar.gz'); 'display' => self::DISPLAY_JSON,
$message = $success ? '' : 'Impossible d\'effacer la mise à jour précédente'; 'content' => [
} 'success' => $success,
if ($success && file_exists(self::TEMP_DIR . 'update.tar')) { 'data' => $success ? null : json_encode($message, JSON_UNESCAPED_UNICODE)
$success = unlink(self::TEMP_DIR . 'update.tar'); ]
$message = $success ? '' : 'Impossible d\'effacer la mise à jour précédente'; ]);
} break;
// Sauvegarde le message dans le journal // Téléchargement
if (!empty($message)) { case 2:
$this->saveLog($message); 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');
// Valeurs en sortie $md5origin = explode(' ', $md5origin);
$this->addOutput([ $md5target = md5_file(self::TEMP_DIR . 'update.tar.gz');
'display' => self::DISPLAY_JSON, // Valeurs en sortie
'content' => [ $this->addOutput([
'success' => $success, 'display' => self::DISPLAY_JSON,
'data' => $success ? null : json_encode($message, JSON_UNESCAPED_UNICODE) 'content' => [
] 'success' => $md5origin[0] === $md5target,
]); 'data' => $md5origin[0] === $md5target ? null : json_encode('Erreur de téléchargement ou de somme de contrôle', JSON_UNESCAPED_UNICODE)
break; ]
// Téléchargement ]);
case 2: break;
$success = true; // Installation
$message = ''; case 3:
$this->secure_file_put_contents(self::TEMP_DIR . 'update.tar.gz', helper::getUrlContents(common::ZWII_UPDATE_URL . common::ZWII_UPDATE_CHANNEL . '/update.tar.gz')); $success = true;
$md5origin = helper::getUrlContents(common::ZWII_UPDATE_URL . common::ZWII_UPDATE_CHANNEL . '/update.md5'); // Check la réécriture d'URL avant d'écraser les fichiers
$md5origin = explode(' ', $md5origin); $rewrite = helper::checkRewrite();
$md5target = md5_file(self::TEMP_DIR . 'update.tar.gz'); // Décompression et installation
// Vérifier si les checksums correspondent try {
if ($md5origin[0] === $md5target) { // Décompression dans le dossier de fichier temporaires
$success = true; $pharData = new PharData(self::TEMP_DIR . 'update.tar.gz');
$message = ""; $pharData->decompress();
} else { // Installation
$success = false; $pharData->extractTo(__DIR__ . '/../../../', null, true);
$message = 'Erreur de téléchargement ou de somme de contrôle'; } catch (Exception $e) {
if (file_exists(self::TEMP_DIR . 'update.tar.gz')) { $success = $e->getMessage();
unlink(self::TEMP_DIR . 'update.tar.gz'); }
http_response_code(500); // Nettoyage du dossier
} if (file_exists(self::TEMP_DIR . 'update.tar.gz')) {
} unlink(self::TEMP_DIR . 'update.tar.gz');
// Sauvegarde le message dans le journal }
if (!empty($message)) { if (file_exists(self::TEMP_DIR . 'update.tar')) {
$this->saveLog($message); unlink(self::TEMP_DIR . 'update.tar');
} }
// 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;
// Installation // Configuration
case 3: case 4:
$success = true; $success = true;
$message = ''; $message = null;
$rewrite = $this->getInput('data');
// Réécriture d'URL
if ($rewrite === "true") { // Ajout des lignes dans le .htaccess
$fileContent = file_get_contents('.htaccess');
$rewriteData = PHP_EOL .
'# URL rewriting' . PHP_EOL .
'<IfModule mod_rewrite.c>' . PHP_EOL .
"\tRewriteEngine on" . PHP_EOL .
"\tRewriteBase " . helper::baseUrl(false, false) . PHP_EOL .
"\tRewriteCond %{REQUEST_FILENAME} !-f" . PHP_EOL .
"\tRewriteCond %{REQUEST_FILENAME} !-d" . PHP_EOL .
"\tRewriteRule ^(.*)$ index.php?$1 [L]" . PHP_EOL .
'</IfModule>' . PHP_EOL .
'# URL rewriting' . PHP_EOL;
$fileContent = str_replace('# URL rewriting', $rewriteData, $fileContent);
$r = file_put_contents(
'.htaccess',
$fileContent
);
$success = $r === false ? false : true;
$message = $r === false ? 'Le fichier htaccess n\'a pas été restauré' : null;
}
// Recopie htaccess
if (
$this->getData(['config', 'autoUpdateHtaccess']) &&
$success && file_exists('.htaccess.bak')
) {
// L'écraser avec le backup
$success = $success || copy('.htaccess.bak', '.htaccess');
// Effacer le backup
unlink('.htaccess.bak');
}
// Check la réécriture d'URL avant d'écraser les fichiers /**
if (helper::checkRewrite()) { * Met à jour les dictionnaires des langues depuis les modèles installés
touch(self::DATA_DIR . '.rewrite'); */
}
// Décompression et installation // Langues installées
try { $installedUI = $this->getData(['languages']);
// Décompression dans le dossier de fichier temporaires
$pharData = new PharData(self::TEMP_DIR . 'update.tar.gz');
$pharData->decompress();
// Installation
$pharData->extractTo(__DIR__ . '/../../../', null, true);
} catch (Exception $e) {
$message = $e->getMessage();
$success = false;
http_response_code(500);
}
// Nettoyage du dossier // Langues disponibles avec la mise à jour
if (file_exists(self::TEMP_DIR . 'update.tar.gz')) { $store = json_decode(file_get_contents('core/module/install/ressource/i18n/languages.json'), true);
unlink(self::TEMP_DIR . 'update.tar.gz'); $store = $store['languages'];
}
if (file_exists(self::TEMP_DIR . 'update.tar')) {
unlink(self::TEMP_DIR . 'update.tar');
}
// Sauvegarde le message dans le journal
if (!empty($message)) {
$this->saveLog($message);
}
// Valeurs en sortie
$this->addOutput([
'display' => self::DISPLAY_JSON,
'content' => [
'success' => $success,
'data' => json_encode($message, JSON_UNESCAPED_UNICODE)
]
]);
break;
// Configuration
case 4:
$success = true;
$message = '';
/** foreach ($installedUI as $key => $value) {
* Restaure le fichier htaccess if ($store[$key]['version'] > $value['version']) {
*/ echo copy('core/module/install/ressource/i18n/' . $key . '.json', self::I18N_DIR . $key . '.json');
// Recopie htaccess $this->setData(['languages', $key, $store[$key]]);
if (
$this->getData(['config', 'autoUpdateHtaccess']) === true
) {
// L'écraser avec le backup
$success = copy('.htaccess.bak', '.htaccess');
if ($success === false) {
$message = helper::translate('La copie de sauvegarde du fichier htaccess n\'a pas été restaurée !');
http_response_code(500);
}
// Effacer le backup
unlink('.htaccess.bak');
} else {
/**
* Restaure la réécriture d'URL
*/
if (file_exists(self::DATA_DIR . '.rewrite')) { // Ajout des lignes dans le .htaccess
$fileContent = file_get_contents('.htaccess');
$rewriteData = PHP_EOL .
'# URL rewriting' . PHP_EOL .
'<IfModule mod_rewrite.c>' . PHP_EOL .
"\tRewriteEngine on" . PHP_EOL .
"\tRewriteBase " . helper::baseUrl(false, false) . PHP_EOL .
"\tRewriteCond %{REQUEST_FILENAME} !-f" . PHP_EOL .
"\tRewriteCond %{REQUEST_FILENAME} !-d" . PHP_EOL .
"\tRewriteRule ^(.*)$ index.php?$1 [L]" . PHP_EOL .
'</IfModule>' . PHP_EOL .
'# URL rewriting' . PHP_EOL;
$fileContent = str_replace('# URL rewriting', $rewriteData, $fileContent);
$success = $this->secure_file_put_contents(
'.htaccess',
$fileContent
);
unlink(self::DATA_DIR . '.rewrite');
}
} }
}
/** // Valeurs en sortie
* Met à jour les dictionnaires des langues depuis les nouveaux modèles installés $this->addOutput([
*/ 'display' => self::DISPLAY_JSON,
require_once('core/module/install/ressource/defaultdata.php'); 'content' => [
$installedLanguages = $this->getData(['language']); 'success' => $success,
$defaultLanguages = init::$defaultData['language']; 'data' => json_encode($message, JSON_UNESCAPED_UNICODE)
foreach ($installedLanguages as $key => $value) { ]
]);
if (
isset($defaultLanguages[$key]['date']) &&
$defaultLanguages[$key]['date'] > $value['date'] &&
isset($defaultLanguages[$key]['version']) &&
$defaultLanguages[$key]['version'] >= $value['version']
) {
copy('core/module/install/ressource/i18n/' . $key . '.json', self::I18N_DIR . $key . '.json');
$this->setData(['language', $key, $defaultLanguages[$key]]);
}
}
// Sauvegarde le message dans le journal
if (!empty($message)) {
$this->saveLog($message);
}
// Valeurs en sortie
$this->addOutput([
'display' => self::DISPLAY_JSON,
'content' => [
'success' => $success,
'data' => json_encode($message, JSON_UNESCAPED_UNICODE)
]
]);
}
} }
} }
@ -449,31 +413,14 @@ class install extends common
*/ */
public function update() public function update()
{ {
// Action interdite // Nouvelle version
if ( self::$newVersion = helper::getUrlContents(common::ZWII_UPDATE_URL . common::ZWII_UPDATE_CHANNEL . '/version');
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true // Valeurs en sortie
) { $this->addOutput([
// Valeurs en sortie 'display' => self::DISPLAY_LAYOUT_LIGHT,
$this->addOutput([ 'title' => helper::translate('Mise à jour'),
'access' => false 'view' => 'update'
]); ]);
} else {
// Nouvelle 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
$this->addOutput([
'display' => self::DISPLAY_LAYOUT_LIGHT,
'title' => helper::translate(self::$updateButtonText),
'view' => 'update'
]);
}
} }
} }

View File

@ -5,7 +5,6 @@ class init extends common
'config' => [ 'config' => [
'autoBackup' => true, 'autoBackup' => true,
'autoUpdate' => true, 'autoUpdate' => true,
'autoUpdateDelay' => 86400,
'autoUpdateHtaccess' => false, 'autoUpdateHtaccess' => false,
'favicon' => 'favicon.ico', 'favicon' => 'favicon.ico',
'faviconDark' => 'faviconDark.ico', 'faviconDark' => 'faviconDark.ico',
@ -26,11 +25,10 @@ class init extends common
'proxyType' => 'tcp://', 'proxyType' => 'tcp://',
'smtp' => [ 'smtp' => [
'enable' => false, 'enable' => false,
'from'=> 'no-reply@localhost'
], ],
'seo' => [ 'seo' => [
'robots' => true, 'robots' => true,
'openGraphImage' => 'screenshot.png' 'keyApi' => 'XXXXXXX-XXXXXXX-XXXXXXX-XXXXXXX'
], ],
'connect' => [ 'connect' => [
'timeout' => 600, 'timeout' => 600,
@ -46,13 +44,33 @@ class init extends common
] ]
], ],
'core' => [ 'core' => [
'dataVersion' => 13000, 'dataVersion' => 12300,
'lastBackup' => 0, 'lastBackup' => 0,
'lastClearTmp' => 0, 'lastClearTmp' => 0,
'lastAutoUpdate' => 0, 'lastAutoUpdate' => 0,
'updateAvailable' => false 'updateAvailable' => false
], ],
'font' => [ 'locale' => [
'homePageId' => 'accueil',
'page302' => 'none',
'page403' => 'none',
'page404' => 'none',
'legalPageId' => 'none',
'searchPageId' => 'none',
'searchPageLabel' => 'Rechercher',
'sitemapPageLabel' => 'Plan du site',
'legalPageLabel' => 'Mentions légales',
'metaDescription' => 'Zwii est un CMS sans base de données qui permet de créer et gérer facilement un site web sans aucune connaissance en programmation.',
'title' => 'Votre site en quelques clics !',
'cookies' => [
'mainLabel' => 'Ce site utilise des cookies nécessaires à son fonctionnement, ils permettent de fluidifier son fonctionnement par exemple en mémorisant les données de connexion, la langue que vous avez choisie ou la validation de ce message.',
'titleLabel' => 'Cookies essentiels',
'linkLegalLabel' => 'Consulter les mentions légales',
'cookiesFooterText' => 'Cookies',
'buttonValidLabel' => 'J\'ai compris'
]
],
'fonts' => [
'files' => [], 'files' => [],
'imported' => [ 'imported' => [
'arimo' => [ 'arimo' => [
@ -72,12 +90,12 @@ class init extends common
], ],
'droid-sans-2' => [ 'droid-sans-2' => [
'name' => 'Droid Sans', 'name' => 'Droid Sans',
'font-family' => '\'Droid Sans\', sans-serif', 'font-family' => '\'Droid Sans\', sans-serif',
'resource' => 'https://fonts.cdnfonts.com/css/droid-sans-2' 'resource' => 'https://fonts.cdnfonts.com/css/droid-sans-2'
], ],
'droid-serif-2' => [ 'droid-serif-2' => [
'name' => 'Droid Serif', 'name' => 'Droid Serif',
'font-family' => '\'Droid Serif\', serif', 'font-family' => '\'Droid Serif\', serif',
'resource' => 'https://fonts.cdnfonts.com/css/droid-serif-2' 'resource' => 'https://fonts.cdnfonts.com/css/droid-serif-2'
], ],
'indie-flower' => [ 'indie-flower' => [
@ -157,8 +175,39 @@ class init extends common
] ]
] ]
], ],
'page' => [
'accueil' => [
'typeMenu' => 'text',
'iconUrl' => '',
'disable' => false,
'content' => 'accueil.html',
'hideTitle' => false,
'homePageId' => true,
'breadCrumb' => false,
'metaDescription' => '',
'metaTitle' => '',
'moduleId' => '',
'modulePosition' => 'bottom',
'parentPageId' => '',
'position' => 1,
'group' => self::GROUP_VISITOR,
'targetBlank' => false,
'title' => 'Accueil',
'shortTitle' => 'Accueil',
'block' => '12',
'barLeft' => '',
'barRight' => '',
'displayMenu' => 'none',
'hideMenuSide' => false,
'hideMenuChildren' => false,
'extraPosition' => false,
'css' => '',
'js' => ''
]
],
'module' => [],
'user' => [], 'user' => [],
'theme' => [ 'theme' => [
'body' => [ 'body' => [
'backgroundColor' => 'rgba(236, 239, 241, 1)', 'backgroundColor' => 'rgba(236, 239, 241, 1)',
'image' => '', 'image' => '',
@ -281,489 +330,13 @@ 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' => [ 'languages'=> [],
"fr_FR" => [
"version" => 13007,
"date" => 1699354723
],
"es" => [
"version" => 13007,
"date" => 1699354723
],
"en_EN" => [
"version" => 13007,
"date" => 1699354723
]
],
'profil' => [
'-1' => [
'name' => 'Banni',
'readonly' => true,
'permanent' => true,
'comment' => 'Accès désactivé',
],
'0' => [
'name' => 'Visiteur',
'readonly' => true,
'permanent' => true,
'comment' => 'Accède au site',
],
'1' => [
'1' => [
'name' => 'Membre simple',
'readonly' => false,
'permanent' => true,
'comment' => 'Accède aux pages réservées',
'filemanager' => false,
'file' => [
'download' => false,
'edit' => false,
'create' => false,
'rename' => false,
'upload' => false,
'delete' => false,
'preview' => false,
'duplicate' => false,
'extract' => false,
'copycut' => false,
'chmod' => false
],
'folder' => [
'create' => false,
'delete' => false,
'rename' => false,
'copycut' => false,
'chmod' => false,
'share' => false,
'path' => null,
],
'page' => [
'add' => false,
'delete' => false,
'duplicate' => false,
'edit' => false,
'jsEditor' => false,
'cssEditor' => false,
'module' => false,
],
'blog' => [
'add' => false,
'delete' => false,
'edit' => false,
'option' => false,
'config' => false,
'comment' => false,
'commentApprove' => false,
'commentDelete' => false,
'commentDeleteAll' => false,
],
'form' => [
'option' => false,
'config' => false,
'data' => false,
'delete' => false,
'deleteAll' => false,
'export2csv' => false,
],
'gallery' => [
'config' => false,
'delete' => false,
'edit' => false,
'add' => false,
'option' => false,
'theme' => false,
],
'news' => [
'add' => false,
'config' => false,
'option' => false,
'delete' => false,
'edit' => false,
],
'redirection' => [
'config' => false,
],
'search' => [
'config' => false,
],
'user' => [
'edit' => true,
]
],
'2' => [
'name' => 'Membre avec droit de partage',
'readonly' => false,
'permanent' => false,
'comment' => 'Accède aux pages réservées et à un dossier partagé',
'filemanager' => true,
'file' => [
'download' => false,
'edit' => false,
'create' => false,
'rename' => false,
'upload' => false,
'delete' => false,
'preview' => false,
'duplicate' => false,
'extract' => false,
'copycut' => false,
'chmod' => false
],
'folder' => [
'create' => false,
'delete' => false,
'rename' => false,
'copycut' => false,
'chmod' => false,
'share' => true,
'path' => '/site/file/source/partage/',
],
'page' => [
'add' => false,
'delete' => false,
'duplicate' => false,
'edit' => false,
'jsEditor' => false,
'cssEditor' => false,
'module' => false,
],
'blog' => [
'add' => false,
'delete' => false,
'edit' => false,
'option' => false,
'config' => false,
'comment' => false,
'commentApprove' => false,
'commentDelete' => false,
'commentDeleteAll' => false,
],
'form' => [
'option' => false,
'config' => false,
'data' => false,
'delete' => false,
'deleteAll' => false,
'export2csv' => false,
],
'gallery' => [
'config' => false,
'delete' => false,
'edit' => false,
'add' => false,
'option' => false,
'theme' => false,
'dirs' => false,
'sortGalleries' => false,
'sortPictures' => false,
],
'news' => [
'add' => false,
'config' => false,
'option' => false,
'delete' => false,
'edit' => false,
],
'redirection' => [
'config' => false,
],
'search' => [
'config' => false,
],
'user' => [
'edit' => true,
]
],
],
'2' => [
'1' => [
'name' => 'Éditeur simple',
'readonly' => false,
'permanent' => true,
'comment' => 'Édition des pages',
'filemanager' => true,
'file' => [
'download' => true,
'edit' => true,
'create' => true,
'rename' => true,
'upload' => true,
'delete' => false,
'preview' => true,
'duplicate' => false,
'extract' => false,
'copycut' => false,
'chmod' => false
],
'folder' => [
'create' => false,
'delete' => false,
'rename' => false,
'copycut' => false,
'chmod' => false,
'share' => true,
'path' => '/site/file/source/partage/',
],
'page' => [
'add' => false,
'delete' => false,
'duplicate' => false,
'edit' => true,
'jsEditor' => true,
'cssEditor' => true,
'module' => true,
],
'blog' => [
'add' => true,
'delete' => false,
'edit' => true,
'option' => false,
'config' => false,
'comment' => false,
'commentApprove' => false,
'commentDelete' => false,
'commentDeleteAll' => false,
],
'form' => [
'option' => false,
'config' => false,
'data' => false,
'delete' => false,
'deleteAll' => false,
'export2csv' => false,
],
'gallery' => [
'config' => false,
'delete' => false,
'edit' => false,
'add' => false,
'option' => false,
'theme' => false,
],
'news' => [
'add' => true,
'config' => false,
'option' => false,
'delete' => false,
'edit' => true,
],
'redirection' => [
'config' => false,
],
'search' => [
'config' => false,
],
'user' => [
'edit' => true,
]
],
'2' => [
'name' => 'Rédacteur',
'readonly' => false,
'permanent' => false,
'comment' => 'Tous les droits d\'édition des contenus',
'filemanager' => true,
'file' => [
'download' => true,
'edit' => true,
'create' => true,
'rename' => true,
'upload' => true,
'delete' => true,
'preview' => true,
'duplicate' => true,
'extract' => true,
'copycut' => true,
'chmod' => true
],
'folder' => [
'create' => true,
'delete' => true,
'rename' => true,
'copycut' => true,
'chmod' => true,
'share' => true,
'path' => '/site/file/source/partage/',
],
'page' => [
'add' => true,
'delete' => true,
'duplicate' => true,
'edit' => true,
'jsEditor' => true,
'cssEditor' => true,
'module' => true,
],
'blog' => [
'add' => true,
'delete' => true,
'edit' => true,
'option' => true,
'config' => true,
'comment' => true,
'commentApprove' => true,
'commentDelete' => true,
'commentDeleteAll' => true,
],
'form' => [
'option' => true,
'config' => true,
'data' => true,
'delete' => true,
'deleteAll' => true,
'export2csv' => true,
],
'gallery' => [
'config' => true,
'delete' => true,
'edit' => true,
'add' => true,
'option' => true,
'theme' => true,
],
'news' => [
'add' => true,
'config' => true,
'option' => true,
'delete' => true,
'edit' => true,
],
'redirection' => [
'config' => true,
],
'search' => [
'config' => true,
],
'user' => [
'edit' => true,
]
],
],
'3' => [
'name' => 'Administrateur',
'readonly' => true,
'permanent' => true,
'comment' => 'Contrôle total',
]
]
]; ];
public static $defaultDataI18n = [ public static $defaultDataI18n = [
'fr_FR' => [ 'en_EN' => [
'locale' => [
'homePageId' => 'accueil',
'page302' => 'none',
'page403' => 'none',
'page404' => 'none',
'legalPageId' => 'none',
'searchPageId' => 'none',
'searchPageLabel' => 'Rechercher',
'sitemapPageLabel' => 'Plan du site',
'legalPageLabel' => 'Mentions légales',
'metaDescription' => 'Zwii est un CMS sans base de données qui permet de créer et gérer facilement un site web sans aucune connaissance en programmation.',
'title' => 'Votre site en quelques clics !',
'cookies' => [
'mainLabel' => 'Ce site utilise des cookies nécessaires à son fonctionnement, ils permettent de fluidifier son fonctionnement par exemple en mémorisant les données de connexion, la langue que vous avez choisie ou la validation de ce message.',
'titleLabel' => 'Cookies essentiels',
'linkLegalLabel' => 'Consulter les mentions légales',
'cookiesFooterText' => 'Cookies',
'buttonValidLabel' => 'J\'ai compris'
]
],
'page' => [
'accueil' => [
'typeMenu' => 'text',
'iconUrl' => '',
'disable' => false,
'content' => 'accueil.html',
'hideTitle' => false,
'homePageId' => true,
'breadCrumb' => false,
'metaDescription' => '',
'metaTitle' => '',
'moduleId' => '',
'modulePosition' => 'bottom',
'parentPageId' => '',
'position' => 1,
'group' => self::GROUP_VISITOR,
'profil' => 0,
'targetBlank' => false,
'title' => 'Accueil',
'shortTitle' => 'Accueil',
'block' => '12',
'barLeft' => '',
'barRight' => '',
'displayMenu' => 'none',
'hideMenuSide' => false,
'hideMenuChildren' => false,
'extraPosition' => false,
'css' => '',
'js' => ''
]
],
'module' => [],
'html' => '<h2>Bienvenue dans cette nouvelle installation de ZwiiCMS. Créez et gérez votre site facilement avec notre système convivial.</h2>'
],
'es' => [
'locale' => [
'homePageId' => 'inicio',
'page302' => 'none',
'page403' => 'none',
'page404' => 'none',
'legalPageId' => 'none',
'searchPageId' => 'none',
'searchPageLabel' => 'none',
'sitemapPageLabel' => 'none',
'legalPageLabel' => 'legales',
"metaDescription" => "Zwii es un CMS sin base de datos que facilita la creación y gestión de un sitio web sin necesidad de conocimientos de programación.",
"title" => "¡Tu sitio en unos clics!",
"cookies" => [
"mainLabel" => "Este sitio web utiliza cookies necesarias para su funcionamiento. Estas cookies permiten optimizar su funcionamiento, por ejemplo, memorizando los datos de conexión, el idioma que has elegido o la validación de este mensaje.",
"titleLabel" => "Cookies esenciales",
"linkLegalLabel" => "Consultar el aviso legal",
"cookiesFooterText" => "Cookies",
"buttonValidLabel" => "Aceptar"
]
],
'page' => [
'inicio' => [
'typeMenu' => 'text',
'iconUrl' => '',
'disable' => false,
'content' => 'inico.html',
'hideTitle' => false,
'homePageId' => true,
'breadCrumb' => false,
'metaDescription' => '',
'metaTitle' => '',
'moduleId' => '',
'modulePosition' => 'bottom',
'parentPageId' => '',
'position' => 1,
'group' => self::GROUP_VISITOR,
'profil' => 0,
'targetBlank' => false,
'title' => 'Página de inicio',
'shortTitle' => 'Página de inicio',
'block' => '12',
'barLeft' => '',
'barRight' => '',
'displayMenu' => 'none',
'hideMenuSide' => false,
'hideMenuChildren' => false,
'extraPosition' => false,
'css' => '',
'js' => ''
]
],
'module' => [],
'html' => '<h2>¡Bienvenido/a a esta nueva instalación de ZwiiCMS!</h2><p>Crea y administra tu sitio web de manera sencilla con nuestro sistema amigable.</p><p>Esta es tu primera página, inicia sesión para crear nuevas.</p>'
],
'default' => [
'locale' => [ 'locale' => [
'homePageId' => 'home', 'homePageId' => 'home',
'page302' => 'none', 'page302' => 'none',
@ -773,7 +346,6 @@ class init extends common
'searchPageId' => 'none', 'searchPageId' => 'none',
'searchPageLabel' => 'none', 'searchPageLabel' => 'none',
'sitemapPageLabel' => 'none', 'sitemapPageLabel' => 'none',
'poweredPageLabel' => 'Powered by',
'legalPageLabel' => 'legals', 'legalPageLabel' => 'legals',
'metaDescription' => 'Zwii is a database-free CMS that makes it easy to create and manage a website without any programming knowledge.', 'metaDescription' => 'Zwii is a database-free CMS that makes it easy to create and manage a website without any programming knowledge.',
'title' => 'Your site in a few clicks!', 'title' => 'Your site in a few clicks!',
@ -801,7 +373,6 @@ class init extends common
'parentPageId' => '', 'parentPageId' => '',
'position' => 1, 'position' => 1,
'group' => self::GROUP_VISITOR, 'group' => self::GROUP_VISITOR,
'profil' => 0,
'targetBlank' => false, 'targetBlank' => false,
'title' => 'Home page', 'title' => 'Home page',
'shortTitle' => 'Home', 'shortTitle' => 'Home',
@ -816,11 +387,12 @@ class init extends common
'js' => '' 'js' => ''
] ]
], ],
'module' => [], 'html' => 'Welcome in this ZwiiCMS, congratulations this is you first page !'
'html' => '<h2>Welcome to this new installation of ZwiiCMS.</h2><p>Easily create and manage your website with our user-friendly system.</p><p>This is your first page, log in to create new ones.</p>'
] ]
]; ];
public static $siteTemplate = [
public static $siteData = [
'page' => [ 'page' => [
'accueil' => [ 'accueil' => [
'typeMenu' => 'text', 'typeMenu' => 'text',
@ -837,7 +409,6 @@ class init extends common
'parentPageId' => '', 'parentPageId' => '',
'position' => 1, 'position' => 1,
'group' => self::GROUP_VISITOR, 'group' => self::GROUP_VISITOR,
'profil' => 0,
'targetBlank' => false, 'targetBlank' => false,
'title' => 'Accueil', 'title' => 'Accueil',
'shortTitle' => 'Accueil', 'shortTitle' => 'Accueil',
@ -865,14 +436,13 @@ class init extends common
'parentPageId' => 'accueil', 'parentPageId' => 'accueil',
'position' => 1, 'position' => 1,
'group' => self::GROUP_VISITOR, 'group' => self::GROUP_VISITOR,
'profil' => 0,
'targetBlank' => false, 'targetBlank' => false,
'title' => 'Page Enfant', 'title' => 'Page Enfant',
'shortTitle' => 'Enfant', 'shortTitle' => 'Enfant',
'block' => '12', 'block' => '12',
'barLeft' => '', 'barLeft' => '',
'barRight' => '', 'barRight' => '',
'displayMenu' => 'none', 'displayMenu' => 'none',
'hideMenuSide' => false, 'hideMenuSide' => false,
'hideMenuChildren' => false, 'hideMenuChildren' => false,
'extraPosition' => false, 'extraPosition' => false,
@ -893,14 +463,13 @@ class init extends common
'modulePosition' => 'bottom', 'modulePosition' => 'bottom',
'position' => 2, 'position' => 2,
'group' => self::GROUP_MEMBER, 'group' => self::GROUP_MEMBER,
'profil' => 1,
'targetBlank' => false, 'targetBlank' => false,
'title' => 'Page privée', 'title' => 'Page privée',
'shortTitle' => 'Privée', 'shortTitle' => 'Privée',
'block' => '12', 'block' => '12',
'barLeft' => '', 'barLeft' => '',
'barRight' => '', 'barRight' => '',
'displayMenu' => 'none', 'displayMenu' => 'none',
'hideMenuSide' => false, 'hideMenuSide' => false,
'hideMenuChildren' => false, 'hideMenuChildren' => false,
'extraPosition' => false, 'extraPosition' => false,
@ -921,14 +490,13 @@ class init extends common
'modulePosition' => 'bottom', 'modulePosition' => 'bottom',
'position' => 2, 'position' => 2,
'group' => self::GROUP_VISITOR, 'group' => self::GROUP_VISITOR,
'profil' => 0,
'targetBlank' => false, 'targetBlank' => false,
'title' => 'Mise en page', 'title' => 'Mise en page',
'shortTitle' => 'Mise en page', 'shortTitle' => 'Mise en page',
'block' => '4-8', 'block' => '4-8',
'barLeft' => 'barre', 'barLeft' => 'barre',
'barRight' => '', 'barRight' => '',
'displayMenu' => 'none', 'displayMenu' => 'none',
'hideMenuSide' => false, 'hideMenuSide' => false,
'hideMenuChildren' => false, 'hideMenuChildren' => false,
'extraPosition' => false, 'extraPosition' => false,
@ -949,14 +517,13 @@ class init extends common
'modulePosition' => 'bottom', 'modulePosition' => 'bottom',
'position' => 3, 'position' => 3,
'group' => self::GROUP_VISITOR, 'group' => self::GROUP_VISITOR,
'profil' => 0,
'targetBlank' => false, 'targetBlank' => false,
'title' => 'Barre latérale avec menu', 'title' => 'Barre latérale avec menu',
'shortTitle' => 'Menu latéral', 'shortTitle' => 'Menu latéral',
'block' => '9-3', 'block' => '9-3',
'barLeft' => '', 'barLeft' => '',
'barRight' => 'barrelateraleavecmenu', 'barRight' => 'barrelateraleavecmenu',
'displayMenu' => 'none', 'displayMenu' => 'none',
'hideMenuSide' => false, 'hideMenuSide' => false,
'hideMenuChildren' => false, 'hideMenuChildren' => false,
'extraPosition' => false, 'extraPosition' => false,
@ -977,14 +544,13 @@ class init extends common
'parentPageId' => '', 'parentPageId' => '',
'position' => 3, 'position' => 3,
'group' => self::GROUP_VISITOR, 'group' => self::GROUP_VISITOR,
'profil' => 0,
'targetBlank' => false, 'targetBlank' => false,
'title' => 'Blog', 'title' => 'Blog',
'shortTitle' => 'Blog', 'shortTitle' => 'Blog',
'block' => '12', 'block' => '12',
'barLeft' => '', 'barLeft' => '',
'barRight' => '', 'barRight' => '',
'displayMenu' => 'none', 'displayMenu' => 'none',
'hideMenuSide' => false, 'hideMenuSide' => false,
'hideMenuChildren' => false, 'hideMenuChildren' => false,
'extraPosition' => false, 'extraPosition' => false,
@ -1005,14 +571,13 @@ class init extends common
'parentPageId' => '', 'parentPageId' => '',
'position' => 4, 'position' => 4,
'group' => self::GROUP_VISITOR, 'group' => self::GROUP_VISITOR,
'profil' => 0,
'targetBlank' => false, 'targetBlank' => false,
'title' => 'Galeries d\'images', 'title' => 'Galeries d\'images',
'shortTitle' => 'Galeries', 'shortTitle' => 'Galeries',
'block' => '12', 'block' => '12',
'barLeft' => '', 'barLeft' => '',
'barRight' => '', 'barRight' => '',
'displayMenu' => 'none', 'displayMenu' => 'none',
'hideMenuSide' => false, 'hideMenuSide' => false,
'hideMenuChildren' => false, 'hideMenuChildren' => false,
'extraPosition' => false, 'extraPosition' => false,
@ -1034,7 +599,6 @@ class init extends common
'parentPageId' => '', 'parentPageId' => '',
'position' => 5, 'position' => 5,
'group' => self::GROUP_VISITOR, 'group' => self::GROUP_VISITOR,
'profil' => 0,
'targetBlank' => true, 'targetBlank' => true,
'title' => 'Site de Zwii', 'title' => 'Site de Zwii',
'shortTitle' => 'Site de Zwii', 'shortTitle' => 'Site de Zwii',
@ -1062,7 +626,6 @@ class init extends common
'parentPageId' => '', 'parentPageId' => '',
'position' => 6, 'position' => 6,
'group' => self::GROUP_VISITOR, 'group' => self::GROUP_VISITOR,
'profil' => 0,
'targetBlank' => false, 'targetBlank' => false,
'title' => 'Contact', 'title' => 'Contact',
'shortTitle' => 'Contact', 'shortTitle' => 'Contact',
@ -1090,7 +653,6 @@ class init extends common
'parentPageId' => '', 'parentPageId' => '',
'position' => 0, 'position' => 0,
'group' => self::GROUP_VISITOR, 'group' => self::GROUP_VISITOR,
'profil' => 0,
'targetBlank' => false, 'targetBlank' => false,
'title' => 'Barre latérale', 'title' => 'Barre latérale',
'shortTitle' => 'Barre latérale', 'shortTitle' => 'Barre latérale',
@ -1118,7 +680,6 @@ class init extends common
'parentPageId' => '', 'parentPageId' => '',
'position' => 0, 'position' => 0,
'group' => self::GROUP_VISITOR, 'group' => self::GROUP_VISITOR,
'profil' => 0,
'targetBlank' => false, 'targetBlank' => false,
'title' => 'Barre latérale avec menu', 'title' => 'Barre latérale avec menu',
'shortTitle' => 'Barre latérale avec menu', 'shortTitle' => 'Barre latérale avec menu',
@ -1145,8 +706,7 @@ class init extends common
'modulePosition' => 'bottom', 'modulePosition' => 'bottom',
'parentPageId' => '', 'parentPageId' => '',
'position' => 0, 'position' => 0,
'group' => self::GROUP_VISITOR, 'group' => 0,
'profil' => 0,
'targetBlank' => false, 'targetBlank' => false,
'title' => 'Mentions légales', 'title' => 'Mentions légales',
'shortTitle' => 'Mentions légales', 'shortTitle' => 'Mentions légales',
@ -1175,7 +735,6 @@ class init extends common
'parentPageId' => '', 'parentPageId' => '',
'position' => 0, 'position' => 0,
'group' => self::GROUP_VISITOR, 'group' => self::GROUP_VISITOR,
'profil' => 0,
'targetBlank' => false, 'targetBlank' => false,
'title' => 'Maintenance en cours', 'title' => 'Maintenance en cours',
'shortTitle' => 'Maintenance en cours', 'shortTitle' => 'Maintenance en cours',
@ -1204,7 +763,6 @@ class init extends common
'parentPageId' => '', 'parentPageId' => '',
'position' => 0, 'position' => 0,
'group' => self::GROUP_VISITOR, 'group' => self::GROUP_VISITOR,
'profil' => 0,
'targetBlank' => false, 'targetBlank' => false,
'title' => 'Erreur 403', 'title' => 'Erreur 403',
'shortTitle' => 'Erreur 403', 'shortTitle' => 'Erreur 403',
@ -1232,7 +790,6 @@ class init extends common
'parentPageId' => '', 'parentPageId' => '',
'position' => 0, 'position' => 0,
'group' => self::GROUP_VISITOR, 'group' => self::GROUP_VISITOR,
'profil' => 0,
'targetBlank' => false, 'targetBlank' => false,
'title' => 'Erreur 404', 'title' => 'Erreur 404',
'shortTitle' => 'Erreur 404', 'shortTitle' => 'Erreur 404',
@ -1260,7 +817,6 @@ class init extends common
'parentPageId' => '', 'parentPageId' => '',
'position' => 7, 'position' => 7,
'group' => self::GROUP_VISITOR, 'group' => self::GROUP_VISITOR,
'profil' => 0,
'targetBlank' => false, 'targetBlank' => false,
'title' => 'Recherche dans le site', 'title' => 'Recherche dans le site',
'shortTitle' => 'Rechercher', 'shortTitle' => 'Rechercher',
@ -1299,17 +855,17 @@ class init extends common
'picturePosition' => 'left', 'picturePosition' => 'left',
'hidePicture' => false, 'hidePicture' => false,
'pictureSize' => 20, 'pictureSize' => 20,
'picturePosition' => 'left',
'publishedOn' => 1548790902, 'publishedOn' => 1548790902,
'state' => true, 'state' => true,
'title' => 'Mon premier article', 'title' => 'Mon premier article',
'userId' => '', 'userId' => '', // Géré au moment de l'installation
// Géré au moment de l'installation
'editConsent' => 'all', 'editConsent' => 'all',
'commentMaxlength' => '500', 'commentMaxlength' => '500',
'commentApproved' => false, 'commentApproved' => false,
'commentClose' => false, 'commentClose' => false,
'commentNotification' => false, 'commentNotification' => false,
'commentGroupNotification' => 1 'commentGroupNotification' => 1
], ],
'mon-deuxieme-article' => [ 'mon-deuxieme-article' => [
'closeComment' => false, 'closeComment' => false,
@ -1319,17 +875,17 @@ class init extends common
'hidePicture' => false, 'hidePicture' => false,
'picturePosition' => 'right', 'picturePosition' => 'right',
'pictureSize' => 40, 'pictureSize' => 40,
'picturePosition' => 'right',
'publishedOn' => 1550432502, 'publishedOn' => 1550432502,
'state' => true, 'state' => true,
'title' => 'Mon deuxième article', 'title' => 'Mon deuxième article',
'userId' => '', 'userId' => '', // Géré au moment de l'installation
// Géré au moment de l'installation
'editConsent' => 'all', 'editConsent' => 'all',
'commentMaxlength' => '500', 'commentMaxlength' => '500',
'commentApproved' => false, 'commentApproved' => false,
'commentClose' => false, 'commentClose' => false,
'commentNotification' => false, 'commentNotification' => false,
'commentGroupNotification' => 1 'commentGroupNotification' => 1
], ],
'mon-troisieme-article' => [ 'mon-troisieme-article' => [
'closeComment' => true, 'closeComment' => true,
@ -1339,17 +895,17 @@ class init extends common
'hidePicture' => false, 'hidePicture' => false,
'picturePosition' => 'left', 'picturePosition' => 'left',
'pictureSize' => 100, 'pictureSize' => 100,
'picturePosition' => 'left',
'publishedOn' => 1550864502, 'publishedOn' => 1550864502,
'state' => true, 'state' => true,
'title' => 'Mon troisième article', 'title' => 'Mon troisième article',
'userId' => '', 'userId' => '', // Géré au moment de l'installation
// Géré au moment de l'installation
'editConsent' => 'all', 'editConsent' => 'all',
'commentMaxlength' => '500', 'commentMaxlength' => '500',
'commentApproved' => false, 'commentApproved' => false,
'commentClose' => false, 'commentClose' => false,
'commentNotification' => false, 'commentNotification' => false,
'commentGroupNotification' => 1 'commentGroupNotification' => 1
], ],
], ],
], ],
@ -1399,24 +955,24 @@ class init extends common
], ],
], ],
'theme' => [ 'theme' => [
'thumbAlign' => 'center', 'thumbAlign' => 'center',
'thumbWidth' => '18em', 'thumbWidth' => '18em',
'thumbHeight' => '15em', 'thumbHeight' => '15em',
'thumbMargin' => '.5em', 'thumbMargin' => '.5em',
'thumbBorder' => '.1em', 'thumbBorder' => '.1em',
'thumbOpacity' => '.7', 'thumbOpacity' => '.7',
'thumbBorderColor' => 'rgba(221, 221, 221, 1)', 'thumbBorderColor' => 'rgba(221, 221, 221, 1)',
'thumbRadius' => '.3em', 'thumbRadius' => '.3em',
'thumbShadows' => '1px 1px 10px', 'thumbShadows' => '1px 1px 10px',
'thumbShadowsColor' => 'rgba(125, 125, 125, 1)', 'thumbShadowsColor' => 'rgba(125, 125, 125, 1)',
'legendHeight' => '.375em', 'legendHeight' => '.375em',
'legendAlign' => 'center', 'legendAlign' => 'center',
'legendTextColor' => 'rgba(255, 255, 255, 1)', 'legendTextColor' => 'rgba(255, 255, 255, 1)',
'legendBgColor' => 'rgba(0, 0, 0, .6)', 'legendBgColor' => 'rgba(0, 0, 0, .6)',
'style' => 'site/data/modules/gallery/galeries.css' 'style' => 'site/data/modules/gallery/galeries.css'
], ],
'config' => [ 'config' => [
'versionData' => '3.0' 'versionData' => '3.0'
], ],
], ],
'site-de-zwii' => [ 'site-de-zwii' => [
@ -1464,20 +1020,9 @@ class init extends common
'page404' => 'none', 'page404' => 'none',
'legalPageId' => 'none', 'legalPageId' => 'none',
'searchPageId' => 'none', 'searchPageId' => 'none',
'poweredPageLabel' => 'Motorisé par',
'searchPageLabel' => 'Rechercher',
'sitemapPageLabel' => 'Plan du site',
'legalPageLabel' => 'Mentions légales',
'metaDescription' => 'Zwii est un CMS sans base de données qui permet de créer et gérer facilement un site web sans aucune connaissance en programmation.', 'metaDescription' => 'Zwii est un CMS sans base de données qui permet de créer et gérer facilement un site web sans aucune connaissance en programmation.',
'title' => 'Votre site en quelques clics !', 'title' => 'Votre site en quelques clics !'
'cookies' => [ ]
'mainLabel' => 'Ce site utilise des cookies nécessaires à son fonctionnement, ils permettent de fluidifier son fonctionnement par exemple en mémorisant les données de connexion, la langue que vous avez choisie ou la validation de ce message.',
'titleLabel' => 'Cookies essentiels',
'linkLegalLabel' => 'Consulter les mentions légales',
'cookiesFooterText' => 'Cookies',
'buttonValidLabel' => 'J\'ai compris'
]
],
]; ];
public static $siteContent = [ public static $siteContent = [
@ -1596,4 +1141,4 @@ class init extends common
'content' => '<h1>Rechercher dans le site</h1>' 'content' => '<h1>Rechercher dans le site</h1>'
] ]
]; ];
} }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,693 +1,2 @@
{ {
"'Ne pas afficher' crée une page orpheline non accessible par le biais des menus.": "",
"'Sauvegarder et télécharger les données du module": "",
"1 jour": "",
"1/4 : Préparation...": "",
"10 minutes": "",
"10 tentatives": "",
"14 jours": "",
"15 minutes": "",
"2 jours": "",
"2/4 : Téléchargement...": "",
"3 tentatives": "",
"3/4 : Installation...": "",
"4 jours": "",
"4/4 : Configuration...": "",
"5 minutes": "",
"5 tentatives": "",
"7 jours": "",
"Accueil": "",
"Accède au site": "",
"Accède aux pages réservées": "",
"Accède aux pages réservées et à un dossier partagé": "",
"Accès bloqué %d minutes": "",
"Accès désactivé": "",
"Accès interdit, erreur 403": "",
"Action interdite": "",
"Activation obligatoire selon les lois françaises sauf si vous utilisez votre propre système de consentement.": "",
"Activer": "",
"Activer la journalisation": "",
"Actualiser": "",
"Adaptation": "",
"Administrateur": "",
"Administration": "",
"Adresse SMTP": "",
"Adresse du proxy": "",
"Adresse électronique": "",
"Affectation": "",
"Affiche le nom de la page parente suivi du nom de la page, le titre ne doit pas être masqué.": "",
"Affiche les icônes de gestion du compte et de déconnexion des membres simples connectés": "",
"Afin d'assurer le bon fonctionnement de Zwii, veuillez ne pas fermer cette page avant la fin de l'opération.": "",
"Aide": "",
"Ajouter": "",
"Ajouter un profil": "",
"Ajouter un utilisateur": "",
"Ajouter une fonte": "",
"Alignement": "",
"Aligner la bannière avec le contenu": "",
"Ancien mot de passe": "",
"Anonymat des adresses IP": "",
"Apache URL intelligent": "",
"Apache URL intelligentes": "",
"Apparence": "",
"Appliquer": "",
"Approuver un commentaire": "",
"Après": "",
"Après la bannière": "",
"Après le contenu de la page": "",
"Archive": "",
"Archive ZIP": "",
"Archive copiée dans le dossier Modules du gestionnaire de fichier": "",
"Archive de thème invalide": "",
"Archive invalide": "",
"Archive invalide, l'écriture dans le dossier core est interdite": "",
"Archive invalide, le descripteur est absent": "",
"Archive invalide, le fichier de classe est absent": "",
"Archive invalide, les dossiers ne correspondent pas au descripteur": "",
"Archive non spécifiée ou introuvable": "",
"Archive à restaurer": "",
"Arrière plan": "",
"Arrière plan des blocs": "",
"Arrière plan des champs": "",
"Arrondi des angles": "",
"Au centre": "",
"Au début": "",
"Au milieu au centre": "",
"Au milieu à droite": "",
"Au milieu à gauche": "",
"Au-dessus du site": "",
"Aucun": "",
"Aucun dossier": "",
"Aucun fichier journal à télécharger": "",
"Aucun journal à effacer": "",
"Aucun menu": "",
"Aucune": "",
"Aucune liste noire à effacer": "",
"Aucune liste noire à télécharger": "",
"Auteur :": "",
"Authentification": "",
"Automatique": "",
"Autoriser les robots à référencer le site": "",
"Autorisé": "",
"Avant la bannière": "",
"Avant le contenu de la page": "",
"Background": "",
"Banni": "",
"Bannière": "",
"Bannière cliquable": "",
"Barre 1/3 - page 2/3": "",
"Barre 1/4 - page 1/2 - barre 1/4": "",
"Barre 1/4 - page 3/4": "",
"Barre 2/12 - page 7/12 - barre 3/12": "",
"Barre 3/12 - page 7/12 - barre 2/12": "",
"Barre de membre": "",
"Barre latérale": "",
"Barre latérale droite :": "",
"Barre latérale gauche :": "",
"Barres latérales": "",
"Bienvenue %s %s": "",
"Blocage après échecs": "",
"Blog": "",
"Bords arrondis": "",
"Bordure des blocs": "",
"Bordure des champs": "",
"Bouton Aide": "",
"Bouton Standard": "",
"Bouton de validation": "",
"Bouton effacement": "",
"Bouton retour": "",
"Bouton standard": "",
"Bouton validation": "",
"Boutons": "",
"Caché": "",
"Cachée": "",
"Captcha complexe": "",
"Captcha à la connexion": "",
"Captcha, identifiant ou mot de passe incorrects": "",
"Capture d'écran Open Graph": "",
"Capture d'écran générée avec succès": "",
"Casse": "",
"Catalogue": "",
"Catégorie": "",
"Ce membre pourra téléverser ou télécharger des fichiers dans le dossier 'partage' et ses sous-dossiers": "",
"Cette page ne doit pas apparaître dans l'arborescence du menu. Créez une page orpheline.": "",
"Cette redirection ne concerne que les pages d'administration du site.": "",
"Chaîne Youtube": "",
"Chiffres": "",
"Cible": "",
"Cliquez sur une zone afin d'accéder à ses options de personnalisation.": "",
"Commentaire": "",
"Complète": "",
"Compte administrateur": "",
"Compte de l'utilisateur": "",
"Compte verrouillé": "",
"Configuration": "",
"Configuration du module": "",
"Configurer": "",
"Configurer mon compte": "",
"Confirmation": "",
"Confirmer la suppression de cet utilisateur": "",
"Confirmer la dissociation du module de cette page": "",
"Confirmer la désinstallation du module": "",
"Confirmer la suppression de cet utilisateur": "",
"Confirmer la suppression de cette langue": "",
"Confirmer la suppression de la page": "",
"Confirmer la suppression des données du module": "",
"Confirmez-vous la suppression de cette page ?": "",
"Connexion": "",
"Consulter l'aide en ligne": "",
"Contents": "",
"Contenu": "",
"Contenu HTML": "",
"Contenu avancé": "",
"Contenu du menu vertical": "",
"Contrôle total": "",
"Cookies": "",
"Cookies Zwii": "",
"Copie de contenus localisés": "",
"Copie de sites inter-langues": "",
"Copie des traductions rédigées": "",
"Copie terminée avec des erreurs": "",
"Copie terminée avec succès": "",
"Copier": "",
"Copier sauvegardes auto": "",
"Couleur de fond automatique": "",
"Couleur icône haut de page": "",
"Couleur texte page active": "",
"Couleur unie ou papier-peint": "",
"Couleur visible en l'absence d'une image.<br />Le curseur horizontal règle le niveau de transparence.": "",
"Couleur visible en l'absence d'une image.<br />Le curseur horizontal règle le niveau de transparence. La couleur du texte est automatique.": "",
"Couleurs": "",
"Dans le site": "",
"Dans quelle langue utiliserez-vous Zwii ?": "",
"Date": "",
"Description": "",
"Disponible si le consentement des cookies est activé.": "",
"Disposition": "",
"Données %s copiées vers %s": "",
"Données des modules": "",
"Données importées": "",
"Dossier": "",
"Droits sur les dossiers": "",
"Droits sur les fichiers": "",
"Dupliquer": "",
"Dupliquer la page": "",
"Déconnecte les sessions ouvertes précédemment sur d'autres navigateurs ou terminaux. Activation recommandée.": "",
"Déconnecter": "",
"Déconnexion !": "",
"Déconnexion automatique": "",
"Définir par défaut": "",
"Dévoiler le mot de passe": "",
"Effacer": "",
"Effacer la page": "",
"Effacer tous les commentaires": "",
"Effacer toutes les statistiques": "",
"Effacer un commentaire": "",
"Effacer une catégorie": "",
"Emplacement :": "",
"Emplacement dans le menu": "",
"En bas au centre": "",
"En bas à droite": "",
"En bas à gauche": "",
"En cas de changement de module, les données du module précédent seront supprimées.": "",
"En dessous du site": "",
"En haut au centre": "",
"En haut à droite": "",
"En haut à gauche": "",
"En position libre ajoutez le module en plaçant [MODULE] à l'endroit voulu dans votre page.": "",
"En-dehors du site": "",
"Enregistrer": "",
"Envoyer un message de confirmation": "",
"Erreur : sauvegarde non générée !": "",
"Erreur d'URL": "",
"Erreur d'extraction, vérifiez les permissions": "",
"Erreur de copie": "",
"Erreur de copie, vérifiez les permissions": "",
"Erreur de lecture, vérifiez les permissions": "",
"Erreur inconnue": "",
"Erreur inconnue, le module n'est pas installé": "",
"Export CSV": "",
"Expéditeur": "",
"Extension": "",
"Extraire": "",
"Facebook": "",
"Famille": "",
"Favicon thème sombre": "",
"Feuille de style spécifique à la page.": "",
"Fichiers": "",
"Fichiers effacés": "",
"Fil d'Ariane dans le titre": "",
"Fond du sous-menu": "",
"FontId": "",
"Fonte": "",
"Fonte actualisée": "",
"Fonte créée": "",
"Fonte en ligne": "",
"Fonte installée": "",
"Fonte non créée, ressource absente !": "",
"Fonte supprimée": "",
"Fontes": "",
"Format incorrect": "",
"Formulaire": "",
"Fréquence de recherche": "",
"Fuseau horaire": "",
"Gabarits de page - Barre latérale": "",
"Gestion": "",
"Gestion des modules": "",
"Gestion des thèmes": "",
"Gestionnaire de fichiers": "",
"Github": "",
"Grande": "",
"Grande (220%)": "",
"Grande (300px)": "",
"Gras": "",
"Groupe": "",
"Groupe associé": "",
"Groupe requis pour accéder à la page :": "",
"Groupes": "",
"Générer sitemap.xml et robots.txt": "",
"Générer une capture Open Graph": "",
"Gérer les catégories": "",
"Gérer les commentaires": "",
"Gérer les données": "",
"Hauteur": "",
"Hauteur de l'image": "",
"Hauteur de l'image sélectionnée": "",
"Hauteur maximale": "",
"ID de la chaîne : https://www.youtube.com/channel/[ID].": "",
"Icône": "",
"Icône avec bulle de texte": "",
"Icône haut de page, couleur arrière-plan": "",
"Identifiant": "",
"Identifiant (sans espace ni majuscule)": "",
"Identité": "",
"Identité de la fonte": "",
"Identité du site": "",
"Il apparaît dans la barre de titre et les partages sur les réseaux sociaux.": "",
"Image": "",
"Image étirée (100% 100%)": "",
"Important": "",
"Importante": "",
"Importation d'utilisateurs": "",
"Importation de fichier plat CSV": "",
"Importation effectuée": "",
"Importer": "",
"Importer dans": "",
"Importer des utilisateurs en masse": "",
"Impossible d'ouvrir l'archive": "",
"Impossible de modifier votre propre groupe.": "",
"Impossible de soumettre le formulaire, car il contient des erreurs": "",
"Impossible de supprimer une page contenant des pages enfants": "",
"Impossible de supprimer votre propre compte": "",
"Inclure le contenu du gestionnaire de fichiers": "",
"Incorrect": "",
"Informations": "",
"Instagram": "",
"Installation terminée": "",
"Installer": "",
"Installer depuis le catalogue en ligne": "",
"Installer depuis une archive": "",
"Installer les données d'un module": "",
"Installer ou mettre à jour un module téléchargé": "",
"Installer un module": "",
"Installer un thème archivé (site ou administration)": "",
"Instructions JS ou jquery spécifiques à la page.": "",
"Interface": "",
"Jeton invalide": "",
"Journal réinitialisé avec succès": "",
"Journalisation": "",
"L'archive a été déposée dans le gestionnaire de fichiers. Les archives inférieures à la version 9 ne sont pas acceptées.": "",
"L'identifiant est défini lors de la création du compte, il ne peut pas être modifié.": "",
"La carte du site a été mise à jour": "",
"La copie de sauvegarde du fichier htaccess n'a pas été restaurée !": "",
"La description d'une page participe à son référencement, chaque page doit disposer d'une description différente.": "",
"La page %s est ouverte par l'utilisateur %s": "",
"La page demandée n'existe pas ou est introuvable (erreur 404)": "",
"La page est affichée dans un menu horizontal mais pas dans le menu vertical d'une barre latérale.": "",
"La première page que vos visiteurs verront.": "",
"La règlementation française impose un anonymat de niveau 2": "",
"La réécriture d'URL n'a pas été restaurée !": "",
"La sauvegarde des fichiers peut prendre du temps. Continuer ?": "",
"La suppression a échoué": "",
"La version installée est plus récente": "",
"La vérification est quotidienne. Option désactivée si la configuration du serveur ne le permet pas.": "",
"Langue de l'administration": "",
"Langue du site par défaut": "",
"Langue par défaut": "",
"Langues": "",
"Langues disponibles": "",
"Langues installées": "",
"Largeur": "",
"Largeur de l'image": "",
"Largeur du site": "",
"Le curseur horizontal règle le niveau de transparence, le placer tout à la gauche pour un surlignement invisible.": "",
"Le curseur horizontal règle le niveau de transparence.": "",
"Le fuseau horaire est utile au bon référencement": "",
"Le menu accessoire est aligné à droite de la barre de menu, c'est un emplacement réservé aux drapeaux et au bouton de connexion.": "",
"Le menu horizontal intégral": "",
"Le module %s a été %s": "",
"Le module %s de la page %s a été supprimé": "",
"Le module %s est désinstallé, il reste peut-être des données dans %s": "",
"Le sous-menu de la page parente": "",
"Le survol d'une icône de l'écran de connexion affiche temporairement le mot de passe.": "",
"Le titre court est affiché dans les menus. Il peut être identique au titre de la page.": "",
"Les langues sélectionnées sont identiques": "",
"Les mentions légales sont obligatoires en France. Une option du pied de page ajoute un lien discret vers cette page.": "",
"Les modifications que vous avez apportées ne seront peut-être pas enregistrées.": "",
"Les tailles des polices de la bannière, de menu et de pied de page sont proportionnelles à cette taille.": "",
"Lettres": "",
"Libre": "",
"Licence :": "",
"Lien de connexion": "",
"Lien page des mentions légales.": "",
"Liens": "",
"Limitation des tentatives": "",
"Limitée au site": "",
"Linkedin": "",
"Liste noire": "",
"Liste noire réinitialisée avec succès": "",
"Lors d'une mise à jour automatique, conserve le fichier htaccess de la racine du site.": "",
"Léger": "",
"Légère": "",
"Maigre": "",
"Maintenance": "",
"Majuscule à chaque mot": "",
"Majuscules": "",
"Marges verticales": "",
"Masquer la bannière en écran réduit": "",
"Masquer la page et les pages enfants dans le menu d'une barre latérale": "",
"Masquer les pages enfants dans le menu horizontal": "",
"Membre": "",
"Membre avec droit de partage": "",
"Membre simple": "",
"Mentions légales": "",
"Menu": "",
"Menu accessoire": "",
"Menu burger dans écran réduit": "",
"Menu standard": "",
"Message d'acceptation des Cookies": "",
"Message de consentement aux cookies": "",
"Mettre à jour": "",
"Mettre à jour le module orphelin": "",
"Minuscules": "",
"Mise en forme des titres": "",
"Mise en forme du texte": "",
"Mise en forme du titre": "",
"Mise en page": "",
"Mise à jour": "",
"Mise à jour automatisée": "",
"Mise à jour terminée avec succès.": "",
"Modifications enregistrées": "",
"Module": "",
"Module de la page": "",
"Modules": "",
"Modules configurés": "",
"Modules installés": "",
"Modules orphelins": "",
"Mot de passe": "",
"Mot de passe oublié": "",
"Mot de passe perdu": "",
"Motorisé par": "",
"Moyen": "",
"Moyenne": "",
"Moyenne (200%)": "",
"Moyenne (200px)": "",
"Méta-description": "",
"Méta-titre": "",
"Ne pas afficher": "",
"Ne pas charger l'exemple de site (utilisateurs avancés)": "",
"Ne pas répéter": "",
"Ne pas saisir les balises": "",
"News": "",
"Niveau 1 (192.168.12.x)": "",
"Niveau 2 (192.168.x.x)": "",
"Niveau 3 (192.x.x.x)": "",
"Nom": "",
"Nom Prénom": "",
"Nom du profil": "",
"Nom utilisateur": "",
"Non": "",
"Non tronquée": "",
"Notre site est actuellement en maintenance. Nous sommes désolés pour la gêne occasionnée et faisons notre possible pour être rapidement de retour.": "",
"Nouveau contenu localisé": "",
"Nouveau mot de passe": "",
"Nouveau mot de passe enregistré": "",
"Nouvel utilisateur": "",
"Nouvelle page créée": "",
"Nouvelle page ou barre latérale": "",
"Obligatoire": "",
"Ombre": "",
"Option active en mode déconnecté uniquement, les pages enfants sont visibles et accessibles.": "",
"Option recommandée pour sécuriser la connexion. S'applique à tous les captchas du site. Le captcha simple se limite à une addition de nombres de 0 à 10. Le captcha complexe utilise quatre opérations de nombres de 0 à 20. Activation recommandée.": "",
"Options": "",
"Options avancées": "",
"Origine": "",
"Oui": "",
"Page": "",
"Page 2/3 - barre 1/3": "",
"Page 3/4 - barre 1/4": "",
"Page associée": "",
"Page de recherche": "",
"Page dupliquée": "",
"Page et module dupliqués": "",
"Page inexistante, erreur 404": "",
"Page non cliquable": "",
"Page parent": "",
"Page standard": "",
"Page supprimée": "",
"Pages dans le menu": "",
"Pages du site": "",
"Pages et les modules de": "",
"Pages orphelines": "",
"Papier peint": "",
"Par défaut le menu est affiché APRES le contenu de la page. Pour le positionner à un emplacement précis, insérez [MENU] dans le contenu de la page.": "",
"Paramètres": "",
"Paramètres de la localisation": "",
"Paramètres de la sauvegarde": "",
"Paramètres du profil": "",
"Paramètres à utiliser lorsque votre hébergeur ne propose pas la fonctionnalité d'envoi de mail.": "",
"Pas de marge au-dessus et en dessous du site": "",
"Pensez à supprimer le cache de votre navigateur si la favicon ne change pas.": "",
"Permission": "",
"Permission et référencement": "",
"Permissions": "",
"Permissions sur les dossiers": "",
"Permissions sur les fichiers": "",
"Permissions sur les pages": "",
"Petite": "",
"Petite (150px)": "",
"Petite (180%)": "",
"Pied de page": "",
"Pinterest": "",
"Plan du site": "",
"Police des titres": "",
"Police du texte": "",
"Port SMTP": "",
"Port du proxy": "",
"Position": "",
"Position du module": "",
"Pour définir la page comme barre latérale, choisissez l'option dans la liste.": "",
"Presse Papier": "",
"Presse papier": "",
"Profils des groupes": "",
"Proportionnelle à la taille définie dans le site.": "",
"Prénom": "",
"Prénom Nom": "",
"Préparation de la mise à jour": "",
"Préserver le fichier htaccess racine": "",
"Préserver les comptes des utilisateurs déjà installés": "",
"Prévenir l'utilisateur par mail": "",
"Prévisualiser": "",
"Pseudo": "",
"Rang 9 > rang 1. Le profil de rang 1 n'est pas modifiable.": "",
"Ratio": "",
"Ratio :": "",
"Recherche": "",
"Recherche dans le site": "",
"Rechercher": "",
"Rechercher une mise à jour en ligne": "",
"Redirection": "",
"Redirection vers la connexion": "",
"Renommer": "",
"Renseignez les champs ci-dessous pour finaliser l'installation.": "",
"Responsive (contain)": "",
"Responsive (cover)": "",
"Restauration des bases de données absentes": "",
"Restauration effectuée avec succès": "",
"Restaurer": "",
"Restaurer les données du site": "",
"Rester connecté sur ce navigateur": "",
"Retour": "",
"Rien à importer, erreur de format ou fichier incorrect": "",
"Rédacteur": "",
"Référencement": "",
"Réinitialisation du mot de passe": "",
"Réinitialiser avec le thème par défaut": "",
"Réinitialiser la feuille de style": "",
"Réinitialiser la liste": "",
"Réinitialiser le journal": "",
"Réinstaller": "",
"Répétition": "",
"Réseau": "",
"Réseaux sociaux": "",
"S'ouvre dans un nouvel onglet": "",
"SMTP": "",
"SMTP personnalisé": "",
"Saisir la clé, puis valider le formulaire avant de cliquer sur le bouton de génération": "",
"Saisissez le Titre de gestion des cookies.": "",
"Saisissez le message pour les cookies déposés par ZwiiCMS, nécessaires au fonctionnement et qui ne nécessitent pas de consentement.": "",
"Saisissez le texte du lien vers les mentions légales,la page doit être définie dans la configuration du site.": "",
"Saisissez votre ID : https://pinterest.com/[ID].": "",
"Saisissez votre ID : https://twitter.com/[ID].": "",
"Saisissez votre ID : https://www.facebook.com/[ID].": "",
"Saisissez votre ID : https://www.instagram.com/[ID].": "",
"Saisissez votre ID Github : https://github.com/[ID].": "",
"Saisissez votre ID Linkedin : https://fr.linkedin.com/in/[ID].": "",
"Saisissez votre ID Utilisateur : https://www.youtube.com/user/[ID].": "",
"Sauvegarde": "",
"Sauvegarde automatique quotidienne du site": "",
"Sauvegarde du thème dans le": "",
"Sauvegarde générée avec succès": "",
"Sauvegarder": "",
"Sauvegarder et télécharger le module": "",
"Sauvegarder le module dans le gestionnaire de fichiers": "",
"Sauvegarder les données du module dans le gestionnaire de fichiers": "",
"Sauvegarder les données du site": "",
"Script dans body": "",
"Script dans head": "",
"Scripts externes": "",
"Se déconnecter": "",
"Service en ligne inaccessible": "",
"Seul un administrateur peut se connecter lors d'une maintenance": "",
"Si le contenu du gestionnaire de fichiers est très volumineux, mieux vaut une copie par FTP.": "",
"Signature": "",
"Site": "",
"Site en maintenance": "",
"Size": "",
"Source": "",
"Standard": "",
"Style": "",
"Suppression interdite": "",
"Suppression interdite, page active dans la configuration de la langue du site": "",
"Supprime le point d'interrogation dans les URL, l'option est indisponible avec les autres serveurs Web": "",
"Supprimer": "",
"Supprimer la page": "",
"Supprimer le module": "",
"Supprimer toutes les sauvegardes automatiques ?": "",
"Sur l'axe horizontal": "",
"Sur l'axe vertical": "",
"Sur les deux axes": "",
"Sécurité": "",
"Sécurité de la connexion": "",
"Sécurité désactivée": "",
"Sélectionner un fichier": "",
"Sélectionnez au moins un contenu à afficher": "",
"Sélectionnez la langue à copier vers une langue cible": "",
"Sélectionnez une icône adaptée à un thème sombre.<br>Pensez à supprimer le cache de votre navigateur si la favicon ne change pas.": "",
"Sélectionnez une image ou une icône de petite dimension": "",
"Sélectionnez une langue": "",
"Sélectionnez une page contenant le module 'Recherche'. Une option du pied de page ajoute un lien discret vers cette page.": "",
"Sélectionnez une page pour activer": "",
"Séparateur": "",
"Taille": "",
"Text": "",
"Texte": "",
"Thème": "",
"Thème de l'administration": "",
"Thème du site": "",
"Thème importé": "",
"Thèmes": "",
"Titre": "",
"Titre court": "",
"Titre masqué": "",
"Titre masqué dans la page": "",
"Titres": "",
"Tous les dossiers": "",
"Tous les droits d'édition des contenus": "",
"Tout Effacer": "",
"Traduction supprimée": "",
"Très grande": "",
"Très grande (240%)": "",
"Très grande (400px)": "",
"Très important": "",
"Très importante": "",
"Très léger": "",
"Très légère": "",
"Très petite": "",
"Très petite (100px) ": "",
"Très petite (160%)": "",
"Twitter": "",
"Type de captcha": "",
"Type de proxy": "",
"Téléchargement et validation de l'archive": "",
"Télécharger": "",
"Télécharger la liste": "",
"Télécharger le journal": "",
"Télécharger le module dans le gestionnaire de fichiers": "",
"Téléverser": "",
"URL incorrecte": "",
"Un mail a été envoyé pour confirmer la réinitialisation": "",
"Une archive du dossier /site/data est conservée pendant 30 jours. Activation recommandée": "",
"Une erreur est survenue lors de l'étape :": "",
"Url du fichier de fonte": "",
"Utilisateur inexistant": "",
"Utilisateur supprimé": "",
"Utilisateurs": "",
"Valider": "",
"Version": "",
"Version n°": "",
"Vider dossier sauvegardes auto": "",
"Visiteur": "",
"Vous n'êtes pas autorisé à consulter cette page (erreur 403)": "",
"Youtube": "",
"ZwiiCMS - Installation": "",
"actualisé": "",
"favicon.ico": "",
"faviconDark.ico": "",
"gestionnaire de fichiers": "",
"installé": "",
"jour": "",
"jours": "",
"sauvegardé avec succès": "",
"vers": "",
"À droite": "",
"À gauche": "",
"À l'emplacement du mot clé [MODULE] dans la page": "",
"Échec de l'écriture, vérifiez les permissions": "",
"Échecs": "",
"Éditer": "",
"Éditer la page": "",
"Éditer les dialogues": "",
"Éditer une catégorie": "",
"Éditeur": "",
"Éditeur CSS": "",
"Éditeur JS": "",
"Éditeur de script %s": "",
"Éditeur de script dans Body": "",
"Éditeur de script dans Head": "",
"Éditeur simple": "",
"Édition des pages": "",
"Édition du profil %s": "",
"Éléments": "",
"Étendu sur la page": "",
"Étiquettes des pages spéciales": "",
"Dimensions minimales": "",
"Taille maximale du fichier": "",
"5 Mo pour les images JPEG": "",
"1 Mo pour les images PNG": "",
"Poids": "",
"Supprimer ce profil ?": "",
"Masqué": "",
"Haut de page": "",
"Bas de page": "",
"Petit triangle": "",
"Grand triangle": "",
"Flèche": "",
"Modèle": "",
"Bouton de navigation droit": "",
"Bouton de navigation gauche": "",
"Groupes / Profils": "",
"Prénom commence par": "",
"Nom commence par": "",
"Impossible de réinitialiser le mot de passe de ce compte !": ""
} }

View File

@ -0,0 +1,16 @@
{
"languages": {
"fr_FR": {
"version": 12300,
"date": 1677838293
},
"es": {
"version": 12300,
"date": 1677838293
},
"en_EN": {
"version": 12300,
"date": 1677838293
}
}
}

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

@ -1,22 +1 @@
/** /* Vide */
* 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
*/
.title {
font-weight: bold;
}

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

@ -2,77 +2,71 @@
<?php echo helper::translate('Renseignez les champs ci-dessous pour finaliser l\'installation.'); ?> <?php echo helper::translate('Renseignez les champs ci-dessous pour finaliser l\'installation.'); ?>
</p> </p>
<?php echo template::formOpen('installForm'); ?> <?php echo template::formOpen('installForm'); ?>
<div class="row"> <h3>
<div class="col12"> <?php echo helper::translate('Compte administrateur'); ?>
<details open> </h3>
<summary> <div>
<span class="title"> <div class="row">
<?php echo helper::translate('Compte administrateur'); ?> <div class="col12">
</span> <?php echo template::text('installId', [
</summary> 'autocomplete' => 'off',
<div class="row"> 'label' => 'Identifiant'
<div class="col6"> ]); ?>
<?php echo template::text('installFirstname', [ </div>
'autocomplete' => 'off', </div>
'label' => 'Prénom' <div class="row">
]); ?> <div class="col6">
</div> <?php echo template::password('installPassword', [
<div class="col6"> 'autocomplete' => 'off',
<?php echo template::text('installLastname', [ 'label' => 'Mot de passe'
'autocomplete' => 'off', ]); ?>
'label' => 'Nom' </div>
]); ?> <div class="col6">
</div> <?php echo template::password('installConfirmPassword', [
</div> 'autocomplete' => 'off',
<div class="row"> 'label' => 'Confirmation'
<div class="col6"> ]); ?>
<?php echo template::text('installId', [ </div>
'autocomplete' => 'off', </div>
'label' => 'Identifiant' <div class="row">
]); ?> <div class="col12">
</div> <?php echo template::mail('installMail', [
<div class="col6"> 'autocomplete' => 'off',
<?php echo template::mail('installMail', [ 'label' => 'Adresse électronique'
'autocomplete' => 'off', ]); ?>
'label' => 'Adresse électronique' </div>
]); ?> </div>
</div> <div class="row">
</div> <div class="col6">
<div class="row"> <?php echo template::text('installFirstname', [
<div class="col6"> 'autocomplete' => 'off',
<?php echo template::password('installPassword', [ 'label' => 'Prénom'
'autocomplete' => 'off', ]); ?>
'label' => 'Mot de passe' </div>
]); ?> <div class="col6">
</div> <?php echo template::text('installLastname', [
<div class="col6"> 'autocomplete' => 'off',
<?php echo template::password('installConfirmPassword', [ 'label' => 'Nom'
'autocomplete' => 'off', ]); ?>
'label' => 'Confirmation' </div>
]); ?>
</div>
</div>
</details>
</div> </div>
</div> </div>
<div class="row"> <ul class="accordion" data-speed="150">
<div class="col12"> <li class="accordion-item">
<details close> <h3 class="accordion-title">
<summary> <?php echo '&#9655; ' . helper::translate('Options avancées'); ?>
<span class="title"> </h3>
<?php echo helper::translate('Options avancées'); ?> <div class="accordion-content">
</span> <?php if ($this->getUrl(2) === 'fr_FR'): ?>
</summary> <div class="row">
<?php if ($_SESSION['ZWII_UI'] === 'fr_FR'): ?> <div class="col12">
<div class="row"> <?php echo template::checkbox('installDefaultData', true, 'Ne pas charger l\'exemple de site (utilisateurs avancés)', [
<div class="col12"> 'checked' => false
<?php echo template::checkbox('installDefaultData', true, 'Ne pas charger l\'exemple de site (utilisateurs avancés)', [ ]);
'checked' => false ?>
]);
?>
</div>
</div> </div>
<?php endif; ?> </div>
<?php endif;?>
<div class="row"> <div class="row">
<div class="col3"> <div class="col3">
<?php echo template::select('installProxyType', $module::$proxyType, [ <?php echo template::select('installProxyType', $module::$proxyType, [
@ -94,14 +88,18 @@
</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)
]); ?> ]); ?>
</div> </div>
</div> </div>
</div> </div>
</div> </li>
</details> </ul>
<div class="row"> <div class="row">
<div class="col2"> <div class="col2">
<?php echo template::button('installPrevious', [ <?php echo template::button('installPrevious', [

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,9 +1,6 @@
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");
$.ajax({ $.ajax({
type: "POST", type: "POST",
url: "<?php echo helper::baseUrl(false); ?>?install/steps", url: "<?php echo helper::baseUrl(false); ?>?install/steps",
@ -12,10 +9,14 @@ function step(i, data) {
data: data data: data
}, },
success: function (result) { success: function (result) {
if (!result.success) { // 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();
$("body").css("cursor", "default");
$("#installUpdateEnd").removeClass("disabled"); $("#installUpdateEnd").removeClass("disabled");
$("#installUpdateProgress").hide(); $("#installUpdateProgress").hide();
} else { } else {
@ -24,50 +25,25 @@ function step(i, data) {
}), 2e3) }), 2e3)
}, },
error: function (xhr) { error: function (xhr) {
// Balance tout dans la console
console.log(i);
console.log(xhr.responseText);
console.log(errors);
// Appel de la fonction de gestion d'erreur // Appel de la fonction de gestion d'erreur
showError(i, xhr.responseText, errors); showError(1, xhr.responseText, errors);
} }
}); });
} }
function showError(step, message, errors) { function showError(step, message, errors) {
$("body").css("cursor", "default"); $("#installUpdateErrorStep").text(errors[step]);
$("#installUpdateErrorStep").text(errors[step] + " (étape n°" + step + ")");
$("#installUpdateError").show(); $("#installUpdateError").show();
$("#installUpdateEnd").removeClass("disabled"); $("#installUpdateEnd").removeClass("disabled");
$("#installUpdateProgress").hide(); $("#installUpdateProgress").hide();
if (typeof message === 'object' && message.data) {
// Vérifier si l'accolade ouvrante est trouvée et qu'elle n'est pas en première position var errorMessage = message.data.replace(/"/g, "");
if (typeof message !== 'object') { $("#installUpdateErrorMessage").text(errorMessage);
// Trouver la position du premier "{" pour repérer le début du tableau
const startOfArray = message.indexOf('{');
// Extraire le message du warning jusqu'au début du tableau
const warningMessage = message.substring(0, startOfArray).trim();
// Extraire le tableau JSON entre les accolades
const jsonString = message.substring(startOfArray);
const jsonData = JSON.parse(jsonString);
// Afficher les résultats
if (jsonData) {
$("#installUpdateErrorMessage").html("<strong>Détails de l'erreur :</strong><br> " +
jsonData.data.replace(/^"(.*)"$/, '$1') +
"<br>" +
warningMessage.replace(/<[^p].*?>/g, ""));
}
} else { } else {
// Vous pouvez également faire quelque chose d'autre ici, par exemple, afficher un message à l'utilisateur, etc. $("#installUpdateErrorMessage").text(message.replace(/<[^p].*?>/g, ""));
$("#installUpdateErrorMessage").html(message);
} }
} }
$(window).on("load", function () { $(window).on("load", function() {
step(1, null); step(1, null);
}); });

View File

@ -1,56 +1,55 @@
<div id="updateContainer"> <p><strong>
<p><strong> <?php echo helper::translate('Mise à jour de ZwiiCMS'); ?>
<?php echo helper::translate('Version'); ?> &nbsp;
&nbsp; <?php echo self::ZWII_VERSION; ?>
<?php echo self::ZWII_VERSION; ?> <?php echo helper::translate('vers ZwiiCMS'); ?>
<?php echo helper::translate('vers'); ?> &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.'); ?> </p>
</p> <div class="row">
<div class="row"> <div class="col9 verticalAlignMiddle">
<div class="col9 verticalAlignMiddle"> <div id="installUpdateProgress">
<div id="installUpdateProgress"> <?php echo template::ico('spin', ['animate' => true]); ?>
<?php echo template::ico('spin', ['animate' => true]); ?> <span class="installUpdateProgressText" data-id="1">
<span class="installUpdateProgressText" data-id="1"> <?php echo helper::translate('1/4 : Préparation...'); ?>
<?php echo helper::translate('1/4 : Préparation...'); ?> </span>
</span> <span class="installUpdateProgressText displayNone" data-id="2">
<span class="installUpdateProgressText displayNone" data-id="2"> <?php echo helper::translate('2/4 : Téléchargement...'); ?>
<?php echo helper::translate('2/4 : Téléchargement...'); ?> </span>
</span> <span class="installUpdateProgressText displayNone" data-id="3">
<span class="installUpdateProgressText displayNone" data-id="3"> <?php echo helper::translate('3/4 : Installation...'); ?>
<?php echo helper::translate('3/4 : Installation...'); ?> </span>
</span> <span class="installUpdateProgressText displayNone" data-id="4">
<span class="installUpdateProgressText displayNone" data-id="4"> <?php echo helper::translate('4/4 : Configuration...'); ?>
<?php echo helper::translate('4/4 : Configuration...'); ?> </span>
</span>
</div>
<div id="installUpdateError" class="message colorRed displayNone">
<?php echo template::ico('cancel'); ?>
<strong>
<?php echo helper::translate('Une erreur est survenue lors de l\'étape :') . '<br>'; ?>
<span id="installUpdateErrorStep"> </span>.
</strong>
</div>
<div id="installUpdateSuccess" class="message colorGreen displayNone">
<?php echo template::ico('check'); ?>
<?php echo helper::translate('Mise à jour terminée avec succès.'); ?>
</div>
</div> </div>
<div class="col3 verticalAlignTop"> <div id="installUpdateError" class="colorRed displayNone">
<?php echo template::button('installUpdateEnd', [ <?php echo template::ico('cancel'); ?>
'value' => 'Terminer', <strong>
'href' => helper::baseUrl() . 'config', <?php echo helper::translate('Une erreur est survenue lors de l\'étape :'); ?>
'ico' => 'check', &nbsp;
'class' => 'disabled' <span id="installUpdateErrorStep"> </span>.
]); ?> </strong>
</div>
<div id="installUpdateSuccess" class="colorGreen displayNone">
<?php echo template::ico('check'); ?>
<?php echo helper::translate('Mise à jour terminée avec succès.'); ?>
</div> </div>
</div> </div>
<div class="row"> <div class="col3 verticalAlignTop">
<div class="col12"> <?php echo template::button('installUpdateEnd', [
<p><em><span class="colorRed" id="installUpdateErrorMessage"></span></em></p> 'value' => 'Terminer',
</div> 'href' => helper::baseUrl() . 'config',
'ico' => 'check',
'class' => 'disabled'
]); ?>
</div> </div>
</div> </div>
<div class="row">
<div class="col12">
<p><em><span class="colorRed" id="installUpdateErrorMessage"></span></em></p>
</div>
</div

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/
*/ */
@ -18,12 +18,12 @@ class page extends common
{ {
public static $actions = [ public static $actions = [
'add' => self::GROUP_EDITOR, 'add' => self::GROUP_MODERATOR,
'delete' => self::GROUP_EDITOR, 'delete' => self::GROUP_MODERATOR,
'edit' => self::GROUP_EDITOR, 'edit' => self::GROUP_MODERATOR,
'duplicate' => self::GROUP_EDITOR, 'duplicate' => self::GROUP_MODERATOR,
'jsEditor' => self::GROUP_EDITOR, 'jsEditor' => self::GROUP_MODERATOR,
'cssEditor' => self::GROUP_EDITOR 'cssEditor' => self::GROUP_MODERATOR
]; ];
public static $pagesNoParentId = [ public static $pagesNoParentId = [
'' => 'Aucune' '' => 'Aucune'
@ -65,75 +65,62 @@ class page extends common
true => 'Menu accessoire' true => 'Menu accessoire'
]; ];
public static $userProfils = [];
public static $navIconTemplate = [
'dir' => 'Petit triangle',
'open' => 'Grand triangle',
'big' => 'Flèche',
];
public static $navIconPosition = [
'none' => 'Masqué',
'top' => 'Haut de page',
'bottom' => 'Bas de page',
];
/** /**
* Duplication * Duplication
*/ */
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); $url = explode('&', $this->getUrl(2));
// La page n'existe pas // La page n'existe pas
if ( if ($this->getData(['page', $url[0]]) === null) {
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true ||
$this->getData(['page', $page]) === null
) {
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'access' => false 'access' => false
]); ]);
} else { } // Jeton incorrect
// Duplication de la page elseif (!isset($_GET['csrf'])) {
$pageTitle = $this->getData(['page', $page, 'title']);
$pageId = helper::increment(helper::filter($pageTitle, helper::FILTER_ID), $this->getData(['page']));
$pageId = helper::increment($pageId, self::$coreModuleIds);
$pageId = helper::increment($pageId, self::$moduleIds);
$data = $this->getData([
'page',
$page
]);
// Ecriture
$this->setData(['page', $pageId, $data]);
$notification = helper::translate('Page dupliquée');
// Duplication du module présent
if ($this->getData(['page', $page, 'moduleId'])) {
$data = $this->getData(['module', $page]);
$this->setData(['module', $pageId, $data]);
$notification = helper::translate('Page et module dupliqués');
}
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $pageId . '/' . self::$siteContent, 'redirect' => helper::baseUrl() . 'page/edit/' . $url[0],
'notification' => $notification, 'notification' => helper::translate('Jeton invalide')
'state' => true ]);
} elseif ($_GET['csrf'] !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $url[0],
'notification' => helper::translate('Suppression interdite')
]); ]);
} }
// Duplication de la page
$pageTitle = $this->getData(['page', $url[0], 'title']);
$pageId = helper::increment(helper::filter($pageTitle, helper::FILTER_ID), $this->getData(['page']));
$pageId = helper::increment($pageId, self::$coreModuleIds);
$pageId = helper::increment($pageId, self::$moduleIds);
$data = $this->getData([
'page',
$url[0]
]);
// Ecriture
$this->setData(['page', $pageId, $data]);
$notification = helper::translate('Page dupliquée');
// Duplication du module présent
if ($this->getData(['page', $url[0], 'moduleId'])) {
$data = $this->getData([
'module',
$url[0]
]);
// Ecriture
$this->setData(['module', $pageId, $data]);
$notification = helper::translate('Page et module dupliqués');
}
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $pageId,
'notification' => $notification,
'state' => true
]);
} }
@ -142,76 +129,55 @@ class page extends common
*/ */
public function add() public function add()
{ {
// La session ne correspond pas au site ouvert dans cet onglet $pageTitle = 'Nouvelle page';
if ( $pageId = helper::increment(helper::filter($pageTitle, helper::FILTER_ID), $this->getData(['page']));
// 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->setData([
$this->getUrl(3) && $this->getUrl(3) != self::$siteContent 'page',
) { $pageId,
$_SESSION['ZWII_SITE_CONTENT'] = $this->getUrl(3); [
header('Refresh:0; url=' . helper::baseUrl() . $this->getUrl()); 'typeMenu' => 'text',
exit(); 'iconUrl' => '',
'disable' => false,
'content' => $pageId . '.html',
'hideTitle' => false,
'breadCrumb' => false,
'metaDescription' => '',
'metaTitle' => '',
'moduleId' => '',
'parentPageId' => '',
'modulePosition' => 'bottom',
'position' => 0,
'group' => self::GROUP_VISITOR,
'targetBlank' => false,
'title' => $pageTitle,
'shortTitle' => $pageTitle,
'block' => '12',
'barLeft' => '',
'barRight' => '',
'displayMenu' => '0',
'hideMenuSide' => false,
'hideMenuHead' => false,
'hideMenuChildren' => false,
'js' => '',
'css' => ''
]
]);
// Creation du contenu de la page
if (!is_dir(self::DATA_DIR . self::$i18nContent . '/content')) {
mkdir(self::DATA_DIR . self::$i18nContent . '/content', 0755);
} }
//file_put_contents(self::DATA_DIR . self::$i18nContent . '/content/' . $pageId . '.html', '<p>Contenu de votre nouvelle page.</p>');
$this->setPage($pageId, '<p>Contenu de votre nouvelle page.</p>', self::$i18nContent);
if ($this->getUser('permission', __CLASS__, __FUNCTION__) !== true) { // Met à jour le sitemap
// Valeurs en sortie $this->updateSitemap();
$this->addOutput([
'access' => false
]);
} else {
$pageTitle = 'Nouvelle page';
$pageId = helper::increment(helper::filter($pageTitle, helper::FILTER_ID), $this->getData(['page']));
$this->setData([
'page',
$pageId,
[
'typeMenu' => 'text',
'iconUrl' => '',
'disable' => false,
'content' => $pageId . '.html',
'hideTitle' => false,
'breadCrumb' => false,
'metaDescription' => '',
'metaTitle' => '',
'moduleId' => '',
'parentPageId' => '',
'modulePosition' => 'bottom',
'position' => 0,
'group' => self::GROUP_VISITOR,
'targetBlank' => false,
'title' => $pageTitle,
'shortTitle' => $pageTitle,
'block' => '12',
'barLeft' => '',
'barRight' => '',
'navLeft' => 'none',
'navRight' => 'none',
'navTemplate' => 'dir',
'displayMenu' => '0',
'hideMenuSide' => false,
'hideMenuHead' => false,
'hideMenuChildren' => false,
'js' => '',
'css' => ''
]
]);
// Creation du contenu de la page
if (!is_dir(self::DATA_DIR . self::$siteContent . '/content')) {
mkdir(self::DATA_DIR . self::$siteContent . '/content', 0755);
}
//$this->secure_file_put_contents(self::DATA_DIR . self::$siteContent . '/content/' . $pageId . '.html', '<p>Contenu de votre nouvelle page.</p>');
$this->setPage($pageId, '<p>Contenu de votre nouvelle page.</p>', self::$siteContent);
// Met à jour le sitemap
$this->updateSitemap();
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . $pageId,
'notification' => helper::translate('Nouvelle page créée'),
'state' => true
]);
}
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . $pageId,
'notification' => helper::translate('Nouvelle page créée'),
'state' => true
]);
} }
/** /**
@ -219,101 +185,116 @@ 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); $url = explode('&', $this->getUrl(2));
// La page n'existe pas // La page n'existe pas
if ( if ($this->getData(['page', $url[0]]) === null) {
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true ||
$this->getData(['page', $page]) === null
) {
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'access' => false 'access' => false
]); ]);
} // Jeton incorrect
elseif (!isset($_GET['csrf'])) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $url[0],
'notification' => helper::translate('Jeton invalide')
]);
} elseif ($_GET['csrf'] !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $url[0],
'notification' => helper::translate('Suppression interdite')
]);
} }
// Impossible de supprimer la page d'accueil // Impossible de supprimer la page d'accueil
elseif ($page === $this->getData(['locale', 'homePageId'])) { elseif ($url[0] === $this->getData(['locale', 'homePageId'])) {
// 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 de recherche affectée
elseif ($page === $this->getData(['locale', 'searchPageId'])) { elseif ($url[0] === $this->getData(['locale', 'searchPageId'])) {
// 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 des mentions légales affectée
elseif ($page === $this->getData(['locale', 'legalPageId'])) { elseif ($url[0] === $this->getData(['locale', 'legalPageId'])) {
// 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 des mentions légales affectée
elseif ($page === $this->getData(['locale', 'page404'])) { elseif ($url[0] === $this->getData(['locale', 'page404'])) {
// 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 des mentions légales affectée
elseif ($page === $this->getData(['locale', 'page403'])) { elseif ($url[0] === $this->getData(['locale', 'page403'])) {
// 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 des mentions légales affectée
elseif ($page === $this->getData(['locale', 'page302'])) { elseif ($url[0] === $this->getData(['locale', 'page302'])) {
// 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')
]);
}
// Jeton incorrect
elseif (!isset($_GET['csrf'])) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $url[0],
'notification' => helper::translate('Jeton invalide')
]);
} elseif ($_GET['csrf'] !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $url[0],
'notification' => helper::translate('Suppression interdite')
]); ]);
} }
// Impossible de supprimer une page contenant des enfants // Impossible de supprimer une page contenant des enfants
elseif ($this->getHierarchy($page, null)) { elseif ($this->getHierarchy($url[0], null)) {
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $page . '/' . self::$siteContent, 'redirect' => helper::baseUrl() . 'page/edit/' . $url[0],
'notification' => helper::translate('Impossible de supprimer une page contenant des pages enfants') 'notification' => helper::translate('Impossible de supprimer une page contenant des pages enfants')
]); ]);
} }
// Suppression // Suppression
else { else {
// Effacer le dossier du module // Effacer le dossier du module
$moduleId = $this->getData(['page', $page, 'moduleId']); $moduleId = $this->getData(['page', $url[0], 'moduleId']);
$modulesData = helper::getModules(); $modulesData = helper::getModules();
if ( if (
array_key_exists($moduleId, $modulesData) array_key_exists($moduleId, $modulesData)
&& is_dir($modulesData[$moduleId]['dataDirectory'] . $page) && is_dir($modulesData[$moduleId]['dataDirectory'] . $url[0])
) { ) {
$this->deleteDir($modulesData[$moduleId]['dataDirectory'] . $page); $this->removeDir($modulesData[$moduleId]['dataDirectory'] . $url[0]);
} }
// Effacer la page // Effacer la page
$this->deleteData(['page', $page]); $this->deleteData(['page', $url[0]]);
if (file_exists(self::DATA_DIR . self::$siteContent . '/content/' . $page . '.html')) { if (file_exists(self::DATA_DIR . self::$i18nContent . '/content/' . $url[0] . '.html')) {
unlink(self::DATA_DIR . self::$siteContent . '/content/' . $page . '.html'); unlink(self::DATA_DIR . self::$i18nContent . '/content/' . $url[0] . '.html');
} }
$this->deleteData(['module', $page]); $this->deleteData(['module', $url[0]]);
// Met à jour le sitemap // Met à jour le sitemap
$this->updateSitemap(); $this->updateSitemap();
@ -333,22 +314,8 @@ 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->getData(['page', $this->getUrl(2)]) === null) {
$this->getUser('permission', __CLASS__, __FUNCTION__) !== true ||
$this->getData(['page', $this->getUrl(2)]) === null
) {
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'access' => false 'access' => false
@ -357,10 +324,7 @@ class page extends common
// La page existe // La page existe
else { else {
// Soumission du formulaire // Soumission du formulaire
if ( if ($this->isPost()) {
$this->getUser('permission', __CLASS__, __FUNCTION__) === true &&
$this->isPost()
) {
// Si le Title n'est pas vide, premier test pour positionner la notification du champ obligatoire // Si le Title n'est pas vide, premier test pour positionner la notification du champ obligatoire
if ($this->getInput('pageEditTitle', helper::FILTER_ID, true) !== null && $this->getInput('pageEditTitle') !== '') { if ($this->getInput('pageEditTitle', helper::FILTER_ID, true) !== null && $this->getInput('pageEditTitle') !== '') {
// Génére l'ID si le titre de la page a changé // Génére l'ID si le titre de la page a changé
@ -394,7 +358,7 @@ class page extends common
// Placer la feuille de style dans un dossier au nom de la nouvelle instance // Placer la feuille de style dans un dossier au nom de la nouvelle instance
mkdir($modulesData[$moduleId]['dataDirectory'] . $pageId, 0755); mkdir($modulesData[$moduleId]['dataDirectory'] . $pageId, 0755);
copy($modulesData[$moduleId]['dataDirectory'] . $this->getUrl(2), $modulesData[$moduleId]['dataDirectory'] . $pageId); copy($modulesData[$moduleId]['dataDirectory'] . $this->getUrl(2), $modulesData[$moduleId]['dataDirectory'] . $pageId);
$this->deleteDir($modulesData[$moduleId]['dataDirectory'] . $this->getUrl(2)); $this->removeDir($modulesData[$moduleId]['dataDirectory'] . $this->getUrl(2));
// Mettre à jour le nom de la feuille de style // Mettre à jour le nom de la feuille de style
$this->setData(['module', $pageId, 'theme', 'style', $modulesData[$moduleId]['dataDirectory'] . $pageId]); $this->setData(['module', $pageId, 'theme', 'style', $modulesData[$moduleId]['dataDirectory'] . $pageId]);
} }
@ -411,8 +375,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 :
@ -498,18 +462,6 @@ class page extends common
} }
} }
} }
// Détermine le groupe selon que la page est une barre ou une page standard
$group = $this->getinput('pageEditBlock') !== 'bar' ? $this->getInput('pageEditGroup', helper::FILTER_INT) : 0;
//Détermine le profil d'utilisateur en fonction du groupe sinon le groupe vaut 0
$profil = 0;
if (
$this->getinput('pageEditBlock') !== 'bar' ||
$group === 1 ||
$group === 2
) {
$profil = $this->getInput('pageEditProfil' . $group, helper::FILTER_INT);
}
// Modifie la page ou en crée une nouvelle si l'id a changé // Modifie la page ou en crée une nouvelle si l'id a changé
$this->setData([ $this->setData([
@ -528,17 +480,13 @@ class page extends common
'modulePosition' => $this->getInput('pageModulePosition'), 'modulePosition' => $this->getInput('pageModulePosition'),
'parentPageId' => $this->getInput('pageEditParentPageId'), 'parentPageId' => $this->getInput('pageEditParentPageId'),
'position' => $position, 'position' => $position,
'group' => $group, 'group' => $this->getinput('pageEditBlock') !== 'bar' ? $this->getInput('pageEditGroup', helper::FILTER_INT) : 0,
'profil' => $profil,
'targetBlank' => $this->getInput('pageEditTargetBlank', helper::FILTER_BOOLEAN), 'targetBlank' => $this->getInput('pageEditTargetBlank', helper::FILTER_BOOLEAN),
'title' => $this->getInput('pageEditTitle', helper::FILTER_STRING_SHORT), 'title' => $this->getInput('pageEditTitle', helper::FILTER_STRING_SHORT),
'shortTitle' => $this->getInput('pageEditShortTitle', helper::FILTER_STRING_SHORT, true), 'shortTitle' => $this->getInput('pageEditShortTitle', helper::FILTER_STRING_SHORT, true),
'block' => $this->getinput('pageEditBlock'), 'block' => $this->getinput('pageEditBlock'),
'barLeft' => $barLeft, 'barLeft' => $barLeft,
'barRight' => $barRight, 'barRight' => $barRight,
'navLeft' => $this->getInput('pageEditNavLeft'),
'navRight' => $this->getInput('pageEditNavRight'),
'navTemplate' => $this->getInput('pageEditNavTemplate'),
'displayMenu' => $this->getinput('pageEditDisplayMenu'), 'displayMenu' => $this->getinput('pageEditDisplayMenu'),
'hideMenuSide' => $this->getinput('pageEditHideMenuSide', helper::FILTER_BOOLEAN), 'hideMenuSide' => $this->getinput('pageEditHideMenuSide', helper::FILTER_BOOLEAN),
'hideMenuHead' => $this->getinput('pageEditHideMenuHead', helper::FILTER_BOOLEAN), 'hideMenuHead' => $this->getinput('pageEditHideMenuHead', helper::FILTER_BOOLEAN),
@ -550,11 +498,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 +529,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) {
@ -606,20 +551,7 @@ class page extends common
self::$pagesBarId[$parentPageId] = $this->getData(['page', $parentPageId, 'title']); self::$pagesBarId[$parentPageId] = $this->getData(['page', $parentPageId, 'title']);
} }
} }
// Profils installés
// Profils disponibles
foreach ($this->getData(['profil']) as $profilId => $profilData) {
if ($profilId < self::GROUP_MEMBER) {
continue;
}
if ($profilId === self::GROUP_ADMIN) {
self::$userProfils[$profilId][self::GROUP_ADMIN] = $profilData['name'];
continue;
}
foreach ($profilData as $key => $value) {
self::$userProfils[$profilId][$key] = $profilData[$key]['name'];
}
}
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'title' => $this->getData(['page', $this->getUrl(2), 'title']), 'title' => $this->getData(['page', $this->getUrl(2), 'title']),
@ -637,22 +569,18 @@ class page extends common
public function cssEditor() public function cssEditor()
{ {
// Soumission du formulaire // Soumission du formulaire
if ( if ($this->isPost()) {
$this->getUser('permission', __CLASS__, __FUNCTION__) === true &&
$this->isPost()
) {
$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
]); ]);
} }
@ -672,22 +600,18 @@ class page extends common
public function jsEditor() public function jsEditor()
{ {
// Soumission du formulaire // Soumission du formulaire
if ( if ($this->isPost()) {
$this->getUser('permission', __CLASS__, __FUNCTION__) === true &&
$this->isPost()
) {
$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 +627,15 @@ 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/
*/ */
@ -44,7 +44,3 @@
background-color: #00BFFF; background-color: #00BFFF;
} }
#pageEditProfil1Wrapper,
#pageEditProfil2Wrapper {
padding: 0;
}

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/
*/ */
@ -54,16 +54,6 @@ function protectModule() {
*/ */
$( document ).ready(function() { $( document ).ready(function() {
// Changement de profil
$(".pageEditGroupProfil").hide();
$("#pageEditGroupProfil" + $("#pageEditGroup").val()).show();
$("#pageEditGroup").on("change", function () {
$(".pageEditGroupProfil").hide();
$("#pageEditGroupProfil" + $(this).val()).show();
});
/** /**
* Sélection des onglets * Sélection des onglets
*/ */
@ -193,7 +183,6 @@ $( document ).ready(function() {
$("#pageEditSeoWrapper").slideUp(); $("#pageEditSeoWrapper").slideUp();
$("#pageEditAdvancedWrapper").removeClass("disabled"); $("#pageEditAdvancedWrapper").removeClass("disabled");
$("#pageEditAdvancedWrapper").slideUp(); $("#pageEditAdvancedWrapper").slideUp();
$(".navSelect").slideUp();
/* /*
$("#pageEditBlockLayout").removeClass("col6"); $("#pageEditBlockLayout").removeClass("col6");
$("#pageEditBlockLayout").addClass("col12"); $("#pageEditBlockLayout").addClass("col12");
@ -510,7 +499,6 @@ pageEditBlockDOM.on("change", function() {
$("#pageEditModuleConfig").slideUp(); $("#pageEditModuleConfig").slideUp();
$("#pageEditDisplayMenuWrapper").addClass("disabled"); $("#pageEditDisplayMenuWrapper").addClass("disabled");
$("#pageEditDisplayMenuWrapper").slideDown(); $("#pageEditDisplayMenuWrapper").slideDown();
$(".navSelect").slideUp();
/* /*
$("#pageEditBlockLayout").removeClass("col6"); $("#pageEditBlockLayout").removeClass("col6");
$("#pageEditBlockLayout").addClass("col12"); $("#pageEditBlockLayout").addClass("col12");
@ -531,7 +519,6 @@ pageEditBlockDOM.on("change", function() {
$("#pageEditModuleConfig").slideDown(); $("#pageEditModuleConfig").slideDown();
$("#pageEditDisplayMenuWrapper").removeClass("disabled"); $("#pageEditDisplayMenuWrapper").removeClass("disabled");
$("#pageEditDisplayMenuWrapper").slideUp(); $("#pageEditDisplayMenuWrapper").slideUp();
$(".navSelect").slideDown();
if ($("#pageEditParentPageId").val() !== "") { if ($("#pageEditParentPageId").val() !== "") {
$("#pageEditbreadCrumbWrapper").addClass("disabled"); $("#pageEditbreadCrumbWrapper").addClass("disabled");
$("#pageEditbreadCrumbWrapper").slideDown(); $("#pageEditbreadCrumbWrapper").slideDown();

View File

@ -1,32 +1,34 @@
<?php echo template::formOpen('pageEditForm'); ?> <?php echo template::formOpen('pageEditForm'); ?>
<div class="row"> <div class="row">
<div class="col1"> <div class="col1">
<?php echo template::button('configModulesBack', [ <?php $href = helper::baseUrl() . $this->getUrl(2); ?>
<?php if ($this->getData(['page', $this->getUrl(2), 'moduleId']) === 'redirection' || 'code') $href = helper::baseUrl(); ?>
<?php echo template::button('pageEditBack', [
'class' => 'buttonGrey', 'class' => 'buttonGrey',
'href' => helper::baseUrl() . $this->getUrl(2), 'href' => $href,
'value' => template::ico('left') 'value' => template::ico('home')
]); ?> ]); ?>
</div> </div>
<div class="col1"> <div class="col1">
<?php /**echo template::button('pageEditHelp', [ <?php /**echo template::button('pageEditHelp', [
'href' => 'https://doc.zwiicms.fr/edition-des-pages', 'href' => 'https://doc.zwiicms.fr/edition-des-pages',
'target' => '_blank', 'target' => '_blank',
'value' => template::ico('help'), 'value' => template::ico('help'),
'class' => 'buttonHelp', 'class' => 'buttonHelp',
'help' => 'Consulter l\'aide en ligne' 'help' => 'Consulter l\'aide en ligne'
]); */?> ]); */ ?>
</div> </div>
<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) . '&csrf=' . $_SESSION['csrf'],
'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) . '&csrf=' . $_SESSION['csrf'],
'value' => template::ico('clone'), 'value' => template::ico('clone'),
'help' => 'Dupliquer la page' 'help' => 'Dupliquer la page'
]); ?> ]); ?>
@ -65,8 +67,7 @@
<div class="row"> <div class="row">
<div class="col12"> <div class="col12">
<div class="block"> <div class="block">
<h4> <h4><?php echo helper::translate('Titres'); ?>
<?php echo helper::translate('Titres'); ?>
<!--<span id="infoHelpButton" class="helpDisplayButton"> <!--<span id="infoHelpButton" class="helpDisplayButton">
<a href="https://doc.zwiicms.fr/informations-generales" target="_blank" title="Cliquer pour consulter l'aide en ligne"> <a href="https://doc.zwiicms.fr/informations-generales" target="_blank" title="Cliquer pour consulter l'aide en ligne">
<?php //echo template::ico('help', ['margin' => 'left']); ?> <?php //echo template::ico('help', ['margin' => 'left']); ?>
@ -108,7 +109,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>
@ -118,8 +119,7 @@
<div class="row"> <div class="row">
<div class="col12"> <div class="col12">
<div class="block"> <div class="block">
<h4> <h4><?php echo helper::translate('Emplacement dans le menu'); ?>
<?php echo helper::translate('Emplacement dans le menu'); ?>
<!--<span id="positionHelpButton" class="helpDisplayButton"> <!--<span id="positionHelpButton" class="helpDisplayButton">
<a href="https://doc.zwiicms.fr/emplacement-dans-le-menu" target="_blank" title="Cliquer pour consulter l'aide en ligne"> <a href="https://doc.zwiicms.fr/emplacement-dans-le-menu" target="_blank" title="Cliquer pour consulter l'aide en ligne">
<?php //echo template::ico('help', ['margin' => 'left']); ?> <?php //echo template::ico('help', ['margin' => 'left']); ?>
@ -135,11 +135,11 @@
]); ?> ]); ?>
</div> </div>
<div class="col4"> <div class="col4">
<?php if ($this->getHierarchy($this->getUrl(2), false)): ?> <?php if ($this->getHierarchy($this->getUrl(2), false)) : ?>
<?php echo template::hidden('pageEditParentPageId', [ <?php echo template::hidden('pageEditParentPageId', [
'value' => $this->getData(['page', $this->getUrl(2), 'parentPageId']) 'value' => $this->getData(['page', $this->getUrl(2), 'parentPageId'])
]); ?> ]); ?>
<?php else: ?> <?php else : ?>
<?php echo template::select('pageEditParentPageId', $module::$pagesNoParentId, [ <?php echo template::select('pageEditParentPageId', $module::$pagesNoParentId, [
'label' => 'Page parent', 'label' => 'Page parent',
'selected' => $this->getData(['page', $this->getUrl(2), 'parentPageId']) 'selected' => $this->getData(['page', $this->getUrl(2), 'parentPageId'])
@ -174,8 +174,7 @@
<div class="row"> <div class="row">
<div class="col12"> <div class="col12">
<div class="block"> <div class="block">
<h4> <h4><?php echo helper::translate('Options avancées'); ?>
<?php echo helper::translate('Options avancées'); ?>
<!--<span id="advancedHelpButton" class="helpDisplayButton"> <!--<span id="advancedHelpButton" class="helpDisplayButton">
<a href="https://doc.zwiicms.fr/options-d-emplacement-avancee" target="_blank" title="Cliquer pour consulter l'aide en ligne"> <a href="https://doc.zwiicms.fr/options-d-emplacement-avancee" target="_blank" title="Cliquer pour consulter l'aide en ligne">
<?php //echo template::ico('help', ['margin' => 'left']); ?> <?php //echo template::ico('help', ['margin' => 'left']); ?>
@ -222,8 +221,7 @@
<div class="row"> <div class="row">
<div class="col6"> <div class="col6">
<div class="block"> <div class="block">
<h4> <h4><?php echo helper::translate('Module'); ?>
<?php echo helper::translate('Module'); ?>
</h4> </h4>
<div class="row"> <div class="row">
<div class="col10"> <div class="col10">
@ -260,9 +258,7 @@
</div> </div>
<div class="col6"> <div class="col6">
<div class="block"> <div class="block">
<h4> <h4><?php echo helper::translate('Contenu avancé');?></h4>
<?php echo helper::translate('Contenu avancé'); ?>
</h4>
<div class="row"> <div class="row">
<div class="col6 offset3"> <div class="col6 offset3">
<?php echo template::button('pageEditCssEditor', [ <?php echo template::button('pageEditCssEditor', [
@ -290,8 +286,7 @@
<div class="row"> <div class="row">
<div class="col12"> <div class="col12">
<div class="block"> <div class="block">
<h4> <h4><?php echo helper::translate('Mise en page'); ?>
<?php echo helper::translate('Mise en page'); ?>
<!--<span id="layoutHelpButton" class="helpDisplayButton"> <!--<span id="layoutHelpButton" class="helpDisplayButton">
<a href="https://doc.zwiicms.fr/mise-en-page-2" target="_blank" title="Cliquer pour consulter l'aide en ligne"> <a href="https://doc.zwiicms.fr/mise-en-page-2" target="_blank" title="Cliquer pour consulter l'aide en ligne">
<?php //echo template::ico('help', ['margin' => 'left']); ?> <?php //echo template::ico('help', ['margin' => 'left']); ?>
@ -313,21 +308,21 @@
</div> </div>
<div class="col6"> <div class="col6">
<!-- Sélection des barres latérales --> <!-- Sélection des barres latérales -->
<?php if ($this->getHierarchy($this->getUrl(2), false, true)): ?> <?php if ($this->getHierarchy($this->getUrl(2), false, true)) : ?>
<?php echo template::hidden('pageEditBarLeft', [ <?php echo template::hidden('pageEditBarLeft', [
'value' => $this->getData(['page', $this->getUrl(2), 'barLeft']) 'value' => $this->getData(['page', $this->getUrl(2), 'barLeft'])
]); ?> ]); ?>
<?php else: ?> <?php else : ?>
<?php echo template::select('pageEditBarLeft', $module::$pagesBarId, [ <?php echo template::select('pageEditBarLeft', $module::$pagesBarId, [
'label' => 'Barre latérale gauche :', 'label' => 'Barre latérale gauche :',
'selected' => $this->getData(['page', $this->getUrl(2), 'barLeft']) 'selected' => $this->getData(['page', $this->getUrl(2), 'barLeft'])
]); ?> ]); ?>
<?php endif; ?> <?php endif; ?>
<?php if ($this->getHierarchy($this->getUrl(2), false, true)): ?> <?php if ($this->getHierarchy($this->getUrl(2), false, true)) : ?>
<?php echo template::hidden('pageEditBarRight', [ <?php echo template::hidden('pageEditBarRight', [
'value' => $this->getData(['page', $this->getUrl(2), 'barRight']) 'value' => $this->getData(['page', $this->getUrl(2), 'barRight'])
]); ?> ]); ?>
<?php else: ?> <?php else : ?>
<?php echo template::select('pageEditBarRight', $module::$pagesBarId, [ <?php echo template::select('pageEditBarRight', $module::$pagesBarId, [
'label' => 'Barre latérale droite :', 'label' => 'Barre latérale droite :',
'selected' => $this->getData(['page', $this->getUrl(2), 'barRight']) 'selected' => $this->getData(['page', $this->getUrl(2), 'barRight'])
@ -340,26 +335,6 @@
]); ?> ]); ?>
</div> </div>
</div> </div>
<div class="row navSelect">
<div class="col4">
<?php echo template::select('pageEditNavLeft', $module::$navIconPosition, [
'label' => 'Bouton de navigation gauche',
'selected' => $this->getData(['page', $this->getUrl(2), 'navLeft']),
]); ?>
</div>
<div class="col4">
<?php echo template::select('pageEditNavTemplate', $module::$navIconTemplate, [
'label' => 'Modèle',
'selected' => $this->getData(['page', $this->getUrl(2), 'navTemplate']),
]); ?>
</div>
<div class="col4">
<?php echo template::select('pageEditNavRight', $module::$navIconPosition, [
'label' => 'Bouton de navigation droit',
'selected' => $this->getData(['page', $this->getUrl(2), 'navRight']),
]); ?>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -370,8 +345,7 @@
<div class="row"> <div class="row">
<div class="col12"> <div class="col12">
<div class="block"> <div class="block">
<h4> <h4><?php echo helper::translate('Permission et référencement');?>
<?php echo helper::translate('Permission et référencement'); ?>
<!--<span id="seoHelpButton" class="helpDisplayButton"> <!--<span id="seoHelpButton" class="helpDisplayButton">
<a href="https://doc.zwiicms.fr/permission-et-referencement" target="_blank" title="Cliquer pour consulter l'aide en ligne"> <a href="https://doc.zwiicms.fr/permission-et-referencement" target="_blank" title="Cliquer pour consulter l'aide en ligne">
<?php //echo template::ico('help', ['margin' => 'left']); ?> <?php //echo template::ico('help', ['margin' => 'left']); ?>
@ -382,31 +356,10 @@
<div class="row"> <div class="row">
<div class='col6'> <div class='col6'>
<?php echo template::select('pageEditGroup', self::$groupPublics, [ <?php echo template::select('pageEditGroup', self::$groupPublics, [
'label' => 'Groupe minimal pour accéder à la page', 'label' => 'Groupe requis pour accéder à la page :',
'selected' => $this->getData(['page', $this->getUrl(2), 'group']), 'selected' => $this->getData(['page', $this->getUrl(2), 'group'])
'help' => 'Les groupes de niveau supérieur accèdent à la page.'
]); ?> ]); ?>
</div> </div>
<div class="col6">
<div class="pageEditGroupProfil displayNone"
id="pageEditGroupProfil<?php echo self::GROUP_MEMBER; ?>">
<?php echo template::select('pageEditProfil' . self::GROUP_MEMBER, $module::$userProfils[self::GROUP_MEMBER], [
'label' => 'Profil minimal pour accéder à la page',
'selected' => $this->getData(['page', $this->getUrl(2), 'profil']),
'help' => 'Les profils de niveau supérieur accèdent à la page.',
]); ?>
</div>
<div class="pageEditGroupProfil displayNone"
id="pageEditGroupProfil<?php echo self::GROUP_EDITOR; ?>">
<?php echo template::select('pageEditProfil' . self::GROUP_EDITOR, $module::$userProfils[self::GROUP_EDITOR], [
'label' => 'Profil minimal pour accéder à la page',
'selected' => $this->getData(['page', $this->getUrl(2), 'profil']),
'help' => 'Les profils de niveau supérieur accèdent à la page.',
]); ?>
</div>
</div>
</div>
<div class="row">
<div class='col12'> <div class='col12'>
<?php echo template::text('pageEditMetaTitle', [ <?php echo template::text('pageEditMetaTitle', [
'label' => 'Méta-titre', 'label' => 'Méta-titre',

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/
*/ */
@ -21,6 +21,12 @@ class plugin extends common
'index' => self::GROUP_ADMIN, 'index' => self::GROUP_ADMIN,
'delete' => self::GROUP_ADMIN, 'delete' => self::GROUP_ADMIN,
'save' => self::GROUP_ADMIN, 'save' => self::GROUP_ADMIN,
// Sauvegarde le module dans un fichier ZIP ou dans le gestionnaire
'dataExport' => self::GROUP_ADMIN,
// Fonction muette d'exportation
'dataImport' => self::GROUP_ADMIN,
// les données d'un module
'dataDelete' => self::GROUP_ADMIN,
'store' => self::GROUP_ADMIN, 'store' => self::GROUP_ADMIN,
'item' => self::GROUP_ADMIN, 'item' => self::GROUP_ADMIN,
// détail d'un objet // détail d'un objet
@ -56,29 +62,28 @@ class plugin extends common
public function delete() public function delete()
{ {
// Action interdite // Jeton incorrect
if ($this->getUser('permission', __CLASS__, __FUNCTION__) !== true) { if ($this->getUrl(3) !== $_SESSION['csrf']) {
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'access' => false 'redirect' => helper::baseUrl() . 'plugin',
'state' => false,
'notification' => helper::translate('Action interdite')
]); ]);
} else { } else {
// Suppression des dossiers // Suppression des dossiers
$infoModules = helper::getModules(); $infoModules = helper::getModules();
$module = $this->getUrl(2); $module = $this->getUrl(2);
//Liste des dossiers associés au module non effacés //Liste des dossiers associés au module non effacés
if ( if ($this->removeDir('./module/' . $module) === true) {
is_dir('./module/' . $module) &&
$this->deleteDir('./module/' . $module) === true
) {
$success = true; $success = true;
$notification = 'Module ' . $module . ' désinstallé'; $notification = 'Module ' . $module . ' désinstallé';
if (($infoModules[$this->getUrl(2)]['dataDirectory'])) { if (($infoModules[$this->getUrl(2)]['dataDirectory'])) {
if ( if (
is_dir($infoModules[$this->getUrl(2)]['dataDirectory']) is_dir($infoModules[$this->getUrl(2)]['dataDirectory'])
&& !$this->removeDir($infoModules[$this->getUrl(2)]['dataDirectory'])
) { ) {
$s = $this->deleteDir($infoModules[$this->getUrl(2)]['dataDirectory']); $notification = sprintf(helper::translate('Le module %s est désinstallé, il reste peut-être des données dans %s'), $module, $infoModules[$this->getUrl(2)]['dataDirectory']);
$notification = $s === false ? sprintf(helper::translate('Le module %s est désinstallé, il reste peut-être des données dans %s'), $module, $infoModules[$this->getUrl(2)]['dataDirectory']) : $notification;
} }
} }
} else { } else {
@ -131,7 +136,7 @@ class plugin extends common
$module = json_decode(file_get_contents(self::TEMP_DIR . $tempFolder . 'enum.json'), true); $module = json_decode(file_get_contents(self::TEMP_DIR . $tempFolder . 'enum.json'), true);
} else { } else {
// Message de retour // Message de retour
$this->deleteDir(self::TEMP_DIR . $tempFolder); $this->removeDir(self::TEMP_DIR . $tempFolder);
$zip->close(); $zip->close();
return ([ return ([
'success' => false, 'success' => false,
@ -146,7 +151,7 @@ class plugin extends common
// Vérification de la présence des dossier décrits // Vérification de la présence des dossier décrits
if (!is_dir(self::TEMP_DIR . $tempFolder . $src)) { if (!is_dir(self::TEMP_DIR . $tempFolder . $src)) {
// Message de retour // Message de retour
$this->deleteDir(self::TEMP_DIR . $tempFolder); $this->removeDir(self::TEMP_DIR . $tempFolder);
$zip->close(); $zip->close();
return ([ return ([
'success' => false, 'success' => false,
@ -156,7 +161,7 @@ class plugin extends common
// Interdire l'écriture dans le dossier core // Interdire l'écriture dans le dossier core
if (strstr($dest, 'core') !== false) { if (strstr($dest, 'core') !== false) {
// Message de retour // Message de retour
$this->deleteDir(self::TEMP_DIR . $tempFolder); $this->removeDir(self::TEMP_DIR . $tempFolder);
$zip->close(); $zip->close();
return ([ return ([
'success' => false, 'success' => false,
@ -171,7 +176,7 @@ class plugin extends common
*/ */
if (!file_exists(self::TEMP_DIR . $tempFolder . $module['name'] . '.php')) { if (!file_exists(self::TEMP_DIR . $tempFolder . $module['name'] . '.php')) {
// Message de retour // Message de retour
$this->deleteDir(self::TEMP_DIR . $tempFolder); $this->removeDir(self::TEMP_DIR . $tempFolder);
$zip->close(); $zip->close();
return ([ return ([
'success' => false, 'success' => false,
@ -204,7 +209,7 @@ class plugin extends common
$installOk = true; $installOk = true;
} else { } else {
// Message de retour // Message de retour
$this->deleteDir(self::TEMP_DIR . $tempFolder); $this->removeDir(self::TEMP_DIR . $tempFolder);
$zip->close(); $zip->close();
return ([ return ([
'success' => false, 'success' => false,
@ -224,28 +229,27 @@ class plugin extends common
if (!is_dir(self::TEMP_DIR . $tempFolder . $src)) { if (!is_dir(self::TEMP_DIR . $tempFolder . $src)) {
mkdir(self::TEMP_DIR . $tempFolder . $src); mkdir(self::TEMP_DIR . $tempFolder . $src);
} }
$success = $success || $this->copyDir(self::TEMP_DIR . $tempFolder . $src, $dest); $success = $success && $this->copyDir(self::TEMP_DIR . $tempFolder . $src, $dest);
} }
} }
// Message de retour // Message de retour
$t = isset($versionInstalled) ? helper::translate('actualisé') : helper::translate('installé'); $t = isset($versionInstalled) ? helper::translate('actualisé') : helper::translate('installé');
$this->deleteDir(self::TEMP_DIR . $tempFolder); $this->removeDir(self::TEMP_DIR . $tempFolder);
$zip->close(); $zip->close();
return ([ return ([
'success' => $success, 'success' => $success,
'notification' => $success 'notification' => $success
? sprintf(helper::translate('Le module %s a été %s'), $module['name'], $t) ? sprintf(helper::translate('Le module %s a été %s'), $module['name'], $t)
: helper::translate('Erreur inconnue, le module n\'est pas installé') : helper::translate('Erreur inconnue, le module n\'est pas installé')
]); ]);
} else { } else {
// Supprimer le dossier temporaire
$this->deleteDir(self::TEMP_DIR . $tempFolder);
$zip->close();
return ([ return ([
'success' => false, 'success' => false,
'notification' => helper::translate('Erreur inconnue, le module n\'est pas installé') 'notification' => helper::translate('Erreur inconnue, le module n\'est pas installé')
]); ]);
// Supprimer le dossier temporaire
$this->removeDir(self::TEMP_DIR . $tempFolder);
$zip->close();
} }
} else { } else {
// Message de retour // Message de retour
@ -262,11 +266,7 @@ class plugin extends common
public function upload() public function upload()
{ {
// Soumission du formulaire // Soumission du formulaire
if ($this->isPost()) {
if (
$this->getUser('permission', __CLASS__, __FUNCTION__) === true &&
$this->isPost()
) {
// Installation d'un module // Installation d'un module
$checkValidMaj = $this->getInput('configModulesCheck', helper::FILTER_BOOLEAN); $checkValidMaj = $this->getInput('configModulesCheck', helper::FILTER_BOOLEAN);
$zipFilename = $this->getInput('configModulesInstallation', helper::FILTER_STRING_SHORT); $zipFilename = $this->getInput('configModulesInstallation', helper::FILTER_STRING_SHORT);
@ -291,11 +291,13 @@ class plugin extends common
*/ */
public function uploadItem() public function uploadItem()
{ {
// Action interdite // Jeton incorrect
if ($this->getUser('permission', __CLASS__, __FUNCTION__) !== true) { if ($this->getUrl(3) !== $_SESSION['csrf']) {
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'access' => false 'redirect' => helper::baseUrl() . 'store',
'state' => false,
'notification' => helper::translate('Action interdite')
]); ]);
} else { } else {
// Récupérer le module en ligne // Récupérer le module en ligne
@ -314,7 +316,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,11 +379,11 @@ 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']),
implode(' - ', $pageInfos), implode(' - ', $pageInfos),
template::button('moduleExport' . $key, [ template::button('moduleExport' . $key, [
'class' => $class, 'class' => $class,
'href' => helper::baseUrl() . $this->getUrl(0) . '/uploadItem/' . $key, 'href' => helper::baseUrl() . $this->getUrl(0) . '/uploadItem/' . $key . '/' . $_SESSION['csrf'],
'value' => $ico, 'value' => $ico,
'help' => $help 'help' => $help
]) ])
@ -403,7 +405,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']);
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'title' => helper::translate('Module ' . self::$storeItem['title']), 'title' => helper::translate('Module ' . self::$storeItem['title']),
@ -417,15 +419,10 @@ class plugin extends common
public function index() public function index()
{ {
$i18nSites = [];
// Tableau des langues rédigées // Tableau des langues rédigées
foreach (self::$languages as $key => $value) { foreach (self::$languages as $key => $value) {
// tableau des langues installées // tableau des langues installées
if ( if (is_dir(self::DATA_DIR . $key)) {
is_dir(self::DATA_DIR . $key)
&& file_exists(self::DATA_DIR . $key . '/page.json')
&& file_exists(self::DATA_DIR . $key . '/module.json')
) {
$i18nSites[$key] = $value; $i18nSites[$key] = $value;
} }
} }
@ -435,11 +432,10 @@ class plugin extends common
// Parcourir les langues du site traduit et recherche les modules affectés à des pages // Parcourir les langues du site traduit et recherche les modules affectés à des pages
$pagesInfos = []; $pagesInfos = [];
foreach ($i18nSites as $keyi18n => $valuei18n) { foreach ($i18nSites as $keyi18n => $valuei18n) {
// Clés moduleIds dans les pages de la langue // Clés moduleIds dans les pages de la langue
$pages = json_decode(file_get_contents(self::DATA_DIR . $keyi18n . '/page.json'), true); $pages = json_decode(file_get_contents(self::DATA_DIR . $keyi18n . '/' . 'page.json'), true);
// Extraire les clés des modules // Extraire les clés des modules
$pagesModules[$keyi18n] = array_filter(helper::arrayColumn($pages['page'], 'moduleId', 'SORT_DESC'), 'strlen'); $pagesModules[$keyi18n] = array_filter(helper::arrayColumn($pages['page'], 'moduleId', 'SORT_DESC'), 'strlen');
@ -447,6 +443,7 @@ class plugin extends common
// Générer la liste des pages avec module de la langue par défaut // Générer la liste des pages avec module de la langue par défaut
foreach ($pagesModules[$keyi18n] as $key => $value) { foreach ($pagesModules[$keyi18n] as $key => $value) {
if (!empty($value)) { if (!empty($value)) {
$pagesInfos[$keyi18n][$key]['pageId'] = $key; $pagesInfos[$keyi18n][$key]['pageId'] = $key;
$pagesInfos[$keyi18n][$key]['title'] = $pages['page'][$key]['title']; $pagesInfos[$keyi18n][$key]['title'] = $pages['page'][$key]['title'];
$pagesInfos[$keyi18n][$key]['moduleId'] = $value; $pagesInfos[$keyi18n][$key]['moduleId'] = $value;
@ -479,7 +476,7 @@ class plugin extends common
$infoModules[$key]['delete'] === true $infoModules[$key]['delete'] === true
? template::button('moduleDelete' . $key, [ ? template::button('moduleDelete' . $key, [
'class' => 'moduleDelete buttonRed', 'class' => 'moduleDelete buttonRed',
'href' => helper::baseUrl() . $this->getUrl(0) . '/delete/' . $key, 'href' => helper::baseUrl() . $this->getUrl(0) . '/delete/' . $key . '/' . $_SESSION['csrf'],
'value' => template::ico('trash'), 'value' => template::ico('trash'),
'help' => 'Supprimer le module' 'help' => 'Supprimer le module'
]) ])
@ -500,12 +497,12 @@ class plugin extends common
$infoModules[$key]['version'], $infoModules[$key]['version'],
'', '',
template::button('moduleSave' . $key, [ template::button('moduleSave' . $key, [
'href' => helper::baseUrl() . $this->getUrl(0) . '/save/filemanager/' . $key, 'href' => helper::baseUrl() . $this->getUrl(0) . '/save/filemanager/' . $key . '/' . $_SESSION['csrf'],
'value' => template::ico('download-cloud'), 'value' => template::ico('download-cloud'),
'help' => 'Sauvegarder le module dans le gestionnaire de fichiers' 'help' => 'Sauvegarder le module dans le gestionnaire de fichiers'
]), ]),
template::button('moduleDownload' . $key, [ template::button('moduleDownload' . $key, [
'href' => helper::baseUrl() . $this->getUrl(0) . '/save/download/' . $key, 'href' => helper::baseUrl() . $this->getUrl(0) . '/save/download/' . $key . '/' . $_SESSION['csrf'],
'value' => template::ico('download'), 'value' => template::ico('download'),
'help' => 'Sauvegarder et télécharger le module' 'help' => 'Sauvegarder et télécharger le module'
]) ])
@ -531,19 +528,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 . '/' . $_SESSION['csrf'],
// 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 . '/' . $_SESSION['csrf'],
// 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 . '/' . $_SESSION['csrf'],
// 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',
@ -569,15 +566,18 @@ class plugin extends common
*/ */
public function save() public function save()
{ {
// Action interdite // Jeton incorrect
if ($this->getUser('permission', __CLASS__, __FUNCTION__) !== true) { if ($this->getUrl(4) !== $_SESSION['csrf']) {
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'access' => false 'redirect' => helper::baseUrl() . 'plugin',
'state' => false,
'notification' => helper::translate('Action interdite')
]); ]);
} else { } else {
// Créer un dossier temporaire // Créer un dossier temporaire
$tmpFolder = self::TEMP_DIR . uniqid() . '/'; $tmpFolder = self::TEMP_DIR . uniqid();
if (!is_dir($tmpFolder)) { if (!is_dir($tmpFolder)) {
mkdir($tmpFolder, 0755); mkdir($tmpFolder, 0755);
} }
@ -587,43 +587,273 @@ class plugin extends common
// Descripteur de l'archive // Descripteur de l'archive
$infoModule = helper::getModules(); $infoModule = helper::getModules();
//Nom de l'archive //Nom de l'archive
$fileName = $moduleId . str_replace('.', '-', $infoModule[$moduleId]['version']) . '.zip'; $fileName = $moduleId . $infoModule[$moduleId]['version'] . '.zip';
// Régénération du descripteur du module // Régénération du module
$this->secure_file_put_contents(self::MODULE_DIR . $moduleId . '/enum.json', $infoModule[$moduleId]); $success = 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(self::TEMP_DIR . $fileName, self::MODULE_DIR . $moduleId);
switch ($action) { switch ($action) {
case 'filemanager': case 'filemanager':
if (is_dir(self::FILE_DIR . 'source/modules') === false) { if (!file_exists(self::FILE_DIR . 'source/modules')) {
mkdir(self::FILE_DIR . 'source/modules'); mkdir(self::FILE_DIR . 'source/modules');
} }
$success = copy($tmpFolder . $fileName, self::FILE_DIR . 'source/modules/' . $fileName); $success = $success && copy(self::TEMP_DIR . $fileName, self::FILE_DIR . 'source/modules/' . $moduleId . '.zip');
// Valeurs en sortie // Valeurs en sortie
$this->addOutput([ $this->addOutput([
'redirect' => helper::baseUrl() . 'plugin', 'redirect' => helper::baseUrl() . 'plugin',
'notification' => $success ? helper::translate('Archive copiée dans le dossier Modules du gestionnaire de fichier') : helper::translate('Erreur de copie'), 'notification' => $success ? helper::translate('Archive copiée dans le dossier Modules du gestionnaire de fichier') : helper::translate('Erreur de copie'),
'state' => $success 'state' => $success
]); ]);
// Nettoyage
unlink(self::TEMP_DIR . $fileName);
$this->removeDir($tmpFolder);
break; break;
case 'download': case 'download':
default:
// Téléchargement du ZIP // Téléchargement du ZIP
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');
header('Content-Disposition: attachment; filename="' . $fileName . '"'); header('Content-Disposition: attachment; filename="' . $fileName . '"');
header('Content-Length: ' . filesize($tmpFolder . $fileName)); header('Content-Length: ' . filesize(self::TEMP_DIR . $fileName));
readfile($tmpFolder . $fileName); readfile(self::TEMP_DIR . $fileName);
// Nettoyage du dossier
unlink(self::TEMP_DIR . $fileName);
exit(); exit();
} }
// Nettoyage
unlink(self::TEMP_DIR . $fileName);
$this->deleteDir($tmpFolder);
} }
} }
/*
* Détacher un module d'une page en supprimant les données du module
* 2 : i18n id
* 3 : moduleId
* 4 : pageId
* 5 : CSRF
*/
public function dataDelete()
{
// Jeton incorrect
if ($this->getUrl(5) !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'plugin',
'state' => false,
'notification' => helper::translate('Action interdite')
]);
} else {
$this->setData(['page', $this->getUrl(4), 'moduleId', '']);
$this->deleteData(['module', $this->getUrl(4)]);
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'plugin',
'notification' => sprintf(helper::translate('Le module %s de la page %s a été supprimé'), $this->getUrl(3), $this->getUrl(4)),
'state' => true
]);
}
}
/*
* Export des données d'un module
* Structure de l'adresse reçue
* 2 : i18n id
* 3 : moduleId
* 4 : pageId
* 5 : CSRF
*/
public function dataExport()
{
// Jeton incorrect
if ($this->getUrl(6) !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'plugin',
'state' => false,
'notification' => helper::translate('Action interdite')
]);
} else {
// Créer un dossier temporaire
$tmpFolder = self::TEMP_DIR . uniqid();
if (!is_dir($tmpFolder)) {
mkdir($tmpFolder, 0755);
}
$action = $this->getUrl(2);
$lang = $this->getUrl(3);
$moduleId = $this->getUrl(4);
$pageId = $this->getUrl(5);
// DOnnèes du module de la page sélectionnée
$moduleData = $this->getData(['module', $pageId]);
// Descripteur du module
$infoModules = helper::getModules();
$infoModule = $infoModules[$moduleId];
// Copier les données et le descripteur
$success = file_put_contents($tmpFolder . '/module.json', json_encode($moduleData, JSON_UNESCAPED_UNICODE)) === false ? false : true;
$success = $success && is_int(file_put_contents($tmpFolder . '/enum.json', json_encode([$moduleId => $infoModule], JSON_UNESCAPED_UNICODE)));
// Le dossier du module s'il existe
if (is_dir(self::DATA_DIR . $moduleId . '/' . $pageId)) {
// Copier le dossier des données
$success = $success && $this->copyDir(self::DATA_DIR . '/' . $moduleId . '/' . $pageId, $tmpFolder . '/dataDirectory');
}
// Création du zip
$fileName = $lang . '-' . $moduleId . '-' . $pageId . '.zip';
$this->makeZip(self::TEMP_DIR . $fileName, $tmpFolder);
// Gestion de l'action
if ($success) {
switch ($action) {
case 'filemanager':
if (!file_exists(self::FILE_DIR . 'source/modules')) {
mkdir(self::FILE_DIR . 'source/modules');
}
if (file_exists(self::TEMP_DIR . $fileName)) {
$success = $success && copy(self::TEMP_DIR . $fileName, self::FILE_DIR . 'source/modules/data' . $moduleId . '.zip');
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'plugin',
'notification' => $success ? helper::translate('Données copiées dans le dossier Module du gestionnaire de fichier') : helper::translate('Erreur de copie'),
'state' => $success
]);
// Nettoyage
unlink(self::TEMP_DIR . $fileName);
$this->removeDir($tmpFolder);
}
break;
case 'download':
default:
if (file_exists(self::TEMP_DIR . $fileName)) {
// Téléchargement du ZIP
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Transfer-Encoding: binary');
header('Content-Disposition: attachment; filename="' . $fileName . '"');
header('Content-Length: ' . filesize(self::TEMP_DIR . $fileName));
readfile(self::TEMP_DIR . $fileName);
// Nettoyage du dossier
unlink(self::TEMP_DIR . $fileName);
exit();
}
}
} else {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'plugin',
'notification' => helper::translate('Erreur inconnue'),
'state' => false
]);
}
}
}
/*
* Importer des données d'un module externes ou interne à module.json
*/
public function dataImport()
{
// Soumission du formulaire d'importation du module dans une page libre
if ($this->isPost()) {
// Récupérer le fichier et le décompacter
$zipFilename = $this->getInput('pluginImportFile', helper::FILTER_STRING_SHORT, true);
$pageId = $this->getInput('pluginImportPage', null, true);
$tmpFolder = uniqid();
// Extraction dans un dossier temporaire
mkdir(self::TEMP_DIR . $tmpFolder, 0755);
$zip = new ZipArchive();
if ($zip->open(self::FILE_DIR . 'source/' . $zipFilename) === TRUE) {
$zip->extractTo(self::TEMP_DIR . $tmpFolder);
}
// Lire le descripteur
$descripteur = json_decode(file_get_contents(self::TEMP_DIR . $tmpFolder . '/enum.json'), true);
$moduleId = array_key_first($descripteur);
// Lecture des données du module
$moduleData = json_decode(file_get_contents(self::TEMP_DIR . $tmpFolder . '/module.json'), true);
// Chargement des données du module importé
$this->setData(['module', $pageId, $moduleData]);
// Intégration des données du module importé dans la page
$this->setData(['page', $pageId, 'moduleId', $moduleId]);
// Copie des fichiers d'accompagnement
// Le dossier du module s'il existe
if (is_dir($tmpFolder . '/dataDirectory')) {
// Copier le dossier des données
$this->copyDir($tmpFolder . '/dataDirectory', self::DATA_DIR . '/' . $moduleId . '/' . $pageId);
}
// Supprimer le dossier temporaire
$this->removeDir(self::TEMP_DIR . $tmpFolder);
$zip->close();
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'plugin',
'state' => true,
'notification' => helper::translate('Données importées')
]);
}
// Bouton d'importation des données d'un module spécifique
if (count(explode('/', $this->getUrl())) === 6) {
// Jeton incorrect
if ($this->getUrl(3) !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'plugin',
'state' => false,
'notification' => helper::translate('Action interdite')
]);
}
// Traitement
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'plugin',
'state' => true,
'notification' => helper::translate('Données importées')
]);
}
/**
* Liste des pages sans module
* et ne sont pas des barres latérales
*/
self::$pagesList = $this->getHierarchy(null, null, null);
foreach (self::$pagesList as $page => $value) {
if (
$this->getData(['page', $page, 'block']) === 'bar' ||
//$this->getData(['page',$page,'disable']) === true ||
$this->getData(['page', $page, 'moduleId']) !== ''
) {
unset(self::$pagesList[$page]);
} else {
self::$pagesList[$page] = $page;
}
}
// Valeurs en sortie
$this->addOutput([
'title' => helper::translate('Importer des données de module'),
'view' => 'dataImport'
]);
}
} }

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

@ -0,0 +1,37 @@
<?php echo template::formOpen('pluginImportForm'); ?>
<div class="row">
<div class="col1">
<?php echo template::button('pluginImportBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'plugin',
'value' => template::ico('left')
]); ?>
</div>
<div class="col2 offset9">
<?php echo template::submit('pluginImportSubmit', [
'value' => 'Appliquer'
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Installer les données d\'un module'); ?>
</h4>
<div class="row">
<div class="col6">
<?php echo template::file('pluginImportFile', [
'language' => $this->getData(['user', $this->getUser('id'), 'language']),
'label' => 'Archive ZIP',
'type' => 2
]); ?>
</div>
<div class="col6">
<?php echo template::select('pluginImportPage', $module::$pagesList, [
'label' => 'Importer dans' . template::flag('selected', '20px')
]); ?>
</div>
</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/
*/ */
@ -17,3 +17,31 @@
* admin.css * admin.css
*/ */
/* Style the tab */
.tab {
margin-top: 1.8em;
overflow: hidden;
text-align: center;
}
.tab ~ .tabContent {
margin-top: -10px;
}
.buttonTab {
display: inline-block;
transition: 0.3s;
border-radius: 10px 10px 0px 0px;
width: 200px;
margin: 0 1px;
}
.buttonTab:hover {
filter: saturate(200%);
}
.activeButton {
background-color: #00BFFF;
}

View File

@ -0,0 +1,13 @@
/**
* 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-2023, Frédéric Tempez
* @license CC Attribution-NonCommercial-NoDerivatives 4.0 International
* @link http://zwiicms.fr/
*/
function setCookie(name,value,days){var expires="";if(days){var date=new Date;date.setTime(date.getTime()+24*days*60*60*1e3),expires="; expires="+date.toUTCString()}document.cookie=name+"="+(value||"")+expires+"; path=/; samesite=lax"}function getCookie(name){for(var nameEQ=name+"=",ca=document.cookie.split(";"),i=0;i<ca.length;i++){for(var c=ca[i];" "==c.charAt(0);)c=c.substring(1,c.length);if(0==c.indexOf(nameEQ))return c.substring(nameEQ.length,c.length)}return null}function capitalizeFirstLetter(string){return string.charAt(0).toUpperCase()+string.slice(1)}$(document).ready((function(){var pluginLayout=getCookie("pluginLayout");null==pluginLayout&&(pluginLayout="module",setCookie("pluginLayout","module")),console.log(pluginLayout),$("#moduleContainer").hide(),$("#dataContainer").hide(),$("#"+pluginLayout+"Container").show(),$("#plugin"+capitalizeFirstLetter(pluginLayout)+"Button").addClass("activeButton")})),$(".moduleDelete").on("click",(function(){var _this=$(this),message_delete="<?php echo helper::translate('Confirmer la désinstallation du module'); ?>";return core.confirm(message_delete,(function(){$(location).attr("href",_this.attr("href"))}))})),$(".dataDelete").on("click",(function(){var _this=$(this),message_unlink="<?php echo helper::translate('Confirmer la dissociation du module de cette page'); ?>";return core.confirm(message_unlink,(function(){$(location).attr("href",_this.attr("href"))}))})),$("#pluginModuleButton").on("click",(function(){$("#dataContainer").hide(),$("#moduleContainer").show(),$("#pluginModuleButton").addClass("activeButton"),$("#pluginDataButton").removeClass("activeButton"),setCookie("pluginLayout","module")})),$("#pluginDataButton").on("click",(function(){$("#moduleContainer").hide(),$("#dataContainer").show(),$("#pluginModuleButton").removeClass("activeButton"),$("#pluginDataButton").addClass("activeButton"),setCookie("pluginLayout","data")}));

View File

@ -3,17 +3,17 @@
<?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">
<?php /**echo template::button('pluginHelp', [ <?php /**echo template::button('pluginHelp', [
'href' => 'https://doc.zwiicms.fr/gestion-des-modules', 'href' => 'https://doc.zwiicms.fr/gestion-des-modules',
'target' => '_blank', 'target' => '_blank',
'value' => template::ico('help'), 'value' => template::ico('help'),
'class' => 'buttonHelp', 'class' => 'buttonHelp',
'help' => 'Consulter l\'aide en ligne' 'help' => 'Consulter l\'aide en ligne'
]);*/?> ]);*/ ?>
</div> </div>
<div class="col1 offset8"> <div class="col1 offset8">
<?php echo template::button('pluginModulesStore', [ <?php echo template::button('pluginModulesStore', [
@ -30,31 +30,70 @@
]); ?> ]); ?>
</div> </div>
</div> </div>
<?php if ($module::$modulesInstalled): ?> <div class="tab">
<div class="row"> <?php echo template::button('pluginModuleButton', [
<div class="col12"> 'value' => 'Modules installés',
<div class="block"> 'class' => ' buttonTab'
<h4> ]); ?>
<?php echo helper::translate('Sauvegarde'); ?> <?php echo template::button('pluginDataButton', [
</h4> 'value' => 'Données des modules',
<?php echo template::table([2, 2, 1, 5, 1, 1], $module::$modulesInstalled, ['Module', 'Identifiant', 'Version', '', '', '']); ?> 'class' => 'buttonTab'
]); ?>
</div>
<div class="tabContent" id="moduleContainer">
<?php if ($module::$modulesInstalled) : ?>
<div class="row">
<div class="col12">
<div class="block">
<h4><?php echo helper::translate('Sauvegarde'); ?>
</h4>
<?php echo template::table([2, 2, 1, 5, 1, 1], $module::$modulesInstalled, ['Module', 'Identifiant', 'Version', '', '', '']); ?>
</div>
</div> </div>
</div> </div>
</div> <?php else : ?>
<?php else: ?> <?php echo template::speech('Aucun module installé.'); ?>
<?php echo template::speech('Aucun module installé.'); ?> <?php endif; ?>
<?php endif; ?> <?php if ($module::$modulesOrphan) : ?>
<?php if ($module::$modulesOrphan): ?> <div class="row">
<div class="row"> <div class="col12">
<div class="col12"> <div class="block">
<div class="block"> <h4><?php echo helper::translate('Modules orphelins'); ?>
<h4> </h4>
<?php echo helper::translate('Modules orphelins'); ?> <?php echo template::table([2, 2, 1, 6, 1], $module::$modulesOrphan, ['Module', 'Identifiant', 'Version', '', '']); ?>
</h4> </div>
<?php echo template::table([2, 2, 1, 6, 1], $module::$modulesOrphan, ['Module', 'Identifiant', 'Version', '', '']); ?>
</div> </div>
</div> </div>
</div> <?php else : ?>
<?php else: ?> <?php echo template::speech('Aucun module orphelin.'); ?>
<?php echo template::speech('Aucun module orphelin.'); ?> <?php endif; ?>
<?php endif; ?> </div>
<div class="tabContent displayNone" id="dataContainer">
<?php if ($module::$modulesData) : ?>
<div class="row">
<div class="col12">
<div class="block">
<h4>
<?php echo helper::translate('Modules configurés'); ?>
</h4>
<div class="row">
<div class="col1 offset11">
<?php echo template::button('configModuledataImport', [
'href' => helper::baseUrl() . 'plugin/dataImport',
'value' => template::ico('upload'),
"help" => 'Importer des données de module dans une page libre'
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<?php echo template::table([4, 1, 4, 1, 1, 1], $module::$modulesData, ['Module', 'Version', 'Page associée', '', '', '']); ?>
</div>
</div>
</div>
</div>
</div>
<?php else : ?>
<?php echo template::speech('Aucune donnée de module.'); ?>
<?php endif; ?>
</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
* @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/
*/ */

File diff suppressed because it is too large Load Diff

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

@ -17,7 +17,7 @@
<div class="col1 offset8"> <div class="col1 offset8">
<?php echo template::button('configAdminReset', [ <?php echo template::button('configAdminReset', [
'class' => 'buttonRed', 'class' => 'buttonRed',
'href' => helper::baseUrl() . 'theme/reset/admin', 'href' => helper::baseUrl() . 'theme/reset/admin' . '&csrf=' . $_SESSION['csrf'],
'value' => template::ico('cancel'), 'value' => template::ico('cancel'),
'help' => 'Réinitialiser avec le thème par défaut' 'help' => 'Réinitialiser avec le thème par défaut'
]); ?> ]); ?>
@ -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.',
@ -139,7 +133,7 @@
<?php echo template::select('adminFontText', $module::$fonts['name'], [ <?php echo template::select('adminFontText', $module::$fonts['name'], [
'label' => 'Police du texte', 'label' => 'Police du texte',
'selected' => $this->getData(['admin', 'fontText']), 'selected' => $this->getData(['admin', 'fontText']),
'font' => $module::$fonts['family'] 'fonts' => $module::$fonts['family']
]); ?> ]); ?>
</div> </div>
<div class="col4"> <div class="col4">
@ -152,7 +146,7 @@
<?php echo template::select('adminFontTitle', $module::$fonts['name'], [ <?php echo template::select('adminFontTitle', $module::$fonts['name'], [
'label' => 'Police des titres', 'label' => 'Police des titres',
'selected' => $this->getData(['admin', 'fontTitle']), 'selected' => $this->getData(['admin', 'fontTitle']),
'font' => $module::$fonts['family'] 'fonts' => $module::$fonts['family']
]); ?> ]); ?>
</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

@ -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

@ -9,7 +9,7 @@
</div> </div>
<div class="col1 offset8"> <div class="col1 offset8">
<?php echo template::button('themeAdvancedReset', [ <?php echo template::button('themeAdvancedReset', [
'href' => helper::baseUrl() . 'theme/reset/custom', 'href' => helper::baseUrl() . 'theme/reset/custom' . '&csrf=' . $_SESSION['csrf'],
'class' => 'buttonRed', 'class' => 'buttonRed',
'value' => template::ico('cancel'), 'value' => template::ico('cancel'),
'help' => 'Réinitialiser la feuille de style' 'help' => 'Réinitialiser la feuille de style'

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

@ -34,23 +34,22 @@
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col6">
<?php echo template::text('themeBodyToTopColor', [
'class' => 'colorPicker',
'help' => 'Le curseur horizontal règle le niveau de transparence.',
'label' => 'Couleur icône haut de page',
'value' => $this->getData(['theme', 'body', 'toTopColor'])
]); ?>
</div>
<div class="col6"> <div class="col6">
<?php echo template::text('themeBodyToTopBackground', [ <?php echo template::text('themeBodyToTopBackground', [
'class' => 'colorPicker', 'class' => 'colorPicker',
'help' => 'Le curseur horizontal règle le niveau de transparence.', 'help' => 'Le curseur horizontal règle le niveau de transparence.',
'label' => 'Icône haut de page, couleur arrière-plan', 'label' => 'Fond icône haut de page',
'value' => $this->getData(['theme', 'body', 'toTopbackgroundColor']) 'value' => $this->getData(['theme', 'body', 'toTopbackgroundColor'])
]); ?> ]); ?>
</div> </div>
<div class="col6">
<?php echo template::text('themeBodyToTopColor', [
'class' => 'colorPicker',
'help' => 'Le curseur horizontal règle le niveau de transparence.',
'label' => 'Icône haut de page',
'value' => $this->getData(['theme', 'body', 'toTopColor'])
]); ?>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -65,6 +64,7 @@
<?php <?php
$imageFile = file_exists(self::FILE_DIR . 'source/' . $this->getData(['theme', 'body', 'image'])) ? $this->getData(['theme', 'body', 'image']) : ""; $imageFile = file_exists(self::FILE_DIR . 'source/' . $this->getData(['theme', 'body', 'image'])) ? $this->getData(['theme', 'body', 'image']) : "";
echo template::file('themeBodyImage', [ echo template::file('themeBodyImage', [
'help' => 'Sélectionner une image',
'language' => $this->getData(['user', $this->getUser('id'), 'language']), 'language' => $this->getData(['user', $this->getUser('id'), 'language']),
'label' => 'Arrière plan', 'label' => 'Arrière plan',
'type' => 1, 'type' => 1,

View File

@ -1,34 +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 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/
*/
$(".themeFontDelete").on("click", (function() {
var _this = $(this);
return core.confirm("Êtes-vous sûr de vouloir supprimer cette fonte ?", (function() {
$(location).attr("href", _this.attr("href"))
}))
}));
$('#dataTables').DataTable({
language: {
url: "core/vendor/datatables/french.json",
},
locale: 'fr',
stateSave: true,
"columnDefs": [{
target: 5,
orderable: false,
searchable: false
},
{
target: 6,
orderable: false,
searchable: false
}
]
});

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,15 +44,14 @@
<?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">
<?php echo template::text('fontEditFontName', [ <?php echo template::text('fontEditFontName', [
'autocomplete' => 'off', 'autocomplete' => 'off',
'label' => 'Nom', 'label' => 'Nom',
'value' => $this->getData(['font', $this->getUrl(2), $this->getUrl(3), 'name']) 'value' => $this->getData(['fonts', $this->getUrl(2), $this->getUrl(3), 'name'])
]); ?> ]); ?>
</div> </div>
</div> </div>
@ -61,16 +60,16 @@
<?php echo template::text('fontEditFontFamilyName', [ <?php echo template::text('fontEditFontFamilyName', [
'autocomplete' => 'off', 'autocomplete' => 'off',
'label' => 'Famille', 'label' => 'Famille',
'value' => stripslashes($this->getData(['font', $this->getUrl(2), $this->getUrl(3), 'font-family'])) 'value' => stripslashes($this->getData(['fonts', $this->getUrl(2), $this->getUrl(3), 'font-family']))
]); ?> ]); ?>
</div> </div>
</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(['fonts', $this->getUrl(2), $this->getUrl(3), 'resource']) : ''
]); ?> ]); ?>
</div> </div>
</div> </div>
@ -78,7 +77,7 @@
<div class="col12"> <div class="col12">
<?php echo template::text('fontEditUrl', [ <?php echo template::text('fontEditUrl', [
'label' => 'Url du fichier de fonte', 'label' => 'Url du fichier de fonte',
'value' => $this->getUrl(2) === 'imported' ? $this->getData(['font', $this->getUrl(2), $this->getUrl(3), 'resource']) : '' 'value' => $this->getUrl(2) === 'imported' ? $this->getData(['fonts', $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/
*/ */

View File

@ -1,22 +1,11 @@
/** /**
* This file is part of Zwii. * This file is part of Zwii.
*
* For full copyright and license information, please see the LICENSE * For full copyright and license information, please see the LICENSE
* file that was distributed with this source code. * 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> * @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(){var _this=$(this);return core.confirm("Êtes-vous sûr de vouloir supprimer cette fonte ?",(function(){$(location).attr("href",_this.attr("href"))}))}));
/** NE PAS EFFACER
* admin.css
*/
.containerPage, .containerModule {
display: none;
}

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/
*/ */

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