This commit is contained in:
Fred 2020-07-02 19:35:51 +02:00
parent c6aee2862f
commit 329f252d82
166 changed files with 603 additions and 383 deletions

0
core/class/SitemapGenerator.class.php Normal file → Executable file
View File

0
core/class/autoload.php Normal file → Executable file
View File

21
core/class/helper.class.php Normal file → Executable file
View File

@ -17,27 +17,6 @@ class helper {
const FILTER_TIMESTAMP = 10;
const FILTER_URL = 11;
/**
* Récupérer l'adresse IP sans tenit compte du proxy
* @return string IP adress
* Cette focntion est utilisé par user
*/
public static function getIp() {
if(!empty($_SERVER['HTTP_CLIENT_IP'])){
$ip=$_SERVER['HTTP_CLIENT_IP'];
}
elseif(!empty($_SERVER['HTTP_X_FORWARDED_FOR'])){
$ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
}
else{
$ip=$_SERVER['REMOTE_ADDR'];
}
return $ip;
}
/**
* Fonction pour récupérer le numéro de version en ligne
* @param string $url à récupérer

0
core/class/jsondb/Dot.class.php Normal file → Executable file
View File

0
core/class/jsondb/JsonDb.class.php Normal file → Executable file
View File

0
core/class/phpmailer/Exception.class.php Normal file → Executable file
View File

0
core/class/phpmailer/PHPMailer.class.php Normal file → Executable file
View File

0
core/class/phpmailer/SMTP.class.php Normal file → Executable file
View File

0
core/class/template.class.php Normal file → Executable file
View File

4
core/core.js.php Normal file → Executable file
View File

@ -125,7 +125,7 @@ core.end = function() {
// Ignore :
// - TinyMCE car il gère lui même le message
// - Les champs avec data-no-dirty
var inputsDOM = formDOM.find("input:not([data-no-dirty]), select:not([data-no-dirty]), textarea:not(.editorWysiwyg):not([data-no-dirty])");
var inputsDOM = formDOM.find("input:not([data-no-dirty]), select:not([data-no-dirty]), textarea:not(.editorWysiwyg,.editorWysiwygComment):not([data-no-dirty])");
var inputSerialize = inputsDOM.serialize();
$(window).on("beforeunload", function() {
if(inputsDOM.serialize() !== inputSerialize) {
@ -225,7 +225,7 @@ core.start = function() {
if(document.cookie.indexOf("ZWII_COOKIE_CONSENT") === -1) {
$("body").append(
$("<div>").attr("id", "cookieConsent").append(
$("<span>").text("En poursuivant votre navigation sur ce site, vous acceptez l'utilisation de cookies et de vos données de visite."),
$("<span>").text("En poursuivant votre navigation sur ce site, vous acceptez l'utilisation de cookies."),
$("<span>")
.attr("id", "cookieConsentConfirm")
.text("OK")

90
core/core.php Normal file → Executable file
View File

@ -39,7 +39,7 @@ class common {
const ACCESS_TIMER = 1800;
// Numéro de version
const ZWII_VERSION = '10.2.02';
const ZWII_VERSION = '10.2.00.dev34';
const ZWII_UPDATE_CHANNEL = "v10";
public static $actions = [];
@ -1314,48 +1314,21 @@ class common {
}
// Version 10.2.00
if ($this->getData(['core', 'dataVersion']) < 10200) {
// Paramètres du compte connecté
if ($this->getUser('id')) {
$this->setData(['user', $this->getUser('id'), 'connectFail',0]);
$this->setData(['user', $this->getUser('id'), 'connectTimeout',0]);
$this->setData(['user', $this->getUser('id'), 'accessTimer',0]);
$this->setData(['user', $this->getUser('id'), 'accessUrl','']);
$this->setData(['user', $this->getUser('id'), 'accessCsrf',$_SESSION['csrf']]);
}
// Paramètres de sécurité
$this->setData(['config', 'connect', 'attempt',999]);
$this->setData(['config', 'connect', 'timeout',0]);
$this->setData(['config', 'connect', 'log',false]);
// Thème
$this->deleteData(['admin','colorButtonText']);
// Remettre à zéro le thème pour la génération du CSS du blog
if (file_exists(self::DATA_DIR . 'theme.css')) {
unlink(self::DATA_DIR . 'theme.css');
}
// Créer les en-têtes du journal
$d = 'Date;Heure;IP;Id;Action' . PHP_EOL;
file_put_contents(self::DATA_DIR . 'journal.log',$d);
// Init préservation htaccess
$this->setData(['config','autoUpdateHtaccess',false]);
// Options de barre de membre simple
$this->setData(['theme','menu','memberBar',true]);
// Thème Menu : couleur de page active non définie
if (!$this->getData(['theme','menu','activeTextColor']) ) {
$this->setData(['theme','menu','activeTextColor', $this->getData(['theme','menu','textColor']) ]);
}
$this->setData(['core', 'updateAvailable', false]);
$this->deleteData(['admin','colorButtonText']);
$this->setData(['config', 'connect', 'attempt',999]);
$this->setData(['config', 'connect', 'timeout',0]);
$this->setData(['config', 'connect', 'log',false]);
// Remettre à zéro le thème pour la génération du CSS du blog
if (file_exists(self::DATA_DIR . 'theme.css')) {
unlink(self::DATA_DIR . 'theme.css');
}
// Créer les en-têtes du journal
$d = 'Date;Heure;Id;Action' . PHP_EOL;
file_put_contents(self::DATA_DIR . 'journal.log',$d);
// Init préservation htaccess
$this->setData(['config','autoUpdateHtaccess',false]);
$this->setData(['core', 'dataVersion', 10200]);
}
// Version 10.2.01
if ($this->getData(['core', 'dataVersion']) < 10201) {
// Options de barre de membre simple
$this->setData(['theme','footer','displayMemberBar',false]);
$this->setData(['theme','menu','memberBar',true]);
$this->deleteData(['theme','footer','displayMemberAccount']);
$this->deleteData(['theme','footer','displayMemberLogout']);
$this->setData(['core', 'dataVersion', 10201]);
}
}
}
@ -1452,9 +1425,9 @@ class core extends common {
$css .= 'a:hover{color:' . $colors['darken'] . '}';
$css .= 'body,.row > div{font-size:' . $this->getData(['theme', 'text', 'fontSize']) . '}';
$css .= 'body{color:' . $this->getData(['theme', 'text', 'textColor']) . '}';
$css .= 'select,input[type=\'password\'],input[type=\'email\'],input[type=\'text\'],.inputFile,select,textarea{color:' . $this->getData(['theme', 'text', 'textColor']) .';background-color:'.$this->getData(['theme', 'site', 'backgroundColor']).';}';
// spécifiques au module de blog
$css .= '.blogDate {color:' . $this->getData(['theme', 'text', 'textColor']) . ';}.blogPicture img{border:1px solid ' . $this->getData(['theme', 'text', 'textColor']) . '; box-shadow: 1px 1px 5px ' . $this->getData(['theme', 'text', 'textColor']) . ';}';
$css .= 'select,input[type=\'email\'],input[type=\'text\'],textarea{color:' . $this->getData(['theme', 'text', 'textColor']) .';background-color:'.$this->getData(['theme', 'site', 'backgroundColor']).';}';
// Couleur fixée dans admin.css
//$css .= '.button.buttonGrey,.button.buttonGrey:hover{color:' . $this->getData(['theme', 'text', 'textColor']) . '}';
$css .= '.container{max-width:' . $this->getData(['theme', 'site', 'width']) . '}';
@ -1463,6 +1436,7 @@ class core extends common {
$css .= $this->getData(['theme', 'site', 'width']) === '750px' ? '.button, button{font-size:0.8em;}' : '';
$css .= '#site{background-color:' . $this->getData(['theme', 'site', 'backgroundColor']) . ';border-radius:' . $this->getData(['theme', 'site', 'radius']) . ';box-shadow:' . $this->getData(['theme', 'site', 'shadow']) . ' #212223;}';
$css .= '.editorWysiwyg {background-color:' . $this->getData(['theme', 'site', 'backgroundColor']) . ';}';
$css .= '.editorWysiwygComment {background-color:' . $this->getData(['theme', 'site', 'backgroundColor']) . ';}';
$colors = helper::colorVariants($this->getData(['theme', 'button', 'backgroundColor']));
$css .= '.speechBubble,.button,.button:hover,button[type=\'submit\'],.pagination a,.pagination a:hover,input[type=\'checkbox\']:checked + label:before,input[type=\'radio\']:checked + label:before,.helpContent{background-color:' . $colors['normal'] . ';color:' . $colors['text'] . '}';
$css .= '.helpButton span{color:' . $colors['normal'] . '}';
@ -1476,6 +1450,7 @@ class core extends common {
// Les blocs
$colors = helper::colorVariants($this->getData(['theme', 'block', 'backgroundColor']));
$css .= '.block {border: 1px solid ' . $this->getdata(['theme','block','borderColor']) . ';}.block h4 {background-color:'. $colors['normal'] . ';color:' . $colors['text'] .';}';
// Contour du bloc édition de tinymce hors administration
$css .= '.mce-tinymce {border: 1px solid ' . $this->getdata(['theme','block','borderColor']) .' !important;}';
// Bannière
$colors = helper::colorVariants($this->getData(['theme', 'header', 'backgroundColor']));
@ -1536,31 +1511,26 @@ class core extends common {
$css .= '#toggle span,#menu a{padding:' . $this->getData(['theme', 'menu', 'height']) .';font-family:"' . str_replace('+', ' ', $this->getData(['theme', 'menu', 'font'])) . '",sans-serif;font-weight:' . $this->getData(['theme', 'menu', 'fontWeight']) . ';font-size:' . $this->getData(['theme', 'menu', 'fontSize']) . ';text-transform:' . $this->getData(['theme', 'menu', 'textTransform']) . '}';
// Pied de page
$colors = helper::colorVariants($this->getData(['theme', 'footer', 'backgroundColor']));
if($this->getData(['theme', 'footer', 'margin'])) {
$css .= 'footer{padding:0 20px;}';
} else {
$css .= 'footer{padding:0}';
}
$css .= 'footer span, #footerText > p {color:' . $this->getData(['theme', 'footer', 'textColor']) . ';font-family:"' . str_replace('+', ' ', $this->getData(['theme', 'footer', 'font'])) . '",sans-serif;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 a{color:' . $this->getData(['theme', 'footer', 'textColor']) . '}';
$css .= 'footer #footersite > div {margin:' . $this->getData(['theme', 'footer', 'height']) . ' 0}';
$css .= 'footer #footerbody > div {margin:' . $this->getData(['theme', 'footer', 'height']) . ' 0}';
$css .= '#footerSocials{text-align:' . $this->getData(['theme', 'footer', 'socialsAlign']) . '}';
$css .= '#footerText > p {text-align:' . $this->getData(['theme', 'footer', 'textAlign']) . '}';
$css .= '#footerCopyright{text-align:' . $this->getData(['theme', 'footer', 'copyrightAlign']) . '}';
// Marge supplémentaire lorsque le pied de page est fixe
if ( $this->getData(['theme', 'footer', 'fixed']) === true &&
$this->getData(['theme', 'footer', 'position']) === 'body') {
$css .= "@media (min-width: 769px) { #site {margin-bottom: 100px;} }";
$css .= "@media (max-width: 768px) { #site {margin-bottom: 150px;} }";
}
// Enregistre la personnalisation
file_put_contents(self::DATA_DIR.'theme.css', $css);
// Effacer le cache pour tenir compte de la couleur de fond TinyMCE
@ -1579,7 +1549,7 @@ class core extends common {
$css .= '#site{background-color:' . $colors['normal']. ';}';
$css .= 'body, .row > div {font:' . $this->getData(['admin','fontSize']) . ' "' . $this->getData(['admin','fontText']) . '", sans-serif;}';
$css .= 'body h1, h2, h3, h4, h5, h6 {font-family:' . $this->getData(['admin','fontTitle' ]) . ', sans-serif;color:' . $this->getData(['admin','colorTitle' ]) . ';}';
$css .= 'body:not(.editorWysiwyg),span .zwiico-help {color:' . $this->getData(['admin','colorText']) . ';}';
$css .= 'body:not(.editorWysiwyg),body:not(.editorWysiwygComment),span .zwiico-help {color:' . $this->getData(['admin','colorText']) . ';}';
$colors = helper::colorVariants($this->getData(['admin','backgroundColorButton']));
$css .= 'input[type="checkbox"]:checked + label::before,.speechBubble{background-color:' . $colors['normal'] . ';color:' . $colors['text'] . ';}';
$css .= '.speechBubble::before {border-color:' . $colors['normal'] . ' transparent transparent transparent;}';
@ -1592,7 +1562,7 @@ class core extends common {
$css .= 'button[type=submit] {background-color: ' . $colors['normal'] . ';color: ' . $colors['text'] . '}button[type=submit]:hover {background-color: ' . $colors['darken'] . ';color: ' . $colors['text'] .';}button[type=submit]:active {background-color: ' . $colors['darken'] . ';color: ' .$colors['text'] .';}';
$colors = helper::colorVariants($this->getData(['admin','backgroundBlockColor']));
$css .= '.block {border: 1px solid ' . $this->getData(['admin','borderBlockColor']) . ';}.block h4 {background-color: ' . $colors['normal'] . ';color:' . $colors['text'] . ';}';
$css .= 'table tr,input[type=email],input[type=text],input[type=password],select:not(#barSelectPage),textarea:not(.editorWysiwyg),.inputFile{background-color: ' . $colors['normal'] . ';color:' . $colors['text'] . ';border: 1px solid ' . $this->getData(['admin','borderBlockColor']) . ';}';
$css .= 'table tr,input[type=email],input[type=text],input[type=password],select:not(#barSelectPage),textarea:not(.editorWysiwyg),textarea:not(.editorWysiwygComment),.inputFile{background-color: ' . $colors['normal'] . ';color:' . $colors['text'] . ';border: 1px solid ' . $this->getData(['admin','borderBlockColor']) . ';}';
// Bordure du contour TinyMCE
$css .= '.mce-tinymce{border: 1px solid '. $this->getData(['admin','borderBlockColor']) . '!important;}';
// Enregistre la personnalisation
@ -1635,7 +1605,6 @@ class core extends common {
}
// Journalisation
$dataLog = strftime('%d/%m/%y',time()) . ';' . strftime('%R',time()) . ';' ;
$dataLog .= helper::getIp() . ';';
$dataLog .= $this->getUser('id') ? $this->getUser('id') . ';' : 'anonyme' . ';';
$dataLog .= $this->getUrl();
$dataLog .= PHP_EOL;
@ -2154,16 +2123,6 @@ class layout extends common {
strip_tags(str_replace('/', '_', $this->getUrl())) .
'" data-tippy-content="Connexion à l\'administration" rel="nofollow">Connexion</a></span>';
}
// Affichage de la barre de membre simple
if ( $this->getUser('group') === self::GROUP_MEMBER
&& $this->getData(['theme','footer','displayMemberBar']) === true
) {
$items .= '<span id="footerDisplayMemberAccount"';
$items .= $this->getData(['theme','footer','displaymemberAccount']) === false ? ' class="displayNone"' : '';
$items .= '><wbr>&nbsp;|<a href="' . helper::baseUrl() . 'user/edit/' . $this->getUser('id'). '/' . $_SESSION['csrf'] . '" data-tippy-content="Gérer mon compte" >' . template::ico('user', 'all') . '</a>';
$items .= '<wbr><a id="barLogout" href="' . helper::baseUrl() . 'user/logout" data-tippy-content="Me déconnecter">' . template::ico('logout','left') . '</a>';
$items .= '</span>';
}
// Fermeture du bloc copyright
$items .= '</span></div>';
echo $items;
@ -2373,15 +2332,6 @@ class layout extends common {
strip_tags(str_replace('/', '_', $this->getUrl())) .
'">Connexion</a></li>';
}
// Commandes pour les membres simples
if($this->getUser('group') == self::GROUP_MEMBER
&& ( $this->getData(['theme','menu','memberBar']) === true
|| $this->getData(['theme','footer','displayMemberBar']) === false
)
) {
$items .= '<li><a href="' . helper::baseUrl() . 'user/edit/' . $this->getUser('id'). '/' . $_SESSION['csrf'] . '" data-tippy-content="Gérer mon compte">' . template::ico('user', 'right') . '</a></li>';
$items .= '<li><a id="barLogout" href="' . helper::baseUrl() . 'user/logout" data-tippy-content="Me déconnecter">' . template::ico('logout') . '</a></li>';
}
// Retourne les items du menu
echo '<ul class="navLevel1">' . $items . '</ul>';
}
@ -2645,7 +2595,7 @@ class layout extends common {
}
}
$rightItems .= '<li><a href="' . helper::baseUrl() . 'user/edit/' . $this->getUser('id'). '/' . $_SESSION['csrf'] . '" data-tippy-content="Configurer mon compte">' . template::ico('user', 'right') . '<span id="displayUsername">' . $this->getUser('firstname') . ' ' . $this->getUser('lastname') . '</span></a></li>';
$rightItems .= '<li><a id="barLogout" href="' . helper::baseUrl() . 'user/logout" data-tippy-content="Me déconnecter">' . template::ico('logout') . '</a></li>';
$rightItems .= '<li><a id="barLogout" href="' . helper::baseUrl() . 'user/logout" data-tippy-content="Se déconnecter">' . template::ico('logout') . '</a></li>';
// Barre de membre
echo '<div id="bar"><div class="container"><ul id="barLeft">' . $leftItems . '</ul><ul id="barRight">' . $rightItems . '</ul></div></div>';
}

0
core/layout/blank.php Normal file → Executable file
View File

View File

@ -372,7 +372,7 @@ td > .col12 {
border: 0;
color: #111112;
font-size: 12px;
background-color: rgba(255, 255, 255, 1);
background-color: rgba(255, 255, 255, 1);
}
@media (min-width: 768px) {
@ -891,7 +891,7 @@ input[type='password'],
select,
textarea {
padding: 10px; /* -1px à cause des bordures */
/*background: #FFF;*/
background: #FFF;
border: 1px solid #D8DFE3;
width: 100%;
border-radius: 2px;

0
core/layout/light.php Normal file → Executable file
View File

0
core/layout/mail.php Normal file → Executable file
View File

4
core/layout/main.php Normal file → Executable file
View File

@ -20,9 +20,7 @@
}?>
</head>
<body>
<?php if($this->getUser('group') > self::GROUP_MEMBER): ?>
<?php $layout->showBar(); ?>
<?php endif;?>
<?php $layout->showBar(); ?>
<?php $layout->showNotification(); ?>
<?php if($this->getData(['theme', 'menu', 'position']) === 'body-first' || $this->getData(['theme', 'menu', 'position']) === 'top' ): ?>
<!-- Menu dans le fond du site avant la bannière -->

18
core/module/config/config.php Normal file → Executable file
View File

@ -283,17 +283,18 @@ class config extends common {
$data = str_replace('_','/',$googlePagespeedData['lighthouseResult']['audits']['final-screenshot']['details']['data']);
$data = str_replace('-','+',$data);
$img = base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $data));
$success = file_put_contents( self::FILE_DIR.'source/screenshot.jpg',$img) ;
// Effacer la miniature png
if (file_exists(self::FILE_DIR.'source/screenshot.png')) {
unlink (self::FILE_DIR.'source/screenshot.png');
// Effacer la miniature
if (file_exists(self::FILE_DIR.'thumb/screenshot.jpg')) {
unlink (self::FILE_DIR.'thumb/screenshot.jpg');
}
file_put_contents( self::FILE_DIR.'source/screenshot.jpg',$img);
$success =true;
}
// Valeurs en sortie
$this->addOutput([
'notification' => $success === false ? 'Service inaccessible ou erreur d\'écriture de l\'image' : 'Image générée avec succès',
'notification' => $success === true ? 'Image Open Graph réinitialisée' : 'Erreur : image Open Graph non créée',
'redirect' => helper::baseUrl() . 'config',
'state' => $success === false ? false : true
'state' => $success
]);
}
@ -358,7 +359,8 @@ class config extends common {
]);
}
// Préserver les comptes des utilisateurs d'une version 9 si option cochée
// Positionnement d'une variable de session lue au constructeurs
// Positionnement d'une variable de session lue au constructeur
echo $version;
if ($version === '9') {
$_SESSION['KEEP_USERS'] = $this->getInput('configManageImportUser', helper::FILTER_BOOLEAN);
}
@ -610,7 +612,7 @@ class config extends common {
if ( file_exists(self::DATA_DIR . 'journal.log') ) {
unlink(self::DATA_DIR . 'journal.log');
// Créer les en-têtes des journaux
$d = 'Date;Heure;IP;Id;Action' . PHP_EOL;
$d = 'Date;Heure;Id;Action' . PHP_EOL;
file_put_contents(self::DATA_DIR . 'journal.log',$d);
// Valeurs en sortie
$this->addOutput([

0
core/module/config/view/backup/backup.php Normal file → Executable file
View File

0
core/module/config/view/index/index.js.php Normal file → Executable file
View File

0
core/module/config/view/index/index.php Normal file → Executable file
View File

0
core/module/config/view/manage/manage.php Normal file → Executable file
View File

0
core/module/config/view/restore/restore.php Normal file → Executable file
View File

0
core/module/config/view/script/script.php Normal file → Executable file
View File

3
core/module/install/install.php Normal file → Executable file
View File

@ -81,7 +81,8 @@ class install extends common {
'group' => self::GROUP_ADMIN,
'lastname' => $userLastname,
'mail' => $userMail,
'password' => $this->getInput('installPassword', helper::FILTER_PASSWORD, true)
'password' => $this->getInput('installPassword', helper::FILTER_PASSWORD, true),
'pseudo' => $userFirstname
]
]);
if ($success === true) { // Formulaire complété envoi du mail

0
core/module/install/ressource/defaultdata.php Normal file → Executable file
View File

0
core/module/install/view/index/index.js.php Normal file → Executable file
View File

0
core/module/install/view/index/index.php Normal file → Executable file
View File

0
core/module/install/view/update/update.js.php Normal file → Executable file
View File

0
core/module/install/view/update/update.php Normal file → Executable file
View File

0
core/module/maintenance/maintenance.php Normal file → Executable file
View File

0
core/module/maintenance/view/index/index.php Normal file → Executable file
View File

0
core/module/page/page.php Normal file → Executable file
View File

40
core/module/page/view/edit/edit.js.php Normal file → Executable file
View File

@ -56,7 +56,7 @@ $( document ).ready(function() {
* Initialisation des blocs
*/
var i = ["info", "layout", "setup", "location", "advanced", "ceo" ];
var i = ["info", "layout", "setup", "position", "advanced", "ceo" ];
$.each(i,function(e) {
if (getCookie(i[e]) === "true") {
$("#" + i[e]).find(".zwiico-plus").hide();
@ -65,25 +65,30 @@ $( document ).ready(function() {
}
});
/**
* Lire un cookie s'il existe
*/
function getCookie(name) {
var v = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)');
return v ? v[2] : null;
}
/**
* Blocs dépliants
*
* Sauvegarder la position des blocs
* true = bloc déplié
*/
$("div .block").click(function(e) {
$(this).find(".zwiico-plus").toggle();
$(this).find(".zwiico-minus").toggle();
$(this).find(".blockContainer").slideToggle();
/*
$(this).find(".blockContainer").slideToggle();
/*
* Sauvegarder la position des blocs
* true = bloc déplié
*/
document.cookie = $(this).attr('id') + "=" + $(this).find(".zwiico-minus").is(":visible");
}).on("click", "span > input, input, textarea, label, option, button, a:not(.inputFile) , .blockContainer", function(e) {
document.cookie = $(this).attr('id') + "=" + $(this).find(".zwiico-minus").is(":visible");
}).on("click", "span > input, input, textarea, label, option, button, a, .blockContainer", function(e) {
// Empêcher les déclenchements dans les blocs
e.stopPropagation();
e.stopPropagation();
});
@ -257,9 +262,9 @@ $( document ).ready(function() {
$("#pageEditHideMenuChildrenWrapper").slideDown();
}
/**
* Cache le l'option "ne pas afficher les pages enfants dans le menu horizontal" lorsque la page est désactivée
*/
/**
* Cache le l'option "ne pas afficher les pages enfants dans le menu horizontal" lorsque la page est désactivée
*/
if ($("#pageEditDisable").is(':checked') ) {
$("#pageEditHideMenuChildrenWrapper").removeClass("disabled");
$("#pageEditHideMenuChildrenWrapper").slideUp();
@ -466,17 +471,6 @@ pageEditBlockDOM.on("change", function() {
}
});
/**
* Lire un cookie s'il existe
*/
function getCookie(name) {
var v = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)');
return v ? v[2] : null;
}
/**
* Masquer ou afficher le chemin de fer
* Quand le titre est masqué

0
core/module/page/view/edit/edit.php Normal file → Executable file
View File

0
core/module/search/search.php Normal file → Executable file
View File

0
core/module/search/view/index/index.php Normal file → Executable file
View File

0
core/module/search/view/result/result.php Normal file → Executable file
View File

0
core/module/sitemap/sitemap.php Normal file → Executable file
View File

0
core/module/sitemap/view/index/index.php Normal file → Executable file
View File

6
core/module/theme/theme.php Normal file → Executable file
View File

@ -375,8 +375,7 @@ class theme extends common {
'displaySiteMap' => $this->getInput('themefooterDisplaySiteMap', helper::FILTER_BOOLEAN),
'displayCopyright' => $this->getInput('themefooterDisplayCopyright', helper::FILTER_BOOLEAN),
'displayLegal' => $this->getInput('themeFooterDisplayLegal', helper::FILTER_BOOLEAN),
'displaySearch' => $this->getInput('themeFooterDisplaySearch', helper::FILTER_BOOLEAN),
'displayMemberBar'=> $this->getInput('themeFooterDisplayMemberBar', helper::FILTER_BOOLEAN),
'displaySearch' => $this->getInput('themeFooterDisplaySearch', helper::FILTER_BOOLEAN),
'template' => $this->getInput('themeFooterTemplate')
]]);
// Valeurs en sortie
@ -505,8 +504,7 @@ class theme extends common {
'activeColor' => $this->getInput('themeMenuActiveColor'),
'activeTextColor' => $this->getInput('themeMenuActiveTextColor'),
'radius' => $this->getInput('themeMenuRadius'),
'burgerTitle' => $this->getInput('themeMenuBurgerTitle', helper::FILTER_BOOLEAN),
'memberBar' => $this->getInput('themeMenuMemberBar', helper::FILTER_BOOLEAN)
'burgerTitle' => $this->getInput('themeMenuBurgerTitle', helper::FILTER_BOOLEAN)
]]);
// Valeurs en sortie
$this->addOutput([

0
core/module/theme/view/admin/admin.js.php Normal file → Executable file
View File

0
core/module/theme/view/admin/admin.php Normal file → Executable file
View File

0
core/module/theme/view/advanced/advanced.js.php Normal file → Executable file
View File

0
core/module/theme/view/advanced/advanced.php Normal file → Executable file
View File

0
core/module/theme/view/body/body.js.php Normal file → Executable file
View File

0
core/module/theme/view/body/body.php Normal file → Executable file
View File

0
core/module/theme/view/footer/footer.js.php Normal file → Executable file
View File

19
core/module/theme/view/footer/footer.php Normal file → Executable file
View File

@ -57,12 +57,6 @@
'help' => (bool) empty($this->getData(['config', 'legalPageId'])) ? 'Pour activer cette option, sélectionnez la page contenant les mentions légales dans la gestion du site' : ''
]); ?>
</div>
<div class="row">
<?php echo template::checkbox('themeFooterDisplayMemberBar', true, 'Barre des membres', [
'checked' => $this->getData(['theme', 'footer', 'displayMemberBar']),
'help' => 'Affiche les icônes de gestion du compte et de déconnexion. Uniquement pour les membres simples une fois connectés.'
]); ?>
</div>
</div>
<div class="col6">
<div class="row">
@ -71,16 +65,19 @@
'help' => 'Un plan du site permet un meilleur référencement.'
]); ?>
</div>
<div class="row">
<?php echo template::checkbox('themeFooterDisplaySearch', true, 'Rechercher', [
'checked' => $this->getData(['theme', 'footer', 'displaySearch'])
]); ?>
</div>
<div class="row">
<?php echo template::checkbox('themeFooterLoginLink', true, 'Lien de connexion', [
'checked' => $this->getData(['theme', 'footer', 'loginLink'])
]); ?>
</div>
<div class="row">
<?php echo template::checkbox('themeFooterDisplaySearch', true, 'Rechercher', [
'checked' => $this->getData(['theme', 'footer', 'displaySearch']),
]); ?>
</div>
</div>
<div class="col12">
<em>Le paramétrage des mentions légales s'effectue dans la configuration du site.</em>
</div>
</div>
</div>

0
core/module/theme/view/header/header.js.php Normal file → Executable file
View File

0
core/module/theme/view/header/header.php Normal file → Executable file
View File

0
core/module/theme/view/index/index.js.php Normal file → Executable file
View File

0
core/module/theme/view/index/index.php Normal file → Executable file
View File

0
core/module/theme/view/manage/manage.php Normal file → Executable file
View File

0
core/module/theme/view/menu/menu.js.php Normal file → Executable file
View File

13
core/module/theme/view/menu/menu.php Normal file → Executable file
View File

@ -168,19 +168,12 @@
<div class="block">
<h4>Contenus</h4>
<div class="row">
<div class="col4">
<div class="col6">
<?php echo template::checkbox('themeMenuLoginLink', true, 'Lien de connexion', [
'checked' => $this->getData(['theme', 'menu', 'loginLink']),
'help' => 'L\'activation de cette option n\'est pas recommandée'
'checked' => $this->getData(['theme', 'menu', 'loginLink'])
]); ?>
</div>
<div class="col4">
<?php echo template::checkbox('themeMenuMemberBar', true, 'Barre de membre', [
'checked' => $this->getData(['theme', 'menu', 'memberBar']),
'help' => 'Icônes de gestion de compte et de déconnexion. Uniquement pour les membres connectés'
]); ?>
</div>
<div class="col4">
<div class="col6">
<?php echo template::checkbox('themeMenuBurgerTitle', true, 'Titre du site dans le menu réduit', [
'checked' => $this->getData(['theme', 'menu', 'burgerTitle']),
'help' => 'Le menu burger remplace le menu complet lorsque la largeur de l\'écran n\'est pas suffisante.'

0
core/module/theme/view/site/site.js.php Normal file → Executable file
View File

0
core/module/theme/view/site/site.php Normal file → Executable file
View File

184
core/module/user/user.php Normal file → Executable file
View File

@ -26,6 +26,15 @@ class user extends common {
];
public static $users = [];
//Paramètre pour choix de la signature
public static $signature = [
1 => 'Identifiant',
2 => 'Pseudo',
3 => 'Prénom Nom',
4 => 'Nom Prénom'
];
/**
* Ajout
*/
@ -48,9 +57,12 @@ class user extends common {
$userFirstname = $this->getInput('userAddFirstname', helper::FILTER_STRING_SHORT, true);
$userLastname = $this->getInput('userAddLastname', helper::FILTER_STRING_SHORT, true);
$userMail = $this->getInput('userAddMail', helper::FILTER_MAIL, true);
$userPseudo = $this->getInput('userAddPseudo', helper::FILTER_STRING_SHORT, true);
$usersignature = $this->getInput('userAddSignature', helper::FILTER_STRING_SHORT, true);
// Pas de nom saisi
if (empty($userFirstname) ||
empty($userLastname) ||
empty($userPseudo) ||
empty($this->getInput('userAddPassword', helper::FILTER_STRING_SHORT, true)) ||
empty($this->getInput('userAddConfirmPassword', helper::FILTER_STRING_SHORT, true))) {
$check=false;
@ -65,8 +77,10 @@ class user extends common {
'forgot' => 0,
'group' => $this->getInput('userAddGroup', helper::FILTER_INT, true),
'lastname' => $userLastname,
'pseudo' => $userPseudo,
'signature' => $usersignature,
'mail' => $userMail,
'password' => $this->getInput('userAddPassword', helper::FILTER_PASSWORD, true),
'password' => $this->getInput('userAddPassword', helper::FILTER_PASSWORD, true)
]
]);
}
@ -210,15 +224,26 @@ class user extends common {
else {
$newGroup = $this->getData(['user', $this->getUrl(2), 'group']);
}
// Modification de nom Prénom
if($this->getUser('group') === self::GROUP_ADMIN){
$newfirstname = $this->getInput('userEditFirstname', helper::FILTER_STRING_SHORT, true);
$newlastname = $this->getInput('userEditLastname', helper::FILTER_STRING_SHORT, true);
}
else{
$newfirstname = $this->getData(['user', $this->getUrl(2), 'firstname']);
$newlastname = $this->getData(['user', $this->getUrl(2), 'lastname']);
}
// Modifie l'utilisateur
$this->setData([
'user',
$this->getUrl(2),
[
'firstname' => $this->getInput('userEditFirstname', helper::FILTER_STRING_SHORT, true),
'firstname' => $newfirstname,
'forgot' => 0,
'group' => $newGroup,
'lastname' => $this->getInput('userEditLastname', helper::FILTER_STRING_SHORT, true),
'lastname' => $newlastname,
'pseudo' => $this->getInput('userEditPseudo', helper::FILTER_STRING_SHORT, true),
'signature' => $this->getInput('userEditSignature', helper::FILTER_INT, true),
'mail' => $this->getInput('userEditMail', helper::FILTER_MAIL, true),
'password' => $newPassword,
'connectFail' => $this->getData(['user',$this->getUrl(2),'connectFail']),
@ -338,108 +363,97 @@ class user extends common {
if($this->isPost()) {
$userId = $this->getInput('userLoginId', helper::FILTER_ID, true);
/**
* Aucun compte existant
*/
if ( !$this->getData(['user', $userId])) {
// le userId n'existe pas, créer ou mettre à jour une entrée dans la liste noire
if( !$this->getData(['user', $userId])) {
//Stockage de l'IP
$this->setData([
'blacklist',
$userId,
[
'connectFail' => $this->getData(['blacklist',$userId,'connectFail']) + 1,
'connectFail' => $this->getData(['blacklist',$userId,'connectFail']) ? $this->getData(['blacklist',$userId,'connectFail']) + 1 : 1,
'lastFail' => time(),
'ip' => helper::getIp()
'ip' => $_SERVER['REMOTE_ADDR']
]
]);
// Verrouillage des IP
$ipBlackList = helper::arrayCollumn($this->getData(['blacklist']), 'ip');
if ( $this->getData(['blacklist',$userId,'connectFail']) >= $this->getData(['config', 'connect', 'attempt'])
OR in_array($this->getData(['blacklist',$userId,'ip']),$ipBlackList) ) {
// Valeurs en sortie
$notification = 'Identifiant ou mot de passe incorrect';
}
/**
* Compte valide :
* Mot de passe
* Groupe
*/
if( $this->getData(['user',$userId,'connectTimeout']) + $this->getData(['config', 'connect', 'timeout']) < time()
AND $this->getData(['user',$userId,'connectFail']) < $this->getData(['config', 'connect', 'attempt'])
AND password_verify($this->getInput('userLoginPassword', helper::FILTER_STRING_SHORT, true), $this->getData(['user', $userId, 'password']))
AND $this->getData(['user', $userId, 'group']) >= self::GROUP_MEMBER
) {
$expire = $this->getInput('userLoginLongTime') ? strtotime("+1 year") : 0;
setcookie('ZWII_USER_ID', $userId, $expire, helper::baseUrl(false, false));
setcookie('ZWII_USER_PASSWORD', $this->getData(['user', $userId, 'password']), $expire, helper::baseUrl(false, false));
// Accès multiples avec le même compte
$this->setData(['user',$userId,'accessCsrf',$_SESSION['csrf']]);
// Valeurs en sortie lorsque le site est en maintenance et que l'utilisateur n'est pas administrateur
if(
$this->getData(['config', 'maintenance'])
AND $this->getData(['user', $userId, 'group']) < self::GROUP_ADMIN
) {
$this->addOutput([
'notification' => 'Trop de tentatives, compte verrouillé',
'notification' => 'Seul un administrateur peut se connecter lors d\'une maintenance',
'redirect' => helper::baseUrl(),
'state' => false
]);
} else {
// Valeurs en sortie
$this->addOutput([
'notification' => 'Identifiant ou mot de passe incorrect'
]);
}
/**
* Le compte existe
*/
} else {
// Cas 4 : le délai de blocage est dépassé et le compte est au max - Réinitialiser
if ($this->getData(['user',$userId,'connectTimeout']) + $this->getData(['config', 'connect', 'timeout']) < time()
AND $this->getData(['user',$userId,'connectFail']) === $this->getData(['config', 'connect', 'attempt']) ) {
else {
// RAZ compteur échec connexion
$this->setData(['user',$userId,'connectFail',0 ]);
$this->setData(['user',$userId,'connectTimeout',0 ]);
}
// Check la présence des variables et contrôle du blocage du compte si valeurs dépassées
// Vérification du mot de passe et du groupe
if (
( $this->getData(['user',$userId,'connectTimeout']) + $this->getData(['config', 'connect', 'timeout']) ) < time()
AND $this->getData(['user',$userId,'connectFail']) < $this->getData(['config', 'connect', 'attempt'])
AND password_verify($this->getInput('userLoginPassword', helper::FILTER_STRING_SHORT, true), $this->getData(['user', $userId, 'password']))
AND $this->getData(['user', $userId, 'group']) >= self::GROUP_MEMBER
) {
$expire = $this->getInput('userLoginLongTime') ? strtotime("+1 year") : 0;
setcookie('ZWII_USER_ID', $userId, $expire, helper::baseUrl(false, false));
setcookie('ZWII_USER_PASSWORD', $this->getData(['user', $userId, 'password']), $expire, helper::baseUrl(false, false));
// Accès multiples avec le même compte
$this->setData(['user',$userId,'accessCsrf',$_SESSION['csrf']]);
// Valeurs en sortie lorsque le site est en maintenance et que l'utilisateur n'est pas administrateur
if(
$this->getData(['config', 'maintenance'])
AND $this->getData(['user', $userId, 'group']) < self::GROUP_ADMIN
) {
$this->addOutput([
'notification' => 'Seul un administrateur peut se connecter lors d\'une maintenance',
'redirect' => helper::baseUrl(),
'state' => false
]);
} else {
// Valeurs en sortie
$this->addOutput([
'notification' => 'Connexion réussie',
'redirect' => helper::baseUrl() . str_replace('_', '/', str_replace('__', '#', $this->getUrl(2))),
'state' => true
]);
}
// Sinon notification d'échec
} else {
$notification = 'Identifiant ou mot de passe incorrect';
// Cas 1 le nombre de connexions est inférieur aux tentatives autorisées : incrément compteur d'échec
if ($this->getData(['user',$userId,'connectFail']) < $this->getData(['config', 'connect', 'attempt'])) {
$this->setData(['user',$userId,'connectFail',$this->getdata(['user',$userId,'connectFail']) + 1 ]);
}
// Cas 2 la limite du nombre de connexion est atteinte : placer le timer
if ( $this->getdata(['user',$userId,'connectFail']) == $this->getData(['config', 'connect', 'attempt']) ) {
$this->setData(['user',$userId,'connectTimeout', time()]);
}
// Cas 3 le délai de bloquage court
if ($this->getData(['user',$userId,'connectTimeout']) + $this->getData(['config', 'connect', 'timeout']) > time() ) {
$notification = 'Trop de tentatives, accès bloqué durant ' . ($this->getData(['config', 'connect', 'timeout']) / 60) . ' minutes.';
}
// Journalisation
$dataLog = strftime('%d/%m/%y',time()) . ';' . strftime('%R',time()) . ';' ;
$dataLog .= helper::getIp() . ';';
$dataLog .= $userId . ';' ;
$dataLog .= $this->getUrl() .';' ;
$dataLog .= 'échec de connexion' ;
$dataLog .= PHP_EOL;
if ($this->getData(['config','connect','log'])) {
file_put_contents(self::DATA_DIR . 'journal.log', $dataLog, FILE_APPEND);
}
// Valeurs en sortie
$this->addOutput([
'notification' => $notification
'notification' => 'Connexion réussie',
'redirect' => helper::baseUrl() . str_replace('_', '/', str_replace('__', '#', $this->getUrl(2))),
'state' => true
]);
}
}
// Sinon notification d'échec
else {
// L'utilisateur existe : incrémenter le compteur d'échec de connexion
if ( is_array($this->getdata(['user',$userId]))
) {
$this->setData(['user',$userId,'connectFail',$this->getdata(['user',$userId,'connectFail']) + 1 ]);
// Mettre à jour le timer et notifier
if ( $this->getdata(['user',$userId,'connectFail']) >= $this->getData(['config', 'connect', 'attempt'])
) {
$notification = 'Trop de tentatives, accès bloqué durant ' . ($this->getData(['config', 'connect', 'timeout']) / 60) . ' minutes.';
// Incrémenter le timer
if ($this->getData(['user',$userId,'connectTimeout']) + $this->getData(['config', 'connect', 'timeout']) < time() ) {
$this->setData(['user',$userId,'connectTimeout', time()]);
}
} else {
$notification = 'Identifiant ou mot de passe incorrect';
}
// L'utilisateur n'existe pas
// Bloquer l'IP après les tentatives autorisées avec ce compte,
} elseif (
$this->getData(['blacklist',$userId,'connectFail']) >= $this->getData(['config', 'connect', 'attempt'])
) {
$notification = 'Trop de tentatives, compte verrouillé';
}
// Journalisation
$dataLog = strftime('%d/%m/%y',time()) . ';' . strftime('%R',time()) . ';' ;
$dataLog .= $userId . ';' ;
$dataLog .= $this->getUrl() .';' ;
$dataLog .= 'échec de connexion' ;
$dataLog .= PHP_EOL;
if ($this->getData(['config','connect','log'])) {
file_put_contents(self::DATA_DIR . 'journal.log', $dataLog, FILE_APPEND);
}
// Valeurs en sortie
$this->addOutput([
'notification' => $notification
]);
}
}
// Valeurs en sortie
$this->addOutput([

0
core/module/user/view/add/add.js.php Normal file → Executable file
View File

8
core/module/user/view/add/add.php Normal file → Executable file
View File

@ -30,6 +30,14 @@
]); ?>
</div>
</div>
<?php echo template::text('userAddPseudo', [
'autocomplete' => 'off',
'label' => 'Pseudo'
]); ?>
<?php echo template::select('userAddSignature', $module::$signature, [
'label' => 'Signature',
'selected' => 1
]); ?>
<?php echo template::mail('userAddMail', [
'autocomplete' => 'off',
'label' => 'Adresse mail'

0
core/module/user/view/edit/edit.js.php Normal file → Executable file
View File

16
core/module/user/view/edit/edit.php Normal file → Executable file
View File

@ -1,7 +1,10 @@
<?php echo template::formOpen('userEditForm'); ?>
<?php if( $this->getUser('group') > 2): $readonly = false;
else: $readonly = true;
endif;?>
<div class="row">
<div class="col2">
<?php if($this->getUser('group') === self::GROUP_ADMIN): ?>
<?php if($this->getUrl(3)): ?>
<?php echo template::button('userEditBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'user',
@ -29,6 +32,7 @@
<div class="col6">
<?php echo template::text('userEditFirstname', [
'autocomplete' => 'off',
'disabled' => $readonly,
'label' => 'Prénom',
'value' => $this->getData(['user', $this->getUrl(2), 'firstname'])
]); ?>
@ -36,11 +40,21 @@
<div class="col6">
<?php echo template::text('userEditLastname', [
'autocomplete' => 'off',
'disabled' => $readonly,
'label' => 'Nom',
'value' => $this->getData(['user', $this->getUrl(2), 'lastname'])
]); ?>
</div>
</div>
<?php echo template::text('userEditPseudo', [
'autocomplete' => 'off',
'label' => 'Pseudo',
'value' => $this->getData(['user', $this->getUrl(2), 'pseudo'])
]); ?>
<?php echo template::select('userEditSignature', $module::$signature, [
'label' => 'Signature',
'selected' => $this->getData(['user', $this->getUrl(2), 'signature'])
]); ?>
<?php echo template::mail('userEditMail', [
'autocomplete' => 'off',
'label' => 'Adresse mail',

0
core/module/user/view/forgot/forgot.php Normal file → Executable file
View File

0
core/module/user/view/index/index.js.php Normal file → Executable file
View File

0
core/module/user/view/index/index.php Normal file → Executable file
View File

0
core/module/user/view/login/login.php Normal file → Executable file
View File

0
core/module/user/view/reset/reset.php Normal file → Executable file
View File

0
core/vendor/filemanager/UploadHandler.php vendored Normal file → Executable file
View File

0
core/vendor/filemanager/ajax_calls.php vendored Normal file → Executable file
View File

0
core/vendor/filemanager/config/config.php vendored Normal file → Executable file
View File

File diff suppressed because one or more lines are too long

0
core/vendor/filemanager/dialog.php vendored Normal file → Executable file
View File

0
core/vendor/filemanager/execute.php vendored Normal file → Executable file
View File

0
core/vendor/filemanager/force_download.php vendored Normal file → Executable file
View File

0
core/vendor/filemanager/include/FtpClient.php vendored Normal file → Executable file
View File

0
core/vendor/filemanager/include/FtpException.php vendored Normal file → Executable file
View File

0
core/vendor/filemanager/include/FtpWrapper.php vendored Normal file → Executable file
View File

0
core/vendor/filemanager/include/Response.php vendored Normal file → Executable file
View File

0
core/vendor/filemanager/include/ftp_class.php vendored Normal file → Executable file
View File

0
core/vendor/filemanager/include/mime_type_lib.php vendored Normal file → Executable file
View File

0
core/vendor/filemanager/include/php_image_magician.php vendored Normal file → Executable file
View File

0
core/vendor/filemanager/include/utils.php vendored Normal file → Executable file
View File

0
core/vendor/filemanager/index.php vendored Normal file → Executable file
View File

0
core/vendor/filemanager/lang/az_AZ.php vendored Normal file → Executable file
View File

0
core/vendor/filemanager/lang/bg_BG.php vendored Normal file → Executable file
View File

0
core/vendor/filemanager/lang/ca.php vendored Normal file → Executable file
View File

0
core/vendor/filemanager/lang/cs.php vendored Normal file → Executable file
View File

0
core/vendor/filemanager/lang/da.php vendored Normal file → Executable file
View File

0
core/vendor/filemanager/lang/de.php vendored Normal file → Executable file
View File

0
core/vendor/filemanager/lang/el_GR.php vendored Normal file → Executable file
View File

0
core/vendor/filemanager/lang/en_EN.php vendored Normal file → Executable file
View File

0
core/vendor/filemanager/lang/es.php vendored Normal file → Executable file
View File

0
core/vendor/filemanager/lang/fa.php vendored Normal file → Executable file
View File

0
core/vendor/filemanager/lang/fr_FR.php vendored Normal file → Executable file
View File

0
core/vendor/filemanager/lang/he_IL.php vendored Normal file → Executable file
View File

0
core/vendor/filemanager/lang/hr.php vendored Normal file → Executable file
View File

0
core/vendor/filemanager/lang/hu_HU.php vendored Normal file → Executable file
View File

0
core/vendor/filemanager/lang/id.php vendored Normal file → Executable file
View File

0
core/vendor/filemanager/lang/it.php vendored Normal file → Executable file
View File

0
core/vendor/filemanager/lang/ja.php vendored Normal file → Executable file
View File

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