Merge branch 'beta' into module_rechercher

This commit is contained in:
Fred Tempez 2020-08-14 16:10:02 +02:00
commit f3013b0764
54 changed files with 405 additions and 279 deletions

View File

@ -1,5 +1,16 @@
# Changelog
## version 10.3.00
- Corrections :
- Bloquage de l'incrémentation de l'id de page lorsque deux pages ont le même nom.
- Login : l'option "Se souvenir de moi" est fonctionnelle.
- Menu : déplacement de la classe "active".
- Modifications :
- Configuration du site :
- Pages 403 (accès interdit) et 404 (page introuvable) personnalisables
- Sauvegarde du site dans une archive : animation d'attente avec message de confirmation ou d'erreur. ; le nom de l'archive prend le nom du sous-domaine s'il existe.
- Captcha : addition présentée en lettres sous la forme d'images, réponse en chiffres ; correction du nom de la fonction (capcha en captcha).
## version 10.2.06
- Corrections :
- Anticipation de la dépréciation de l'option de cookie samesite=none.

View File

@ -1,6 +1,6 @@
![](https://img.shields.io/github/last-commit/fredtempez/ZwiiCMS/master) ![](https://img.shields.io/github/release-date/fredtempez/ZwiiCMS)
# ZwiiCMS 10.2.06
# ZwiiCMS 10.2.07
Zwii est un CMS sans base de données (flat-file) qui permet de créer et gérer facilement un site web sans aucune connaissance en programmation.

View File

@ -98,7 +98,9 @@ class helper {
public static function autoBackup($folder, $filter = ['backup','tmp'] ) {
// Creation du ZIP
$fileName = 'ZwiiCMS-backup'. date('Y-m-d-h-i-s', time()) . '.zip';
$baseName = str_replace('/','',helper::baseUrl(false,false));
$baseName = empty($baseName) ? 'ZwiiCMS' : $baseName;
$fileName = $baseName . '-backup-' . date('Y-m-d-h-i-s', time()) . '.zip';
$zip = new ZipArchive();
$zip->open($folder . $fileName, ZipArchive::CREATE | ZipArchive::OVERWRITE);
$directory = 'site/';

View File

@ -33,12 +33,12 @@ class template {
}
/**
* Crée un champ capcha
* Crée un champ captcha
* @param string $nameId Nom et id du champ
* @param array $attributes Attributs ($key => $value)
* @return string
*/
public static function capcha($nameId, array $attributes = []) {
public static function captcha($nameId, array $attributes = []) {
// Attributs par défaut
$attributes = array_merge([
'class' => '',
@ -48,15 +48,18 @@ class template {
'name' => $nameId,
'value' => ''
], $attributes);
// Génère deux nombres pour le capcha
$firstNumber = mt_rand(1, 15);
$secondNumber = mt_rand(1, 15);
// Génère deux nombres pour le captcha
$numbers = array(0,1,2,3,4,5,6,7,8,9,10,12,13,14,15,16,17,18,19,20);
$letters = array('u','t','s','r','q','p','o','n','m','l','k','j','i','h','g','f','e','d','c','b','a');
$firstNumber = rand ( 0 , count($letters)-1 );
$secondNumber = rand ( 0 , count($letters)-1 );
// Début du wrapper
$html = '<div id="' . $attributes['id'] . 'Wrapper" class="inputWrapper ' . $attributes['classWrapper'] . '">';
// Label
$html .= self::label($attributes['id'], $firstNumber . ' + ' . $secondNumber . ' = ?', [
'help' => $attributes['help']
]);
$html .= self::label($attributes['id'],
'<img class="captchaNumber" src="core/vendor/zwiico/png/'.$letters[$firstNumber] . '.png" /> + <img class="captchaNumber" src="core/vendor/zwiico/png/' . $letters[$secondNumber] . '.png" /> = en chiffres ?', [
'help' => $attributes['help']
]);
// Notice
$notice = '';
if(array_key_exists($attributes['id'], common::$inputNotices)) {
@ -64,7 +67,7 @@ class template {
$attributes['class'] .= ' notice';
}
$html .= self::notice($attributes['id'], $notice);
// Capcha
// captcha
$html .= sprintf(
'<input type="text" %s>',
helper::sprintAttributes($attributes)
@ -241,7 +244,7 @@ class template {
'value' => $attributes['value']
]);
// Champ d'upload
$html .= '<div>';
$html .= '<div class="inputFileManagerWrapper">';
$html .= sprintf(
'<a
href="' .
@ -249,7 +252,6 @@ class template {
'?relative_url=1' .
'&field_id=' . $attributes['id'] .
'&type=' . $attributes['type'] .
//'&akey=' . md5_file('site/data/'.'core.json') .
'&akey=' . md5_file(core::DATA_DIR.'core.json') .
($attributes['extensions'] ? '&extensions=' . $attributes['extensions'] : '')
. '"

View File

@ -39,7 +39,7 @@ class common {
const ACCESS_TIMER = 1800;
// Numéro de version
const ZWII_VERSION = '10.2.06';
const ZWII_VERSION = '10.3.00';
const ZWII_UPDATE_CHANNEL = "v10";
public static $actions = [];
@ -1351,11 +1351,17 @@ class common {
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]);
}
// Version 10.3.00
if ($this->getData(['core', 'dataVersion']) < 10300) {
// Options de barre de membre simple
$this->setData(['config','page404','none']);
$this->setData(['config','page403','none']);
$this->setData(['core', 'dataVersion', 10300]);
}
}
}
@ -1946,18 +1952,26 @@ class core extends common {
'content' => template::speech('La page <strong>' . $accessInfo['pageId'] . '</strong> est ouverte par l\'utilisateur <strong>' . $accessInfo['userName'] . '</strong>')
]);
} else {
$this->addOutput([
'title' => 'Erreur 403',
'content' => template::speech('Vous n\'êtes pas autorisé à accéder à cette page...')
]);
if ( $this->getData(['config','page403']) === 'none') {
$this->addOutput([
'title' => 'Erreur 403',
'content' => template::speech('Vous n\'êtes pas autorisé à accéder à cette page...')
]);
} else {
header('Location:' . helper::baseUrl() . $this->getData(['config','page403']));
}
}
}
elseif($this->output['content'] === '') {
http_response_code(404);
$this->addOutput([
'title' => 'Erreur 404',
'content' => template::speech('Oups ! La page demandée est introuvable...')
]);
if ( $this->getData(['config','page404']) === 'none') {
$this->addOutput([
'title' => 'Erreur 404',
'content' => template::speech('Oups ! La page demandée est introuvable...')
]);
} else {
header('Location:' . helper::baseUrl() . $this->getData(['config','page404']));
}
}
// Mise en forme des métas
if($this->output['metaTitle'] === '') {
@ -2258,7 +2272,7 @@ class layout extends common {
foreach($this->getHierarchy() as $parentPageId => $childrenPageIds) {
// Passer les entrées masquées
// Propriétés de l'item
$active = ($parentPageId === $currentPageId OR in_array($currentPageId, $childrenPageIds)) ? ' class="active"' : '';
$active = ($parentPageId === $currentPageId OR in_array($currentPageId, $childrenPageIds)) ? 'active ' : '';
$targetBlank = $this->getData(['page', $parentPageId, 'targetBlank']) ? ' target="_blank"' : '';
// Mise en page de l'item
$items .= '<li>';
@ -2268,7 +2282,7 @@ class layout extends common {
{$items .= '<a class="' . $parentPageId . '" href="'.$this->getUrl(1).'">';
} else {
$items .= '<a class="' . $parentPageId . '" href="' . helper::baseUrl() . $parentPageId . '"' . $active . $targetBlank . '>';
$items .= '<a class="' . $active . $parentPageId . '" href="' . helper::baseUrl() . $parentPageId . '"' . $targetBlank . '>';
}
switch ($this->getData(['page', $parentPageId, 'typeMenu'])) {
@ -2314,7 +2328,7 @@ class layout extends common {
$items .= '<ul class="navLevel2">';
foreach($childrenPageIds as $childKey) {
// Propriétés de l'item
$active = ($childKey === $currentPageId) ? ' class="active"' : '';
$active = ($childKey === $currentPageId) ? 'active ' : '';
$targetBlank = $this->getData(['page', $childKey, 'targetBlank']) ? ' target="_blank"' : '';
// Mise en page du sous-item
$items .= '<li>';
@ -2322,7 +2336,7 @@ class layout extends common {
AND $this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD') ) {
$items .= '<a class="' . $parentPageId . '" href="'.$this->getUrl(1).'">';
} else {
$items .= '<a class="' . $parentPageId . '" href="' . helper::baseUrl() . $childKey . '"' . $active . $targetBlank . '>';
$items .= '<a class="' . $active . $parentPageId . '" href="' . helper::baseUrl() . $childKey . '"' . $targetBlank . '>';
}
switch ($this->getData(['page', $childKey, 'typeMenu'])) {
@ -2422,7 +2436,7 @@ class layout extends common {
continue;
}
// Propriétés de l'item
$active = ($parentPageId === $currentPageId OR in_array($currentPageId, $childrenPageIds)) ? ' class="active"' : '';
$active = ($parentPageId === $currentPageId OR in_array($currentPageId, $childrenPageIds)) ? 'active ' : '';
$targetBlank = $this->getData(['page', $parentPageId, 'targetBlank']) ? ' target="_blank"' : '';
// Mise en page de l'item;
// Ne pas afficher le parent d'une sous-page quand l'option est sélectionnée.
@ -2432,7 +2446,7 @@ class layout extends common {
AND $this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD') ) {
$items .= '<a href="'.$this->getUrl(1).'">';
} else {
$items .= '<a href="' . helper::baseUrl() . $parentPageId . '"' . $active . $targetBlank . '>';
$items .= '<a href="' . $active . helper::baseUrl() . $parentPageId . '"' . $targetBlank . '>';
}
$items .= $this->getData(['page', $parentPageId, 'title']);
$items .= '</a>';
@ -2445,7 +2459,7 @@ class layout extends common {
}
// Propriétés de l'item
$active = ($childKey === $currentPageId) ? ' class="active"' : '';
$active = ($childKey === $currentPageId) ? 'active ' : '';
$targetBlank = $this->getData(['page', $childKey, 'targetBlank']) ? ' target="_blank"' : '';
// Mise en page du sous-item
$itemsChildren .= '<li class="menuSideChild">';
@ -2454,7 +2468,7 @@ class layout extends common {
AND $this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD') ) {
$itemsChildren .= '<a href="'.$this->getUrl(1).'">';
} else {
$itemsChildren .= '<a href="' . helper::baseUrl() . $childKey . '"' . $active . $targetBlank . '>';
$itemsChildren .= '<a href="' .$active . helper::baseUrl() . $childKey . '"' . $targetBlank . '>';
}
$itemsChildren .= $this->getData(['page', $childKey, 'title']);

View File

@ -448,12 +448,12 @@ header .container {
height: 100%;
}
/* Element du header */
/* Element du header
#themeHeaderImage {
font-style: italic;
font-size: 0.9em;
}
}*/
/* Menu
body > nav {
@ -1019,6 +1019,16 @@ label {
text-decoration: none;
}
/* Empêche le débordement et les sauts de ligne */
.inputFileManagerWrapper {
display: inline;
}
.inputFileManagerWrapper > .inputFile {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
/* Pagination */
.pagination {
padding: 10px 0;
@ -1359,3 +1369,11 @@ th.col12 {
.accordion-content {
padding: 7px;
}
/* Captcha
* Taille des images
*/
.captchaNumber {
height:20px;
vertical-align: middle;
}

View File

@ -8,7 +8,7 @@
*
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* * @author Frédéric Tempez <frederic.tempez@outlook.com>
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2020, Frédéric Tempez
* @license GNU General Public License, version 3
* @link http://zwiicms.com/
@ -246,17 +246,19 @@ class config extends common {
// Creation du ZIP
$filter = $this->getInput('configBackupOption',helper::FILTER_BOOLEAN) === true ? ['backup','tmp'] : ['backup','tmp','file'];
$fileName = helper::autoBackup(self::TEMP_DIR,$filter);
// Téléchargement du ZIP
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename="' . $fileName . '"');
header('Content-Length: ' . filesize(self::TEMP_DIR . $fileName));
readfile(self::TEMP_DIR . $fileName);
// Créer le répertoire manquant
if (!is_dir(self::FILE_DIR.'source/backup')) {
mkdir(self::FILE_DIR.'source/backup');
}
// Copie dans les fichiers
$success = copy (self::TEMP_DIR . $fileName , self::FILE_DIR.'source/backup/' . $fileName);
// Détruire le temporaire
unlink(self::TEMP_DIR . $fileName);
// Valeurs en sortie
$this->addOutput([
'display' => self::DISPLAY_RAW
'display' => self::DISPLAY_JSON,
'content' => json_encode($success)
]);
unlink(self::TEMP_DIR . $fileName);
} else {
// Valeurs en sortie
$this->addOutput([
@ -417,11 +419,14 @@ class config extends common {
} else {
$legalPageId = '';
}
$this->getInput('configPage404');
// Sauvegarder
$this->setData([
'config',
[
'homePageId' => $this->getInput('configHomePageId', helper::FILTER_ID, true),
'page404' => $this->getInput('configPage404'),
'page403' => $this->getInput('configPage403'),
'analyticsId' => $this->getInput('configAnalyticsId'),
'autoBackup' => $this->getInput('configAutoBackup', helper::FILTER_BOOLEAN),
'maintenance' => $this->getInput('configMaintenance', helper::FILTER_BOOLEAN),

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

View File

@ -13,3 +13,45 @@
*/
@import url("site/data/admin.css");
/**
* Effet d'animation
*/
/* Start by setting display:none to make this hidden.
Then we position it in relation to the viewport window
with position:fixed. Width, height, top and left speak
for themselves. Background we set to 80% white with
our animation centered, and no-repeating */
.modal {
display: none;
position: fixed;
z-index: 1000;
top: 0;
left: 0;
height: 100%;
width: 100%;
background: rgba( 0, 0, 0, .9 )
url('core/module/config/ressource/ajax-loader.png')
50% 45%
no-repeat;
}
.alertMessage {
color: lightgrey;
display: none;
display: flex;
align-items: center;
justify-content: center;
}
/* When the body has the loading class, we turn
the scrollbar off with overflow:hidden */
body.loading .modal .alertMessage {
overflow: hidden;
}
/* Anytime the body has the loading class, our
modal element will be visible */
body.loading .modal .alertMessage {
display: block;
}

View File

@ -0,0 +1,39 @@
/**
* 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-2020, Frédéric Tempez
* @license GNU General Public License, version 3
* @link http://zwiicms.com/
*/
$( document).ready(function() {
$("#configBackupForm").submit( function(e){
$("#configBackupSubmit").addClass("disabled").prop("disabled", true);
e.preventDefault();
$("body").addClass("loading");
$(".modal").addClass("alertMessage");
var url = "<?php echo helper::baseUrl() . $this->getUrl(0); ?>/backup";
$.ajax({
type: "POST",
url: url,
data: $("form").serialize(),
success: function(data){
$("body").removeClass("loading");
core.alert("La sauvegarde a été générée avec succès.");
},
error: function(data){
$("body").removeClass("loading");
core.alert("Une erreur s'est produite, la sauvegarde n'a pas été générée !");
},
complete: function(){
$("#configBackupSubmit").removeClass("disabled").prop("disabled", false);
$(".modal").removeClass("alertMessage");
}
});
});
});

View File

@ -10,22 +10,25 @@
</div>
<div class="col2 offset8">
<?php echo template::submit('configBackupSubmit',[
'value' => 'Valider',
'ico' => 'check'
]); ?>
'value' => 'Sauvegarder'
]); ?>
</div>
<div class="modal">Merci de patienter, je travaille pour vous.<!-- Emplacement pour l'animation --></div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Paramètre</h4>
<div class="row">
<div class="col8 offset1">
<div class="col12">
<?php echo template::checkbox('configBackupOption', true, 'Inclure le contenu du gestionnaire de fichiers', [
'checked' => true,
'help' => 'Cette option n\'est pas recommandée lorsque le contenu du gestionnaire de fichiers est très volumineux.'
'help' => 'Si le contenu du gestionnaire de fichiers est très volumineux, mieux vaut une copie par FTP.'
]); ?>
</div>
<div class="col12">
<em>L'archive est générée dans <a href="<?php echo helper::baseUrl(false); ?>core/vendor/filemanager/dialog.php?fldr=backup&type=0&akey=<?php echo md5_file(self::DATA_DIR.'core.json'); ?>" data-lity>le dossier Backup</a> du gestionnaire de fichiers.</em>
</div>
</div>
</div>
</div>

View File

@ -11,15 +11,13 @@
<div class="col2 offset4">
<?php echo template::button('configManageButton', [
'href' => helper::baseUrl() . 'config/backup',
'value' => 'Sauvegarder',
'ico' => 'download'
'value' => 'Sauvegarder'
]); ?>
</div>
<div class="col2">
<?php echo template::button('configManageButton', [
'href' => helper::baseUrl() . 'config/manage',
'value' => 'Restaurer',
'ico' => 'upload'
'value' => 'Restaurer'
]); ?>
</div>
<div class="col2">
@ -31,21 +29,7 @@
<div class="block">
<h4>Informations générales</h4>
<div class="row">
<div class="col4">
<?php
$pages = $this->getData(['page']);
foreach($pages as $page => $pageId) {
if ($this->getData(['page',$page,'block']) === 'bar' ||
$this->getData(['page',$page,'disable']) === true) {
unset($pages[$page]);
}
}
echo template::select('configHomePageId', helper::arrayCollumn($pages, 'title', 'SORT_ASC'), [
'label' => 'Page d\'accueil',
'selected' =>$this->getData(['config', 'homePageId'])
]); ?>
</div>
<div class="col8">
<div class="col12">
<?php echo template::text('configTitle', [
'label' => 'Titre du site',
'value' => $this->getData(['config', 'title']),
@ -58,13 +42,62 @@
<?php echo template::textarea('configMetaDescription', [
'label' => 'Description du site',
'value' => $this->getData(['config', 'metaDescription']),
'help' => 'Elle apparaît dans les partages sur les réseaux sociaux.'
'help' => 'La description participe au référence, n\'oubliez pas de personnaliser la description de chaque page sans copié collé.'
]); ?>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Pages spéciales</h4>
<div class="row">
<div class="col6">
<?php
$pages = $this->getData(['page']);
foreach($pages as $page => $pageId) {
if ($this->getData(['page',$page,'block']) === 'bar' ||
$this->getData(['page',$page,'disable']) === true) {
unset($pages[$page]);
}
}
echo template::select('configHomePageId', helper::arrayCollumn($pages, 'title', 'SORT_ASC'), [
'label' => 'Accueil du site',
'selected' =>$this->getData(['config', 'homePageId']),
'help' => 'La page par défaut, c\'est la première page vue par vos visiteurs'
]); ?>
</div>
<div class="col6">
<?php echo template::select('configLegalPageId', array_merge(['' => 'Sélectionner'] , helper::arrayCollumn($this->getData(['page']), 'title', 'SORT_ASC') ) , [
'label' => 'Mentions légales',
'selected' => $this->getData(['config', 'legalPageId']),
'help' => 'Les mentions légales sont obligatoires en France. Une option du thèmz - pied de page ajoute un lien discret vers cette page.'
]); ?>
</div>
</div>
<div class="row">
<div class="col6">
<?php
echo template::select('configPage403', array_merge(['none' => 'Aucune'],helper::arrayCollumn($pages, 'title', 'SORT_ASC')), [
'label' => 'Accès interdit, erreur 403',
'selected' =>$this->getData(['config', 'page403']),
'help' => 'Une page 403 ne doit pas apparaître dans l\'arborescence du menu. Créez puis sélectionnez une page orpheline.'
]); ?>
</div>
<div class="col6">
<?php
echo template::select('configPage404', array_merge(['none' => 'Aucune'],helper::arrayCollumn($pages, 'title', 'SORT_ASC')), [
'label' => 'Page inexistante, erreur 404 ',
'selected' =>$this->getData(['config', 'page404']),
'help' => 'Une page 404 ne doit pas apparaître dans l\'arborescence du menu. Créez puis sélectionnez une page orpheline.'
]); ?>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
@ -103,16 +136,7 @@
'help' => 'Le fuseau horaire est utile au bon référencement'
]); ?>
</div>
<div class="col4">
<?php $listePageId = array_merge(['' => 'Sélectionner'] , helper::arrayCollumn($this->getData(['page']), 'title', 'SORT_ASC') );
?>
<?php echo template::select('configLegalPageId', $listePageId , [
'label' => 'Mentions légales',
'selected' => $this->getData(['config', 'legalPageId']),
'help' => 'Les mentions légales sont obligatoires en France'
]); ?>
</div>
<div class="col4 verticalAlignBottom">
<div class="col8 verticalAlignBottom">
<?php echo template::checkbox('configCookieConsent', true, 'Message de consentement aux cookies', [
'checked' => $this->getData(['config', 'cookieConsent'])
]); ?>

View File

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

View File

@ -1,15 +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-2020, Frédéric Tempez
* @license GNU General Public License, version 3
* @link http://zwiicms.com/
*/
@import url("site/data/admin.css");

View File

@ -1,85 +0,0 @@
<?php echo template::formOpen('configRestoreForm'); ?>
<div class="row">
<div class="col2">
<?php echo template::button('configRestoreBack', [
'class' => 'buttonGrey',
'href' => helper::baseUrl() . 'config',
'ico' => 'left',
'value' => 'Retour'
]); ?>
</div>
<div class="col2 offset8">
<?php echo template::submit('configRestoreSubmit',[
'value' => 'Restaurer',
'ico' => 'upload'
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Restauration ou transfert d'un site</h4>
<div class="row">
<div class="col8 offset2">
<?php echo template::file('configRestoreImportFile', [
'label' => 'Sélectionnez une sauvegarde au format ZIP',
'type' => 2,
'help' => 'L\'archive a été déposée dans le gestionnaire de fichiers. Les archives inférieures à la version 9 ne sont pas acceptées.'
]); ?>
</div>
</div>
<div class="row">
<div class="col8 offset2">
<?php echo template::checkbox('configRestoreImportUser', true, 'Préserver les comptes des utilisateurs', [
'checked' => true,
'help' => 'Les données des utilisateurs installés ne sont pas écrasés par la restauration quand l\'option est active.'
]); ?>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Conversion des URL après transfert de site</h4>
<div class="row">
<div class="col5">
<?php
if (is_null($this->getData(['core', 'baseUrl'])) ) {
$baseUrlValue = 'Pas de donnée dans la sauvegarde';
$buttonClass = 'disabled';
} elseif ($this->getData(['core', 'baseUrl']) === '') {
$baseUrlValue = '/';
$buttonClass = (helper::baseUrl(true,false) !== $this->getData(['core', 'baseUrl']) ) ? '' : 'disabled';
} else {
$baseUrlValue = $this->getData(['core', 'baseUrl']);
$buttonClass = (helper::baseUrl(true,false) !== $this->getData(['core', 'baseUrl']) ) ? '' : 'disabled';
}
echo template::text('configRestoreBaseURLToConvert', [
'label' => 'Dossier d\'installation de l\'archive' ,
'value' => $baseUrlValue,
'readonly' => true,
'help' => 'Lors de la restauration d\'un backup d\'une version 9.2.10 ou supérieure, l\'URL de base est stockée dans la configuration sinon cette donnée est vide.'
]); ?>
</div>
<div class="col5">
<?php echo template::text('configRestoreCurrentURL', [
'label' => 'Dossier du site actuel',
'value' => helper::baseUrl(true,false),
'readonly' => true,
'help' => 'Dossier du site installé.'
]); ?>
</div>
<div class="col2 verticalAlignBottom">
<?php echo template::button('configRestoreUpdateBaseURLButton', [
'href' => helper::baseUrl() . 'config/updateBaseUrl',
'class' => $buttonClass,
'value' => 'convertir'
]); ?>
</div>
</div>
</div>
</div>
</div>
<?php echo template::formClose(); ?>

View File

@ -5,10 +5,13 @@ class init extends common {
'analyticsId' => '',
'autoBackup' => true,
'autoUpdate' => true,
'autoUpdateHtaccess' => false,
'cookieConsent' => true,
'favicon' => 'favicon.ico',
'faviconDark' => 'faviconDark.ico',
'homePageId' => 'accueil',
'page404' => 'erreur404',
'page403' => 'erreur403',
'maintenance' => false,
'social' => [
'facebookId' => 'facebook',
@ -24,20 +27,20 @@ class init extends common {
'legalPageId' => 'mentions-legales',
'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 !',
'proxyUrl' => "",
'proxyPort' => "",
'proxyType' => "tcp://",
'proxyUrl' => '',
'proxyPort' => '',
'proxyType' => 'tcp://',
'smtp' => [
'enable' => false,
],
"connect" => [
"timeout" => 600,
"attempt" => 3,
'connect' => [
'timeout' => 600,
'attempt' => 3,
'log' => false
]
],
'core' => [
'dataVersion' => 10000,
'dataVersion' => 10300,
'lastBackup' => 0,
'lastClearTmp' => 0,
'lastAutoUpdate' => 0,
@ -109,10 +112,11 @@ class init extends common {
'displayCopyright' => false,
'displayLegal' => false,
'displaySearch' => false,
'displayMemberBar' => false,
'template' => '3'
],
'header' => [
'backgroundColor' => 'rgba(255, 255, 255, 1)',
'backgroundColor' => 'rgba(32, 59, 82, 1)',
'font' => 'Oswald',
'fontSize' => '2em',
'fontWeight' => 'normal',
@ -123,7 +127,7 @@ class init extends common {
'margin' => false,
'position' => 'site',
'textAlign' => 'center',
'textColor' => 'rgba(0, 17, 157, 1)',
'textColor' => 'rgba(255, 255, 255, 1)',
'textHide' => false,
'textTransform' => 'none',
'linkHomePage' => true,
@ -146,7 +150,8 @@ class init extends common {
'activeColorAuto' => true,
'activeColor' => 'rgba(255, 255, 255, 1)',
'activeTextColor' => 'rgba(255, 255, 255, 1)',
'radius' => '0px'
'radius' => '0px',
'memberBar' => true
],
'site' => [
'backgroundColor' => 'rgba(255, 255, 255, 1)',
@ -537,7 +542,53 @@ class init extends common {
'hideMenuSide' => false,
'hideMenuHead' => false,
'hideMenuChildren' => false
]
],
'erreur403' => [
'typeMenu' => 'text',
'iconUrl' => '',
'disable' => false,
'content' => '<h2 style="text-align: center;">Vous n\'êtes pas autorisé à accéder à cette page...</h2><p style="text-align: center;">Personnalisez cette page à votre convenance sans qu\'elle apparaisse dans les menus.<p>',
'hideTitle' => false,
'breadCrumb' => false,
'metaDescription' => '',
'metaTitle' => '',
'moduleId' => '',
'modulePosition' => 'bottom',
'parentPageId' => '',
'position' => 0,
'group' => self::GROUP_VISITOR,
'targetBlank' => false,
'title' => 'Erreur 403',
'block' => '12',
'barLeft' => '',
'barRight' => '',
'displayMenu' => 'none',
'hideMenuSide' => false,
'hideMenuChildren' =>false
],
'erreur404' => [
'typeMenu' => 'text',
'iconUrl' => '',
'disable' => false,
'content' => '<h2 style="text-align: center;">Oups ! La page demandée est introuvable...</h2><p style="text-align: center;">Personnalisez cette page à votre convenance sans qu\'elle apparaisse dans les menus.<p>',
'hideTitle' => false,
'breadCrumb' => false,
'metaDescription' => '',
'metaTitle' => '',
'moduleId' => '',
'modulePosition' => 'bottom',
'parentPageId' => '',
'position' => 0,
'group' => self::GROUP_VISITOR,
'targetBlank' => false,
'title' => 'Erreur 404',
'block' => '12',
'barLeft' => '',
'barRight' => '',
'displayMenu' => 'none',
'hideMenuSide' => false,
'hideMenuChildren' =>false
],
],
'module' => [
'blog' => [
@ -632,7 +683,7 @@ class init extends common {
'contact' => [
'config' => [
'button' => '',
'capcha' => true,
'captcha' => true,
'group' => self::GROUP_ADMIN,
'pageId' => '',
'subject' => ''
@ -665,3 +716,4 @@ class init extends common {
]
];
}

18
core/module/install/view/index/index.css Executable file → Normal file
View File

@ -1,17 +1 @@
/**
* 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-2020, Frédéric Tempez
* @license GNU General Public License, version 3
* @link http://zwiicms.com/
*/
@import url("site/data/admin.css");
/* Vide */

View File

@ -185,7 +185,12 @@ class page extends common {
else {
// Soumission du formulaire
if($this->isPost()) {
$pageId = $this->getInput('pageEditTitle', helper::FILTER_ID, true);
// Génére l'ID si le titre de la page a changé
if ( $this->getInput('pageEditTitle') !== $this->getData(['page',$this->getUrl(2),'title']) ) {
$pageId = $this->getInput('pageEditTitle', helper::FILTER_ID, true);
} else {
$pageId = $this->getUrl(2);
}
// un dossier existe du même nom (erreur en cas de redirection)
if (file_exists($pageId)) {
$pageId = uniqid($pageId);

View File

@ -669,7 +669,7 @@ class theme extends common {
unlink (self::TEMP_DIR . $zipFilename);
// Valeurs en sortie
$this->addOutput([
'notification' => 'Archive <b>'.$zipFilename.'</b> sauvegardée dans fichiers',
'notification' => 'Archive <b>'.$zipFilename.'</b> sauvegardée avec succès',
'redirect' => helper::baseUrl() . 'theme/manage',
'state' => true
]);

View File

@ -49,13 +49,18 @@
<div class="col6">
<div class="block">
<h4>Image</h4>
<?php
$imageFile = file_exists(self::FILE_DIR.'source/'.$this->getData(['theme', 'body', 'image'])) ? $this->getData(['theme', 'body', 'image']) : "";
echo template::file('themeBodyImage', [
'label' => 'Fond',
'type' => 1,
'value' => $imageFile
]); ?>
<div class="row">
<div class="col12">
<?php
$imageFile = file_exists(self::FILE_DIR.'source/'.$this->getData(['theme', 'body', 'image'])) ? $this->getData(['theme', 'body', 'image']) : "";
echo template::file('themeBodyImage', [
'help' => 'Sélectionner une image',
'label' => 'Fond',
'type' => 1,
'value' => $imageFile
]); ?>
</div>
</div>
<div id="themeBodyImageOptions" class="displayNone">
<div class="row">
<div class="col6">

View File

@ -47,6 +47,7 @@
$imageFile = file_exists(self::FILE_DIR.'source/'.$this->getData(['theme', 'header', 'image'])) ?
$this->getData(['theme', 'header', 'image']) : "";
echo template::file('themeHeaderImage', [
'help' => 'Sélectionner une image aux dimensions recommandées ci-dessous :',
'label' => 'Fond',
'type' => 1,
'value' => $imageFile

View File

@ -49,6 +49,11 @@
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<em>Le fichier de sauvegarde est généré dans <a href="<?php echo helper::baseUrl(false); ?>core/vendor/filemanager/dialog.php?fldr=theme&type=0&akey=<?php echo md5_file(self::DATA_DIR.'core.json'); ?>" data-lity>le dossier Thème</a> du gestionnaire de fichiers.</em>
</div>
</div>
</div>
<div class="block">
<h4>Télécharger le thème</h4>

View File

@ -24,8 +24,13 @@ class user extends common {
'logout' => self::GROUP_MEMBER,
'reset' => self::GROUP_VISITOR
];
public static $users = [];
public static $userId = '';
public static $userLongtime = false;
/**
* Ajout
*/
@ -388,8 +393,10 @@ class user extends common {
) {
// Expiration
$expire = $this->getInput('userLoginLongTime') ? strtotime("+1 year") : 0;
setcookie('ZWII_USER_ID', $userId, $expire, helper::baseUrl(false, false), '', helper::isHttps(), true);
$c = $this->getInput('userLoginLongTime', helper::FILTER_BOOLEAN) === true ? 'true' : 'false';
setcookie('ZWII_USER_ID', $userId, $expire, helper::baseUrl(false, false) , '', helper::isHttps(), true);
setcookie('ZWII_USER_PASSWORD', $this->getData(['user', $userId, 'password']), $expire, helper::baseUrl(false, false), '', helper::isHttps(), true);
setcookie('ZWII_USER_LONGTIME', $c, $expire, helper::baseUrl(false, false), '', helper::isHttps(), true);
// 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
@ -442,6 +449,12 @@ class user extends common {
}
}
}
if (!empty($_COOKIE['ZWII_USER_ID'])) {
self::$userId = $_COOKIE['ZWII_USER_ID'];
}
if (!empty($_COOKIE['ZWII_USER_LONGTIME'])) {
self::$userLongtime = $_COOKIE['ZWII_USER_LONGTIME'] == 'true' ? true : false;
}
// Valeurs en sortie
$this->addOutput([
'display' => self::DISPLAY_LAYOUT_LIGHT,
@ -454,7 +467,11 @@ class user extends common {
* Déconnexion
*/
public function logout() {
helper::deleteCookie('ZWII_USER_ID');
// Ne pas effacer l'identifiant mais seulement le mot de passe
if ($_COOKIE['ZWII_USER_LONGTIME'] !== 'true' ) {
helper::deleteCookie('ZWII_USER_ID');
helper::deleteCookie('ZWII_USER_LONGTIME');
}
helper::deleteCookie('ZWII_USER_PASSWORD');
session_destroy();
// Valeurs en sortie

View File

@ -2,7 +2,8 @@
<div class="row">
<div class="col6">
<?php echo template::text('userLoginId', [
'label' => 'Identifiant'
'label' => 'Identifiant',
'value' => $module::$userId
]); ?>
</div>
<div class="col6">
@ -14,9 +15,8 @@
<div class="row">
<div class="col6">
<?php echo template::checkbox('userLoginLongTime', true, 'Se souvenir de moi', [
'help' => 'La session est close à la fermeture du navigateur.'
]); ?>
'checked' => $module::$userLongtime
]); ?>
</div>
<div class="col6 textAlignRight">
<a href="<?php echo helper::baseUrl(); ?>user/forgot/<?php echo $this->getUrl(2); ?>">Mot de passe perdu ?</a>

BIN
core/vendor/zwiico/png/a.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

BIN
core/vendor/zwiico/png/b.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
core/vendor/zwiico/png/c.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

BIN
core/vendor/zwiico/png/d.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

BIN
core/vendor/zwiico/png/e.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

BIN
core/vendor/zwiico/png/f.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
core/vendor/zwiico/png/g.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
core/vendor/zwiico/png/h.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
core/vendor/zwiico/png/i.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

BIN
core/vendor/zwiico/png/j.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

BIN
core/vendor/zwiico/png/k.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
core/vendor/zwiico/png/l.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
core/vendor/zwiico/png/m.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
core/vendor/zwiico/png/n.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
core/vendor/zwiico/png/o.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
core/vendor/zwiico/png/p.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

BIN
core/vendor/zwiico/png/q.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

BIN
core/vendor/zwiico/png/r.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

BIN
core/vendor/zwiico/png/s.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

BIN
core/vendor/zwiico/png/t.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
core/vendor/zwiico/png/u.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -28,6 +28,7 @@ setlocale (LC_TIME, 'fra_FRA', 'french');
/**
* Initialisation de Zwii
*/
session_start();
// Chargement des classes
require 'core/class/autoload.php';

View File

@ -339,12 +339,12 @@ class blog extends common {
else {
// Soumission du formulaire
if($this->isPost()) {
// Check la capcha
// Check la captcha
if(
$this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD')
AND $this->getInput('blogArticleCapcha', helper::FILTER_INT) !== $this->getInput('blogArticleCapchaFirstNumber', helper::FILTER_INT) + $this->getInput('blogArticleCapchaSecondNumber', helper::FILTER_INT))
AND $this->getInput('blogArticlecaptcha', helper::FILTER_INT) !== $this->getInput('blogArticlecaptchaFirstNumber', helper::FILTER_INT) + $this->getInput('blogArticlecaptchaSecondNumber', helper::FILTER_INT))
{
self::$inputNotices['blogArticleCapcha'] = 'Incorrect';
self::$inputNotices['blogArticlecaptcha'] = 'Incorrect';
}
// Crée le commentaire
$commentId = helper::increment(uniqid(), $this->getData(['module', $this->getUrl(0), $this->getUrl(1), 'comment']));

View File

@ -6,7 +6,10 @@
à <?php echo utf8_encode(strftime('%H:%M', $this->getData(['module', $this->getUrl(0), $this->getUrl(1), 'publishedOn']))); ?>
</div>
</div>
<?php if($this->getUser('group') >= self::GROUP_ADMIN): ?>
<?php if(
$this->getUser('group') >= self::GROUP_ADMIN
AND $this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD')
): ?>
<div class="col2">
<?php echo template::button('blogEdit', [
'href' => helper::baseUrl() . $this->getUrl(0) . '/edit/' . $this->getUrl(1) . '/' . $_SESSION['csrf'],
@ -74,8 +77,8 @@
]); ?>
<?php if($this->getUser('password') !== $this->getInput('ZWII_USER_PASSWORD')): ?>
<div class="row">
<div class="col4">
<?php echo template::capcha('blogArticleCapcha'); ?>
<div class="col5">
<?php echo template::captcha('blogArticlecaptcha'); ?>
</div>
</div>
<?php endif; ?>

View File

@ -36,7 +36,7 @@
</div>
</div>
<div class="row">
<div class="col4">
<div class="col6">
<?php echo template::file('blogEditPicture', [
'help' => 'Taille optimale de l\'image de couverture : ' . ((int) substr($this->getData(['theme', 'site', 'width']), 0, -2) - (20 * 2)) . ' x 350 pixels.',
'label' => 'Image de couverture',
@ -44,13 +44,13 @@
'value' => $this->getData(['module', $this->getUrl(0), $this->getUrl(2), 'picture'])
]); ?>
</div>
<div class="col4">
<div class="col3">
<?php echo template::select('blogEditPictureSize', $module::$pictureSizes, [
'label' => 'Largeur de l\'image',
'selected' => $this->getData(['module', $this->getUrl(0), $this->getUrl(2), 'pictureSize'])
]); ?>
</div>
<div class="col4">
<div class="col3">
<?php echo template::select('blogEditPicturePosition', $module::$picturePositions, [
'label' => 'Position',
'selected' => $this->getData(['module', $this->getUrl(0), $this->getUrl(2), 'picturePosition']),

View File

@ -71,23 +71,17 @@ class form extends common {
// Soumission du formulaire
if($this->isPost()) {
// Configuration
// Option sélectionnée sans page choisie
$pageId = '';
if ($this->getInput('formConfigPageId') !== "") {
// Option désactivée, réinitialiser l'id de la page sélectionnée.
$pageId = $this->getInput('formConfigPageIdToggle', helper::FILTER_BOOLEAN) === true ? $this->getInput('formConfigPageId', helper::FILTER_ID) : '';
}
$this->setData([
'module',
$this->getUrl(0),
'config',
[
'button' => $this->getInput('formConfigButton'),
'capcha' => $this->getInput('formConfigCapcha', helper::FILTER_BOOLEAN),
'captcha' => $this->getInput('formConfigcaptcha', helper::FILTER_BOOLEAN),
'group' => $this->getInput('formConfigGroup', helper::FILTER_INT),
'user' => self::$listUsers [$this->getInput('formConfigUser', helper::FILTER_INT)],
'mail' => $this->getInput('formConfigMail') ,
'pageId' => $pageId,
'pageId' => $this->getInput('formConfigPageIdToggle', helper::FILTER_BOOLEAN) === true ? $this->getInput('formConfigPageId', helper::FILTER_ID) : '',
'subject' => $this->getInput('formConfigSubject'),
'replyto' => $this->getInput('formConfigMailReplyTo', helper::FILTER_BOOLEAN)
]
@ -285,12 +279,12 @@ class form extends common {
public function index() {
// Soumission du formulaire
if($this->isPost()) {
// Check la capcha
// Check la captcha
if(
$this->getData(['module', $this->getUrl(0), 'config', 'capcha'])
AND $this->getInput('formCapcha', helper::FILTER_INT) !== $this->getInput('formCapchaFirstNumber', helper::FILTER_INT) + $this->getInput('formCapchaSecondNumber', helper::FILTER_INT))
$this->getData(['module', $this->getUrl(0), 'config', 'captcha'])
AND $this->getInput('formcaptcha', helper::FILTER_INT) !== $this->getInput('formcaptchaFirstNumber', helper::FILTER_INT) + $this->getInput('formcaptchaSecondNumber', helper::FILTER_INT))
{
self::$inputNotices['formCapcha'] = 'Incorrect';
self::$inputNotices['formcaptcha'] = 'Incorrect';
}
// Préparation le contenu du mail

View File

@ -142,8 +142,8 @@
]); ?>
</div>
</div>
<?php echo template::checkbox('formConfigCapcha', true, 'Valider un capcha afin de soumettre le formulaire.', [
'checked' => $this->getData(['module', $this->getUrl(0), 'config', 'capcha'])
<?php echo template::checkbox('formConfigcaptcha', true, 'Valider un captcha afin de soumettre le formulaire.', [
'checked' => $this->getData(['module', $this->getUrl(0), 'config', 'captcha'])
]); ?>
</div>
<div class="block">

View File

@ -43,10 +43,10 @@
</h3>
<?php endif; ?>
<?php endforeach; ?>
<?php if($this->getData(['module', $this->getUrl(0), 'config', 'capcha'])): ?>
<?php if($this->getData(['module', $this->getUrl(0), 'config', 'captcha'])): ?>
<div class="row">
<div class="col4">
<?php echo template::capcha('formCapcha'); ?>
<div class="col5">
<?php echo template::captcha('formcaptcha'); ?>
</div>
</div>
<?php endif; ?>