Merge branch 'master' into blog_v3

This commit is contained in:
Fred Tempez 2020-09-24 18:01:34 +02:00
commit 78259f3da6
262 changed files with 1769 additions and 1076 deletions

0
.htaccess Executable file → Normal file
View File

View File

@ -11,11 +11,46 @@
- Suppression des commentaires en masse.
- Limiter l'édition des articles et des commentaires à l'id de l'éditeur
- Approbation des commentaires
- 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".
- Le titre dans la configuration du module non affiché si le titre de la page est masqué.
- Masque de saisie : formulaire validé malgré la présence d'une notice d'erreur
- Classe jsonDb, suppression de la réinitialisation de la structure de données en cas d'absence du fichier.
- Modifications :
- Noyau :
- Mise en cache des données des modules.
- Module recherche :
- La recherche dans le site devient un module externe plutôt qu'un module interne ;
- Diverses corrections optimisations permettant une recherche à l'aide de plusieurs mot-clés.
- Module galerie :
- Les données du thème de galerie sont désormais stockées de manière unique, un seul thème par site pour toutes les galeries d'un même site.
- 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).
- Page :
- Duplication d'une page.
- Mise à jour :
- Script favicon-switcher 1.2.2
## version 10.2.09
- Correction :
- Sécurisation de la fonction d'enregistrement des données.
## version 10.2.08
- Correction :
- Bug pageId, régression corrigée.
## version 10.2.07
- Correction :
- Défaut de chargement de flatpickr dans le module formulaire qui passe en version 2.4
## version 10.2.06
- Corrections :
- Anticipation de la dépréciation de l'option de cookie samesite=none.
- Warning : absence de fichier map dans le thème TinyMCE lightgray
- Warning : absence de fichier map dans le thème TinyMCE lightgray.
## version 10.2.05
- Correction :

0
core/class/.htaccess Executable file → Normal file
View File

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

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

6
core/class/helper.class.php Executable file → Normal file
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/';
@ -185,7 +187,7 @@ class helper {
* @return string
*/
public static function getOnlineVersion() {
return (helper::urlGetContents('http://zwiicms.com/update/'. common::ZWII_UPDATE_CHANNEL . '/version'));
return (helper::urlGetContents('http://zwiicms.fr/update/'. common::ZWII_UPDATE_CHANNEL . '/version'));
}

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

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

@ -22,10 +22,10 @@ class JsonDb extends \Prowebcraft\Dot
public function __construct($config = [])
{
$this->config = array_merge([
'name' => 'data.json',
'backup' => 5,
'name' => 'data.json',
'backup' => 5,
'dir' => getcwd(),
'template' => getcwd() . DIRECTORY_SEPARATOR . 'data.template.json'
'template' => getcwd() . DIRECTORY_SEPARATOR . 'data.template.json'
], $config);
$this->loadData();
parent::__construct();
@ -36,7 +36,7 @@ class JsonDb extends \Prowebcraft\Dot
*
* @param mixed $key Path or array of paths and values
* @param mixed|null $value Value to set if path is not an array
* @param bool $save Сохранить данные в базу
* @param bool $save Save data to database
* @return $this
*/
public function set($key, $value = null, $save = true)
@ -49,10 +49,10 @@ class JsonDb extends \Prowebcraft\Dot
/**
* Add value or array of values to path
*
* @param mixed $key Path or array of paths and values
* @param mixed $key Path or array of paths and values
* @param mixed|null $value Value to set if path is not an array
* @param boolean $pop Helper to pop out last key if value is an array
* @param bool $save Сохранить данные в базу
* @param boolean $pop Helper to pop out last key if value is an array
* @param bool $save Save data to database
* @return $this
*/
public function add($key, $value = null, $pop = false, $save = true)
@ -65,8 +65,8 @@ class JsonDb extends \Prowebcraft\Dot
/**
* Delete path or array of paths
*
* @param mixed $key Path or array of paths to delete
* @param bool $save Сохранить данные в базу
* @param mixed $key Path or array of paths to delete
* @param bool $save Save data to database
* @return $this
*/
public function delete($key, $save = true)
@ -81,8 +81,8 @@ class JsonDb extends \Prowebcraft\Dot
* optionally format path if it doesn't exist
*
* @param mixed|null $key Path or array of paths to clean
* @param boolean $format Format option
* @param bool $save Сохранить данные в базу
* @param boolean $format Format option
* @param bool $save Save data to database
* @return $this
*/
public function clear($key = null, $format = false, $save = true)
@ -94,14 +94,15 @@ class JsonDb extends \Prowebcraft\Dot
/**
* Загрузка локальной базы данных
* @param bool $reload
* Перезагрузить данные?
* Local database upload
* @param bool $reload Reboot data?
* @return array|mixed|null
*/
protected function loadData($reload = false) {
if ($this->data === null || $reload) {
$this->db = $this->config['dir'] . DIRECTORY_SEPARATOR . $this->config['name'];
// $this->db = $this->config['dir'] . DIRECTORY_SEPARATOR . $this->config['name'];
$this->db = $this->config['dir'] . $this->config['name'];
/*
if (!file_exists($this->db)) {
$templateFile = $this->config['template'];
if (file_exists($templateFile)) {
@ -118,6 +119,7 @@ class JsonDb extends \Prowebcraft\Dot
}
}
}
*/
$this->data = json_decode(file_get_contents($this->db), true);
if (!$this->data === null) {
throw new \InvalidArgumentException('Database file ' . $this->db
@ -128,11 +130,9 @@ class JsonDb extends \Prowebcraft\Dot
}
/**
* Сохранение в локальную базу
* Saving to local database
*/
public function save() {
file_put_contents($this->db, json_encode($this->data, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT));
}
}

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

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

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

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

24
core/class/template.class.php Executable file → Normal file
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'] : '')
. '"

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

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @license GNU General Public License, version 3
* @link http://zwiicms.com/
* @link http://zwiicms.fr/
*/
var core = {};

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

@ -10,7 +10,7 @@
* @license GNU General Public License, version 3
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2020, Frédéric Tempez
* @link http://zwiicms.com/
* @link http://zwiicms.fr/
*/
class common {
@ -43,7 +43,7 @@ class common {
const ACCESS_TIMER = 1800;
// Numéro de version
const ZWII_VERSION = '10.3.00';
const ZWII_VERSION = '10.4.00';
const ZWII_UPDATE_CHANNEL = "v10";
public static $actions = [];
@ -52,7 +52,6 @@ class common {
'install',
'maintenance',
'page',
'search',
'sitemap',
'theme',
'user'
@ -150,8 +149,11 @@ class common {
];
public static $timezone;
private $url = '';
// Données de site
private $user = [];
private $page = '';
private $page = [];
private $module = [];
/**
* Constructeur commun
@ -191,8 +193,9 @@ class common {
$this->user = $this->getData(['user', $this->getInput('ZWII_USER_ID')]);
}
// Mise en cache des pages
$this->page = $this->getPageCache();
// Mise en cache des pages et des modules
$this->page = $this->getCache('page');
$this->module = $this->getCache('module');
// Construit la liste des pages parents/enfants
if($this->hierarchy['all'] === []) {
@ -323,12 +326,9 @@ class common {
//Retourne une chaine contenant le dossier à créer
$folder = $this->dirData ($keys[0],'fr');
// Constructeur JsonDB
//require_once "core/vendor/jsondb/Dot.php";
//require_once "core/vendor/jsondb/JsonDb.php";
$db = new \Prowebcraft\JsonDb([
'name' => $keys[0] . '.json',
'dir' => $folder,
'template' => self::TEMP_DIR . 'data.template.json'
'dir' => $folder
]);
switch(count($keys)) {
case 1:
@ -370,10 +370,14 @@ class common {
public function getData($keys = []) {
if (count($keys) >= 1) {
// Lecture d'une donnée de page en cache
if ($keys[0] === 'page') {
/**
* Lecture dans le cache, page et module
*/
if ($keys[0] === 'page' ||
$keys[0] === 'module' ) {
// Décent dans les niveaux de la variable $data
$data = $this->page;
$data = array_merge ($this->page , $this->module);
foreach($keys as $key) {
// Si aucune donnée n'existe retourne null
if(isset($data[$key]) === false) {
@ -387,13 +391,16 @@ class common {
// Retourne les données
return $data;
}
/**
* Lecture directe
*/
//Retourne une chaine contenant le dossier à créer
$folder = $this->dirData ($keys[0],'fr');
// Constructeur JsonDB
$db = new \Prowebcraft\JsonDb([
'name' => $keys[0] . '.json',
'dir' => $folder,
'template' => self::TEMP_DIR . 'data.template.json'
'dir' => $folder
]);
switch(count($keys)) {
case 1:
@ -427,19 +434,15 @@ class common {
* Lecture des fichiers de données de page et mise ne cache
* @param @return string données des pages
*/
public function getPageCache() {
// Trois tentatives
for($i = 0; $i < 3; $i++) {
$data =json_decode(file_get_contents(self::DATA_DIR.'fr/page.json'), true);
if($data) {
return($data);
}
elseif($i === 2) {
exit('Erreur fatale : impossible d\'accéder aux pages');
}
// Pause de 10 millisecondes
usleep(10000);
}
public function getCache($data) {
$folder = $this->dirData ($data,'fr');
// Constructeur JsonDB
$db = new \Prowebcraft\JsonDb([
'name' => $data . '.json',
'dir' => $folder
]);
$tempData = $db->get($data);
return [$data => $tempData];
}
/*
@ -595,7 +598,7 @@ class common {
break;
}
elseif($i === 2) {
exit('Impossible de lire les données à importer.');
throw new \ErrorException('Import des données impossible.');
}
// Pause de 10 millisecondes
usleep(10000);
@ -950,8 +953,9 @@ class common {
*/
public function setData($keys = []) {
// Pas d'enregistrement lorsqu'une notice est présente
if (!empty(self::$inputNotices)) {
// Pas d'enregistrement lorsqu'une notice est présente ou tableau transmis vide
if (!empty(self::$inputNotices
OR empty($keys))) {
return false;
}
@ -960,8 +964,7 @@ class common {
// Constructeur JsonDB
$db = new \Prowebcraft\JsonDb([
'name' => $keys[0] . '.json',
'dir' => $folder,
'template' => self::TEMP_DIR . 'data.template.json'
'dir' => $folder
]);
switch(count($keys)) {
@ -1012,8 +1015,7 @@ class common {
// Constructeur JsonDB
$db = new \Prowebcraft\JsonDb([
'name' => $module . '.json',
'dir' => $folder,
'template' => self::TEMP_DIR . 'data.template.json'
'dir' => $folder
]);
if ($sampleSite === true) {
$db->set($module,init::$siteData[$module]);
@ -1355,12 +1357,57 @@ 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']);
// Module de recherche
// Suppression du dossier search
if (is_dir('core/module/search')) {
$dir = getcwd();
chdir('core/module/search');
$files = glob('*');
foreach($files as $file) unlink($file);
chdir($dir);
rmdir ('core/module/search/');
}
// Désactivation de l'option dans le pied de page
$this->setData(['theme','footer','displaySearch',false]);
// Inscription des nouvelles variables
$this->setData(['config','searchPageId','']);
// Mettre à jour les données des galeries
$pageList = array();
foreach ($this->getHierarchy(null,null,null) as $parentKey=>$parentValue) {
$pageList [] = $parentKey;
foreach ($parentValue as $childKey) {
$pageList [] = $childKey;
}
}
// Mise à jour des données de thème de la galerie
// Les données de thème sont communes au site
foreach ($pageList as $parentKey => $parent) {
//La page a une galerie
if ($this->getData(['page',$parent,'moduleId']) === 'gallery' ) {
foreach ( $this->getData(['module', $parent]) as $galleryKey => $galleryItem) {
// Transfert du theme dans une structure unique
if ( is_array($this->getdata(['theme',$parent])) ) {
$this->setdata(['theme','gallery',$this->getdata(['theme',$parent])]);
}
}
$this->deleteData(['theme',$parent]);
}
}
// Mise à jour du numéro de version
$this->setData(['core', 'dataVersion', 10300]);
}
// Version 10.4.00
if ($this->getData(['core', 'dataVersion']) < 10300) {
// Ajouter le prénom comme pseudo et le pseudo comme signature
foreach($this->getData(['user']) as $userId => $userIds){
@ -1399,7 +1446,7 @@ class common {
}
}
}
$this->setData(['core', 'dataVersion', 10300]);
$this->setData(['core', 'dataVersion', 10400]);
}
}
}
@ -1713,7 +1760,7 @@ class core extends common {
// Déconnexion
$user = new user;
$user->logout();
// Rédirection
// Redirection
http_response_code(302);
header('Location:' . helper::baseUrl() . 'maintenance');
exit();
@ -1753,11 +1800,11 @@ class core extends common {
foreach($this->getData(['user']) as $userId => $userIds){
$t = explode('/',$this->getData(['user', $userId, 'accessUrl']));
if ( $this->getuser('id') &&
$userId !== $this->getuser('id') &&
$this->getData(['user', $userId,'accessUrl']) === $this->getUrl() &&
array_intersect($t,self::$accessList) &&
array_intersect($t,self::$accessExclude) !== false &&
time() < $this->getData(['user', $userId,'accessTimer']) + self::ACCESS_TIMER
$userId !== $this->getuser('id') &&
$this->getData(['user', $userId,'accessUrl']) === $this->getUrl() &&
array_intersect($t,self::$accessList) &&
array_intersect($t,self::$accessExclude) !== false &&
time() < $this->getData(['user', $userId,'accessTimer']) + self::ACCESS_TIMER
) {
$access = false;
$accessInfo['userName'] = $this->getData(['user', $userId, 'lastname']) . ' ' . $this->getData(['user', $userId, 'firstname']);
@ -1990,20 +2037,31 @@ class core extends common {
'title' => 'Accès verrouillé',
'content' => template::speech('La page <strong>' . $accessInfo['pageId'] . '</strong> est ouverte par l\'utilisateur <strong>' . $accessInfo['userName'] . '</strong>')
]);
} else {
if ( $this->getData(['config','page403']) !== 'none'
AND $this->getData(['page',$this->getData(['config','page403'])]))
{
header('Location:' . helper::baseUrl() . $this->getData(['config','page403']));
} else {
$this->addOutput([
'title' => 'Erreur 403',
'content' => template::speech('Vous n\'êtes pas autorisé à accéder à cette page...')
]);
}
}
} elseif ($this->output['content'] === '') {
http_response_code(404);
if ( $this->getData(['config','page404']) !== 'none'
AND $this->getData(['page',$this->getData(['config','page404'])]))
{
header('Location:' . helper::baseUrl() . $this->getData(['config','page404']));
} else {
$this->addOutput([
'title' => 'Erreur 403',
'content' => template::speech('Vous n\'êtes pas autorisé à accéder à cette page...')
'title' => 'Erreur 404',
'content' => template::speech('Oups ! La page demandée est introuvable...')
]);
}
}
elseif($this->output['content'] === '') {
http_response_code(404);
$this->addOutput([
'title' => 'Erreur 404',
'content' => template::speech('Oups ! La page demandée est introuvable...')
]);
}
// Mise en forme des métas
if($this->output['metaTitle'] === '') {
if($this->output['title']) {
@ -2088,12 +2146,12 @@ class layout extends common {
AND (
$this->getData(['page', $this->getUrl(0)]) === null
OR $this->getData(['page', $this->getUrl(0), 'hideTitle']) === false
OR $this->getUrl(1) === 'config'
)
) {
echo '<h1 id="sectionTitle">' . $this->core->output['title'] . '</h1>';
}
echo $this->core->output['content'];
}
@ -2162,7 +2220,7 @@ class layout extends common {
$items .= '>Motorisé&nbsp;par&nbsp;</span>';
// Toujours afficher le nom du CMS
$items .= '<span id="footerZwiiCMS">';
$items .= '<a href="http://zwiicms.com/" onclick="window.open(this.href);return false" data-tippy-content="Zwii CMS sans base de données, très léger et performant">ZwiiCMS</a>';
$items .= '<a href="https://zwiicms.fr/" onclick="window.open(this.href);return false" data-tippy-content="Zwii CMS sans base de données, très léger et performant">ZwiiCMS</a>';
$items .= '</span>';
// Affichage du numéro de version
$items .= '<span id="footerDisplayVersion"';
@ -2177,7 +2235,7 @@ class layout extends common {
// Affichage du module de recherche
$items .= '<span id="footerDisplaySearch"';
$items .= $this->getData(['theme','footer','displaySearch']) === false ? ' class="displayNone"' : '';
$items .= '><wbr>&nbsp;|&nbsp;<a href="' . helper::baseUrl() . 'search" data-tippy-content="Rechercher dans le site" >Rechercher</a>';
$items .= '><wbr>&nbsp;|&nbsp;<a href="' . helper::baseUrl() . $this->getData(['config','searchPageId']) . '" data-tippy-content="Rechercher dans le site" >Recherche</a>';
$items .= '</span>';
// Affichage des mentions légales
$items .= '<span id="footerDisplayLegal"';
@ -2288,7 +2346,8 @@ class layout extends common {
file_exists(self::FILE_DIR.'source/' . $faviconDark)
) {
echo '<link rel="shortcut icon" media="(prefers-color-scheme:dark)" href="' . helper::baseUrl(false) . self::FILE_DIR.'source/' . $faviconDark . '">';
echo '<script src="https://unpkg.com/favicon-switcher@1.2.0/dist/index.js" crossorigin="anonymous" type="application/javascript"></script>';
//echo '<script src="https://unpkg.com/favicon-switcher@1.2.2/dist/index.js" crossorigin="anonymous" type="application/javascript"></script>';
echo '<script src="' . helper::baseUrl(false) . 'core/vendor/favicon-switcher/favicon-switcher.js" crossorigin="anonymous" type="application/javascript"></script>';
}
}
@ -2303,7 +2362,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>';
@ -2313,7 +2372,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'])) {
@ -2359,7 +2418,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>';
@ -2367,7 +2426,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'])) {
@ -2467,7 +2526,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.
@ -2477,7 +2536,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>';
@ -2490,7 +2549,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">';
@ -2499,7 +2558,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']);
@ -2663,6 +2722,7 @@ class layout extends common {
if ($this->getData(['page', $this->getUrl(0),'moduleId'])) {
$leftItems .= '<li><a href="' . helper::baseUrl() . $this->getUrl(0) . '/config' . '" data-tippy-content="Configurer le module">' . template::ico('gear') . '</a></li>';
}
$leftItems .= '<li><a id="pageDuplicate" href="' . helper::baseUrl() . 'page/duplicate/' . $this->getUrl(0) . '&csrf=' . $_SESSION['csrf'] . '" data-tippy-content="Dupliquer la page">' . template::ico('clone') . '</a></li>';
$leftItems .= '<li><a id="pageDelete" href="' . helper::baseUrl() . 'page/delete/' . $this->getUrl(0) . '&csrf=' . $_SESSION['csrf'] . '" data-tippy-content="Effacer la page">' . template::ico('trash') . '</a></li>';
}
}
@ -2676,13 +2736,14 @@ class layout extends common {
$rightItems .= '<li><a href="' . helper::baseUrl() . 'theme" data-tippy-content="Personnaliser les thèmes">' . template::ico('brush') . '</a></li>';
$rightItems .= '<li><a href="' . helper::baseUrl() . 'config" data-tippy-content="Configurer le site">' . template::ico('cog-alt') . '</a></li>';
// Mise à jour automatique
$today = mktime(0, 0, 0);
// Une mise à jour est disponible + recherche auto activée + 1 jour de délais
$lastAutoUpdate = mktime(0, 0, 0);
if( $this->getData(['config','autoUpdate']) === true &&
$lastAutoUpdate > $this->getData(['core','lastAutoUpdate']) + 86400 &&
helper::checkNewVersion(common::ZWII_UPDATE_CHANNEL)) {
$this->setData(['core','updateAvailable', true]);
$this->setData(['core','lastAutoUpdate',$lastAutoUpdate]);
if ( $this->getData(['config','autoUpdate']) === true
AND $today > $this->getData(['core','lastAutoUpdate']) + 86400 ) {
if ( helper::checkNewVersion(common::ZWII_UPDATE_CHANNEL) ) {
$this->setData(['core','updateAvailable', true]);
$this->setData(['core','lastAutoUpdate',$today]);
}
}
// Afficher le bouton : Mise à jour détectée + activée
if ( $this->getData(['core','updateAvailable']) === true &&

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @license GNU General Public License, version 3
* @link http://zwiicms.com/
* @link http://zwiicms.fr/
*/
/**

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

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @license GNU General Public License, version 3
* @link http://zwiicms.com/
* @link http://zwiicms.fr/
*/
/**
@ -207,7 +207,6 @@ Signature dans les articles blog et news
}
.table tbody tr {
background: #F6F7F8;
-webkit-transition: background .3s ease-out;
transition: background .3s ease-out;
}
.table tbody tr:nth-child(2n + 2) {
@ -357,7 +356,6 @@ td > .col12 {
display: inline-block;
padding: 0 12px;
color: #FFF;
-webkit-transition: background .3s ease-out;
transition: background .3s ease-out;
}
#bar a:hover {
@ -448,12 +446,12 @@ header .container {
height: 100%;
}
/* Element du header */
/* Element du header
#themeHeaderImage {
font-style: italic;
font-size: 0.9em;
}
}*/
/* Menu
body > nav {
@ -501,7 +499,6 @@ nav li ul {
width: 200px;
z-index: -1;
opacity: 0;
-webkit-transition: .3s ease-out;
transition: .3s ease-out;
padding-left: 10px;
}
@ -518,7 +515,6 @@ nav li:hover ul {
nav a {
display: inherit;
-webkit-transition: background .3s ease-out;
transition: background .3s ease-out;
}
@ -702,7 +698,6 @@ footer #footerSocials span {
margin: 0 5px;
display: inline-block;
border-radius: 2px;
-webkit-transition: background .3s ease-out;
transition: background .3s ease-out;
}
footer #footerSocials .zwiico-facebook {
@ -766,7 +761,6 @@ footer #footerSocials .zwiico-github:hover {
margin: 16px auto;
text-align: left;
border-radius: 2px;
-webkit-transition: background .3s ease-out;
transition: background .3s ease-out;
}
.speechBubble:before {
@ -792,7 +786,6 @@ footer #footerSocials .zwiico-github:hover {
cursor: pointer;
display: none;
border-radius: 50%;
-webkit-transition: background.3s ease-out;
transition: background .3s ease-out;
}
#backToTop:hover {
@ -822,7 +815,6 @@ footer #footerSocials .zwiico-github:hover {
background: #666;
padding: 4px 8px;
display: inline-block;
-webkit-transition: background.3s ease-out;
transition: background .3s ease-out;
}
#cookieConsentConfirm:hover {
@ -902,7 +894,6 @@ textarea {
width: 100%;
border-radius: 2px;
font-family: inherit;
-webkit-transition: border .3s ease-out;
transition: border .3s ease-out;
}
select {
@ -950,7 +941,6 @@ button {
cursor: pointer;
font-family: inherit;
border-radius: 2px;
-webkit-transition: background .3s ease-out;
transition: background .3s ease-out;
}
textarea {
@ -982,7 +972,6 @@ label {
user-select: none;
cursor: pointer;
border-radius: 2px;
-webkit-transition: background .3s ease-out;
transition: background .3s ease-out;
}
/* Bouton redimensionnable pour le formulaire*/
@ -1019,6 +1008,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 +1358,34 @@ th.col12 {
.accordion-content {
padding: 7px;
}
/* Captcha
* Taille des images
*/
.captchaNumber {
height: 25px;
vertical-align: bottom;
padding-left: 5px;
padding-right: 5px;
}
/*
* Couleur des icônes + et -
*/
.zwiico-minus-circled,
.zwiico-plus-circled {
color: #D8890B;
font-size: 1.3em !important;
}
.zwiico-minus-circled,
.zwiico-plus-circled {
transition: all 1s ease;
}
.zwiico-minus-circled:hover,
.zwiico-plus-circled:hover {
-webkit-transform:scale(1.25); /* Safari et Chrome */
-moz-transform:scale(1.25); /* Firefox */
-ms-transform:scale(1.25); /* Internet Explorer 9 */
-o-transform:scale(1.25); /* Opera */
transform:scale(1.25);
}

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @license GNU General Public License, version 3
* @link http://zwiicms.com/
* @link http://zwiicms.fr/
*/
/**

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

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

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

@ -186,7 +186,7 @@
<div class="row siteContainer">
<?php
if ($blockleft !== "") :?>
<div class="<?php echo $blockleft; ?>" id="contentLeft"><?php $layout->showBarContentLeft(); ?></div>
<div class="<?php echo $blockleft; ?>" id="contentLeft"><aside><?php $layout->showBarContentLeft(); ?></aside></div>
<?php endif; ?>
<div class="<?php echo $content; ?>" id="contentSite"><?php $layout->showContent();
if (file_exists(self::DATA_DIR . 'body.inc.html')) {
@ -196,7 +196,7 @@
</div>
<?php
if ($blockright !== "") :?>
<div class="<?php echo $blockright; ?>" id="contentRight"><?php $layout->showBarContentRight(); ?></div>
<div class="<?php echo $blockright; ?>" id="contentRight"><aside><?php $layout->showBarContentRight(); ?></aside></div>
<?php endif; ?>
</div>
<?php }

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

@ -8,10 +8,10 @@
*
* @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/
* @link http://zwiicms.fr/
*/
class config extends common {
@ -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([
@ -406,22 +408,41 @@ class config extends common {
public function index() {
// Soumission du formulaire
if($this->isPost()) {
$success = true;
// Basculement en mise à jour auto
// Remise à 0 du compteur
if ($this->getData(['config','autoUpdate']) === false &&
$this->getInput('configAutoUpdate', helper::FILTER_BOOLEAN) === true) {
$this->setData(['core','lastAutoUpdate',0]);
}
if ($this->getInput('configLegalCheck', helper::FILTER_BOOLEAN) === true ) {
$legalPageId = $this->getInput('configLegalPageId', helper::FILTER_ID);
// Empêcher la modification si défini dans footer
if ( $this->getData(['theme','footer','displaySearch']) === true
AND $this->getInput('configSearchPageId') === ''
){
$searchPageId = $this->getData(['config','searchPageId']);
self::$inputNotices['configSearchPageId'] = 'Désactiver l\'option dans le pied de page';
$success = false;
} else {
$legalPageId = '';
$searchPageId = $this->getInput('configSearchPageId');
}
// Empêcher la modification si défini dans footer
if ( $this->getData(['theme','footer','displayLegal']) === true
AND $this->getInput('configLegalPageId') === ''
){
$legalPageId = $this->getData(['config','legalPageId']);
self::$inputNotices['configLegalPageId'] = 'Désactiver l\'option dans le pied de page';
$success = false;
} else {
$legalPageId = $this->getInput('configLegalPageId');
}
// Sauvegarder
$this->setData([
'config',
[
'homePageId' => $this->getInput('configHomePageId', helper::FILTER_ID, true),
'page404' => $this->getInput('configPage404'),
'page403' => $this->getInput('configPage403'),
'page302' => $this->getInput('configPage302'),
'analyticsId' => $this->getInput('configAnalyticsId'),
'autoBackup' => $this->getInput('configAutoBackup', helper::FILTER_BOOLEAN),
'maintenance' => $this->getInput('configMaintenance', helper::FILTER_BOOLEAN),
@ -440,7 +461,8 @@ class config extends common {
],
'timezone' => $this->getInput('configTimezone', helper::FILTER_STRING_SHORT, true),
'itemsperPage' => $this->getInput('configItemsperPage', helper::FILTER_INT,true),
'legalPageId' => $this->getInput('configLegalPageId'),
'legalPageId' => $legalPageId,
'searchPageId' => $searchPageId,
'metaDescription' => $this->getInput('configMetaDescription', helper::FILTER_STRING_LONG, true),
'title' => $this->getInput('configTitle', helper::FILTER_STRING_SHORT, true),
'autoUpdate' => $this->getInput('configAutoUpdate', helper::FILTER_BOOLEAN),
@ -509,7 +531,7 @@ class config extends common {
$this->addOutput([
'redirect' => helper::baseUrl() . $this->getUrl(),
'notification' => 'Modifications enregistrées',
'state' => true
'state' => $success
]);
}
// Initialisation du screen - APPEL AUTO DESACTIVE POUR EVITER UN RALENTISSEMENT

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

View File

@ -9,7 +9,49 @@
* @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/
* @link http://zwiicms.fr/
*/
@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,43 @@
/**
* 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.fr/
*/
$( document).ready(function() {
$("#configBackupForm").submit( function(e){
$("#configBackupSubmit").addClass("disabled").prop("disabled", true);
e.preventDefault();
if ($("input[name=configBackupOption]").is(':checked')) {
$("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(){
if ($("input[name=configBackupOption]").is(':checked')) {
$(".modal").removeClass("alertMessage");
}
$("#configBackupSubmit").removeClass("disabled").prop("disabled", false);
}
});
});
});

13
core/module/config/view/backup/backup.php Executable file → Normal file
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

@ -9,7 +9,7 @@
* @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/
* @link http://zwiicms.fr/
*/
@import url("site/data/admin.css");
@ -18,17 +18,17 @@
display : none;
}
#info .zwiico-minus {
#info .zwiico-minus-circled {
display: inline;
}
.zwiico-minus,
#info .zwiico-plus {
.zwiico-minus-circled,
#info .zwiico-plus-circled {
display: none;
}
.zwiico-minus,
.zwiico-plus {
.zwiico-minus-circled,
.zwiico-plus-circled {
cursor: pointer;
}

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

@ -7,7 +7,7 @@
* @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/
* @link http://zwiicms.fr/
*/
$( document).ready(function() {
@ -42,8 +42,8 @@ $( document).ready(function() {
var i = [ "social", "ceo", "network", "smtp", "login", "logs", "script", "system" ];
$.each(i,function(e) {
if (getCookie(i[e]) === "true") {
$("#" + i[e]).find(".zwiico-plus").hide();
$("#" + i[e]).find(".zwiico-minus").show();
$("#" + i[e]).find(".zwiico-plus-circled").hide();
$("#" + i[e]).find(".zwiico-minus-circled").show();
$("#" + i[e]).find(".blockContainer").show();
}
});
@ -54,8 +54,8 @@ $( document).ready(function() {
*/
$("div .block").click(function(e) {
$(this).find(".zwiico-plus").toggle();
$(this).find(".zwiico-minus").toggle();
$(this).find(".zwiico-plus-circled").toggle();
$(this).find(".zwiico-minus-circled").toggle();
$(this).find(".blockContainer").slideToggle();
/*
* Sauvegarder la position des blocs

192
core/module/config/view/index/index.php Executable file → Normal file
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,7 +42,7 @@
<?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>
@ -68,7 +52,7 @@
<div class="row">
<div class="col12">
<div class="block">
<h4>Paramètres</h4>
<h4>Paramètres généraux</h4>
<?php $error = helper::urlGetContents('http://zwiicms.com/update/' . common::ZWII_UPDATE_CHANNEL . '/version');?>
<div class="row">
<div class="col4">
@ -103,16 +87,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'])
]); ?>
@ -165,14 +140,87 @@
</div>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block">
<h4>Pages spéciales</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]);
}
}
$orphans = $this->getData(['page']);
foreach($orphans as $page => $pageId) {
if ($this->getData(['page',$page,'block']) === 'bar' ||
$this->getData(['page',$page,'disable']) === true ||
$this->getdata(['page',$page, 'position']) !== 0) {
unset($orphans[$page]);
}
}
echo template::select('configHomePageId', helper::arrayCollumn($pages, 'title', 'SORT_ASC'), [
'label' => 'Accueil du site',
'selected' =>$this->getData(['config', 'homePageId']),
'help' => 'La première page que vos visiteurs verront.'
]); ?>
</div>
<div class="col4">
<?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 pied de page ajoute un lien discret vers cette page.'
]); ?>
</div>
<div class="col4">
<?php echo template::select('configSearchPageId', array_merge(['' => 'Sélectionner'] , helper::arrayCollumn($this->getData(['page']), 'title', 'SORT_ASC') ) , [
'label' => 'Recherche dans le site',
'selected' => $this->getData(['config', 'searchPageId']),
'help' => 'Sélectionner la page "Recherche" ou une page contenant le module "Recherche" permet d\'activer un lien dans le pied de page. '
]); ?>
</div>
</div>
<div class="row">
<div class="col4">
<?php
echo template::select('configPage403', array_merge(['none' => 'Aucune'],helper::arrayCollumn($orphans, 'title', 'SORT_ASC')), [
'label' => 'Accès interdit, erreur 403',
'selected' =>$this->getData(['config', 'page403']),
'help' => 'Cette page ne doit pas apparaître dans l\'arborescence du menu. Créez une page orpheline.'
]); ?>
</div>
<div class="col4">
<?php
echo template::select('configPage404', array_merge(['none' => 'Aucune'],helper::arrayCollumn($orphans, 'title', 'SORT_ASC')), [
'label' => 'Page inexistante, erreur 404',
'selected' =>$this->getData(['config', 'page404']),
'help' => 'Cette page ne doit pas apparaître dans l\'arborescence du menu. Créez une page orpheline.'
]); ?>
</div>
<div class="col4">
<?php
echo template::select('configPage302', array_merge(['none' => 'Aucune'],helper::arrayCollumn($orphans, 'title', 'SORT_ASC')), [
'label' => 'Site en maintenance',
'selected' =>$this->getData(['config', 'page302']),
'help' => 'Cette page ne doit pas apparaître dans l\'arborescence du menu. Créez une page orpheline.'
]); ?>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col12">
<div class="block" id="social">
<h4>Réseaux sociaux
<div class="openClose">
<?php
echo template::ico('plus','right');
echo template::ico('minus','right');
echo template::ico('plus-circled','right');
echo template::ico('minus-circled','right');
?>
</div>
</h4>
@ -247,8 +295,8 @@
<h4>Référencement
<div class="openClose">
<?php
echo template::ico('plus','right');
echo template::ico('minus','right');
echo template::ico('plus-circled','right');
echo template::ico('minus-circled','right');
?>
</div>
</h4>
@ -294,8 +342,8 @@
<h4>Réseau
<div class="openClose">
<?php
echo template::ico('plus','right');
echo template::ico('minus','right');
echo template::ico('plus-circled','right');
echo template::ico('minus-circled','right');
?>
</div>
</h4>
@ -332,8 +380,8 @@
<h4>Messagerie SMTP
<div class="openClose">
<?php
echo template::ico('plus','right');
echo template::ico('minus','right');
echo template::ico('plus-circled','right');
echo template::ico('minus-circled','right');
?>
</div>
</h4>
@ -403,8 +451,8 @@
<h4>Sécurité de la connexion
<div class="openClose">
<?php
echo template::ico('plus','right');
echo template::ico('minus','right');
echo template::ico('plus-circled','right');
echo template::ico('minus-circled','right');
?>
</div>
</h4>
@ -454,8 +502,8 @@
<h4>Journalisation
<div class="openClose">
<?php
echo template::ico('plus','right');
echo template::ico('minus','right');
echo template::ico('plus-circled','right');
echo template::ico('minus-circled','right');
?>
</div>
</h4>
@ -492,8 +540,8 @@
<h4>Scripts
<div class="openClose">
<?php
echo template::ico('plus','right');
echo template::ico('minus','right');
echo template::ico('plus-circled','right');
echo template::ico('minus-circled','right');
?>
</div>
</h4>
@ -529,57 +577,23 @@
<div class="row">
<div class="col12" >
<div class="block" id="system">
<h4>Système
<h4>Versions des modules
<div class="openClose">
<?php
echo template::ico('plus','right');
echo template::ico('minus','right');
echo template::ico('plus-circled','right');
echo template::ico('minus-circled','right');
?>
</div>
</h4>
<div class="blockContainer">
<div class="row">
<div class="col2">
<?php echo template::text('configVersion', [
'label' => 'ZwiiCMS',
'readonly' => true,
'value' => common::ZWII_VERSION
]); ?>
</div>
<div class="col2">
<?php echo template::text('moduleBlogVersion', [
'label' => 'Blog',
'readonly' => true,
'value' => blog::BLOG_VERSION
]); ?>
</div>
<div class="col2">
<?php echo template::text('moduleFormVersion', [
'label' => 'Form',
'readonly' => true,
'value' => form::FORM_VERSION
]); ?>
</div>
<div class="col2">
<?php echo template::text('moduleGalleryVersion', [
'label' => 'Gallery',
'readonly' => true,
'value' => gallery::GALLERY_VERSION
]); ?>
</div>
<div class="col2">
<?php echo template::text('moduleNewsVersion', [
'label' => 'News',
'readonly' => true,
'value' => news::NEWS_VERSION
]); ?>
</div>
<div class="col2">
<?php echo template::text('moduleRedirectionVersion', [
'label' => 'Redirection',
'readonly' => true,
'value' => redirection::REDIRECTION_VERSION
]); ?>
<div class="col12">
<?php echo 'ZwiiCMS : ' . common::ZWII_VERSION . '&nbsp;&nbsp;-&nbsp;&nbsp;';?>
<?php echo 'Blog : ' . blog::BLOG_VERSION . '&nbsp;&nbsp;-&nbsp;&nbsp;';?>
<?php echo 'Formulaire : ' . form::FORM_VERSION . '&nbsp;&nbsp;-&nbsp;&nbsp;';?>
<?php echo 'News : ' . news::NEWS_VERSION . '&nbsp;&nbsp;-&nbsp;&nbsp;';?>
<?php echo 'Redirection : ' . redirection::REDIRECTION_VERSION . '&nbsp;&nbsp;-&nbsp;&nbsp;';?>
<?php echo 'Recherche : ' . search::SEARCH_VERSION ;?>
</div>
</div>
</div>

View File

@ -9,7 +9,7 @@
* @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/
* @link http://zwiicms.fr/
*/
@import url("site/data/admin.css");

3
core/module/config/view/manage/manage.php Executable file → Normal file
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,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

@ -9,7 +9,7 @@
* @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/
* @link http://zwiicms.fr/
*/
@import url("site/data/admin.css");

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

View File

@ -9,7 +9,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @license GNU General Public License, version 3
* @link http://zwiicms.com/
* @link http://zwiicms.fr/
*/
@ -19,7 +19,7 @@ class install extends common {
'index' => self::GROUP_VISITOR,
'steps' => self::GROUP_ADMIN,
'update' => self::GROUP_ADMIN,
'removeAll' => self::GROUP_ADMIN,
'removeAll' => self::GROUP_ADMIN
];
@ -41,17 +41,44 @@ class install extends common {
else {
// Soumission du formulaire
if($this->isPost()) {
//$sent = $success = false;
$success = true;
// 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)) {
self::$inputNotices['installConfirmPassword'] = 'Incorrect';
$success = false;
}
// Crée l'utilisateur
// Utilisateur
$userFirstname = $this->getInput('installFirstname', helper::FILTER_STRING_SHORT, true);
$userLastname = $this->getInput('installLastname', helper::FILTER_STRING_SHORT, true);
$userMail = $this->getInput('installMail', helper::FILTER_MAIL, true);
$userId = $this->getInput('installId', helper::FILTER_ID, true);
// Bannière par défaut
// Création de l'utilisateur si les données sont complétées.
// success retour de l'enregistrement des données
$success = $this->setData([
'user',
$userId,
[
'firstname' => $userFirstname,
'forgot' => 0,
'group' => self::GROUP_ADMIN,
'lastname' => $userLastname,
'mail' => $userMail,
'password' => $this->getInput('installPassword', helper::FILTER_PASSWORD, true)
]
]);
// Compte créé, envoi du mail et création des données du site
if ($success) { // Formulaire complété envoi du mail
// Envoie le mail
// Sent contient true si réussite sinon code erreur d'envoi en clair
$sent = $this->sendMail(
$userMail,
'Installation de votre site',
'Bonjour' . ' <strong>' . $userFirstname . ' ' . $userLastname . '</strong>,<br><br>' .
'Voici les détails de votre installation.<br><br>' .
'<strong>URL du site :</strong> <a href="' . helper::baseUrl(false) . '" target="_blank">' . helper::baseUrl(false) . '</a><br>' .
'<strong>Identifiant du compte :</strong> ' . $this->getInput('installId') . '<br>',
null
);
// Créer les dossiers
if (!is_dir(self::FILE_DIR.'source/banniere/')) {
mkdir(self::FILE_DIR.'source/banniere/');}
@ -65,50 +92,25 @@ class install extends common {
copy('core/module/install/ressource/file/source/favicon.ico',self::FILE_DIR.'source/favicon.ico');
copy('core/module/install/ressource/file/source/faviconDark.ico',self::FILE_DIR.'source/faviconDark.ico');
// Configure certaines données par défaut
if ($this->getInput('installDefaultData',helper::FILTER_BOOLEAN) === TRUE) {
if ($this->getInput('installDefaultData',helper::FILTER_BOOLEAN) === FALSE) {
$this->initData('page','fr',true);
$this->initData('module','fr',true);
$this->setData(['module', 'blog', 'mon-premier-article', 'userId', $userId]);
$this->setData(['module', 'blog', 'mon-deuxieme-article', 'userId', $userId]);
$this->setData(['module', 'blog', 'mon-troisieme-article', 'userId', $userId]);
}
$success = $this->setData([
'user',
$userId,
[
'firstname' => $userFirstname,
'forgot' => 0,
'group' => self::GROUP_ADMIN,
'lastname' => $userLastname,
'mail' => $userMail,
'password' => $this->getInput('installPassword', helper::FILTER_PASSWORD, true),
'pseudo' => $userFirstname,
'signature'=> self::SIGNATURE_PSEUDO
]
// Stocker le dossier d'installation
$this->setData(['core', 'baseUrl', helper::baseUrl(false,false) ]);
// Générer un fichier robots.txt
$this->createRobots();
// Créer sitemap
$this->createSitemap();
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl(false),
'notification' => ($sent === true ? 'Installation terminée' : $sent),
'state' => ($sent === true ? true : null)
]);
if ($success === true) { // Formulaire complété envoi du mail
// Envoie le mail
$sent = $this->sendMail(
$userMail,
'Installation de votre site',
'Bonjour' . ' <strong>' . $userFirstname . ' ' . $userLastname . '</strong>,<br><br>' .
'Voici les détails de votre installation.<br><br>' .
'<strong>URL du site :</strong> <a href="' . helper::baseUrl(false) . '" target="_blank">' . helper::baseUrl(false) . '</a><br>' .
'<strong>Identifiant du compte :</strong> ' . $this->getInput('installId') . '<br>',
null
);
// Stocker le dossier d'installation
$this->setData(['core', 'baseUrl', helper::baseUrl(false,false) ]);
// Générer un fichier robots.txt
$this->createRobots();
// Créer sitemap
$this->createSitemap();
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl(false),
'notification' => ($sent === true ? 'Installation terminée' : $sent),
'state' => ($sent === true ? true : null)
]);
}
}

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

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

@ -5,10 +5,14 @@ class init extends common {
'analyticsId' => '',
'autoBackup' => true,
'autoUpdate' => true,
'autoUpdateHtaccess' => false,
'cookieConsent' => true,
'favicon' => 'favicon.ico',
'faviconDark' => 'faviconDark.ico',
'homePageId' => 'accueil',
'page302' => 'erreur302',
'page403' => 'erreur403',
'page404' => 'erreur404',
'maintenance' => false,
'social' => [
'facebookId' => 'facebook',
@ -22,22 +26,23 @@ class init extends common {
'timezone' => 'Europe/Paris',
'itemsperPage' => 10,
'legalPageId' => 'mentions-legales',
'searchPageId' => 'recherche',
'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 +114,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 +129,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 +152,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)',
@ -227,9 +234,9 @@ class init extends common {
'disable' => false,
'content' => '<p>Vous pouvez assigner des parents à vos pages afin de mieux organiser votre menu !</p>
<div class="row">
<div class="col4"><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam interdum, neque non vulputate hendrerit, arcu turpis dapibus nisl, id scelerisque metus lectus vitae nisi. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec feugiat dolor et turpis finibus condimentum. Cras sit amet ligula sagittis justo.</p></div>
<div class="col4"><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam interdum, neque non vulputate hendrerit, arcu turpis dapibus nisl, id scelerisque metus lectus vitae nisi. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec feugiat dolor et turpis finibus condimentum. Cras sit amet ligula sagittis justo.</p></div>
<div class="col4"><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam interdum, neque non vulputate hendrerit, arcu turpis dapibus nisl, id scelerisque metus lectus vitae nisi. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec feugiat dolor et turpis finibus condimentum. Cras sit amet ligula sagittis justo.</p></div>
<div class="col4"><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ac dolor arcu. Cras dignissim finibus nisi, vulputate egestas mauris faucibus ultricies. Nullam ornare pretium eleifend. Donec placerat purus ut turpis dapibus condimentum. Fusce at leo pharetra nisl vestibulum fermentum. Maecenas feugiat justo at semper tincidunt. Integer in blandit lorem.</p></div>
<div class="col4"><p>Ergo ego senator inimicus, si ita vultis, homini, amicus esse, sicut semper fui, rei publicae debeo. Quid? si ipsas inimicitias, depono rei publicae causa, quis me tandem iure reprehendet, praesertim cum ego omnium meorum consiliorum atque factorum exempla semper ex summorum hominum consiliis atque factis mihi censuerim petenda.</p></div>
<div class="col4"><p>Principium autem unde latius se funditabat, emersit ex negotio tali. Chilo ex vicario et coniux eius Maxima nomine, questi apud Olybrium ea tempestate urbi praefectum, vitamque suam venenis petitam adseverantes inpetrarunt ut hi, quos suspectati sunt, ilico rapti conpingerentur in vincula, organarius Sericus et Asbolius palaestrita et aruspex Campensis.</p></div>
</div>',
'hideTitle' => false,
'breadCrumb' => true,
@ -255,8 +262,8 @@ class init extends common {
'disable' => false,
'content' => '<p>Cette page n\'est visible que des membres de votre site !</p>
<div class="row">
<div class="col6"><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam interdum, neque non vulputate hendrerit, arcu turpis dapibus nisl, id scelerisque metus lectus vitae nisi. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec feugiat dolor et turpis finibus condimentum. Cras sit amet ligula sagittis justo.</p></div>
<div class="col6"><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam interdum, neque non vulputate hendrerit, arcu turpis dapibus nisl, id scelerisque metus lectus vitae nisi. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec feugiat dolor et turpis finibus condimentum. Cras sit amet ligula sagittis justo.</p></div>
<div class="col6"><p>Eius populus ab incunabulis primis ad usque pueritiae tempus extremum, quod annis circumcluditur fere trecentis, circummurana pertulit bella, deinde aetatem ingressus adultam post multiplices bellorum aerumnas Alpes transcendit et fretum, in iuvenem erectus et virum ex omni plaga quam orbis ambit inmensus, reportavit laureas et triumphos, iamque vergens in senium et nomine solo aliquotiens vincens ad tranquilliora vitae discessit.</p></div>
<div class="col6"><p>Exsistit autem hoc loco quaedam quaestio subdifficilis, num quando amici novi, digni amicitia, veteribus sint anteponendi, ut equis vetulis teneros anteponere solemus. Indigna homine dubitatio! Non enim debent esse amicitiarum sicut aliarum rerum satietates; veterrima quaeque, ut ea vina, quae vetustatem ferunt, esse debet suavissima; verumque illud est, quod dicitur, multos modios salis simul edendos esse, ut amicitiae munus expletum sit.</p></div>
</div>',
'hideTitle' => false,
'breadCrumb' => true,
@ -291,7 +298,7 @@ class init extends common {
'moduleId' => '',
'parentPageId' => 'accueil',
'modulePosition' => 'bottom',
'position' => 3,
'position' => 2,
'group' => self::GROUP_VISITOR,
'targetBlank' => false,
'title' => 'Mise en page',
@ -339,7 +346,7 @@ class init extends common {
'moduleId' => 'blog',
'modulePosition' => 'bottom',
'parentPageId' => '',
'position' => 4,
'position' => 3,
'group' => self::GROUP_VISITOR,
'targetBlank' => false,
'title' => 'Blog',
@ -362,7 +369,7 @@ class init extends common {
'moduleId' => 'gallery',
'modulePosition' => 'bottom',
'parentPageId' => '',
'position' => 5,
'position' => 4,
'group' => self::GROUP_VISITOR,
'targetBlank' => false,
'title' => 'Galeries',
@ -386,7 +393,7 @@ class init extends common {
'moduleId' => 'redirection',
'modulePosition' => 'bottom',
'parentPageId' => '',
'position' => 6,
'position' => 5,
'group' => self::GROUP_VISITOR,
'targetBlank' => true,
'title' => 'Site de Zwii',
@ -409,7 +416,7 @@ class init extends common {
'moduleId' => 'form',
'modulePosition' => 'bottom',
'parentPageId' => '',
'position' => 7,
'position' => 6,
'group' => self::GROUP_VISITOR,
'targetBlank' => false,
'title' => 'Contact',
@ -537,7 +544,101 @@ class init extends common {
'hideMenuSide' => false,
'hideMenuHead' => false,
'hideMenuChildren' => false
]
],
'erreur302' => [
'typeMenu' => 'text',
'iconUrl' => '',
'disable' => false,
'content' => '<p>Notre site est actuellement en maintenance. Nous sommes d&eacute;sol&eacute;s pour la g&ecirc;ne occasionn&eacute;e et faisons notre possible pour &ecirc;tre rapidement de retour.</p>
<div class="row"><div class="col4 offset8 textAlignCenter"><a href="./?user/login" id="maintenanceLogin" name="maintenanceLogin" class="button"><span class="zwiico-lock zwiico-margin-right"></span>Administration</a></div></div>',
'hideTitle' => false,
'breadCrumb' => false,
'metaDescription' => '',
'metaTitle' => '',
'moduleId' => '',
'modulePosition' => '',
'parentPageId' => '',
'position' => 0,
'group' => self::GROUP_VISITOR,
'targetBlank' => false,
'title' => 'Maintenance en cours',
'block' => '12',
'barLeft' => '',
'barRight' => '',
'displayMenu' => 'none',
'hideMenuSide' => true,
'hideMenuHead' => true,
'hideMenuChildren' => true
],
'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' => 'search',
'modulePosition' => 'bottom',
'parentPageId' => '',
'position' => 0,
'group' => self::GROUP_VISITOR,
'targetBlank' => false,
'title' => 'Erreur 404',
'block' => '12',
'barLeft' => '',
'barRight' => '',
'displayMenu' => 'none',
'hideMenuSide' => false,
'hideMenuChildren' =>false
],
'recherche' => [
'typeMenu' => 'icon',
'iconUrl' => 'icones/loupe.png',
'disable' => false,
'content' => '<h1>Rechercher dans le site</h1>',
'hideTitle' => true,
'breadCrumb' => false,
'metaDescription' => '',
'metaTitle' => '',
'moduleId' => 'search',
'modulePosition' => 'bottom',
'parentPageId' => '',
'position' => 7,
'group' => self::GROUP_VISITOR,
'targetBlank' => false,
'title' => 'Recherche',
'block' => '12',
'barLeft' => '',
'barRight' => '',
'displayMenu' => 'none',
'hideMenuSide' => false,
'hideMenuChildren' => false
],
],
'module' => [
'blog' => [
@ -551,7 +652,7 @@ class init extends common {
'userId' => ''
]
],
'content' => '<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. In a placerat metus. Morbi luctus laoreet dolor et euismod. Phasellus eget eros ac eros pretium tincidunt. Sed maximus magna lectus, non vestibulum sapien pretium maximus. Donec convallis leo tortor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cras convallis lacus eu risus gravida varius. Etiam mattis massa vitae eros placerat bibendum.</p><p>Vivamus tempus magna augue, in bibendum quam blandit at. Morbi felis tortor, suscipit ut ipsum ut, volutpat consectetur orci. Nulla tincidunt quis ligula non viverra. Sed pretium dictum blandit. Donec fringilla, nunc at dictum pretium, arcu massa viverra leo, et porta turpis ipsum eget risus. Quisque quis maximus purus, in elementum arcu. Donec nisi orci, aliquam non luctus non, congue volutpat massa. Curabitur sed risus congue, porta arcu vel, tincidunt nisi. Duis tincidunt quam ut velit maximus ornare. Nullam sagittis, ante quis pharetra hendrerit, lorem massa dapibus mi, a hendrerit dolor odio nec augue. Nunc sem nisl, tincidunt vitae nunc et, viverra tristique diam. In eget dignissim lectus. Nullam volutpat lacus id ex dapibus viverra. Pellentesque ultricies lorem ut nunc elementum volutpat. Cras id ultrices justo.</p><p>Phasellus nec erat leo. Praesent at sem nunc. Vestibulum quis condimentum turpis. Cras semper diam vitae enim fringilla, ut fringilla mauris efficitur. In nec porttitor urna. Nam eros leo, vehicula eget lobortis sed, gravida id mauris. Nulla bibendum nunc tortor, non bibendum justo consectetur vel. Phasellus nec risus diam. In commodo tellus nec nulla fringilla, nec feugiat nunc consectetur. Etiam non eros sodales, sodales lacus vel, finibus leo. Quisque hendrerit tristique congue. Phasellus nec augue vitae libero elementum facilisis. Mauris pretium ornare nisi, non scelerisque velit consectetur sit amet.</p>',
'content' => '<p>Et eodem impetu Domitianum praecipitem per scalas itidem funibus constrinxerunt, eosque coniunctos per ampla spatia civitatis acri raptavere discursu. iamque artuum et membrorum divulsa conpage superscandentes corpora mortuorum ad ultimam truncata deformitatem velut exsaturati mox abiecerunt in flumen.</p><p>Ex his quidam aeternitati se commendari posse per statuas aestimantes eas ardenter adfectant quasi plus praemii de figmentis aereis sensu carentibus adepturi, quam ex conscientia honeste recteque factorum, easque auro curant inbracteari, quod Acilio Glabrioni delatum est primo, cum consiliis armisque regem superasset Antiochum. quam autem sit pulchrum exigua haec spernentem et minima ad ascensus verae gloriae tendere longos et arduos, ut memorat vates Ascraeus, Censorius Cato monstravit. qui interrogatus quam ob rem inter multos... statuam non haberet malo inquit ambigere bonos quam ob rem id non meruerim, quam quod est gravius cur inpetraverim mussitare.</p><p>Latius iam disseminata licentia onerosus bonis omnibus Caesar nullum post haec adhibens modum orientis latera cuncta vexabat nec honoratis parcens nec urbium primatibus nec plebeiis.</p>',
'picture' => 'galerie/landscape/meadow.jpg',
'hidePicture' => false,
'pictureSize' => 20,
@ -563,7 +664,7 @@ class init extends common {
'mon-deuxieme-article' => [
'closeComment' => false,
'comment' => [],
'content' => '<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam lobortis eros pharetra metus rutrum pretium et sagittis mauris. Donec commodo venenatis sem nec suscipit. In tempor sollicitudin scelerisque. Etiam quis nibh eleifend, congue nisl quis, ultricies ipsum. Integer at est a eros vulputate pellentesque eu vitae tellus. Nullam suscipit quam nisl. Vivamus dui odio, luctus ac fringilla ultrices, eleifend vel sapien. Integer sem ex, lobortis eu mattis eu, condimentum non libero. Aliquam non porttitor elit, eu hendrerit neque. Praesent tortor urna, tincidunt sed dictum id, rutrum tempus sapien.</p><p>Donec accumsan ante ac odio laoreet porttitor. Pellentesque et leo a leo scelerisque mattis id vel elit. Quisque egestas congue enim nec semper. Morbi mollis nibh sapien. Nunc quis fringilla lorem. Donec vel venenatis nunc. Donec lectus velit, tempor sit amet dui sed, consequat commodo enim. Nam porttitor neque semper, dapibus nunc bibendum, lobortis urna. Morbi ullamcorper molestie lectus a elementum. Curabitur eu cursus orci, sed tristique justo. In massa lacus, imperdiet eu elit quis, consectetur maximus magna. Integer suscipit varius ante vitae egestas. Morbi scelerisque fermentum ipsum, euismod faucibus mi tincidunt id. Sed at consectetur velit. Ut fermentum nunc nibh, at commodo felis lacinia nec.</p><p>Nullam a justo quis lectus facilisis semper eget quis sem. Morbi suscipit erat sem, non fermentum nunc luctus vel. Proin venenatis quam ut arcu luctus efficitur. Interdum et malesuada fames ac ante ipsum primis in faucibus. Nam sollicitudin tristique nunc nec convallis. Maecenas id tortor semper, tempus nisl laoreet, cursus lacus. Aliquam sagittis est in leo congue, a pharetra felis aliquet. Nulla gravida lobortis sapien, quis viverra enim ullamcorper sed. Donec ultrices sem eu volutpat dapibus. Nam euismod, tellus eu congue mollis, massa nisi finibus odio, vitae porta arcu urna ac lorem. Sed faucibus dignissim pretium. Pellentesque eget ante tellus. Pellentesque a elementum odio, sit amet vulputate diam. Lorem ipsum dolor sit amet, consectetur adipiscing elit. In hendrerit consequat dolor, malesuada pellentesque tellus molestie non. Aenean quis purus a lectus pellentesque laoreet.</p>',
'content' => '<p>Et prima post Osdroenam quam, ut dictum est, ab hac descriptione discrevimus, Commagena, nunc Euphratensis, clementer adsurgit, Hierapoli, vetere Nino et Samosata civitatibus amplis inlustris.</p><p>Ob haec et huius modi multa, quae cernebantur in paucis, omnibus timeri sunt coepta. et ne tot malis dissimulatis paulatimque serpentibus acervi crescerent aerumnarum, nobilitatis decreto legati mittuntur: Praetextatus ex urbi praefecto et ex vicario Venustus et ex consulari Minervius oraturi, ne delictis supplicia sint grandiora, neve senator quisquam inusitato et inlicito more tormentis exponeretur.</p><p>Sed ut tum ad senem senex de senectute, sic hoc libro ad amicum amicissimus scripsi de amicitia. Tum est Cato locutus, quo erat nemo fere senior temporibus illis, nemo prudentior; nunc Laelius et sapiens (sic enim est habitus) et amicitiae gloria excellens de amicitia loquetur. Tu velim a me animum parumper avertas, Laelium loqui ipsum putes. C. Fannius et Q. Mucius ad socerum veniunt post mortem Africani; ab his sermo oritur, respondet Laelius, cuius tota disputatio est de amicitia, quam legens te ipse cognosces.</p>',
'picture' => 'galerie/landscape/desert.jpg',
'hidePicture' => false,
'pictureSize' => 40,
@ -575,7 +676,7 @@ class init extends common {
'mon-troisieme-article' => [
'closeComment' => true,
'comment' => [],
'content' => '<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut ut tempus nibh. Cras eget iaculis justo, ac laoreet lacus. Nunc tellus nulla, auctor id hendrerit eu, pellentesque in sapien. In hac habitasse platea dictumst. Aliquam leo urna, hendrerit id nunc eget, finibus maximus dolor. Sed rutrum sapien consectetur, tincidunt nulla at, blandit quam. Duis ex enim, vehicula vel nisi vitae, lobortis volutpat nisl. Vivamus enim libero, euismod nec risus vel, interdum placerat elit. In cursus sapien condimentum dui imperdiet, sed lobortis ante consectetur. Maecenas hendrerit eget felis non consequat.</p><p>Nullam nec risus non velit efficitur tempus eget tincidunt mauris. Etiam venenatis leo id justo sagittis, commodo dignissim sapien tristique. Vivamus finibus augue malesuada sapien gravida rutrum. Integer mattis lectus ac pulvinar scelerisque. Integer suscipit feugiat metus, ac molestie odio suscipit eget. Fusce at elit in tellus venenatis finibus id sit amet magna. Integer sodales luctus neque blandit posuere. Cras pellentesque dictum lorem eget vestibulum. Quisque vitae metus non nisi efficitur rhoncus ut vitae ipsum. Donec accumsan massa at est faucibus lacinia. Quisque imperdiet luctus neque eu vestibulum. Phasellus pellentesque felis ligula, id imperdiet elit ultrices eu.</p>',
'content' => '<p>Rogatus ad ultimum admissusque in consistorium ambage nulla praegressa inconsiderate et leviter proficiscere inquit ut praeceptum est, Caesar sciens quod si cessaveris, et tuas et palatii tui auferri iubebo prope diem annonas. hocque solo contumaciter dicto subiratus abscessit nec in conspectum eius postea venit saepius arcessitus.</p><p>Proinde concepta rabie saeviore, quam desperatio incendebat et fames, amplificatis viribus ardore incohibili in excidium urbium matris Seleuciae efferebantur, quam comes tuebatur Castricius tresque legiones bellicis sudoribus induratae.</p><p>Inter has ruinarum varietates a Nisibi quam tuebatur accitus Vrsicinus, cui nos obsecuturos iunxerat imperiale praeceptum, dispicere litis exitialis certamina cogebatur abnuens et reclamans, adulatorum oblatrantibus turmis, bellicosus sane milesque semper et militum ductor sed forensibus iurgiis longe discretus, qui metu sui discriminis anxius cum accusatores quaesitoresque subditivos sibi consociatos ex isdem foveis cerneret emergentes, quae clam palamve agitabantur, occultis Constantium litteris edocebat inplorans subsidia, quorum metu tumor notissimus Caesaris exhalaret.</p>',
'picture' => 'galerie/landscape/iceberg.jpg',
'hidePicture' => false,
'pictureSize' => 100,
@ -632,7 +733,7 @@ class init extends common {
'contact' => [
'config' => [
'button' => '',
'capcha' => true,
'captcha' => true,
'group' => self::GROUP_ADMIN,
'pageId' => '',
'subject' => ''
@ -665,3 +766,4 @@ class init extends common {
]
];
}

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

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

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @license GNU General Public License, version 3
* @link http://zwiicms.com/
* @link http://zwiicms.fr/
*/
/**

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

@ -38,8 +38,8 @@
</div>
<div class="row">
<div class="col12">
<?php echo template::checkbox('installDefaultData',true , 'Charger un exemple de site', [
'checked' => true
<?php echo template::checkbox('installDefaultData',true , 'Ne pas charger l\'exemple de site (utilisateurs avancés)', [
'checked' => false
]);
?>
</div>

View File

@ -9,7 +9,7 @@
* @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/
* @link http://zwiicms.fr/
*/

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

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

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

@ -9,7 +9,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @license GNU General Public License, version 3
* @link http://zwiicms.com/
* @link http://zwiicms.fr/
*/
class maintenance extends common {
@ -22,12 +22,23 @@ class maintenance extends common {
* Maintenance
*/
public function index() {
// Valeurs en sortie
$this->addOutput([
'display' => self::DISPLAY_LAYOUT_LIGHT,
'title' => 'Maintenance en cours...',
'view' => 'index'
]);
// Page perso définie et existante
if ($this->getData(['config','page302']) !== 'none'
AND $this->getData(['page',$this->getData(['config','page302'])]) ) {
$this->addOutput([
'display' => self::DISPLAY_LAYOUT_LIGHT,
'title' => $this->getData(['page',$this->getData(['config','page302']),'title']),
'content' => $this->getdata(['page',$this->getData(['config','page302']),'content']),
'view' => 'index'
]);
} else {
// Valeurs en sortie
$this->addOutput([
'display' => self::DISPLAY_LAYOUT_LIGHT,
'title' => 'Maintenance en cours...',
'view' => 'index'
]);
}
}
}

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

@ -2,7 +2,7 @@
<div class="row">
<div class="col4 offset8 textAlignCenter">
<?php echo template::button('maintenanceLogin', [
'value' => 'Administration',
'value' => 'Connexion',
'href' => helper::baseUrl() . 'user/login',
'ico' => 'lock'
]); ?>

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

@ -11,7 +11,7 @@
* @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/
* @link http://zwiicms.fr/
*/
class page extends common {
@ -19,7 +19,8 @@ class page extends common {
public static $actions = [
'add' => self::GROUP_MODERATOR,
'delete' => self::GROUP_MODERATOR,
'edit' => self::GROUP_MODERATOR
'edit' => self::GROUP_MODERATOR,
'duplicate' => self::GROUP_MODERATOR
];
public static $pagesNoParentId = [
'' => 'Aucune'
@ -34,12 +35,13 @@ class page extends common {
'blog' => 'Blog',
'form' => 'Formulaire',
'gallery' => 'Galerie',
'redirection' => 'Redirection'
'redirection' => 'Redirection',
'search' => 'Recherche'
];
public static $typeMenu = [
'text' => 'Texte',
'icon' => 'Icône',
'icontitle' => 'Icône et bulle'
'icontitle' => 'Icône avec bulle de texte'
];
// Position du module
public static $modulePosition = [
@ -64,6 +66,62 @@ class page extends common {
'children' => 'Le sous-menu de la page parente'
];
/**
* Duplication
*/
public function duplicate() {
// Adresse sans le token
$url = explode('&',$this->getUrl(2));
// La page n'existe pas
if($this->getData(['page', $url[0]]) === null) {
// Valeurs en sortie
$this->addOutput([
'access' => false
]);
} // Jeton incorrect
elseif(!isset($_GET['csrf'])) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $url[0],
'notification' => 'Jeton invalide'
]);
}
elseif ($_GET['csrf'] !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $url[0],
'notification' => 'Suppression non autorisée'
]);
}
// Duplication de la page
$pageTitle = $this->getData(['page',$url[0],'title']);
$pageId = helper::increment(helper::filter($pageTitle, helper::FILTER_ID), $this->getData(['page']));
$data = $this->getData([
'page',
$url[0]
]);
// Ecriture
$this->setData (['page',$pageId,$data]);
$notification = 'La page a été 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 = 'La page et son module ont été dupliqués';
}
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $pageId,
'notification' => $notification,
'state' => true
]);
}
/**
* Création
*/
@ -120,13 +178,67 @@ class page extends common {
$this->addOutput([
'access' => false
]);
} // Jeton incorrect
elseif(!isset($_GET['csrf'])) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $url[0],
'notification' => 'Jeton invalide'
]);
}
elseif ($_GET['csrf'] !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $url[0],
'notification' => 'Suppression non autorisée'
]);
}
// Impossible de supprimer la page d'accueil
elseif($url[0] === $this->getData(['config', 'homePageId'])) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'page/edit/' . $url[0],
'notification' => 'Impossible de supprimer la page d\'accueil'
'redirect' => helper::baseUrl() . 'config',
'notification' => 'Désactiver la page dans la configuration avant de la supprimer'
]);
}
// Impossible de supprimer la page de recherche affectée
elseif($url[0] === $this->getData(['config', 'searchPageId'])) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'config',
'notification' => 'Désactiver la page dans la configuration avant de la supprimer'
]);
}
// Impossible de supprimer la page des mentions légales affectée
elseif($url[0] === $this->getData(['config', 'legalPageId'])) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'config',
'notification' => 'Désactiver la page dans la configuration avant de la supprimer'
]);
}
// Impossible de supprimer la page des mentions légales affectée
elseif($url[0] === $this->getData(['config', 'page404'])) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'config',
'notification' => 'Désactiver la page dans la configuration avant de la supprimer'
]);
}
// Impossible de supprimer la page des mentions légales affectée
elseif($url[0] === $this->getData(['config', 'page403'])) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'config',
'notification' => 'Désactiver la page dans la configuration avant de la supprimer'
]);
}
// Impossible de supprimer la page des mentions légales affectée
elseif($url[0] === $this->getData(['config', 'page302'])) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . 'config',
'notification' => 'Désactiver la page dans la configuration avant de la supprimer'
]);
}
// Jeton incorrect
@ -184,7 +296,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);
@ -215,6 +332,22 @@ class page extends common {
if($pageId !== $this->getUrl(2)) {
$this->deleteData(['page', $this->getUrl(2)]);
}
// Traitement des pages spéciales affectées dans la config :
if ($this->getUrl(2) === $this->getData(['config', 'legalPageId']) ) {
$this->setData(['config','legalPageId', $pageId]);
}
if ($this->getUrl(2) === $this->getData(['config', 'searchPageId']) ) {
$this->setData(['config','searchPageId', $pageId]);
}
if ($this->getUrl(2) === $this->getData(['config', 'page404']) ) {
$this->setData(['config','page404', $pageId]);
}
if ($this->getUrl(2) === $this->getData(['config', 'page403']) ) {
$this->setData(['config','page403', $pageId]);
}
if ($this->getUrl(2) === $this->getData(['config', 'page302']) ) {
$this->setData(['config','page302', $pageId]);
}
// Si la page est une page enfant, actualise les positions des autres enfants du parent, sinon actualise les pages sans parents
$lastPosition = 1;
$hierarchy = $this->getInput('pageEditParentPageId') ? $this->getHierarchy($this->getInput('pageEditParentPageId')) : array_keys($this->getHierarchy());

View File

@ -9,7 +9,7 @@
* @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/
* @link http://zwiicms.fr/
*/
@ -20,21 +20,21 @@
display: none;
}
#info .zwiico-minus,
#layout .zwiico-minus,
#location .zwiico-minus {
#info .zwiico-minus-circled,
#layout .zwiico-minus-circled,
#location .zwiico-minus-circled {
display: inline;
}
.zwiico-minus,
#info .zwiico-plus,
#layout .zwiico-plus,
#location .zwiico-plus {
.zwiico-minus-circled,
#info .zwiico-plus-circled,
#layout .zwiico-plus-circled,
#location .zwiico-plus-circled {
display: none;
}
.zwiico-minus,
.zwiico-plus {
.zwiico-minus-circled,
.zwiico-plus-circled {
cursor: pointer;
}

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

@ -9,7 +9,7 @@
* @authorFré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/
* @link http://zwiicms.fr/
*/
/**
@ -59,8 +59,8 @@ $( document ).ready(function() {
var i = ["info", "layout", "setup", "location", "advanced", "ceo" ];
$.each(i,function(e) {
if (getCookie(i[e]) === "true") {
$("#" + i[e]).find(".zwiico-plus").hide();
$("#" + i[e]).find(".zwiico-minus").show();
$("#" + i[e]).find(".zwiico-plus-circled").hide();
$("#" + i[e]).find(".zwiico-minus-circled").show();
$("#" + i[e]).find(".blockContainer").show();
}
});
@ -73,8 +73,8 @@ $( document ).ready(function() {
*/
$("div .block").click(function(e) {
$(this).find(".zwiico-plus").toggle();
$(this).find(".zwiico-minus").toggle();
$(this).find(".zwiico-plus-circled").toggle();
$(this).find(".zwiico-minus-circled").toggle();
$(this).find(".blockContainer").slideToggle();
/*
* Sauvegarder la position des blocs

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

@ -5,7 +5,7 @@ echo template::formOpen('pageEditForm');
<div class="row">
<div class="col2">
<?php $href = helper::baseUrl() . $this->getUrl(2); ?>
<?php if ($this->getData(['page', $this->getUrl(2), 'moduleId']) === 'redirection' || 'code')$href = helper::baseUrl(); ?>
<?php if ($this->getData(['page', $this->getUrl(2), 'moduleId']) === 'redirection' || 'code')$href = helper::baseUrl(); ?>
<?php echo template::button('pageEditBack', [
'class' => 'buttonGrey',
'href' => $href,
@ -13,7 +13,14 @@ echo template::formOpen('pageEditForm');
'value' => 'Retour'
]); ?>
</div>
<div class="col2 offset6">
<div class="col2 offset4">
<?php echo template::button('pageEditDuplicate', [
'href' => helper::baseUrl() . 'page/duplicate/' . $this->getUrl(2) . '&csrf=' . $_SESSION['csrf'],
'value' => 'Dupliquer',
'ico' => 'clone'
]); ?>
</div>
<div class="col2">
<?php echo template::button('pageEditDelete', [
'class' => 'buttonRed',
'href' => helper::baseUrl() . 'page/delete/' . $this->getUrl(2) . '&csrf=' . $_SESSION['csrf'],
@ -63,13 +70,13 @@ echo template::formOpen('pageEditForm');
<div class="row">
<div class="col4">
<?php echo template::select('pageTypeMenu', $module::$typeMenu,[
'help' => 'La page peut être représentée par une image de petite taille.',
'label' => 'Aspect',
'label' => 'Aspect du lien',
'selected' => $this->getData(['page', $this->getUrl(2), 'typeMenu'])
]); ?>
</div>
<div class="col4">
<?php echo template::file('pageIconUrl', [
'help' => 'Sélectionnez une image ou une icône de petite dimension',
'label' => 'Icône',
'value' => $this->getData(['page', $this->getUrl(2), 'iconUrl'])
]); ?>
@ -77,7 +84,7 @@ echo template::formOpen('pageEditForm');
<div class="col4">
<?php echo template::select('configModulePosition', $module::$modulePosition,[
'help' => 'En position libre ajoutez le module en plaçant [MODULE] à l\'endroit voulu dans votre page.',
'label' => 'Position du module dans la page',
'label' => 'Position du module',
'selected' => $this->getData(['page', $this->getUrl(2), 'modulePosition'])
]); ?>
</div>
@ -99,8 +106,8 @@ echo template::formOpen('pageEditForm');
<h4>Mise en page
<div class="openClose">
<?php
echo template::ico('plus','right');
echo template::ico('minus','right');
echo template::ico('plus-circled','right');
echo template::ico('minus-circled','right');
?>
</div>
</h4>
@ -156,8 +163,8 @@ echo template::formOpen('pageEditForm');
<h4>Emplacement dans le menu
<div class="openClose">
<?php
echo template::ico('plus','right');
echo template::ico('minus','right');
echo template::ico('plus-circled','right');
echo template::ico('minus-circled','right');
?>
</div>
</h4>
@ -216,11 +223,11 @@ echo template::formOpen('pageEditForm');
<div class='row' id="pageEditAdvancedWrapper">
<div class="col12">
<div class="block" id="advanced">
<h4>Options avancées d'emplacement
<h4>Options d'emplacement avancées
<div class="openClose">
<?php
echo template::ico('plus','right');
echo template::ico('minus','right');
echo template::ico('plus-circled','right');
echo template::ico('minus-circled','right');
?>
</div>
</h4>
@ -248,8 +255,8 @@ echo template::formOpen('pageEditForm');
<h4>Permission et référencement
<div class="openClose">
<?php
echo template::ico('plus','right');
echo template::ico('minus','right');
echo template::ico('plus-circled','right');
echo template::ico('minus-circled','right');
?>
</div>
</h4>

View File

@ -1,211 +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
* @license GNU General Public License, version 3
* @link http://zwiicms.com/
*
* Module search
* Produit par la communauté à partit d'un développement de Sylvain Lelièvre
*/
// Module de recherche d'un mot ou d'une phrase clef
class search extends common {
public static $actions = [
'index' => self::GROUP_VISITOR
];
public function index() {
if($this->isPost()) {
//Initialisations variables
$success = true;
$result = '';
$notification = '';
$total='';
$this->setData(['search',$total,0]);
// Récupération du mot clef passé par le formulaire de ...view/index.php, avec caractères accentués
$motclef=$this->getInput('searchMotphraseclef');
// Récupération de l'état de l'option mot entier passé par le même formulaire
$motentier=$this->getInput('searchMotentier', helper::FILTER_BOOLEAN);
//Pour affichage de l'entête du résultat
$result = '<h1>Recherche avec le mot clef : '.$motclef.'<br/></h1>';
if ($motclef !== "" && strlen($motclef) > 2) {
foreach($this->getHierarchy(null,false,null) as $parentId => $childIds) {
if ($this->getData(['page', $parentId, 'disable']) === false &&
$this->getUser('group') >= $this->getData(['page', $parentId, 'group']) &&
$this->getData(['page', $parentId, 'block']) !== 'bar') {
$url = $parentId;
$titre = $this->getData(['page', $parentId, 'title']);
$contenu = $this->getData(['page', $parentId, 'content']);
// Pages sauf pages filles et articles de blog
$result .= $this->occurrence($url, $titre, $contenu, $motclef, $motentier);
}
foreach($childIds as $childId) {
// Sous page
if ($this->getData(['page', $childId, 'disable']) === false &&
$this->getUser('group') >= $this->getData(['page', $parentId, 'group']) &&
$this->getData(['page', $parentId, 'block']) !== 'bar') {
$url = $childId;
$titre = $this->getData(['page', $childId, 'title']);
$contenu = $this->getData(['page', $childId, 'content']);
//Pages filles
$result .= $this->occurrence($url, $titre, $contenu, $motclef, $motentier);
}
// Articles d'une sous-page blog
if ($this->getData(['page', $childId, 'moduleId']) === 'blog')
{
foreach($this->getData(['module',$childId]) as $articleId => $article) {
if($this->getData(['module',$childId,$articleId,'state']) === true) {
$url = $childId . '/' . $articleId;
$titre = $article['title'];
$contenu = $article['content'];
// Articles de sous-page de type blog
$result .= $this->occurrence($url, $titre, $contenu, $motclef, $motentier);
}
}
}
}
// Articles d'un blog
if ($this->getData(['page', $parentId, 'moduleId']) === 'blog' ) {
foreach($this->getData(['module',$parentId]) as $articleId => $article) {
if($this->getData(['module',$parentId,$articleId,'state']) === true)
{
$url = $parentId. '/' . $articleId;
$titre = $article['title'];
$contenu = $article['content'];
// Articles de Blog
$result .= $this->occurrence($url, $titre, $contenu, $motclef, $motentier);
}
}
}
}
// Message de synthèse de la recherche
if ($this->getData(['search',$total])===0) {
$notification = 'Mot clef non trouv&eacute;. Avez-vous pens&eacute; aux accents ?';
$result .='Mot clef non trouv&eacute;. Avez-vous pens&eacute; aux accents ?';
$success = false;
} else {
$result .= 'Nombre d\'occurrences : '.$this->getData(['search',$total]);
$notification = 'Nombre d\'occurrences : '.$this->getData(['search',$total]);
$success = true;
}
} else {
$notification = 'Trop court ! Minimum 3 caract&egrave;res';
$result = 'Trop court ! Minimum 3 caract&egrave;res';
$success = false;
}
$_POST['result'] = $result;
$_POST['occurence'] = $total;
// Valeurs en sortie, affichage du résultat
$this->addOutput([
'title' => '',
'view' => 'result',
'notification' => $notification,
'state' => $success
]);
} else {
// Valeurs en sortie, affichage du formulaire
$this->addOutput([
'title' => '',
'view' => 'index'
]);
}
}
// Fonction de recherche des occurrences dans $contenu
// Renvoie le résultat sous forme de chaîne
private function occurrence($url, $titre, $contenu, $motclef, $motentier)
{
// Nettoyage de $contenu : on enlève tout ce qui est inclus entre < et >
$contenu = $this->nettoyer_html($contenu);
// Accentuation
$contenu = html_entity_decode($contenu);
// Initialisations
$nboccu = 0;
$dejavu = '';
$total = '';
$resultat= '';
// Recherche des occurrences
do {
$occu = stristr($contenu,$motclef);
if ($occu !== false) {
if ($motentier === true) {
$controle_entier=$this->test_motentier($contenu,$motclef);
} else {
$controle_entier=true;
}
if ($controle_entier) {
if ($titre !== $dejavu) {
$resultat = '<p><br/>Mot clef trouv&eacute; dans la page : <a href="./?'.$url.'" target="_blank" rel="noopener">'.$titre.'</a><br/></p>';
}
$dejavu = $titre;
$nboccu++;
$resultat .= '<p>'.$nboccu.' - "...<em>'.substr($occu,0,200).'</em>..."<br/></p>';
}
// Pour recherche d'une autre occurrence dans le même contenu
$contenu = substr($occu,10);
}
}
while($occu != '');
$this->setData(['search',$total,$this->getData(['search',$total]) + $nboccu]);
return $resultat;
}
// Déclaration de la fonction nettoyer(string $contenu) : string
// Supprime de $contenu les caractères placés entre < et >, donc les balises html comme <p> <br/> etc...
// Retourne $contenu nettoyée, le résultat est sensiblement différent de celui obtenu avec la fonction strip_tags()
private function nettoyer_html($contenu)
{
do {
$pos1=strpos($contenu,chr(60));
if($pos1!==false) {
$pos2=strpos($contenu,chr(62));
if($pos2!==false) $contenu=substr_replace($contenu," ",$pos1,($pos2 - $pos1 + 1));
}
}
while($pos1!==false);
return $contenu;
}
// Déclaration de la fonction test_motentier(string $chaine, string $clef) : bool
// Vérifie si dans la string $chaine, $clef est un mot entier
// $clef ne doit pas être précédé ni suivi d'une lettre maj ou min
private function test_motentier($chaine, $clef)
{
$resultat=true;
$pos1=stripos($chaine,$clef);
$avant=ord(substr($chaine,$pos1-1, 1));
$apres=ord(substr($chaine,$pos1+strlen($clef),1));
// Traitement pour le caractère qui précède et celui qui suit
if (($avant>=65 && $avant<=90) ||
($avant>=97 && $avant<=122) ||
($apres>=65 && $apres<=90) ||
($apres>=97 && $apres<=122) ) {
$resultat=false;
}
return $resultat;
}
}

View File

@ -1,29 +0,0 @@
<?php echo template::formOpen('searchForm'); ?>
<div class="row">
<div class="col12">
<div class="block">
<h4>Rechercher</h4>
<div class="row">
<div class="col10 verticalAlignBottom">
<?php echo template::text('searchMotphraseclef', [
'label' => 'Mot ou phrase',
'help' => 'Tout ou partie d\'un mot ou d\'une phrase, sans guillemets. N\'oubliez pas les accents.'
]); ?>
</div>
<div class="col2 verticalAlignBottom">
<?php echo template::submit('pageEditSubmit', [
'value' => 'Ok'
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<?php echo template::checkbox('searchMotentier', true, 'Mot entier uniquement', [
'checked' => false
]); ?>
</div>
</div>
</div>
</div>
</div>
<?php echo template::formClose(); ?>

View File

@ -1,38 +0,0 @@
<?php echo template::formOpen('searchForm'); ?>
<div class="row">
<div class="col12">
<div class="block">
<h4>Recherche</h4>
<div class="row">
<div class="col10 verticalAlignBottom">
<?php echo template::text('searchMotphraseclef', [
'label' => 'Mot ou phrase',
'value' => isset($_POST['searchMotphraseclef']) === true ? $_POST['searchMotphraseclef'] : '',
'help' => 'Tout ou partie d\'un mot ou d\'une phrase, sans guillemets. N\'oubliez pas les accents.'
]); ?>
</div>
<div class="col2 verticalAlignBottom">
<?php echo template::submit('pageEditSubmit', [
'value' => 'Ok'
]); ?>
</div>
</div>
<div class="row">
<?php echo template::checkbox('searchMotentier', true, 'Mot entier uniquement', [
'checked' => isset($_POST['searchMotentier']) === true ? $_POST['searchMotentier'] : ''
]); ?>
</div>
</div>
</div>
<div class="col12">
<div class="block">
<h4>Résultat(s)</h4>
<?php if (isset($_POST['result'])) {
echo $_POST['result'];
} else {
echo "Rien à afficher";
} ?>
</div>
</div>
</div>
<?php echo template::formClose(); ?>

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

@ -9,7 +9,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @license GNU General Public License, version 3
* @link http://zwiicms.com/
* @link http://zwiicms.fr/
*/
class sitemap extends common {

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

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

@ -9,7 +9,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @license GNU General Public License, version 3
* @link http://zwiicms.com/
* @link http://zwiicms.fr/
* @copyright : Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2020, Frédéric Tempez
*/
@ -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

@ -9,7 +9,7 @@
* @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/
* @link http://zwiicms.fr/
*/
/* Thème administration */

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

@ -7,7 +7,7 @@
* @author Fred Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @license GNU General Public License, version 3
* @link http://zwiicms.com/
* @link http://zwiicms.fr/
*/
/**

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

View File

@ -9,7 +9,7 @@
* @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/
* @link http://zwiicms.fr/
*/
/* Thème administration */

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

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @license GNU General Public License, version 3
* @link http://zwiicms.com/
* @link http://zwiicms.fr/
*/
/**

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

View File

@ -8,7 +8,7 @@
* @license GNU General Public License, version 3
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2020, Frédéric Tempez
* @link http://zwiicms.com/
* @link http://zwiicms.fr/
*/
@import url("site/data/admin.css");

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

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @license GNU General Public License, version 3
* @link http://zwiicms.com/
* @link http://zwiicms.fr/
*/
/**

19
core/module/theme/view/body/body.php Executable file → Normal file
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

@ -9,7 +9,7 @@
* @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/
* @link http://zwiicms.fr/
*/
/* Thème administration */

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

@ -9,7 +9,7 @@
* @license GNU General Public License, version 3
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2020, Frédéric Tempez
* @link http://zwiicms.com/
* @link http://zwiicms.fr/
*/
/**

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

@ -13,11 +13,11 @@
</div>
</div>
<div class="row">
<div class="col6">
<div class="col4">
<div class="block">
<h4>Couleurs</h4>
<div class="row">
<div class="col6">
<div class="col12">
<?php echo template::text('themeFooterBackgroundColor', [
'class' => 'colorPicker',
'label' => 'Fond',
@ -25,7 +25,9 @@
'help' => 'Quand le pied de page est dans le site, l\'arrière plan transparent montre le fond de la page. Quand le pied de page est hors du site, l\'arrière plan transparent montre le fond du site.'
]); ?>
</div>
<div class="col6">
</div>
<div class="row">
<div class="col12">
<?php echo template::text('themeFooterTextColor', [
'class' => 'colorPicker',
'label' => 'Texte',
@ -35,52 +37,59 @@
</div>
</div>
</div>
<div class="col6">
<div class="col8">
<div class="block">
<h4>Informations</h4>
<h4>Paramètres du bloc Informations</h4>
<div class="row">
<div class="col6">
<div class="row">
<?php echo template::checkbox('themefooterDisplayCopyright', true, 'Motorisé par', [
'checked' => $this->getData(['theme', 'footer','displayCopyright'])
]); ?>
</div>
<div class="row">
<?php echo template::checkbox('themefooterDisplayVersion', true, 'Numéro de version', [
'checked' => $this->getData(['theme', 'footer','displayVersion'])
]); ?>
</div>
<div class="row">
<?php echo template::checkbox('themeFooterDisplayLegal', true, 'Mentions légales', [
'checked' => (bool) empty($this->getData(['config', 'legalPageId'])) ? false : $this->getData(['theme', 'footer', 'displayLegal']),
'disabled' => (bool) empty($this->getData(['config', 'legalPageId'])) ? true : false,
'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.'
<?php echo template::checkbox('themefooterDisplayCopyright', true, 'Motorisé par', [
'checked' => $this->getData(['theme', 'footer','displayCopyright']),
'help' => 'Affiche cette mention devant ZwiiCMS'
]); ?>
</div>
</div>
<div class="col6">
<div class="row">
<?php echo template::checkbox('themefooterDisplaySiteMap', true, 'Plan du site', [
'checked' => $this->getData(['theme', 'footer', 'displaySiteMap']),
'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>
<?php echo template::checkbox('themefooterDisplayVersion', true, 'Numéro de version', [
'checked' => $this->getData(['theme', 'footer','displayVersion']),
'help' => 'Affiche le numéro de version après ZwiiCMS'
]); ?>
</div>
</div>
<div class="row">
<div class="col6">
<?php echo template::checkbox('themefooterDisplaySiteMap', true, 'Plan du site', [
'checked' => $this->getData(['theme', 'footer', 'displaySiteMap']),
'help' => 'Un plan du site permet un meilleur référencement.'
]); ?>
</div>
<div class="col6">
<?php echo template::checkbox('themeFooterLoginLink', true, 'Lien de connexion', [
'checked' => $this->getData(['theme', 'footer', 'loginLink']),
'help' => 'Pour éviter les tentatives de piratage, enregistrez la page de connexion en favori et désactivez cette option.'
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<?php echo template::checkbox('themeFooterDisplayMemberBar', true, 'Barre du membre connecté', [
'checked' => $this->getData(['theme', 'footer', 'displayMemberBar']),
'help' => 'Affiche les icônes de gestion du compte et de déconnexion des membres simples connectés, ne s\'applique pas aux éditeurs et administrateurs.'
]); ?>
</div>
</div>
<div class="row">
<div class="col6">
<?php echo template::checkbox('themeFooterDisplayLegal', true, 'Mentions légales', [
'checked' => (bool) empty($this->getData(['config', 'legalPageId'])) ? false : $this->getData(['theme', 'footer', 'displayLegal']),
'disabled' => (bool) empty($this->getData(['config', 'legalPageId'])) ? true : false,
'help' => (bool) empty($this->getData(['config', 'legalPageId'])) ? 'Pour activer cette option, sélectionnez la page contenant les mentions légales dans la configuration du site' : ''
]); ?>
</div>
<div class="col6">
<?php echo template::checkbox('themeFooterDisplaySearch', true, 'Rechercher dans le site', [
'checked' => (bool) empty($this->getData(['config', 'searchPageId'])) ? false : $this->getData(['theme', 'footer', 'displaySearch']),
'disabled' => (bool) empty($this->getData(['config', 'searchPageId'])) ? true : false,
'help' => (bool) empty($this->getData(['config', 'searchPageId'])) ? 'Pour activer cette option, sélectionnez la page contenant un module de recherche dans la configuration du site' : ''
]); ?>
</div>
</div>
</div>
@ -136,10 +145,9 @@
<div class="row">
<div class="col12">
<div class="block">
<h4>Configuration</h4>
<h4>Configuration des blocs</h4>
<div class="row">
<div class="col4">
<?php $footerBlockPosition = is_null($this->getData(['theme', 'footer', 'template'])) ? $module::$footerblocks[3] : $module::$footerblocks [$this->getData(['theme', 'footer', 'template'])] ;?>
<?php echo template::select('themeFooterTemplate', $module::$footerTemplate, [
'label' => 'Disposition',
@ -162,39 +170,63 @@
<div class="row">
<div class="col4">
<p><strong>Contenu personnalisé</strong></p>
<?php echo template::select('themeFooterTextPosition', $footerBlockPosition, [
'label' => 'Emplacement',
'selected' => $this->getData(['theme', 'footer', 'textPosition']),
'class' => 'themeFooterContent'
]); ?>
<?php echo template::select('themeFooterTextAlign', $module::$aligns, [
'label' => 'Alignement',
'selected' => $this->getData(['theme', 'footer', 'textAlign'])
]); ?>
<div class="row">
<div class="col12">
<?php echo template::select('themeFooterTextPosition', $footerBlockPosition, [
'label' => 'Emplacement',
'selected' => $this->getData(['theme', 'footer', 'textPosition']),
'class' => 'themeFooterContent'
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<?php echo template::select('themeFooterTextAlign', $module::$aligns, [
'label' => 'Alignement',
'selected' => $this->getData(['theme', 'footer', 'textAlign'])
]); ?>
</div>
</div>
</div>
<div class="col4">
<p><strong>Réseaux sociaux</strong></p>
<?php echo template::select('themeFooterSocialsPosition', $footerBlockPosition, [
'label' => 'Emplacement',
'selected' => $this->getData(['theme', 'footer', 'socialsPosition']),
'class' => 'themeFooterContent'
]); ?>
<?php echo template::select('themeFooterSocialsAlign', $module::$aligns, [
'label' => 'Alignement',
'selected' => $this->getData(['theme', 'footer', 'socialsAlign'])
]); ?>
<div class="row">
<div class="col12">
<?php echo template::select('themeFooterSocialsPosition', $footerBlockPosition, [
'label' => 'Emplacement',
'selected' => $this->getData(['theme', 'footer', 'socialsPosition']),
'class' => 'themeFooterContent'
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<?php echo template::select('themeFooterSocialsAlign', $module::$aligns, [
'label' => 'Alignement',
'selected' => $this->getData(['theme', 'footer', 'socialsAlign'])
]); ?>
</div>
</div>
</div>
<div class="col4">
<p><strong>Informations</strong></p>
<?php echo template::select('themeFooterCopyrightPosition', $footerBlockPosition, [
'label' => 'Emplacement',
'selected' => $this->getData(['theme', 'footer', 'copyrightPosition']),
'class' => 'themeFooterContent'
]); ?>
<?php echo template::select('themeFooterCopyrightAlign', $module::$aligns, [
'label' => 'Alignement',
'selected' => $this->getData(['theme', 'footer', 'copyrightAlign'])
]); ?>
<div class="row">
<div class="col12">
<?php echo template::select('themeFooterCopyrightPosition', $footerBlockPosition, [
'label' => 'Emplacement',
'selected' => $this->getData(['theme', 'footer', 'copyrightPosition']),
'class' => 'themeFooterContent'
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<?php echo template::select('themeFooterCopyrightAlign', $module::$aligns, [
'label' => 'Alignement',
'selected' => $this->getData(['theme', 'footer', 'copyrightAlign'])
]); ?>
</div>
</div>
</div>
<div class="col6">
<div id="themeFooterPositionOptions">

View File

@ -9,7 +9,7 @@
* @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/
* @link http://zwiicms.fr/
*/
@import url("site/data/admin.css");

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

@ -9,7 +9,7 @@
* @license GNU General Public License, version 3
* @author Frédéric Tempez <frederic.tempez@outlook.com>
* @copyright Copyright (C) 2018-2020, Frédéric Tempez
* @link http://zwiicms.com/
* @link http://zwiicms.fr/
*/
$(document).ready(function(){

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

@ -13,11 +13,11 @@
</div>
</div>
<div class="row">
<div class="col4">
<div class="col6">
<div class="block">
<h4>Couleurs</h4>
<div class="row">
<div class="col12">
<div class="col6">
<?php echo template::text('themeHeaderBackgroundColor', [
'class' => 'colorPicker',
'help' => 'Le curseur horizontal règle le niveau de transparence.',
@ -25,9 +25,7 @@
'value' => $this->getData(['theme', 'header', 'backgroundColor'])
]); ?>
</div>
</div>
<div class="row">
<div class="col12">
<div class="col6">
<?php echo template::text('themeHeaderTextColor', [
'class' => 'colorPicker',
'help' => 'Le curseur horizontal règle le niveau de transparence.',
@ -38,7 +36,7 @@
</div>
</div>
</div>
<div class="col8">
<div class="col6">
<div class="block">
<h4>Image</h4>
<div class="row">
@ -47,6 +45,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
@ -83,7 +82,7 @@
<div class="row">
<div class="col12 textAlignCenter">
<span id="themeHeaderImage">
Dimensions de l'image : largeur <span id="themeHeaderImageWidth"></span> - hauteur <span id="themeHeaderImageHeight"></span> - ratio <span id="themeHeaderImageRatio"></span>
Largeur : <span id="themeHeaderImageWidth"></span> | Hauteur : <span id="themeHeaderImageHeight"></span> | ratio : <span id="themeHeaderImageRatio"></span>
</span>
</div>
</div>

View File

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @license GNU General Public License, version 3
* @link http://zwiicms.com/
* @link http://zwiicms.fr/
*/

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

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @license GNU General Public License, version 3
* @link http://zwiicms.com/
* @link http://zwiicms.fr/
*/
/**

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

View File

@ -9,7 +9,7 @@
* @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/
* @link http://zwiicms.fr/
*/
/* Thème administration */

5
core/module/theme/view/manage/manage.php Executable file → Normal file
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

@ -9,7 +9,7 @@
* @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/
* @link http://zwiicms.fr/
*/
@import url("site/data/admin.css");

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

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @license GNU General Public License, version 3
* @link http://zwiicms.com/
* @link http://zwiicms.fr/
*/
$(document).ready(function(){

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

View File

@ -9,7 +9,7 @@
* @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/
* @link http://zwiicms.fr/
*/

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

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @license GNU General Public License, version 3
* @link http://zwiicms.com/
* @link http://zwiicms.fr/
*/
/*

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

View File

@ -9,7 +9,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @license GNU General Public License, version 3
* @link http://zwiicms.com/
* @link http://zwiicms.fr/
*/
class user extends common {
@ -24,6 +24,7 @@ class user extends common {
'logout' => self::GROUP_MEMBER,
'reset' => self::GROUP_VISITOR
];
public static $users = [];
//Paramètres pour choix de la signature
@ -34,6 +35,9 @@ class user extends common {
self::SIGNATURE_LASTFIRSTNAME => 'Nom Prénom'
];
public static $userId = '';
public static $userLongtime = false;
/**
* Ajout
@ -57,33 +61,21 @@ 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;
}
// Si tout est ok création effective
if ($check === true) {
$this->setData([
'user',
$userId,
[
'firstname' => $userFirstname,
'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)
]
]);
}
// Stockage des données
$this->setData([
'user',
$userId,
[
'firstname' => $userFirstname,
'forgot' => 0,
'group' => $this->getInput('userAddGroup', helper::FILTER_INT, true),
'lastname' => $userLastname,
'mail' => $userMail,
'password' => $this->getInput('userAddPassword', helper::FILTER_PASSWORD, true),
]
]);
// Envoie le mail
$sent = true;
if($this->getInput('userAddSendMail', helper::FILTER_BOOLEAN) && $check === true) {
@ -413,8 +405,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
@ -467,6 +461,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,
@ -479,7 +479,12 @@ 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 (array_key_exists('ZWII_USER_LONGTIME',$_COOKIE)
AND $_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

@ -9,7 +9,7 @@
* @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/
* @link http://zwiicms.fr/
*/
@import url("site/data/admin.css");

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

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @license GNU General Public License, version 3
* @link http://zwiicms.com/
* @link http://zwiicms.fr/
*/
/**

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

View File

@ -9,7 +9,7 @@
* @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/
* @link http://zwiicms.fr/
*/

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

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @license GNU General Public License, version 3
* @link http://zwiicms.com/
* @link http://zwiicms.fr/
*/
/**

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

View File

@ -9,7 +9,7 @@
* @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/
* @link http://zwiicms.fr/
*/

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

View File

@ -9,7 +9,7 @@
* @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/
* @link http://zwiicms.fr/
*/

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

@ -7,7 +7,7 @@
* @author Rémi Jean <remi.jean@outlook.com>
* @copyright Copyright (C) 2008-2018, Rémi Jean
* @license GNU General Public License, version 3
* @link http://zwiicms.com/
* @link http://zwiicms.fr/
*/
/**

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

View File

@ -9,7 +9,7 @@
* @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/
* @link http://zwiicms.fr/
*/
/*

8
core/module/user/view/login/login.php Executable file → Normal file
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>

View File

@ -9,7 +9,7 @@
* @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/
* @link http://zwiicms.fr/
*/
@import url("site/data/admin.css");

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

View File

@ -0,0 +1,56 @@
;(function(mod){
function collectLinks() {
return Array.prototype.slice.apply(
document.head.querySelectorAll('link[rel*="icon"]')
)
}
function applyLink(source, target) {
target.setAttribute('type', source.getAttribute('type'))
target.setAttribute('href', source.getAttribute('href'))
}
// eslint-disable-next-line no-unused-vars
function initSwitcher(delay) {
// Exit if media queries aren't supported
if (typeof window.matchMedia !== 'function') {
return function noop() {}
}
var links = collectLinks()
var current = document.createElement('link')
var prevMatch
current.setAttribute('rel', 'shortcut icon')
document.head.appendChild(current)
function faviconApplyLoop() {
links.forEach(function(link) {
if (window.matchMedia(link.media).matches) {
if (link.media !== prevMatch) {
prevMatch = link.media
applyLink(link, current)
}
}
})
}
var intervalId = setInterval(faviconApplyLoop, delay || 300)
function unsubscribe() {
clearInterval(intervalId)
links.forEach(function(link) {
document.head.appendChild(link)
})
}
faviconApplyLoop()
links.forEach(function(link) {
document.head.removeChild(link)
})
return unsubscribe
}
initSwitcher()
})()

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

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